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.

◆ SubTransCtl

#define SubTransCtl   (&SubTransCtlData)

Definition at line 63 of file subtrans.c.

◆ TransactionIdToEntry

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

Definition at line 55 of file subtrans.c.

◆ TransactionIdToPage

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

Definition at line 54 of file subtrans.c.

Function Documentation

◆ BootStrapSUBTRANS()

void BootStrapSUBTRANS ( void  )

Definition at line 211 of file subtrans.c.

212 {
213  int slotno;
214 
215  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
216 
217  /* Create and zero the first page of the subtrans log */
218  slotno = ZeroSUBTRANSPage(0);
219 
220  /* Make sure it's written out */
222  Assert(!SubTransCtl->shared->page_dirty[slotno]);
223 
224  LWLockRelease(SubtransSLRULock);
225 }
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1195
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1808
@ LW_EXCLUSIVE
Definition: lwlock.h:116
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:615
static int ZeroSUBTRANSPage(int pageno)
Definition: subtrans.c:236
#define SubTransCtl
Definition: subtrans.c:63

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

Referenced by BootStrapXLOG().

◆ CheckPointSUBTRANS()

void CheckPointSUBTRANS ( void  )

Definition at line 284 of file subtrans.c.

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

References SimpleLruWriteAll(), and SubTransCtl.

Referenced by CheckPointGuts().

◆ ExtendSUBTRANS()

void ExtendSUBTRANS ( TransactionId  newestXact)

Definition at line 308 of file subtrans.c.

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

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

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

◆ StartupSUBTRANS()

void StartupSUBTRANS ( TransactionId  oldestActiveXID)

Definition at line 249 of file subtrans.c.

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

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

Referenced by StartupXLOG().

◆ SubTransGetParent()

TransactionId SubTransGetParent ( TransactionId  xid)

Definition at line 109 of file subtrans.c.

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 }
uint32 TransactionId
Definition: c.h:641
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
Definition: slru.c:496
TransactionId TransactionXmin
Definition: snapmgr.c:104
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:329
#define InvalidTransactionId
Definition: transam.h:31
#define TransactionIdIsNormal(xid)
Definition: transam.h:42

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

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

◆ SubTransGetTopmostTransaction()

TransactionId SubTransGetTopmostTransaction ( TransactionId  xid)

Definition at line 150 of file subtrans.c.

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 }
#define ERROR
Definition: elog.h:39
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:109
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:280
#define TransactionIdIsValid(xid)
Definition: transam.h:41

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

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

◆ SubTransPagePrecedes()

static bool SubTransPagePrecedes ( int  page1,
int  page2 
)
static

Definition at line 362 of file subtrans.c.

363 {
364  TransactionId xid1;
365  TransactionId xid2;
366 
367  xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
368  xid1 += FirstNormalTransactionId + 1;
369  xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
370  xid2 += FirstNormalTransactionId + 1;
371 
372  return (TransactionIdPrecedes(xid1, xid2) &&
374 }
#define SUBTRANS_XACTS_PER_PAGE
Definition: subtrans.c:52

References FirstNormalTransactionId, SUBTRANS_XACTS_PER_PAGE, and TransactionIdPrecedes().

Referenced by SUBTRANSShmemInit().

◆ SubTransSetParent()

void SubTransSetParent ( TransactionId  xid,
TransactionId  parent 
)

Definition at line 74 of file subtrans.c.

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 }
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:77
int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid)
Definition: slru.c:396
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition: transam.c:314

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

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

◆ SUBTRANSShmemInit()

void SUBTRANSShmemInit ( void  )

Definition at line 191 of file subtrans.c.

192 {
193  SubTransCtl->PagePrecedes = SubTransPagePrecedes;
195  SubtransSLRULock, "pg_subtrans",
198 }
@ LWTRANCHE_SUBTRANS_BUFFER
Definition: lwlock.h:183
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:188
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition: slru.h:156
static bool SubTransPagePrecedes(int page1, int page2)
Definition: subtrans.c:362
#define NUM_SUBTRANS_BUFFERS
Definition: subtrans.h:15
@ SYNC_HANDLER_NONE
Definition: sync.h:42

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

Referenced by CreateSharedMemoryAndSemaphores().

◆ SUBTRANSShmemSize()

Size SUBTRANSShmemSize ( void  )

Definition at line 185 of file subtrans.c.

186 {
188 }
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:156

References NUM_SUBTRANS_BUFFERS, and SimpleLruShmemSize().

Referenced by CalculateShmemSize().

◆ TruncateSUBTRANS()

void TruncateSUBTRANS ( TransactionId  oldestXact)

Definition at line 338 of file subtrans.c.

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

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

◆ ZeroSUBTRANSPage()

static int ZeroSUBTRANSPage ( int  pageno)
static

Definition at line 236 of file subtrans.c.

237 {
238  return SimpleLruZeroPage(SubTransCtl, pageno);
239 }
int SimpleLruZeroPage(SlruCtl ctl, int pageno)
Definition: slru.c:281

References SimpleLruZeroPage(), and SubTransCtl.

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

Variable Documentation

◆ SubTransCtlData

SlruCtlData SubTransCtlData
static

Definition at line 61 of file subtrans.c.