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 "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)
 
static void WriteSetTimestampXlogRec (TransactionId mainxid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid)
 
void TransactionTreeSetCommitTsData (TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid, bool write_xlog)
 
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
 
CommitTimestampSharedcommitTsShared
 
bool track_commit_timestamp
 

Macro Definition Documentation

◆ COMMIT_TS_XACTS_PER_PAGE

#define COMMIT_TS_XACTS_PER_PAGE   (BLCKSZ / SizeOfCommitTimestampEntry)

Definition at line 66 of file commit_ts.c.

Referenced by CommitTsPagePrecedes(), and CommitTsShmemInit().

◆ CommitTsCtl

◆ SizeOfCommitTimestampEntry

#define SizeOfCommitTimestampEntry
Value:
sizeof(RepOriginId))
uint16 RepOriginId
Definition: xlogdefs.h:65
#define offsetof(type, field)
Definition: c.h:727

Definition at line 63 of file commit_ts.c.

Referenced by TransactionIdGetCommitTsData(), and TransactionIdSetCommitTs().

◆ TransactionIdToCTsEntry

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

◆ TransactionIdToCTsPage

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

Typedef Documentation

◆ CommitTimestampEntry

◆ CommitTimestampShared

Function Documentation

◆ ActivateCommitTs()

static void ActivateCommitTs ( void  )
static

Definition at line 695 of file commit_ts.c.

References Assert, CommitTimestampShared::commitTsActive, CommitTsCtl, 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().

696 {
697  TransactionId xid;
698  int pageno;
699 
700  /* If we've done this already, there's nothing to do */
701  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
703  {
704  LWLockRelease(CommitTsLock);
705  return;
706  }
707  LWLockRelease(CommitTsLock);
708 
710  pageno = TransactionIdToCTsPage(xid);
711 
712  /*
713  * Re-Initialize our idea of the latest page number.
714  */
715  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
716  CommitTsCtl->shared->latest_page_number = pageno;
717  LWLockRelease(CommitTsSLRULock);
718 
719  /*
720  * If CommitTs is enabled, but it wasn't in the previous server run, we
721  * need to set the oldest and newest values to the next Xid; that way, we
722  * will not try to read data that might not have been set.
723  *
724  * XXX does this have a problem if a server is started with commitTs
725  * enabled, then started with commitTs disabled, then restarted with it
726  * enabled again? It doesn't look like it does, because there should be a
727  * checkpoint that sets the value to InvalidTransactionId at end of
728  * recovery; and so any chance of injecting new transactions without
729  * CommitTs values would occur after the oldestCommitTsXid has been set to
730  * Invalid temporarily.
731  */
732  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
734  {
737  }
738  LWLockRelease(CommitTsLock);
739 
740  /* Create the current segment file, if necessary */
742  {
743  int slotno;
744 
745  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
746  slotno = ZeroCommitTsPage(pageno, false);
748  Assert(!CommitTsCtl->shared->page_dirty[slotno]);
749  LWLockRelease(CommitTsSLRULock);
750  }
751 
752  /* Change the activation status in shared memory. */
753  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
755  LWLockRelease(CommitTsLock);
756 }
uint32 TransactionId
Definition: c.h:587
#define CommitTsCtl
Definition: commit_ts.c:79
static int ZeroCommitTsPage(int pageno, bool writeXlog)
Definition: commit_ts.c:605
static TransactionId ReadNextTransactionId(void)
Definition: transam.h:308
FullTransactionId nextXid
Definition: transam.h:213
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
bool SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int pageno)
Definition: slru.c:625
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:613
TransactionId oldestCommitTsXid
Definition: transam.h:225
#define TransactionIdToCTsPage(xid)
Definition: commit_ts.c:69
#define Assert(condition)
Definition: c.h:804
TransactionId newestCommitTsXid
Definition: transam.h:226
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
CommitTimestampShared * commitTsShared
Definition: commit_ts.c:99

◆ AdvanceOldestCommitTsXid()

void AdvanceOldestCommitTsXid ( TransactionId  oldestXact)

Definition at line 920 of file commit_ts.c.

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

Referenced by commit_ts_redo(), and vac_truncate_clog().

921 {
922  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
926  LWLockRelease(CommitTsLock);
927 }
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
TransactionId oldestCommitTsXid
Definition: transam.h:225
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206

◆ BootStrapCommitTs()

void BootStrapCommitTs ( void  )

Definition at line 586 of file commit_ts.c.

Referenced by BootStrapXLOG().

587 {
588  /*
589  * Nothing to do here at present, unlike most other SLRU modules; segments
590  * are created when the server is started with this module enabled. See
591  * ActivateCommitTs.
592  */
593 }

◆ CheckPointCommitTs()

void CheckPointCommitTs ( void  )

Definition at line 807 of file commit_ts.c.

References CommitTsCtl, and SimpleLruWriteAll().

Referenced by CheckPointGuts().

808 {
809  /*
810  * Write dirty CommitTs pages to disk. This may result in sync requests
811  * queued for later handling by ProcessSyncRequests(), as part of the
812  * checkpoint.
813  */
815 }
#define CommitTsCtl
Definition: commit_ts.c:79
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1155

◆ commit_ts_redo()

void commit_ts_redo ( XLogReaderState record)

