Thanks to visit codestin.com
Credit goes to doxygen.postgresql.org

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 "miscadmin.h"
#include "pg_trace.h"
#include "utils/guc_hooks.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 TransactionIdToEntry(xid)   ((xid) % (TransactionId) SUBTRANS_XACTS_PER_PAGE)
 
#define SubTransCtl   (&SubTransCtlData)
 

Functions

static int64 TransactionIdToPage (TransactionId xid)
 
static bool SubTransPagePrecedes (int64 page1, int64 page2)
 
void SubTransSetParent (TransactionId xid, TransactionId parent)
 
TransactionId SubTransGetParent (TransactionId xid)
 
TransactionId SubTransGetTopmostTransaction (TransactionId xid)
 
static int SUBTRANSShmemBuffers (void)
 
Size SUBTRANSShmemSize (void)
 
void SUBTRANSShmemInit (void)
 
bool check_subtrans_buffers (int *newval, void **extra, GucSource source)
 
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 54 of file subtrans.c.

◆ SubTransCtl

#define SubTransCtl   (&SubTransCtlData)

Definition at line 74 of file subtrans.c.

◆ TransactionIdToEntry

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

Definition at line 66 of file subtrans.c.

Function Documentation

◆ BootStrapSUBTRANS()

void BootStrapSUBTRANS ( void  )

Definition at line 269 of file subtrans.c.

270{
271 /* Zero the initial page and flush it to disk */
273}
void SimpleLruZeroAndWritePage(SlruCtl ctl, int64 pageno)
Definition: slru.c:444
#define SubTransCtl
Definition: subtrans.c:74

References SimpleLruZeroAndWritePage(), and SubTransCtl.

Referenced by BootStrapXLOG().

◆ check_subtrans_buffers()

bool check_subtrans_buffers ( int *  newval,
void **  extra,
GucSource  source 
)

Definition at line 253 of file subtrans.c.

254{
255 return check_slru_buffers("subtransaction_buffers", newval);
256}
#define newval
bool check_slru_buffers(const char *name, int *newval)
Definition: slru.c:355

References check_slru_buffers(), and newval.

◆ CheckPointSUBTRANS()

void CheckPointSUBTRANS ( void  )

Definition at line 329 of file subtrans.c.

330{
331 /*
332 * Write dirty SUBTRANS pages to disk
333 *
334 * This is not actually necessary from a correctness point of view. We do
335 * it merely to improve the odds that writing of dirty pages is done by
336 * the checkpoint process and not by backends.
337 */
338 TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_START(true);
340 TRACE_POSTGRESQL_SUBTRANS_CHECKPOINT_DONE(true);
341}
void SimpleLruWriteAll(SlruCtl ctl, bool allow_redirtied)
Definition: slru.c:1347

References SimpleLruWriteAll(), and SubTransCtl.

Referenced by CheckPointGuts().

◆ ExtendSUBTRANS()

void ExtendSUBTRANS ( TransactionId  newestXact)

Definition at line 353 of file subtrans.c.

354{
355 int64 pageno;
356 LWLock *lock;
357
358 /*
359 * No work except at first XID of a page. But beware: just after
360 * wraparound, the first XID of page zero is FirstNormalTransactionId.
361 */
362 if (TransactionIdToEntry(newestXact) != 0 &&
364 return;
365
366 pageno = TransactionIdToPage(newestXact);
367
368 lock = SimpleLruGetBankLock(SubTransCtl, pageno);
370
371 /* Zero the page */
373
374 LWLockRelease(lock);
375}
int64_t int64
Definition: c.h:535
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
@ LW_EXCLUSIVE
Definition: lwlock.h:112
int SimpleLruZeroPage(SlruCtl ctl, int64 pageno)
Definition: slru.c:375
static LWLock * SimpleLruGetBankLock(SlruCtl ctl, int64 pageno)
Definition: slru.h:175
Definition: lwlock.h:42
#define TransactionIdToEntry(xid)
Definition: subtrans.c:66
static int64 TransactionIdToPage(TransactionId xid)
Definition: subtrans.c:61
#define TransactionIdEquals(id1, id2)
Definition: transam.h:43
#define FirstNormalTransactionId
Definition: transam.h:34

References FirstNormalTransactionId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), SimpleLruGetBankLock(), SimpleLruZeroPage(), SubTransCtl, TransactionIdEquals, TransactionIdToEntry, and TransactionIdToPage().

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

