PostgreSQL Source Code git master
clog.c File Reference
#include "postgres.h"
#include "access/clog.h"
#include "access/slru.h"
#include "access/transam.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "access/xlogutils.h"
#include "miscadmin.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "storage/proc.h"
#include "storage/sync.h"
#include "utils/guc_hooks.h"
Include dependency graph for clog.c:

Go to the source code of this file.

Macros

#define CLOG_BITS_PER_XACT   2
 
#define CLOG_XACTS_PER_BYTE   4
 
#define CLOG_XACTS_PER_PAGE   (BLCKSZ * CLOG_XACTS_PER_BYTE)
 
#define CLOG_XACT_BITMASK   ((1 << CLOG_BITS_PER_XACT) - 1)
 
#define CLOG_MAX_ALLOWED_BUFFERS
 
#define TransactionIdToPgIndex(xid)   ((xid) % (TransactionId) CLOG_XACTS_PER_PAGE)
 
#define TransactionIdToByte(xid)   (TransactionIdToPgIndex(xid) / CLOG_XACTS_PER_BYTE)
 
#define TransactionIdToBIndex(xid)   ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE)
 
#define CLOG_XACTS_PER_LSN_GROUP   32 /* keep this a power of 2 */
 
#define CLOG_LSNS_PER_PAGE   (CLOG_XACTS_PER_PAGE / CLOG_XACTS_PER_LSN_GROUP)
 
#define GetLSNIndex(slotno, xid)
 
#define THRESHOLD_SUBTRANS_CLOG_OPT   5
 
#define XactCtl   (&XactCtlData)
 

Functions

static int64 TransactionIdToPage (TransactionId xid)
 
static int ZeroCLOGPage (int64 pageno, bool writeXlog)
 
static bool CLOGPagePrecedes (int64 page1, int64 page2)
 
static void WriteZeroPageXlogRec (int64 pageno)
 
static void WriteTruncateXlogRec (int64 pageno, TransactionId oldestXact, Oid oldestXactDb)
 
static void TransactionIdSetPageStatus (TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int64 pageno, bool all_xact_same_page)
 
static void TransactionIdSetStatusBit (TransactionId xid, XidStatus status, XLogRecPtr lsn, int slotno)
 
