]> granicus.if.org Git - postgresql/commitdiff
Avoid SnapshotResetXmin() during AtEOXact_Snapshot()
authorSimon Riggs <simon@2ndQuadrant.com>
Thu, 6 Apr 2017 12:31:52 +0000 (08:31 -0400)
committerSimon Riggs <simon@2ndQuadrant.com>
Thu, 6 Apr 2017 12:31:52 +0000 (08:31 -0400)
For normal commits and aborts we already reset PgXact->xmin,
so we can simply avoid running SnapshotResetXmin() twice.

During performance tests by Alexander Korotkov, diagnosis
by Andres Freund showed PgXact array as a bottleneck. After
manual analysis by me of the code paths that touch those
memory locations, I was able to identify extraneous code
in the main transaction commit path.

Avoiding touching highly contented shmem improves concurrent
performance slightly on all workloads, confirmed by tests
run by Ashutosh Sharma and Alexander Korotkov.

Simon Riggs

Discussion: CANP8+jJdXE9b+b9F8CQT-LuxxO0PBCB-SZFfMVAdp+akqo4zfg@mail.gmail.com

src/backend/access/transam/xact.c
src/backend/utils/time/snapmgr.c
src/include/utils/snapmgr.h

index 6f614e4fad07c8c7b0ff0f6eab262dcbb7357b20..84409ea956284b1c19417571ef9bd32915580671 100644 (file)
@@ -2137,7 +2137,7 @@ CommitTransaction(void)
        AtEOXact_ComboCid();
        AtEOXact_HashTables(true);
        AtEOXact_PgStat(true);
-       AtEOXact_Snapshot(true);
+       AtEOXact_Snapshot(true, false);
        AtCommit_ApplyLauncher();
        pgstat_report_xact_timestamp(0);
 
@@ -2409,7 +2409,7 @@ PrepareTransaction(void)
        AtEOXact_ComboCid();
        AtEOXact_HashTables(true);
        /* don't call AtEOXact_PgStat here; we fixed pgstat state above */
-       AtEOXact_Snapshot(true);
+       AtEOXact_Snapshot(true, true);
        pgstat_report_xact_timestamp(0);
 
        CurrentResourceOwner = NULL;
@@ -2640,7 +2640,7 @@ CleanupTransaction(void)
         * do abort cleanup processing
         */
        AtCleanup_Portals();            /* now safe to release portal memory */
-       AtEOXact_Snapshot(false);       /* and release the transaction's snapshots */
+       AtEOXact_Snapshot(false, false); /* and release the transaction's snapshots */
 
        CurrentResourceOwner = NULL;    /* and resource owner */
        if (TopTransactionResourceOwner)
index ecc32cb3fe76f31ddce840adc665eb535950b0f8..dff3d51ec3c1c40ba7d21c794fa653a7d56214ad 100644 (file)
@@ -1051,7 +1051,7 @@ AtSubAbort_Snapshot(int level)
  *             Snapshot manager's cleanup function for end of transaction
  */
 void
-AtEOXact_Snapshot(bool isCommit)
+AtEOXact_Snapshot(bool isCommit, bool isPrepare)
 {
        /*
         * In transaction-snapshot mode we must release our privately-managed
@@ -1136,7 +1136,17 @@ AtEOXact_Snapshot(bool isCommit)
 
        FirstSnapshotSet = false;
 
-       SnapshotResetXmin();
+       /*
+        * During normal commit and abort processing, we call
+        * ProcArrayEndTransaction() or ProcArrayClearTransaction() to
+        * reset the PgXact->xmin. That call happens prior to the call to
+        * AtEOXact_Snapshot(), so we need not touch xmin here at all,
+        * accept when we are preparing a transaction.
+        */
+       if (isPrepare)
+               SnapshotResetXmin();
+
+       Assert(isPrepare || MyPgXact->xmin == 0);
 }
 
 
index 86c48d9c8eff6ff90bb9635a57d60c2bd9aa4597..2f8d4fd4a0ca531c85d504888e080cb9b4ec0c4e 100644 (file)
@@ -85,7 +85,7 @@ extern void UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner);
 
 extern void AtSubCommit_Snapshot(int level);
 extern void AtSubAbort_Snapshot(int level);
-extern void AtEOXact_Snapshot(bool isCommit);
+extern void AtEOXact_Snapshot(bool isCommit, bool isPrepare);
 
 extern void ImportSnapshot(const char *idstr);
 extern bool XactHasExportedSnapshots(void);