PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 "pgstat.h"
#include "pg_trace.h"
#include "storage/proc.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 TransactionIdToPage(xid)   ((xid) / (TransactionId) CLOG_XACTS_PER_PAGE)
 
#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 ClogCtl   (&ClogCtlData)
 

Functions

static int ZeroCLOGPage (int pageno, bool writeXlog)
 
static bool CLOGPagePrecedes (int page1, int page2)
 
static void WriteZeroPageXlogRec (int pageno)
 
static void WriteTruncateXlogRec (int pageno, TransactionId oldestXact, Oid oldestXidDb)
 
static void TransactionIdSetPageStatus (TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int 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, int pageno)
 
static void TransactionIdSetPageStatusInternal (TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int pageno)
 
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 ShutdownCLOG (void)
 
void CheckPointCLOG (void)
 
void ExtendCLOG (TransactionId newestXact)
 
void TruncateCLOG (TransactionId oldestXact, Oid oldestxid_datoid)
 
void clog_redo (XLogReaderState *record)
 

Variables

static SlruCtlData ClogCtlData
 

Macro Definition Documentation

#define CLOG_BITS_PER_XACT   2

Definition at line 59 of file clog.c.

Referenced by TransactionIdGetStatus(), TransactionIdSetStatusBit(), and TrimCLOG().

#define CLOG_LSNS_PER_PAGE   (CLOG_XACTS_PER_PAGE / CLOG_XACTS_PER_LSN_GROUP)

Definition at line 71 of file clog.c.

Referenced by CLOGShmemInit(), and CLOGShmemSize().

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

Definition at line 62 of file clog.c.

Referenced by TransactionIdGetStatus(), and TransactionIdSetStatusBit().

#define CLOG_XACTS_PER_BYTE   4

Definition at line 60 of file clog.c.

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

Definition at line 70 of file clog.c.

#define CLOG_XACTS_PER_PAGE   (BLCKSZ * CLOG_XACTS_PER_BYTE)

Definition at line 61 of file clog.c.

Referenced by CLOGPagePrecedes().

#define GetLSNIndex (   slotno,
  xid 
)
Value:
((slotno) * CLOG_LSNS_PER_PAGE + \
#define CLOG_XACTS_PER_PAGE
Definition: clog.c:61
uint32 TransactionId
Definition: c.h:391
#define CLOG_LSNS_PER_PAGE
Definition: clog.c:71
#define CLOG_XACTS_PER_LSN_GROUP
Definition: clog.c:70

Definition at line 73 of file clog.c.

Referenced by TransactionIdGetStatus(), and TransactionIdSetStatusBit().

#define THRESHOLD_SUBTRANS_CLOG_OPT   5

Definition at line 81 of file clog.c.

Referenced by TransactionIdSetPageStatus().

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

Definition at line 67 of file clog.c.

Referenced by TransactionIdGetStatus(), TransactionIdSetStatusBit(), and TrimCLOG().

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

Definition at line 66 of file clog.c.

Referenced by TransactionIdGetStatus(), TransactionIdSetStatusBit(), and TrimCLOG().

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

Definition at line 65 of file clog.c.

Referenced by ExtendCLOG(), and TrimCLOG().

Function Documentation

void BootStrapCLOG ( void  )

Definition at line 706 of file clog.c.

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

Referenced by BootStrapXLOG().

707 {
708  int slotno;
709 
710  LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
711 
712  /* Create and zero the first page of the commit log */
713  slotno = ZeroCLOGPage(0, false);
714 
715  /* Make sure it's written out */
716  SimpleLruWritePage(ClogCtl, slotno);
717  Assert(!ClogCtl->shared->page_dirty[slotno]);
718 
719  LWLockRelease(CLogControlLock);
720 }
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define ClogCtl
Definition: clog.c:88
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:578
#define Assert(condition)
Definition: c.h:664
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
static int ZeroCLOGPage(int pageno, bool writeXlog)
Definition: clog.c:732
void CheckPointCLOG ( void  )

Definition at line 836 of file clog.c.

References ClogCtl, fsync_fname(), and SimpleLruFlush().

Referenced by CheckPointGuts().

837 {
838  /* Flush dirty CLOG pages to disk */
839  TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(true);
840  SimpleLruFlush(ClogCtl, true);
841 
842  /*
843  * fsync pg_xact to ensure that any files flushed previously are durably
844  * on disk.
845  */
846  fsync_fname("pg_xact", true);
847 
848  TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(true);
849 }
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:572
void SimpleLruFlush(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1103
#define ClogCtl
Definition: clog.c:88
void clog_redo ( XLogReaderState record)

Definition at line 997 of file clog.c.

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

998 {
999  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1000 
1001  /* Backup blocks are not used in clog records */
1002  Assert(!XLogRecHasAnyBlockRefs(record));
1003 
1004  if (info == CLOG_ZEROPAGE)
1005  {
1006  int pageno;
1007  int slotno;
1008 
1009  memcpy(&pageno, XLogRecGetData(record), sizeof(int));
1010 
1011  LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
1012 
1013  slotno = ZeroCLOGPage(pageno, false);
1014  SimpleLruWritePage(ClogCtl, slotno);
1015  Assert(!ClogCtl->shared->page_dirty[slotno]);
1016 
1017  LWLockRelease(CLogControlLock);
1018  }
1019  else if (info == CLOG_TRUNCATE)
1020  {
1021  xl_clog_truncate xlrec;
1022 
1023  memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_clog_truncate));
1024 
1025  /*
1026  * During XLOG replay, latest_page_number isn't set up yet; insert a
1027  * suitable value to bypass the sanity test in SimpleLruTruncate.
1028  */
1029  ClogCtl->shared->latest_page_number = xlrec.pageno;
1030 
1032 
1034  }
1035  else
1036  elog(PANIC, "clog_redo: unknown op code %u", info);
1037 }
void SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
Definition: slru.c:1168
unsigned char uint8
Definition: c.h:256
#define PANIC
Definition: elog.h:53
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define ClogCtl
Definition: clog.c:88
#define CLOG_ZEROPAGE
Definition: clog.h:54
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:271
#define XLogRecGetData(decoder)
Definition: xlogreader.h:226
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:578
int pageno
Definition: clog.h:33
#define CLOG_TRUNCATE
Definition: clog.h:55
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:222
TransactionId oldestXact
Definition: clog.h:34
#define Assert(condition)
Definition: c.h:664
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
static int ZeroCLOGPage(int pageno, bool writeXlog)
Definition: clog.c:732
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:228
#define elog
Definition: elog.h:219
static bool CLOGPagePrecedes ( int  page1,
int  page2 
)
static