static void set_status_by_pages (int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
 
static bool TransactionGroupUpdateXidStatus (TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno)
 
static void TransactionIdSetPageStatusInternal (TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int64 pageno)
 
void TransactionIdSetTreeStatus (TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn)
 
XidStatus TransactionIdGetStatus (TransactionId xid, XLogRecPtr *lsn)
 
static int CLOGShmemBuffers (void)
 
Size CLOGShmemSize (void)
 
void CLOGShmemInit (void)
 
bool check_transaction_buffers (int *newval, void **extra, GucSource source)
 
void BootStrapCLOG (void)
 
void StartupCLOG (void)
 
void TrimCLOG (void)
 
void CheckPointCLOG (void)
 
void ExtendCLOG (TransactionId newestXact)
 
void TruncateCLOG (TransactionId oldestXact, Oid oldestxid_datoid)
 
void clog_redo (XLogReaderState *record)
 
int clogsyncfiletag (const FileTag *ftag, char *path)
 

Variables

static SlruCtlData XactCtlData
 

Macro Definition Documentation

◆ CLOG_BITS_PER_XACT

#define CLOG_BITS_PER_XACT   2

Definition at line 62 of file clog.c.

◆ CLOG_LSNS_PER_PAGE

#define CLOG_LSNS_PER_PAGE   (CLOG_XACTS_PER_PAGE / CLOG_XACTS_PER_LSN_GROUP)

Definition at line 93 of file clog.c.

◆ CLOG_MAX_ALLOWED_BUFFERS

#define CLOG_MAX_ALLOWED_BUFFERS
Value:
#define Min(x, y)
Definition: c.h:961
#define CLOG_XACTS_PER_PAGE
Definition: clog.c:64
#define SLRU_MAX_ALLOWED_BUFFERS
Definition: slru.h:24
#define MaxTransactionId
Definition: transam.h:35

Definition at line 72 of file clog.c.

◆ CLOG_XACT_BITMASK

#define CLOG_XACT_BITMASK   ((1 << CLOG_BITS_PER_XACT) - 1)

Definition at line 65 of file clog.c.

◆ CLOG_XACTS_PER_BYTE

#define CLOG_XACTS_PER_BYTE   4

Definition at line 63 of file clog.c.

◆ CLOG_XACTS_PER_LSN_GROUP

#define CLOG_XACTS_PER_LSN_GROUP   32 /* keep this a power of 2 */

Definition at line 92 of file clog.c.

◆ CLOG_XACTS_PER_PAGE

#define CLOG_XACTS_PER_PAGE   (BLCKSZ * CLOG_XACTS_PER_BYTE)

Definition at line 64 of file clog.c.

◆ GetLSNIndex

#define GetLSNIndex (   slotno,
  xid 
)
Value:
((slotno) * CLOG_LSNS_PER_PAGE + \
uint32 TransactionId
Definition: c.h:609
#define CLOG_XACTS_PER_LSN_GROUP
Definition: clog.c:92
#define CLOG_LSNS_PER_PAGE
Definition: clog.c:93

Definition at line 95 of file clog.c.

◆ THRESHOLD_SUBTRANS_CLOG_OPT

#define THRESHOLD_SUBTRANS_CLOG_OPT   5

Definition at line 103 of file clog.c.

◆ TransactionIdToBIndex

#define TransactionIdToBIndex (   xid)    ((xid) % (TransactionId) CLOG_XACTS_PER_BYTE)

Definition at line 89 of file clog.c.

◆ TransactionIdToByte

#define TransactionIdToByte (   xid)    (TransactionIdToPgIndex(xid) / CLOG_XACTS_PER_BYTE)

Definition at line 88 of file clog.c.

◆ TransactionIdToPgIndex

#define TransactionIdToPgIndex (   xid)    ((xid) % (TransactionId) CLOG_XACTS_PER_PAGE)

Definition at line 87 of file clog.c.

◆ XactCtl

#define XactCtl   (&XactCtlData)

Definition at line 110 of file clog.c.

Function Documentation

◆ BootStrapCLOG()

void BootStrapCLOG ( void  )

Definition at line 833 of file clog.c.

834{
835 int slotno;
837
839
840 /* Create and zero the first page of the commit log */
841 slotno = ZeroCLOGPage(0, false);
842
843 /* Make sure it's written out */
845 Assert(!XactCtl->shared->page_dirty[slotno]);
846
847 LWLockRelease(lock);
848}
#define Assert(condition)
Definition: c.h:815
static int ZeroCLOGPage(int64 pageno, bool writeXlog)
Definition: clog.c:860
#define XactCtl
Definition: clog.c:110
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1168
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1781
@ LW_EXCLUSIVE
Definition: lwlock.h:114
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:732
static LWLock * SimpleLruGetBankLock(SlruCtl ctl, int64 pageno)
Definition: slru.h:175
Definition: lwlock.h:42

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

Referenced by BootStrapXLOG().

◆ check_transaction_buffers()

bool check_transaction_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 821 of file clog.c.

822{
823 return check_slru_buffers("transaction_buffers", newval);
824}
#define newval
bool check_slru_buffers(const char *name, int *newval)
Definition: slru.c:355

References check_slru_buffers(), and newval.

◆ CheckPointCLOG()

void CheckPointCLOG ( void  )

Definition at line 937 of file clog.c.

938{
939 /*
940 * Write dirty CLOG pages to disk. This may result in sync requests
941 * queued for later handling by ProcessSyncRequests(), as part of the
942 * checkpoint.
943 */
944 TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(true);
946 TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(true);
947}
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1322

References SimpleLruWriteAll(), and XactCtl.

Referenced by CheckPointGuts().

◆ clog_redo()

void clog_redo ( XLogReaderState record)

Definition at line 1107 of file clog.c.

1108{
1109 uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1110
1111 /* Backup blocks are not used in clog records */
1113
1114 if (info == CLOG_ZEROPAGE)
1115 {
1116 int64 pageno;
1117 int slotno;
1118 LWLock *lock;
1119
1120 memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
1121
1122 lock = SimpleLruGetBankLock(XactCtl, pageno);
1124
1125 slotno = ZeroCLOGPage(pageno, false);
1126 SimpleLruWritePage(XactCtl, slotno);
1127 Assert(!XactCtl->shared->page_dirty[slotno]);
1128
1129 LWLockRelease(lock);
1130 }
1131 else if (info == CLOG_TRUNCATE)
1132 {
1133 xl_clog_truncate xlrec;
1134
1135 memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_clog_truncate));
1136
1138
1140 }
1141 else
1142 elog(PANIC, "clog_redo: unknown op code %u", info);
1143}
uint8_t uint8
Definition: c.h:486
int64_t int64
Definition: c.h:485
#define CLOG_ZEROPAGE
Definition: clog.h:55
#define CLOG_TRUNCATE
Definition: clog.h:56
#define PANIC
Definition: elog.h:42
#define elog(elevel,...)
Definition: elog.h:225
void SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
Definition: slru.c:1408
int64 pageno
Definition: clog.h:34
TransactionId oldestXact
Definition: clog.h:35
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:355
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:410
#define XLogRecGetData(decoder)
Definition: xlogreader.h:415
#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, SimpleLruGetBankLock(), SimpleLruTruncate(), SimpleLruWritePage(), XactCtl, XLogRecGetData, XLogRecGetInfo, XLogRecHasAnyBlockRefs, and ZeroCLOGPage().

◆ CLOGPagePrecedes()

static bool CLOGPagePrecedes ( int64  page1,
int64  page2 
)
static

Definition at line 1055 of file clog.c.

1056{
1057 TransactionId xid1;
1058 TransactionId xid2;
1059
1060 xid1 = ((TransactionId) page1) * CLOG_XACTS_PER_PAGE;
1061 xid1 += FirstNormalTransactionId + 1;
1062 xid2 = ((TransactionId) page2) * CLOG_XACTS_PER_PAGE;
1063 xid2 += FirstNormalTransactionId + 1;
1064
1065 return (TransactionIdPrecedes(xid1, xid2) &&
1066 TransactionIdPrecedes(xid1, xid2 + CLOG_XACTS_PER_PAGE - 1));
1067}
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
#define FirstNormalTransactionId
Definition: transam.h:34

References CLOG_XACTS_PER_PAGE, FirstNormalTransactionId, and TransactionIdPrecedes().

Referenced by CLOGShmemInit().

◆ CLOGShmemBuffers()

static int CLOGShmemBuffers ( void  )
static

Definition at line 768 of file clog.c.

