From: Nathan Bossart Date: Wed, 26 Jul 2023 16:24:01 -0700 Subject: [PATCH v3 1/1] WORK IN PROGRESS: pg_msleep --- src/backend/access/nbtree/nbtpage.c | 2 +- src/backend/access/transam/multixact.c | 3 ++- src/backend/access/transam/xlog.c | 6 +++--- src/backend/access/transam/xlogutils.c | 3 ++- src/backend/commands/vacuum.c | 4 +--- src/backend/libpq/pqcomm.c | 3 ++- src/backend/port/win32/socket.c | 2 +- src/backend/postmaster/autovacuum.c | 8 ++++---- src/backend/postmaster/bgworker.c | 2 +- src/backend/postmaster/bgwriter.c | 2 +- src/backend/postmaster/checkpointer.c | 4 ++-- src/backend/postmaster/pgarch.c | 6 ++++-- src/backend/postmaster/postmaster.c | 2 +- src/backend/postmaster/walwriter.c | 2 +- src/backend/replication/walsender.c | 2 +- src/backend/storage/file/fd.c | 4 ++-- src/backend/storage/ipc/latch.c | 14 ++++++++++++++ src/backend/storage/ipc/procarray.c | 2 +- src/backend/storage/ipc/standby.c | 4 ++-- src/backend/storage/lmgr/lmgr.c | 4 ++-- src/backend/utils/activity/wait_event_names.txt | 2 ++ src/backend/utils/init/postinit.c | 4 ++-- src/include/storage/latch.h | 1 + 23 files changed, 53 insertions(+), 33 deletions(-) diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index d78971bfe8..ab31da93a4 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -3013,7 +3013,7 @@ _bt_pendingfsm_finalize(Relation rel, BTVacState *vstate) * never be effective without some other backend concurrently consuming an * XID. */ - pg_usleep(5000000L); + pg_msleep(5000, WAIT_EVENT_PG_SLEEP); #endif /* diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index abb022e067..18c4041b19 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -90,6 +90,7 @@ #include "utils/builtins.h" #include "utils/memutils.h" #include "utils/snapmgr.h" +#include "utils/wait_event.h" /* @@ -1390,7 +1391,7 @@ retry: /* Corner case 2: next multixact is still being filled in */ LWLockRelease(MultiXactOffsetSLRULock); CHECK_FOR_INTERRUPTS(); - pg_usleep(1000L); + pg_msleep(1, WAIT_EVENT_PG_SLEEP); goto retry; } diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 60c0b7ec3a..0dce93637b 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -5130,7 +5130,7 @@ StartupXLOG(void) /* This is just to allow attaching to startup process with a debugger */ #ifdef XLOG_REPLAY_DELAY if (ControlFile->state != DB_SHUTDOWNED) - pg_usleep(60000000L); + pg_msleep(60000, WAIT_EVENT_PG_SLEEP); #endif /* @@ -6710,7 +6710,7 @@ CreateCheckPoint(int flags) { do { - pg_usleep(10000L); /* wait for 10 msec */ + pg_msleep(10, WAIT_EVENT_PG_SLEEP); } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids, DELAY_CHKPT_START)); } @@ -6723,7 +6723,7 @@ CreateCheckPoint(int flags) { do { - pg_usleep(10000L); /* wait for 10 msec */ + pg_msleep(10, WAIT_EVENT_PG_SLEEP); } while (HaveVirtualXIDsDelayingChkpt(vxids, nvxids, DELAY_CHKPT_COMPLETE)); } diff --git a/src/backend/access/transam/xlogutils.c b/src/backend/access/transam/xlogutils.c index e174a2a891..ff24a1f0b8 100644 --- a/src/backend/access/transam/xlogutils.c +++ b/src/backend/access/transam/xlogutils.c @@ -27,6 +27,7 @@ #include "miscadmin.h" #include "pgstat.h" #include "storage/fd.h" +#include "storage/latch.h" #include "storage/smgr.h" #include "utils/guc.h" #include "utils/hsearch.h" @@ -958,7 +959,7 @@ read_local_xlog_page_guts(XLogReaderState *state, XLogRecPtr targetPagePtr, } CHECK_FOR_INTERRUPTS(); - pg_usleep(1000L); + pg_msleep(1, WAIT_EVENT_PG_SLEEP); } else { diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c index 69ac276687..f82f6e8878 100644 --- a/src/backend/commands/vacuum.c +++ b/src/backend/commands/vacuum.c @@ -2384,9 +2384,7 @@ vacuum_delay_point(void) if (msec > vacuum_cost_delay * 4) msec = vacuum_cost_delay * 4; - pgstat_report_wait_start(WAIT_EVENT_VACUUM_DELAY); - pg_usleep(msec * 1000); - pgstat_report_wait_end(); + pg_msleep(msec, WAIT_EVENT_VACUUM_DELAY); /* * We don't want to ignore postmaster death during very long vacuums diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index da5bb5fc5d..e1c620fd26 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -80,6 +80,7 @@ #include "storage/ipc.h" #include "utils/guc_hooks.h" #include "utils/memutils.h" +#include "utils/wait_event.h" /* * Cope with the various platform-specific ways to spell TCP keepalive socket @@ -714,7 +715,7 @@ StreamConnection(pgsocket server_fd, Port *port) * (The most likely reason for failure is being out of kernel file * table slots; we can do little except hope some will get freed up.) */ - pg_usleep(100000L); /* wait 0.1 sec */ + pg_msleep(100, WAIT_EVENT_PG_SLEEP); return STATUS_ERROR; } diff --git a/src/backend/port/win32/socket.c b/src/backend/port/win32/socket.c index 9c339397d1..c328a45e45 100644 --- a/src/backend/port/win32/socket.c +++ b/src/backend/port/win32/socket.c @@ -436,7 +436,7 @@ pgwin32_recv(SOCKET s, char *buf, int len, int f) * again. We try up to 5 times - if it fails more than that it's not * likely to ever come back. */ - pg_usleep(10000); + pg_msleep(10, WAIT_EVENT_PG_SLEEP); } ereport(NOTICE, (errmsg_internal("could not read from ready socket (after retries)"))); diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index ae9be9b911..1c49368521 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -453,7 +453,7 @@ AutoVacLauncherMain(int argc, char *argv[]) (errmsg_internal("autovacuum launcher started"))); if (PostAuthDelay) - pg_usleep(PostAuthDelay * 1000000L); + pg_msleep(PostAuthDelay * 1000, WAIT_EVENT_POST_AUTH_DELAY); SetProcessingMode(InitProcessing); @@ -572,7 +572,7 @@ AutoVacLauncherMain(int argc, char *argv[]) * Sleep at least 1 second after any error. We don't want to be * filling the error logs as fast as we can. */ - pg_usleep(1000000L); + pg_msleep(1000, WAIT_EVENT_PG_SLEEP); } /* We can now handle ereport(ERROR) */ @@ -698,7 +698,7 @@ AutoVacLauncherMain(int argc, char *argv[]) * of a worker will continue to fail in the same way. */ AutoVacuumShmem->av_signal[AutoVacForkFailed] = false; - pg_usleep(1000000L); /* 1s */ + pg_msleep(1000, WAIT_EVENT_PG_SLEEP); SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER); continue; } @@ -1714,7 +1714,7 @@ AutoVacWorkerMain(int argc, char *argv[]) (errmsg_internal("autovacuum: processing database \"%s\"", dbname))); if (PostAuthDelay) - pg_usleep(PostAuthDelay * 1000000L); + pg_msleep(PostAuthDelay * 1000, WAIT_EVENT_POST_AUTH_DELAY); /* And do an appropriate amount of work */ recentXid = ReadNextTransactionId(); diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 5b4bd71694..0cf06539a7 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -759,7 +759,7 @@ StartBackgroundWorker(void) /* Apply PostAuthDelay */ if (PostAuthDelay > 0) - pg_usleep(PostAuthDelay * 1000000L); + pg_msleep(PostAuthDelay * 1000, WAIT_EVENT_POST_AUTH_DELAY); /* * Set up signal handlers. diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index caad642ec9..3f683286fe 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -195,7 +195,7 @@ BackgroundWriterMain(void) * to be repeated, and we don't want to be filling the error logs as * fast as we can. */ - pg_usleep(1000000L); + pg_msleep(1000, WAIT_EVENT_PG_SLEEP); /* * Close all open files after any error. This is helpful on Windows, diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index ace9893d95..a79bca7a11 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -309,7 +309,7 @@ CheckpointerMain(void) * to be repeated, and we don't want to be filling the error logs as * fast as we can. */ - pg_usleep(1000000L); + pg_msleep(1000, WAIT_EVENT_CHECKPOINTER_MAIN); /* * Close all open files after any error. This is helpful on Windows, @@ -1005,7 +1005,7 @@ RequestCheckpoint(int flags) break; /* signal sent successfully */ CHECK_FOR_INTERRUPTS(); - pg_usleep(100000L); /* wait 0.1 sec, then retry */ + pg_msleep(100, WAIT_EVENT_CHECKPOINTER_MAIN); /* wait 0.1 sec, then retry */ } /* diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c index 46af349564..f526f51ee9 100644 --- a/src/backend/postmaster/pgarch.c +++ b/src/backend/postmaster/pgarch.c @@ -453,7 +453,7 @@ pgarch_ArchiverCopyLoop(void) } /* wait a bit before retrying */ - pg_usleep(1000000L); + pg_msleep(1000, WAIT_EVENT_ARCHIVER_MAIN); continue; } @@ -485,7 +485,9 @@ pgarch_ArchiverCopyLoop(void) xlog))); return; /* give up archiving for now */ } - pg_usleep(1000000L); /* wait a bit before retrying */ + + /* wait a bit before retrying */ + pg_msleep(1000, WAIT_EVENT_ARCHIVER_MAIN); } } } diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 9c8ec779f9..52b8a37259 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -4264,7 +4264,7 @@ BackendInitialize(Port *port) * is not honored until after authentication.) */ if (PreAuthDelay > 0) - pg_usleep(PreAuthDelay * 1000000L); + pg_msleep(PreAuthDelay * 1000, WAIT_EVENT_PRE_AUTH_DELAY); /* This flag will remain set until InitPostgres finishes authentication */ ClientAuthInProgress = true; /* limit visibility of log messages */ diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c index 266fbc2339..d84ebb30b4 100644 --- a/src/backend/postmaster/walwriter.c +++ b/src/backend/postmaster/walwriter.c @@ -188,7 +188,7 @@ WalWriterMain(void) * to be repeated, and we don't want to be filling the error logs as * fast as we can. */ - pg_usleep(1000000L); + pg_msleep(1000, WAIT_EVENT_WAL_WRITER_MAIN); /* * Close all open files after any error. This is helpful on Windows, diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index d27ef2985d..63626187cb 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -3461,7 +3461,7 @@ WalSndWaitStopping(void) if (all_stopped) return; - pg_usleep(10000L); /* wait for 10 msec */ + pg_msleep(10, WAIT_EVENT_PG_SLEEP); } } diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index a027a8aabc..4f76d7ec19 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -2124,7 +2124,7 @@ retry: switch (error) { case ERROR_NO_SYSTEM_RESOURCES: - pg_usleep(1000L); + pg_msleep(1, WAIT_EVENT_PG_SLEEP); errno = EINTR; break; default: @@ -2222,7 +2222,7 @@ retry: switch (error) { case ERROR_NO_SYSTEM_RESOURCES: - pg_usleep(1000L); + pg_msleep(1, WAIT_EVENT_PG_SLEEP); errno = EINTR; break; default: diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index db889385b7..78d023c2fd 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -2264,3 +2264,17 @@ drain(void) } #endif + +/* + * Convenient wrapper around WaitLatch(NULL, ...). + */ +void +pg_msleep(int timeout, uint32 wait_event_info) +{ + Assert(timeout >= 0); + + (void) WaitLatch(NULL, + WL_EXIT_ON_PM_DEATH | WL_TIMEOUT, + timeout, + wait_event_info); +} diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 2a3da49b8f..f3740db9ab 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -3745,7 +3745,7 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared) (void) kill(autovac_pids[index], SIGTERM); /* ignore any error */ /* sleep, then try again */ - pg_usleep(100 * 1000L); /* 100ms */ + pg_msleep(100, WAIT_EVENT_PG_SLEEP); } return true; /* timed out, still conflicts */ diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index cc22d2e87c..f2035a9cf4 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -397,7 +397,7 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, * an unresponsive backend when system is heavily loaded. */ if (pid != 0) - pg_usleep(5000L); + pg_msleep(5, WAIT_EVENT_PG_SLEEP); } if (waitStart != 0 && (!logged_recovery_conflict || !waiting)) @@ -587,7 +587,7 @@ ResolveRecoveryConflictWithDatabase(Oid dbid) * Wait awhile for them to die so that we avoid flooding an * unresponsive backend when system is heavily loaded. */ - pg_usleep(10000); + pg_msleep(10, WAIT_EVENT_PG_SLEEP); } } diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c index ee9b89a672..65955d70bf 100644 --- a/src/backend/storage/lmgr/lmgr.c +++ b/src/backend/storage/lmgr/lmgr.c @@ -722,7 +722,7 @@ XactLockTableWait(TransactionId xid, Relation rel, ItemPointer ctid, * through, to avoid slowing down the normal case.) */ if (!first) - pg_usleep(1000L); + pg_msleep(1, WAIT_EVENT_PG_SLEEP); first = false; xid = SubTransGetTopmostTransaction(xid); } @@ -760,7 +760,7 @@ ConditionalXactLockTableWait(TransactionId xid) /* See XactLockTableWait about this case */ if (!first) - pg_usleep(1000L); + pg_msleep(1, WAIT_EVENT_PG_SLEEP); first = false; xid = SubTransGetTopmostTransaction(xid); } diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt index 3fabad96d9..2c6b527a72 100644 --- a/src/backend/utils/activity/wait_event_names.txt +++ b/src/backend/utils/activity/wait_event_names.txt @@ -154,6 +154,8 @@ Section: ClassName - WaitEventTimeout WAIT_EVENT_BASE_BACKUP_THROTTLE BaseBackupThrottle "Waiting during base backup when throttling activity." WAIT_EVENT_CHECKPOINT_WRITE_DELAY CheckpointWriteDelay "Waiting between writes while performing a checkpoint." WAIT_EVENT_PG_SLEEP PgSleep "Waiting due to a call to pg_sleep or a sibling function." +WAIT_EVENT_PRE_AUTH_DELAY PreAuthDelay "Waiting before authentication." +WAIT_EVENT_POST_AUTH_DELAY PostAuthDelay "Waiting after authentication." WAIT_EVENT_RECOVERY_APPLY_DELAY RecoveryApplyDelay "Waiting to apply WAL during recovery because of a delay setting." WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL RecoveryRetrieveRetryInterval "Waiting during recovery when WAL data is not available from any source (pg_wal, archive or stream)." WAIT_EVENT_REGISTER_SYNC_REQUEST RegisterSyncRequest "Waiting while sending synchronization requests to the checkpointer, because the request queue is full." diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index f31b85c013..8846a61aff 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -983,7 +983,7 @@ InitPostgres(const char *in_dbname, Oid dboid, /* Apply PostAuthDelay as soon as we've read all options */ if (PostAuthDelay > 0) - pg_usleep(PostAuthDelay * 1000000L); + pg_msleep(PostAuthDelay * 1000, WAIT_EVENT_POST_AUTH_DELAY); /* initialize client encoding */ InitializeClientEncoding(); @@ -1200,7 +1200,7 @@ InitPostgres(const char *in_dbname, Oid dboid, /* Apply PostAuthDelay as soon as we've read all options */ if (PostAuthDelay > 0) - pg_usleep(PostAuthDelay * 1000000L); + pg_msleep(PostAuthDelay * 1000, WAIT_EVENT_POST_AUTH_DELAY); /* * Initialize various default states that can't be set up until we've diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h index 99cc47874a..2b92d75e1f 100644 --- a/src/include/storage/latch.h +++ b/src/include/storage/latch.h @@ -190,5 +190,6 @@ extern int WaitLatchOrSocket(Latch *latch, int wakeEvents, extern void InitializeLatchWaitSet(void); extern int GetNumRegisteredWaitEvents(WaitEventSet *set); extern bool WaitEventSetCanReportClosed(void); +extern void pg_msleep(int timeout, uint32 wait_event_info); #endif /* LATCH_H */ -- 2.25.1 --qDbXVdCdHGoSgWSk--