Definition at line 946 of file clog.c.

References CLOG_XACTS_PER_PAGE, FirstNormalTransactionId, and TransactionIdPrecedes().

Referenced by CLOGShmemInit().

947 {
948  TransactionId xid1;
949  TransactionId xid2;
950 
951  xid1 = ((TransactionId) page1) * CLOG_XACTS_PER_PAGE;
952  xid1 += FirstNormalTransactionId;
953  xid2 = ((TransactionId) page2) * CLOG_XACTS_PER_PAGE;
954  xid2 += FirstNormalTransactionId;
955 
956  return TransactionIdPrecedes(xid1, xid2);
957 }
#define CLOG_XACTS_PER_PAGE
Definition: clog.c:61
uint32 TransactionId
Definition: c.h:391
#define FirstNormalTransactionId
Definition: transam.h:34
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
Size CLOGShmemBuffers ( void  )

Definition at line 677 of file clog.c.

References Max, Min, and NBuffers.

Referenced by CLOGShmemInit(), and CLOGShmemSize().

678 {
679  return Min(128, Max(4, NBuffers / 512));
680 }
#define Min(x, y)
Definition: c.h:795
#define Max(x, y)
Definition: c.h:789
int NBuffers
Definition: globals.c:123
void CLOGShmemInit ( void  )

Definition at line 692 of file clog.c.

References CLOG_LSNS_PER_PAGE, ClogCtl, CLOGPagePrecedes(), CLOGShmemBuffers(), LWTRANCHE_CLOG_BUFFERS, and SimpleLruInit().

Referenced by CreateSharedMemoryAndSemaphores().

693 {
694  ClogCtl->PagePrecedes = CLOGPagePrecedes;
696  CLogControlLock, "pg_xact", LWTRANCHE_CLOG_BUFFERS);
697 }
#define ClogCtl
Definition: clog.c:88
#define CLOG_LSNS_PER_PAGE
Definition: clog.c:71
static bool CLOGPagePrecedes(int page1, int page2)
Definition: clog.c:946
Size CLOGShmemBuffers(void)
Definition: clog.c:677
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, LWLock *ctllock, const char *subdir, int tranche_id)
Definition: slru.c:165
Size CLOGShmemSize ( void  )

Definition at line 686 of file clog.c.

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

Referenced by CreateSharedMemoryAndSemaphores().

687 {
689 }
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:145
#define CLOG_LSNS_PER_PAGE
Definition: clog.c:71
Size CLOGShmemBuffers(void)
Definition: clog.c:677
void ExtendCLOG ( TransactionId  newestXact)

Definition at line 861 of file clog.c.

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

Referenced by GetNewTransactionId().

