PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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 "storage/subsystems.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   (&SubTransSlruDesc)
 

Functions

static int64 TransactionIdToPage (TransactionId xid)
 
static void SUBTRANSShmemRequest (void *arg)
 
static void SUBTRANSShmemInit (void *arg)
 
static bool SubTransPagePrecedes (int64 page1, int64 page2)
 
static int subtrans_errdetail_for_io_error (const void *opaque_data)
 
void SubTransSetParent (TransactionId xid, TransactionId parent)
 
TransactionId SubTransGetParent (TransactionId xid)
 
TransactionId SubTransGetTopmostTransaction (TransactionId xid)
 
static int SUBTRANSShmemBuffers (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

const ShmemCallbacks SUBTRANSShmemCallbacks
 
static SlruDesc SubTransSlruDesc
 

Macro Definition Documentation

◆ SUBTRANS_XACTS_PER_PAGE

#define SUBTRANS_XACTS_PER_PAGE   (BLCKSZ / sizeof(TransactionId))

Definition at line 55 of file subtrans.c.

◆ SubTransCtl

#define SubTransCtl   (&SubTransSlruDesc)

Definition at line 85 of file subtrans.c.

◆ TransactionIdToEntry

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

Definition at line 67 of file subtrans.c.

Function Documentation

◆ BootStrapSUBTRANS()

void BootStrapSUBTRANS ( void  )

Definition at line 288 of file subtrans.c.

289{
290 /* Zero the initial page and flush it to disk */
292}
void SimpleLruZeroAndWritePage(SlruDesc *ctl, int64 pageno)
Definition slru.c:466
#define SubTransCtl
Definition subtrans.c:85

References SimpleLruZeroAndWritePage(), and SubTransCtl.

Referenced by BootStrapXLOG().

◆ check_subtrans_buffers()

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

Definition at line 272 of file subtrans.c.

273{
274 return check_slru_buffers("subtransaction_buffers", newval);
275}
#define newval
bool check_slru_buffers(const char *name, int *newval)
Definition slru.c:377

References check_slru_buffers(), and newval.

◆ CheckPointSUBTRANS()

void CheckPointSUBTRANS ( void  )

Definition at line 348 of file subtrans.c.

349{
350 /*
351 * Write dirty SUBTRANS pages to disk
352 *
353 * This is not actually necessary from a correctness point of view. We do
354 * it merely to improve the odds that writing of dirty pages is done by
355 * the checkpoint process and not by backends.
356 */
360}
static int fb(int x)
void SimpleLruWriteAll(SlruDesc *ctl, bool allow_redirtied)
Definition slru.c:1372

References fb(), SimpleLruWriteAll(), and SubTransCtl.

Referenced by CheckPointGuts().

◆ ExtendSUBTRANS()

void ExtendSUBTRANS ( TransactionId  newestXact)

Definition at line 372 of file subtrans.c.

373{
374 int64 pageno;
375 LWLock *lock;
376
377 /*
378 * No work except at first XID of a page. But beware: just after
379 * wraparound, the first XID of page zero is FirstNormalTransactionId.
380 */
383 return;
384
386
387 lock = SimpleLruGetBankLock(SubTransCtl, pageno);
389
390 /* Zero the page */
392
393 LWLockRelease(lock);
394}
int64_t int64
Definition c.h:621
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition lwlock.c:1150
void LWLockRelease(LWLock *lock)
Definition lwlock.c:1767
@ LW_EXCLUSIVE
Definition lwlock.h:104
int SimpleLruZeroPage(SlruDesc *ctl, int64 pageno)
Definition slru.c:397
static LWLock * SimpleLruGetBankLock(SlruDesc *ctl, int64 pageno)
Definition slru.h:207
#define TransactionIdToEntry(xid)
Definition subtrans.c:67
static int64 TransactionIdToPage(TransactionId xid)
Definition subtrans.c:62
#define TransactionIdEquals(id1, id2)
Definition transam.h:43
#define FirstNormalTransactionId
Definition transam.h:34

References fb(), 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 302 of file subtrans.c.

303{
304 FullTransactionId nextXid;
308 LWLock *lock;
309
310 /*
311 * Since we don't expect pg_subtrans to be valid across crashes, we
312 * initialize the currently-active page(s) to zeroes during startup.
313 * Whenever we advance into a new page, ExtendSUBTRANS will likewise zero
314 * the new page without regard to whatever was previously on disk.
315 */
317 nextXid = TransamVariables->nextXid;
319
320 for (;;)
321 {
323 if (prevlock != lock)
324 {
325 if (prevlock)
328 prevlock = lock;
329 }
330
332 if (startPage == endPage)
333 break;
334
335 startPage++;
336 /* must account for wraparound */
338 startPage = 0;
339 }
340
341 LWLockRelease(lock);
342}
FullTransactionId nextXid
Definition transam.h:220
#define XidFromFullTransactionId(x)
Definition transam.h:48
#define MaxTransactionId
Definition transam.h:35
TransamVariablesData * TransamVariables
Definition varsup.c:37

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

Referenced by StartupXLOG().

◆ subtrans_errdetail_for_io_error()

static int subtrans_errdetail_for_io_error ( const void opaque_data)
static

Definition at line 443 of file subtrans.c.

444{
445 TransactionId xid = *(const TransactionId *) opaque_data;
446
447 return errdetail("Could not access subtransaction status of transaction %u.", xid);
448}
uint32 TransactionId
Definition c.h:736
int errdetail(const char *fmt,...) pg_attribute_printf(1

References errdetail(), and fb().

Referenced by SUBTRANSShmemRequest().

◆ SubTransGetParent()

TransactionId SubTransGetParent ( TransactionId  xid)

Definition at line 129 of file subtrans.c.

130{
131 int64 pageno = TransactionIdToPage(xid);
132 int entryno = TransactionIdToEntry(xid);
133 int slotno;
134 TransactionId *ptr;
135 TransactionId parent;
136
137 /* Can't ask about stuff that might not be around anymore */
139
140 /* Bootstrap and frozen XIDs have no parent */
141 if (!TransactionIdIsNormal(xid))
143
144 /* lock is acquired by SimpleLruReadPage_ReadOnly */
145
147 ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
148 ptr += entryno;
149
150 parent = *ptr;
151
153
154 return parent;
155}
#define Assert(condition)
Definition c.h:943
int SimpleLruReadPage_ReadOnly(SlruDesc *ctl, int64 pageno, const void *opaque_data)
Definition slru.c:654
TransactionId TransactionXmin
Definition snapmgr.c:159
#define InvalidTransactionId
Definition transam.h:31
static bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition transam.h:312
#define TransactionIdIsNormal(xid)
Definition transam.h:42

References Assert, fb(), 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 170 of file subtrans.c.

171{
173 previousXid = xid;
174
175 /* Can't ask about stuff that might not be around anymore */
177
179 {
182 break;
184
185 /*
186 * By convention the parent xid gets allocated first, so should always
187 * precede the child xid. Anything else points to a corrupted data
188 * structure that could lead to an infinite loop, so exit.
189 */
191 elog(ERROR, "pg_subtrans contains invalid entry: xid %u points to parent xid %u",
193 }
194
196
197 return previousXid;
198}
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
TransactionId SubTransGetParent(TransactionId xid)
Definition subtrans.c:129
#define TransactionIdIsValid(xid)
Definition transam.h:41
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition transam.h:263

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

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

◆ SubTransPagePrecedes()

static bool SubTransPagePrecedes ( int64  page1,
int64  page2 
)
static

◆ SubTransSetParent()

void SubTransSetParent ( TransactionId  xid,
TransactionId  parent 
)

Definition at line 92 of file subtrans.c.

93{
94 int64 pageno = TransactionIdToPage(xid);
96 int slotno;
97 LWLock *lock;
98 TransactionId *ptr;
99
101 Assert(TransactionIdFollows(xid, parent));
102
103 lock = SimpleLruGetBankLock(SubTransCtl, pageno);
105
106 slotno = SimpleLruReadPage(SubTransCtl, pageno, true, &xid);
107 ptr = (TransactionId *) SubTransCtl->shared->page_buffer[slotno];
108 ptr += entryno;
109
110 /*
111 * It's possible we'll try to set the parent xid multiple times but we
112 * shouldn't ever be changing the xid from one valid xid to another valid
113 * xid, which would corrupt the data structure.
114 */
115 if (*ptr != parent)
116 {
118 *ptr = parent;
119 SubTransCtl->shared->page_dirty[slotno] = true;
120 }
121
122 LWLockRelease(lock);
123}
int SimpleLruReadPage(SlruDesc *ctl, int64 pageno, bool write_ok, const void *opaque_data)
Definition slru.c:550
static bool TransactionIdFollows(TransactionId id1, TransactionId id2)
Definition transam.h:297

References Assert, fb(), 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 208 of file subtrans.c.

209{
210 /* auto-tune based on shared buffers */
211 if (subtransaction_buffers == 0)
212 return SimpleLruAutotuneBuffers(512, 1024);
213
215}
#define Min(x, y)
Definition c.h:1091
#define Max(x, y)
Definition c.h:1085
int subtransaction_buffers
Definition globals.c:169
int SimpleLruAutotuneBuffers(int divisor, int max)
Definition slru.c:235
#define SLRU_MAX_ALLOWED_BUFFERS
Definition slru.h:26

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

Referenced by SUBTRANSShmemRequest().

◆ SUBTRANSShmemInit()

static void SUBTRANSShmemInit ( void arg)
static

Definition at line 263 of file subtrans.c.

264{
266}
#define SlruPagePrecedesUnitTests(ctl, per_page)
Definition slru.h:233

References SlruPagePrecedesUnitTests, SUBTRANS_XACTS_PER_PAGE, and SubTransCtl.

◆ SUBTRANSShmemRequest()

static void SUBTRANSShmemRequest ( void arg)
static

Definition at line 223 of file subtrans.c.

224{
225 /* If auto-tuning is requested, now is the time to do it */
226 if (subtransaction_buffers == 0)
227 {
228 char buf[32];
229
230 snprintf(buf, sizeof(buf), "%d", SUBTRANSShmemBuffers());
231 SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
233
234 /*
235 * We prefer to report this value's source as PGC_S_DYNAMIC_DEFAULT.
236 * However, if the DBA explicitly set subtransaction_buffers = 0 in
237 * the config file, then PGC_S_DYNAMIC_DEFAULT will fail to override
238 * that and we must force the matter with PGC_S_OVERRIDE.
239 */
240 if (subtransaction_buffers == 0) /* failed to apply it? */
241 SetConfigOption("subtransaction_buffers", buf, PGC_POSTMASTER,
243 }
245
247 .name = "subtransaction",
248 .Dir = "pg_subtrans",
249 .long_segment_names = false,
250
251 .nslots = SUBTRANSShmemBuffers(),
252
253 .sync_handler = SYNC_HANDLER_NONE,
254 .PagePrecedes = SubTransPagePrecedes,
255 .errdetail_for_io_error = subtrans_errdetail_for_io_error,
256
257 .buffer_tranche_id = LWTRANCHE_SUBTRANS_BUFFER,
258 .bank_tranche_id = LWTRANCHE_SUBTRANS_SLRU,
259 );
260}
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition guc.c:4234
@ PGC_S_DYNAMIC_DEFAULT
Definition guc.h:114
@ PGC_S_OVERRIDE
Definition guc.h:123
@ PGC_POSTMASTER
Definition guc.h:74
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define snprintf
Definition port.h:260
#define SimpleLruRequest(...)
Definition slru.h:218
static int subtrans_errdetail_for_io_error(const void *opaque_data)
Definition subtrans.c:443
static SlruDesc SubTransSlruDesc
Definition subtrans.c:83
static int SUBTRANSShmemBuffers(void)
Definition subtrans.c:208
static bool SubTransPagePrecedes(int64 page1, int64 page2)
Definition subtrans.c:428
@ SYNC_HANDLER_NONE
Definition sync.h:42
const char * name

References Assert, buf, fb(), name, PGC_POSTMASTER, PGC_S_DYNAMIC_DEFAULT, PGC_S_OVERRIDE, SetConfigOption(), SimpleLruRequest, snprintf, subtrans_errdetail_for_io_error(), subtransaction_buffers, SubTransPagePrecedes(), SUBTRANSShmemBuffers(), SubTransSlruDesc, and SYNC_HANDLER_NONE.

◆ TransactionIdToPage()

static int64 TransactionIdToPage ( TransactionId  xid)
inlinestatic

◆ TruncateSUBTRANS()

void TruncateSUBTRANS ( TransactionId  oldestXact)

Definition at line 404 of file subtrans.c.

405{
407
408 /*
409 * The cutoff point is the start of the segment containing oldestXact. We
410 * pass the *page* containing oldestXact to SimpleLruTruncate. We step
411 * back one transaction to avoid passing a cutoff page that hasn't been
412 * created yet in the rare case that oldestXact would be the first item on
413 * a page and oldestXact == next XID. In that case, if we didn't subtract
414 * one, we'd trigger SimpleLruTruncate's wraparound detection.
415 */
416 TransactionIdRetreat(oldestXact);
417 cutoffPage = TransactionIdToPage(oldestXact);
418
420}
void SimpleLruTruncate(SlruDesc *ctl, int64 cutoffPage)
Definition slru.c:1458
#define TransactionIdRetreat(dest)
Definition transam.h:141

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

Referenced by CreateCheckPoint(), and CreateRestartPoint().

Variable Documentation

◆ SUBTRANSShmemCallbacks

const ShmemCallbacks SUBTRANSShmemCallbacks
Initial value:
= {
.request_fn = SUBTRANSShmemRequest,
.init_fn = SUBTRANSShmemInit,
}
static void SUBTRANSShmemInit(void *arg)
Definition subtrans.c:263
static void SUBTRANSShmemRequest(void *arg)
Definition subtrans.c:223

Definition at line 75 of file subtrans.c.

75 {
76 .request_fn = SUBTRANSShmemRequest,
77 .init_fn = SUBTRANSShmemInit,
78};

◆ SubTransSlruDesc

SlruDesc SubTransSlruDesc
static

Definition at line 83 of file subtrans.c.

Referenced by SUBTRANSShmemRequest().