Skip to content

Commit b65be6e

Browse files
Ensure we have a snapshot when updating various system catalogs.
A few places that access system catalogs don't set up an active snapshot before potentially accessing their TOAST tables. To fix, push an active snapshot just before each section of code that might require accessing one of these TOAST tables, and pop it shortly afterwards. While at it, this commit adds some rather strict assertions in an attempt to prevent such issues in the future. Commit 16bf24e recently removed pg_replication_origin's TOAST table in order to fix the same problem for that catalog. On the back-branches, those bugs are left in place. We cannot easily remove a catalog's TOAST table on released major versions, and only replication origins with extremely long names are affected. Given the low severity of the issue, fixing older versions doesn't seem worth the trouble of significantly modifying the patch. Also, on v13 and v14, the aforementioned strict assertions have been omitted because commit 2776922, which added HaveRegisteredOrActiveSnapshot(), was not back-patched. While we could probably back-patch it now, I've opted against it because it seems unlikely that new TOAST snapshot issues will be introduced in the oldest supported versions. Reported-by: Alexander Lakhin <exclusion@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/18127-fe54b6a667f29658%40postgresql.org Discussion: https://postgr.es/m/18309-c0bf914950c46692%40postgresql.org Discussion: https://postgr.es/m/ZvMSUPOqUU-VNADN%40nathan Backpatch-through: 13
1 parent 4a07c09 commit b65be6e

File tree

3 files changed

+23
-0
lines changed

3 files changed

+23
-0
lines changed

src/backend/commands/indexcmds.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4005,12 +4005,20 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
40054005
get_rel_namespace(oldidx->tableId),
40064006
false);
40074007

4008+
/*
4009+
* Swapping the indexes might involve TOAST table access, so ensure we
4010+
* have a valid snapshot.
4011+
*/
4012+
PushActiveSnapshot(GetTransactionSnapshot());
4013+
40084014
/*
40094015
* Swap old index with the new one. This also marks the new one as
40104016
* valid and the old one as not valid.
40114017
*/
40124018
index_concurrently_swap(newidx->indexId, oldidx->indexId, oldName);
40134019

4020+
PopActiveSnapshot();
4021+
40144022
/*
40154023
* Invalidate the relcache for the table, so that after this commit
40164024
* all sessions will refresh any cached plans that might reference the

src/backend/commands/tablecmds.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18220,9 +18220,17 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel,
1822018220
tab->rel = rel;
1822118221
}
1822218222

18223+
/*
18224+
* Detaching the partition might involve TOAST table access, so ensure we
18225+
* have a valid snapshot.
18226+
*/
18227+
PushActiveSnapshot(GetTransactionSnapshot());
18228+
1822318229
/* Do the final part of detaching */
1822418230
DetachPartitionFinalize(rel, partRel, concurrent, defaultPartOid);
1822518231

18232+
PopActiveSnapshot();
18233+
1822618234
ObjectAddressSet(address, RelationRelationId, RelationGetRelid(partRel));
1822718235

1822818236
/* keep our lock until commit */

src/backend/postmaster/autovacuum.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2321,6 +2321,12 @@ do_autovacuum(void)
23212321
get_namespace_name(classForm->relnamespace),
23222322
NameStr(classForm->relname))));
23232323

2324+
/*
2325+
* Deletion might involve TOAST table access, so ensure we have a
2326+
* valid snapshot.
2327+
*/
2328+
PushActiveSnapshot(GetTransactionSnapshot());
2329+
23242330
object.classId = RelationRelationId;
23252331
object.objectId = relid;
23262332
object.objectSubId = 0;
@@ -2333,6 +2339,7 @@ do_autovacuum(void)
23332339
* To commit the deletion, end current transaction and start a new
23342340
* one. Note this also releases the locks we took.
23352341
*/
2342+
PopActiveSnapshot();
23362343
CommitTransactionCommand();
23372344
StartTransactionCommand();
23382345

0 commit comments

Comments
 (0)