PostgreSQL Source Code  git master
clog.h File Reference
#include "access/xlogreader.h"
#include "storage/sync.h"
#include "lib/stringinfo.h"
Include dependency graph for clog.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  xl_clog_truncate
 

Macros

#define TRANSACTION_STATUS_IN_PROGRESS   0x00
 
#define TRANSACTION_STATUS_COMMITTED   0x01
 
#define TRANSACTION_STATUS_ABORTED   0x02
 
#define TRANSACTION_STATUS_SUB_COMMITTED   0x03
 
#define CLOG_ZEROPAGE   0x00
 
#define CLOG_TRUNCATE   0x10
 

Typedefs

typedef int XidStatus
 
typedef struct xl_clog_truncate xl_clog_truncate
 

Functions

void TransactionIdSetTreeStatus (TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
 
XidStatus TransactionIdGetStatus (TransactionId xid, XLogRecPtr *lsn)
 
Size CLOGShmemBuffers (void)
 
Size CLOGShmemSize (void)
 
void CLOGShmemInit (void)
 
void BootStrapCLOG (void)
 
void StartupCLOG (void)
 
void TrimCLOG (void)
 
void CheckPointCLOG (void)
 
void ExtendCLOG (TransactionId newestXact)
 
void TruncateCLOG (TransactionId oldestXact, Oid oldestxid_datoid)
 
int clogsyncfiletag (const FileTag *ftag, char *path)
 
void clog_redo (XLogReaderState *record)
 
void clog_desc (StringInfo buf, XLogReaderState *record)
 
const char * clog_identify (uint8 info)
 

Macro Definition Documentation

◆ CLOG_TRUNCATE

#define CLOG_TRUNCATE   0x10

Definition at line 57 of file clog.h.

◆ CLOG_ZEROPAGE

#define CLOG_ZEROPAGE   0x00

Definition at line 56 of file clog.h.

◆ TRANSACTION_STATUS_ABORTED

#define TRANSACTION_STATUS_ABORTED   0x02

Definition at line 29 of file clog.h.

◆ TRANSACTION_STATUS_COMMITTED

#define TRANSACTION_STATUS_COMMITTED   0x01

Definition at line 28 of file clog.h.

◆ TRANSACTION_STATUS_IN_PROGRESS

#define TRANSACTION_STATUS_IN_PROGRESS   0x00

Definition at line 27 of file clog.h.

◆ TRANSACTION_STATUS_SUB_COMMITTED

#define TRANSACTION_STATUS_SUB_COMMITTED   0x03

Definition at line 30 of file clog.h.

Typedef Documentation

◆ XidStatus

typedef int XidStatus

Definition at line 25 of file clog.h.

◆ xl_clog_truncate

Function Documentation

◆ BootStrapCLOG()

void BootStrapCLOG ( void  )

Definition at line 722 of file clog.c.

723 {
724  int slotno;
725 
726  LWLockAcquire(XactSLRULock, LW_EXCLUSIVE);
727 
728  /* Create and zero the first page of the commit log */
729  slotno = ZeroCLOGPage(0, false);
730 
731  /* Make sure it's written out */
732  SimpleLruWritePage(XactCtl, slotno);
733  Assert(!XactCtl->shared->page_dirty[slotno]);
734 
735  LWLockRelease(XactSLRULock);
736 }
static int ZeroCLOGPage(int64 pageno, bool writeXlog)
Definition: clog.c:748
#define XactCtl
Definition: clog.c:99
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
@ LW_EXCLUSIVE
Definition: lwlock.h:116
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:649

References Assert(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SimpleLruWritePage(), XactCtl, and ZeroCLOGPage().

Referenced by BootStrapXLOG().

◆ CheckPointCLOG()

void CheckPointCLOG ( void  )

Definition at line 824 of file clog.c.

825 {
826  /*
827  * Write dirty CLOG pages to disk. This may result in sync requests
828  * queued for later handling by ProcessSyncRequests(), as part of the
829  * checkpoint.
830  */
831  TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(true);
832  SimpleLruWriteAll(XactCtl, true);
833  TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(true);
834 }
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1199

References SimpleLruWriteAll(), and XactCtl.

Referenced by CheckPointGuts().

◆ clog_desc()

void clog_desc ( StringInfo  buf,
XLogReaderState record 
)

Definition at line 21 of file clogdesc.c.

22 {
23  char *rec = XLogRecGetData(record);
24  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
25 
26  if (info == CLOG_ZEROPAGE)
27  {
28  int64 pageno;
29 
30  memcpy(&pageno, rec, sizeof(pageno));
31  appendStringInfo(buf, "page %lld", (long long) pageno);
32  }
33  else if (info == CLOG_TRUNCATE)
34  {
35  xl_clog_truncate xlrec;
36 
37  memcpy(&xlrec, rec, sizeof(xl_clog_truncate));
38  appendStringInfo(buf, "page %lld; oldestXact %u",
39  (long long) xlrec.pageno, xlrec.oldestXact);
40  }
41 }
unsigned char uint8
Definition: c.h:493
#define CLOG_ZEROPAGE
Definition: clog.h:56
#define CLOG_TRUNCATE
Definition: clog.h:57
static char * buf
Definition: pg_test_fsync.c:73
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
int64 pageno
Definition: clog.h:34
TransactionId oldestXact
Definition: clog.h:35
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#define XLR_INFO_MASK
Definition: xlogrecord.h:62

References appendStringInfo(), buf, CLOG_TRUNCATE, CLOG_ZEROPAGE, xl_clog_truncate::oldestXact, xl_clog_truncate::pageno, XLogRecGetData, XLogRecGetInfo, and XLR_INFO_MASK.

◆ clog_identify()

const char* clog_identify ( uint8  info)

Definition at line 44 of file clogdesc.c.

45 {
46  const char *id = NULL;
47 
48  switch (info & ~XLR_INFO_MASK)
49  {
50  case CLOG_ZEROPAGE:
51  id = "ZEROPAGE";
52  break;
53  case CLOG_TRUNCATE:
54  id = "TRUNCATE";
55  break;
56  }
57 
58  return id;
59 }

References CLOG_TRUNCATE, CLOG_ZEROPAGE, and XLR_INFO_MASK.

◆ clog_redo()

void clog_redo ( XLogReaderState record)

Definition at line 992 of file clog.c.

993 {
994  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
995 
996  /* Backup blocks are not used in clog records */
997  Assert(!XLogRecHasAnyBlockRefs(record));
998 
999  if (info == CLOG_ZEROPAGE)
1000  {
1001  int64 pageno;
1002  int slotno;
1003 
1004  memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
1005 
1006  LWLockAcquire(XactSLRULock, LW_EXCLUSIVE);
1007 
1008  slotno = ZeroCLOGPage(pageno, false);
1009  SimpleLruWritePage(XactCtl, slotno);
1010  Assert(!XactCtl->shared->page_dirty[slotno]);
1011 
1012  LWLockRelease(XactSLRULock);
1013  }
1014  else if (info == CLOG_TRUNCATE)
1015  {
1016  xl_clog_truncate xlrec;
1017 
1018  memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_clog_truncate));
1019 
1021 
1023  }
1024  else
1025  elog(PANIC, "clog_redo: unknown op code %u", info);
1026 }
#define PANIC
Definition: elog.h:42
void SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
Definition: slru.c:1269
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:355
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:417

