PostgreSQL Source Code  git master
commit_ts.c File Reference
#include "postgres.h"
#include "access/commit_ts.h"
#include "access/htup_details.h"
#include "access/slru.h"
#include "access/transam.h"
#include "access/xloginsert.h"
#include "access/xlogutils.h"
#include "catalog/pg_type.h"
#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"
Include dependency graph for commit_ts.c:

Go to the source code of this file.

Data Structures

struct  CommitTimestampEntry
 
struct  CommitTimestampShared
 

Macros

#define SizeOfCommitTimestampEntry
 
#define COMMIT_TS_XACTS_PER_PAGE    (BLCKSZ / SizeOfCommitTimestampEntry)
 
#define TransactionIdToCTsPage(xid)    ((xid) / (TransactionId) COMMIT_TS_XACTS_PER_PAGE)
 
#define TransactionIdToCTsEntry(xid)    ((xid) % (TransactionId) COMMIT_TS_XACTS_PER_PAGE)
 
#define CommitTsCtl   (&CommitTsCtlData)
 

Typedefs

typedef struct CommitTimestampEntry CommitTimestampEntry
 
typedef struct CommitTimestampShared CommitTimestampShared
 

Functions

static void SetXidCommitTsInPage (TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz ts, RepOriginId nodeid, int pageno)
 
static void TransactionIdSetCommitTs (TransactionId xid, TimestampTz ts, RepOriginId nodeid, int slotno)
 
static void error_commit_ts_disabled (void)
 
static int ZeroCommitTsPage (int pageno, bool writeXlog)
 
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, TransactionId oldestXid)
 
void TransactionTreeSetCommitTsData (TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid)
 
bool TransactionIdGetCommitTsData (TransactionId xid, TimestampTz *ts, RepOriginId *nodeid)
 
TransactionId GetLatestCommitTsData (TimestampTz *ts, RepOriginId *nodeid)
 
Datum pg_xact_commit_timestamp (PG_FUNCTION_ARGS)
 
Datum pg_last_committed_xact (PG_FUNCTION_ARGS)
 
Datum pg_xact_commit_timestamp_origin (PG_FUNCTION_ARGS)
 
Size CommitTsShmemBuffers (void)
 
Size CommitTsShmemSize (void)
 
void CommitTsShmemInit (void)
 
void BootStrapCommitTs (void)
 
void StartupCommitTs (void)
 
void CompleteCommitTsInitialization (void)
 
void CommitTsParameterChange (bool newvalue, bool oldvalue)
 
void CheckPointCommitTs (void)
 
void ExtendCommitTs (TransactionId newestXact)
 
void TruncateCommitTs (TransactionId oldestXact)
 
void SetCommitTsLimit (TransactionId oldestXact, TransactionId newestXact)
 
void AdvanceOldestCommitTsXid (TransactionId oldestXact)
 
void commit_ts_redo (XLogReaderState *record)
 
int committssyncfiletag (const FileTag *ftag, char *path)
 

Variables

static SlruCtlData CommitTsCtlData
 
static CommitTimestampSharedcommitTsShared
 
bool track_commit_timestamp
 

Macro Definition Documentation

◆ COMMIT_TS_XACTS_PER_PAGE

#define COMMIT_TS_XACTS_PER_PAGE    (BLCKSZ / SizeOfCommitTimestampEntry)

Definition at line 65 of file commit_ts.c.

◆ CommitTsCtl

#define CommitTsCtl   (&CommitTsCtlData)

Definition at line 78 of file commit_ts.c.

◆ SizeOfCommitTimestampEntry

#define SizeOfCommitTimestampEntry
Value:
(offsetof(CommitTimestampEntry, nodeid) + \
sizeof(RepOriginId))
uint16 RepOriginId
Definition: xlogdefs.h:65

Definition at line 62 of file commit_ts.c.

◆ TransactionIdToCTsEntry

#define TransactionIdToCTsEntry (   xid)     ((xid) % (TransactionId) COMMIT_TS_XACTS_PER_PAGE)

Definition at line 70 of file commit_ts.c.

◆ TransactionIdToCTsPage

#define TransactionIdToCTsPage (   xid)     ((xid) / (TransactionId) COMMIT_TS_XACTS_PER_PAGE)

Definition at line 68 of file commit_ts.c.

Typedef Documentation

◆ CommitTimestampEntry

◆ CommitTimestampShared

Function Documentation

◆ ActivateCommitTs()

static void ActivateCommitTs ( void  )
static

Definition at line 680 of file commit_ts.c.

