Fix waiting in RegisterSyncRequest().
authorThomas Munro
Wed, 16 Mar 2022 02:37:15 +0000 (15:37 +1300)
committerThomas Munro
Wed, 16 Mar 2022 02:37:15 +0000 (15:37 +1300)
If we run out of space in the checkpointer sync request queue (which is
hopefully rare on real systems, but common with very small buffer pool),
we wait for it to drain.  While waiting, we should report that as a wait
event so that users know what is going on, and also handle postmaster
death, since otherwise the loop might never terminate if the
checkpointer has exited.

Back-patch to 12.  Although the problem exists in earlier releases too,
the code is structured differently before 12 so I haven't gone any
further for now, in the absence of field complaints.

Reported-by: Andres Freund
Reviewed-by: Andres Freund
Discussion: https://postgr.es/m/20220226213942.nb7uvb2pamyu26dj%40alap3.anarazel.de

doc/src/sgml/monitoring.sgml
src/backend/postmaster/pgstat.c
src/backend/storage/sync/sync.c
src/include/pgstat.h

index 6abb29ecafebe958e854a0cfef10b692ad7de4ae..7b6ea8b24dfa63d5b61881ad5d71640ea4e9fb36 100644 (file)
@@ -2160,6 +2160,11 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   11:34   0:00 postgres: ser
       Waiting during recovery when WAL data is not available from any
        source (pg_wal, archive or stream).
      
+     
+      RegisterSyncRequest
+      Waiting while sending synchronization requests to the
+       checkpointer, because the request queue is full.
+     
      
       VacuumDelay
       Waiting in a cost-based vacuum delay point.
index 24e54d6766f59dc160c7f4de78656d79ce22c44e..1e2064456b05797347674d746934ca71e3b2517f 100644 (file)
@@ -3919,6 +3919,9 @@ pgstat_get_wait_timeout(WaitEventTimeout w)
        case WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL:
            event_name = "RecoveryRetrieveRetryInterval";
            break;
+       case WAIT_EVENT_REGISTER_SYNC_REQUEST:
+           event_name = "RegisterSyncRequest";
+           break;
        case WAIT_EVENT_VACUUM_DELAY:
            event_name = "VacuumDelay";
            break;
index 4ce2e687d3c8983a50862ea71146e3a348a665ed..d8c02220a296fd8432d3928ebd4f3c7e410c2fe6 100644 (file)
@@ -27,6 +27,7 @@
 #include "postmaster/bgwriter.h"
 #include "storage/bufmgr.h"
 #include "storage/ipc.h"
+#include "storage/latch.h"
 #include "storage/md.h"
 #include "utils/hsearch.h"
 #include "utils/inval.h"
@@ -585,7 +586,8 @@ RegisterSyncRequest(const FileTag *ftag, SyncRequestType type,
        if (ret || (!ret && !retryOnError))
            break;
 
-       pg_usleep(10000L);
+       WaitLatch(NULL, WL_EXIT_ON_PM_DEATH | WL_TIMEOUT, 10,
+                 WAIT_EVENT_REGISTER_SYNC_REQUEST);
    }
 
    return ret;
index c55dc1481ca5b4bbf3dd2acca621e06de6195c38..46fa42c2013c8466fdd06ebdcc3215e05167870a 100644 (file)
@@ -902,7 +902,8 @@ typedef enum
    WAIT_EVENT_PG_SLEEP,
    WAIT_EVENT_RECOVERY_APPLY_DELAY,
    WAIT_EVENT_RECOVERY_RETRIEVE_RETRY_INTERVAL,
-   WAIT_EVENT_VACUUM_DELAY
+   WAIT_EVENT_VACUUM_DELAY,
+   WAIT_EVENT_REGISTER_SYNC_REQUEST
 } WaitEventTimeout;
 
 /* ----------