PostgreSQL Source Code  git master
subtrans.c File Reference
#include "postgres.h"
#include "access/slru.h"
#include "access/subtrans.h"
#include "access/transam.h"
#include "pg_trace.h"
#include "utils/snapmgr.h"
Include dependency graph for subtrans.c:

Go to the source code of this file.

Macros

#define SUBTRANS_XACTS_PER_PAGE   (BLCKSZ / sizeof(TransactionId))
 
#define TransactionIdToPage(xid)   ((xid) / (TransactionId) SUBTRANS_XACTS_PER_PAGE)
 
#define TransactionIdToEntry(xid)   ((xid) % (TransactionId) SUBTRANS_XACTS_PER_PAGE)
 
#define SubTransCtl   (&SubTransCtlData)
 

Functions

static int ZeroSUBTRANSPage (int pageno)
 
static bool SubTransPagePrecedes (int page1, int page2)
 
void SubTransSetParent (TransactionId xid, TransactionId parent)
 
TransactionId SubTransGetParent (TransactionId xid)
 
TransactionId SubTransGetTopmostTransaction (TransactionId xid)
 
Size SUBTRANSShmemSize (void)
 
void SUBTRANSShmemInit (void)
 
void BootStrapSUBTRANS (void)
 
void StartupSUBTRANS (TransactionId oldestActiveXID)
 
void CheckPointSUBTRANS (void)
 
void ExtendSUBTRANS (TransactionId newestXact)
 
void TruncateSUBTRANS (TransactionId oldestXact)
 

Variables

static SlruCtlData SubTransCtlData
 

Macro Definition Documentation

◆ SUBTRANS_XACTS_PER_PAGE

#define SUBTRANS_XACTS_PER_PAGE   (BLCKSZ / sizeof(TransactionId))

Definition at line 52 of file subtrans.c.

Referenced by SubTransPagePrecedes().

◆ SubTransCtl

◆ TransactionIdToEntry

#define TransactionIdToEntry (   xid)    ((xid) % (TransactionId) SUBTRANS_XACTS_PER_PAGE)

Definition at line 55 of file subtrans.c.

Referenced by ExtendSUBTRANS(), SubTransGetParent(), and SubTransSetParent().

◆ TransactionIdToPage

#define TransactionIdToPage (   xid)    ((xid) / (TransactionId) SUBTRANS_XACTS_PER_PAGE)

Function Documentation

◆ BootStrapSUBTRANS()

void BootStrapSUBTRANS ( void  )

Definition at line 210 of file subtrans.c.

References Assert, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SimpleLruWritePage(), SubTransCtl, and ZeroSUBTRANSPage().

Referenced by BootStrapXLOG().

211 {
212  int slotno;
213 
214  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
215 
216  /* Create and zero the first page of the subtrans log */
217  slotno = ZeroSUBTRANSPage(0);
218 
219  /* Make sure it's written out */
221  Assert(!SubTransCtl->shared->page_dirty[slotno]);
222 
223  LWLockRelease(SubtransSLRULock);
224 }
static int ZeroSUBTRANSPage(int pageno)
Definition: subtrans.c:235
#define SubTransCtl
Definition: subtrans.c:63
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:613
#define Assert(condition)
Definition: c.h:746
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208

◆ CheckPointSUBTRANS()

void CheckPointSUBTRANS ( void  )

Definition at line 283 of file subtrans.c.

References SimpleLruWriteAll(), and SubTransCtl.

Referenced by CheckPointGuts().

284 {
285  /*
286  * Write dirty SUBTRANS pages to disk
287  *
288  * This is not actually necessary from a correctness point of view. We do
289  * it merely to improve the odds that writing of dirty pages is done by
290  * the checkpoint process and not by backends.
291  */
292  TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(true);
294  TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true);
295 }
#define SubTransCtl
Definition: subtrans.c:63
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1155

◆ ExtendSUBTRANS()

void ExtendSUBTRANS ( TransactionId  newestXact)

Definition at line 307 of file subtrans.c.

References FirstNormalTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), TransactionIdEquals, TransactionIdToEntry, TransactionIdToPage, and ZeroSUBTRANSPage().