Definition at line 1022 of file commit_ts.c.

References AdvanceOldestCommitTsXid(), Assert, COMMIT_TS_SETTS, COMMIT_TS_TRUNCATE, COMMIT_TS_ZEROPAGE, CommitTsCtl, elog, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_commit_ts_set::mainxid, xl_commit_ts_set::nodeid, xl_commit_ts_truncate::oldestXid, xl_commit_ts_truncate::pageno, palloc(), PANIC, pfree(), SimpleLruTruncate(), SimpleLruWritePage(), SizeOfCommitTsSet, xl_commit_ts_set::timestamp, TransactionTreeSetCommitTsData(), XLogRecGetData, XLogRecGetDataLen, XLogRecGetInfo, XLogRecHasAnyBlockRefs, XLR_INFO_MASK, and ZeroCommitTsPage().

1023 {
1024  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1025 
1026  /* Backup blocks are not used in commit_ts records */
1027  Assert(!XLogRecHasAnyBlockRefs(record));
1028 
1029  if (info == COMMIT_TS_ZEROPAGE)
1030  {
1031  int pageno;
1032  int slotno;
1033 
1034  memcpy(&pageno, XLogRecGetData(record), sizeof(int));
1035 
1036  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
1037 
1038  slotno = ZeroCommitTsPage(pageno, false);
1040  Assert(!CommitTsCtl->shared->page_dirty[slotno]);
1041 
1042  LWLockRelease(CommitTsSLRULock);
1043  }
1044  else if (info == COMMIT_TS_TRUNCATE)
1045  {
1047 
1049 
1050  /*
1051  * During XLOG replay, latest_page_number isn't set up yet; insert a
1052  * suitable value to bypass the sanity test in SimpleLruTruncate.
1053  */
1054  CommitTsCtl->shared->latest_page_number = trunc->pageno;
1055 
1057  }
1058  else if (info == COMMIT_TS_SETTS)
1059  {
1060  xl_commit_ts_set *setts = (xl_commit_ts_set *) XLogRecGetData(record);
1061  int nsubxids;
1062  TransactionId *subxids;
1063 
1064  nsubxids = ((XLogRecGetDataLen(record) - SizeOfCommitTsSet) /
1065  sizeof(TransactionId));
1066  if (nsubxids > 0)
1067  {
1068  subxids = palloc(sizeof(TransactionId) * nsubxids);
1069  memcpy(subxids,
1071  sizeof(TransactionId) * nsubxids);
1072  }
1073  else
1074  subxids = NULL;
1075 
1076  TransactionTreeSetCommitTsData(setts->mainxid, nsubxids, subxids,
1077  setts->timestamp, setts->nodeid, true);
1078  if (subxids)
1079  pfree(subxids);
1080  }
1081  else
1082  elog(PANIC, "commit_ts_redo: unknown op code %u", info);
1083 }
#define COMMIT_TS_ZEROPAGE
Definition: commit_ts.h:51
#define COMMIT_TS_SETTS
Definition: commit_ts.h:53
uint32 TransactionId
Definition: c.h:587
#define CommitTsCtl
Definition: commit_ts.c:79
static int ZeroCommitTsPage(int pageno, bool writeXlog)
Definition: commit_ts.c:605
void SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
Definition: slru.c:1225
unsigned char uint8
Definition: c.h:439
#define PANIC
Definition: elog.h:55
void AdvanceOldestCommitTsXid(TransactionId oldestXact)
Definition: commit_ts.c:920
TimestampTz timestamp
Definition: commit_ts.h:57
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
void pfree(void *pointer)
Definition: mcxt.c:1057
#define XLogRecGetData(decoder)
Definition: xlogreader.h:310
#define XLogRecGetDataLen(decoder)
Definition: xlogreader.h:311
#define SizeOfCommitTsSet
Definition: commit_ts.h:63
TransactionId oldestXid
Definition: commit_ts.h:69
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:613
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:305
#define COMMIT_TS_TRUNCATE
Definition: commit_ts.h:52
TransactionId mainxid
Definition: commit_ts.h:59
#define Assert(condition)
Definition: c.h:804
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
void * palloc(Size size)
Definition: mcxt.c:950
RepOriginId nodeid
Definition: commit_ts.h:58
#define elog(elevel,...)
Definition: elog.h:227
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:312
void TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid, bool write_xlog)
Definition: commit_ts.c:145

◆ CommitTsPagePrecedes()

static bool CommitTsPagePrecedes ( int  page1,
int  page2 
)
static

Definition at line 954 of file commit_ts.c.

References COMMIT_TS_XACTS_PER_PAGE, FirstNormalTransactionId, and TransactionIdPrecedes().

Referenced by CommitTsShmemInit().