681 {
682  TransactionId xid;
683  int pageno;
684 
685  /* If we've done this already, there's nothing to do */
686  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
688  {
689  LWLockRelease(CommitTsLock);
690  return;
691  }
692  LWLockRelease(CommitTsLock);
693 
695  pageno = TransactionIdToCTsPage(xid);
696 
697  /*
698  * Re-Initialize our idea of the latest page number.
699  */
700  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
701  CommitTsCtl->shared->latest_page_number = pageno;
702  LWLockRelease(CommitTsSLRULock);
703 
704  /*
705  * If CommitTs is enabled, but it wasn't in the previous server run, we
706  * need to set the oldest and newest values to the next Xid; that way, we
707  * will not try to read data that might not have been set.
708  *
709  * XXX does this have a problem if a server is started with commitTs
710  * enabled, then started with commitTs disabled, then restarted with it
711  * enabled again? It doesn't look like it does, because there should be a
712  * checkpoint that sets the value to InvalidTransactionId at end of
713  * recovery; and so any chance of injecting new transactions without
714  * CommitTs values would occur after the oldestCommitTsXid has been set to
715  * Invalid temporarily.
716  */
717  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
719  {
722  }
723  LWLockRelease(CommitTsLock);
724 
725  /* Create the current segment file, if necessary */
727  {
728  int slotno;
729 
730  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
731  slotno = ZeroCommitTsPage(pageno, false);
733  Assert(!CommitTsCtl->shared->page_dirty[slotno]);
734  LWLockRelease(CommitTsSLRULock);
735  }
736 
737  /* Change the activation status in shared memory. */
738  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
740  LWLockRelease(CommitTsLock);
741 }
uint32 TransactionId
Definition: c.h:588
static CommitTimestampShared * commitTsShared
Definition: commit_ts.c:98
static int ZeroCommitTsPage(int pageno, bool writeXlog)
Definition: commit_ts.c:590
#define CommitTsCtl
Definition: commit_ts.c:78
#define TransactionIdToCTsPage(xid)
Definition: commit_ts.c:68
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1194
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1802
@ LW_EXCLUSIVE
Definition: lwlock.h:112
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:615
bool SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int pageno)
Definition: slru.c:627
FullTransactionId nextXid
Definition: transam.h:220
TransactionId newestCommitTsXid
Definition: transam.h:233
TransactionId oldestCommitTsXid
Definition: transam.h:232
static TransactionId ReadNextTransactionId(void)
Definition: transam.h:315
#define InvalidTransactionId
Definition: transam.h:31
#define XidFromFullTransactionId(x)
Definition: transam.h:48
VariableCache ShmemVariableCache
Definition: varsup.c:34

References Assert(), CommitTimestampShared::commitTsActive, CommitTsCtl, commitTsShared, InvalidTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::newestCommitTsXid, VariableCacheData::nextXid, VariableCacheData::oldestCommitTsXid, ReadNextTransactionId(), ShmemVariableCache, SimpleLruDoesPhysicalPageExist(), SimpleLruWritePage(), TransactionIdToCTsPage, XidFromFullTransactionId, and ZeroCommitTsPage().

Referenced by CommitTsParameterChange(), CompleteCommitTsInitialization(), and StartupCommitTs().

◆ AdvanceOldestCommitTsXid()

void AdvanceOldestCommitTsXid ( TransactionId  oldestXact)

Definition at line 905 of file commit_ts.c.

906 {
907  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
911  LWLockRelease(CommitTsLock);
912 }
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:273

References InvalidTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::oldestCommitTsXid, ShmemVariableCache, and TransactionIdPrecedes().

Referenced by commit_ts_redo(), and vac_truncate_clog().

◆ BootStrapCommitTs()

void BootStrapCommitTs ( void  )

Definition at line 571 of file commit_ts.c.

572 {
573  /*
574  * Nothing to do here at present, unlike most other SLRU modules; segments
575  * are created when the server is started with this module enabled. See
576  * ActivateCommitTs.
577  */
578 }

Referenced by BootStrapXLOG().

◆ CheckPointCommitTs()

void CheckPointCommitTs ( void  )

Definition at line 792 of file commit_ts.c.

793 {
794  /*
795  * Write dirty CommitTs pages to disk. This may result in sync requests
796  * queued for later handling by ProcessSyncRequests(), as part of the
797  * checkpoint.
798  */
800 }
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1157

References CommitTsCtl, and SimpleLruWriteAll().

Referenced by CheckPointGuts().

◆ commit_ts_redo()

void commit_ts_redo ( XLogReaderState record)

Definition at line 985 of file commit_ts.c.

986 {
987  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
988 
989  /* Backup blocks are not used in commit_ts records */
990  Assert(!XLogRecHasAnyBlockRefs(record));
991 
992  if (info == COMMIT_TS_ZEROPAGE)
993  {
994  int pageno;
995  int slotno;
996 
997  memcpy(&pageno, XLogRecGetData(record), sizeof(int));
998 
999  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
1000 
1001  slotno = ZeroCommitTsPage(pageno, false);
1003  Assert(!CommitTsCtl->shared->page_dirty[slotno]);
1004 
1005  LWLockRelease(CommitTsSLRULock);
1006  }
1007  else if (info == COMMIT_TS_TRUNCATE)
1008  {
1010 
1012 
1013  /*
1014  * During XLOG replay, latest_page_number isn't set up yet; insert a
1015  * suitable value to bypass the sanity test in SimpleLruTruncate.
1016  */
1017  CommitTsCtl->shared->latest_page_number = trunc->pageno;
1018 
1020  }
1021  else
1022  elog(PANIC, "commit_ts_redo: unknown op code %u", info);
1023 }
unsigned char uint8
Definition: c.h:440
void AdvanceOldestCommitTsXid(TransactionId oldestXact)
Definition: commit_ts.c:905
#define COMMIT_TS_ZEROPAGE
Definition: commit_ts.h:47
#define COMMIT_TS_TRUNCATE
Definition: commit_ts.h:48
#define PANIC
Definition: elog.h:38
void SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
Definition: slru.c:1227
TransactionId oldestXid
Definition: commit_ts.h:64
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:411
#define XLogRecGetData(decoder)
Definition: xlogreader.h:416
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:418
#define XLR_INFO_MASK
Definition: xlogrecord.h:62

