Re: CREATE INDEX CONCURRENTLY does not index prepared xact's data
Michael Paquier <michael@paquier.xyz>
From: Michael Paquier <michael@paquier.xyz>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Andrey Borodin <x4mmm@yandex-team.ru>, pgsql-bugs@lists.postgresql.org
Date: 2020-12-21T05:40:03Z
Lists: pgsql-bugs
On Sat, Dec 19, 2020 at 12:57:41PM -0500, Tom Lane wrote:
> Andrey Borodin <x4mmm@yandex-team.ru> writes:
>> This happens because WaitForLockersMultiple() does not take prepared
>> xacts into account.
>
> Ugh, clearly an oversight.
This looks to be the case since 295e639 where virtual XIDs have been
introduced. So this is an old bug.
> Don't follow your point here --- I'm pretty sure that prepared xacts
> continue to hold their locks.
Yes, that's what I recall as well.
> Haven't you completely broken VirtualXactLock()? Certainly, whether the
> target is a normal or prepared transaction shouldn't alter the meaning
> of the "wait" flag.
Yep.
> In general, I wonder whether WaitForLockersMultiple and GetLockConflicts
> need to gain an additional parameter indicating whether to consider
> prepared xacts. It's not clear to me that their current behavior is wrong
> for all possible uses.
WaitForLockers is used only by REINDEX and CREATE/DROP CONCURRENTLY,
where it seems to me we need to care about all the cases related to
concurrent build, validation and index drop. The other caller of
GetLockConflicts() is for conflict resolution in standbys where it is
fine to ignore 2PC transactions as these cannot be cancelled. So I
agree that we are going to need more control with a new option
argument to be able to control if 2PC transactions are ignored or
not.
Hmm. The approach taken by the patch looks to be back-patchable.
Based on the lack of complaints on the matter, we could consider
instead putting an error in WaitForLockersMultiple() if there is at
least one numPrepXact which would at least avoid inconsistent data.
But I don't think what's proposed here is bad either.
VirtualTransactionIdIsValidOrPreparedXact() is confusing IMO, knowing
that VirtualTransactionIdIsPreparedXact() combined with
LocalTransactionIdIsValid() would be enough to do the job.
- Assert(VirtualTransactionIdIsValid(vxid));
+ Assert(VirtualTransactionIdIsValidOrPreparedXact(vxid));
+
+ if (VirtualTransactionIdIsPreparedXact(vxid))
[...]
#define VirtualTransactionIdIsPreparedXact(vxid) \
((vxid).backendId == InvalidBackendId)
This would allow the case where backendId and localTransactionId are
both invalid. So it would be better to also check in
VirtualTransactionIdIsPreparedXact() that the XID is not invalid, no?
--
Michael
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Improve contrib/amcheck's tests for CREATE INDEX CONCURRENTLY.
- b1f943d2aa7e 14.1 landed
- 7f580aa5d88a 15.0 landed
- 5a4b8a8a720c 13.5 landed
- 141cd0ef0b0b 12.9 landed
-
Fix minor memory leaks in pg_dump.
- 70bef494000e 15.0 cited
-
Avoid race in RelationBuildDesc() affecting CREATE INDEX CONCURRENTLY.
- e428699cb3be 9.6.24 landed
- db86746fd11e 10.19 landed
- 5141e471b36a 11.14 landed
- dde966efb286 14.1 landed
- 2e33b43599ad 13.5 landed
- 0869e53d3a07 12.9 landed
- fdd965d074d4 15.0 landed
-
Fix CREATE INDEX CONCURRENTLY for the newest prepared transactions.
- df6158139f64 11.14 landed
- 560124a37c2f 10.19 landed
- 5184932432b4 9.6.24 landed
- fe5d44a1d38f 12.9 landed
- a9d0a5409415 13.5 landed
- a5b9a0000e14 14.1 landed
- 3cd9c3b92197 15.0 landed
-
Add -w back to the flags for pg_ctl (re)start in PostgresNode
- b33259e261ae 15.0 cited
-
Fix CREATE INDEX CONCURRENTLY for simultaneous prepared transactions.
- 77a0e14f0b21 9.5.25 landed
- d683d6528dba 9.6.21 landed
- 179775135b41 10.16 landed
- d1ab4bf6ed2d 11.11 landed
- be843ce29737 12.6 landed
- 86a5b309c933 13.2 landed
- 8a54e12a38d1 14.0 landed