Referenced by GetNewTransactionId(), ProcArrayApplyRecoveryInfo(), and RecordKnownAssignedTransactionIds().

308 {
309  int pageno;
310 
311  /*
312  * No work except at first XID of a page. But beware: just after
313  * wraparound, the first XID of page zero is FirstNormalTransactionId.
314  */
315  if (TransactionIdToEntry(newestXact) != 0 &&
317  return;
318 
319  pageno = TransactionIdToPage(newestXact);
320 
321  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
322 
323  /* Zero the page */
324  ZeroSUBTRANSPage(pageno);
325 
326  LWLockRelease(SubtransSLRULock);
327 }
static int ZeroSUBTRANSPage(int pageno)
Definition: subtrans.c:235
#define TransactionIdToEntry(xid)
Definition: subtrans.c:55
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define FirstNormalTransactionId
Definition: transam.h:34
#define TransactionIdToPage(xid)
Definition: subtrans.c:54
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208

◆ StartupSUBTRANS()

void StartupSUBTRANS ( TransactionId  oldestActiveXID)

Definition at line 248 of file subtrans.c.

References LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MaxTransactionId, VariableCacheData::nextXid, ShmemVariableCache, TransactionIdToPage, XidFromFullTransactionId, and ZeroSUBTRANSPage().

Referenced by StartupXLOG().

249 {
250  FullTransactionId nextXid;
251  int startPage;
252  int endPage;
253 
254  /*
255  * Since we don't expect pg_subtrans to be valid across crashes, we
256  * initialize the currently-active page(s) to zeroes during startup.
257  * Whenever we advance into a new page, ExtendSUBTRANS will likewise zero
258  * the new page without regard to whatever was previously on disk.
259  */
260  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
261 
262  startPage = TransactionIdToPage(oldestActiveXID);
263  nextXid = ShmemVariableCache->nextXid;
264  endPage = TransactionIdToPage(XidFromFullTransactionId(nextXid));
265 
266  while (startPage != endPage)
267  {
268  (void) ZeroSUBTRANSPage(startPage);
269  startPage++;
270  /* must account for wraparound */
271  if (startPage > TransactionIdToPage(MaxTransactionId))
272  startPage = 0;
273  }
274  (void) ZeroSUBTRANSPage(startPage);
275 
276  LWLockRelease(SubtransSLRULock);
277 }
static int ZeroSUBTRANSPage(int pageno)
Definition: subtrans.c:235
FullTransactionId nextXid
Definition: transam.h:213
#define XidFromFullTransactionId(x)
Definition: transam.h:48
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
VariableCache ShmemVariableCache
Definition: varsup.c:34
#define MaxTransactionId
Definition: transam.h:35
#define TransactionIdToPage(xid)
Definition: subtrans.c:54
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208

◆ SubTransGetParent()

TransactionId SubTransGetParent ( TransactionId  xid)

Definition at line 109 of file subtrans.c.

References Assert, InvalidTransactionId, LWLockRelease(), SimpleLruReadPage_ReadOnly(), SubTransCtl, TransactionIdFollowsOrEquals(), TransactionIdIsNormal, TransactionIdToEntry, TransactionIdToPage, and TransactionXmin.

Referenced by SubTransGetTopmostTransaction(), TransactionIdDidAbort(), and TransactionIdDidCommit().

110 {
111  int pageno = TransactionIdToPage(xid);
112  int entryno = TransactionIdToEntry(xid);
113  int slotno;
114  TransactionId *ptr;
115  TransactionId parent;
116 
117  /* Can't ask about stuff that might not be around anymore */
119 
120  /* Bootstrap and frozen XIDs have no parent */
121  if (!TransactionIdIsNormal(xid))
122  return InvalidTransactionId;
123 
124  /* lock is acquired by SimpleLruReadPage_ReadOnly */
125 
126  slotno = SimpleLruReadPage_ReadOnly(SubTransCtl, pageno, xid);
127  ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
128  ptr += entryno;
129 
130  parent = *ptr;
131 
132  LWLockRelease(SubtransSLRULock);
133 
134  return parent;
135 }
#define TransactionIdToEntry(xid)
Definition: subtrans.c:55
uint32 TransactionId
Definition: c.h:521
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId TransactionXmin
Definition: snapmgr.c:112
#define SubTransCtl
Definition: subtrans.c:63
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
#define InvalidTransactionId
Definition: transam.h:31
#define TransactionIdToPage(xid)
Definition: subtrans.c:54
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
Definition: slru.c:494
#define Assert(condition)
Definition: c.h:746
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

◆ SubTransGetTopmostTransaction()

TransactionId SubTransGetTopmostTransaction ( TransactionId  xid)

Definition at line 150 of file subtrans.c.

References Assert, elog, ERROR, SubTransGetParent(), TransactionIdFollowsOrEquals(), TransactionIdIsValid, TransactionIdPrecedes(), and TransactionXmin.

Referenced by ConditionalXactLockTableWait(), HeapCheckForSerializableConflictOut(), TransactionIdIsInProgress(), XactLockTableWait(), and XidInMVCCSnapshot().

151 {
152  TransactionId parentXid = xid,
153  previousXid = xid;
154 
155  /* Can't ask about stuff that might not be around anymore */
157 
158  while (TransactionIdIsValid(parentXid))
159  {
160  previousXid = parentXid;
161  if (TransactionIdPrecedes(parentXid, TransactionXmin))
162  break;
163  parentXid = SubTransGetParent(parentXid);
164 
165  /*
166  * By convention the parent xid gets allocated first, so should always
167  * precede the child xid. Anything else points to a corrupted data
168  * structure that could lead to an infinite loop, so exit.
169  */
170  if (!TransactionIdPrecedes(parentXid, previousXid))
171  elog(ERROR, "pg_subtrans contains invalid entry: xid %u points to parent xid %u",
172  previousXid, parentXid);
173  }
174 
175  Assert(TransactionIdIsValid(previousXid));
176 
177  return previousXid;
178 }
uint32 TransactionId
Definition: c.h:521
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:109
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId TransactionXmin
Definition: snapmgr.c:112
#define ERROR
Definition: elog.h:43
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define Assert(condition)
Definition: c.h:746
#define elog(elevel,...)
Definition: elog.h:214
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ SubTransPagePrecedes()

static bool SubTransPagePrecedes ( int  page1,
int  page2 
)
static

Definition at line 366 of file subtrans.c.

References FirstNormalTransactionId, SUBTRANS_XACTS_PER_PAGE, and TransactionIdPrecedes().

Referenced by SUBTRANSShmemInit().

367 {
368  TransactionId xid1;
369  TransactionId xid2;
370 
371  xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
372  xid1 += FirstNormalTransactionId;
373  xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
374  xid2 += FirstNormalTransactionId;
375 
376  return TransactionIdPrecedes(xid1, xid2);
377 }
uint32 TransactionId
Definition: c.h:521
#define FirstNormalTransactionId
Definition: transam.h:34
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define SUBTRANS_XACTS_PER_PAGE
Definition: subtrans.c:52

◆ SubTransSetParent()

void SubTransSetParent ( TransactionId  xid,
TransactionId  parent 
)

Definition at line 74 of file subtrans.c.

References Assert, InvalidTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SimpleLruReadPage(), SubTransCtl, TransactionIdFollows(), TransactionIdIsValid, TransactionIdToEntry, and TransactionIdToPage.

Referenced by AssignTransactionId(), ProcArrayApplyXidAssignment(), and ProcessTwoPhaseBuffer().

75 {
76  int pageno = TransactionIdToPage(xid);
77  int entryno = TransactionIdToEntry(xid);
78  int slotno;
79  TransactionId *ptr;
80 
82  Assert(TransactionIdFollows(xid, parent));
83 
84  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
85 
86  slotno = SimpleLruReadPage(SubTransCtl, pageno, true, xid);
87  ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
88  ptr += entryno;
89 
90  /*
91  * It's possible we'll try to set the parent xid multiple times but we
92  * shouldn't ever be changing the xid from one valid xid to another valid
93  * xid, which would corrupt the data structure.
94  */
95  if (*ptr != parent)
96  {
98  *ptr = parent;
99  SubTransCtl->shared->page_dirty[slotno] = true;
100  }
101 
102  LWLockRelease(SubtransSLRULock);
103 }
#define TransactionIdToEntry(xid)
Definition: subtrans.c:55
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition: transam.c:334
uint32 TransactionId
Definition: c.h:521
#define SubTransCtl
Definition: subtrans.c:63
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1812
int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid)
Definition: slru.c:394
#define InvalidTransactionId
Definition: transam.h:31
#define TransactionIdToPage(xid)
Definition: subtrans.c:54
#define Assert(condition)
Definition: c.h:746
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1208
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ SUBTRANSShmemInit()