References AdvanceOldestClogXid(), Assert(), CLOG_TRUNCATE, CLOG_ZEROPAGE, elog(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_clog_truncate::oldestXact, xl_clog_truncate::pageno, PANIC, SimpleLruTruncate(), SimpleLruWritePage(), XactCtl, XLogRecGetData, XLogRecGetInfo, XLogRecHasAnyBlockRefs, XLR_INFO_MASK, and ZeroCLOGPage().

◆ CLOGShmemBuffers()

Size CLOGShmemBuffers ( void  )

Definition at line 691 of file clog.c.

692 {
693  return Min(128, Max(4, NBuffers / 512));
694 }
#define Min(x, y)
Definition: c.h:993
#define Max(x, y)
Definition: c.h:987
int NBuffers
Definition: globals.c:139

References Max, Min, and NBuffers.

Referenced by CLOGShmemInit(), and CLOGShmemSize().

◆ CLOGShmemInit()

void CLOGShmemInit ( void  )

Definition at line 706 of file clog.c.

707 {
708  XactCtl->PagePrecedes = CLOGPagePrecedes;
710  XactSLRULock, "pg_xact", LWTRANCHE_XACT_BUFFER,
711  SYNC_HANDLER_CLOG, false);
713 }
#define CLOG_XACTS_PER_PAGE
Definition: clog.c:62
Size CLOGShmemBuffers(void)
Definition: clog.c:691
static bool CLOGPagePrecedes(int64 page1, int64 page2)
Definition: clog.c:940
#define CLOG_LSNS_PER_PAGE
Definition: clog.c:82
@ LWTRANCHE_XACT_BUFFER
Definition: lwlock.h:181
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, LWLock *ctllock, const char *subdir, int tranche_id, SyncRequestHandler sync_handler, bool long_segment_names)
Definition: slru.c:215
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition: slru.h:168
@ SYNC_HANDLER_CLOG
Definition: sync.h:38

