aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/transam/xlog.c15
-rw-r--r--src/backend/storage/sync/sync.c14
2 files changed, 21 insertions, 8 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 885558f291e..a30314bc830 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8715,6 +8715,14 @@ CreateCheckPoint(int flags)
CheckpointStats.ckpt_start_t = GetCurrentTimestamp();
/*
+ * Let smgr prepare for checkpoint; this has to happen outside the
+ * critical section and before we determine the REDO pointer. Note that
+ * smgr must not do anything that'd have to be undone if we decide no
+ * checkpoint is needed.
+ */
+ SyncPreCheckpoint();
+
+ /*
* Use a critical section to force system panic if we have trouble.
*/
START_CRIT_SECTION();
@@ -8728,13 +8736,6 @@ CreateCheckPoint(int flags)
LWLockRelease(ControlFileLock);
}
- /*
- * Let smgr prepare for checkpoint; this has to happen before we determine
- * the REDO pointer. Note that smgr must not do anything that'd have to
- * be undone if we decide no checkpoint is needed.
- */
- SyncPreCheckpoint();
-
/* Begin filling in the checkpoint WAL record */
MemSet(&checkPoint, 0, sizeof(checkPoint));
checkPoint.time = (pg_time_t) time(NULL);
diff --git a/src/backend/storage/sync/sync.c b/src/backend/storage/sync/sync.c
index a67dc591e0e..fce2093beab 100644
--- a/src/backend/storage/sync/sync.c
+++ b/src/backend/storage/sync/sync.c
@@ -151,7 +151,9 @@ InitSync(void)
* counter is incremented here.
*
* This must be called *before* the checkpoint REDO point is determined.
- * That ensures that we won't delete files too soon.
+ * That ensures that we won't delete files too soon. Since this calls
+ * AbsorbSyncRequests(), which performs memory allocations, it cannot be
+ * called within a critical section.
*
* Note that we can't do anything here that depends on the assumption
* that the checkpoint will be completed.
@@ -160,6 +162,16 @@ void
SyncPreCheckpoint(void)
{
/*
+ * Operations such as DROP TABLESPACE assume that the next checkpoint will
+ * process all recently forwarded unlink requests, but if they aren't
+ * absorbed prior to advancing the cycle counter, they won't be processed
+ * until a future checkpoint. The following absorb ensures that any
+ * unlink requests forwarded before the checkpoint began will be processed
+ * in the current checkpoint.
+ */
+ AbsorbSyncRequests();
+
+ /*
* Any unlink requests arriving after this point will be assigned the next
* cycle counter, and won't be unlinked until next checkpoint.
*/