Give most recovery conflict errors a retryable error code. From recent
requests and discussions with Yeb Havinga and Kevin Grittner.
This commit is contained in:
parent
44e55690fd
commit
66035734ec
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.593 2010/04/20 01:38:52 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.594 2010/05/12 19:45:02 sriggs Exp $
|
||||
*
|
||||
* NOTES
|
||||
* this is the "main" module of the postgres backend and
|
||||
@ -174,6 +174,7 @@ static int UseNewLine = 0; /* Use EOF as query delimiters */
|
||||
|
||||
/* whether or not, and why, we were cancelled by conflict with recovery */
|
||||
static bool RecoveryConflictPending = false;
|
||||
static bool RecoveryConflictRetryable = true;
|
||||
static ProcSignalReason RecoveryConflictReason;
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
@ -2836,6 +2837,15 @@ RecoveryConflictInterrupt(ProcSignalReason reason)
|
||||
|
||||
Assert(RecoveryConflictPending && (QueryCancelPending || ProcDiePending));
|
||||
|
||||
/*
|
||||
* All conflicts apart from database cause dynamic errors where the
|
||||
* command or transaction can be retried at a later point with some
|
||||
* potential for success. No need to reset this, since
|
||||
* non-retryable conflict errors are currently FATAL.
|
||||
*/
|
||||
if (reason == PROCSIG_RECOVERY_CONFLICT_DATABASE)
|
||||
RecoveryConflictRetryable = false;
|
||||
|
||||
/*
|
||||
* If it's safe to interrupt, and we're waiting for input or a lock,
|
||||
* service the interrupt immediately
|
||||
@ -2885,6 +2895,11 @@ ProcessInterrupts(void)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_ADMIN_SHUTDOWN),
|
||||
errmsg("terminating autovacuum process due to administrator command")));
|
||||
else if (RecoveryConflictPending && RecoveryConflictRetryable)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
|
||||
errmsg("terminating connection due to conflict with recovery"),
|
||||
errdetail_recovery_conflict()));
|
||||
else if (RecoveryConflictPending)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_ADMIN_SHUTDOWN),
|
||||
@ -2936,14 +2951,14 @@ ProcessInterrupts(void)
|
||||
DisableCatchupInterrupt();
|
||||
if (DoingCommandRead)
|
||||
ereport(FATAL,
|
||||
(errcode(ERRCODE_ADMIN_SHUTDOWN),
|
||||
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
|
||||
errmsg("terminating connection due to conflict with recovery"),
|
||||
errdetail_recovery_conflict(),
|
||||
errhint("In a moment you should be able to reconnect to the"
|
||||
" database and repeat your command.")));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_QUERY_CANCELED),
|
||||
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
|
||||
errmsg("canceling statement due to conflict with recovery"),
|
||||
errdetail_recovery_conflict()));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user