955 {
956  TransactionId xid1;
957  TransactionId xid2;
958 
959  xid1 = ((TransactionId) page1) * COMMIT_TS_XACTS_PER_PAGE;
960  xid1 += FirstNormalTransactionId + 1;
961  xid2 = ((TransactionId) page2) * COMMIT_TS_XACTS_PER_PAGE;
962  xid2 += FirstNormalTransactionId + 1;
963 
964  return (TransactionIdPrecedes(xid1, xid2) &&
966 }
uint32 TransactionId
Definition: c.h:587
#define FirstNormalTransactionId
Definition: transam.h:34
#define COMMIT_TS_XACTS_PER_PAGE
Definition: commit_ts.c:66
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300

◆ CommitTsParameterChange()

void CommitTsParameterChange ( bool  newvalue,
bool  oldvalue 
)

Definition at line 654 of file commit_ts.c.

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

Referenced by xlog_redo().

655 {
656  /*
657  * If the commit_ts module is disabled in this server and we get word from
658  * the primary server that it is enabled there, activate it so that we can
659  * replay future WAL records involving it; also mark it as active on
660  * pg_control. If the old value was already set, we already did this, so
661  * don't do anything.
662  *
663  * If the module is disabled in the primary, disable it here too, unless
664  * the module is enabled locally.
665  *
666  * Note this only runs in the recovery process, so an unlocked read is
667  * fine.
668  */
669  if (newvalue)
670  {
673  }
674  else if (commitTsShared->commitTsActive)
676 }
static void ActivateCommitTs(void)
Definition: commit_ts.c:695
static void DeactivateCommitTs(void)
Definition: commit_ts.c:769
CommitTimestampShared * commitTsShared
Definition: commit_ts.c:99

◆ CommitTsShmemBuffers()

Size CommitTsShmemBuffers ( void  )

Definition at line 531 of file commit_ts.c.

References Max, Min, and NBuffers.

Referenced by CommitTsShmemInit(), and CommitTsShmemSize().

532 {
533  return Min(16, Max(4, NBuffers / 1024));
534 }
#define Min(x, y)
Definition: c.h:986
#define Max(x, y)
Definition: c.h:980
int NBuffers
Definition: globals.c:133

◆ CommitTsShmemInit()

void CommitTsShmemInit ( void  )

Definition at line 551 of file commit_ts.c.

References Assert, COMMIT_TS_XACTS_PER_PAGE, CommitTimestampShared::commitTsActive, CommitTsCtl, CommitTsPagePrecedes(), 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().

552 {
553  bool found;
554 
555  CommitTsCtl->PagePrecedes = CommitTsPagePrecedes;
557  CommitTsSLRULock, "pg_commit_ts",
561 
562  commitTsShared = ShmemInitStruct("CommitTs shared",
563  sizeof(CommitTimestampShared),
564  &found);
565 
566  if (!IsUnderPostmaster)
567  {
568  Assert(!found);
569 
574  }
575  else
576  Assert(found);
577 }
CommitTimestampEntry dataLastCommit
Definition: commit_ts.c:95
#define CommitTsCtl
Definition: commit_ts.c:79
Size CommitTsShmemBuffers(void)
Definition: commit_ts.c:531
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:186
#define COMMIT_TS_XACTS_PER_PAGE
Definition: commit_ts.c:66
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:396
bool IsUnderPostmaster
Definition: globals.c:110
#define InvalidTransactionId
Definition: transam.h:31
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:112
TimestampTz time
Definition: commit_ts.c:59
static bool CommitTsPagePrecedes(int page1, int page2)
Definition: commit_ts.c:954
TransactionId xidLastCommit
Definition: commit_ts.c:94
#define Assert(condition)
Definition: c.h:804
#define InvalidRepOriginId
Definition: origin.h:33
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition: slru.h:156
RepOriginId nodeid
Definition: commit_ts.c:60
CommitTimestampShared * commitTsShared
Definition: commit_ts.c:99

◆ CommitTsShmemSize()

Size CommitTsShmemSize ( void  )

Definition at line 540 of file commit_ts.c.

References CommitTsShmemBuffers(), and SimpleLruShmemSize().

Referenced by CreateSharedMemoryAndSemaphores().

541 {
543  sizeof(CommitTimestampShared);
544 }
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:155
Size CommitTsShmemBuffers(void)
Definition: commit_ts.c:531
struct CommitTimestampShared CommitTimestampShared

◆ committssyncfiletag()

int committssyncfiletag ( const FileTag ftag,
char *  path 
)

Definition at line 1089 of file commit_ts.c.

References CommitTsCtl, and SlruSyncFileTag().

1090 {
1091  return SlruSyncFileTag(CommitTsCtl, ftag, path);
1092 }
int SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path)
Definition: slru.c:1592
#define CommitTsCtl
Definition: commit_ts.c:79

◆ CompleteCommitTsInitialization()

void CompleteCommitTsInitialization ( void  )

Definition at line 632 of file commit_ts.c.

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

Referenced by StartupXLOG().

633 {
634  /*
635  * If the feature is not enabled, turn it off for good. This also removes
636  * any leftover data.
637  *
638  * Conversely, we activate the module if the feature is enabled. This is
639  * necessary for primary and standby as the activation depends on the
640  * control file contents at the beginning of recovery or when a
641  * XLOG_PARAMETER_CHANGE is replayed.
642  */
645  else
647 }
bool track_commit_timestamp
Definition: commit_ts.c:103
static void ActivateCommitTs(void)
Definition: commit_ts.c:695
static void DeactivateCommitTs(void)
Definition: commit_ts.c:769

◆ DeactivateCommitTs()

static void DeactivateCommitTs ( void  )
static

Definition at line 769 of file commit_ts.c.

References CommitTimestampShared::commitTsActive, CommitTsCtl, 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().