void SUBTRANSShmemInit ( void  )

Definition at line 191 of file subtrans.c.

References LWTRANCHE_SUBTRANS_BUFFER, NUM_SUBTRANS_BUFFERS, SimpleLruInit(), SubTransCtl, SubTransPagePrecedes(), and SYNC_HANDLER_NONE.

Referenced by CreateSharedMemoryAndSemaphores().

192 {
193  SubTransCtl->PagePrecedes = SubTransPagePrecedes;
195  SubtransSLRULock, "pg_subtrans",
197 }
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, LWLock *ctllock, const char *subdir, int tranche_id, SyncRequestHandler sync_handler)
Definition: slru.c:186
#define SubTransCtl
Definition: subtrans.c:63
static bool SubTransPagePrecedes(int page1, int page2)
Definition: subtrans.c:366
#define NUM_SUBTRANS_BUFFERS
Definition: subtrans.h:15

◆ SUBTRANSShmemSize()

Size SUBTRANSShmemSize ( void  )

Definition at line 185 of file subtrans.c.

References NUM_SUBTRANS_BUFFERS, and SimpleLruShmemSize().

Referenced by CreateSharedMemoryAndSemaphores().

186 {
188 }
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:155
#define NUM_SUBTRANS_BUFFERS
Definition: subtrans.h:15