References AdvanceOldestCommitTsXid(), Assert(), COMMIT_TS_TRUNCATE, COMMIT_TS_ZEROPAGE, CommitTsCtl, elog(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_commit_ts_truncate::oldestXid, xl_commit_ts_truncate::pageno, PANIC, SimpleLruTruncate(), SimpleLruWritePage(), XLogRecGetData, XLogRecGetInfo, XLogRecHasAnyBlockRefs, XLR_INFO_MASK, and ZeroCommitTsPage().

◆ CommitTsPagePrecedes()

static bool CommitTsPagePrecedes ( int  page1,
int  page2 
)
static

Definition at line 939 of file commit_ts.c.

940 {
941  TransactionId xid1;
942  TransactionId xid2;
943 
944  xid1 = ((TransactionId) page1) * COMMIT_TS_XACTS_PER_PAGE;
945  xid1 += FirstNormalTransactionId + 1;
946  xid2 = ((TransactionId) page2) * COMMIT_TS_XACTS_PER_PAGE;
947  xid2 += FirstNormalTransactionId + 1;
948 
949  return (TransactionIdPrecedes(xid1, xid2) &&
951 }
#define COMMIT_TS_XACTS_PER_PAGE
Definition: commit_ts.c:65
#define FirstNormalTransactionId
Definition: transam.h:34

References COMMIT_TS_XACTS_PER_PAGE, FirstNormalTransactionId, and TransactionIdPrecedes().

Referenced by CommitTsShmemInit().

◆ CommitTsParameterChange()

void CommitTsParameterChange ( bool  newvalue,
bool  oldvalue 
)

Definition at line 639 of file commit_ts.c.

640 {
641  /*
642  * If the commit_ts module is disabled in this server and we get word from
643  * the primary server that it is enabled there, activate it so that we can
644  * replay future WAL records involving it; also mark it as active on
645  * pg_control. If the old value was already set, we already did this, so
646  * don't do anything.
647  *
648  * If the module is disabled in the primary, disable it here too, unless
649  * the module is enabled locally.
650  *
651  * Note this only runs in the recovery process, so an unlocked read is
652  * fine.
653  */
654  if (newvalue)
655  {
658  }
659  else if (commitTsShared->commitTsActive)
661 }
static void DeactivateCommitTs(void)
Definition: commit_ts.c:754
static void ActivateCommitTs(void)
Definition: commit_ts.c:680

References ActivateCommitTs(), CommitTimestampShared::commitTsActive, commitTsShared, and DeactivateCommitTs().

Referenced by xlog_redo().

◆ CommitTsShmemBuffers()

Size CommitTsShmemBuffers ( void  )

Definition at line 516 of file commit_ts.c.

517 {
518  return Min(256, Max(4, NBuffers / 256));
519 }
#define Min(x, y)
Definition: c.h:937
#define Max(x, y)
Definition: c.h:931
int NBuffers
Definition: globals.c:136

References Max, Min, and NBuffers.

Referenced by CommitTsShmemInit(), and CommitTsShmemSize().

◆ CommitTsShmemInit()

void CommitTsShmemInit ( void  )

Definition at line 536 of file commit_ts.c.

537 {
538  bool found;
539 
540  CommitTsCtl->PagePrecedes = CommitTsPagePrecedes;
542  CommitTsSLRULock, "pg_commit_ts",
546 
547  commitTsShared = ShmemInitStruct("CommitTs shared",
548  sizeof(CommitTimestampShared),
549  &found);
550 
551  if (!IsUnderPostmaster)
552  {
553  Assert(!found);
554 
559  }
560  else
561  Assert(found);
562 }
Size CommitTsShmemBuffers(void)
Definition: commit_ts.c:516
static bool CommitTsPagePrecedes(int page1, int page2)
Definition: commit_ts.c:939
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:151
bool IsUnderPostmaster
Definition: globals.c:113
@ LWTRANCHE_COMMITTS_BUFFER
Definition: lwlock.h:178
#define InvalidRepOriginId
Definition: origin.h:33
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:396
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, LWLock *ctllock, const char *subdir, int tranche_id, SyncRequestHandler sync_handler)
Definition: slru.c:188
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition: slru.h:156
TimestampTz time
Definition: commit_ts.c:58
RepOriginId nodeid
Definition: commit_ts.c:59
CommitTimestampEntry dataLastCommit
Definition: commit_ts.c:94
TransactionId xidLastCommit
Definition: commit_ts.c:93
@ SYNC_HANDLER_COMMIT_TS
Definition: sync.h:39

References Assert(), COMMIT_TS_XACTS_PER_PAGE, CommitTimestampShared::commitTsActive, CommitTsCtl, CommitTsPagePrecedes(), commitTsShared, CommitTsShmemBuffers(), CommitTimestampShared::dataLastCommit, InvalidRepOriginId, InvalidTransactionId, IsUnderPostmaster, LWTRANCHE_COMMITTS_BUFFER, CommitTimestampEntry::nodeid, ShmemInitStruct(), SimpleLruInit(), SlruPagePrecedesUnitTests, SYNC_HANDLER_COMMIT_TS, CommitTimestampEntry::time, TIMESTAMP_NOBEGIN, and CommitTimestampShared::xidLastCommit.

Referenced by CreateSharedMemoryAndSemaphores().

◆ CommitTsShmemSize()

Size CommitTsShmemSize ( void  )

Definition at line 525 of file commit_ts.c.

526 {
528  sizeof(CommitTimestampShared);
529 }
struct CommitTimestampShared CommitTimestampShared
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:156

References CommitTsShmemBuffers(), and SimpleLruShmemSize().

Referenced by CalculateShmemSize().

◆ committssyncfiletag()

int committssyncfiletag ( const FileTag ftag,
char *  path 
)

Definition at line 1029 of file commit_ts.c.

1030 {
1031  return SlruSyncFileTag(CommitTsCtl, ftag, path);
1032 }
int SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path)
Definition: slru.c:1594

