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 TransactionId cachedFetchSubXid = InvalidTransactionId
 
static TransactionId cachedFetchTopmostXid = InvalidTransactionId
 
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 71 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 229 of file subtrans.c.

230 {
231  int slotno;
232 
233  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
234 
235  /* Create and zero the first page of the subtrans log */
236  slotno = ZeroSUBTRANSPage(0);
237 
238  /* Make sure it's written out */
240  Assert(!SubTransCtl->shared->page_dirty[slotno]);
241 
242  LWLockRelease(SubtransSLRULock);
243 }
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1196
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1800
@ LW_EXCLUSIVE
Definition: lwlock.h:104
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:614
static int ZeroSUBTRANSPage(int pageno)
Definition: subtrans.c:254
#define SubTransCtl
Definition: subtrans.c:71

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

Referenced by BootStrapXLOG().

◆ CheckPointSUBTRANS()

void CheckPointSUBTRANS ( void  )

Definition at line 302 of file subtrans.c.

303 {
304  /*
305  * Write dirty SUBTRANS pages to disk
306  *
307  * This is not actually necessary from a correctness point of view. We do
308  * it merely to improve the odds that writing of dirty pages is done by
309  * the checkpoint process and not by backends.
310  */
311  TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(true);
313  TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true);
314 }
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1156

References SimpleLruWriteAll(), and SubTransCtl.

Referenced by CheckPointGuts().

◆ ExtendSUBTRANS()

void ExtendSUBTRANS ( TransactionId  newestXact)

Definition at line 326 of file subtrans.c.

327 {
328  int pageno;
329 
330  /*
331  * No work except at first XID of a page. But beware: just after
332  * wraparound, the first XID of page zero is FirstNormalTransactionId.
333  */
334  if (TransactionIdToEntry(newestXact) != 0 &&
336  return;
337 
338  pageno = TransactionIdToPage(newestXact);
339 
340  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
341 
342  /* Zero the page */
343  ZeroSUBTRANSPage(pageno);
344 
345  LWLockRelease(SubtransSLRULock);
346 }
#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 267 of file subtrans.c.

268 {
269  FullTransactionId nextXid;
270  int startPage;
271  int endPage;
272 
273  /*
274  * Since we don't expect pg_subtrans to be valid across crashes, we
275  * initialize the currently-active page(s) to zeroes during startup.
276  * Whenever we advance into a new page, ExtendSUBTRANS will likewise zero
277  * the new page without regard to whatever was previously on disk.
278  */
279  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
280 
281  startPage = TransactionIdToPage(oldestActiveXID);
282  nextXid = ShmemVariableCache->nextXid;
283  endPage = TransactionIdToPage(XidFromFullTransactionId(nextXid));
284 
285  while (startPage != endPage)
286  {
287  (void) ZeroSUBTRANSPage(startPage);
288  startPage++;
289  /* must account for wraparound */
290  if (startPage > TransactionIdToPage(MaxTransactionId))
291  startPage = 0;
292  }
293  (void) ZeroSUBTRANSPage(startPage);
294 
295  LWLockRelease(SubtransSLRULock);
296 }
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 117 of file subtrans.c.

118 {
119  int pageno = TransactionIdToPage(xid);
120  int entryno = TransactionIdToEntry(xid);
121  int slotno;
122  TransactionId *ptr;
123  TransactionId parent;
124 
125  /* Can't ask about stuff that might not be around anymore */
127 
128  /* Bootstrap and frozen XIDs have no parent */
129  if (!TransactionIdIsNormal(xid))
130  return InvalidTransactionId;
131 
132  /* lock is acquired by SimpleLruReadPage_ReadOnly */
133 
134  slotno = SimpleLruReadPage_ReadOnly(SubTransCtl, pageno, xid);
135  ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
136  ptr += entryno;
137 
138  parent = *ptr;
139 
140  LWLockRelease(SubtransSLRULock);
141 
142  return parent;
143 }
uint32 TransactionId
Definition: c.h:587
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int pageno, TransactionId xid)
Definition: slru.c:495
TransactionId TransactionXmin
Definition: snapmgr.c:112
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
#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 158 of file subtrans.c.

