diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 82f9a3c..4f6551d 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -186,6 +186,7 @@ typedef struct TransactionStateData bool prevXactReadOnly; /* entry-time xact r/o state */ bool startedInRecovery; /* did we start in recovery? */ bool didLogXid; /* has xid been included in WAL record? */ + bool didLogAELock; /* did we log any access exclusive locks? */ int parallelModeLevel; /* Enter/ExitParallelMode counter */ struct TransactionStateData *parent; /* back link to parent */ } TransactionStateData; @@ -217,6 +218,7 @@ static TransactionStateData TopTransactionStateData = { false, /* entry-time xact r/o state */ false, /* startedInRecovery */ false, /* didLogXid */ + false, /* didLogAELock */ 0, /* parallelMode */ NULL /* link to parent state block */ }; @@ -447,6 +449,17 @@ MarkCurrentTransactionIdLoggedIfAny(void) CurrentTransactionState->didLogXid = true; } +/* + * MarkCurrentTransactionIDLoggedAELocks + * + * Remember if the current xid logged any Access Exclusive Locks + */ +void +MarkCurrentTransactionIDLoggedAELocks(void) +{ + if (TransactionIdIsValid(CurrentTransactionState->transactionId)) + CurrentTransactionState->didLogAELock = true; +} /* * GetStableLatestTransactionId @@ -5191,6 +5204,9 @@ XactLogCommitRecord(TimestampTz commit_time, xl_origin.origin_timestamp = replorigin_session_origin_timestamp; } + if (CurrentTransactionState->didLogAELock) + xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS; + if (xl_xinfo.xinfo != 0) info |= XLOG_XACT_HAS_INFO; @@ -5325,6 +5341,9 @@ XactLogAbortRecord(TimestampTz abort_time, if (xl_xinfo.xinfo & XACT_XINFO_HAS_TWOPHASE) XLogRegisterData((char *) (&xl_twophase), sizeof(xl_xact_twophase)); + if (CurrentTransactionState->didLogAELock) + xl_xinfo.xinfo |= XACT_XINFO_HAS_AE_LOCKS; + return XLogInsert(RM_XACT_ID, info); } @@ -5427,7 +5446,8 @@ xact_redo_commit(xl_xact_parsed_commit *parsed, * via their top-level xid only, so no need to provide subxact list, * which will save time when replaying commits. */ - StandbyReleaseLockTree(xid, 0, NULL); + if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS) + StandbyReleaseLockTree(xid, 0, NULL); } if (parsed->xinfo & XACT_XINFO_HAS_ORIGIN) @@ -5563,7 +5583,8 @@ xact_redo_abort(xl_xact_parsed_abort *parsed, TransactionId xid) /* * Release locks, if any. There are no invalidations to send. */ - StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts); + if (parsed->xinfo & XACT_XINFO_HAS_AE_LOCKS) + StandbyReleaseLockTree(xid, parsed->nsubxacts, parsed->subxacts); } /* Make sure files supposed to be dropped are dropped */ diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index 6259070..d7bd084 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -1040,6 +1040,7 @@ LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks) XLogRegisterData((char *) &xlrec, offsetof(xl_standby_locks, locks)); XLogRegisterData((char *) locks, nlocks * sizeof(xl_standby_lock)); XLogSetRecordFlags(XLOG_MARK_UNIMPORTANT); + MarkCurrentTransactionIDLoggedAELocks(); (void) XLogInsert(RM_STANDBY_ID, XLOG_STANDBY_LOCK); } diff --git a/src/include/access/xact.h b/src/include/access/xact.h index e7d1191..0bb0f87 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -137,6 +137,7 @@ typedef void (*SubXactCallback) (SubXactEvent event, SubTransactionId mySubid, #define XACT_XINFO_HAS_INVALS (1U << 3) #define XACT_XINFO_HAS_TWOPHASE (1U << 4) #define XACT_XINFO_HAS_ORIGIN (1U << 5) +#define XACT_XINFO_HAS_AE_LOCKS (1U << 6) /* * Also stored in xinfo, these indicating a variety of additional actions that @@ -316,6 +317,7 @@ extern TransactionId GetCurrentTransactionIdIfAny(void); extern TransactionId GetStableLatestTransactionId(void); extern SubTransactionId GetCurrentSubTransactionId(void); extern void MarkCurrentTransactionIdLoggedIfAny(void); +extern void MarkCurrentTransactionIDLoggedAELocks(void); extern bool SubTransactionIsActive(SubTransactionId subxid); extern CommandId GetCurrentCommandId(bool used); extern TimestampTz GetCurrentTransactionStartTimestamp(void);