770 {
771  /*
772  * Cleanup the status in the shared memory.
773  *
774  * We reset everything in the commitTsShared record to prevent user from
775  * getting confusing data about last committed transaction on the standby
776  * when the module was activated repeatedly on the primary.
777  */
778  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
779 
784 
787 
788  LWLockRelease(CommitTsLock);
789 
790  /*
791  * Remove *all* files. This is necessary so that there are no leftover
792  * files; in the case where this feature is later enabled after running
793  * with it disabled for some time there may be a gap in the file sequence.
794  * (We can probably tolerate out-of-sequence files, as they are going to
795  * be overwritten anyway when we wrap around, but it seems better to be
796  * tidy.)
797  */
798  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
800  LWLockRelease(CommitTsSLRULock);
801 }
CommitTimestampEntry dataLastCommit
Definition: commit_ts.c:95
bool SlruScanDirCbDeleteAll(SlruCtl ctl, char *filename, int segpage, void *data)
Definition: slru.c:1529
#define CommitTsCtl
Definition: commit_ts.c:79
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
#define TIMESTAMP_NOBEGIN(j)
Definition: timestamp.h:112
TransactionId oldestCommitTsXid
Definition: transam.h:225
TimestampTz time
Definition: commit_ts.c:59
TransactionId xidLastCommit
Definition: commit_ts.c:94
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition: slru.c:1552
TransactionId newestCommitTsXid
Definition: transam.h:226
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
#define InvalidRepOriginId
Definition: origin.h:33
RepOriginId nodeid
Definition: commit_ts.c:60
CommitTimestampShared * commitTsShared
Definition: commit_ts.c:99

◆ error_commit_ts_disabled()

static void error_commit_ts_disabled ( void  )
static

Definition at line 389 of file commit_ts.c.

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

Referenced by GetLatestCommitTsData(), and TransactionIdGetCommitTsData().

390 {
391  ereport(ERROR,
392  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
393  errmsg("could not get commit timestamp data"),
395  errhint("Make sure the configuration parameter \"%s\" is set on the primary server.",
396  "track_commit_timestamp") :
397  errhint("Make sure the configuration parameter \"%s\" is set.",
398  "track_commit_timestamp")));
399 }
int errhint(const char *fmt,...)
Definition: elog.c:1152
int errcode(int sqlerrcode)
Definition: elog.c:694
bool RecoveryInProgress(void)
Definition: xlog.c:8132
#define ERROR
Definition: elog.h:45
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:905

◆ ExtendCommitTs()

void ExtendCommitTs ( TransactionId  newestXact)

Definition at line 829 of file commit_ts.c.

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

Referenced by GetNewTransactionId().

830 {
831  int pageno;
832 
833  /*
834  * Nothing to do if module not enabled. Note we do an unlocked read of
835  * the flag here, which is okay because this routine is only called from
836  * GetNewTransactionId, which is never called in a standby.
837  */
838  Assert(!InRecovery);
840  return;
841 
842  /*
843  * No work except at first XID of a page. But beware: just after
844  * wraparound, the first XID of page zero is FirstNormalTransactionId.
845  */
846  if (TransactionIdToCTsEntry(newestXact) != 0 &&
848  return;
849 
850  pageno = TransactionIdToCTsPage(newestXact);
851 
852  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
853 
854  /* Zero the page and make an XLOG entry about it */
855  ZeroCommitTsPage(pageno, !InRecovery);
856 
857  LWLockRelease(CommitTsSLRULock);
858 }
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
static int ZeroCommitTsPage(int pageno, bool writeXlog)
Definition: commit_ts.c:605
bool InRecovery
Definition: xlog.c:206
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
#define FirstNormalTransactionId
Definition: transam.h:34
#define TransactionIdToCTsPage(xid)
Definition: commit_ts.c:69
#define Assert(condition)
Definition: c.h:804
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
#define TransactionIdToCTsEntry(xid)
Definition: commit_ts.c:71
CommitTimestampShared * commitTsShared
Definition: commit_ts.c:99

◆ GetLatestCommitTsData()

TransactionId GetLatestCommitTsData ( TimestampTz ts,
RepOriginId nodeid 
)

Definition at line 368 of file commit_ts.c.

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

Referenced by pg_last_committed_xact().

369 {
370  TransactionId xid;
371 
372  LWLockAcquire(CommitTsLock, LW_SHARED);
373 
374  /* Error if module not enabled */
377 
379  if (ts)
381  if (nodeid)
383  LWLockRelease(CommitTsLock);
384 
385  return xid;
386 }
CommitTimestampEntry dataLastCommit
Definition: commit_ts.c:95
uint32 TransactionId
Definition: c.h:587
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
TimestampTz time
Definition: commit_ts.c:59
TransactionId xidLastCommit
Definition: commit_ts.c:94
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
RepOriginId nodeid
Definition: commit_ts.c:60
CommitTimestampShared * commitTsShared
Definition: commit_ts.c:99
static void error_commit_ts_disabled(void)
Definition: commit_ts.c:389

◆ pg_last_committed_xact()

Datum pg_last_committed_xact ( PG_FUNCTION_ARGS  )

Definition at line 428 of file commit_ts.c.

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

429 {
430  TransactionId xid;
431  RepOriginId nodeid;
432  TimestampTz ts;
433  Datum values[3];
434  bool nulls[3];
435  TupleDesc tupdesc;
436  HeapTuple htup;
437 
438  /* and construct a tuple with our data */
439  xid = GetLatestCommitTsData(&ts, &nodeid);
440 
441  /*
442  * Construct a tuple descriptor for the result row. This must match this
443  * function's pg_proc entry!
444  */
445  tupdesc = CreateTemplateTupleDesc(3);
446  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid",
447  XIDOID, -1, 0);
448  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "timestamp",
449  TIMESTAMPTZOID, -1, 0);
450  TupleDescInitEntry(tupdesc, (AttrNumber) 3, "roident",
451  OIDOID, -1, 0);
452  tupdesc = BlessTupleDesc(tupdesc);
453 
454  if (!TransactionIdIsNormal(xid))
455  {
456  memset(nulls, true, sizeof(nulls));
457  }
458  else
459  {
460  values[0] = TransactionIdGetDatum(xid);
461  nulls[0] = false;
462 
463  values[1] = TimestampTzGetDatum(ts);
464  nulls[1] = false;
465 
466  values[2] = ObjectIdGetDatum((Oid) nodeid);
467  nulls[2] = false;
468  }
469 
470  htup = heap_form_tuple(tupdesc, values, nulls);
471 
473 }
uint32 TransactionId
Definition: c.h:587
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
int64 TimestampTz
Definition: timestamp.h:39
uint16 RepOriginId
Definition: xlogdefs.h:65
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2052
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
#define TransactionIdGetDatum(X)
Definition: postgres.h:521
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
static Datum values[MAXATTR]
Definition: bootstrap.c:165
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
int16 AttrNumber
Definition: attnum.h:21
TransactionId GetLatestCommitTsData(TimestampTz *ts, RepOriginId *nodeid)
Definition: commit_ts.c:368