862 {
863  int pageno;
864 
865  /*
866  * No work except at first XID of a page. But beware: just after
867  * wraparound, the first XID of page zero is FirstNormalTransactionId.
868  */
869  if (TransactionIdToPgIndex(newestXact) != 0 &&
871  return;
872 
873  pageno = TransactionIdToPage(newestXact);
874 
875  LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
876 
877  /* Zero the page and make an XLOG entry about it */
878  ZeroCLOGPage(pageno, true);
879 
880  LWLockRelease(CLogControlLock);
881 }
#define TransactionIdToPage(xid)
Definition: clog.c:64
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define TransactionIdToPgIndex(xid)
Definition: clog.c:65
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define FirstNormalTransactionId
Definition: transam.h:34
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
static int ZeroCLOGPage(int pageno, bool writeXlog)
Definition: clog.c:732
static void set_status_by_pages ( int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn 
)
static

Definition at line 237 of file clog.c.

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

Referenced by TransactionIdSetTreeStatus().

239 {
240  int pageno = TransactionIdToPage(subxids[0]);
241  int offset = 0;
242  int i = 0;
243 
244  while (i < nsubxids)
245  {
246  int num_on_page = 0;
247 
248  while (TransactionIdToPage(subxids[i]) == pageno && i < nsubxids)
249  {
250  num_on_page++;
251  i++;
252  }
253 
255  num_on_page, subxids + offset,
256  status, lsn, pageno, false);
257  offset = i;
258  pageno = TransactionIdToPage(subxids[offset]);
259  }
260 }
#define TransactionIdToPage(xid)
Definition: clog.c:64
#define InvalidTransactionId
Definition: transam.h:31
static void TransactionIdSetPageStatus(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int pageno, bool all_xact_same_page)
Definition: clog.c:267
int i
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
void ShutdownCLOG ( void  )

Definition at line 817 of file clog.c.

References ClogCtl, fsync_fname(), and SimpleLruFlush().

Referenced by ShutdownXLOG().

818 {
819  /* Flush dirty CLOG pages to disk */
820  TRACE_POSTGRESQL_CLOG_CHECKPOINT_START(false);
821  SimpleLruFlush(ClogCtl, false);
822 
823  /*
824  * fsync pg_xact to ensure that any files flushed previously are durably
825  * on disk.
826  */
827  fsync_fname("pg_xact", true);
828 
829  TRACE_POSTGRESQL_CLOG_CHECKPOINT_DONE(false);
830 }
void fsync_fname(const char *fname, bool isdir)
Definition: fd.c:572
void SimpleLruFlush(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1103
#define ClogCtl
Definition: clog.c:88
void StartupCLOG ( void  )

Definition at line 749 of file clog.c.

References ClogCtl, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), VariableCacheData::nextXid, ShmemVariableCache, and TransactionIdToPage.

Referenced by StartupXLOG().

750 {
752  int pageno = TransactionIdToPage(xid);
753 
754  LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
755 
756  /*
757  * Initialize our idea of the latest page number.
758  */
759  ClogCtl->shared->latest_page_number = pageno;
760 
761  LWLockRelease(CLogControlLock);
762 }
#define TransactionIdToPage(xid)
Definition: clog.c:64
uint32 TransactionId
Definition: c.h:391
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define ClogCtl
Definition: clog.c:88
TransactionId nextXid
Definition: transam.h:117
VariableCache ShmemVariableCache
Definition: varsup.c:34
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
static bool TransactionGroupUpdateXidStatus ( TransactionId  xid,
XidStatus  status,
XLogRecPtr  lsn,
int  pageno 
)
static

Definition at line 414 of file clog.c.

References PROC_HDR::allPgXact, PROC_HDR::allProcs, Assert, PROC_HDR::clogGroupFirst, PGPROC::clogGroupMember, PGPROC::clogGroupMemberLsn, PGPROC::clogGroupMemberPage, PGPROC::clogGroupMemberXid, PGPROC::clogGroupMemberXidStatus, PGPROC::clogGroupNext, INVALID_PGPROCNO, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MyProc, PGXACT::nxids, PGXACT::overflowed, pg_atomic_compare_exchange_u32(), pg_atomic_exchange_u32(), pg_atomic_read_u32(), pg_atomic_write_u32(), pg_write_barrier, PGPROC::pgprocno, PGSemaphoreLock(), PGSemaphoreUnlock(), pgstat_report_wait_end(), pgstat_report_wait_start(), ProcGlobal, PGPROC::sem, status(), PGPROC::subxids, TransactionIdIsValid, TransactionIdSetPageStatusInternal(), WAIT_EVENT_CLOG_GROUP_UPDATE, and XidCache::xids.

Referenced by TransactionIdSetPageStatus().

