background-write-clog.patch
application/octet-stream
Filename: background-write-clog.patch
Type: application/octet-stream
Part: 1
Message:
CLOG background writing
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/access/transam/clog.c | 37 | 0 |
| src/backend/access/transam/slru.c | 36 | 0 |
| src/backend/postmaster/bgwriter.c | 5 | 0 |
| src/include/access/clog.h | 1 | 0 |
| src/include/access/slru.h | 1 | 0 |
diff --git a/src/backend/access/transam/clog.c b/src/backend/access/transam/clog.c
index 33b5ca2..ac8d62b 100644
--- a/src/backend/access/transam/clog.c
+++ b/src/backend/access/transam/clog.c
@@ -37,6 +37,8 @@
#include "access/transam.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "storage/procarray.h"
+#include "utils/snapmgr.h"
/*
* Defines for CLOG page sizes. A page is the same BLCKSZ as is used
@@ -691,6 +693,41 @@ CLOGPagePrecedes(int page1, int page2)
/*
+ * Write dirty CLOG pages that won't receive any more updates.
+ *
+ * Return true if we do any work, and false otherwise.
+ */
+bool
+BackgroundWriteCLOG()
+{
+ int pageno;
+ bool result;
+ static SnapshotData DummySnapshotData;
+
+ /*
+ * Compute cutoff page - i.e. the point before which we don't expect to
+ * do any more writes. During recovery it may not be possible to compute
+ * a snapshot, so we just skip it in that case. (There might be a way
+ * to improve this.)
+ */
+ if (RecoveryInProgress())
+ return false;
+ GetSnapshotData(&DummySnapshotData);
+ pageno = TransactionIdToPage(RecentXmin);
+
+ /*
+ * The actual write is done by the SLRU code, but we must acquire the
+ * lock first.
+ */
+ LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
+ result = SimpleLruBackgroundFlush(ClogCtl, pageno);
+ LWLockRelease(CLogControlLock);
+
+ return result;
+}
+
+
+/*
* Write a ZEROPAGE xlog record
*/
static void
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index a8e3f19..6f9b993 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -1091,6 +1091,42 @@ SimpleLruFlush(SlruCtl ctl, bool checkpoint)
}
/*
+ * Write out a dirty page, if there's one that precedes the cutoff point.
+ *
+ * The intention here is that pageno should be chosen so that no further writes
+ * are expected in any preceding page. That way, we won't do background writes
+ * of pages that will be re-dirtied.
+ */
+bool
+SimpleLruBackgroundFlush(SlruCtl ctl, int pageno)
+{
+ SlruShared shared = ctl->shared;
+ int slotno;
+ int target_slot = -1;
+ int target_page = pageno;
+
+ /* Find the oldest valid, dirty page before the cutoff point. */
+ for (slotno = 0; slotno < shared->num_slots; slotno++)
+ {
+ if (shared->page_status[slotno] == SLRU_PAGE_VALID &&
+ shared->page_dirty[slotno] &&
+ ctl->PagePrecedes(shared->page_number[slotno], target_page))
+ {
+ target_slot = slotno;
+ target_page = shared->page_number[slotno];
+ }
+ }
+
+ /* No qualifying pages, so indicate that there's no work to be done. */
+ if (target_slot == -1)
+ return false;
+
+ /* Write the page. */
+ SlruInternalWritePage(ctl, target_slot, NULL);
+ return true;
+}
+
+/*
* Remove all segments before the one holding the passed page number
*/
void
diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c
index 59c539a..971f03f 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -42,6 +42,7 @@
#include <time.h>
#include <unistd.h>
+#include "access/clog.h"
#include "access/xlog_internal.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h"
@@ -285,6 +286,10 @@ BackgroundWriterMain(void)
ResetLatch(&MyProc->procLatch);
lapped = BgBufferSync();
+ /* Consider writing old CLOG pages. */
+ if (BackgroundWriteCLOG())
+ lapped = false;
+
if (lapped && !hibernating)
{
/*
diff --git a/src/include/access/clog.h b/src/include/access/clog.h
index bed3b8c..577df43 100644
--- a/src/include/access/clog.h
+++ b/src/include/access/clog.h
@@ -40,6 +40,7 @@ extern void StartupCLOG(void);
extern void TrimCLOG(void);
extern void ShutdownCLOG(void);
extern void CheckPointCLOG(void);
+extern bool BackgroundWriteCLOG(void);
extern void ExtendCLOG(TransactionId newestXact);
extern void TruncateCLOG(TransactionId oldestXact);
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index 41cd484..52dfe31 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -143,6 +143,7 @@ extern int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
extern int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno,
TransactionId xid);
extern void SimpleLruWritePage(SlruCtl ctl, int slotno);
+extern bool SimpleLruBackgroundFlush(SlruCtl ctl, int pageno);
extern void SimpleLruFlush(SlruCtl ctl, bool checkpoint);
extern void SimpleLruTruncate(SlruCtl ctl, int cutoffPage);