From 6f15be5bedfc423b8a8f2f0282e2a0eb20a16663 Mon Sep 17 00:00:00 2001 From: Noah Misch Date: Wed, 9 Sep 2020 18:50:24 -0700 Subject: [PATCH] Fix rd_firstRelfilenodeSubid for nailed relations, in parallel workers. Move applicable code out of RelationBuildDesc(), which nailed relations bypass. Non-assert builds experienced no known problems. Back-patch to v13, where commit c6b92041d38512a4176ed76ad06f713d2e6c01a8 introduced rd_firstRelfilenodeSubid. Kyotaro Horiguchi. Reported by Justin Pryzby. Discussion: https://postgr.es/m/20200907023737.GA7158@telsasoft.com --- src/backend/utils/cache/relcache.c | 23 ++++++++++++------- src/test/regress/expected/reindex_catalog.out | 10 ++++++++ src/test/regress/sql/reindex_catalog.sql | 11 +++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 0b9eb00d2d..9c9cb6377a 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -1242,14 +1242,6 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) if (insertIt) RelationCacheInsert(relation, true); - /* - * For RelationNeedsWAL() to answer correctly on parallel workers, restore - * rd_firstRelfilenodeSubid. No subtransactions start or end while in - * parallel mode, so the specific SubTransactionId does not matter. - */ - if (IsParallelWorker() && RelFileNodeSkippingWAL(relation->rd_node)) - relation->rd_firstRelfilenodeSubid = TopSubTransactionId; - /* It's fully valid */ relation->rd_isvalid = true; @@ -1272,6 +1264,8 @@ RelationBuildDesc(Oid targetRelId, bool insertIt) static void RelationInitPhysicalAddr(Relation relation) { + Oid oldnode = relation->rd_node.relNode; + /* these relations kinds never have storage */ if (!RELKIND_HAS_STORAGE(relation->rd_rel->relkind)) return; @@ -1329,6 +1323,19 @@ RelationInitPhysicalAddr(Relation relation) elog(ERROR, "could not find relation mapping for relation \"%s\", OID %u", RelationGetRelationName(relation), relation->rd_id); } + + /* + * For RelationNeedsWAL() to answer correctly on parallel workers, restore + * rd_firstRelfilenodeSubid. No subtransactions start or end while in + * parallel mode, so the specific SubTransactionId does not matter. + */ + if (IsParallelWorker() && oldnode != relation->rd_node.relNode) + { + if (RelFileNodeSkippingWAL(relation->rd_node)) + relation->rd_firstRelfilenodeSubid = TopSubTransactionId; + else + relation->rd_firstRelfilenodeSubid = InvalidSubTransactionId; + } } /* diff --git a/src/test/regress/expected/reindex_catalog.out b/src/test/regress/expected/reindex_catalog.out index 4b5fba4949..204f056c9a 100644 --- a/src/test/regress/expected/reindex_catalog.out +++ b/src/test/regress/expected/reindex_catalog.out @@ -36,3 +36,13 @@ REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical +-- Check the same REINDEX INDEX statements under parallelism. +BEGIN; +SET min_parallel_table_scan_size = 0; +REINDEX INDEX pg_class_oid_index; -- mapped, non-shared, critical +REINDEX INDEX pg_class_relname_nsp_index; -- mapped, non-shared, non-critical +REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical +REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical +REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical +REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical +ROLLBACK; diff --git a/src/test/regress/sql/reindex_catalog.sql b/src/test/regress/sql/reindex_catalog.sql index 87ecf52244..8203641cf9 100644 --- a/src/test/regress/sql/reindex_catalog.sql +++ b/src/test/regress/sql/reindex_catalog.sql @@ -39,3 +39,14 @@ REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical + +-- Check the same REINDEX INDEX statements under parallelism. +BEGIN; +SET min_parallel_table_scan_size = 0; +REINDEX INDEX pg_class_oid_index; -- mapped, non-shared, critical +REINDEX INDEX pg_class_relname_nsp_index; -- mapped, non-shared, non-critical +REINDEX INDEX pg_index_indexrelid_index; -- non-mapped, non-shared, critical +REINDEX INDEX pg_index_indrelid_index; -- non-mapped, non-shared, non-critical +REINDEX INDEX pg_database_oid_index; -- mapped, shared, critical +REINDEX INDEX pg_shdescription_o_c_index; -- mapped, shared, non-critical +ROLLBACK;