References CommitTsCtl, and SlruSyncFileTag().

◆ CompleteCommitTsInitialization()

void CompleteCommitTsInitialization ( void  )

Definition at line 617 of file commit_ts.c.

618 {
619  /*
620  * If the feature is not enabled, turn it off for good. This also removes
621  * any leftover data.
622  *
623  * Conversely, we activate the module if the feature is enabled. This is
624  * necessary for primary and standby as the activation depends on the
625  * control file contents at the beginning of recovery or when a
626  * XLOG_PARAMETER_CHANGE is replayed.
627  */
630  else
632 }
bool track_commit_timestamp
Definition: commit_ts.c:102

References ActivateCommitTs(), DeactivateCommitTs(), and track_commit_timestamp.

Referenced by StartupXLOG().

◆ DeactivateCommitTs()

static void DeactivateCommitTs ( void  )
static

Definition at line 754 of file commit_ts.c.

755 {
756  /*
757  * Cleanup the status in the shared memory.
758  *
759  * We reset everything in the commitTsShared record to prevent user from
760  * getting confusing data about last committed transaction on the standby
761  * when the module was activated repeatedly on the primary.
762  */
763  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
764 
769 
772 
773  LWLockRelease(CommitTsLock);
774 
775  /*
776  * Remove *all* files. This is necessary so that there are no leftover
777  * files; in the case where this feature is later enabled after running
778  * with it disabled for some time there may be a gap in the file sequence.
779  * (We can probably tolerate out-of-sequence files, as they are going to
780  * be overwritten anyway when we wrap around, but it seems better to be
781  * tidy.)
782  */
783  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
785  LWLockRelease(CommitTsSLRULock);
786 }
bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, void *data)
Definition: slru.c:1531
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition: slru.c:1554

References CommitTimestampShared::commitTsActive, CommitTsCtl, commitTsShared, CommitTimestampShared::dataLastCommit, InvalidRepOriginId, InvalidTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::newestCommitTsXid, CommitTimestampEntry::nodeid, VariableCacheData::oldestCommitTsXid, ShmemVariableCache, SlruScanDirCbDeleteAll(), SlruScanDirectory(), CommitTimestampEntry::time, TIMESTAMP_NOBEGIN, and CommitTimestampShared::xidLastCommit.

Referenced by CommitTsParameterChange(), and CompleteCommitTsInitialization().

◆ error_commit_ts_disabled()

static void error_commit_ts_disabled ( void  )
static

Definition at line 373 of file commit_ts.c.

374 {
375  ereport(ERROR,
376  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
377  errmsg("could not get commit timestamp data"),
379  errhint("Make sure the configuration parameter \"%s\" is set on the primary server.",
380  "track_commit_timestamp") :
381  errhint("Make sure the configuration parameter \"%s\" is set.",
382  "track_commit_timestamp")));
383 }
int errhint(const char *fmt,...)
Definition: elog.c:1153
int errcode(int sqlerrcode)
Definition: elog.c:695
int errmsg(const char *fmt,...)
Definition: elog.c:906
#define ERROR
Definition: elog.h:35
#define ereport(elevel,...)
Definition: elog.h:145
bool RecoveryInProgress(void)
Definition: xlog.c:5912

References ereport, errcode(), errhint(), errmsg(), ERROR, and RecoveryInProgress().

Referenced by GetLatestCommitTsData(), and TransactionIdGetCommitTsData().

◆ ExtendCommitTs()

void ExtendCommitTs ( TransactionId  newestXact)

Definition at line 814 of file commit_ts.c.

