mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-17 19:30:00 +08:00
Avoid testing tuple visibility without buffer lock.
INSERT ... ON CONFLICT (specifically ExecCheckHeapTupleVisible) contains
another example of this unsafe coding practice. It is much harder to get
a failure out of it than the case fixed in commit 6292c2339
, because in
most scenarios any hint bits that could be set would have already been set
earlier in the command. However, Konstantin Knizhnik reported a failure
with a custom transaction manager, and it's clearly possible to get a
failure via a race condition in async-commit mode.
For lack of a reproducible example, no regression test case in this
commit.
I did some testing with Asserts added to tqual.c's functions, and can say
that running "make check-world" exposed these two bugs and no others.
The Asserts are messy enough that I've not added them to the code for now.
Report: <57EE93C8.8080504@postgrespro.ru>
Related-Discussion: <CAO3NbwOycQjt2Oqy2VW-eLTq2M5uGMyHnGm=RNga4mjqcYD7gQ@mail.gmail.com>
This commit is contained in:
parent
a6c0a5b6e8
commit
8f1fb7d621
@ -194,6 +194,11 @@ ExecCheckHeapTupleVisible(EState *estate,
|
||||
if (!IsolationUsesXactSnapshot())
|
||||
return;
|
||||
|
||||
/*
|
||||
* We need buffer pin and lock to call HeapTupleSatisfiesVisibility.
|
||||
* Caller should be holding pin, but not lock.
|
||||
*/
|
||||
LockBuffer(buffer, BUFFER_LOCK_SHARE);
|
||||
if (!HeapTupleSatisfiesVisibility(tuple, estate->es_snapshot, buffer))
|
||||
{
|
||||
/*
|
||||
@ -207,6 +212,7 @@ ExecCheckHeapTupleVisible(EState *estate,
|
||||
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
|
||||
errmsg("could not serialize access due to concurrent update")));
|
||||
}
|
||||
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user