416 {
417  volatile PROC_HDR *procglobal = ProcGlobal;
418  PGPROC *proc = MyProc;
419  uint32 nextidx;
420  uint32 wakeidx;
421 
422  /* We should definitely have an XID whose status needs to be updated. */
424 
425  /*
426  * Add ourselves to the list of processes needing a group XID status
427  * update.
428  */
429  proc->clogGroupMember = true;
430  proc->clogGroupMemberXid = xid;
432  proc->clogGroupMemberPage = pageno;
433  proc->clogGroupMemberLsn = lsn;
434 
435  nextidx = pg_atomic_read_u32(&procglobal->clogGroupFirst);
436 
437  while (true)
438  {
439  /*
440  * Add the proc to list, if the clog page where we need to update the
441  * current transaction status is same as group leader's clog page.
442  *
443  * There is a race condition here, which is that after doing the below
444  * check and before adding this proc's clog update to a group, the
445  * group leader might have already finished the group update for this
446  * page and becomes group leader of another group. This will lead to a
447  * situation where a single group can have different clog page
448  * updates. This isn't likely and will still work, just maybe a bit
449  * less efficiently.
450  */
451  if (nextidx != INVALID_PGPROCNO &&
453  {
454  proc->clogGroupMember = false;
455  return false;
456  }
457 
458  pg_atomic_write_u32(&proc->clogGroupNext, nextidx);
459 
461  &nextidx,
462  (uint32) proc->pgprocno))
463  break;
464  }
465 
466  /*
467  * If the list was not empty, the leader will update the status of our
468  * XID. It is impossible to have followers without a leader because the
469  * first process that has added itself to the list will always have
470  * nextidx as INVALID_PGPROCNO.
471  */
472  if (nextidx != INVALID_PGPROCNO)
473  {
474  int extraWaits = 0;
475 
476  /* Sleep until the leader updates our XID status. */
478  for (;;)
479  {
480  /* acts as a read barrier */
481  PGSemaphoreLock(proc->sem);
482  if (!proc->clogGroupMember)
483  break;
484  extraWaits++;
485  }
487 
489 
490  /* Fix semaphore count for any absorbed wakeups */
491  while (extraWaits-- > 0)
492  PGSemaphoreUnlock(proc->sem);
493  return true;
494  }
495 
496  /* We are the leader. Acquire the lock on behalf of everyone. */
497  LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
498 
499  /*
500  * Now that we've got the lock, clear the list of processes waiting for
501  * group XID status update, saving a pointer to the head of the list.
502  * Trying to pop elements one at a time could lead to an ABA problem.
503  */
504  nextidx = pg_atomic_exchange_u32(&procglobal->clogGroupFirst,
506 
507  /* Remember head of list so we can perform wakeups after dropping lock. */
508  wakeidx = nextidx;
509 
510  /* Walk the list and update the status of all XIDs. */
511  while (nextidx != INVALID_PGPROCNO)
512  {
513  PGPROC *proc = &ProcGlobal->allProcs[nextidx];
514  PGXACT *pgxact = &ProcGlobal->allPgXact[nextidx];
515 
516  /*
517  * Overflowed transactions should not use group XID status update
518  * mechanism.
519  */
520  Assert(!pgxact->overflowed);
521 
523  pgxact->nxids,
524  proc->subxids.xids,
526  proc->clogGroupMemberLsn,
527  proc->clogGroupMemberPage);
528 
529  /* Move to next proc in list. */
530  nextidx = pg_atomic_read_u32(&proc->clogGroupNext);
531  }
532 
533  /* We're done with the lock now. */
534  LWLockRelease(CLogControlLock);
535 
536  /*
537  * Now that we've released the lock, go back and wake everybody up. We
538  * don't do this under the lock so as to keep lock hold times to a
539  * minimum.
540  */
541  while (wakeidx != INVALID_PGPROCNO)
542  {
543  PGPROC *proc = &ProcGlobal->allProcs[wakeidx];
544 
545  wakeidx = pg_atomic_read_u32(&proc->clogGroupNext);
547 
548  /* ensure all previous writes are visible before follower continues. */
550 
551  proc->clogGroupMember = false;
552 
553  if (proc != MyProc)
554  PGSemaphoreUnlock(proc->sem);
555  }
556 
557  return true;
558 }
XidStatus clogGroupMemberXidStatus
Definition: proc.h:179
void PGSemaphoreUnlock(PGSemaphore sema)
Definition: posix_sema.c:323
Definition: proc.h:219
XLogRecPtr clogGroupMemberLsn
Definition: proc.h:183
static bool pg_atomic_compare_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 *expected, uint32 newval)
Definition: atomics.h:322
PGXACT * allPgXact
Definition: proc.h:246
PGPROC * MyProc
Definition: proc.c:67
PROC_HDR * ProcGlobal
Definition: proc.c:80
pg_atomic_uint32 clogGroupNext
Definition: proc.h:177
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
static uint32 pg_atomic_exchange_u32(volatile pg_atomic_uint32 *ptr, uint32 newval)
Definition: atomics.h:303
int clogGroupMemberPage
Definition: proc.h:181
uint8 nxids
Definition: proc.h:235
TransactionId clogGroupMemberXid
Definition: proc.h:178
unsigned int uint32
Definition: c.h:258
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1244
struct XidCache subxids
Definition: proc.h:159
#define INVALID_PGPROCNO
Definition: proc.h:77
Definition: proc.h:241
bool overflowed
Definition: proc.h:231
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]
Definition: proc.h:40
#define Assert(condition)
Definition: c.h:664
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1220
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
void PGSemaphoreLock(PGSemaphore sema)
Definition: posix_sema.c:303
pg_atomic_uint32 clogGroupFirst
Definition: proc.h:258
int pgprocno
Definition: proc.h:110
bool clogGroupMember
Definition: proc.h:176
#define pg_write_barrier()
Definition: atomics.h:162
static void TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int pageno)
Definition: clog.c:339
PGPROC * allProcs
Definition: proc.h:244
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void pg_atomic_write_u32(volatile pg_atomic_uint32 *ptr, uint32 val)
Definition: atomics.h:269
PGSemaphore sem
Definition: proc.h:101
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
Definition: proc.h:95
static uint32 pg_atomic_read_u32(volatile pg_atomic_uint32 *ptr)
Definition: atomics.h:252
XidStatus TransactionIdGetStatus ( TransactionId  xid,
XLogRecPtr lsn 
)

