Commit 66035734 authored by Simon Riggs's avatar Simon Riggs

Give most recovery conflict errors a retryable error code. From recent

requests and discussions with Yeb Havinga and Kevin Grittner.
parent 44e55690
......@@ -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()));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment