PostgreSQL ERROR: dichiarazione di annullamento a causa di un conflitto con il recupero


139

Ricevo il seguente errore quando eseguo una query su un db PostgreSQL in modalità standby. La query che causa l'errore funziona correttamente per 1 mese ma quando si esegue una query per più di 1 mese si ottiene un errore.

ERROR: canceling statement due to conflict with recovery
Detail: User query might have needed to see row versions that must be removed

Qualche suggerimento su come risolvere? Grazie


Si prega di trovare il documento AWS che menzionava questo errore e ha anche la soluzione aws.amazon.com/blogs/database/…
arunjos007

Risposte:


89

L'esecuzione di query sul server hot-standby è piuttosto complicata: può non riuscire, poiché durante la query alcune righe necessarie potrebbero essere aggiornate o eliminate sul primario. Poiché un primario non sa che una query viene avviata in secondo luogo, pensa di poter ripulire (vuoto) le vecchie versioni delle sue righe. Quindi il secondario deve ripetere questa pulizia e deve forzare l'annullamento di tutte le query che possono utilizzare queste righe.

Le query più lunghe verranno annullate più spesso.

È possibile aggirare questo problema avviando una transazione di lettura ripetibile sul primario che esegue una query fittizia e quindi rimane inattiva mentre una query reale viene eseguita sul secondario. La sua presenza impedirà l'aspirazione delle vecchie versioni di fila sul primario.

Ulteriori informazioni su questo argomento e altre soluzioni alternative sono spiegate nella sezione Hot Standby - Gestione dei conflitti di query nella documentazione.


10
Per gli utenti di PostgreSQL 9.1+: vedere la risposta di eradman di seguito per una soluzione pratica.
Zoltán,

3
Per gli utenti di PostgreSQL 9.1+: la risposta di max-malysh è molto più intelligente. Non dare il suggerimento di Eradman a meno che tu non abbia compreso i rischi.
Davos,

91

Non c'è bisogno di toccarlo hot_standby_feedback. Come altri hanno già detto, impostarlo su onpuò gonfiare il padrone. Immagina di aprire una transazione su uno slave e di non chiuderla.

Invece, imposta max_standby_archive_delaye max_standby_streaming_delaysu un valore sano:

# /etc/postgresql/10/main/postgresql.conf on a slave
max_standby_archive_delay = 900s
max_standby_streaming_delay = 900s

In questo modo le query sugli slave con una durata inferiore a 900 secondi non verranno annullate. Se il carico di lavoro richiede query più lunghe, basta impostare queste opzioni su un valore più elevato.


1
Questa è la soluzione che abbiamo finito per usare. Sembra il miglior compromesso tra tutte le opzioni presentate qui.
mohit6up,

2
Questa è la risposta migliore Nota come da documenti che sono cumulativi; se sulla replica sono presenti più query che trattengono la replica, è possibile che si arrivi a 899, quindi un'altra query di 2 secondi viene annullata. È meglio implementare solo un back-off esponenziale nel codice. Inoltre, il ritardo dello streaming è attivo mentre la replica è in streaming. Se la replica non riesce a tenere il passo con lo streaming, passerà alla replica dall'archivio. Se stai eseguendo la replica dall'archivio, dovresti probabilmente lasciarlo recuperare, max_standby_archive_delaypotrebbe essere necessario essere più piccolo dell'altro.
Davos,

2
Questa è ancora la soluzione migliore qui. Si noti che in Redshift, è possibile impostare questo tramite le impostazioni del gruppo di parametri, solo che dovrebbe essere in ms, cioè 900s = 16 minuti = 900000ms.
NullDev


A condizione che lo scopo di standby sia, ad esempio, il reporting e non è un hot standby che deve essere pronto per gestire il failover, questa è assolutamente la risposta migliore.
soupdog,

77

Non è necessario avviare transazioni inattive sul master. In postgresql-9.1 il modo più diretto per risolvere questo problema è l'impostazione

hot_standby_feedback = on

Ciò renderà il master consapevole delle query di lunga durata. Dai documenti :

La prima opzione è impostare il parametro hot_standby_feedback, che impedisce a VACUUM di rimuovere le righe morte di recente e quindi non si verificano conflitti di pulizia.

Perché non è questo il valore predefinito? Questo parametro è stato aggiunto dopo l'implementazione iniziale ed è l'unico modo in cui uno standby può influire su un master.


11
Questo parametro deve essere impostato in standby.
Steve Kehlet,

3
Ci sono alcuni svantaggi per il master in questo caso. Hot-Standby-Feedback
Evgeny Liskovets

50

Come indicato qui su hot_standby_feedback = on:

Bene, lo svantaggio è che lo standby può gonfiare il master, il che potrebbe sorprendere anche alcune persone

E qui :

Con quale impostazione di max_standby_streaming_delay? Preferirei che l'impostazione predefinita fosse -1 anziché l'impostazione predefinita hot_standby_feedback su. In questo modo ciò che si fa in standby influisce solo sullo standby


Quindi ho aggiunto

max_standby_streaming_delay = -1

E niente più pg_dumperrori per noi, né padrone gonfiare :)

Per l'istanza di AWS RDS, consultare http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.html


1
@lennard, ha funzionato per me. Ho aggiunto questa configurazione su postgresql.conf dello slave, quindi ho riavviato lo slave.
Ardee Aram,