◆ pg_xact_commit_timestamp()

Datum pg_xact_commit_timestamp ( PG_FUNCTION_ARGS  )

Definition at line 405 of file commit_ts.c.

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

406 {
408  TimestampTz ts;
409  bool found;
410 
411  found = TransactionIdGetCommitTsData(xid, &ts, NULL);
412 
413  if (!found)
414  PG_RETURN_NULL();
415 
417 }
uint32 TransactionId
Definition: c.h:587
int64 TimestampTz
Definition: timestamp.h:39
#define PG_RETURN_TIMESTAMPTZ(x)
Definition: timestamp.h:40
#define PG_GETARG_TRANSACTIONID(n)
Definition: fmgr.h:279
bool TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts, RepOriginId *nodeid)
Definition: commit_ts.c:282
#define PG_RETURN_NULL()
Definition: fmgr.h:345

◆ pg_xact_commit_timestamp_origin()

Datum pg_xact_commit_timestamp_origin ( PG_FUNCTION_ARGS  )

Definition at line 482 of file commit_ts.c.

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

483 {
485  RepOriginId nodeid;
486  TimestampTz ts;
487  Datum values[2];
488  bool nulls[2];
489  TupleDesc tupdesc;
490  HeapTuple htup;
491  bool found;
492 
493  found = TransactionIdGetCommitTsData(xid, &ts, &nodeid);
494 
495  /*
496  * Construct a tuple descriptor for the result row. This must match this
497  * function's pg_proc entry!
498  */
499  tupdesc = CreateTemplateTupleDesc(2);
500  TupleDescInitEntry(tupdesc, (AttrNumber) 1, "timestamp",
501  TIMESTAMPTZOID, -1, 0);
502  TupleDescInitEntry(tupdesc, (AttrNumber) 2, "roident",
503  OIDOID, -1, 0);
504  tupdesc = BlessTupleDesc(tupdesc);
505 
506  if (!found)
507  {
508  memset(nulls, true, sizeof(nulls));
509  }
510  else
511  {
512  values[0] = TimestampTzGetDatum(ts);
513  nulls[0] = false;
514 
515  values[1] = ObjectIdGetDatum((Oid) nodeid);
516  nulls[1] = false;
517  }
518 
519  htup = heap_form_tuple(tupdesc, values, nulls);
520 
522 }
uint32 TransactionId
Definition: c.h:587
TupleDesc CreateTemplateTupleDesc(int natts)
Definition: tupdesc.c:44
int64 TimestampTz
Definition: timestamp.h:39
uint16 RepOriginId
Definition: xlogdefs.h:65
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum *values, bool *isnull)
Definition: heaptuple.c:1020
unsigned int Oid
Definition: postgres_ext.h:31
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define TimestampTzGetDatum(X)
Definition: timestamp.h:32
TupleDesc BlessTupleDesc(TupleDesc tupdesc)
Definition: execTuples.c:2052
#define PG_GETARG_TRANSACTIONID(n)
Definition: fmgr.h:279
void TupleDescInitEntry(TupleDesc desc, AttrNumber attributeNumber, const char *attributeName, Oid oidtypeid, int32 typmod, int attdim)
Definition: tupdesc.c:603
bool TransactionIdGetCommitTsData(TransactionId xid, TimestampTz *ts, RepOriginId *nodeid)
Definition: commit_ts.c:282
uintptr_t Datum
Definition: postgres.h:367
#define PG_RETURN_DATUM(x)
Definition: fmgr.h:353
#define HeapTupleGetDatum(tuple)
Definition: funcapi.h:221
static Datum values[MAXATTR]
Definition: bootstrap.c:165
int16 AttrNumber
Definition: attnum.h:21