769{
770 /* auto-tune based on shared buffers */
771 if (transaction_buffers == 0)
772 return SimpleLruAutotuneBuffers(512, 1024);
773
775}
#define Max(x, y)
Definition: c.h:955
#define CLOG_MAX_ALLOWED_BUFFERS
Definition: clog.c:72
int transaction_buffers
Definition: globals.c:166
int SimpleLruAutotuneBuffers(int divisor, int max)
Definition: slru.c:232

References CLOG_MAX_ALLOWED_BUFFERS, Max, Min, SimpleLruAutotuneBuffers(), and transaction_buffers.

Referenced by CLOGShmemInit(), and CLOGShmemSize().

◆ CLOGShmemInit()

void CLOGShmemInit ( void  )

Definition at line 787 of file clog.c.

788{
789 /* If auto-tuning is requested, now is the time to do it */
790 if (transaction_buffers == 0)
791 {
792 char buf[32];
793
794 snprintf(buf, sizeof(buf), "%d", CLOGShmemBuffers());
795 SetConfigOption("transaction_buffers", buf, PGC_POSTMASTER,
797
798 /*
799 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
800 * However, if the DBA explicitly set transaction_buffers = 0 in the
801 * config file, then PGC_S_DYNAMIC_DEFAULT will fail to override that
802 * and we must force the matter with PGC_S_OVERRIDE.
803 */
804 if (transaction_buffers == 0) /* failed to apply it? */
805 SetConfigOption("transaction_buffers", buf, PGC_POSTMASTER,
807 }
809
810 XactCtl->PagePrecedes = CLOGPagePrecedes;
812 "pg_xact", LWTRANCHE_XACT_BUFFER,
815}
static int CLOGShmemBuffers(void)
Definition: clog.c:768
static bool CLOGPagePrecedes(int64 page1, int64 page2)
Definition: clog.c:1055
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:4332
@ PGC_S_DYNAMIC_DEFAULT
Definition: guc.h:110
@ PGC_S_OVERRIDE
Definition: guc.h:119
@ PGC_POSTMASTER
Definition: guc.h:70
@ LWTRANCHE_XACT_BUFFER
Definition: lwlock.h:179
@ LWTRANCHE_XACT_SLRU
Definition: lwlock.h:216
static char * buf
Definition: pg_test_fsync.c:72
#define snprintf
Definition: port.h:238
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, const char *subdir, int buffer_tranche_id, int bank_tranche_id, SyncRequestHandler sync_handler, bool long_segment_names)
Definition: slru.c:252
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition: slru.h:199
@ SYNC_HANDLER_CLOG
Definition: sync.h:38

References Assert, buf, CLOG_LSNS_PER_PAGE, CLOG_XACTS_PER_PAGE, CLOGPagePrecedes(), CLOGShmemBuffers(), LWTRANCHE_XACT_BUFFER, LWTRANCHE_XACT_SLRU, PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT, PGC_S_OVERRIDE, SetConfigOption(), SimpleLruInit(), SlruPagePrecedesUnitTests, snprintf, SYNC_HANDLER_CLOG, transaction_buffers, and XactCtl.

Referenced by CreateOrAttachShmemStructs().

◆ CLOGShmemSize()

Size CLOGShmemSize ( void  )

Definition at line 781 of file clog.c.

782{
784}
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:199

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

Referenced by CalculateShmemSize().

◆ clogsyncfiletag()

int clogsyncfiletag ( const FileTag ftag,
char *  path 
)

Definition at line 1149 of file clog.c.

1150{
1151 return SlruSyncFileTag(XactCtl, ftag, path);
1152}
int SlruSyncFileTag(SlruCtl ctl, const FileTag *ftag, char *path)
Definition: slru.c:1831

References SlruSyncFileTag(), and XactCtl.

◆ ExtendCLOG()

void ExtendCLOG ( TransactionId  newestXact)

Definition at line 959 of file clog.c.

960{
961 int64 pageno;
962 LWLock *lock;
963
964 /*
965 * No work except at first XID of a page. But beware: just after
966 * wraparound, the first XID of page zero is FirstNormalTransactionId.
967 */
968 if (TransactionIdToPgIndex(newestXact) != 0 &&
970 return;
971
972 pageno = TransactionIdToPage(newestXact);
973 lock = SimpleLruGetBankLock(XactCtl, pageno);
974
976
977 /* Zero the page and make an XLOG entry about it */
978 ZeroCLOGPage(pageno, true);
979
980 LWLockRelease(lock);
981}
static int64 TransactionIdToPage(TransactionId xid)
Definition: clog.c:82
#define TransactionIdToPgIndex(xid)
Definition: clog.c:87
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43

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

Referenced by GetNewTransactionId().

◆ set_status_by_pages()

static void set_status_by_pages ( int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn 
)
static

Definition at line 257 of file clog.c.

259{
260 int64 pageno = TransactionIdToPage(subxids[0]);
261 int offset = 0;
262 int i = 0;
263
264 Assert(nsubxids > 0); /* else the pageno fetch above is unsafe */
265
266 while (i < nsubxids)
267 {
268 int num_on_page = 0;
269 int64 nextpageno;
270
271 do
272 {
273 nextpageno = TransactionIdToPage(subxids[i]);
274 if (nextpageno != pageno)
275 break;
276 num_on_page++;
277 i++;
278 } while (i < nsubxids);
279
281 num_on_page, subxids + offset,
282 status, lsn, pageno, false);
283 offset = i;
284 pageno = nextpageno;
285 }
286}
static void TransactionIdSetPageStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int64 pageno, bool all_xact_same_page)
Definition: clog.c:293
int i
Definition: isn.c:72
#define InvalidTransactionId
Definition: transam.h:31

