148 lines
6.1 KiB
C
148 lines
6.1 KiB
C
/*
|
|
* multixact.h
|
|
*
|
|
* PostgreSQL multi-transaction-log manager
|
|
*
|
|
* Portions Copyright (c) 2020 Huawei Technologies Co.,Ltd.
|
|
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/access/multixact.h
|
|
*/
|
|
#ifndef MULTIXACT_H
|
|
#define MULTIXACT_H
|
|
|
|
#include "access/xlogreader.h"
|
|
#include "lib/stringinfo.h"
|
|
|
|
#define InvalidMultiXactId UINT64CONST(0)
|
|
#define FirstMultiXactId UINT64CONST(1)
|
|
#define MaxMultiXactId UINT64CONST(0xFFFFFFFFFFFFFFFF)
|
|
|
|
#define MultiXactIdIsValid(multi) ((multi) != InvalidMultiXactId)
|
|
|
|
#define MaxMultiXactOffset UINT64CONST(0xFFFFFFFFFFFFFFFF)
|
|
|
|
#define MULTIXACTDIR (g_instance.datadir_cxt.multixactDir)
|
|
|
|
/* Number of SLRU buffers to use for multixact */
|
|
#define NUM_MXACTOFFSET_BUFFERS 8
|
|
#define NUM_MXACTMEMBER_BUFFERS 16
|
|
|
|
/*
|
|
* Possible multixact lock modes ("status"). The first four modes are for
|
|
* tuple locks (FOR KEY SHARE, FOR SHARE, FOR NO KEY UPDATE, FOR UPDATE); the
|
|
* next two are used for update and delete modes.
|
|
*/
|
|
typedef enum {
|
|
MultiXactStatusForShare = 0x00, /* set FOR_SHARE = 0 here for compatibility */
|
|
MultiXactStatusForKeyShare = 0x01,
|
|
MultiXactStatusForNoKeyUpdate = 0x02,
|
|
MultiXactStatusForUpdate = 0x03,
|
|
/* an update that doesn't touch "key" columns */
|
|
MultiXactStatusNoKeyUpdate = 0x04,
|
|
/* other updates, and delete */
|
|
MultiXactStatusUpdate = 0x05
|
|
} MultiXactStatus;
|
|
|
|
#define MaxMultiXactStatus MultiXactStatusUpdate
|
|
|
|
/* does a status value correspond to a tuple update? */
|
|
#define ISUPDATE_from_mxstatus(status) \
|
|
((status) > MultiXactStatusForUpdate)
|
|
|
|
typedef struct MultiXactMember {
|
|
TransactionId xid;
|
|
MultiXactStatus status;
|
|
} MultiXactMember;
|
|
|
|
/*
|
|
* In htup.h, we define MaxTransactionId, and first four bits are reserved.
|
|
* We use low 60 bits to record member xid and high 3 bits to record member status.
|
|
*/
|
|
#define MULTIXACT_MEMBER_XID_MASK UINT64CONST((UINT64CONST(1) << 60) - 1)
|
|
#define GET_MEMBER_XID_FROM_SLRU_XID(xid) ((xid) & MULTIXACT_MEMBER_XID_MASK)
|
|
#define GET_MEMBER_STATUS_FROM_SLRU_XID(xid) (MultiXactStatus((xid) >> 61))
|
|
#define GET_SLRU_XID_FROM_MULTIXACT_MEMBER(member) \
|
|
(((TransactionId)((member)->status) << 61) | (((member)->xid) & MULTIXACT_MEMBER_XID_MASK))
|
|
|
|
/*
|
|
* Defines for MultiXactOffset page sizes. A page is the same BLCKSZ as is
|
|
* used everywhere else in openGauss.
|
|
*
|
|
* We need four bytes per offset and also four bytes per member
|
|
*/
|
|
#define MULTIXACT_OFFSETS_PER_PAGE (BLCKSZ / sizeof(MultiXactOffset))
|
|
#define MULTIXACT_MEMBERS_PER_PAGE (BLCKSZ / sizeof(TransactionId))
|
|
|
|
#define MultiXactIdToOffsetPage(xid) ((xid) / (MultiXactOffset)MULTIXACT_OFFSETS_PER_PAGE)
|
|
#define MultiXactIdToOffsetEntry(xid) ((xid) % (MultiXactOffset)MULTIXACT_OFFSETS_PER_PAGE)
|
|
|
|
#define MXOffsetToMemberPage(xid) ((xid) / (TransactionId)MULTIXACT_MEMBERS_PER_PAGE)
|
|
#define MXOffsetToMemberEntry(xid) ((xid) % (TransactionId)MULTIXACT_MEMBERS_PER_PAGE)
|
|
|
|
|
|
/* ----------------
|
|
* multixact-related XLOG entries
|
|
* ----------------
|
|
*/
|
|
|
|
#define XLOG_MULTIXACT_ZERO_OFF_PAGE 0x00
|
|
#define XLOG_MULTIXACT_ZERO_MEM_PAGE 0x10
|
|
#define XLOG_MULTIXACT_CREATE_ID 0x20
|
|
|
|
#define XLOG_MULTIXACT_MASK 0x70
|
|
#define XLOG_MULTIXACT_INT64_PAGENO 0x80
|
|
|
|
|
|
typedef struct xl_multixact_create {
|
|
MultiXactId mid; /* new MultiXact's ID */
|
|
MultiXactOffset moff; /* its starting offset in members file */
|
|
int32 nxids; /* number of member XIDs */
|
|
TransactionId xids[FLEXIBLE_ARRAY_MEMBER]; /* low 60 bits record member xid, high 3 bits record member status */
|
|
} xl_multixact_create;
|
|
|
|
#define MinSizeOfMultiXactCreate offsetof(xl_multixact_create, xids)
|
|
|
|
MultiXactId MultiXactIdCreate(TransactionId xid1, MultiXactStatus status1,
|
|
TransactionId xid2, MultiXactStatus status2);
|
|
extern MultiXactId MultiXactIdExpand(MultiXactId multi, TransactionId xid, MultiXactStatus status);
|
|
extern bool MultiXactIdIsRunning(MultiXactId multi);
|
|
extern bool MultiXactIdIsCurrent(MultiXactId multi);
|
|
extern MultiXactId ReadNextMultiXactId(void);
|
|
extern bool DoMultiXactIdWait(MultiXactId multi, MultiXactStatus status, int *remaining, bool nowait, int waitSec = 0);
|
|
extern void MultiXactIdWait(MultiXactId multi, MultiXactStatus status, int *remaining, int waitSec = 0);
|
|
extern bool ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status, int *remaining);
|
|
extern void MultiXactIdSetOldestMember(void);
|
|
extern int GetMultiXactIdMembers(MultiXactId multi, MultiXactMember** members);
|
|
|
|
extern void AtEOXact_MultiXact(void);
|
|
extern void AtPrepare_MultiXact(void);
|
|
extern void PostPrepare_MultiXact(TransactionId xid);
|
|
|
|
extern Size MultiXactShmemSize(void);
|
|
extern void MultiXactShmemInit(void);
|
|
extern void BootStrapMultiXact(void);
|
|
extern void StartupMultiXact(void);
|
|
extern void ShutdownMultiXact(void);
|
|
extern void SetMultiXactIdLimit(MultiXactId oldest_datminmxid, Oid oldest_datoid);
|
|
extern void MultiXactGetCheckptMulti(bool is_shutdown, MultiXactId* nextMulti, MultiXactOffset* nextMultiOffset);
|
|
extern void CheckPointMultiXact(void);
|
|
extern MultiXactId GetOldestMultiXactId(void);
|
|
extern void TruncateMultiXact(MultiXactId cutoff_multi = InvalidMultiXactId);
|
|
extern void MultiXactSetNextMXact(MultiXactId nextMulti, MultiXactOffset nextMultiOffset);
|
|
extern void MultiXactAdvanceNextMXact(MultiXactId minMulti, MultiXactOffset minMultiOffset);
|
|
extern void MultiXactAdvanceOldest(MultiXactId oldestMulti, Oid oldestMultiDB);
|
|
|
|
extern void multixact_twophase_recover(TransactionId xid, uint16 info, void* recdata, uint32 len);
|
|
extern void multixact_twophase_postcommit(TransactionId xid, uint16 info, void* recdata, uint32 len);
|
|
extern void multixact_twophase_postabort(TransactionId xid, uint16 info, void* recdata, uint32 len);
|
|
|
|
extern void multixact_redo(XLogReaderState* record);
|
|
extern void multixact_desc(StringInfo buf, XLogReaderState* record);
|
|
extern const char* multixact_type_name(uint8 subtype);
|
|
extern void get_multixact_pageno(uint8 info, int64 *pageno, XLogReaderState *record);
|
|
extern void SSMultiXactShmemClear(void);
|
|
|
|
#endif /* MULTIXACT_H */
|