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

Reply via email to