References Assert, i, InvalidTransactionId, TransactionIdSetPageStatus(), and TransactionIdToPage().

Referenced by TransactionIdSetTreeStatus().

◆ StartupCLOG()

void StartupCLOG ( void  )

Definition at line 877 of file clog.c.

878{
880 int64 pageno = TransactionIdToPage(xid);
881
882 /*
883 * Initialize our idea of the latest page number.
884 */
885 pg_atomic_write_u64(&XactCtl->shared->latest_page_number, pageno);
886}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
Definition: atomics.h:485
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().

◆ TransactionGroupUpdateXidStatus()

static bool TransactionGroupUpdateXidStatus ( TransactionId  xid,
XidStatus  status,
XLogRecPtr  lsn,
int64  pageno 
)
static

Definition at line 441 of file clog.c.

443{
444 volatile PROC_HDR *procglobal = ProcGlobal;
445 PGPROC *proc = MyProc;
446 uint32 nextidx;
447 uint32 wakeidx;
448 int64 prevpageno;
449 LWLock *prevlock = NULL;
450
451 /* We should definitely have an XID whose status needs to be updated. */
453
454 /*
455 * Prepare to add ourselves to the list of processes needing a group XID
456 * status update.
457 */
458 proc->clogGroupMember = true;
459 proc->clogGroupMemberXid = xid;
460 proc->clogGroupMemberXidStatus = status;
461 proc->clogGroupMemberPage = pageno;
462 proc->clogGroupMemberLsn = lsn;
463
464 /*
465 * We put ourselves in the queue by writing MyProcNumber to
466 * ProcGlobal->clogGroupFirst. However, if there's already a process
467 * listed there, we compare our pageno with that of that process; if it
468 * differs, we cannot participate in the group, so we return for caller to
469 * update pg_xact in the normal way.
470 *
471 * If we're not the first process in the list, we must follow the leader.
472 * We do this by storing the data we want updated in our PGPROC entry
473 * where the leader can find it, then going to sleep.
474 *
475 * If no process is already in the list, we're the leader; our first step
476 * is to lock the SLRU bank to which our page belongs, then we close out
477 * the group by resetting the list pointer from ProcGlobal->clogGroupFirst
478 * (this lets other processes set up other groups later); finally we do
479 * the SLRU updates, release the SLRU bank lock, and wake up the sleeping
480 * processes.
481 *
482 * If another group starts to update a page in a different SLRU bank, they
483 * can proceed concurrently, since the bank lock they're going to use is
484 * different from ours. If another group starts to update a page in the
485 * same bank as ours, they wait until we release the lock.
486 */
487 nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
488
489 while (true)
490 {
491 /*
492 * Add the proc to list, if the clog page where we need to update the
493 * current transaction status is same as group leader's clog page.
494 *
495 * There is a race condition here, which is that after doing the below
496 * check and before adding this proc's clog update to a group, the
497 * group leader might have already finished the group update for this
498 * page and becomes group leader of another group, updating a
499 * different page. This will lead to a situation where a single group
500 * can have different clog page updates. This isn't likely and will
501 * still work, just less efficiently -- we handle this case by
502 * switching to a different bank lock in the loop below.
503 */
504 if (nextidx != INVALID_PROC_NUMBER &&
505 GetPGProcByNumber(nextidx)->clogGroupMemberPage != proc->clogGroupMemberPage)
506 {
507 /*
508 * Ensure that this proc is not a member of any clog group that
509 * needs an XID status update.
510 */
511 proc->clogGroupMember = false;
513 return false;
514 }
515
516 pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
517
519 &nextidx,
521 break;
522 }
523
524 /*
525 * If the list was not empty, the leader will update the status of our
526 * XID. It is impossible to have followers without a leader because the
527 * first process that has added itself to the list will always have
528 * nextidx as INVALID_PROC_NUMBER.
529 */
530 if (nextidx != INVALID_PROC_NUMBER)
531 {
532 int extraWaits = 0;
533
534 /* Sleep until the leader updates our XID status. */
535 pgstat_report_wait_start(WAIT_EVENT_XACT_GROUP_UPDATE);
536 for (;;)
537 {
538 /* acts as a read barrier */
539 PGSemaphoreLock(proc->sem);
540 if (!proc->clogGroupMember)
541 break;
542 extraWaits++;
543 }
545
547
548 /* Fix semaphore count for any absorbed wakeups */
549 while (extraWaits-- > 0)
550 PGSemaphoreUnlock(proc->sem);
551 return true;
552 }
553
554 /*
555 * By here, we know we're the leader process. Acquire the SLRU bank lock
556 * that corresponds to the page we originally wanted to modify.
557 */
558 prevpageno = proc->clogGroupMemberPage;
559 prevlock = SimpleLruGetBankLock(XactCtl, prevpageno);
560 LWLockAcquire(prevlock, LW_EXCLUSIVE);
561
562 /*
563 * Now that we've got the lock, clear the list of processes waiting for
564 * group XID status update, saving a pointer to the head of the list.
565 * (Trying to pop elements one at a time could lead to an ABA problem.)
566 *
567 * At this point, any processes trying to do this would create a separate
568 * group.
569 */
570 nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
572
573 /* Remember head of list so we can perform wakeups after dropping lock. */
574 wakeidx = nextidx;
575
576 /* Walk the list and update the status of all XIDs. */
577 while (nextidx != INVALID_PROC_NUMBER)
578 {
579 PGPROC *nextproc = &ProcGlobal->allProcs[nextidx];
580 int64 thispageno = nextproc->clogGroupMemberPage;
581
582 /*
583 * If the page to update belongs to a different bank than the previous
584 * one, exchange bank lock to the new one. This should be quite rare,
585 * as described above.
586 *
587 * (We could try to optimize this by waking up the processes for which
588 * we have already updated the status while we exchange the lock, but
589 * the code doesn't do that at present. I think it'd require
590 * additional bookkeeping, making the common path slower in order to
591 * improve an infrequent case.)
592 */
593 if (thispageno != prevpageno)
594 {
595 LWLock *lock = SimpleLruGetBankLock(XactCtl, thispageno);
596
597 if (prevlock != lock)
598 {
599 LWLockRelease(prevlock);
601 }
602 prevlock = lock;
603 prevpageno = thispageno;
604 }
605
606 /*
607 * Transactions with more than THRESHOLD_SUBTRANS_CLOG_OPT sub-XIDs
608 * should not use group XID status update mechanism.
609 */
611
613 nextproc->subxidStatus.count,
614 nextproc->subxids.xids,
615 nextproc->clogGroupMemberXidStatus,
616 nextproc->clogGroupMemberLsn,
617 nextproc->clogGroupMemberPage);
618
619 /* Move to next proc in list. */
620 nextidx = pg_atomic_read_u32(&nextproc->clogGroupNext);
621 }
622
623 /* We're done with the lock now. */
624 if (prevlock != NULL)
625 LWLockRelease(prevlock);
626
627 /*
628 * Now that we've released the lock, go back and wake everybody up. We
629 * don't do this under the lock so as to keep lock hold times to a
630 * minimum.
631 *
632 * (Perhaps we could do this in two passes, the first setting
633 * clogGroupNext to invalid while saving the semaphores to an array, then
634 * a single write barrier, then another pass unlocking the semaphores.)
635 */
636 while (wakeidx != INVALID_PROC_NUMBER)
637 {
638 PGPROC *wakeproc = &ProcGlobal->allProcs[wakeidx];
639
640 wakeidx = pg_atomic_read_u32(&wakeproc->clogGroupNext);
642
643 /* ensure all previous writes are visible before follower continues. */
645
646 wakeproc->clogGroupMember = false;
647
648 if (wakeproc != MyProc)
649 PGSemaphoreUnlock(wakeproc->sem);
650 }
651
652 return true;
653}
static bool pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval)
Definition: atomics.h:349
#define pg_write_barrier()
Definition: atomics.h:157
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:276
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:239
static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
Definition: atomics.h:330
uint32_t uint32
Definition: c.h:488
#define THRESHOLD_SUBTRANS_CLOG_OPT
Definition: clog.c:103
static void TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int64 pageno)
Definition: clog.c:364
ProcNumber MyProcNumber
Definition: globals.c:89
void PGSemaphoreUnlock(PGSemaphore sema)
Definition: posix_sema.c:339
void PGSemaphoreLock(PGSemaphore sema)
Definition: posix_sema.c:319
#define GetPGProcByNumber(n)
Definition: proc.h:423
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
PGPROC * MyProc
Definition: proc.c:66
PROC_HDR * ProcGlobal
Definition: proc.c:78
Definition: proc.h:162
XLogRecPtr clogGroupMemberLsn
Definition: proc.h:289
TransactionId clogGroupMemberXid
Definition: proc.h:284
int64 clogGroupMemberPage
Definition: proc.h:287
bool clogGroupMember
Definition: proc.h:282
pg_atomic_uint32 clogGroupNext
Definition: proc.h:283
XidStatus clogGroupMemberXidStatus
Definition: proc.h:285
XidCacheStatus subxidStatus
Definition: proc.h:263
struct XidCache subxids
Definition: proc.h:265
PGSemaphore sem
Definition: proc.h:166
Definition: proc.h:369
PGPROC * allProcs
Definition: proc.h:371
pg_atomic_uint32 clogGroupFirst
Definition: proc.h:401
uint8 count
Definition: proc.h:44
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]
Definition: proc.h:51
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: wait_event.h:85
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101

