]> granicus.if.org Git - postgresql/blobdiff - src/backend/access/transam/commit_ts.c
Phase 2 of pgindent updates.
[postgresql] / src / backend / access / transam / commit_ts.c
index e330105217d83c4bb7075cccb207a07d8d91d252..7646c23c4e7fa6e24a75cddb8263b95bf46bdd20 100644 (file)
@@ -3,7 +3,7 @@
  * commit_ts.c
  *             PostgreSQL commit timestamp manager
  *
- * This module is a pg_clog-like system that stores the commit timestamp
+ * This module is a pg_xact-like system that stores the commit timestamp
  * for each transaction.
  *
  * XLOG interactions: this module generates an XLOG record whenever a new
@@ -15,7 +15,7 @@
  * re-perform the status update on redo; so we need make no additional XLOG
  * entry here.
  *
- * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * src/backend/access/transam/commit_ts.c
@@ -32,6 +32,7 @@
 #include "funcapi.h"
 #include "miscadmin.h"
 #include "pg_trace.h"
+#include "storage/shmem.h"
 #include "utils/builtins.h"
 #include "utils/snapmgr.h"
 #include "utils/timestamp.h"
@@ -112,7 +113,7 @@ static bool CommitTsPagePrecedes(int page1, int page2);
 static void ActivateCommitTs(void);
 static void DeactivateCommitTs(void);
 static void WriteZeroPageXlogRec(int pageno);
-static void WriteTruncateXlogRec(int pageno);
+static void WriteTruncateXlogRec(int pageno, TransactionId oldestXid);
 static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids,
                                                 TransactionId *subxids, TimestampTz timestamp,
                                                 RepOriginId nodeid);
@@ -288,11 +289,18 @@ TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts,
        TransactionId oldestCommitTsXid;
        TransactionId newestCommitTsXid;
 
-       /* error if the given Xid doesn't normally commit */
-       if (!TransactionIdIsNormal(xid))
+       if (!TransactionIdIsValid(xid))
                ereport(ERROR,
                                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                errmsg("cannot retrieve commit timestamp for transaction %u", xid)));
+       else if (!TransactionIdIsNormal(xid))
+       {
+               /* frozen and bootstrap xids are always committed far in the past */
+               *ts = 0;
+               if (nodeid)
+                       *nodeid = 0;
+               return false;
+       }
 
        LWLockAcquire(CommitTsLock, LW_SHARED);
 
@@ -607,7 +615,7 @@ CommitTsParameterChange(bool newvalue, bool oldvalue)
 
 /*
  * Activate this module whenever necessary.
- *             This must happen during postmaster or standalong-backend startup,
+ *             This must happen during postmaster or standalone-backend startup,
  *             or during WAL replay anytime the track_commit_timestamp setting is
  *             changed in the master.
  *
@@ -738,6 +746,12 @@ ShutdownCommitTs(void)
 {
        /* Flush dirty CommitTs pages to disk */
        SimpleLruFlush(CommitTsCtl, false);
+
+       /*
+        * fsync pg_commit_ts to ensure that any files flushed previously are
+        * durably on disk.
+        */
+       fsync_fname("pg_commit_ts", true);
 }
 
 /*
@@ -748,6 +762,12 @@ CheckPointCommitTs(void)
 {
        /* Flush dirty CommitTs pages to disk */
        SimpleLruFlush(CommitTsCtl, true);
+
+       /*
+        * fsync pg_commit_ts to ensure that any files flushed previously are
+        * durably on disk.
+        */
+       fsync_fname("pg_commit_ts", true);
 }
 
 /*
@@ -816,7 +836,7 @@ TruncateCommitTs(TransactionId oldestXact)
                return;                                 /* nothing to remove */
 
        /* Write XLOG record */
-       WriteTruncateXlogRec(cutoffPage);
+       WriteTruncateXlogRec(cutoffPage, oldestXact);
 
        /* Now we can remove the old CommitTs segment(s) */
        SimpleLruTruncate(CommitTsCtl, cutoffPage);
@@ -843,6 +863,8 @@ SetCommitTsLimit(TransactionId oldestXact, TransactionId newestXact)
        else
        {
                Assert(ShmemVariableCache->newestCommitTsXid == InvalidTransactionId);
+               ShmemVariableCache->oldestCommitTsXid = oldestXact;
+               ShmemVariableCache->newestCommitTsXid = newestXact;
        }
        LWLockRelease(CommitTsLock);
 }
@@ -900,10 +922,15 @@ WriteZeroPageXlogRec(int pageno)
  * Write a TRUNCATE xlog record
  */
 static void
-WriteTruncateXlogRec(int pageno)
+WriteTruncateXlogRec(int pageno, TransactionId oldestXid)
 {
+       xl_commit_ts_truncate xlrec;
+
+       xlrec.pageno = pageno;
+       xlrec.oldestXid = oldestXid;
+
        XLogBeginInsert();
-       XLogRegisterData((char *) (&pageno), sizeof(int));
+       XLogRegisterData((char *) (&xlrec), SizeOfCommitTsTruncate);
        (void) XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_TRUNCATE);
 }
 
@@ -957,17 +984,17 @@ commit_ts_redo(XLogReaderState *record)
        }
        else if (info == COMMIT_TS_TRUNCATE)
        {
-               int                     pageno;
+               xl_commit_ts_truncate *trunc = (xl_commit_ts_truncate *) XLogRecGetData(record);
 
-               memcpy(&pageno, XLogRecGetData(record), sizeof(int));
+               AdvanceOldestCommitTsXid(trunc->oldestXid);
 
                /*
                 * During XLOG replay, latest_page_number isn't set up yet; insert a
                 * suitable value to bypass the sanity test in SimpleLruTruncate.
                 */
-               CommitTsCtl->shared->latest_page_number = pageno;
+               CommitTsCtl->shared->latest_page_number = trunc->pageno;
 
-               SimpleLruTruncate(CommitTsCtl, pageno);
+               SimpleLruTruncate(CommitTsCtl, trunc->pageno);
        }
        else if (info == COMMIT_TS_SETTS)
        {