815 {
816  int pageno;
817 
818  /*
819  * Nothing to do if module not enabled. Note we do an unlocked read of
820  * the flag here, which is okay because this routine is only called from
821  * GetNewTransactionId, which is never called in a standby.
822  */
823  Assert(!InRecovery);
825  return;
826 
827  /*
828  * No work except at first XID of a page. But beware: just after
829  * wraparound, the first XID of page zero is FirstNormalTransactionId.
830  */
831  if (TransactionIdToCTsEntry(newestXact) != 0 &&
833  return;
834 
835  pageno = TransactionIdToCTsPage(newestXact);
836 
837  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
838 
839  /* Zero the page and make an XLOG entry about it */
840  ZeroCommitTsPage(pageno, !InRecovery);
841 
842  LWLockRelease(CommitTsSLRULock);
843 }
#define TransactionIdToCTsEntry(xid)
Definition: commit_ts.c:70
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
bool InRecovery
Definition: xlogutils.c:53

References Assert(), CommitTimestampShared::commitTsActive, commitTsShared, FirstNormalTransactionId, InRecovery, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), TransactionIdEquals, TransactionIdToCTsEntry, TransactionIdToCTsPage, and ZeroCommitTsPage().

Referenced by GetNewTransactionId().

◆ GetLatestCommitTsData()

TransactionId GetLatestCommitTsData ( TimestampTz ts,
RepOriginId nodeid 
)

Definition at line 352 of file commit_ts.c.

353 {
354  TransactionId xid;
355 
356  LWLockAcquire(CommitTsLock, LW_SHARED);
357 
358  /* Error if module not enabled */
361 
363  if (ts)
365  if (nodeid)
367  LWLockRelease(CommitTsLock);
368 
369  return xid;
370 }
static void error_commit_ts_disabled(void)
Definition: commit_ts.c:373
@ LW_SHARED
Definition: lwlock.h:113

References CommitTimestampShared::commitTsActive, commitTsShared, CommitTimestampShared::dataLastCommit, error_commit_ts_disabled(), LW_SHARED, LWLockAcquire(), LWLockRelease(), CommitTimestampEntry::nodeid, CommitTimestampEntry::time, and CommitTimestampShared::xidLastCommit.

Referenced by pg_last_committed_xact().

◆ pg_last_committed_xact()

Datum pg_last_committed_xact ( PG_FUNCTION_ARGS  )

Definition at line 412 of file commit_ts.c.

413 {
414  TransactionId xid;
415  RepOriginId nodeid;
416  TimestampTz ts;
417  Datum values[3];
418  bool nulls[3];
419  TupleDesc tupdesc;
420  HeapTuple htup;
421 
422  /* and construct a tuple with our data */
423  xid = GetLatestCommitTsData(&ts, &nodeid);
424 
425  /*
426  * Construct a tuple descriptor for the result row. This must match this
427  * function's pg_proc entry!
428  */
429  tupdesc = CreateTemplateTupleDesc(3);
430  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid",
431  XIDOID, -1, 0);
432  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "timestamp",
433  TIMESTAMPTZOID, -1, 0);
434  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "roident",
435  OIDOID, -1, 0);
436  tupdesc = BlessTupleDesc(tupdesc);
437 
438  if (!TransactionIdIsNormal(xid))
439  {
440  memset(nulls, true, sizeof(nulls));
441  }
442  else
443  {
444  values[0] = TransactionIdGetDatum(xid);
445  nulls[0] = false;
446 
447  values[1] = TimestampTzGetDatum(ts);
448  nulls[1] = false;
449 
450  values[2] = ObjectIdGetDatum((Oid) nodeid);
451  nulls[2] = false;
452  }
453 
454  htup = heap_form_tuple(tupdesc, values, nulls);
455 
457 }
int16 AttrNumber
Definition: attnum.h:21
static Datum values[MAXATTR]
Definition: bootstrap.c:156
TransactionId GetLatestCommitTsData(TimestampTz *ts, RepOriginId *nodeid)
Definition: commit_ts.c:352
int64 TimestampTz
Definition: timestamp.h:39
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2071
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
Definition: funcapi.h:230
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
static Datum TransactionIdGetDatum(TransactionId X)
Definition: postgres.h:620
uintptr_t Datum
Definition: postgres.h:412
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:600
unsigned int Oid
Definition: postgres_ext.h:31
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:45
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:583
static Datum TimestampTzGetDatum(TimestampTz X)
Definition: timestamp.h:52

References BlessTupleDesc(), CreateTemplateTupleDesc(), GetLatestCommitTsData(), heap_form_tuple(), HeapTupleGetDatum(), ObjectIdGetDatum(), PG_RETURN_DATUM, TimestampTzGetDatum(), TransactionIdGetDatum(), TransactionIdIsNormal, TupleDescInitEntry(), and values.

◆ pg_xact_commit_timestamp()

Datum pg_xact_commit_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 389 of file commit_ts.c.