Definition at line 635 of file clog.c.

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

Referenced by TransactionIdGetCommitLSN(), and TransactionLogFetch().

636 {
637  int pageno = TransactionIdToPage(xid);
638  int byteno = TransactionIdToByte(xid);
639  int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
640  int slotno;
641  int lsnindex;
642  char *byteptr;
644 
645  /* lock is acquired by SimpleLruReadPage_ReadOnly */
646 
647  slotno = SimpleLruReadPage_ReadOnly(ClogCtl, pageno, xid);
648  byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
649 
650  status = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
651 
652  lsnindex = GetLSNIndex(slotno, xid);
653  *lsn = ClogCtl->shared->group_lsn[lsnindex];
654 
655  LWLockRelease(CLogControlLock);
656 
657  return status;
658 }
#define TransactionIdToBIndex(xid)
Definition: clog.c:67
#define CLOG_XACT_BITMASK
Definition: clog.c:62
#define TransactionIdToPage(xid)
Definition: clog.c:64
#define GetLSNIndex(slotno, xid)
Definition: clog.c:73
int XidStatus
Definition: clog.h:24
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define ClogCtl
Definition: clog.c:88
#define CLOG_BITS_PER_XACT
Definition: clog.c:59
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
Definition: slru.c:467
#define TransactionIdToByte(xid)
Definition: clog.c:66
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
static void TransactionIdSetPageStatus ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn,
int  pageno,
bool  all_xact_same_page 
)
static

Definition at line 267 of file clog.c.

References Assert, LW_EXCLUSIVE, LWLockAcquire(), LWLockConditionalAcquire(), LWLockRelease(), MyPgXact, MyProc, PGXACT::nxids, PGPROC_MAX_CACHED_SUBXIDS, StaticAssertStmt, PGPROC::subxids, THRESHOLD_SUBTRANS_CLOG_OPT, TransactionGroupUpdateXidStatus(), TransactionIdSetPageStatusInternal(), PGXACT::xid, and XidCache::xids.

Referenced by set_status_by_pages(), and TransactionIdSetTreeStatus().

271 {
272  /* Can't use group update when PGPROC overflows. */
274  "group clog threshold less than PGPROC cached subxids");
275 
276  /*
277  * When there is contention on CLogControlLock, we try to group multiple
278  * updates; a single leader process will perform transaction status
279  * updates for multiple backends so that the number of times
280  * CLogControlLock needs to be acquired is reduced.
281  *
282  * For this optimization to be safe, the XID in MyPgXact and the subxids
283  * in MyProc must be the same as the ones for which we're setting the
284  * status. Check that this is the case.
285  *
286  * For this optimization to be efficient, we shouldn't have too many
287  * sub-XIDs and all of the XIDs for which we're adjusting clog should be
288  * on the same page. Check those conditions, too.
289  */
290  if (all_xact_same_page && xid == MyPgXact->xid &&
291  nsubxids <= THRESHOLD_SUBTRANS_CLOG_OPT &&
292  nsubxids == MyPgXact->nxids &&
293  memcmp(subxids, MyProc->subxids.xids,
294  nsubxids * sizeof(TransactionId)) == 0)
295  {
296  /*
297  * We don't try to do group update optimization if a process has
298  * overflowed the subxids array in its PGPROC, since in that case we
299  * don't have a complete list of XIDs for it.
300  */
302 
303  /*
304  * If we can immediately acquire CLogControlLock, we update the status
305  * of our own XID and release the lock. If not, try use group XID
306  * update. If that doesn't work out, fall back to waiting for the
307  * lock to perform an update for this transaction only.
308  */
309  if (LWLockConditionalAcquire(CLogControlLock, LW_EXCLUSIVE))
310  {
311  /* Got the lock without waiting! Do the update. */
312  TransactionIdSetPageStatusInternal(xid, nsubxids, subxids, status,
313  lsn, pageno);
314  LWLockRelease(CLogControlLock);
315  return;
316  }
317  else if (TransactionGroupUpdateXidStatus(xid, status, lsn, pageno))
318  {
319  /* Group update mechanism has done the work. */
320  return;
321  }
322 
323  /* Fall through only if update isn't done yet. */
324  }
325 
326  /* Group update not applicable, or couldn't accept this page number. */
327  LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
328  TransactionIdSetPageStatusInternal(xid, nsubxids, subxids, status,
329  lsn, pageno);
330  LWLockRelease(CLogControlLock);
331 }
uint32 TransactionId
Definition: c.h:391
static bool TransactionGroupUpdateXidStatus(TransactionId xid, XidStatus status, XLogRecPtr lsn, int pageno)
Definition: clog.c:414
PGPROC * MyProc
Definition: proc.c:67
TransactionId xid
Definition: proc.h:221
PGXACT * MyPgXact
Definition: proc.c:68
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define StaticAssertStmt(condition, errmessage)
Definition: c.h:746
#define THRESHOLD_SUBTRANS_CLOG_OPT
Definition: clog.c:81
bool LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1289
uint8 nxids
Definition: proc.h:235
struct XidCache subxids
Definition: proc.h:159
#define PGPROC_MAX_CACHED_SUBXIDS
Definition: proc.h:36
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]
Definition: proc.h:40
#define Assert(condition)
Definition: c.h:664
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
static void TransactionIdSetPageStatusInternal(TransactionId xid, int nsubxids, TransactionId *subxids, XidStatus status, XLogRecPtr lsn, int pageno)
Definition: clog.c:339
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
static void TransactionIdSetPageStatusInternal ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn,
int  pageno 
)
static

