PostgreSQL Source Code: src/include/access/multixact.h File Reference (original) (raw)
Go to the source code of this file.
Data Structures | |
---|---|
struct | MultiXactMember |
struct | xl_multixact_create |
struct | xl_multixact_truncate |
Macros | |
---|---|
#define | InvalidMultiXactId ((MultiXactId) 0) |
#define | FirstMultiXactId ((MultiXactId) 1) |
#define | MaxMultiXactId ((MultiXactId) 0xFFFFFFFF) |
#define | MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId) |
#define | MaxMultiXactOffset ((MultiXactOffset) 0xFFFFFFFF) |
#define | MaxMultiXactStatus MultiXactStatusUpdate |
#define | ISUPDATE_from_mxstatus(status) ((status) > MultiXactStatusForUpdate) |
#define | XLOG_MULTIXACT_ZERO_OFF_PAGE 0x00 |
#define | XLOG_MULTIXACT_ZERO_MEM_PAGE 0x10 |
#define | XLOG_MULTIXACT_CREATE_ID 0x20 |
#define | XLOG_MULTIXACT_TRUNCATE_ID 0x30 |
#define | SizeOfMultiXactCreate (offsetof(xl_multixact_create, members)) |
#define | SizeOfMultiXactTruncate (sizeof(xl_multixact_truncate)) |
Typedefs | |
---|---|
typedef struct MultiXactMember | MultiXactMember |
typedef struct xl_multixact_create | xl_multixact_create |
typedef struct xl_multixact_truncate | xl_multixact_truncate |
◆ FirstMultiXactId
◆ InvalidMultiXactId
◆ ISUPDATE_from_mxstatus
◆ MaxMultiXactId
◆ MaxMultiXactOffset
◆ MaxMultiXactStatus
◆ MultiXactIdIsValid
◆ SizeOfMultiXactCreate
◆ SizeOfMultiXactTruncate
◆ XLOG_MULTIXACT_CREATE_ID
#define XLOG_MULTIXACT_CREATE_ID 0x20
◆ XLOG_MULTIXACT_TRUNCATE_ID
#define XLOG_MULTIXACT_TRUNCATE_ID 0x30
◆ XLOG_MULTIXACT_ZERO_MEM_PAGE
#define XLOG_MULTIXACT_ZERO_MEM_PAGE 0x10
◆ XLOG_MULTIXACT_ZERO_OFF_PAGE
#define XLOG_MULTIXACT_ZERO_OFF_PAGE 0x00
◆ MultiXactMember
◆ xl_multixact_create
◆ xl_multixact_truncate
◆ MultiXactStatus
Enumerator |
---|
MultiXactStatusForKeyShare |
MultiXactStatusForShare |
MultiXactStatusForNoKeyUpdate |
MultiXactStatusForUpdate |
MultiXactStatusNoKeyUpdate |
MultiXactStatusUpdate |
Definition at line 37 of file multixact.h.
38{
43
45
@ MultiXactStatusForShare
@ MultiXactStatusForNoKeyUpdate
@ MultiXactStatusNoKeyUpdate
@ MultiXactStatusForUpdate
@ MultiXactStatusForKeyShare
◆ AtEOXact_MultiXact()
void AtEOXact_MultiXact | ( | void | ) |
---|
◆ AtPrepare_MultiXact()
void AtPrepare_MultiXact | ( | void | ) |
---|
◆ BootStrapMultiXact()
void BootStrapMultiXact | ( | void | ) |
---|
Definition at line 2034 of file multixact.c.
2035{
2036 int slotno;
2038
2041
2042
2044
2045
2048
2050
2053
2054
2056
2057
2060
2062}
Assert(PointerIsAligned(start, uint64))
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
static int ZeroMultiXactMemberPage(int64 pageno, bool writeXlog)
#define MultiXactMemberCtl
#define MultiXactOffsetCtl
static int ZeroMultiXactOffsetPage(int64 pageno, bool writeXlog)
void SimpleLruWritePage(SlruCtl ctl, int slotno)
static LWLock * SimpleLruGetBankLock(SlruCtl ctl, int64 pageno)
References Assert(), LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MultiXactMemberCtl, MultiXactOffsetCtl, SimpleLruGetBankLock(), SimpleLruWritePage(), ZeroMultiXactMemberPage(), and ZeroMultiXactOffsetPage().
Referenced by BootStrapXLOG().
◆ CheckPointMultiXact()
void CheckPointMultiXact | ( | void | ) |
---|
◆ GetMultiXactIdMembers()
Definition at line 1299 of file multixact.c.
1301{
1303 int64 prev_pageno;
1304 int entryno;
1305 int slotno;
1308 int length;
1309 int truelength;
1316 bool slept = false;
1317
1319
1321 {
1322 *members = NULL;
1323 return -1;
1324 }
1325
1326
1328 if (length >= 0)
1329 {
1332 return length;
1333 }
1334
1335
1337
1338
1339
1340
1341
1342
1343 if (isLockOnly &&
1345 {
1346 debug_elog2(DEBUG2, "GetMembers: a locker-only multi is too old");
1347 *members = NULL;
1348 return -1;
1349 }
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1367
1371
1373
1376 (errcode(ERRCODE_INTERNAL_ERROR),
1377 errmsg("MultiXactId %u does no longer exist -- apparent wraparound",
1378 multi)));
1379
1382 (errcode(ERRCODE_INTERNAL_ERROR),
1383 errmsg("MultiXactId %u has not been created yet -- apparent wraparound",
1384 multi)));
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421retry:
1424
1425
1428
1431 offptr += entryno;
1432 offset = *offptr;
1433
1434 Assert(offset != 0);
1435
1436
1437
1438
1439
1440 tmpMXact = multi + 1;
1441
1442 if (nextMXact == tmpMXact)
1443 {
1444
1445 length = nextOffset - offset;
1446 }
1447 else
1448 {
1450
1451
1454
1455 prev_pageno = pageno;
1456
1459
1460 if (pageno != prev_pageno)
1461 {
1463
1464
1465
1466
1467
1468
1470 if (newlock != lock)
1471 {
1474 lock = newlock;
1475 }
1477 }
1478
1480 offptr += entryno;
1481 nextMXOffset = *offptr;
1482
1483 if (nextMXOffset == 0)
1484 {
1485
1488
1489 INJECTION_POINT("multixact-get-members-cv-sleep", NULL);
1490
1492 WAIT_EVENT_MULTIXACT_CREATION);
1493 slept = true;
1494 goto retry;
1495 }
1496
1497 length = nextMXOffset - offset;
1498 }
1499
1501 lock = NULL;
1502
1503
1504
1505
1506 if (slept)
1508
1510
1511 truelength = 0;
1512 prev_pageno = -1;
1513 for (int i = 0; i < length; i++, offset++)
1514 {
1517 int flagsoff;
1518 int bshift;
1519 int memberoff;
1520
1523
1524 if (pageno != prev_pageno)
1525 {
1527
1528
1529
1530
1531
1532
1534 if (newlock != lock)
1535 {
1536 if (lock)
1539 lock = newlock;
1540 }
1541
1543 prev_pageno = pageno;
1544 }
1545
1548
1550 {
1551
1552 Assert(offset == 0);
1553 continue;
1554 }
1555
1559
1560 ptr[truelength].xid = *xactptr;
1562 truelength++;
1563 }
1564
1566
1567
1568 Assert(truelength > 0);
1569
1570
1571
1572
1574
1577 *members = ptr;
1578 return truelength;
1579}
bool ConditionVariableCancelSleep(void)
void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
#define INJECTION_POINT(name, arg)
if(TABLE==NULL||TABLE_index==NULL)
#define CHECK_FOR_INTERRUPTS()
static int mXactCacheGetById(MultiXactId multi, MultiXactMember **members)
static int64 MXOffsetToMemberPage(MultiXactOffset offset)
#define MXACT_MEMBER_XACT_BITMASK
bool MultiXactIdPrecedes(MultiXactId multi1, MultiXactId multi2)
static void MultiXactIdSetOldestVisible(void)
static int MultiXactIdToOffsetEntry(MultiXactId multi)
static void mXactCachePut(MultiXactId multi, int nmembers, MultiXactMember *members)
static int MXOffsetToMemberOffset(MultiXactOffset offset)
static int64 MultiXactIdToOffsetPage(MultiXactId multi)
#define debug_elog3(a, b, c)
char * mxid_to_string(MultiXactId multi, int nmembers, MultiXactMember *members)
static int MXOffsetToFlagsOffset(MultiXactOffset offset)
static MultiXactStateData * MultiXactState
static int MXOffsetToFlagsBitShift(MultiXactOffset offset)
#define debug_elog2(a, b)
int SimpleLruReadPage(SlruCtl ctl, int64 pageno, bool write_ok, TransactionId xid)
MultiXactOffset nextOffset
MultiXactId oldestMultiXactId
ConditionVariable nextoff_cv
#define TransactionIdIsValid(xid)
References Assert(), CHECK_FOR_INTERRUPTS, ConditionVariableCancelSleep(), ConditionVariableSleep(), DEBUG2, debug_elog2, debug_elog3, ereport, errcode(), errmsg(), ERROR, FirstMultiXactId, i, if(), INJECTION_POINT, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MultiXactIdIsValid, MultiXactIdPrecedes(), MultiXactIdSetOldestVisible(), MultiXactIdToOffsetEntry(), MultiXactIdToOffsetPage(), MultiXactMemberCtl, MultiXactOffsetCtl, MultiXactState, MXACT_MEMBER_XACT_BITMASK, mXactCacheGetById(), mXactCachePut(), mxid_to_string(), MXOffsetToFlagsBitShift(), MXOffsetToFlagsOffset(), MXOffsetToMemberOffset(), MXOffsetToMemberPage(), MyProcNumber, MultiXactStateData::nextMXact, MultiXactStateData::nextoff_cv, MultiXactStateData::nextOffset, MultiXactStateData::oldestMultiXactId, OldestVisibleMXactId, palloc(), SimpleLruGetBankLock(), SimpleLruReadPage(), MultiXactMember::status, TransactionIdIsValid, and MultiXactMember::xid.
Referenced by Do_MultiXactIdWait(), DoesMultiXactIdConflict(), FreezeMultiXactId(), GetMultiXactIdHintBits(), heap_lock_tuple(), heap_lock_updated_tuple_rec(), heap_tuple_should_freeze(), MultiXactIdExpand(), MultiXactIdGetUpdateXid(), MultiXactIdIsRunning(), pg_get_multixact_members(), pgrowlocks(), and test_read_multixact().
◆ GetOldestMultiXactId()
Definition at line 2660 of file multixact.c.
2661{
2664 int i;
2665
2666
2667
2668
2669
2671
2672
2673
2674
2675
2676
2680
2681 oldestMXact = nextMXact;
2683 {
2685
2689 oldestMXact = thisoldest;
2693 oldestMXact = thisoldest;
2694 }
2695
2697
2698 return oldestMXact;
2699}
References FirstMultiXactId, i, LW_SHARED, LWLockAcquire(), LWLockRelease(), MaxOldestSlot, MultiXactIdIsValid, MultiXactIdPrecedes(), MultiXactState, MultiXactStateData::nextMXact, OldestMemberMXactId, and OldestVisibleMXactId.
Referenced by heapam_relation_set_new_filelocator(), vac_update_datfrozenxid(), and vacuum_get_cutoffs().
◆ multixact_desc()
Definition at line 50 of file mxactdesc.c.
51{
54
57 {
59
60 memcpy(&pageno, rec, sizeof(pageno));
62 }
64 {
66 int i;
67
72 }
74 {
76
80 }
81}
#define XLOG_MULTIXACT_ZERO_MEM_PAGE
#define XLOG_MULTIXACT_ZERO_OFF_PAGE
#define XLOG_MULTIXACT_TRUNCATE_ID
#define XLOG_MULTIXACT_CREATE_ID
static void out_member(StringInfo buf, MultiXactMember *member)
void appendStringInfo(StringInfo str, const char *fmt,...)
MultiXactMember members[FLEXIBLE_ARRAY_MEMBER]
MultiXactOffset startTruncMemb
MultiXactOffset endTruncMemb
MultiXactId startTruncOff
#define XLogRecGetInfo(decoder)
#define XLogRecGetData(decoder)
References appendStringInfo(), buf, xl_multixact_truncate::endTruncMemb, xl_multixact_truncate::endTruncOff, i, xl_multixact_create::members, xl_multixact_create::mid, xl_multixact_create::moff, xl_multixact_create::nmembers, out_member(), xl_multixact_truncate::startTruncMemb, xl_multixact_truncate::startTruncOff, XLOG_MULTIXACT_CREATE_ID, XLOG_MULTIXACT_TRUNCATE_ID, XLOG_MULTIXACT_ZERO_MEM_PAGE, XLOG_MULTIXACT_ZERO_OFF_PAGE, XLogRecGetData, and XLogRecGetInfo.
◆ multixact_identify()
const char * multixact_identify | ( | uint8 | info | ) |
---|
◆ multixact_redo()
Definition at line 3394 of file multixact.c.
3395{
3397
3398
3400
3402 {
3404 int slotno;
3406
3407 memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
3408
3411
3415
3417 }
3419 {
3421 int slotno;
3423
3424 memcpy(&pageno, XLogRecGetData(record), sizeof(pageno));
3425
3428
3432
3434 }
3436 {
3440 int i;
3441
3442
3445
3446
3449
3450
3451
3452
3453
3454
3457 {
3460 }
3461
3463 }
3465 {
3468
3471
3472 elog(DEBUG1, "replaying multixact truncation: "
3473 "offsets [%u, %u), offsets segments [%" PRIx64 ", %" PRIx64 "), "
3474 "members [%u, %u), members segments [%" PRIx64 ", %" PRIx64 ")",
3481
3482
3484
3485
3486
3487
3488
3490
3492
3493
3494
3495
3496
3497
3500 pageno);
3502
3504 }
3505 else
3506 elog(PANIC, "multixact_redo: unknown op code %u", info);
3507}
static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)
static int64 MultiXactIdToOffsetSegment(MultiXactId multi)
static void PerformOffsetsTruncation(MultiXactId oldestMulti, MultiXactId newOldestMulti)
static void PerformMembersTruncation(MultiXactOffset oldestOffset, MultiXactOffset newOldestOffset)
void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
static void RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset, int nmembers, MultiXactMember *members)
static int64 MXOffsetToMemberSegment(MultiXactOffset offset)
void MultiXactAdvanceNextMXact(MultiXactId minMulti, MultiXactOffset minMultiOffset)
#define SizeOfMultiXactTruncate
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
void AdvanceNextFullTransactionIdPastXid(TransactionId xid)
#define XLogRecGetXid(decoder)
#define XLogRecHasAnyBlockRefs(decoder)
References AdvanceNextFullTransactionIdPastXid(), Assert(), DEBUG1, elog, xl_multixact_truncate::endTruncMemb, xl_multixact_truncate::endTruncOff, i, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), xl_multixact_create::members, xl_multixact_create::mid, xl_multixact_create::moff, MultiXactAdvanceNextMXact(), MultiXactIdToOffsetPage(), MultiXactIdToOffsetSegment(), MultiXactMemberCtl, MultiXactOffsetCtl, MXOffsetToMemberSegment(), xl_multixact_create::nmembers, xl_multixact_truncate::oldestMultiDB, PANIC, PerformMembersTruncation(), PerformOffsetsTruncation(), pg_atomic_write_u64(), RecordNewMultiXact(), SetMultiXactIdLimit(), SimpleLruGetBankLock(), SimpleLruWritePage(), SizeOfMultiXactTruncate, xl_multixact_truncate::startTruncMemb, xl_multixact_truncate::startTruncOff, TransactionIdPrecedes(), MultiXactMember::xid, XLOG_MULTIXACT_CREATE_ID, XLOG_MULTIXACT_TRUNCATE_ID, XLOG_MULTIXACT_ZERO_MEM_PAGE, XLOG_MULTIXACT_ZERO_OFF_PAGE, XLogRecGetData, XLogRecGetInfo, XLogRecGetXid, XLogRecHasAnyBlockRefs, ZeroMultiXactMemberPage(), and ZeroMultiXactOffsetPage().
◆ multixact_twophase_postabort()
◆ multixact_twophase_postcommit()
◆ multixact_twophase_recover()
◆ MultiXactAdvanceNextMXact()
Definition at line 2511 of file multixact.c.
2513{
2516 {
2517 debug_elog3(DEBUG2, "MultiXact: setting next multi to %u", minMulti);
2519 }
2521 {
2523 minMultiOffset);
2525 }
2527}
static bool MultiXactOffsetPrecedes(MultiXactOffset offset1, MultiXactOffset offset2)
References DEBUG2, debug_elog3, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MultiXactIdPrecedes(), MultiXactOffsetPrecedes(), MultiXactState, MultiXactStateData::nextMXact, and MultiXactStateData::nextOffset.
Referenced by multixact_redo(), and xlog_redo().
◆ MultiXactAdvanceOldest()
void MultiXactAdvanceOldest | ( | MultiXactId | oldestMulti, |
---|---|---|---|
Oid | oldestMultiDB | ||
) |
◆ MultiXactGetCheckptMulti()
Definition at line 2282 of file multixact.c.
2287{
2294
2296 "MultiXact: checkpoint is nextMulti %u, nextOffset %u, oldestMulti %u in DB %u",
2297 *nextMulti, *nextMultiOffset, *oldestMulti, *oldestMultiDB);
2298}
#define debug_elog6(a, b, c, d, e, f)
References DEBUG2, debug_elog6, LW_SHARED, LWLockAcquire(), LWLockRelease(), MultiXactState, MultiXactStateData::nextMXact, MultiXactStateData::nextOffset, MultiXactStateData::oldestMultiXactDB, and MultiXactStateData::oldestMultiXactId.
Referenced by CreateCheckPoint().
◆ MultiXactIdCreate()
Definition at line 434 of file multixact.c.
436{
439
442
444
445
447
448
449
450
451
452
453
454 members[0].xid = xid1;
455 members[0].status = status1;
456 members[1].xid = xid2;
457 members[1].status = status2;
458
460
463
464 return newMulti;
465}
MultiXactId MultiXactIdCreateFromMembers(int nmembers, MultiXactMember *members)
#define TransactionIdEquals(id1, id2)
References Assert(), DEBUG2, debug_elog3, MultiXactIdCreateFromMembers(), MultiXactIdIsValid, mxid_to_string(), MyProcNumber, OldestMemberMXactId, MultiXactMember::status, TransactionIdEquals, TransactionIdIsValid, and MultiXactMember::xid.
Referenced by compute_new_xmax_infomask(), and test_create_multixact().
◆ MultiXactIdCreateFromMembers()
Definition at line 815 of file multixact.c.
816{
820
823
824
825
826
827
828
829
830
831
832
833
836 {
838 return multi;
839 }
840
841
842 {
843 int i;
844 bool has_update = false;
845
846 for (i = 0; i < nmembers; i++)
847 {
849 {
850 if (has_update)
851 elog(ERROR, "new multixact has more than one updating member: %s",
853 has_update = true;
854 }
855 }
856 }
857
858
860
861
862
863
864
865
866
867
868
869
870
871
872
874
876
877
878 xlrec.mid = multi;
879 xlrec.moff = offset;
881
882
883
884
885
886
887
891
893
894
896
897
899
900
902
904
905 return multi;
906}
#define INJECTION_POINT_CACHED(name, arg)
#define INJECTION_POINT_LOAD(name)
#define END_CRIT_SECTION()
static MultiXactId GetNewMultiXactId(int nmembers, MultiXactOffset *offset)
static MultiXactId mXactCacheGetBySet(int nmembers, MultiXactMember *members)
#define ISUPDATE_from_mxstatus(status)
#define SizeOfMultiXactCreate
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
void XLogRegisterData(const void *data, uint32 len)
void XLogBeginInsert(void)
References DEBUG2, debug_elog2, debug_elog3, elog, END_CRIT_SECTION, ERROR, GetNewMultiXactId(), i, INJECTION_POINT_CACHED, INJECTION_POINT_LOAD, InvalidMultiXactId, ISUPDATE_from_mxstatus, xl_multixact_create::mid, xl_multixact_create::moff, MultiXactIdIsValid, mXactCacheGetBySet(), mXactCachePut(), mxid_to_string(), xl_multixact_create::nmembers, RecordNewMultiXact(), SizeOfMultiXactCreate, XLOG_MULTIXACT_CREATE_ID, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().
Referenced by FreezeMultiXactId(), MultiXactIdCreate(), and MultiXactIdExpand().
◆ MultiXactIdExpand()
Definition at line 487 of file multixact.c.
488{
492 int nmembers;
493 int i;
494 int j;
495
498
499
501
502 debug_elog5(DEBUG2, "Expand: received multi %u, xid %u status %s",
504
505
506
507
508
509
511
512 if (nmembers < 0)
513 {
515
516
517
518
519
520
521
522
523 member.xid = xid;
524 member.status = status;
526
527 debug_elog4(DEBUG2, "Expand: %u has no members, create singleton %u",
528 multi, newMulti);
529 return newMulti;
530 }
531
532
533
534
535
536 for (i = 0; i < nmembers; i++)
537 {
539 (members[i].status == status))
540 {
542 xid, multi);
544 return multi;
545 }
546 }
547
548
549
550
551
552
553
554
555
556
557
558
559
560
563
564 for (i = 0, j = 0; i < nmembers; i++)
565 {
569 {
570 newMembers[j].xid = members[i].xid;
572 }
573 }
574
576 newMembers[j++].status = status;
578
580 pfree(newMembers);
581
583
584 return newMulti;
585}
void pfree(void *pointer)
#define debug_elog5(a, b, c, d, e)
#define debug_elog4(a, b, c, d)
static char * mxstatus_to_string(MultiXactStatus status)
int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, bool from_pgupgrade, bool isLockOnly)
bool TransactionIdIsInProgress(TransactionId xid)
bool TransactionIdDidCommit(TransactionId transactionId)
References Assert(), DEBUG2, debug_elog3, debug_elog4, debug_elog5, GetMultiXactIdMembers(), i, ISUPDATE_from_mxstatus, j, MultiXactIdCreateFromMembers(), MultiXactIdIsValid, mxstatus_to_string(), MyProcNumber, OldestMemberMXactId, palloc(), pfree(), MultiXactMember::status, TransactionIdDidCommit(), TransactionIdEquals, TransactionIdIsInProgress(), TransactionIdIsValid, and MultiXactMember::xid.
Referenced by compute_new_xmax_infomask().
◆ MultiXactIdIsRunning()
bool MultiXactIdIsRunning | ( | MultiXactId | multi, |
---|---|---|---|
bool | isLockOnly | ||
) |
Definition at line 599 of file multixact.c.
600{
602 int nmembers;
603 int i;
604
606
607
608
609
610
612
613 if (nmembers <= 0)
614 {
616 return false;
617 }
618
619
620
621
622
623
624
625
626 for (i = 0; i < nmembers; i++)
627 {
629 {
632 return true;
633 }
634 }
635
636
637
638
639
640
641 for (i = 0; i < nmembers; i++)
642 {
644 {
648 return true;
649 }
650 }
651
653
655
656 return false;
657}
bool TransactionIdIsCurrentTransactionId(TransactionId xid)
References DEBUG2, debug_elog2, debug_elog3, debug_elog4, GetMultiXactIdMembers(), i, pfree(), TransactionIdIsCurrentTransactionId(), and TransactionIdIsInProgress().
Referenced by compute_new_xmax_infomask(), FreezeMultiXactId(), HeapTupleSatisfiesUpdate(), and HeapTupleSatisfiesVacuumHorizon().
◆ MultiXactIdPrecedes()
Definition at line 3317 of file multixact.c.
3318{
3319 int32 diff = (int32) (multi1 - multi2);
3320
3321 return (diff < 0);
3322}
Referenced by check_mxid_in_range(), copy_table_data(), do_start_worker(), FreezeMultiXactId(), GetMultiXactIdMembers(), GetNewMultiXactId(), GetOldestMultiXactId(), heap_prepare_freeze_tuple(), heap_tuple_should_freeze(), heap_vacuum_eager_scan_setup(), MultiXactAdvanceNextMXact(), MultiXactAdvanceOldest(), MultiXactIdSetOldestVisible(), MultiXactOffsetPagePrecedes(), relation_needs_vacanalyze(), SetMultiXactIdLimit(), TruncateMultiXact(), vac_truncate_clog(), vac_update_datfrozenxid(), vac_update_relstats(), vacuum_get_cutoffs(), and vacuum_xid_failsafe_check().
◆ MultiXactIdPrecedesOrEquals()
◆ MultiXactIdSetOldestMember()
void MultiXactIdSetOldestMember | ( | void | ) |
---|
Definition at line 673 of file multixact.c.
674{
676 {
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
694
695
696
697
698
699
703
705
707
710 }
711}
References DEBUG2, debug_elog4, FirstMultiXactId, LW_SHARED, LWLockAcquire(), LWLockRelease(), MultiXactIdIsValid, MultiXactState, MyProcNumber, MultiXactStateData::nextMXact, and OldestMemberMXactId.
Referenced by heap_delete(), heap_lock_tuple(), heap_lock_updated_tuple(), heap_update(), and test_create_multixact().
◆ MultiXactMemberFreezeThreshold()
int MultiXactMemberFreezeThreshold | ( | void | ) |
---|
◆ multixactmemberssyncfiletag()
int multixactmemberssyncfiletag | ( | const FileTag * | ftag, |
---|---|---|---|
char * | path | ||
) |
◆ multixactoffsetssyncfiletag()
int multixactoffsetssyncfiletag | ( | const FileTag * | ftag, |
---|---|---|---|
char * | path | ||
) |
◆ MultiXactSetNextMXact()
Definition at line 2328 of file multixact.c.
2330{
2331 debug_elog4(DEBUG2, "MultiXact: setting next multi to %u offset %u",
2332 nextMulti, nextMultiOffset);
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2351}
static void MaybeExtendOffsetSlru(void)
References DEBUG2, debug_elog4, IsBinaryUpgrade, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MaybeExtendOffsetSlru(), MultiXactState, MultiXactStateData::nextMXact, and MultiXactStateData::nextOffset.
Referenced by BootStrapXLOG(), StartupXLOG(), and xlog_redo().
◆ MultiXactShmemInit()
void MultiXactShmemInit | ( | void | ) |
---|
Definition at line 1964 of file multixact.c.
1965{
1966 bool found;
1967
1969
1972
1978 false);
1985 false);
1986
1987
1988
1991 &found);
1993 {
1995
1996
1999 }
2000 else
2002
2003
2004
2005
2008}
#define MemSet(start, val, len)
void ConditionVariableInit(ConditionVariable *cv)
int multixact_offset_buffers
int multixact_member_buffers
@ LWTRANCHE_MULTIXACTOFFSET_SLRU
@ LWTRANCHE_MULTIXACTMEMBER_SLRU
@ LWTRANCHE_MULTIXACTMEMBER_BUFFER
@ LWTRANCHE_MULTIXACTOFFSET_BUFFER
static bool MultiXactMemberPagePrecedes(int64 page1, int64 page2)
#define MULTIXACT_OFFSETS_PER_PAGE
#define SHARED_MULTIXACT_STATE_SIZE
static bool MultiXactOffsetPagePrecedes(int64 page1, int64 page2)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
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)
#define SlruPagePrecedesUnitTests(ctl, per_page)
MultiXactId perBackendXactIds[FLEXIBLE_ARRAY_MEMBER]
@ SYNC_HANDLER_MULTIXACT_MEMBER
@ SYNC_HANDLER_MULTIXACT_OFFSET
References Assert(), ConditionVariableInit(), DEBUG2, debug_elog2, IsUnderPostmaster, LWTRANCHE_MULTIXACTMEMBER_BUFFER, LWTRANCHE_MULTIXACTMEMBER_SLRU, LWTRANCHE_MULTIXACTOFFSET_BUFFER, LWTRANCHE_MULTIXACTOFFSET_SLRU, MaxOldestSlot, MemSet, multixact_member_buffers, multixact_offset_buffers, MULTIXACT_OFFSETS_PER_PAGE, MultiXactMemberCtl, MultiXactMemberPagePrecedes(), MultiXactOffsetCtl, MultiXactOffsetPagePrecedes(), MultiXactState, MultiXactStateData::nextoff_cv, OldestMemberMXactId, OldestVisibleMXactId, MultiXactStateData::perBackendXactIds, SHARED_MULTIXACT_STATE_SIZE, ShmemInitStruct(), SimpleLruInit(), SlruPagePrecedesUnitTests, SYNC_HANDLER_MULTIXACT_MEMBER, and SYNC_HANDLER_MULTIXACT_OFFSET.
Referenced by CreateOrAttachShmemStructs().
◆ MultiXactShmemSize()
Size MultiXactShmemSize | ( | void | ) |
---|
◆ mxid_to_string()
Definition at line 1777 of file multixact.c.
1778{
1779 static char *str = NULL;
1781 int i;
1782
1783 if (str != NULL)
1785
1787
1788 appendStringInfo(&buf, "%u %d[%u (%s)", multi, nmembers, members[0].xid,
1790
1791 for (i = 1; i < nmembers; i++)
1794
1798 return str;
1799}
char * MemoryContextStrdup(MemoryContext context, const char *string)
MemoryContext TopMemoryContext
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
References appendStringInfo(), appendStringInfoChar(), buf, i, initStringInfo(), MemoryContextStrdup(), mxstatus_to_string(), pfree(), str, and TopMemoryContext.
Referenced by GetMultiXactIdMembers(), MultiXactIdCreate(), MultiXactIdCreateFromMembers(), mXactCacheGetById(), mXactCacheGetBySet(), and mXactCachePut().
◆ PostPrepare_MultiXact()
Definition at line 1850 of file multixact.c.
1851{
1853
1854
1855
1856
1857
1860 {
1862
1863
1864
1865
1866
1867
1868
1870
1873
1875 }
1876
1877
1878
1879
1880
1881
1882
1883
1884
1886
1887
1888
1889
1892}
References dclist_init(), InvalidMultiXactId, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MultiXactIdIsValid, MXactCache, MXactContext, MyProcNumber, OldestMemberMXactId, OldestVisibleMXactId, and TwoPhaseGetDummyProcNumber().
Referenced by PrepareTransaction().
◆ ReadMultiXactIdRange()
◆ ReadNextMultiXactId()
Definition at line 771 of file multixact.c.
772{
774
775
779
782
783 return mxid;
784}
References FirstMultiXactId, LW_SHARED, LWLockAcquire(), LWLockRelease(), MultiXactState, and MultiXactStateData::nextMXact.
Referenced by ATRewriteTables(), AutoVacWorkerMain(), do_start_worker(), mxid_age(), refresh_by_heap_swap(), vac_update_datfrozenxid(), vac_update_relstats(), vacuum_get_cutoffs(), and vacuum_xid_failsafe_check().
◆ SetMultiXactIdLimit()
void SetMultiXactIdLimit | ( | MultiXactId | oldest_datminmxid, |
---|---|---|---|
Oid | oldest_datoid, | ||
bool | is_startup | ||
) |
Definition at line 2362 of file multixact.c.
2364{
2370 bool needs_offset_vacuum;
2371
2373
2374
2375
2376
2377
2378
2379
2380
2381 multiWrapLimit = oldest_datminmxid + (MaxMultiXactId >> 1);
2384
2385
2386
2387
2388
2389 multiStopLimit = multiWrapLimit - 3000000;
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403 multiWarnLimit = multiWrapLimit - 40000000;
2406
2407
2408
2409
2410
2411
2412
2413
2414
2418
2419
2429
2430
2432 (errmsg_internal("MultiXactId wrap limit is %u, limited by database with OID %u",
2433 multiWrapLimit, oldest_datoid)));
2434
2435
2436
2437
2438
2439
2440
2441
2443 return;
2444
2446
2447
2449
2450
2451
2452
2453
2454
2455
2456
2460
2461
2463 {
2464 char *oldest_datname;
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2477 else
2478 oldest_datname = NULL;
2479
2480 if (oldest_datname)
2482 (errmsg_plural("database \"%s\" must be vacuumed before %u more MultiXactId is used",
2483 "database \"%s\" must be vacuumed before %u more MultiXactIds are used",
2484 multiWrapLimit - curMulti,
2485 oldest_datname,
2486 multiWrapLimit - curMulti),
2487 errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n"
2488 "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
2489 else
2491 (errmsg_plural("database with OID %u must be vacuumed before %u more MultiXactId is used",
2492 "database with OID %u must be vacuumed before %u more MultiXactIds are used",
2493 multiWrapLimit - curMulti,
2494 oldest_datoid,
2495 multiWrapLimit - curMulti),
2496 errhint("To avoid MultiXactId assignment failures, execute a database-wide VACUUM in that database.\n"
2497 "You might also need to commit or roll back old prepared transactions, or drop stale replication slots.")));
2498 }
2499}
char * get_database_name(Oid dbid)
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
int errmsg_internal(const char *fmt,...)
int errhint(const char *fmt,...)
static bool SetOffsetVacuumLimit(bool is_startup)
void SendPostmasterSignal(PMSignalReason reason)
@ PMSIGNAL_START_AUTOVAC_LAUNCHER
MultiXactId multiWrapLimit
MultiXactId multiStopLimit
MultiXactId multiWarnLimit
MultiXactId multiVacLimit
bool IsTransactionState(void)
References Assert(), autovacuum_multixact_freeze_max_age, DEBUG1, ereport, errhint(), errmsg_internal(), errmsg_plural(), MultiXactStateData::finishedStartup, FirstMultiXactId, get_database_name(), InRecovery, IsTransactionState(), IsUnderPostmaster, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), MaxMultiXactId, MultiXactStateData::multiStopLimit, MultiXactStateData::multiVacLimit, MultiXactStateData::multiWarnLimit, MultiXactStateData::multiWrapLimit, MultiXactIdIsValid, MultiXactIdPrecedes(), MultiXactState, MultiXactStateData::nextMXact, MultiXactStateData::oldestMultiXactDB, MultiXactStateData::oldestMultiXactId, PMSIGNAL_START_AUTOVAC_LAUNCHER, SendPostmasterSignal(), SetOffsetVacuumLimit(), and WARNING.
Referenced by BootStrapXLOG(), multixact_redo(), MultiXactAdvanceOldest(), StartupXLOG(), TrimMultiXact(), and vac_truncate_clog().
◆ StartupMultiXact()
void StartupMultiXact | ( | void | ) |
---|
◆ TrimMultiXact()
void TrimMultiXact | ( | void | ) |
---|
Definition at line 2178 of file multixact.c.
2179{
2183 Oid oldestMXactDB;
2185 int entryno;
2186 int flagsoff;
2187
2194
2195
2196
2197
2198
2199
2202 pageno);
2203
2204
2205
2206
2207
2208
2209
2210
2211
2213 if (entryno != 0)
2214 {
2215 int slotno;
2218
2222 offptr += entryno;
2223
2225
2228 }
2229
2230
2231
2232
2233
2234
2237 pageno);
2238
2239
2240
2241
2242
2244 if (flagsoff != 0)
2245 {
2246 int slotno;
2248 int memberoff;
2250
2256
2257 MemSet(xidptr, 0, BLCKSZ - memberoff);
2258
2259
2260
2261
2262
2263
2264
2267 }
2268
2269
2273
2274
2276}
References MultiXactStateData::finishedStartup, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MemSet, MultiXactIdToOffsetEntry(), MultiXactIdToOffsetPage(), MultiXactMemberCtl, MultiXactOffsetCtl, MultiXactState, MXOffsetToFlagsOffset(), MXOffsetToMemberOffset(), MXOffsetToMemberPage(), MultiXactStateData::nextMXact, MultiXactStateData::nextOffset, MultiXactStateData::oldestMultiXactDB, MultiXactStateData::oldestMultiXactId, pg_atomic_write_u64(), SetMultiXactIdLimit(), SimpleLruGetBankLock(), and SimpleLruReadPage().
Referenced by StartupXLOG().
◆ TruncateMultiXact()
void TruncateMultiXact | ( | MultiXactId | newOldestMulti, |
---|---|---|---|
Oid | newOldestMultiDB | ||
) |
Definition at line 3102 of file multixact.c.
3103{
3111
3114
3115
3116
3117
3118
3119
3120
3122
3129
3130
3131
3132
3133
3134
3136 {
3138 return;
3139 }
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3164
3165
3167 {
3169 return;
3170 }
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180 if (oldestMulti == nextMulti)
3181 {
3182
3183 oldestOffset = nextOffset;
3184 }
3186 {
3188 (errmsg("oldest MultiXact %u not found, earliest MultiXact %u, skipping truncation",
3189 oldestMulti, earliest)));
3191 return;
3192 }
3193
3194
3195
3196
3197
3198 if (newOldestMulti == nextMulti)
3199 {
3200
3201 newOldestOffset = nextOffset;
3202 }
3204 {
3206 (errmsg("cannot truncate up to MultiXact %u because it does not exist on disk, skipping truncation",
3207 newOldestMulti)));
3209 return;
3210 }
3211
3212 elog(DEBUG1, "performing multixact truncation: "
3213 "offsets [%u, %u), offsets segments [%" PRIx64 ", %" PRIx64 "), "
3214 "members [%u, %u), members segments [%" PRIx64 ", %" PRIx64 ")",
3215 oldestMulti, newOldestMulti,
3218 oldestOffset, newOldestOffset,
3221
3222
3223
3224
3225
3226
3227
3229
3230
3231
3232
3233
3234
3235
3238
3239
3241 oldestMulti, newOldestMulti,
3242 oldestOffset, newOldestOffset);
3243
3244
3245
3246
3247
3248
3249
3250
3251
3256
3257
3259
3260
3262
3264
3267}
#define START_CRIT_SECTION()
static void WriteMTruncateXlogRec(Oid oldestMultiDB, MultiXactId startTruncOff, MultiXactId endTruncOff, MultiXactOffset startTruncMemb, MultiXactOffset endTruncMemb)
static bool find_multixact_start(MultiXactId multi, MultiXactOffset *result)
static bool SlruScanDirCbFindEarliest(SlruCtl ctl, char *filename, int64 segpage, void *data)
bool MultiXactIdPrecedesOrEquals(MultiXactId multi1, MultiXactId multi2)
#define DELAY_CHKPT_START
bool SlruScanDirectory(SlruCtl ctl, SlruScanCallback callback, void *data)
int64 earliestExistingPage
bool RecoveryInProgress(void)
References Assert(), DEBUG1, DELAY_CHKPT_START, PGPROC::delayChkptFlags, mxtruncinfo::earliestExistingPage, elog, END_CRIT_SECTION, ereport, errmsg(), find_multixact_start(), MultiXactStateData::finishedStartup, FirstMultiXactId, LOG, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), MULTIXACT_OFFSETS_PER_PAGE, MultiXactIdIsValid, MultiXactIdPrecedes(), MultiXactIdPrecedesOrEquals(), MultiXactIdToOffsetSegment(), MultiXactOffsetCtl, MultiXactState, MXOffsetToMemberSegment(), MyProc, MultiXactStateData::nextMXact, MultiXactStateData::nextOffset, MultiXactStateData::oldestMultiXactDB, MultiXactStateData::oldestMultiXactId, PerformMembersTruncation(), PerformOffsetsTruncation(), RecoveryInProgress(), SlruScanDirCbFindEarliest(), SlruScanDirectory(), START_CRIT_SECTION, and WriteMTruncateXlogRec().
Referenced by vac_truncate_clog().