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
Functions
MultiXactId MultiXactIdCreate (TransactionId xid1, MultiXactStatus status1, TransactionId xid2, MultiXactStatus status2)
MultiXactId MultiXactIdExpand (MultiXactId multi, TransactionId xid, MultiXactStatus status)
MultiXactId MultiXactIdCreateFromMembers (int nmembers, MultiXactMember *members)
MultiXactId ReadNextMultiXactId (void)
void ReadMultiXactIdRange (MultiXactId *oldest, MultiXactId *next)
bool MultiXactIdIsRunning (MultiXactId multi, bool isLockOnly)
void MultiXactIdSetOldestMember (void)
int GetMultiXactIdMembers (MultiXactId multi, MultiXactMember **members, bool from_pgupgrade, bool isLockOnly)
bool MultiXactIdPrecedes (MultiXactId multi1, MultiXactId multi2)
bool MultiXactIdPrecedesOrEquals (MultiXactId multi1, MultiXactId multi2)
int multixactoffsetssyncfiletag (const FileTag *ftag, char *path)
int multixactmemberssyncfiletag (const FileTag *ftag, char *path)
void AtEOXact_MultiXact (void)
void AtPrepare_MultiXact (void)
void PostPrepare_MultiXact (TransactionId xid)
Size MultiXactShmemSize (void)
void MultiXactShmemInit (void)
void BootStrapMultiXact (void)
void StartupMultiXact (void)
void TrimMultiXact (void)
void SetMultiXactIdLimit (MultiXactId oldest_datminmxid, Oid oldest_datoid, bool is_startup)
void MultiXactGetCheckptMulti (bool is_shutdown, MultiXactId *nextMulti, MultiXactOffset *nextMultiOffset, MultiXactId *oldestMulti, Oid *oldestMultiDB)
void CheckPointMultiXact (void)
MultiXactId GetOldestMultiXactId (void)
void TruncateMultiXact (MultiXactId newOldestMulti, Oid newOldestMultiDB)
void MultiXactSetNextMXact (MultiXactId nextMulti, MultiXactOffset nextMultiOffset)
void MultiXactAdvanceNextMXact (MultiXactId minMulti, MultiXactOffset minMultiOffset)
void MultiXactAdvanceOldest (MultiXactId oldestMulti, Oid oldestMultiDB)
int MultiXactMemberFreezeThreshold (void)
void multixact_twophase_recover (TransactionId xid, uint16 info, void *recdata, uint32 len)
void multixact_twophase_postcommit (TransactionId xid, uint16 info, void *recdata, uint32 len)
void multixact_twophase_postabort (TransactionId xid, uint16 info, void *recdata, uint32 len)
void multixact_redo (XLogReaderState *record)
void multixact_desc (StringInfo buf, XLogReaderState *record)
const char * multixact_identify (uint8 info)
char * mxid_to_string (MultiXactId multi, int nmembers, MultiXactMember *members)

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

575 newMembers[j].xid = xid;

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 {

646 i, members[i].xid);

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().