On Thu, 2009-06-25 at 17:35 +0300, Heikki Linnakangas wrote:
> Heikki Linnakangas wrote:
> > Hmm, what happens when the startup process performs a write, and
> > bgwriter is not running? Do the fsync requests queue up in the shmem
> > queue until the end of recovery when bgwriter is launched? I guess I'll
> > have to try it out...
> 
> Oh dear, doesn't look good. The startup process has a pendingOpsTable of
> its own. bgwriter won't fsync() files that the startup process has
> written itself. That needs to be fixed, or you can lose data when an
> archive recovery crashes after a restartpoint.

Yes, that's what I see also. Patch attached.

-- 
 Simon Riggs           www.2ndQuadrant.com
 PostgreSQL Training, Services and Support
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.343
diff -c -r1.343 xlog.c
*** src/backend/access/transam/xlog.c	11 Jun 2009 14:48:54 -0000	1.343
--- src/backend/access/transam/xlog.c	25 Jun 2009 15:00:13 -0000
***************
*** 5472,5479 ****
  			 * process in addition to postmaster!
  			 */
  			if (InArchiveRecovery && IsUnderPostmaster)
  				SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
! 
  			/*
  			 * main redo apply loop
  			 */
--- 5472,5482 ----
  			 * process in addition to postmaster!
  			 */
  			if (InArchiveRecovery && IsUnderPostmaster)
+ 			{
  				SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
! 				SetForwardFsyncRequests();
! 			}
! 	
  			/*
  			 * main redo apply loop
  			 */
Index: src/backend/storage/smgr/md.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/storage/smgr/md.c,v
retrieving revision 1.146
diff -c -r1.146 md.c
*** src/backend/storage/smgr/md.c	11 Jun 2009 14:49:02 -0000	1.146
--- src/backend/storage/smgr/md.c	25 Jun 2009 15:02:26 -0000
***************
*** 141,146 ****
--- 141,147 ----
  
  static HTAB *pendingOpsTable = NULL;
  static List *pendingUnlinks = NIL;
+ static 	remember_fsync_requests_locally = false;
  
  static CycleCtr mdsync_cycle_ctr = 0;
  static CycleCtr mdckpt_cycle_ctr = 0;
***************
*** 199,204 ****
--- 200,206 ----
  									  100L,
  									  &hash_ctl,
  								   HASH_ELEM | HASH_FUNCTION | HASH_CONTEXT);
+ 		remember_fsync_requests_locally = true;
  		pendingUnlinks = NIL;
  	}
  }
***************
*** 1180,1185 ****
--- 1182,1202 ----
  }
  
  /*
+  * InArchiveRecovery we need forward requests to the bgwriter.
+  */
+ void
+ SetForwardFsyncRequests(void)
+ {
+ 	remember_fsync_requests_locally = false;
+ 
+ 	/*
+ 	 * In case caller has any pending ops
+ 	 */
+ 	if (pendingOpsTable)
+ 		mdsync();
+ }
+ 
+ /*
   * register_dirty_segment() -- Mark a relation segment as needing fsync
   *
   * If there is a local pending-ops table, just make an entry in it for
***************
*** 1191,1197 ****
  static void
  register_dirty_segment(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg)
  {
! 	if (pendingOpsTable)
  	{
  		/* push it into local pending-ops table */
  		RememberFsyncRequest(reln->smgr_rnode, forknum, seg->mdfd_segno);
--- 1208,1214 ----
  static void
  register_dirty_segment(SMgrRelation reln, ForkNumber forknum, MdfdVec *seg)
  {
! 	if (remember_fsync_requests_locally)
  	{
  		/* push it into local pending-ops table */
  		RememberFsyncRequest(reln->smgr_rnode, forknum, seg->mdfd_segno);
***************
*** 1219,1225 ****
  static void
  register_unlink(RelFileNode rnode)
  {
! 	if (pendingOpsTable)
  	{
  		/* push it into local pending-ops table */
  		RememberFsyncRequest(rnode, MAIN_FORKNUM, UNLINK_RELATION_REQUEST);
--- 1236,1242 ----
  static void
  register_unlink(RelFileNode rnode)
  {
! 	if (remember_fsync_requests_locally)
  	{
  		/* push it into local pending-ops table */
  		RememberFsyncRequest(rnode, MAIN_FORKNUM, UNLINK_RELATION_REQUEST);
***************
*** 1377,1383 ****
  void
  ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum)
  {
! 	if (pendingOpsTable)
  	{
  		/* standalone backend or startup process: fsync state is local */
  		RememberFsyncRequest(rnode, forknum, FORGET_RELATION_FSYNC);
--- 1394,1400 ----
  void
  ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum)
  {
! 	if (remember_fsync_requests_locally)
  	{
  		/* standalone backend or startup process: fsync state is local */
  		RememberFsyncRequest(rnode, forknum, FORGET_RELATION_FSYNC);
***************
*** 1416,1422 ****
  	rnode.spcNode = 0;
  	rnode.relNode = 0;
  
! 	if (pendingOpsTable)
  	{
  		/* standalone backend or startup process: fsync state is local */
  		RememberFsyncRequest(rnode, InvalidForkNumber, FORGET_DATABASE_FSYNC);
--- 1433,1439 ----
  	rnode.spcNode = 0;
  	rnode.relNode = 0;
  
! 	if (remember_fsync_requests_locally)
  	{
  		/* standalone backend or startup process: fsync state is local */
  		RememberFsyncRequest(rnode, InvalidForkNumber, FORGET_DATABASE_FSYNC);
Index: src/include/storage/smgr.h
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/storage/smgr.h,v
retrieving revision 1.67
diff -c -r1.67 smgr.h
*** src/include/storage/smgr.h	11 Jun 2009 14:49:12 -0000	1.67
--- src/include/storage/smgr.h	25 Jun 2009 14:59:43 -0000
***************
*** 109,114 ****
--- 109,115 ----
  extern void mdsync(void);
  extern void mdpostckpt(void);
  
+ extern void SetForwardFsyncRequests(void);
  extern void RememberFsyncRequest(RelFileNode rnode, ForkNumber forknum,
  					 BlockNumber segno);
  extern void ForgetRelationFsyncRequests(RelFileNode rnode, ForkNumber forknum);
-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to