pgsql: Fix improper abort during update chain locking - Mailing list pgsql-committers

From Alvaro Herrera
Subject pgsql: Fix improper abort during update chain locking
Date
Msg-id E1Vog2b-00039y-HU@gemulon.postgresql.org
Whole thread Raw
List pgsql-committers
Fix improper abort during update chain locking

In 247c76a98909, I added some code to do fine-grained checking of
MultiXact status of locking/updating transactions when traversing an
update chain.  There was a thinko in that patch which would have the
traversing abort, that is return HeapTupleUpdated, when the other
transaction is a committed lock-only.  In this case we should ignore it
and return success instead.  Of course, in the case where there is a
committed update, HeapTupleUpdated is the correct return value.

A user-visible symptom of this bug is that in REPEATABLE READ and
SERIALIZABLE transaction isolation modes spurious serializability errors
can occur:
  ERROR:  could not serialize access due to concurrent update

In order for this to happen, there needs to be a tuple that's key-share-
locked and also updated, and the update must abort; a subsequent
transaction trying to acquire a new lock on that tuple would abort with
the above error.  The reason is that the initial FOR KEY SHARE is seen
as committed by the new locking transaction, which triggers this bug.
(If the UPDATE commits, then the serialization error is correctly
reported.)

When running a query in READ COMMITTED mode, what happens is that the
locking is aborted by the HeapTupleUpdated return value, then
EvalPlanQual fetches the newest version of the tuple, which is then the
only version that gets locked.  (The second time the tuple is checked
there is no misbehavior on the committed lock-only, because it's not
checked by the code that traverses update chains; so no bug.) Only the
newest version of the tuple is locked, not older ones, but this is
harmless.

The isolation test added by this commit illustrates the desired
behavior, including the proper serialization errors that get thrown.

Backpatch to 9.3.

Branch
------
master

Details
-------
http://git.postgresql.org/pg/commitdiff/312bde3d404f770943c992992565c73f0336d21b

Modified Files
--------------
src/backend/access/heap/heapam.c                   |   19 ++-
.../isolation/expected/multixact-no-forget.out     |  130 ++++++++++++++++++++
.../isolation/expected/multixact-no-forget_1.out   |  126 +++++++++++++++++++
src/test/isolation/isolation_schedule              |    1 +
src/test/isolation/specs/multixact-no-forget.spec  |   44 +++++++
5 files changed, 317 insertions(+), 3 deletions(-)


pgsql-committers by date:

Previous
From: Tom Lane
Date:
Subject: pgsql: Clear retry flags properly in replacement OpenSSL sock_write fun
Next
From: Alvaro Herrera
Date:
Subject: pgsql: Fix improper abort during update chain locking