◆ StartupSUBTRANS()

void StartupSUBTRANS ( TransactionId  oldestActiveXID)

Definition at line 283 of file subtrans.c.

284{
285 FullTransactionId nextXid;
286 int64 startPage;
287 int64 endPage;
288 LWLock *prevlock = NULL;
289 LWLock *lock;
290
291 /*
292 * Since we don't expect pg_subtrans to be valid across crashes, we
293 * initialize the currently-active page(s) to zeroes during startup.
294 * Whenever we advance into a new page, ExtendSUBTRANS will likewise zero
295 * the new page without regard to whatever was previously on disk.
296 */
297 startPage = TransactionIdToPage(oldestActiveXID);
298 nextXid = TransamVariables->nextXid;
300
301 for (;;)
302 {
303 lock = SimpleLruGetBankLock(SubTransCtl, startPage);
304 if (prevlock != lock)
305 {
306 if (prevlock)
307 LWLockRelease(prevlock);
309 prevlock = lock;
310 }
311
312 (void) SimpleLruZeroPage(SubTransCtl, startPage);
313 if (startPage == endPage)
314 break;
315
316 startPage++;
317 /* must account for wraparound */
318 if (startPage > TransactionIdToPage(MaxTransactionId))
319 startPage = 0;
320 }
321
322 LWLockRelease(lock);
323}
FullTransactionId nextXid
Definition: transam.h:220
#define XidFromFullTransactionId(x)
Definition: transam.h:48
#define MaxTransactionId
Definition: transam.h:35
TransamVariablesData * TransamVariables
Definition: varsup.c:34

References LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MaxTransactionId, TransamVariablesData::nextXid, SimpleLruGetBankLock(), SimpleLruZeroPage(), SubTransCtl, TransactionIdToPage(), TransamVariables, and XidFromFullTransactionId.

Referenced by StartupXLOG().

◆ SubTransGetParent()

TransactionId SubTransGetParent ( TransactionId  xid)

Definition at line 121 of file subtrans.c.

122{
123 int64 pageno = TransactionIdToPage(xid);
124 int entryno = TransactionIdToEntry(xid);
125 int slotno;
126 TransactionId *ptr;
127 TransactionId parent;
128
129 /* Can't ask about stuff that might not be around anymore */
131
132 /* Bootstrap and frozen XIDs have no parent */
133 if (!TransactionIdIsNormal(xid))
135
136 /* lock is acquired by SimpleLruReadPage_ReadOnly */
137
138 slotno = SimpleLruReadPage_ReadOnly(SubTransCtl, pageno, xid);
139 ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
140 ptr += entryno;
141
142 parent = *ptr;
143
145
146 return parent;
147}
uint32 TransactionId
Definition: c.h:657
Assert(PointerIsAligned(start, uint64))
int SimpleLruReadPage_ReadOnly(SlruCtl ctl, int64 pageno, TransactionId xid)
Definition: slru.c:630
TransactionId TransactionXmin
Definition: snapmgr.c:158
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(), SimpleLruGetBankLock(), SimpleLruReadPage_ReadOnly(), SubTransCtl, TransactionIdFollowsOrEquals(), TransactionIdIsNormal, TransactionIdToEntry, TransactionIdToPage(), and TransactionXmin.

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

◆ SubTransGetTopmostTransaction()

TransactionId SubTransGetTopmostTransaction ( TransactionId  xid)

Definition at line 162 of file subtrans.c.

