Noah Misch <noah@leadboat.com> writes:
> On Thu, Oct 26, 2023 at 09:44:04PM -0700, Noah Misch wrote:
>> We'll likely need to change how we maintain relhasindex or perhaps take a lock
>> in GRANT.
> The main choice is accepting more DDL blocking vs. accepting inefficient
> relcache builds. Options I'm seeing:
It looks to me like you're only thinking about relhasindex, but it
seems to me that any call of heap_inplace_update brings some
risk of this kind. Excluding the bootstrap-mode-only usage in
create_toast_table, I see four callers:
* index_update_stats updating a pg_class tuple's
relhasindex, relpages, reltuples, relallvisible
* vac_update_relstats updating a pg_class tuple's
relpages, reltuples, relallvisible, relhasindex, relhasrules,
relhastriggers, relfrozenxid, relminmxid
* vac_update_datfrozenxid updating a pg_database tuple's
datfrozenxid, datminmxid
* dropdb updating a pg_database tuple's datconnlimit
So we have just as much of a problem with GRANTs on databases
as GRANTs on relations. Also, it looks like we can lose
knowledge of the presence of rules and triggers, which seems
nearly as bad as forgetting about indexes. The rest of these
updates might not be correctness-critical, although I wonder
how bollixed things could get if we forget an advancement of
relfrozenxid or datfrozenxid (especially if the calling
transaction goes on to make other changes that assume that
the update happened).
BTW, vac_update_datfrozenxid believes (correctly I think) that
it cannot use the syscache copy of a tuple as the basis for in-place
update, because syscache will have detoasted any toastable fields.
These other callers are ignoring that, which seems like it should
result in heap_inplace_update failing with "wrong tuple length".
I wonder how come we're not seeing reports of that from the field.
I'm inclined to propose that heap_inplace_update should check to
make sure that it's operating on the latest version of the tuple
(including, I guess, waiting for an uncommitted update?) and throw
error if not. I think this is what your B3 option is, but maybe
I misinterpreted. It might be better to throw error immediately
instead of waiting to see if the other updater commits.
regards, tom lane