skip-commit-record.patch
application/octet-stream
Filename: skip-commit-record.patch
Type: application/octet-stream
Part: 0
Message:
write scalability
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index e8821f7..f953537 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -960,9 +960,6 @@ RecordTransactionCommit(void)
}
else
{
- /*
- * Begin commit critical section and insert the commit XLOG record.
- */
/* Tell bufmgr and smgr to prepare for commit */
BufmgrCommit();
@@ -1046,7 +1043,13 @@ RecordTransactionCommit(void)
(void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT, rdata);
}
- else
+ /*
+ * If we created any XLOG entries, we must emit a commit record of
+ * some kind, but can use the compact format. We also need to do this
+ * in Hot Standby mode, to avoid confusing the KnownAssignedXids
+ * machinery.
+ */
+ else if (wrote_xlog || XLogStandbyInfoActive())
{
XLogRecData rdata[2];
int lastrdata = 0;
@@ -1069,6 +1072,20 @@ RecordTransactionCommit(void)
(void) XLogInsert(RM_XACT_ID, XLOG_XACT_COMMIT_COMPACT, rdata);
}
+ else
+ {
+ /*
+ * It seems we don't need a commit record after all. Go ahead
+ * and mark CLOG without flushing anything. This update might
+ * get lost if we crash before the pages physically hit the disk,
+ * but since whatever modifications the transactions made weren't
+ * WAL-logged either, we won't be losing anything that matters.
+ * In particular, any temporary or unlogged tables we've written
+ * will be gone after a crash recovery anyway.
+ */
+ TransactionIdCommitTree(xid, nchildren, children);
+ goto cleanup;
+ }
}
/*
@@ -1078,13 +1095,7 @@ RecordTransactionCommit(void)
* case can arise if the current transaction wrote only to temporary
* and/or unlogged tables. In case of a crash, the loss of such a
* transaction will be irrelevant since temp tables will be lost anyway,
- * and unlogged tables will be truncated. (Given the foregoing, you might
- * think that it would be unnecessary to emit the XLOG record at all in
- * this case, but we don't currently try to do that. It would certainly
- * cause problems at least in Hot Standby mode, where the
- * KnownAssignedXids machinery requires tracking every XID assignment. It
- * might be OK to skip it only when wal_level < hot_standby, but for now
- * we don't.)
+ * and unlogged tables will be truncated.
*
* However, if we're doing cleanup of any non-temp rels or committing any
* command that wanted to force sync commit, then we must flush XLOG
@@ -1152,6 +1163,7 @@ RecordTransactionCommit(void)
TransactionIdAsyncCommitTree(xid, nchildren, children, XactLastRecEnd);
}
+cleanup:
/*
* If we entered a commit critical section, leave it now, and let
* checkpoints proceed.
@@ -1160,10 +1172,10 @@ RecordTransactionCommit(void)
{
MyProc->inCommit = false;
END_CRIT_SECTION();
- }
- /* Compute latestXid while we have the child XIDs handy */
- latestXid = TransactionIdLatest(xid, nchildren, children);
+ /* Compute latestXid while we have the child XIDs handy */
+ latestXid = TransactionIdLatest(xid, nchildren, children);
+ }
/*
* Wait for synchronous replication, if required.
@@ -1171,12 +1183,12 @@ RecordTransactionCommit(void)
* Note that at this stage we have marked clog, but still show as running
* in the procarray and continue to hold locks.
*/
- SyncRepWaitForLSN(XactLastRecEnd);
+ if (wrote_xlog)
+ SyncRepWaitForLSN(XactLastRecEnd);
/* Reset XactLastRecEnd until the next transaction writes something */
XactLastRecEnd.xrecoff = 0;
-cleanup:
/* Clean up local data */
if (rels)
pfree(rels);