◆ TruncateSUBTRANS()

void TruncateSUBTRANS ( TransactionId  oldestXact)

Definition at line 337 of file subtrans.c.

References SimpleLruTruncate(), SubTransCtl, TransactionIdRetreat, and TransactionIdToPage.

Referenced by CreateCheckPoint(), and CreateRestartPoint().

338 {
339  int cutoffPage;
340 
341  /*
342  * The cutoff point is the start of the segment containing oldestXact. We
343  * pass the *page* containing oldestXact to SimpleLruTruncate. We step
344  * back one transaction to avoid passing a cutoff page that hasn't been
345  * created yet in the rare case that oldestXact would be the first item on
346  * a page and oldestXact == next XID. In that case, if we didn't subtract
347  * one, we'd trigger SimpleLruTruncate's wraparound detection.
348  */
349  TransactionIdRetreat(oldestXact);
350  cutoffPage = TransactionIdToPage(oldestXact);
351 
352  SimpleLruTruncate(SubTransCtl, cutoffPage);
353 }
void SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
Definition: slru.c:1225
#define TransactionIdRetreat(dest)
Definition: transam.h:141
#define SubTransCtl
Definition: subtrans.c:63
#define TransactionIdToPage(xid)
Definition: subtrans.c:54

◆ ZeroSUBTRANSPage()

static int ZeroSUBTRANSPage ( int  pageno)
static

Definition at line 235 of file subtrans.c.

References SimpleLruZeroPage(), and SubTransCtl.

Referenced by BootStrapSUBTRANS(), ExtendSUBTRANS(), and StartupSUBTRANS().

236 {
237  return SimpleLruZeroPage(SubTransCtl, pageno);
238 }
#define SubTransCtl
Definition: subtrans.c:63
int SimpleLruZeroPage(SlruCtl ctl, int pageno)
Definition: slru.c:279

Variable Documentation

◆ SubTransCtlData

SlruCtlData SubTransCtlData
static

Definition at line 61 of file subtrans.c.