13
Naturalmente puoi ottenere un ritardo di replica illimitato in questo modo. E se si utilizza uno slot di replica per connettere la replica al master, ciò può comportare un'eccessiva conservazione degli xlog sul master, quindi è realmente praticabile solo se si utilizza l'archiviazione WAL.
Craig Ringer,

7
Come impostarlo su AWS RDS?
Kris MP

1
@KrisMP Usa psql
Yehonatan il

4
@KrisMP nel gruppo di parametri - docs.aws.amazon.com/AmazonRDS/latest/UserGuide/…
r3m0t

13

I dati della tabella sul server slave hot standby vengono modificati mentre è in esecuzione una query di lunga durata. Una soluzione (PostgreSQL 9.1+) per assicurarsi che i dati della tabella non vengano modificati è quella di sospendere la replica e riprendere dopo la query:

select pg_xlog_replay_pause(); -- suspend
select * from foo; -- your query
select pg_xlog_replay_resume(); --resume

1
Ciò richiede i diritti di superutente. Quindi potrebbe non essere una soluzione in alcuni casi.
Joao Baltazar,

1
In PostgreSQL 10, è xlogstato sostituito con wal, quindi si desidera chiamare pg_wal_replay_pause()e pg_wal_replay_resume().
Womble,

3

Potrebbe essere troppo tardi per la risposta, ma affrontiamo lo stesso tipo di problema sulla produzione. In precedenza abbiamo un solo RDS e poiché il numero di utenti aumenta sul lato app, abbiamo deciso di aggiungere Read Replica per questo. La replica di lettura funziona correttamente nella gestione temporanea, ma una volta passati alla produzione iniziamo a ricevere lo stesso errore.

Quindi risolviamo ciò abilitando la proprietà hot_standby_feedback nelle proprietà Postgres. Abbiamo fatto riferimento al seguente link

https://aws.amazon.com/blogs/database/best-practices-for-amazon-rds-postgresql-replication/

Spero che sarà di aiuto.


2

Ho intenzione di aggiungere alcune informazioni aggiornate e riferimenti all'eccellente risposta di @ max-malysh sopra.

In breve, se si fa qualcosa sul master, è necessario replicarlo sullo slave. Per questo Postgres utilizza i record WAL, che vengono inviati allo slave dopo ogni azione registrata sul master. Lo slave esegue quindi l'azione e i due sono di nuovo sincronizzati. In uno dei numerosi scenari, puoi essere in conflitto sullo schiavo con ciò che arriva dal master in un'azione WAL. Nella maggior parte di essi, c'è una transazione in corso sullo slave che è in conflitto con ciò che l'azione WAL vuole cambiare. In tal caso, hai due opzioni:

  1. Ritarda l'applicazione dell'azione WAL per un po ', consentendo allo slave di completare la transazione in conflitto, quindi applica l'azione.
  2. Annulla la query in conflitto sullo slave.

Ci occupiamo del n. 1 e di due valori:

  • max_standby_archive_delay - questo è il ritardo utilizzato dopo una lunga disconnessione tra master e slave, quando i dati vengono letti da un archivio WAL, che non sono dati correnti.
  • max_standby_streaming_delay - ritardo utilizzato per annullare le query alla ricezione di voci WAL tramite la replica in streaming.

In genere, se il server è destinato alla replica ad alta disponibilità, si desidera mantenere questi numeri brevi. L'impostazione predefinita di 30000(millisecondi se nessuna unità fornita) è sufficiente per questo. Se, tuttavia, desideri impostare qualcosa come un archivio, una replica di report o una replica di lettura che potrebbe avere query di lunga durata, ti consigliamo di impostarlo su un valore superiore per evitare query annullate. L' 900simpostazione consigliata sopra sembra un buon punto di partenza. Non sono d'accordo con i documenti ufficiali sull'impostazione di un valore infinito -1come una buona idea, che potrebbe mascherare un codice errato e causare molti problemi.

L'unico avvertimento sulle query a esecuzione prolungata e l'impostazione di questi valori su un valore più alto è che le altre query in esecuzione sullo slave in parallelo a quella a esecuzione prolungata che causa il ritardo dell'azione WAL vedranno i vecchi dati fino al completamento della query lunga. Gli sviluppatori dovranno comprendere questo e serializzare le query che non devono essere eseguite contemporaneamente.

Per la piena spiegazione di come max_standby_archive_delaye di max_standby_streaming_delaylavoro e per questo, andare qui .


1

Allo stesso modo, ecco un secondo avvertimento all'elaborazione di @ Artif3x dell'eccellente risposta di @ max-malysh, entrambe sopra.

In caso di applicazione ritardata delle transazioni da parte del master, i follower avranno una visione obsoleta e non aggiornata dei dati. Pertanto, pur fornendo tempo per il completamento della query sul follower impostando max_standby_archive_delay e max_standby_streaming_delay ha un senso, tenere a mente entrambi questi avvertimenti:

Se il valore del follower per il backup risulta troppo in conflitto con le query di hosting, una soluzione sarebbe più follower, ognuno ottimizzato per l'uno o l'altro.

Inoltre, tieni presente che diverse query di seguito possono causare ritardi nell'applicazione delle voci wal. Quindi, quando si scelgono i nuovi valori, non è solo il momento di una singola query, ma una finestra mobile che inizia ogni volta che inizia una query in conflitto e termina quando viene finalmente applicata la voce wal.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.