◆ SetCommitTsLimit()

void SetCommitTsLimit ( TransactionId  oldestXact,
TransactionId  newestXact 
)

Definition at line 893 of file commit_ts.c.

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

Referenced by BootStrapXLOG(), and StartupXLOG().

894 {
895  /*
896  * Be careful not to overwrite values that are either further into the
897  * "future" or signal a disabled committs.
898  */
899  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
901  {
906  }
907  else
908  {
912  }
913  LWLockRelease(CommitTsLock);
914 }
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define InvalidTransactionId
Definition: transam.h:31
TransactionId oldestCommitTsXid
Definition: transam.h:225
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define Assert(condition)
Definition: c.h:804
TransactionId newestCommitTsXid
Definition: transam.h:226
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206

◆ SetXidCommitTsInPage()

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

Definition at line 231 of file commit_ts.c.

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

Referenced by TransactionTreeSetCommitTsData().

234 {
235  int slotno;
236  int i;
237 
238  LWLockAcquire(CommitTsSLRULock, LW_EXCLUSIVE);
239 
240  slotno = SimpleLruReadPage(CommitTsCtl, pageno, true, xid);
241 
242  TransactionIdSetCommitTs(xid, ts, nodeid, slotno);
243  for (i = 0; i < nsubxids; i++)
244  TransactionIdSetCommitTs(subxids[i], ts, nodeid, slotno);
245 
246  CommitTsCtl->shared->page_dirty[slotno] = true;
247 
248  LWLockRelease(CommitTsSLRULock);
249 }
#define CommitTsCtl
Definition: commit_ts.c:79
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
static void TransactionIdSetCommitTs(TransactionId xid, TimestampTz ts, RepOriginId nodeid, int slotno)
Definition: commit_ts.c:257
int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid)
Definition: slru.c:394
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
int i

◆ StartupCommitTs()

void StartupCommitTs ( void  )

Definition at line 622 of file commit_ts.c.

References ActivateCommitTs().

Referenced by StartupXLOG().

623 {
625 }
static void ActivateCommitTs(void)
Definition: commit_ts.c:695

◆ TransactionIdGetCommitTsData()

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

Definition at line 282 of file commit_ts.c.

References Assert, CommitTimestampShared::commitTsActive, CommitTsCtl, 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().

284 {
285  int pageno = TransactionIdToCTsPage(xid);
286  int entryno = TransactionIdToCTsEntry(xid);
287  int slotno;
288  CommitTimestampEntry entry;
289  TransactionId oldestCommitTsXid;
290  TransactionId newestCommitTsXid;
291 
292  if (!TransactionIdIsValid(xid))
293  ereport(ERROR,
294  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
295  errmsg("cannot retrieve commit timestamp for transaction %u", xid)));
296  else if (!TransactionIdIsNormal(xid))
297  {
298  /* frozen and bootstrap xids are always committed far in the past */
299  *ts = 0;
300  if (nodeid)
301  *nodeid = 0;
302  return false;
303  }
304 
305  LWLockAcquire(CommitTsLock, LW_SHARED);
306 
307  /* Error if module not enabled */
310 
311  /*
312  * If we're asked for the cached value, return that. Otherwise, fall
313  * through to read from SLRU.
314  */
315  if (commitTsShared->xidLastCommit == xid)
316  {
318  if (nodeid)
320 
321  LWLockRelease(CommitTsLock);
322  return *ts != 0;
323  }
324 
325  oldestCommitTsXid = ShmemVariableCache->oldestCommitTsXid;
326  newestCommitTsXid = ShmemVariableCache->newestCommitTsXid;
327  /* neither is invalid, or both are */
328  Assert(TransactionIdIsValid(oldestCommitTsXid) == TransactionIdIsValid(newestCommitTsXid));
329  LWLockRelease(CommitTsLock);
330 
331  /*
332  * Return empty if the requested value is outside our valid range.
333  */
334  if (!TransactionIdIsValid(oldestCommitTsXid) ||
335  TransactionIdPrecedes(xid, oldestCommitTsXid) ||
336  TransactionIdPrecedes(newestCommitTsXid, xid))
337  {
338  *ts = 0;
339  if (nodeid)
340  *nodeid = InvalidRepOriginId;
341  return false;
342  }
343 
344  /* lock is acquired by SimpleLruReadPage_ReadOnly */
345  slotno = SimpleLruReadPage_ReadOnly(CommitTsCtl, pageno, xid);
346  memcpy(&entry,
347  CommitTsCtl->shared->page_buffer[slotno] +
348  SizeOfCommitTimestampEntry * entryno,
350 
351  *ts = entry.time;
352  if (nodeid)
353  *nodeid = entry.nodeid;
354 
355  LWLockRelease(CommitTsSLRULock);
356  return *ts != 0;
357 }
CommitTimestampEntry dataLastCommit
Definition: commit_ts.c:95
uint32 TransactionId
Definition: c.h:587
#define SizeOfCommitTimestampEntry
Definition: commit_ts.c:63
#define CommitTsCtl
Definition: commit_ts.c:79
int errcode(int sqlerrcode)
Definition: elog.c:694
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
#define ERROR
Definition: elog.h:45
VariableCache ShmemVariableCache
Definition: varsup.c:34
TransactionId oldestCommitTsXid
Definition: transam.h:225
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
TimestampTz time
Definition: commit_ts.c:59
#define TransactionIdToCTsPage(xid)
Definition: commit_ts.c:69
TransactionId xidLastCommit
Definition: commit_ts.c:94
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
Definition: slru.c:494
#define ereport(elevel,...)
Definition: elog.h:155
#define Assert(condition)
Definition: c.h:804
TransactionId newestCommitTsXid
Definition: transam.h:226
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
#define TransactionIdToCTsEntry(xid)
Definition: commit_ts.c:71
#define InvalidRepOriginId
Definition: origin.h:33
int errmsg(const char *fmt,...)
Definition: elog.c:905
#define TransactionIdIsValid(xid)
Definition: transam.h:41
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
RepOriginId nodeid
Definition: commit_ts.c:60
CommitTimestampShared * commitTsShared
Definition: commit_ts.c:99
static void error_commit_ts_disabled(void)
Definition: commit_ts.c:389