390 {
392  TimestampTz ts;
393  bool found;
394 
395  found = TransactionIdGetCommitTsData(xid, &ts, NULL);
396 
397  if (!found)
398  PG_RETURN_NULL();
399 
401 }
bool TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts, RepOriginId *nodeid)
Definition: commit_ts.c:266
#define PG_RETURN_NULL()
Definition: fmgr.h:345
#define PG_GETARG_TRANSACTIONID(n)
Definition: fmgr.h:279
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:68

References PG_GETARG_TRANSACTIONID, PG_RETURN_NULL, PG_RETURN_TIMESTAMPTZ, and TransactionIdGetCommitTsData().

◆ pg_xact_commit_timestamp_origin()

Datum pg_xact_commit_timestamp_origin ( PG_FUNCTION_ARGS  )

Definition at line 466 of file commit_ts.c.

467 {
469  RepOriginId nodeid;
470  TimestampTz ts;
471  Datum values[2];
472  bool nulls[2];
473  TupleDesc tupdesc;
474  HeapTuple htup;
475  bool found;
476 
477  found = TransactionIdGetCommitTsData(xid, &ts, &nodeid);
478 
479  /*
480  * Construct a tuple descriptor for the result row. This must match this
481  * function's pg_proc entry!
482  */
483  tupdesc = CreateTemplateTupleDesc(2);
484  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "timestamp",
485  TIMESTAMPTZOID, -1, 0);
486  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "roident",
487  OIDOID, -1, 0);
488  tupdesc = BlessTupleDesc(tupdesc);
489 
490  if (!found)
491  {
492  memset(nulls, true, sizeof(nulls));
493  }
494  else
495  {
496  values[0] = TimestampTzGetDatum(ts);
497  nulls[0] = false;
498 
499  values[1] = ObjectIdGetDatum((Oid) nodeid);
500  nulls[1] = false;
501  }
502 
503  htup = heap_form_tuple(tupdesc, values, nulls);
504 
506 }

References BlessTupleDesc(), CreateTemplateTupleDesc(), heap_form_tuple(), HeapTupleGetDatum(), ObjectIdGetDatum(), PG_GETARG_TRANSACTIONID, PG_RETURN_DATUM, TimestampTzGetDatum(), TransactionIdGetCommitTsData(), TupleDescInitEntry(), and values.

◆ SetCommitTsLimit()

void SetCommitTsLimit ( TransactionId  oldestXact,
TransactionId  newestXact 
)

Definition at line 878 of file commit_ts.c.

879 {
880  /*
881  * Be careful not to overwrite values that are either further into the
882  * "future" or signal a disabled committs.
883  */
884  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
886  {
891  }
892  else
893  {
897  }
898  LWLockRelease(CommitTsLock);
899 }

References Assert(), InvalidTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::newestCommitTsXid, VariableCacheData::oldestCommitTsXid, ShmemVariableCache, and TransactionIdPrecedes().

Referenced by BootStrapXLOG(), and StartupXLOG().

◆ SetXidCommitTsInPage()

static void SetXidCommitTsInPage ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
TimestampTz  ts,
RepOriginId  nodeid,
int  pageno 
)
static

Definition at line 215 of file commit_ts.c.

218 {
219  int slotno;
220  int i;
221 
222  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
223 
224  slotno = SimpleLruReadPage(CommitTsCtl, pageno, true, xid);
225 
226  TransactionIdSetCommitTs(xid, ts, nodeid, slotno);
227  for (i = 0; i < nsubxids; i++)
228  TransactionIdSetCommitTs(subxids[i], ts, nodeid, slotno);
229 
230  CommitTsCtl->shared->page_dirty[slotno] = true;
231 
232  LWLockRelease(CommitTsSLRULock);
233 }
static void TransactionIdSetCommitTs(TransactionId xid, TimestampTz ts, RepOriginId nodeid, int slotno)
Definition: commit_ts.c:241
int i
Definition: isn.c:73
int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid)
Definition: slru.c:396

References CommitTsCtl, i, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SimpleLruReadPage(), and TransactionIdSetCommitTs().

Referenced by TransactionTreeSetCommitTsData().

◆ StartupCommitTs()

void StartupCommitTs ( void  )

Definition at line 607 of file commit_ts.c.

608 {
610 }

References ActivateCommitTs().

Referenced by StartupXLOG().

◆ TransactionIdGetCommitTsData()

bool TransactionIdGetCommitTsData ( TransactionId  xid,
TimestampTz ts,
RepOriginId nodeid 
)

Definition at line 266 of file commit_ts.c.