References PROC_HDR::allProcs, Assert, PROC_HDR::clogGroupFirst, PGPROC::clogGroupMember, PGPROC::clogGroupMemberLsn, PGPROC::clogGroupMemberPage, PGPROC::clogGroupMemberXid, PGPROC::clogGroupMemberXidStatus, PGPROC::clogGroupNext, XidCacheStatus::count, GetPGProcByNumber, INVALID_PROC_NUMBER, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyProc, MyProcNumber, pg_atomic_compare_exchange_u32(), pg_atomic_exchange_u32(), pg_atomic_read_u32(), pg_atomic_write_u32(), pg_write_barrier, PGSemaphoreLock(), PGSemaphoreUnlock(), pgstat_report_wait_end(), pgstat_report_wait_start(), ProcGlobal, PGPROC::sem, SimpleLruGetBankLock(), PGPROC::subxids, PGPROC::subxidStatus, THRESHOLD_SUBTRANS_CLOG_OPT, TransactionIdIsValid, TransactionIdSetPageStatusInternal(), XactCtl, and XidCache::xids.

Referenced by TransactionIdSetPageStatus().

◆ TransactionIdGetStatus()

XidStatus TransactionIdGetStatus ( TransactionId  xid,
XLogRecPtr lsn 
)

Definition at line 735 of file clog.c.

