0002-Dont-FATAL-a-IDLE-IN-TRANSACTIOn-backend-during-conf.patch
text/x-patch
Filename: 0002-Dont-FATAL-a-IDLE-IN-TRANSACTIOn-backend-during-conf.patch
Type: text/x-patch
Part: 0
Message:
idle in txn query cancellation
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch 0002
Subject: Dont FATAL a IDLE IN TRANSACTIOn backend during conflict resolution. Instead avoid sending the error (and a later "read for query") to the client to avoid confusing the client state.
| File | + | − |
|---|---|---|
| src/backend/tcop/postgres.c | 0 | 0 |
From 2171feda1a91b0e77c1c0788abb3fc3183503b79 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Sat, 13 Feb 2010 22:30:41 +0100
Subject: [PATCH 2/2] Dont FATAL a IDLE IN TRANSACTIOn backend during conflict
resolution. Instead avoid sending the error (and a later "read for
query") to the client to avoid confusing the client state.
---
src/backend/tcop/postgres.c | 41 ++++++++++++++++++++++++++++++++---------
1 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 13734f0..e9c622e 100644
*** a/src/backend/tcop/postgres.c
--- b/src/backend/tcop/postgres.c
*************** static int UseNewLine = 0; /* Use EOF a
*** 176,181 ****
--- 176,187 ----
static bool RecoveryConflictPending = false;
static ProcSignalReason RecoveryConflictReason;
+ /*
+ * Are we disallowed from sending a "ready for query" message right
+ * now because it would confuse the frontend?
+ */
+ bool silent_error_while_idle = false;
+
/* ----------------------------------------------------------------
* decls for routines only used in this file
* ----------------------------------------------------------------
*************** ProcessInterrupts(void)
*** 2917,2934 ****
RecoveryConflictPending = false;
DisableNotifyInterrupt();
DisableCatchupInterrupt();
! if (DoingCommandRead)
! ereport(FATAL,
! (errcode(ERRCODE_ADMIN_SHUTDOWN),
! 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),
errmsg("canceling statement due to conflict with recovery"),
errdetail_recovery_conflict()));
}
/*
--- 2923,2948 ----
RecoveryConflictPending = false;
DisableNotifyInterrupt();
DisableCatchupInterrupt();
! if (DoingCommandRead){
! /*
! * We cant issue a normal ERROR here because the
! * client doesnt expect the server to send an error at
! * that point.
! * We also may not send a "ready for query"/Z message
! * because that would be unexpected as well.
! */
! silent_error_while_idle = true;
! ereport(ERROR | LOG_NO_CLIENT,
! (errcode(ERRCODE_QUERY_CANCELED),
! errmsg("canceling statement due to conflict with recovery"),
! errdetail_recovery_conflict()));
! }
! else{
ereport(ERROR,
(errcode(ERRCODE_QUERY_CANCELED),
errmsg("canceling statement due to conflict with recovery"),
errdetail_recovery_conflict()));
+ }
}
/*
*************** PostgresMain(int argc, char *argv[], con
*** 3767,3773 ****
* processing of batched messages, and because we don't want to report
* uncommitted updates (that confuses autovacuum).
*/
! if (send_ready_for_query)
{
if (IsAbortedTransactionBlockState())
{
--- 3781,3787 ----
* processing of batched messages, and because we don't want to report
* uncommitted updates (that confuses autovacuum).
*/
! if (send_ready_for_query && !silent_error_while_idle)
{
if (IsAbortedTransactionBlockState())
{
*************** PostgresMain(int argc, char *argv[], con
*** 3792,3797 ****
--- 3806,3820 ----
}
/*
+ * After ReadCommand continued we are sure that the frontend
+ * sent a message and can handle a 'Z' message. We cant set
+ * that after ReadCommand because that will error out when in
+ * an aborted transaction - which we are when
+ * silent_error_while_idle was set.
+ */
+ silent_error_while_idle = false;
+
+ /*
* (2) Allow asynchronous signals to be executed immediately if they
* come in while we are waiting for client input. (This must be
* conditional since we don't want, say, reads on behalf of COPY FROM
--
1.6.5.12.gd65df24