Definition at line 339 of file clog.c.

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

Referenced by TransactionGroupUpdateXidStatus(), and TransactionIdSetPageStatus().

342 {
343  int slotno;
344  int i;
345 
349  Assert(LWLockHeldByMeInMode(CLogControlLock, LW_EXCLUSIVE));
350 
351  /*
352  * If we're doing an async commit (ie, lsn is valid), then we must wait
353  * for any active write on the page slot to complete. Otherwise our
354  * update could reach disk in that write, which will not do since we
355  * mustn't let it reach disk until we've done the appropriate WAL flush.
356  * But when lsn is invalid, it's OK to scribble on a page while it is
357  * write-busy, since we don't care if the update reaches disk sooner than
358  * we think.
359  */
360  slotno = SimpleLruReadPage(ClogCtl, pageno, XLogRecPtrIsInvalid(lsn), xid);
361 
362  /*
363  * Set the main transaction id, if any.
364  *
365  * If we update more than one xid on this page while it is being written
366  * out, we might find that some of the bits go to disk and others don't.
367  * If we are updating commits on the page with the top-level xid that
368  * could break atomicity, so we subcommit the subxids first before we mark
369  * the top-level commit.
370  */
371  if (TransactionIdIsValid(xid))
372  {
373  /* Subtransactions first, if needed ... */
375  {
376  for (i = 0; i < nsubxids; i++)
377  {
378  Assert(ClogCtl->shared->page_number[slotno] == TransactionIdToPage(subxids[i]));
379  TransactionIdSetStatusBit(subxids[i],
381  lsn, slotno);
382  }
383  }
384 
385  /* ... then the main transaction */
386  TransactionIdSetStatusBit(xid, status, lsn, slotno);
387  }
388 
389  /* Set the subtransactions */
390  for (i = 0; i < nsubxids; i++)
391  {
392  Assert(ClogCtl->shared->page_number[slotno] == TransactionIdToPage(subxids[i]));
393  TransactionIdSetStatusBit(subxids[i], status, lsn, slotno);
394  }
395 
396  ClogCtl->shared->page_dirty[slotno] = true;
397 }
#define TransactionIdToPage(xid)
Definition: clog.c:64
bool LWLockHeldByMeInMode(LWLock *l, LWLockMode mode)
Definition: lwlock.c:1855
#define TRANSACTION_STATUS_COMMITTED
Definition: clog.h:27
static void TransactionIdSetStatusBit(TransactionId xid, XidStatus status, XLogRecPtr lsn, int slotno)
Definition: clog.c:566
#define ClogCtl
Definition: clog.c:88
int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid)
Definition: slru.c:375
#define TRANSACTION_STATUS_ABORTED
Definition: clog.h:28
#define TRANSACTION_STATUS_SUB_COMMITTED
Definition: clog.h:29
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define Assert(condition)
Definition: c.h:664
int i
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
static void TransactionIdSetStatusBit ( TransactionId  xid,
XidStatus  status,
XLogRecPtr  lsn,
int  slotno 
)
static

Definition at line 566 of file clog.c.