163{
164 TransactionId parentXid = xid,
165 previousXid = xid;
166
167 /* Can't ask about stuff that might not be around anymore */
169
170 while (TransactionIdIsValid(parentXid))
171 {
172 previousXid = parentXid;
174 break;
175 parentXid = SubTransGetParent(parentXid);
176
177 /*
178 * By convention the parent xid gets allocated first, so should always
179 * precede the child xid. Anything else points to a corrupted data
180 * structure that could lead to an infinite loop, so exit.
181 */
182 if (!TransactionIdPrecedes(parentXid, previousXid))
183 elog(ERROR, "pg_subtrans contains invalid entry: xid %u points to parent xid %u",
184 previousXid, parentXid);
185 }
186
187 Assert(TransactionIdIsValid(previousXid));
188
189 return previousXid;
190}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:226
TransactionId SubTransGetParent(TransactionId xid)
Definition: subtrans.c:121
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 ( int64  page1,
int64  page2 
)
static

Definition at line 409 of file subtrans.c.

410{
411 TransactionId xid1;
412 TransactionId xid2;
413
414 xid1 = ((TransactionId) page1) * SUBTRANS_XACTS_PER_PAGE;
415 xid1 += FirstNormalTransactionId + 1;
416 xid2 = ((TransactionId) page2) * SUBTRANS_XACTS_PER_PAGE;
417 xid2 += FirstNormalTransactionId + 1;
418
419 return (TransactionIdPrecedes(xid1, xid2) &&
421}
#define SUBTRANS_XACTS_PER_PAGE
Definition: subtrans.c:54

References FirstNormalTransactionId, SUBTRANS_XACTS_PER_PAGE, and TransactionIdPrecedes().

Referenced by SUBTRANSShmemInit().

◆ SubTransSetParent()

void SubTransSetParent ( TransactionId  xid,
TransactionId  parent 
)

Definition at line 84 of file subtrans.c.

85{
86 int64 pageno = TransactionIdToPage(xid);
87 int entryno = TransactionIdToEntry(xid);
88 int slotno;
89 LWLock *lock;
90 TransactionId *ptr;
91
93 Assert(TransactionIdFollows(xid, parent));
94
95 lock = SimpleLruGetBankLock(SubTransCtl, pageno);
97
98 slotno = SimpleLruReadPage(SubTransCtl, pageno, true, xid);
99 ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
100 ptr += entryno;
101
102 /*
103 * It's possible we'll try to set the parent xid multiple times but we
104 * shouldn't ever be changing the xid from one valid xid to another valid
105 * xid, which would corrupt the data structure.
106 */
107 if (*ptr != parent)
108 {
110 *ptr = parent;
111 SubTransCtl->shared->page_dirty[slotno] = true;
112 }
113
114 LWLockRelease(lock);
115}
if(TABLE==NULL||TABLE_index==NULL)
Definition: isn.c:81
int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, TransactionId xid)
Definition: slru.c:527
bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition: transam.c:314

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

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

◆ SUBTRANSShmemBuffers()

static int SUBTRANSShmemBuffers ( void  )
static

Definition at line 200 of file subtrans.c.

201{
202 /* auto-tune based on shared buffers */
203 if (subtransaction_buffers == 0)
204 return SimpleLruAutotuneBuffers(512, 1024);
205
207}
#define Min(x, y)
Definition: c.h:1003
#define Max(x, y)
Definition: c.h:997
int subtransaction_buffers
Definition: globals.c:166
int SimpleLruAutotuneBuffers(int divisor, int max)
Definition: slru.c:231
#define SLRU_MAX_ALLOWED_BUFFERS
Definition: slru.h:24

References Max, Min, SimpleLruAutotuneBuffers(), SLRU_MAX_ALLOWED_BUFFERS, and subtransaction_buffers.

Referenced by SUBTRANSShmemInit(), and SUBTRANSShmemSize().

◆ SUBTRANSShmemInit()

void SUBTRANSShmemInit ( void  )

