I wrote: >>> (IIRC only the Async module is doing that.) > Hm, maybe we can fix that.
Yeah, it's quite easy to make async.c postpone its first write to the async SLRU. This seems like a win all around, because many installations don't use NOTIFY and so will never need to do that work at all. In installations that do use notify, this costs an extra instruction or two per NOTIFY, but that's down in the noise. I got through check-world with the assertion shown that we are not counting any SLRU operations in the postmaster. Don't know if we want to commit that or not --- any thoughts? regards, tom lane
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c index 0c9d20e..6ecea01 100644 --- a/src/backend/commands/async.c +++ b/src/backend/commands/async.c @@ -200,7 +200,10 @@ typedef struct QueuePosition } while (0) #define QUEUE_POS_EQUAL(x,y) \ - ((x).page == (y).page && (x).offset == (y).offset) + ((x).page == (y).page && (x).offset == (y).offset) + +#define QUEUE_POS_IS_ZERO(x) \ + ((x).page == 0 && (x).offset == 0) /* choose logically smaller QueuePosition */ #define QUEUE_POS_MIN(x,y) \ @@ -515,7 +518,6 @@ void AsyncShmemInit(void) { bool found; - int slotno; Size size; /* @@ -562,13 +564,6 @@ AsyncShmemInit(void) * During start or reboot, clean out the pg_notify directory. */ (void) SlruScanDirectory(AsyncCtl, SlruScanDirCbDeleteAll, NULL); - - /* Now initialize page zero to empty */ - LWLockAcquire(AsyncCtlLock, LW_EXCLUSIVE); - slotno = SimpleLruZeroPage(AsyncCtl, QUEUE_POS_PAGE(QUEUE_HEAD)); - /* This write is just to verify that pg_notify/ is writable */ - SimpleLruWritePage(AsyncCtl, slotno); - LWLockRelease(AsyncCtlLock); } } @@ -1470,9 +1465,18 @@ asyncQueueAddEntries(ListCell *nextNotify) */ queue_head = QUEUE_HEAD; - /* Fetch the current page */ + /* + * If this is the first write since the postmaster started, we need to + * initialize the first page of the async SLRU. Otherwise, the current + * page should be initialized already, so just fetch it. + */ pageno = QUEUE_POS_PAGE(queue_head); - slotno = SimpleLruReadPage(AsyncCtl, pageno, true, InvalidTransactionId); + if (QUEUE_POS_IS_ZERO(queue_head)) + slotno = SimpleLruZeroPage(AsyncCtl, pageno); + else + slotno = SimpleLruReadPage(AsyncCtl, pageno, true, + InvalidTransactionId); + /* Note we mark the page dirty before writing in it */ AsyncCtl->shared->page_dirty[slotno] = true; diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index 80a06e5..e3c808b 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -6729,6 +6729,8 @@ slru_entry(int slru_idx) { Assert((slru_idx >= 0) && (slru_idx < SLRU_NUM_ELEMENTS)); + Assert(IsUnderPostmaster || !IsPostmasterEnvironment); + return &SLRUStats[slru_idx]; }