References CLOG_LSNS_PER_PAGE, CLOG_XACTS_PER_PAGE, CLOGPagePrecedes(), CLOGShmemBuffers(), LWTRANCHE_XACT_BUFFER, SimpleLruInit(), SlruPagePrecedesUnitTests, SYNC_HANDLER_CLOG, and XactCtl.

Referenced by CreateOrAttachShmemStructs().

◆ CLOGShmemSize()

Size CLOGShmemSize ( void  )

Definition at line 700 of file clog.c.

701 {
703 }
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:183

References CLOG_LSNS_PER_PAGE, CLOGShmemBuffers(), and SimpleLruShmemSize().

Referenced by CalculateShmemSize().

◆ clogsyncfiletag()

int clogsyncfiletag ( const FileTag ftag,
char *  path 
)

Definition at line 1032 of file clog.c.

1033 {
1034  return SlruSyncFileTag(XactCtl, ftag, path);
1035 }
int SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path)
Definition: slru.c:1664

References SlruSyncFileTag(), and XactCtl.

◆ ExtendCLOG()

void ExtendCLOG ( TransactionId  newestXact)

Definition at line 846 of file clog.c.

847 {
848  int64 pageno;
849 
850  /*
851  * No work except at first XID of a page. But beware: just after
852  * wraparound, the first XID of page zero is FirstNormalTransactionId.
853  */
854  if (TransactionIdToPgIndex(newestXact) != 0 &&
856  return;
857 
858  pageno = TransactionIdToPage(newestXact);
859 
860  LWLockAcquire(XactSLRULock, LW_EXCLUSIVE);
861 
862  /* Zero the page and make an XLOG entry about it */
863  ZeroCLOGPage(pageno, true);
864 
865  LWLockRelease(XactSLRULock);
866 }
static int64 TransactionIdToPage(TransactionId xid)
Definition: clog.c:71
#define TransactionIdToPgIndex(xid)
Definition: clog.c:76
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define FirstNormalTransactionId
Definition: transam.h:34

References FirstNormalTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), TransactionIdEquals, TransactionIdToPage(), TransactionIdToPgIndex, and ZeroCLOGPage().

Referenced by GetNewTransactionId().

◆ StartupCLOG()

void StartupCLOG ( void  )

Definition at line 765 of file clog.c.

766 {
768  int64 pageno = TransactionIdToPage(xid);
769 
770  /*
771  * Initialize our idea of the latest page number.
772  */
773  pg_atomic_write_u64(&XactCtl->shared->latest_page_number, pageno);
774 }
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:433
uint32 TransactionId
Definition: c.h:641
FullTransactionId nextXid
Definition: transam.h:220
#define XidFromFullTransactionId(x)
Definition: transam.h:48
TransamVariablesData * TransamVariables
Definition: varsup.c:34

References TransamVariablesData::nextXid, pg_atomic_write_u64(), TransactionIdToPage(), TransamVariables, XactCtl, and XidFromFullTransactionId.

Referenced by StartupXLOG().

◆ TransactionIdGetStatus()

XidStatus TransactionIdGetStatus ( TransactionId  xid,
XLogRecPtr lsn 
)

Definition at line 649 of file clog.c.