736{
737 int64 pageno = TransactionIdToPage(xid);
738 int byteno = TransactionIdToByte(xid);
739 int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
740 int slotno;
741 int lsnindex;
742 char *byteptr;
743 XidStatus status;
744
745 /* lock is acquired by SimpleLruReadPage_ReadOnly */
746
747 slotno = SimpleLruReadPage_ReadOnly(XactCtl, pageno, xid);
748 byteptr = XactCtl->shared->page_buffer[slotno] + byteno;
749
750 status = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
751
752 lsnindex = GetLSNIndex(slotno, xid);
753 *lsn = XactCtl->shared->group_lsn[lsnindex];
754
756
757 return status;
758}
#define CLOG_XACT_BITMASK
Definition: clog.c:65
#define TransactionIdToBIndex(xid)
Definition: clog.c:89
#define CLOG_BITS_PER_XACT
Definition: clog.c:62
#define TransactionIdToByte(xid)
Definition: clog.c:88
#define GetLSNIndex(slotno, xid)
Definition: clog.c:95
int XidStatus
Definition: clog.h:25
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno, TransactionId xid)
Definition: slru.c:605

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

Referenced by TransactionIdGetCommitLSN(), and TransactionLogFetch().

◆ TransactionIdSetPageStatus()

static void TransactionIdSetPageStatus ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn,
int64  pageno,
bool  all_xact_same_page 
)
static

Definition at line 293 of file clog.c.

297{
298 LWLock *lock;
299
300 /* Can't use group update when PGPROC overflows. */
302 "group clog threshold less than PGPROC cached subxids");
303
304 /* Get the SLRU bank lock for the page we are going to access. */
305 lock = SimpleLruGetBankLock(XactCtl, pageno);
306
307 /*
308 * When there is contention on the SLRU bank lock we need, we try to group
309 * multiple updates; a single leader process will perform transaction
310 * status updates for multiple backends so that the number of times the
311 * bank lock needs to be acquired is reduced.
312 *
313 * For this optimization to be safe, the XID and subxids in MyProc must be
314 * the same as the ones for which we're setting the status. Check that
315 * this is the case.
316 *
317 * For this optimization to be efficient, we shouldn't have too many
318 * sub-XIDs and all of the XIDs for which we're adjusting clog should be
319 * on the same page. Check those conditions, too.
320 */
321 if (all_xact_same_page && xid == MyProc->xid &&
322 nsubxids <= THRESHOLD_SUBTRANS_CLOG_OPT &&
323 nsubxids == MyProc->subxidStatus.count &&
324 (nsubxids == 0 ||
325 memcmp(subxids, MyProc->subxids.xids,
326 nsubxids * sizeof(TransactionId)) == 0))
327 {
328 /*
329 * If we can immediately acquire the lock, we update the status of our
330 * own XID and release the lock. If not, try use group XID update. If
331 * that doesn't work out, fall back to waiting for the lock to perform
332 * an update for this transaction only.
333 */
335 {
336 /* Got the lock without waiting! Do the update. */
337 TransactionIdSetPageStatusInternal(xid, nsubxids, subxids, status,
338 lsn, pageno);
339 LWLockRelease(lock);
340 return;
341 }
342 else if (TransactionGroupUpdateXidStatus(xid, status, lsn, pageno))
343 {
344 /* Group update mechanism has done the work. */
345 return;
346 }
347
348 /* Fall through only if update isn't done yet. */
349 }
350
351 /* Group update not applicable, or couldn't accept this page number. */
353 TransactionIdSetPageStatusInternal(xid, nsubxids, subxids, status,
354 lsn, pageno);
355 LWLockRelease(lock);
356}
#define StaticAssertDecl(condition, errmessage)
Definition: c.h:893
static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int64 pageno)
Definition: clog.c:441
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1339
#define PGPROC_MAX_CACHED_SUBXIDS
Definition: proc.h:39
TransactionId xid
Definition: proc.h:172

References XidCacheStatus::count, LW_EXCLUSIVE, LWLockAcquire(), LWLockConditionalAcquire(), LWLockRelease(), MyProc, PGPROC_MAX_CACHED_SUBXIDS, SimpleLruGetBankLock(), StaticAssertDecl, PGPROC::subxids, PGPROC::subxidStatus, THRESHOLD_SUBTRANS_CLOG_OPT, TransactionGroupUpdateXidStatus(), TransactionIdSetPageStatusInternal(), XactCtl, PGPROC::xid, and XidCache::xids.

Referenced by set_status_by_pages(), and TransactionIdSetTreeStatus().

◆ TransactionIdSetPageStatusInternal()

static void TransactionIdSetPageStatusInternal ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn,
int64  pageno 
)
static

Definition at line 364 of file clog.c.

