Tom Lane wrote: > After some discussion, the core committee has concluded that we should go > ahead with the already-wrapped releases. 9.2.6 and below are good anyway, > and despite this issue 9.3.2 is an improvement over 9.3.1. We'll plan to > do a 9.3.3 as soon as the multixact situation can be straightened out; > but let's learn from experience and not try to fix it in a panic.
I would suggest we include this one fix in 9.3.2a. This bug is more serious than the others because it happens because of checking HTSU on a tuple containing running locker-only transactions and an aborted update. -- Álvaro Herrera http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
commit 4be26fe1ebc3b198d093a0334e033bb70516fa60 Author: Alvaro Herrera <alvhe...@alvh.no-ip.org> Date: Tue Dec 3 15:06:40 2013 -0300 Fixup "Don't TransactionIdDidAbort in ..." patch Noah Misch reported a failure in the new freezing logic for MultiXactIds, providing a test case that demonstrated it; further investigation revealed a problem that HeapTupleSatisfiesUpdate routine could ignore in-progress locker transactions for a tuple whose Xmax is a MultiXactId that contains an aborted update. In short, the lock would suddenly go ignored by other transactions. This change reverts the change to the delete-abort-savept isolation test; turns out changing it was in error. Andres Freund and Álvaro Herrera diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index 4d63b1c..f787f2c 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -789,13 +789,26 @@ HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid, if (TransactionIdDidCommit(xmax)) return HeapTupleUpdated; - /* no member, even just a locker, alive anymore */ + /* + * By here, the update in the Xmax is either aborted or crashed, but + * what about the other members? + */ + if (!MultiXactIdIsRunning(HeapTupleHeaderGetRawXmax(tuple))) + { + /* + * There's no member, even just a locker, alive anymore, so we can + * mark the Xmax as invalid. + */ SetHintBits(tuple, buffer, HEAP_XMAX_INVALID, InvalidTransactionId); - - /* it must have aborted or crashed */ - return HeapTupleMayBeUpdated; + return HeapTupleMayBeUpdated; + } + else + { + /* There are lockers running */ + return HeapTupleBeingUpdated; + } } if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetRawXmax(tuple))) diff --git a/src/test/isolation/expected/delete-abort-savept.out b/src/test/isolation/expected/delete-abort-savept.out index 5b8c444..3420cf4 100644 --- a/src/test/isolation/expected/delete-abort-savept.out +++ b/src/test/isolation/expected/delete-abort-savept.out @@ -23,11 +23,12 @@ key value step s1svp: SAVEPOINT f; step s1d: DELETE FROM foo; step s1r: ROLLBACK TO f; -step s2l: SELECT * FROM foo FOR UPDATE; +step s2l: SELECT * FROM foo FOR UPDATE; <waiting ...> +step s1c: COMMIT; +step s2l: <... completed> key value 1 1 -step s1c: COMMIT; step s2c: COMMIT; starting permutation: s1l s1svp s1d s1r s2l s2c s1c @@ -38,12 +39,8 @@ key value step s1svp: SAVEPOINT f; step s1d: DELETE FROM foo; step s1r: ROLLBACK TO f; -step s2l: SELECT * FROM foo FOR UPDATE; -key value - -1 1 -step s2c: COMMIT; -step s1c: COMMIT; +step s2l: SELECT * FROM foo FOR UPDATE; <waiting ...> +invalid permutation detected starting permutation: s1l s1svp s1d s2l s1r s1c s2c step s1l: SELECT * FROM foo FOR KEY SHARE;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers