cancel_syncrep_at_shutdown.v1.patch
text/x-patch
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: context
Series: patch v1
| File | + | − |
|---|---|---|
| src/backend/replication/syncrep.c | 4 | 1 |
| src/backend/tcop/postgres.c | 28 | 0 |
| src/include/miscadmin.h | 3 | 0 |
*** a/src/backend/replication/syncrep.c
--- b/src/backend/replication/syncrep.c
***************
*** 63,71 ****
/* User-settable parameters for sync rep */
bool sync_rep_mode = false; /* Only set in user backends */
! int sync_rep_timeout = 120; /* Only set in user backends */
char *SyncRepStandbyNames;
#define IsOnSyncRepQueue() (MyProc->lwWaiting)
--- 63,72 ----
/* User-settable parameters for sync rep */
bool sync_rep_mode = false; /* Only set in user backends */
! int sync_rep_timeout = 120; /* Only set in user backends */
char *SyncRepStandbyNames;
+ bool WaitingForSyncRep = false; /* Global state for some exit methods */
#define IsOnSyncRepQueue() (MyProc->lwWaiting)
***************
*** 202,207 **** SyncRepWaitOnQueue(XLogRecPtr XactCommitLSN)
--- 203,209 ----
MyProc->waitLSN = XactCommitLSN;
SyncRepAddToQueue();
LWLockRelease(SyncRepLock);
+ WaitingForSyncRep = true;
/*
* Alter ps display to show waiting for sync rep.
***************
*** 241,246 **** SyncRepWaitOnQueue(XLogRecPtr XactCommitLSN)
--- 243,249 ----
{
SyncRepRemoveFromQueue();
LWLockRelease(SyncRepLock);
+ WaitingForSyncRep = false;
/*
* Reset our waitLSN.
***************
*** 248,254 **** SyncRepWaitOnQueue(XLogRecPtr XactCommitLSN)
MyProc->waitLSN.xlogid = 0;
MyProc->waitLSN.xrecoff = 0;
-
if (new_status)
{
/* Reset ps display */
--- 251,256 ----
*** a/src/backend/tcop/postgres.c
--- b/src/backend/tcop/postgres.c
***************
*** 2902,2907 **** ProcessInterrupts(void)
--- 2902,2935 ----
ereport(FATAL,
(errcode(ERRCODE_ADMIN_SHUTDOWN),
errmsg("terminating autovacuum process due to administrator command")));
+ else if (WaitingForSyncRep)
+ {
+ /*
+ * This must NOT be a FATAL message. We want the state of the
+ * transaction being aborted to be indeterminate to ensure that
+ * the transaction completion guarantee is never broken.
+ */
+ ereport(WARNING,
+ (errcode(ERRCODE_ADMIN_SHUTDOWN),
+ errmsg("terminating connection because fast shutdown is requested"),
+ errdetail("This connection requested synchronous replication at commit"
+ " yet confirmation of replication has not been received."
+ " The transaction has committed locally and might be committed"
+ " on recently disconnected standby servers also.")));
+
+ /*
+ * We DO NOT want to run proc_exit() callbacks -- we're here because
+ * we are shutting down and don't want any code to stall or
+ * prevent that.
+ */
+ on_exit_reset();
+
+ /*
+ * Note we do exit(0) not exit(>0). This is to avoid forcing
+ * postmaster into a system reset cycle.
+ */
+ exit(0);
+ }
else if (RecoveryConflictPending && RecoveryConflictRetryable)
{
pgstat_report_recovery_conflict(RecoveryConflictReason);
*** a/src/include/miscadmin.h
--- b/src/include/miscadmin.h
***************
*** 78,83 **** extern PGDLLIMPORT volatile uint32 CritSectionCount;
--- 78,86 ----
/* in tcop/postgres.c */
extern void ProcessInterrupts(void);
+ /* in replication/syncrep.c */
+ extern bool WaitingForSyncRep;
+
#ifndef WIN32
#define CHECK_FOR_INTERRUPTS() \