From 9aa8eabf8d781740ac8b1ad8691f072877435192 Mon Sep 17 00:00:00 2001 From: Simon Riggs Date: Wed, 18 Feb 2009 16:46:16 +0000 Subject: [PATCH] Reimplement some changes from prior to refactoring. The code was undocumented, so I removed it to ensure we didn't have bogus processing in there. It is now back, correct and documented. These related to handling of unobserved xid processing for subtransactions on abort and commit, when those subtransactions were the latest arrived xids. Rarely occurring code, typically 1-2 times per make installcheck. Also fix problem with redo debug messages not being displayed correctly. Also replace tests for prepared transactions. --- src/backend/access/transam/xact.c | 49 +++++++++++++++++++++++++++--- src/backend/access/transam/xlog.c | 6 ++-- src/test/regress/parallel_schedule | 4 +-- src/test/regress/serial_schedule | 2 +- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index b9b88f1253..b1eafba161 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -4488,7 +4488,6 @@ RecordKnownAssignedTransactionIds(XLogRecPtr lsn, TransactionId top_xid, Transac { TransactionId xid; PGPROC *proc = NULL; - bool unobserved = false; bool mark_subtrans = false; Xid_to_Proc *hentry; bool found = false; @@ -4693,7 +4692,7 @@ RecordKnownAssignedTransactionIds(XLogRecPtr lsn, TransactionId top_xid, Transac elog(trace_recovery(DEBUG4), "record known xact top_xid %u child_xid %u %s%slatestObservedXid %u", top_xid, child_xid, - (unobserved ? "unobserved " : " "), + (found ? "new top_xid " : " "), (mark_subtrans ? "mark subtrans " : " "), latestObservedXid); @@ -4722,6 +4721,40 @@ RecordKnownAssignedTransactionIds(XLogRecPtr lsn, TransactionId top_xid, Transac return true; } +static void +RecordKnownAssignedSubTransactionIds(int nsubxacts, TransactionId *sub_xids) +{ + int i; + + /* + * We may receive a completion record that contains unrecorded + * xids, so sometimes we must do further processing to ensure we + * get the xid arrival sequence exactly correct. We assume that + * xids are already in modulo ascending order. The code is + * deliberately similar to how topxid and childxid are handled in + * RecordKnownAssignedTransactionIds(). + */ + for (i = 0; i < nsubxacts; i++) + { + TransactionId next_expected_xid = latestObservedXid; + TransactionId subxid = sub_xids[i]; + TransactionIdAdvance(next_expected_xid); + + if (next_expected_xid == subxid) + { + Assert(!XidInUnobservedTransactions(subxid)); + latestObservedXid = subxid; + } + else if (TransactionIdPrecedes(next_expected_xid, subxid)) + { + UnobservedTransactionsAddXids(next_expected_xid, subxid); + latestObservedXid = subxid; + } + else + elog(FATAL, "transaction ids not in sequence"); + } +} + /* * LatestRemovedXidAdvances - returns true if latestRemovedXid is moved * forwards by the latest provided value @@ -4763,6 +4796,9 @@ xact_redo_commit(xl_xact_commit *xlrec, TransactionId xid, bool preparedXact) max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids); + if (TransactionIdPrecedes(latestObservedXid, max_xid)) + RecordKnownAssignedSubTransactionIds(xlrec->nsubxacts, sub_xids); + /* Mark the transaction committed in pg_clog */ TransactionIdCommitTree(xid, xlrec->nsubxacts, sub_xids); @@ -4885,6 +4921,9 @@ xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid, TransactionId topxid) sub_xids = (TransactionId *) &(xlrec->xnodes[xlrec->nrels]); max_xid = TransactionIdLatest(xid, xlrec->nsubxacts, sub_xids); + if (TransactionIdPrecedes(latestObservedXid, max_xid)) + RecordKnownAssignedSubTransactionIds(xlrec->nsubxacts, sub_xids); + /* Mark the transaction aborted in pg_clog */ TransactionIdAbortTree(xid, xlrec->nsubxacts, sub_xids); @@ -4904,7 +4943,7 @@ xact_redo_abort(xl_xact_abort *xlrec, TransactionId xid, TransactionId topxid) { Xid_to_Proc *hentry = (Xid_to_Proc *) hash_search(local_recovery_xid_to_proc_hash, - (void *) &xid, + (void *) &topxid, HASH_REMOVE, NULL); Assert(hentry->proc != NULL); @@ -5204,14 +5243,14 @@ xact_desc(StringInfo buf, uint8 xl_info, char *rec) { xl_xact_commit_prepared *xlrec = (xl_xact_commit_prepared *) rec; - appendStringInfo(buf, "commit %u: ", xlrec->xid); + appendStringInfo(buf, "commit prepared %u: ", xlrec->xid); xact_desc_commit(buf, &xlrec->crec); } else if (info == XLOG_XACT_ABORT_PREPARED) { xl_xact_abort_prepared *xlrec = (xl_xact_abort_prepared *) rec; - appendStringInfo(buf, "abort %u: ", xlrec->xid); + appendStringInfo(buf, "abort prepared %u: ", xlrec->xid); xact_desc_abort(buf, &xlrec->arec); } else if (info == XLOG_XACT_ASSIGNMENT) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 2ffd4001fa..9c58231e94 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -74,6 +74,8 @@ bool fullPageWrites = true; bool log_checkpoints = false; int sync_method = DEFAULT_SYNC_METHOD; +#define WAL_DEBUG + #ifdef WAL_DEBUG bool XLOG_DEBUG = false; #endif @@ -5958,8 +5960,8 @@ StartupXLOG(void) { #ifdef WAL_DEBUG if (XLOG_DEBUG || - (rmid == RM_XACT_ID && trace_recovery_messages >= DEBUG2) || - (rmid != RM_XACT_ID && trace_recovery_messages >= DEBUG3)) + (rmid == RM_XACT_ID && trace_recovery_messages <= DEBUG2) || + (rmid != RM_XACT_ID && trace_recovery_messages <= DEBUG3)) { StringInfoData buf; diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index b5f455749f..3b1d843929 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -67,9 +67,9 @@ test: select ignore: random # ---------- -# Another group of parallel tests test removed=prepared_xacts +# Another group of parallel tests # ---------- -test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace delete +test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete test: privileges test: misc diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule index 4699b9114e..b7984ed163 100644 --- a/src/test/regress/serial_schedule +++ b/src/test/regress/serial_schedule @@ -84,7 +84,7 @@ test: hash_index test: update test: delete test: namespace -#test: prepared_xacts +test: prepared_xacts test: privileges test: misc test: select_views -- 2.39.5