cancel_syncrep_at_shutdown.v1.patch

text/x-patch

Filename: cancel_syncrep_at_shutdown.v1.patch
Type: text/x-patch
Part: 0
Message: Re: Sync Rep v17

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() \