159 {
160  TransactionId parentXid = xid,
161  previousXid = xid;
162 
163  /* Can't ask about stuff that might not be around anymore */
165 
166  /*
167  * Before going to the subtrans log, check our single item cache to see if
168  * we know the result from a previous/recent request.
169  */
171  return cachedFetchTopmostXid;
172 
173  while (TransactionIdIsValid(parentXid))
174  {
175  previousXid = parentXid;
176  if (TransactionIdPrecedes(parentXid, TransactionXmin))
177  break;
178  parentXid = SubTransGetParent(parentXid);
179 
180  /*
181  * By convention the parent xid gets allocated first, so should always
182  * precede the child xid. Anything else points to a corrupted data
183  * structure that could lead to an infinite loop, so exit.
184  */
185  if (!TransactionIdPrecedes(parentXid, previousXid))
186  elog(ERROR, "pg_subtrans contains invalid entry: xid %u points to parent xid %u",
187  previousXid, parentXid);
188  }
189 
190  Assert(TransactionIdIsValid(previousXid));
191 
192  cachedFetchSubXid = xid;
193  cachedFetchTopmostXid = previousXid;
194 
195  return previousXid;
196 }
#define ERROR
Definition: elog.h:33
#define elog(elevel,...)
Definition: elog.h:218
static TransactionId cachedFetchSubXid
Definition: subtrans.c:63
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:117
static TransactionId cachedFetchTopmostXid
Definition: subtrans.c:64
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define TransactionIdIsValid(xid)
Definition: transam.h:41

References Assert(), cachedFetchSubXid, cachedFetchTopmostXid, elog, ERROR, SubTransGetParent(), TransactionIdEquals, 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 380 of file subtrans.c.

381 {
382  TransactionId xid1;
383  TransactionId xid2;
384 
385  xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
386  xid1 += FirstNormalTransactionId + 1;
387  xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
388  xid2 += FirstNormalTransactionId + 1;
389 
390  return (TransactionIdPrecedes(xid1, xid2) &&
392 }
#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 82 of file subtrans.c.

83 {
84  int pageno = TransactionIdToPage(xid);
85  int entryno = TransactionIdToEntry(xid);
86  int slotno;
87  TransactionId *ptr;
88 
90  Assert(TransactionIdFollows(xid, parent));
91 
92  LWLockAcquire(SubtransSLRULock, LW_EXCLUSIVE);
93 
94  slotno = SimpleLruReadPage(SubTransCtl, pageno, true, xid);
95  ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
96  ptr += entryno;
97 
98  /*
99  * It's possible we'll try to set the parent xid multiple times but we
100  * shouldn't ever be changing the xid from one valid xid to another valid
101  * xid, which would corrupt the data structure.
102  */
103  if (*ptr != parent)
104  {
105  Assert(*ptr == InvalidTransactionId);
106  *ptr = parent;
107  SubTransCtl->shared->page_dirty[slotno] = true;
108  }
109 
110  LWLockRelease(SubtransSLRULock);
111 }
int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid)
Definition: slru.c:395
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition: transam.c:334

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 209 of file subtrans.c.

210 {
211  SubTransCtl->PagePrecedes = SubTransPagePrecedes;
213  SubtransSLRULock, "pg_subtrans",
216 }
@ LWTRANCHE_SUBTRANS_BUFFER
Definition: lwlock.h:171
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:187
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition: slru.h:156
static bool SubTransPagePrecedes(int page1, int page2)
Definition: subtrans.c:380
#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 203 of file subtrans.c.

204 {
206 }
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 356 of file subtrans.c.

357 {
358  int cutoffPage;
359 
360  /*
361  * The cutoff point is the start of the segment containing oldestXact. We
362  * pass the *page* containing oldestXact to SimpleLruTruncate. We step
363  * back one transaction to avoid passing a cutoff page that hasn't been
364  * created yet in the rare case that oldestXact would be the first item on
365  * a page and oldestXact == next XID. In that case, if we didn't subtract
366  * one, we'd trigger SimpleLruTruncate's wraparound detection.
367  */
368  TransactionIdRetreat(oldestXact);
369  cutoffPage = TransactionIdToPage(oldestXact);
370 
371  SimpleLruTruncate(SubTransCtl, cutoffPage);
372 }
void SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
Definition: slru.c:1226
#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 254 of file subtrans.c.

255 {
256  return SimpleLruZeroPage(SubTransCtl, pageno);
257 }
int SimpleLruZeroPage(SlruCtl ctl, int pageno)
Definition: slru.c:280

References SimpleLruZeroPage(), and SubTransCtl.

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

Variable Documentation

◆ cachedFetchSubXid

TransactionId cachedFetchSubXid = InvalidTransactionId
static

Definition at line 63 of file subtrans.c.

Referenced by SubTransGetTopmostTransaction().

◆ cachedFetchTopmostXid

TransactionId cachedFetchTopmostXid = InvalidTransactionId
static

Definition at line 64 of file subtrans.c.

Referenced by SubTransGetTopmostTransaction().

◆ SubTransCtlData

SlruCtlData SubTransCtlData
static

Definition at line 69 of file subtrans.c.