PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
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 ShutdownSUBTRANS (void)
 
void CheckPointSUBTRANS (void)
 
void ExtendSUBTRANS (TransactionId newestXact)
 
void TruncateSUBTRANS (TransactionId oldestXact)
 

Variables

static SlruCtlData SubTransCtlData
 

Macro Definition Documentation

#define SUBTRANS_XACTS_PER_PAGE   (BLCKSZ / sizeof(TransactionId))

Definition at line 52 of file subtrans.c.

Referenced by SubTransPagePrecedes().

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

Definition at line 55 of file subtrans.c.

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

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

Function Documentation

void BootStrapSUBTRANS ( void  )

Definition at line 212 of file subtrans.c.

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

Referenced by BootStrapXLOG().

213 {
214  int slotno;
215 
216  LWLockAcquire(SubtransControlLock, LW_EXCLUSIVE);
217 
218  /* Create and zero the first page of the subtrans log */
219  slotno = ZeroSUBTRANSPage(0);
220 
221  /* Make sure it's written out */
223  Assert(!SubTransCtl->shared->page_dirty[slotno]);
224 
225  LWLockRelease(SubtransControlLock);
226 }
static int ZeroSUBTRANSPage(int pageno)
Definition: subtrans.c:237
#define SubTransCtl
Definition: subtrans.c:63
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void SimpleLruWritePage(SlruCtl ctl, int slotno)
Definition: slru.c:574
#define Assert(condition)
Definition: c.h:675
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
void CheckPointSUBTRANS ( void  )

Definition at line 300 of file subtrans.c.

References SimpleLruFlush(), and SubTransCtl.

Referenced by CheckPointGuts().