367{
368 int slotno;
369 int i;
370
372 status == TRANSACTION_STATUS_ABORTED ||
375 LW_EXCLUSIVE));
376
377 /*
378 * If we're doing an async commit (ie, lsn is valid), then we must wait
379 * for any active write on the page slot to complete. Otherwise our
380 * update could reach disk in that write, which will not do since we
381 * mustn't let it reach disk until we've done the appropriate WAL flush.
382 * But when lsn is invalid, it's OK to scribble on a page while it is
383 * write-busy, since we don't care if the update reaches disk sooner than
384 * we think.
385 */
386 slotno = SimpleLruReadPage(XactCtl, pageno, XLogRecPtrIsInvalid(lsn), xid);
387
388 /*
389 * Set the main transaction id, if any.
390 *
391 * If we update more than one xid on this page while it is being written
392 * out, we might find that some of the bits go to disk and others don't.
393 * If we are updating commits on the page with the top-level xid that
394 * could break atomicity, so we subcommit the subxids first before we mark
395 * the top-level commit.
396 */
397 if (TransactionIdIsValid(xid))
398 {
399 /* Subtransactions first, if needed ... */
400 if (status == TRANSACTION_STATUS_COMMITTED)
401 {
402 for (i = 0; i < nsubxids; i++)
403 {
404 Assert(XactCtl->shared->page_number[slotno] == TransactionIdToPage(subxids[i]));
407 lsn, slotno);
408 }
409 }
410
411 /* ... then the main transaction */
412 TransactionIdSetStatusBit(xid, status, lsn, slotno);
413 }
414
415 /* Set the subtransactions */
416 for (i = 0; i < nsubxids; i++)
417 {
418 Assert(XactCtl->shared->page_number[slotno] == TransactionIdToPage(subxids[i]));
419 TransactionIdSetStatusBit(subxids[i], status, lsn, slotno);
420 }
421
422 XactCtl->shared->page_dirty[slotno] = true;
423}
static void TransactionIdSetStatusBit(TransactionId xid, XidStatus status, XLogRecPtr lsn, int slotno)
Definition: clog.c:661
#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
bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1937
int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, TransactionId xid)
Definition: slru.c:502
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29

References Assert, i, LW_EXCLUSIVE, LWLockHeldByMeInMode(), SimpleLruGetBankLock(), SimpleLruReadPage(), TRANSACTION_STATUS_ABORTED, TRANSACTION_STATUS_COMMITTED, TRANSACTION_STATUS_SUB_COMMITTED, TransactionIdIsValid, TransactionIdSetStatusBit(), TransactionIdToPage(), XactCtl, and XLogRecPtrIsInvalid.

Referenced by TransactionGroupUpdateXidStatus(), and TransactionIdSetPageStatus().

◆ TransactionIdSetStatusBit()

static void TransactionIdSetStatusBit ( TransactionId  xid,
XidStatus  status,
XLogRecPtr  lsn,
int  slotno 
)
static

Definition at line 661 of file clog.c.

662{
663 int byteno = TransactionIdToByte(xid);
664 int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
665 char *byteptr;
666 char byteval;
667 char curval;
668
669 Assert(XactCtl->shared->page_number[slotno] == TransactionIdToPage(xid));
671 XactCtl->shared->page_number[slotno]),
672 LW_EXCLUSIVE));
673
674 byteptr = XactCtl->shared->page_buffer[slotno] + byteno;
675 curval = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
676
677 /*
678 * When replaying transactions during recovery we still need to perform
679 * the two phases of subcommit and then commit. However, some transactions
680 * are already correctly marked, so we just treat those as a no-op which
681 * allows us to keep the following Assert as restrictive as possible.
682 */
685 return;
686
687 /*
688 * Current state change should be from 0 or subcommitted to target state
689 * or we should already be there when replaying changes during recovery.
690 */
691 Assert(curval == 0 ||
694 curval == status);
695
696 /* note this assumes exclusive access to the clog page */
697 byteval = *byteptr;
698 byteval &= ~(((1 << CLOG_BITS_PER_XACT) - 1) << bshift);
699 byteval |= (status << bshift);
700 *byteptr = byteval;
701
702 /*
703 * Update the group LSN if the transaction completion LSN is higher.
704 *
705 * Note: lsn will be invalid when supplied during InRecovery processing,
706 * so we don't need to do anything special to avoid LSN updates during
707 * recovery. After recovery completes the next clog change will set the
708 * LSN correctly.
709 */
710 if (!XLogRecPtrIsInvalid(lsn))
711 {
712 int lsnindex = GetLSNIndex(slotno, xid);
713
714 if (XactCtl->shared->group_lsn[lsnindex] < lsn)
715 XactCtl->shared->group_lsn[lsnindex] = lsn;
716 }
717}
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:27
bool InRecovery
Definition: xlogutils.c:50

References Assert, CLOG_BITS_PER_XACT, CLOG_XACT_BITMASK, GetLSNIndex, InRecovery, LW_EXCLUSIVE, LWLockHeldByMeInMode(), SimpleLruGetBankLock(), TRANSACTION_STATUS_COMMITTED, TRANSACTION_STATUS_IN_PROGRESS, TRANSACTION_STATUS_SUB_COMMITTED, TransactionIdToBIndex, TransactionIdToByte, TransactionIdToPage(), XactCtl, and XLogRecPtrIsInvalid.

Referenced by TransactionIdSetPageStatusInternal().

◆ TransactionIdSetTreeStatus()

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

Definition at line 183 of file clog.c.

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

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().

◆ TransactionIdToPage()

◆ TrimCLOG()

void TrimCLOG ( void  )

Definition at line 892 of file clog.c.