268 {
269  int pageno = TransactionIdToCTsPage(xid);
270  int entryno = TransactionIdToCTsEntry(xid);
271  int slotno;
272  CommitTimestampEntry entry;
273  TransactionId oldestCommitTsXid;
274  TransactionId newestCommitTsXid;
275 
276  if (!TransactionIdIsValid(xid))
277  ereport(ERROR,
278  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
279  errmsg("cannot retrieve commit timestamp for transaction %u", xid)));
280  else if (!TransactionIdIsNormal(xid))
281  {
282  /* frozen and bootstrap xids are always committed far in the past */
283  *ts = 0;
284  if (nodeid)
285  *nodeid = 0;
286  return false;
287  }
288 
289  LWLockAcquire(CommitTsLock, LW_SHARED);
290 
291  /* Error if module not enabled */
294 
295  /*
296  * If we're asked for the cached value, return that. Otherwise, fall
297  * through to read from SLRU.
298  */
299  if (commitTsShared->xidLastCommit == xid)
300  {
302  if (nodeid)
304 
305  LWLockRelease(CommitTsLock);
306  return *ts != 0;
307  }
308 
309  oldestCommitTsXid = ShmemVariableCache->oldestCommitTsXid;
310  newestCommitTsXid = ShmemVariableCache->newestCommitTsXid;
311  /* neither is invalid, or both are */
312  Assert(TransactionIdIsValid(oldestCommitTsXid) == TransactionIdIsValid(newestCommitTsXid));
313  LWLockRelease(CommitTsLock);
314 
315  /*
316  * Return empty if the requested value is outside our valid range.
317  */
318  if (!TransactionIdIsValid(oldestCommitTsXid) ||
319  TransactionIdPrecedes(xid, oldestCommitTsXid) ||
320  TransactionIdPrecedes(newestCommitTsXid, xid))
321  {
322  *ts = 0;
323  if (nodeid)
324  *nodeid = InvalidRepOriginId;
325  return false;
326  }
327 
328  /* lock is acquired by SimpleLruReadPage_ReadOnly */
329  slotno = SimpleLruReadPage_ReadOnly(CommitTsCtl, pageno, xid);
330  memcpy(&entry,
331  CommitTsCtl->shared->page_buffer[slotno] +
332  SizeOfCommitTimestampEntry * entryno,
334 
335  *ts = entry.time;
336  if (nodeid)
337  *nodeid = entry.nodeid;
338 
339  LWLockRelease(CommitTsSLRULock);
340  return *ts != 0;
341 }
#define SizeOfCommitTimestampEntry
Definition: commit_ts.c:62
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
Definition: slru.c:496
#define TransactionIdIsValid(xid)
Definition: transam.h:41

References Assert(), CommitTimestampShared::commitTsActive, CommitTsCtl, commitTsShared, CommitTimestampShared::dataLastCommit, ereport, errcode(), errmsg(), ERROR, error_commit_ts_disabled(), InvalidRepOriginId, LW_SHARED, LWLockAcquire(), LWLockRelease(), VariableCacheData::newestCommitTsXid, CommitTimestampEntry::nodeid, VariableCacheData::oldestCommitTsXid, ShmemVariableCache, SimpleLruReadPage_ReadOnly(), SizeOfCommitTimestampEntry, CommitTimestampEntry::time, TransactionIdIsNormal, TransactionIdIsValid, TransactionIdPrecedes(), TransactionIdToCTsEntry, TransactionIdToCTsPage, and CommitTimestampShared::xidLastCommit.

Referenced by pg_xact_commit_timestamp(), and pg_xact_commit_timestamp_origin().

◆ TransactionIdSetCommitTs()

static void TransactionIdSetCommitTs ( TransactionId  xid,
TimestampTz  ts,
RepOriginId  nodeid,
int  slotno 
)
static

Definition at line 241 of file commit_ts.c.

243 {
244  int entryno = TransactionIdToCTsEntry(xid);
245  CommitTimestampEntry entry;
246 
248 
249  entry.time = ts;
250  entry.nodeid = nodeid;
251 
252  memcpy(CommitTsCtl->shared->page_buffer[slotno] +
253  SizeOfCommitTimestampEntry * entryno,
255 }

References Assert(), CommitTsCtl, CommitTimestampEntry::nodeid, SizeOfCommitTimestampEntry, CommitTimestampEntry::time, TransactionIdIsNormal, and TransactionIdToCTsEntry.

Referenced by SetXidCommitTsInPage().

◆ TransactionTreeSetCommitTsData()

void TransactionTreeSetCommitTsData ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
TimestampTz  timestamp,
RepOriginId  nodeid 
)

Definition at line 134 of file commit_ts.c.

137 {
138  int i;
139  TransactionId headxid;
140  TransactionId newestXact;
141 
142  /*
143  * No-op if the module is not active.
144  *
145  * An unlocked read here is fine, because in a standby (the only place
146  * where the flag can change in flight) this routine is only called by the
147  * recovery process, which is also the only process which can change the
148  * flag.
149  */
151  return;
152 
153  /*
154  * Figure out the latest Xid in this batch: either the last subxid if
155  * there's any, otherwise the parent xid.
156  */
157  if (nsubxids > 0)
158  newestXact = subxids[nsubxids - 1];
159  else
160  newestXact = xid;
161 
162  /*
163  * We split the xids to set the timestamp to in groups belonging to the
164  * same SLRU page; the first element in each such set is its head. The
165  * first group has the main XID as the head; subsequent sets use the first
166  * subxid not on the previous page as head. This way, we only have to
167  * lock/modify each SLRU page once.
168  */
169  headxid = xid;
170  i = 0;
171  for (;;)
172  {
173  int pageno = TransactionIdToCTsPage(headxid);
174  int j;
175 
176  for (j = i; j < nsubxids; j++)
177  {
178  if (TransactionIdToCTsPage(subxids[j]) != pageno)
179  break;
180  }
181  /* subxids[i..j] are on the same page as the head */
182 
183  SetXidCommitTsInPage(headxid, j - i, subxids + i, timestamp, nodeid,
184  pageno);
185 
186  /* if we wrote out all subxids, we're done. */
187  if (j >= nsubxids)
188  break;
189 
190  /*
191  * Set the new head and skip over it, as well as over the subxids we
192  * just wrote.
193  */
194  headxid = subxids[j];
195  i = j + 1;
196  }
197 
198  /* update the cached value in shared memory */
199  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
203 
204  /* and move forwards our endpoint, if needed */
207  LWLockRelease(CommitTsLock);
208 }
static void SetXidCommitTsInPage(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz ts, RepOriginId nodeid, int pageno)
Definition: commit_ts.c:215
int j
Definition: isn.c:74
int64 timestamp