301 {
302  /*
303  * Flush dirty SUBTRANS pages to disk
304  *
305  * This is not actually necessary from a correctness point of view. We do
306  * it merely to improve the odds that writing of dirty pages is done by
307  * the checkpoint process and not by backends.
308  */
309  TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(true);
311  TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true);
312 }
void SimpleLruFlush(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1100
#define SubTransCtl
Definition: subtrans.c:63
void ExtendSUBTRANS ( TransactionId  newestXact)

Definition at line 324 of file subtrans.c.

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

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

325 {
326  int pageno;
327 
328  /*
329  * No work except at first XID of a page. But beware: just after
330  * wraparound, the first XID of page zero is FirstNormalTransactionId.
331  */
332  if (TransactionIdToEntry(newestXact) != 0 &&
334  return;
335 
336  pageno = TransactionIdToPage(newestXact);
337 
338  LWLockAcquire(SubtransControlLock, LW_EXCLUSIVE);
339 
340  /* Zero the page */
341  ZeroSUBTRANSPage(pageno);
342 
343  LWLockRelease(SubtransControlLock);
344 }
static int ZeroSUBTRANSPage(int pageno)
Definition: subtrans.c:237
#define TransactionIdToEntry(xid)
Definition: subtrans.c:55
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#define FirstNormalTransactionId
Definition: transam.h:34
#define TransactionIdToPage(xid)
Definition: subtrans.c:54
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
void ShutdownSUBTRANS ( void  )

Definition at line 283 of file subtrans.c.

References SimpleLruFlush(), and SubTransCtl.

Referenced by ShutdownXLOG().

284 {
285  /*
286  * Flush dirty SUBTRANS pages to disk
287  *
288  * This is not actually necessary from a correctness point of view. We do
289  * it merely as a debugging aid.
290  */
291  TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(false);
292  SimpleLruFlush(SubTransCtl, false);
293  TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(false);
294 }
void SimpleLruFlush(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1100
#define SubTransCtl
Definition: subtrans.c:63
void StartupSUBTRANS ( TransactionId  oldestActiveXID)

Definition at line 250 of file subtrans.c.

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

Referenced by StartupXLOG().

251 {
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(SubtransControlLock, LW_EXCLUSIVE);
262 
263  startPage = TransactionIdToPage(oldestActiveXID);
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(SubtransControlLock);
277 }
static int ZeroSUBTRANSPage(int pageno)
Definition: subtrans.c:237
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
TransactionId nextXid
Definition: transam.h:117
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:1111
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 ConditionalXactLockTableWait(), SubTransGetTopmostTransaction(), TransactionIdDidAbort(), TransactionIdDidCommit(), and XactLockTableWait().

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(SubtransControlLock);
133 
134  return parent;
135 }
#define TransactionIdToEntry(xid)
Definition: subtrans.c:55
uint32 TransactionId
Definition: c.h:397
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId TransactionXmin
Definition: snapmgr.c:164
#define SubTransCtl
Definition: subtrans.c:63
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
#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:463
#define Assert(condition)
Definition: c.h:675
#define TransactionIdIsNormal(xid)
Definition: transam.h:42
TransactionId SubTransGetTopmostTransaction ( TransactionId  xid)

Definition at line 150 of file subtrans.c.

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

Referenced by CheckForSerializableConflictOut(), PredicateLockTuple(), TransactionIdIsInProgress(), 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:397
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:109
bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition: transam.c:349
TransactionId TransactionXmin
Definition: snapmgr.c:164
#define ERROR
Definition: elog.h:43
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define Assert(condition)
Definition: c.h:675
#define elog
Definition: elog.h:219
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static bool SubTransPagePrecedes ( int  page1,
int  page2 
)
static

Definition at line 383 of file subtrans.c.

References FirstNormalTransactionId, SUBTRANS_XACTS_PER_PAGE, and TransactionIdPrecedes().

Referenced by SUBTRANSShmemInit().

384 {
385  TransactionId xid1;
386  TransactionId xid2;
387 
388  xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
389  xid1 += FirstNormalTransactionId;
390  xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
391  xid2 += FirstNormalTransactionId;
392 
393  return TransactionIdPrecedes(xid1, xid2);
394 }
uint32 TransactionId
Definition: c.h:397
#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
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(SubtransControlLock, 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(SubtransControlLock);
103 }
#define TransactionIdToEntry(xid)
Definition: subtrans.c:55
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition: transam.c:334
uint32 TransactionId
Definition: c.h:397
#define SubTransCtl
Definition: subtrans.c:63
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
int SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok, TransactionId xid)
Definition: slru.c:371
#define InvalidTransactionId
Definition: transam.h:31
#define TransactionIdToPage(xid)
Definition: subtrans.c:54
#define Assert(condition)
Definition: c.h:675
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1111
#define TransactionIdIsValid(xid)
Definition: transam.h:41
void SUBTRANSShmemInit ( void  )

Definition at line 191 of file subtrans.c.

References LWTRANCHE_SUBTRANS_BUFFERS, NUM_SUBTRANS_BUFFERS, SimpleLruInit(), SubTransCtl, and SubTransPagePrecedes().

Referenced by CreateSharedMemoryAndSemaphores().

192 {
193  SubTransCtl->PagePrecedes = SubTransPagePrecedes;
195  SubtransControlLock, "pg_subtrans",
197  /* Override default assumption that writes should be fsync'd */
198  SubTransCtl->do_fsync = false;
199 }
#define SubTransCtl
Definition: subtrans.c:63
static bool SubTransPagePrecedes(int page1, int page2)
Definition: subtrans.c:383
#define NUM_SUBTRANS_BUFFERS
Definition: subtrans.h:15
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, LWLock *ctllock, const char *subdir, int tranche_id)
Definition: slru.c:165
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:145
#define NUM_SUBTRANS_BUFFERS
Definition: subtrans.h:15
void TruncateSUBTRANS ( TransactionId  oldestXact)

Definition at line 354 of file subtrans.c.

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

355 {
356  int cutoffPage;
357 
358  /*
359  * The cutoff point is the start of the segment containing oldestXact. We
360  * pass the *page* containing oldestXact to SimpleLruTruncate. We step
361  * back one transaction to avoid passing a cutoff page that hasn't been
362  * created yet in the rare case that oldestXact would be the first item on
363  * a page and oldestXact == next XID. In that case, if we didn't subtract
364  * one, we'd trigger SimpleLruTruncate's wraparound detection.
365  */
366  TransactionIdRetreat(oldestXact);
367  cutoffPage = TransactionIdToPage(oldestXact);
368 
369  SimpleLruTruncate(SubTransCtl, cutoffPage);
370 }
void SimpleLruTruncate(SlruCtl ctl, int cutoffPage)
Definition: slru.c:1165
#define TransactionIdRetreat(dest)
Definition: transam.h:56
#define SubTransCtl
Definition: subtrans.c:63
#define TransactionIdToPage(xid)
Definition: subtrans.c:54
static int ZeroSUBTRANSPage ( int  pageno)
static

Definition at line 237 of file subtrans.c.

References SimpleLruZeroPage(), and SubTransCtl.

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

238 {
239  return SimpleLruZeroPage(SubTransCtl, pageno);
240 }
#define SubTransCtl
Definition: subtrans.c:63
int SimpleLruZeroPage(SlruCtl ctl, int pageno)
Definition: slru.c:259

Variable Documentation

SlruCtlData SubTransCtlData
static

Definition at line 61 of file subtrans.c.