Re: CREATE INDEX CONCURRENTLY does not index prepared xact's data

Поиск
Список
Период
Сортировка
От Michael Paquier
Тема Re: CREATE INDEX CONCURRENTLY does not index prepared xact's data
Дата
Msg-id X+A1M1HajC+knVDz@paquier.xyz
обсуждение исходный текст
Ответ на Re: CREATE INDEX CONCURRENTLY does not index prepared xact's data  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: CREATE INDEX CONCURRENTLY does not index prepared xact's data  (Andrey Borodin <x4mmm@yandex-team.ru>)
Re: CREATE INDEX CONCURRENTLY does not index prepared xact's data  (Andrey Borodin <x4mmm@yandex-team.ru>)
Список 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

Вложения

В списке pgsql-bugs по дате отправления:

Предыдущее
От: Stephen Frost
Дата:
Сообщение: Re: BUG #16079: Question Regarding the BUG #16064
Следующее
От: Michael Paquier
Дата:
Сообщение: Re: BUG #16780: Inconsistent recovery_target_xid handling across platforms