bgwriter_clean_stats.patch
application/octet-stream
Filename: bgwriter_clean_stats.patch
Type: application/octet-stream
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/storage/buffer/bufmgr.c | 33 | 1 |
| src/include/storage/buf_internals.h | 1 | 0 |
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 3924a51..f4267ed 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -75,6 +75,12 @@ double bgwriter_lru_multiplier = 2.0;
*/
int target_prefetch_pages = 0;
+/*
+ * Counters to measure bgwriter effectiveness.
+ */
+uint64 bgwriter_clean_dirty_before_evict = 0;
+uint64 bgwriter_clean_evict_before_dirty = 0;
+
/* local state for StartBufferIO and related functions */
static volatile BufferDesc *InProgressBuf = NULL;
static bool IsForInput;
@@ -804,7 +810,9 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
* 1 so that the buffer can survive one clock-sweep pass.)
*/
buf->tag = newTag;
- buf->flags &= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_CHECKPOINT_NEEDED | BM_IO_ERROR | BM_PERMANENT);
+ if ((buf->flags & BM_BGWRITER_CLEANED) != 0)
+ ++bgwriter_clean_evict_before_dirty;
+ buf->flags &= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_CHECKPOINT_NEEDED | BM_IO_ERROR | BM_PERMANENT | BM_BGWRITER_CLEANED);
if (relpersistence == RELPERSISTENCE_PERMANENT)
buf->flags |= BM_TAG_VALID | BM_PERMANENT;
else
@@ -976,6 +984,11 @@ MarkBufferDirty(Buffer buffer)
if (!(bufHdr->flags & BM_DIRTY))
dirtied = true;
+ if ((bufHdr->flags & BM_BGWRITER_CLEANED) != 0)
+ {
+ ++bgwriter_clean_dirty_before_evict;
+ bufHdr->flags &= ~BM_BGWRITER_CLEANED;
+ }
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
@@ -1650,6 +1663,13 @@ SyncOneBuffer(int buf_id, bool skip_recently_used)
}
/*
+ * If skip_recently_used = true, then this is the bgwriter doing cleaning.
+ * If it's false, this is a checkpoint, so we don't set the flag.
+ */
+ if (skip_recently_used)
+ bufHdr->flags |= BM_BGWRITER_CLEANED;
+
+ /*
* Pin it, share-lock it, write it. (FlushBuffer will do nothing if the
* buffer is clean by the time we've locked it.)
*/
@@ -1729,6 +1749,11 @@ AtProcExit_Buffers(int code, Datum arg)
/* localbuf.c needs a chance too */
AtProcExit_LocalBuffers();
+
+ elog(LOG,
+ "bgwriter_clean: " UINT64_FORMAT " evict-before-dirty, "
+ UINT64_FORMAT " dirty-before-evict",
+ bgwriter_clean_evict_before_dirty, bgwriter_clean_dirty_before_evict);
}
/*
@@ -2360,7 +2385,14 @@ SetBufferCommitInfoNeedsSave(Buffer buffer)
LockBufHdr(bufHdr);
Assert(bufHdr->refcount > 0);
if (!(bufHdr->flags & BM_DIRTY))
+ {
dirtied = true;
+ if ((bufHdr->flags & BM_BGWRITER_CLEANED) != 0)
+ {
+ ++bgwriter_clean_dirty_before_evict;
+ bufHdr->flags &= ~BM_BGWRITER_CLEANED;
+ }
+ }
bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
UnlockBufHdr(bufHdr);
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index e43719e..dc70530 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -39,6 +39,7 @@
#define BM_CHECKPOINT_NEEDED (1 << 7) /* must write for checkpoint */
#define BM_PERMANENT (1 << 8) /* permanent relation (not
* unlogged) */
+#define BM_BGWRITER_CLEANED (1 << 9) /* bg writer has cleaned it */
typedef bits16 BufFlags;