650 {
651  int64 pageno = TransactionIdToPage(xid);
652  int byteno = TransactionIdToByte(xid);
653  int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
654  int slotno;
655  int lsnindex;
656  char *byteptr;
657  XidStatus status;
658 
659  /* lock is acquired by SimpleLruReadPage_ReadOnly */
660 
661  slotno = SimpleLruReadPage_ReadOnly(XactCtl, pageno, xid);
662  byteptr = XactCtl->shared->page_buffer[slotno] + byteno;
663 
664  status = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
665 
666  lsnindex = GetLSNIndex(slotno, xid);
667  *lsn = XactCtl->shared->group_lsn[lsnindex];
668 
669  LWLockRelease(XactSLRULock);
670 
671  return status;
672 }
#define CLOG_XACT_BITMASK
Definition: clog.c:63
#define TransactionIdToBIndex(xid)
Definition: clog.c:78
#define CLOG_BITS_PER_XACT
Definition: clog.c:60
#define TransactionIdToByte(xid)
Definition: clog.c:77
#define GetLSNIndex(slotno, xid)
Definition: clog.c:84
int XidStatus
Definition: clog.h:25
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno, TransactionId xid)
Definition: slru.c:530

References CLOG_BITS_PER_XACT, CLOG_XACT_BITMASK, GetLSNIndex, LWLockRelease(), SimpleLruReadPage_ReadOnly(), TransactionIdToBIndex, TransactionIdToByte, TransactionIdToPage(), and XactCtl.

Referenced by TransactionIdGetCommitLSN(), and TransactionLogFetch().

◆ TransactionIdSetTreeStatus()

void TransactionIdSetTreeStatus ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn 
)

Definition at line 172 of file clog.c.

174 {
175  int64 pageno = TransactionIdToPage(xid); /* get page of parent */
176  int i;
177 
179  status == TRANSACTION_STATUS_ABORTED);
180 
181  /*
182  * See how many subxids, if any, are on the same page as the parent, if
183  * any.
184  */
185  for (i = 0; i < nsubxids; i++)
186  {
187  if (TransactionIdToPage(subxids[i]) != pageno)
188  break;
189  }
190 
191  /*
192  * Do all items fit on a single page?
193  */
194  if (i == nsubxids)
195  {
196  /*
197  * Set the parent and all subtransactions in a single call
198  */
199  TransactionIdSetPageStatus(xid, nsubxids, subxids, status, lsn,
200  pageno, true);
201  }
202  else
203  {
204  int nsubxids_on_first_page = i;
205 
206  /*
207  * If this is a commit then we care about doing this correctly (i.e.
208  * using the subcommitted intermediate status). By here, we know
209  * we're updating more than one page of clog, so we must mark entries
210  * that are *not* on the first page so that they show as subcommitted
211  * before we then return to update the status to fully committed.
212  *
213  * To avoid touching the first page twice, skip marking subcommitted
214  * for the subxids on that first page.
215  */
216  if (status == TRANSACTION_STATUS_COMMITTED)
217  set_status_by_pages(nsubxids - nsubxids_on_first_page,
218  subxids + nsubxids_on_first_page,
220 
221  /*
222  * Now set the parent and subtransactions on same page as the parent,
223  * if any
224  */
225  pageno = TransactionIdToPage(xid);
226  TransactionIdSetPageStatus(xid, nsubxids_on_first_page, subxids, status,
227  lsn, pageno, false);
228 
229  /*
230  * Now work through the rest of the subxids one clog page at a time,
231  * starting from the second page onwards, like we did above.
232  */
233  set_status_by_pages(nsubxids - nsubxids_on_first_page,
234  subxids + nsubxids_on_first_page,
235  status, lsn);
236  }
237 }
static void TransactionIdSetPageStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int64 pageno, bool all_xact_same_page)
Definition: clog.c:282
static void set_status_by_pages(int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
Definition: clog.c:246
#define TRANSACTION_STATUS_ABORTED
Definition: clog.h:29
#define TRANSACTION_STATUS_SUB_COMMITTED
Definition: clog.h:30
#define TRANSACTION_STATUS_COMMITTED
Definition: clog.h:28
int i
Definition: isn.c:73

References Assert(), i, set_status_by_pages(), TRANSACTION_STATUS_ABORTED, TRANSACTION_STATUS_COMMITTED, TRANSACTION_STATUS_SUB_COMMITTED, TransactionIdSetPageStatus(), and TransactionIdToPage().

Referenced by TransactionIdAbortTree(), TransactionIdAsyncCommitTree(), and TransactionIdCommitTree().

◆ TrimCLOG()

void TrimCLOG ( void  )

Definition at line 780 of file clog.c.

781 {
783  int64 pageno = TransactionIdToPage(xid);
784 
785  LWLockAcquire(XactSLRULock, LW_EXCLUSIVE);
786 
787  /*
788  * Zero out the remainder of the current clog page. Under normal
789  * circumstances it should be zeroes already, but it seems at least
790  * theoretically possible that XLOG replay will have settled on a nextXID
791  * value that is less than the last XID actually used and marked by the
792  * previous database lifecycle (since subtransaction commit writes clog
793  * but makes no WAL entry). Let's just be safe. (We need not worry about
794  * pages beyond the current one, since those will be zeroed when first
795  * used. For the same reason, there is no need to do anything when
796  * nextXid is exactly at a page boundary; and it's likely that the
797  * "current" page doesn't exist yet in that case.)
798  */
799  if (TransactionIdToPgIndex(xid) != 0)
800  {
801  int byteno = TransactionIdToByte(xid);
802  int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
803  int slotno;
804  char *byteptr;
805 
806  slotno = SimpleLruReadPage(XactCtl, pageno, false, xid);
807  byteptr = XactCtl->shared->page_buffer[slotno] + byteno;
808 
809  /* Zero so-far-unused positions in the current byte */
810  *byteptr &= (1 << bshift) - 1;
811  /* Zero the rest of the page */
812  MemSet(byteptr + 1, 0, BLCKSZ - byteno - 1);
813 
814  XactCtl->shared->page_dirty[slotno] = true;
815  }
816 
817  LWLockRelease(XactSLRULock);
818 }
#define MemSet(start, val, len)
Definition: c.h:1009
int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, TransactionId xid)
Definition: slru.c:430