References CommitTimestampShared::commitTsActive, commitTsShared, CommitTimestampShared::dataLastCommit, i, j, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::newestCommitTsXid, CommitTimestampEntry::nodeid, SetXidCommitTsInPage(), ShmemVariableCache, CommitTimestampEntry::time, TransactionIdPrecedes(), TransactionIdToCTsPage, and CommitTimestampShared::xidLastCommit.

Referenced by RecordTransactionCommit(), RecordTransactionCommitPrepared(), and xact_redo_commit().

◆ TruncateCommitTs()

void TruncateCommitTs ( TransactionId  oldestXact)

Definition at line 852 of file commit_ts.c.

853 {
854  int cutoffPage;
855 
856  /*
857  * The cutoff point is the start of the segment containing oldestXact. We
858  * pass the *page* containing oldestXact to SimpleLruTruncate.
859  */
860  cutoffPage = TransactionIdToCTsPage(oldestXact);
861 
862  /* Check to see if there's any files that could be removed */
864  &cutoffPage))
865  return; /* nothing to remove */
866 
867  /* Write XLOG record */
868  WriteTruncateXlogRec(cutoffPage, oldestXact);
869 
870  /* Now we can remove the old CommitTs segment(s) */
871  SimpleLruTruncate(CommitTsCtl, cutoffPage);
872 }
static void WriteTruncateXlogRec(int pageno, TransactionId oldestXid)
Definition: commit_ts.c:969
bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, int segpage, void *data)
Definition: slru.c:1501

References CommitTsCtl, SimpleLruTruncate(), SlruScanDirCbReportPresence(), SlruScanDirectory(), TransactionIdToCTsPage, and WriteTruncateXlogRec().

Referenced by vac_truncate_clog().

◆ WriteTruncateXlogRec()

static void WriteTruncateXlogRec ( int  pageno,
TransactionId  oldestXid 
)
static

Definition at line 969 of file commit_ts.c.

970 {
971  xl_commit_ts_truncate xlrec;
972 
973  xlrec.pageno = pageno;
974  xlrec.oldestXid = oldestXid;
975 
976  XLogBeginInsert();
977  XLogRegisterData((char *) (&xlrec), SizeOfCommitTsTruncate);
978  (void) XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_TRUNCATE);
979 }
#define SizeOfCommitTsTruncate
Definition: commit_ts.h:67
void XLogRegisterData(char *data, uint32 len)
Definition: xloginsert.c:351
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:451
void XLogBeginInsert(void)
Definition: xloginsert.c:150

References COMMIT_TS_TRUNCATE, xl_commit_ts_truncate::oldestXid, xl_commit_ts_truncate::pageno, SizeOfCommitTsTruncate, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by TruncateCommitTs().

◆ WriteZeroPageXlogRec()

static void WriteZeroPageXlogRec ( int  pageno)
static

Definition at line 958 of file commit_ts.c.

959 {
960  XLogBeginInsert();
961  XLogRegisterData((char *) (&pageno), sizeof(int));
962  (void) XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_ZEROPAGE);
963 }

References COMMIT_TS_ZEROPAGE, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by ZeroCommitTsPage().

◆ ZeroCommitTsPage()

static int ZeroCommitTsPage ( int  pageno,
bool  writeXlog 
)
static

Definition at line 590 of file commit_ts.c.

591 {
592  int slotno;
593 
594  slotno = SimpleLruZeroPage(CommitTsCtl, pageno);
595 
596  if (writeXlog)
597  WriteZeroPageXlogRec(pageno);
598 
599  return slotno;
600 }
static void WriteZeroPageXlogRec(int pageno)
Definition: commit_ts.c:958
int SimpleLruZeroPage(SlruCtl ctl, int pageno)
Definition: slru.c:281

References CommitTsCtl, SimpleLruZeroPage(), and WriteZeroPageXlogRec().

Referenced by ActivateCommitTs(), commit_ts_redo(), and ExtendCommitTs().

Variable Documentation

◆ CommitTsCtlData

SlruCtlData CommitTsCtlData
static

Definition at line 76 of file commit_ts.c.

◆ commitTsShared

◆ track_commit_timestamp

bool track_commit_timestamp