From 27fc7000943bfddc4a4df3ca0fce6b02fb6a94b7 Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy Date: Tue, 6 Jul 2021 11:34:08 +0000 Subject: [PATCH v1] Use a WaitLatch for Pre and Post Auth Delay Instead of using pg_usleep() for waiting PostAuthDelay and PreAuthDelay, use a WaitLatch. This has the advantage that we will realize if the postmaster has been killed since the last time we decided to sleep. For PostAuthDelay, don't use WL_LATCH_SET. Because MyLatch, on which WaitLatch going to wait, could have been set in SwitchToSharedLatch() by InitProcess(). For PreAuthDelay, although there's no problem to use WL_LATCH_SET as MyLatch still points to local latch in BackendInitialize(), let's not use it as the MyLatch may point to shared latch later. --- doc/src/sgml/monitoring.sgml | 10 ++++++++++ src/backend/postmaster/autovacuum.c | 24 ++++++++++++++++++++++-- src/backend/postmaster/bgworker.c | 11 ++++++++++- src/backend/postmaster/postmaster.c | 11 ++++++++++- src/backend/utils/activity/wait_event.c | 6 ++++++ src/backend/utils/init/postinit.c | 22 ++++++++++++++++++++-- src/include/utils/wait_event.h | 2 ++ 7 files changed, 80 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 643e1ad49f..3f04704832 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -2228,6 +2228,16 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser Waiting due to a call to pg_sleep or a sibling function. + + PostAuthDelay + Waiting on connection startup after authentication to allow attach + from a debugger. + + + PreAuthDelay + Waiting on connection startup before authentication to allow + attach from a debugger. + RecoveryApplyDelay Waiting to apply WAL during recovery because of a delay diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 912ef9cb54..336dde07b2 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -446,8 +446,18 @@ AutoVacLauncherMain(int argc, char *argv[]) ereport(DEBUG1, (errmsg_internal("autovacuum launcher started"))); + /* Apply PostAuthDelay */ if (PostAuthDelay) - pg_usleep(PostAuthDelay * 1000000L); + { + /* + * PostAuthDelay will not get applied, if WL_LATCH_SET is used. This + * is because the latch could have been set initially. + */ + (void) WaitLatch(MyLatch, + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + PostAuthDelay * 1000L, + WAIT_EVENT_POST_AUTH_DELAY); + } SetProcessingMode(InitProcessing); @@ -1706,8 +1716,18 @@ AutoVacWorkerMain(int argc, char *argv[]) ereport(DEBUG1, (errmsg_internal("autovacuum: processing database \"%s\"", dbname))); + /* Apply PostAuthDelay */ if (PostAuthDelay) - pg_usleep(PostAuthDelay * 1000000L); + { + /* + * PostAuthDelay will not get applied, if WL_LATCH_SET is used. + * This is because the latch could have been set initially. + */ + (void) WaitLatch(MyLatch, + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + PostAuthDelay * 1000L, + 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 c40410d73e..9c97a5d1f6 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -763,7 +763,16 @@ StartBackgroundWorker(void) /* Apply PostAuthDelay */ if (PostAuthDelay > 0) - pg_usleep(PostAuthDelay * 1000000L); + { + /* + * PostAuthDelay will not get applied, if WL_LATCH_SET is used. This + * is because the latch could have been set initially. + */ + (void) WaitLatch(MyLatch, + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + PostAuthDelay * 1000L, + WAIT_EVENT_POST_AUTH_DELAY); + } /* * Set up signal handlers. diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 5a050898fe..f880eaf682 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -4332,7 +4332,16 @@ BackendInitialize(Port *port) * is not honored until after authentication.) */ if (PreAuthDelay > 0) - pg_usleep(PreAuthDelay * 1000000L); + { + /* + * Do not use WL_LATCH_SET during backend initialization because the + * MyLatch may point to shared latch later. + */ + (void) WaitLatch(MyLatch, + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + PreAuthDelay * 1000L, + 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/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c index ef7e6bfb77..9b2835bef8 100644 --- a/src/backend/utils/activity/wait_event.c +++ b/src/backend/utils/activity/wait_event.c @@ -476,6 +476,12 @@ pgstat_get_wait_timeout(WaitEventTimeout w) case WAIT_EVENT_PG_SLEEP: event_name = "PgSleep"; break; + case WAIT_EVENT_POST_AUTH_DELAY: + event_name = "PostAuthDelay"; + break; + case WAIT_EVENT_PRE_AUTH_DELAY: + event_name = "PreAuthDelay"; + break; case WAIT_EVENT_RECOVERY_APPLY_DELAY: event_name = "RecoveryApplyDelay"; break; diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c index 51d1bbef30..c5491f635f 100644 --- a/src/backend/utils/init/postinit.c +++ b/src/backend/utils/init/postinit.c @@ -849,7 +849,16 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, /* Apply PostAuthDelay as soon as we've read all options */ if (PostAuthDelay > 0) - pg_usleep(PostAuthDelay * 1000000L); + { + /* + * PostAuthDelay will not get applied, if WL_LATCH_SET is used. + * This is because the latch could have been set initially. + */ + (void) WaitLatch(MyLatch, + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + PostAuthDelay * 1000L, + WAIT_EVENT_POST_AUTH_DELAY); + } /* initialize client encoding */ InitializeClientEncoding(); @@ -1055,7 +1064,16 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username, /* Apply PostAuthDelay as soon as we've read all options */ if (PostAuthDelay > 0) - pg_usleep(PostAuthDelay * 1000000L); + { + /* + * PostAuthDelay will not get applied, if WL_LATCH_SET is used. This + * is because the latch could have been set initially. + */ + (void) WaitLatch(MyLatch, + WL_TIMEOUT | WL_EXIT_ON_PM_DEATH, + PostAuthDelay * 1000L, + WAIT_EVENT_POST_AUTH_DELAY); + } /* * Initialize various default states that can't be set up until we've diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h index 6007827b44..1154f537b3 100644 --- a/src/include/utils/wait_event.h +++ b/src/include/utils/wait_event.h @@ -138,6 +138,8 @@ typedef enum { WAIT_EVENT_BASE_BACKUP_THROTTLE = PG_WAIT_TIMEOUT, WAIT_EVENT_PG_SLEEP, + WAIT_EVENT_POST_AUTH_DELAY, + WAIT_EVENT_PRE_AUTH_DELAY, WAIT_EVENT_RECOVERY_APPLY_DELAY, WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL, WAIT_EVENT_VACUUM_DELAY, -- 2.25.1