On Thu, 2011-03-03 at 02:14 -0500, Tom Lane wrote:
> Fujii Masao <masao.fu...@gmail.com> writes:
> > On Thu, Mar 3, 2011 at 12:11 AM, Heikki Linnakangas
> > <heikki.linnakan...@enterprisedb.com> wrote:
> >> To achieve the effect Fujii is looking for, we would have to silently drop
> >> the connection. That would correctly leave the client not knowing whether
> >> the transaction committed or not.
> 
> > Yeah, this seems to make more sense.
> 
> It was pointed out that sending an ERROR would not do because it would
> likely lead to client code assuming the transaction failed, which might
> or might not be the case.  But maybe we could send a WARNING and then
> close the connection?  That would give humans a clue what had happened,
> but not do anything to the state of automated clients.

So when we perform a Fast Shutdown we want to do something fairly
similar to quickdie()?

Please review the attached patch.

-- 
 Simon Riggs           http://www.2ndQuadrant.com/books/
 PostgreSQL Development, 24x7 Support, Training and Services
 
*** 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() \
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to