References Assert, CLOG_BITS_PER_XACT, CLOG_XACT_BITMASK, ClogCtl, GetLSNIndex, InRecovery, TRANSACTION_STATUS_COMMITTED, TRANSACTION_STATUS_IN_PROGRESS, TRANSACTION_STATUS_SUB_COMMITTED, TransactionIdToBIndex, TransactionIdToByte, and XLogRecPtrIsInvalid.

Referenced by TransactionIdSetPageStatusInternal().

567 {
568  int byteno = TransactionIdToByte(xid);
569  int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
570  char *byteptr;
571  char byteval;
572  char curval;
573 
574  byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
575  curval = (*byteptr >> bshift) & CLOG_XACT_BITMASK;
576 
577  /*
578  * When replaying transactions during recovery we still need to perform
579  * the two phases of subcommit and then commit. However, some transactions
580  * are already correctly marked, so we just treat those as a no-op which
581  * allows us to keep the following Assert as restrictive as possible.
582  */
585  return;
586 
587  /*
588  * Current state change should be from 0 or subcommitted to target state
589  * or we should already be there when replaying changes during recovery.
590  */
591  Assert(curval == 0 ||
594  curval == status);
595 
596  /* note this assumes exclusive access to the clog page */
597  byteval = *byteptr;
598  byteval &= ~(((1 << CLOG_BITS_PER_XACT) - 1) << bshift);
599  byteval |= (status << bshift);
600  *byteptr = byteval;
601 
602  /*
603  * Update the group LSN if the transaction completion LSN is higher.
604  *
605  * Note: lsn will be invalid when supplied during InRecovery processing,
606  * so we don't need to do anything special to avoid LSN updates during
607  * recovery. After recovery completes the next clog change will set the
608  * LSN correctly.
609  */
610  if (!XLogRecPtrIsInvalid(lsn))
611  {
612  int lsnindex = GetLSNIndex(slotno, xid);
613 
614  if (ClogCtl->shared->group_lsn[lsnindex] < lsn)
615  ClogCtl->shared->group_lsn[lsnindex] = lsn;
616  }
617 }
#define TransactionIdToBIndex(xid)
Definition: clog.c:67
#define CLOG_XACT_BITMASK
Definition: clog.c:62
#define TRANSACTION_STATUS_COMMITTED
Definition: clog.h:27
#define GetLSNIndex(slotno, xid)
Definition: clog.c:73
bool InRecovery
Definition: xlog.c:194
#define ClogCtl
Definition: clog.c:88
#define TRANSACTION_STATUS_SUB_COMMITTED
Definition: clog.h:29
#define CLOG_BITS_PER_XACT
Definition: clog.c:59
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29
#define Assert(condition)
Definition: c.h:664
#define TransactionIdToByte(xid)
Definition: clog.c:66
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:224
#define TRANSACTION_STATUS_IN_PROGRESS
Definition: clog.h:26
void TransactionIdSetTreeStatus ( TransactionId  xid,
int  nsubxids,
TransactionId subxids,
XidStatus  status,
XLogRecPtr  lsn 
)

Definition at line 163 of file clog.c.

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

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

Definition at line 768 of file clog.c.

References CLOG_BITS_PER_XACT, ClogCtl, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MemSet, VariableCacheData::nextXid, ShmemVariableCache, SimpleLruReadPage(), TransactionIdToBIndex, TransactionIdToByte, TransactionIdToPage, and TransactionIdToPgIndex.

Referenced by StartupXLOG().

769 {
771  int pageno = TransactionIdToPage(xid);
772 
773  LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);
774 
775  /*
776  * Re-Initialize our idea of the latest page number.
777  */
778  ClogCtl->shared->latest_page_number = pageno;
779 
780  /*
781  * Zero out the remainder of the current clog page. Under normal
782  * circumstances it should be zeroes already, but it seems at least
783  * theoretically possible that XLOG replay will have settled on a nextXID
784  * value that is less than the last XID actually used and marked by the
785  * previous database lifecycle (since subtransaction commit writes clog
786  * but makes no WAL entry). Let's just be safe. (We need not worry about
787  * pages beyond the current one, since those will be zeroed when first
788  * used. For the same reason, there is no need to do anything when
789  * nextXid is exactly at a page boundary; and it's likely that the
790  * "current" page doesn't exist yet in that case.)
791  */
792  if (TransactionIdToPgIndex(xid) != 0)
793  {
794  int byteno = TransactionIdToByte(xid);
795  int bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;
796  int slotno;
797  char *byteptr;
798 
799  slotno = SimpleLruReadPage(ClogCtl, pageno, false, xid);
800  byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;
801 
802  /* Zero so-far-unused positions in the current byte */
803  *byteptr &= (1 << bshift) - 1;
804  /* Zero the rest of the page */
805  MemSet(byteptr + 1, 0, BLCKSZ - byteno - 1);
806 
807  ClogCtl->shared->page_dirty[slotno] = true;
808  }
809 
810  LWLockRelease(CLogControlLock);
811 }
#define TransactionIdToBIndex(xid)
Definition: clog.c:67
#define TransactionIdToPage(xid)
Definition: clog.c:64
uint32 TransactionId
Definition: c.h:391
#define TransactionIdToPgIndex(xid)
Definition: clog.c:65
#define MemSet(start, val, len)
Definition: c.h:846
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1721
#define ClogCtl
Definition: clog.c:88
TransactionId nextXid
Definition: transam.h:117
int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid)
Definition: slru.c:375
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define CLOG_BITS_PER_XACT
Definition: clog.c:59
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1117
#define TransactionIdToByte(xid)
Definition: clog.c:66
void TruncateCLOG ( TransactionId  oldestXact,
Oid  oldestxid_datoid 
)