893{
895 int64 pageno = TransactionIdToPage(xid);
896 LWLock *lock = SimpleLruGetBankLock(XactCtl, pageno);
897
899
900 /*
901 * Zero out the remainder of the current clog page. Under normal
902 * circumstances it should be zeroes already, but it seems at least
903 * theoretically possible that XLOG replay will have settled on a nextXID
904 * value that is less than the last XID actually used and marked by the
905 * previous database lifecycle (since subtransaction commit writes clog
906 * but makes no WAL entry). Let's just be safe. (We need not worry about
907 * pages beyond the current one, since those will be zeroed when first
908 * used. For the same reason, there is no need to do anything when
909 * nextXid is exactly at a page boundary; and it's likely that the
910 * "current" page doesn't exist yet in that case.)
911 */
912 if (TransactionIdToPgIndex(xid) != 0)
913 {
914 int byteno = TransactionIdToByte(xid);
915 int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
916 int slotno;
917 char *byteptr;
918
919 slotno = SimpleLruReadPage(XactCtl, pageno, false, xid);
920 byteptr = XactCtl->shared->page_buffer[slotno] + byteno;
921
922 /* Zero so-far-unused positions in the current byte */
923 *byteptr &= (1 << bshift) - 1;
924 /* Zero the rest of the page */
925 MemSet(byteptr + 1, 0, BLCKSZ - byteno - 1);
926
927 XactCtl->shared->page_dirty[slotno] = true;
928 }
929
930 LWLockRelease(lock);
931}
#define MemSet(start, val, len)
Definition: c.h:977

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

Referenced by StartupXLOG().

◆ TruncateCLOG()

void TruncateCLOG ( TransactionId  oldestXact,
Oid  oldestxid_datoid 
)

Definition at line 1000 of file clog.c.

1001{
1002 int64 cutoffPage;
1003
1004 /*
1005 * The cutoff point is the start of the segment containing oldestXact. We
1006 * pass the *page* containing oldestXact to SimpleLruTruncate.
1007 */
1008 cutoffPage = TransactionIdToPage(oldestXact);
1009
1010 /* Check to see if there's any files that could be removed */
1012 return; /* nothing to remove */
1013
1014 /*
1015 * Advance oldestClogXid before truncating clog, so concurrent xact status
1016 * lookups can ensure they don't attempt to access truncated-away clog.
1017 *
1018 * It's only necessary to do this if we will actually truncate away clog
1019 * pages.
1020 */
1021 AdvanceOldestClogXid(oldestXact);
1022
1023 /*
1024 * Write XLOG record and flush XLOG to disk. We record the oldest xid
1025 * we're keeping information about here so we can ensure that it's always
1026 * ahead of clog truncation in case we crash, and so a standby finds out
1027 * the new valid xid before the next checkpoint.
1028 */
1029 WriteTruncateXlogRec(cutoffPage, oldestXact, oldestxid_datoid);
1030
1031 /* Now we can remove the old CLOG segment(s) */
1032 SimpleLruTruncate(XactCtl, cutoffPage);
1033}
static void WriteTruncateXlogRec(int64 pageno, TransactionId oldestXact, Oid oldestXactDb)
Definition: clog.c:1088
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition: slru.c:1791
bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, int64 segpage, void *data)
Definition: slru.c:1712

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

Referenced by vac_truncate_clog().

◆ WriteTruncateXlogRec()

static void WriteTruncateXlogRec ( int64  pageno,
TransactionId  oldestXact,
Oid  oldestXactDb 
)
static

Definition at line 1088 of file clog.c.

1089{
1090 XLogRecPtr recptr;
1091 xl_clog_truncate xlrec;
1092
1093 xlrec.pageno = pageno;
1094 xlrec.oldestXact = oldestXact;
1095 xlrec.oldestXactDb = oldestXactDb;
1096
1098 XLogRegisterData((char *) (&xlrec), sizeof(xl_clog_truncate));
1099 recptr = XLogInsert(RM_CLOG_ID, CLOG_TRUNCATE);
1100 XLogFlush(recptr);
1101}
Oid oldestXactDb
Definition: clog.h:36
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2802
uint64 XLogRecPtr
Definition: xlogdefs.h:21
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:474
void XLogRegisterData(const char *data, uint32 len)
Definition: xloginsert.c:364
void XLogBeginInsert(void)
Definition: xloginsert.c:149

References CLOG_TRUNCATE, xl_clog_truncate::oldestXact, xl_clog_truncate::oldestXactDb, xl_clog_truncate::pageno, XLogBeginInsert(), XLogFlush(), XLogInsert(), and XLogRegisterData().

Referenced by TruncateCLOG().

◆ WriteZeroPageXlogRec()

static void WriteZeroPageXlogRec ( int64  pageno)
static

Definition at line 1074 of file clog.c.

1075{
1077 XLogRegisterData((char *) (&pageno), sizeof(pageno));
1078 (void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE);
1079}

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

Referenced by ZeroCLOGPage().

◆ ZeroCLOGPage()

static int ZeroCLOGPage ( int64  pageno,
bool  writeXlog 
)
static

Definition at line 860 of file clog.c.

861{
862 int slotno;
863
864 slotno = SimpleLruZeroPage(XactCtl, pageno);
865
866 if (writeXlog)
867 WriteZeroPageXlogRec(pageno);
868
869 return slotno;
870}
static void WriteZeroPageXlogRec(int64 pageno)
Definition: clog.c:1074
int SimpleLruZeroPage(SlruCtl ctl, int64 pageno)
Definition: slru.c:375

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

Referenced by BootStrapCLOG(), clog_redo(), and ExtendCLOG().

Variable Documentation

◆ XactCtlData

SlruCtlData XactCtlData
static

Definition at line 108 of file clog.c.