Definition at line 219 of file subtrans.c.

220{
221 /* If auto-tuning is requested, now is the time to do it */
222 if (subtransaction_buffers == 0)
223 {
224 char buf[32];
225
226 snprintf(buf, sizeof(buf), "%d", SUBTRANSShmemBuffers());
227 SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
229
230 /*
231 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
232 * However, if the DBA explicitly set subtransaction_buffers = 0 in
233 * the config file, then PGC_S_DYNAMIC_DEFAULT will fail to override
234 * that and we must force the matter with PGC_S_OVERRIDE.
235 */
236 if (subtransaction_buffers == 0) /* failed to apply it? */
237 SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
239 }
241
242 SubTransCtl->PagePrecedes = SubTransPagePrecedes;
243 SimpleLruInit(SubTransCtl, "subtransaction", SUBTRANSShmemBuffers(), 0,
244 "pg_subtrans", LWTRANCHE_SUBTRANS_BUFFER,
245 LWTRANCHE_SUBTRANS_SLRU, SYNC_HANDLER_NONE, false);
247}
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:4337
@ PGC_S_DYNAMIC_DEFAULT
Definition: guc.h:114
@ PGC_S_OVERRIDE
Definition: guc.h:123
@ PGC_POSTMASTER
Definition: guc.h:74
static char * buf
Definition: pg_test_fsync.c:72
#define snprintf
Definition: port.h:239
void SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns, const char *subdir, int buffer_tranche_id, int bank_tranche_id, SyncRequestHandler sync_handler, bool long_segment_names)
Definition: slru.c:252
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition: slru.h:200
static int SUBTRANSShmemBuffers(void)
Definition: subtrans.c:200
static bool SubTransPagePrecedes(int64 page1, int64 page2)
Definition: subtrans.c:409
@ SYNC_HANDLER_NONE
Definition: sync.h:42

References Assert(), buf, PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT, PGC_S_OVERRIDE, SetConfigOption(), SimpleLruInit(), SlruPagePrecedesUnitTests, snprintf, SUBTRANS_XACTS_PER_PAGE, subtransaction_buffers, SubTransCtl, SubTransPagePrecedes(), SUBTRANSShmemBuffers(), and SYNC_HANDLER_NONE.

Referenced by CreateOrAttachShmemStructs().

◆ SUBTRANSShmemSize()

Size SUBTRANSShmemSize ( void  )

Definition at line 213 of file subtrans.c.

214{
216}
Size SimpleLruShmemSize(int nslots, int nlsns)
Definition: slru.c:198

References SimpleLruShmemSize(), and SUBTRANSShmemBuffers().

Referenced by CalculateShmemSize().

◆ TransactionIdToPage()

static int64 TransactionIdToPage ( TransactionId  xid)
inlinestatic

◆ TruncateSUBTRANS()

void TruncateSUBTRANS ( TransactionId  oldestXact)

Definition at line 385 of file subtrans.c.

386{
387 int64 cutoffPage;
388
389 /*
390 * The cutoff point is the start of the segment containing oldestXact. We
391 * pass the *page* containing oldestXact to SimpleLruTruncate. We step
392 * back one transaction to avoid passing a cutoff page that hasn't been
393 * created yet in the rare case that oldestXact would be the first item on
394 * a page and oldestXact == next XID. In that case, if we didn't subtract
395 * one, we'd trigger SimpleLruTruncate's wraparound detection.
396 */
397 TransactionIdRetreat(oldestXact);
398 cutoffPage = TransactionIdToPage(oldestXact);
399
400 SimpleLruTruncate(SubTransCtl, cutoffPage);
401}
void SimpleLruTruncate(SlruCtl ctl, int64 cutoffPage)
Definition: slru.c:1433
#define TransactionIdRetreat(dest)
Definition: transam.h:141

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

Variable Documentation

◆ SubTransCtlData

SlruCtlData SubTransCtlData
static

Definition at line 72 of file subtrans.c.