Definition at line 900 of file clog.c.

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

Referenced by vac_truncate_clog().

901 {
902  int cutoffPage;
903 
904  /*
905  * The cutoff point is the start of the segment containing oldestXact. We
906  * pass the *page* containing oldestXact to SimpleLruTruncate.
907  */
908  cutoffPage = TransactionIdToPage(oldestXact);
909 
910  /* Check to see if there's any files that could be removed */
912  return; /* nothing to remove */
913 
914  /*
915  * Advance oldestClogXid before truncating clog, so concurrent xact status
916  * lookups can ensure they don't attempt to access truncated-away clog.
917  *
918  * It's only necessary to do this if we will actually truncate away clog
919  * pages.
920  */
921  AdvanceOldestClogXid(oldestXact);
922 
923  /*
924  * Write XLOG record and flush XLOG to disk. We record the oldest xid
925  * we're keeping information about here so we can ensure that it's always
926  * ahead of clog truncation in case we crash, and so a standby finds out
927  * the new valid xid before the next checkpoint.
928  */
929  WriteTruncateXlogRec(cutoffPage, oldestXact, oldestxid_datoid);
930 
931  /* Now we can remove the old CLOG segment(s) */
932  SimpleLruTruncate(ClogCtl, cutoffPage);
933 }
#define TransactionIdToPage(xid)
Definition: clog.c:64
void SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
Definition: slru.c:1168
#define ClogCtl
Definition: clog.c:88
void AdvanceOldestClogXid(TransactionId oldest_datfrozenxid)
Definition: varsup.c:271
bool SlruScanDirCbReportPresence(SlruCtl ctl, char *filename, int segpage, void *data)
Definition: slru.c:1321
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
Definition: slru.c:1376
static void WriteTruncateXlogRec(int pageno, TransactionId oldestXact, Oid oldestXidDb)
Definition: clog.c:978
static void WriteTruncateXlogRec ( int  pageno,
TransactionId  oldestXact,
Oid  oldestXidDb 
)
static

Definition at line 978 of file clog.c.

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

Referenced by TruncateCLOG().

979 {
980  XLogRecPtr recptr;
981  xl_clog_truncate xlrec;
982 
983  xlrec.pageno = pageno;
984  xlrec.oldestXact = oldestXact;
985  xlrec.oldestXactDb = oldestXactDb;
986 
987  XLogBeginInsert();
988  XLogRegisterData((char *) (&xlrec), sizeof(xl_clog_truncate));
989  recptr = XLogInsert(RM_CLOG_ID, CLOG_TRUNCATE);
990  XLogFlush(recptr);
991 }
void XLogFlush(XLogRecPtr record)
Definition: xlog.c:2773
int pageno
Definition: clog.h:33
#define CLOG_TRUNCATE
Definition: clog.h:55
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
TransactionId oldestXact
Definition: clog.h:34
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
uint64 XLogRecPtr
Definition: xlogdefs.h:21
Oid oldestXactDb
Definition: clog.h:35
void XLogBeginInsert(void)
Definition: xloginsert.c:120
static void WriteZeroPageXlogRec ( int  pageno)
static

Definition at line 964 of file clog.c.

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

Referenced by ZeroCLOGPage().

965 {
966  XLogBeginInsert();
967  XLogRegisterData((char *) (&pageno), sizeof(int));
968  (void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE);
969 }
#define CLOG_ZEROPAGE
Definition: clog.h:54
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
void XLogBeginInsert(void)
Definition: xloginsert.c:120
static int ZeroCLOGPage ( int  pageno,
bool  writeXlog 
)
static

Definition at line 732 of file clog.c.

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

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

733 {
734  int slotno;
735 
736  slotno = SimpleLruZeroPage(ClogCtl, pageno);
737 
738  if (writeXlog)
739  WriteZeroPageXlogRec(pageno);
740 
741  return slotno;
742 }
static void WriteZeroPageXlogRec(int pageno)
Definition: clog.c:964
#define ClogCtl
Definition: clog.c:88
int SimpleLruZeroPage(SlruCtl ctl, int pageno)
Definition: slru.c:263

Variable Documentation

SlruCtlData ClogCtlData
static

Definition at line 86 of file clog.c.