References CLOG_BITS_PER_XACT, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, TransamVariablesData::nextXid, SimpleLruReadPage(), TransactionIdToBIndex, TransactionIdToByte, TransactionIdToPage(), TransactionIdToPgIndex, TransamVariables, XactCtl, and XidFromFullTransactionId.

Referenced by StartupXLOG().

◆ TruncateCLOG()

void TruncateCLOG ( TransactionId  oldestXact,
Oid  oldestxid_datoid 
)

Definition at line 885 of file clog.c.

886 {
887  int64 cutoffPage;
888 
889  /*
890  * The cutoff point is the start of the segment containing oldestXact. We
891  * pass the *page* containing oldestXact to SimpleLruTruncate.
892  */
893  cutoffPage = TransactionIdToPage(oldestXact);
894 
895  /* Check to see if there's any files that could be removed */
897  return; /* nothing to remove */
898 
899  /*
900  * Advance oldestClogXid before truncating clog, so concurrent xact status
901  * lookups can ensure they don't attempt to access truncated-away clog.
902  *
903  * It's only necessary to do this if we will actually truncate away clog
904  * pages.
905  */
906  AdvanceOldestClogXid(oldestXact);
907 
908  /*
909  * Write XLOG record and flush XLOG to disk. We record the oldest xid
910  * we're keeping information about here so we can ensure that it's always
911  * ahead of clog truncation in case we crash, and so a standby finds out
912  * the new valid xid before the next checkpoint.
913  */
914  WriteTruncateXlogRec(cutoffPage, oldestXact, oldestxid_datoid);
915 
916  /* Now we can remove the old CLOG segment(s) */
917  SimpleLruTruncate(XactCtl, cutoffPage);
918 }
static void WriteTruncateXlogRec(int64 pageno, TransactionId oldestXact, Oid oldestXactDb)
Definition: clog.c:973
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition: slru.c:1624
bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, int64 segpage, void *data)
Definition: slru.c:1545

References AdvanceOldestClogXid(), SimpleLruTruncate(), SlruScanDirCbReportPresence(), SlruScanDirectory(), TransactionIdToPage(), WriteTruncateXlogRec(), and XactCtl.

Referenced by vac_truncate_clog().