◆ TransactionIdSetCommitTs()

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

Definition at line 257 of file commit_ts.c.

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

Referenced by SetXidCommitTsInPage().

259 {
260  int entryno = TransactionIdToCTsEntry(xid);
261  CommitTimestampEntry entry;
262 
264 
265  entry.time = ts;
266  entry.nodeid = nodeid;
267 
268  memcpy(CommitTsCtl->shared->page_buffer[slotno] +
269  SizeOfCommitTimestampEntry * entryno,
271 }
#define SizeOfCommitTimestampEntry
Definition: commit_ts.c:63
#define CommitTsCtl
Definition: commit_ts.c:79
TimestampTz time
Definition: commit_ts.c:59
#define Assert(condition)
Definition: c.h:804
#define TransactionIdToCTsEntry(xid)
Definition: commit_ts.c:71
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
RepOriginId nodeid
Definition: commit_ts.c:60

◆ TransactionTreeSetCommitTsData()

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

Definition at line 145 of file commit_ts.c.

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

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

148 {
149  int i;
150  TransactionId headxid;
151  TransactionId newestXact;
152 
153  /*
154  * No-op if the module is not active.
155  *
156  * An unlocked read here is fine, because in a standby (the only place
157  * where the flag can change in flight) this routine is only called by the
158  * recovery process, which is also the only process which can change the
159  * flag.
160  */
162  return;
163 
164  /*
165  * Comply with the WAL-before-data rule: if caller specified it wants this
166  * value to be recorded in WAL, do so before touching the data.
167  */
168  if (write_xlog)
169  WriteSetTimestampXlogRec(xid, nsubxids, subxids, timestamp, nodeid);
170 
171  /*
172  * Figure out the latest Xid in this batch: either the last subxid if
173  * there's any, otherwise the parent xid.
174  */
175  if (nsubxids > 0)
176  newestXact = subxids[nsubxids - 1];
177  else
178  newestXact = xid;
179 
180  /*
181  * We split the xids to set the timestamp to in groups belonging to the
182  * same SLRU page; the first element in each such set is its head. The
183  * first group has the main XID as the head; subsequent sets use the first
184  * subxid not on the previous page as head. This way, we only have to
185  * lock/modify each SLRU page once.
186  */
187  for (i = 0, headxid = xid;;)
188  {
189  int pageno = TransactionIdToCTsPage(headxid);
190  int j;
191 
192  for (j = i; j < nsubxids; j++)
193  {
194  if (TransactionIdToCTsPage(subxids[j]) != pageno)
195  break;
196  }
197  /* subxids[i..j] are on the same page as the head */
198 
199  SetXidCommitTsInPage(headxid, j - i, subxids + i, timestamp, nodeid,
200  pageno);
201 
202  /* if we wrote out all subxids, we're done. */
203  if (j + 1 >= nsubxids)
204  break;
205 
206  /*
207  * Set the new head and skip over it, as well as over the subxids we
208  * just wrote.
209  */
210  headxid = subxids[j];
211  i += j - i + 1;
212  }
213 
214  /* update the cached value in shared memory */
215  LWLockAcquire(CommitTsLock, LW_EXCLUSIVE);
219 
220  /* and move forwards our endpoint, if needed */
223  LWLockRelease(CommitTsLock);
224 }
CommitTimestampEntry dataLastCommit
Definition: commit_ts.c:95
uint32 TransactionId
Definition: c.h:587
static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids, TransactionId *subxids, TimestampTz timestamp, RepOriginId nodeid)
Definition: commit_ts.c:1000
int64 timestamp
static void SetXidCommitTsInPage(TransactionId xid, int nsubxids, TransactionId *subxids, TimestampTz ts, RepOriginId nodeid, int pageno)
Definition: commit_ts.c:231
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
TimestampTz time
Definition: commit_ts.c:59
#define TransactionIdToCTsPage(xid)
Definition: commit_ts.c:69
TransactionId xidLastCommit
Definition: commit_ts.c:94
TransactionId newestCommitTsXid
Definition: transam.h:226
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1206
int i
RepOriginId nodeid
Definition: commit_ts.c:60
CommitTimestampShared * commitTsShared
Definition: commit_ts.c:99

