77 * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
88 * Portions Copyright (c) 1994, Regents of the University of California
99 *
10- * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.114 2003/04/25 19:45:08 tgl Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v 1.115 2003/05/10 18:01:31 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -2973,11 +2973,13 @@ CreateCheckPoint(bool shutdown, bool force)
29732973elog (ERROR ,"CreateCheckPoint: cannot be called inside transaction block" );
29742974
29752975/*
2976+ * Acquire CheckpointLock to ensure only one checkpoint happens at a time.
2977+ *
29762978 * The CheckpointLock can be held for quite a while, which is not good
29772979 * because we won't respond to a cancel/die request while waiting for
29782980 * an LWLock. (But the alternative of using a regular lock won't work
29792981 * for background checkpoint processes, which are not regular
2980- * backends.) So, rather than use a plain LWLockAcquire, use this
2982+ * backends.) So, rather than use a plain LWLockAcquire, use this
29812983 * kluge to allow an interrupt to be accepted while we are waiting:
29822984 */
29832985while (!LWLockConditionalAcquire (CheckpointLock ,LW_EXCLUSIVE ))
@@ -2986,6 +2988,9 @@ CreateCheckPoint(bool shutdown, bool force)
29862988sleep (1 );
29872989}
29882990
2991+ /*
2992+ * Use a critical section to force system panic if we have trouble.
2993+ */
29892994START_CRIT_SECTION ();
29902995
29912996if (shutdown )
@@ -3056,6 +3061,13 @@ CreateCheckPoint(bool shutdown, bool force)
30563061/*
30573062 * Here we update the shared RedoRecPtr for future XLogInsert calls;
30583063 * this must be done while holding the insert lock AND the info_lck.
3064+ *
3065+ * Note: if we fail to complete the checkpoint, RedoRecPtr will be
3066+ * left pointing past where it really needs to point. This is okay;
3067+ * the only consequence is that XLogInsert might back up whole buffers
3068+ * that it didn't really need to. We can't postpone advancing RedoRecPtr
3069+ * because XLogInserts that happen while we are dumping buffers must
3070+ * assume that their buffer changes are not included in the checkpoint.
30593071 */
30603072{
30613073/* use volatile pointer to prevent code rearrangement */
@@ -3094,6 +3106,9 @@ CreateCheckPoint(bool shutdown, bool force)
30943106 */
30953107LWLockRelease (WALInsertLock );
30963108
3109+ /*
3110+ * Get the other info we need for the checkpoint record.
3111+ */
30973112LWLockAcquire (XidGenLock ,LW_SHARED );
30983113checkPoint .nextXid = ShmemVariableCache -> nextXid ;
30993114LWLockRelease (XidGenLock );
@@ -3107,10 +3122,18 @@ CreateCheckPoint(bool shutdown, bool force)
31073122/*
31083123 * Having constructed the checkpoint record, ensure all shmem disk
31093124 * buffers and commit-log buffers are flushed to disk.
3125+ *
3126+ * This I/O could fail for various reasons. If so, we will fail to
3127+ * complete the checkpoint, but there is no reason to force a system
3128+ * panic. Accordingly, exit critical section while doing it.
31103129 */
3130+ END_CRIT_SECTION ();
3131+
31113132CheckPointCLOG ();
31123133FlushBufferPool ();
31133134
3135+ START_CRIT_SECTION ();
3136+
31143137/*
31153138 * Now insert the checkpoint record into XLOG.
31163139 */
@@ -3166,6 +3189,12 @@ CreateCheckPoint(bool shutdown, bool force)
31663189UpdateControlFile ();
31673190LWLockRelease (ControlFileLock );
31683191
3192+ /*
3193+ * We are now done with critical updates; no need for system panic if
3194+ * we have trouble while fooling with offline log segments.
3195+ */
3196+ END_CRIT_SECTION ();
3197+
31693198/*
31703199 * Delete offline log files (those no longer needed even for previous
31713200 * checkpoint).
@@ -3185,8 +3214,6 @@ CreateCheckPoint(bool shutdown, bool force)
31853214PreallocXlogFiles (recptr );
31863215
31873216LWLockRelease (CheckpointLock );
3188-
3189- END_CRIT_SECTION ();
31903217}
31913218
31923219/*