aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Munro <tmunro@postgresql.org>2019-03-14 10:25:27 +1300
committerThomas Munro <tmunro@postgresql.org>2019-03-14 10:59:33 +1300
commitc6c9474aafa4de357ae424cd18b69e8bf7a4babe (patch)
tree99d567cf37361f559828c2240fc93989a2124f76 /src
parent5655565c077c53b6e9b4b9bfcdf96439cf3af065 (diff)
downloadpostgresql-c6c9474aafa4de357ae424cd18b69e8bf7a4babe.tar.gz
postgresql-c6c9474aafa4de357ae424cd18b69e8bf7a4babe.zip
Use condition variables to wait for checkpoints.
Previously we used a polling/sleeping loop to wait for checkpoints to begin and end, which leads to up to a couple hundred milliseconds of needless thumb-twiddling. Use condition variables instead. Author: Thomas Munro Reviewed-by: Andres Freund Discussion: https://postgr.es/m/CA%2BhUKGLY7sDe%2Bbg1K%3DbnEzOofGoo4bJHYh9%2BcDCXJepb6DQmLw%40mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/postmaster/checkpointer.c21
-rw-r--r--src/backend/postmaster/pgstat.c6
-rw-r--r--src/include/pgstat.h2
3 files changed, 25 insertions, 4 deletions
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index fe96c41359b..3d5b382d048 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -126,6 +126,9 @@ typedef struct
int ckpt_flags; /* checkpoint flags, as defined in xlog.h */
+ ConditionVariable start_cv; /* signaled when ckpt_started advances */
+ ConditionVariable done_cv; /* signaled when ckpt_done advances */
+
uint32 num_backend_writes; /* counts user backend buffer writes */
uint32 num_backend_fsync; /* counts user backend fsync calls */
@@ -428,6 +431,8 @@ CheckpointerMain(void)
CheckpointerShmem->ckpt_started++;
SpinLockRelease(&CheckpointerShmem->ckpt_lck);
+ ConditionVariableBroadcast(&CheckpointerShmem->start_cv);
+
/*
* The end-of-recovery checkpoint is a real checkpoint that's
* performed while we're still in recovery.
@@ -488,6 +493,8 @@ CheckpointerMain(void)
CheckpointerShmem->ckpt_done = CheckpointerShmem->ckpt_started;
SpinLockRelease(&CheckpointerShmem->ckpt_lck);
+ ConditionVariableBroadcast(&CheckpointerShmem->done_cv);
+
if (ckpt_performed)
{
/*
@@ -915,6 +922,8 @@ CheckpointerShmemInit(void)
MemSet(CheckpointerShmem, 0, size);
SpinLockInit(&CheckpointerShmem->ckpt_lck);
CheckpointerShmem->max_requests = NBuffers;
+ ConditionVariableInit(&CheckpointerShmem->start_cv);
+ ConditionVariableInit(&CheckpointerShmem->done_cv);
}
}
@@ -1023,6 +1032,7 @@ RequestCheckpoint(int flags)
new_failed;
/* Wait for a new checkpoint to start. */
+ ConditionVariablePrepareToSleep(&CheckpointerShmem->start_cv);
for (;;)
{
SpinLockAcquire(&CheckpointerShmem->ckpt_lck);
@@ -1032,13 +1042,15 @@ RequestCheckpoint(int flags)
if (new_started != old_started)
break;
- CHECK_FOR_INTERRUPTS();
- pg_usleep(100000L);
+ ConditionVariableSleep(&CheckpointerShmem->start_cv,
+ WAIT_EVENT_CHECKPOINT_START);
}
+ ConditionVariableCancelSleep();
/*
* We are waiting for ckpt_done >= new_started, in a modulo sense.
*/
+ ConditionVariablePrepareToSleep(&CheckpointerShmem->done_cv);
for (;;)
{
int new_done;
@@ -1051,9 +1063,10 @@ RequestCheckpoint(int flags)
if (new_done - new_started >= 0)
break;
- CHECK_FOR_INTERRUPTS();
- pg_usleep(100000L);
+ ConditionVariableSleep(&CheckpointerShmem->done_cv,
+ WAIT_EVENT_CHECKPOINT_DONE);
}
+ ConditionVariableCancelSleep();
if (new_failed != old_failed)
ereport(ERROR,
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index ba31f532ea4..2fbfadd9f0c 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3623,6 +3623,12 @@ pgstat_get_wait_ipc(WaitEventIPC w)
case WAIT_EVENT_BTREE_PAGE:
event_name = "BtreePage";
break;
+ case WAIT_EVENT_CHECKPOINT_DONE:
+ event_name = "CheckpointDone";
+ break;
+ case WAIT_EVENT_CHECKPOINT_START:
+ event_name = "CheckpointStart";
+ break;
case WAIT_EVENT_CLOG_GROUP_UPDATE:
event_name = "ClogGroupUpdate";
break;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 725c8b0d64a..ea6cc8b560f 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -817,6 +817,8 @@ typedef enum
WAIT_EVENT_BGWORKER_STARTUP,
WAIT_EVENT_BTREE_PAGE,
WAIT_EVENT_CLOG_GROUP_UPDATE,
+ WAIT_EVENT_CHECKPOINT_DONE,
+ WAIT_EVENT_CHECKPOINT_START,
WAIT_EVENT_EXECUTE_GATHER,
WAIT_EVENT_HASH_BATCH_ALLOCATING,
WAIT_EVENT_HASH_BATCH_ELECTING,