◆ TruncateCommitTs()

void TruncateCommitTs ( TransactionId  oldestXact)

Definition at line 867 of file commit_ts.c.

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

Referenced by vac_truncate_clog().

868 {
869  int cutoffPage;
870 
871  /*
872  * The cutoff point is the start of the segment containing oldestXact. We
873  * pass the *page* containing oldestXact to SimpleLruTruncate.
874  */
875  cutoffPage = TransactionIdToCTsPage(oldestXact);
876 
877  /* Check to see if there's any files that could be removed */
879  &cutoffPage))
880  return; /* nothing to remove */
881 
882  /* Write XLOG record */
883  WriteTruncateXlogRec(cutoffPage, oldestXact);
884 
885  /* Now we can remove the old CommitTs segment(s) */
886  SimpleLruTruncate(CommitTsCtl, cutoffPage);
887 }
#define CommitTsCtl
Definition: commit_ts.c:79
void SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
Definition: slru.c:1225
static void WriteTruncateXlogRec(int pageno, TransactionId oldestXid)
Definition: commit_ts.c:984
bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, int segpage, void *data)
Definition: slru.c:1499
#define TransactionIdToCTsPage(xid)
Definition: commit_ts.c:69
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition: slru.c:1552

◆ WriteSetTimestampXlogRec()

static void WriteSetTimestampXlogRec ( TransactionId  mainxid,
int  nsubxids,
TransactionId subxids,
TimestampTz  timestamp,
RepOriginId  nodeid 
)
static

Definition at line 1000 of file commit_ts.c.

References COMMIT_TS_SETTS, xl_commit_ts_set::mainxid, xl_commit_ts_set::nodeid, CommitTimestampEntry::nodeid, offsetof, xl_commit_ts_set::timestamp, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by TransactionTreeSetCommitTsData().

1003 {
1004  xl_commit_ts_set record;
1005 
1006  record.timestamp = timestamp;
1007  record.nodeid = nodeid;
1008  record.mainxid = mainxid;
1009 
1010  XLogBeginInsert();
1011  XLogRegisterData((char *) &record,
1012  offsetof(xl_commit_ts_set, mainxid) +
1013  sizeof(TransactionId));
1014  XLogRegisterData((char *) subxids, nsubxids * sizeof(TransactionId));
1015  XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_SETTS);
1016 }
#define COMMIT_TS_SETTS
Definition: commit_ts.h:53
uint32 TransactionId
Definition: c.h:587
int64 timestamp
TimestampTz timestamp
Definition: commit_ts.h:57
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
TransactionId mainxid
Definition: commit_ts.h:59
RepOriginId nodeid
Definition: commit_ts.h:58
void XLogBeginInsert(void)
Definition: xloginsert.c:123
#define offsetof(type, field)
Definition: c.h:727

◆ WriteTruncateXlogRec()

static void WriteTruncateXlogRec ( int  pageno,
TransactionId  oldestXid 
)
static

Definition at line 984 of file commit_ts.c.

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

Referenced by TruncateCommitTs().

985 {
986  xl_commit_ts_truncate xlrec;
987 
988  xlrec.pageno = pageno;
989  xlrec.oldestXid = oldestXid;
990 
991  XLogBeginInsert();
992  XLogRegisterData((char *) (&xlrec), SizeOfCommitTsTruncate);
993  (void) XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_TRUNCATE);
994 }
TransactionId oldestXid
Definition: commit_ts.h:69
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
#define COMMIT_TS_TRUNCATE
Definition: commit_ts.h:52
void XLogBeginInsert(void)
Definition: xloginsert.c:123
#define SizeOfCommitTsTruncate
Definition: commit_ts.h:72

◆ WriteZeroPageXlogRec()

static void WriteZeroPageXlogRec ( int  pageno)
static

Definition at line 973 of file commit_ts.c.

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

Referenced by ZeroCommitTsPage().

974 {
975  XLogBeginInsert();
976  XLogRegisterData((char *) (&pageno), sizeof(int));
977  (void) XLogInsert(RM_COMMIT_TS_ID, COMMIT_TS_ZEROPAGE);
978 }
#define COMMIT_TS_ZEROPAGE
Definition: commit_ts.h:51
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
void XLogBeginInsert(void)
Definition: xloginsert.c:123

◆ ZeroCommitTsPage()

static int ZeroCommitTsPage ( int  pageno,
bool  writeXlog 
)
static

Definition at line 605 of file commit_ts.c.

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

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

606 {
607  int slotno;
608 
609  slotno = SimpleLruZeroPage(CommitTsCtl, pageno);
610 
611  if (writeXlog)
612  WriteZeroPageXlogRec(pageno);
613 
614  return slotno;
615 }
#define CommitTsCtl
Definition: commit_ts.c:79
static void WriteZeroPageXlogRec(int pageno)
Definition: commit_ts.c:973
int SimpleLruZeroPage(SlruCtl ctl, int pageno)
Definition: slru.c:279

Variable Documentation

◆ CommitTsCtlData

SlruCtlData CommitTsCtlData
static

Definition at line 77 of file commit_ts.c.

◆ commitTsShared

CommitTimestampShared* commitTsShared

Definition at line 99 of file commit_ts.c.

◆ track_commit_timestamp

bool track_commit_timestamp