Re: BUG #19620: pg_class index corruption caused by statement_timeout during VACUUM FULL - Mailing list pgsql-bugs

From Tesla V.
Subject Re: BUG #19620: pg_class index corruption caused by statement_timeout during VACUUM FULL
Date
Msg-id CABr23Z-d8qvOkR+ZY6NUCD13pmJasLDd9eP9KDS82Va8jpw=eQ@mail.gmail.com
Whole thread
List pgsql-bugs
Hi Zheng, hi Andrey,

Zheng's autovacuum=off result matches what I see: this is the July 2020
catalog HOT / index-build race, not a new interrupt-safety bug.
statement_timeout only causes VACUUM FULL of pg_class to retry while
autovacuum is still HOT-updating catalog rows.

Waiting for INSERT_IN_PROGRESS is not usable on catalogs. Commit
1ddc2703a936 stopped those waits on non-unique builds because VACUUM
FULL / CLUSTER takes AccessExclusiveLock on the catalog and then
deadlocks with a backend whose in-progress insert we would wait for.
VACUUM FULL also sets skip_constraint_checks, so even unique pg_class
indexes take the non-waiting path. That is why the original report
could corrupt pg_class_relname_nsp_index.

The attached patch keeps that decision. heapam_index_build_range_scan
records which root offsets on the current page have already been
handed to the AM, and skips a second callback for the same root TID.
The mark is taken only after a partial-index predicate would accept
the tuple. Refreshing root_offsets for an unknown HOT parent does not
clear the map.

I reproduced this on current master with cassert. With about 14000
pg_class rows, REINDEX INDEX pg_class_tblspc_relfilenode_index against
GRANT/REVOKE on one table (relacl is not indexed, so the update is
HOT) traps without the patch in comparetup_index_btree_tiebreak
("ItemPointer values should never be equal") within a few seconds.
The same workload with the patch does not trap. bt_index_check and
bt_index_parent_check pass, and VACUUM FULL pg_class still completes
while another transaction has an open catalog insert.

contrib/amcheck/t/007_catalog_reindex_hot.pl covers the deadlock
invariant and the concurrent REINDEX + GRANT case.

The patch is against master.

Thanks,
Marcelo Tesla

Attachment

pgsql-bugs by date:

Previous
From: "Hayato Kuroda (Fujitsu)"
Date:
Subject: RE: START_REPLICATION silently truncates an overlong LSN component
Next
From: Samriddha Kumar Tripathi
Date:
Subject: Re: BUG #19685: START_REPLICATION accepts an overflowing LSN component