aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndres Freund <andres@anarazel.de>2022-12-02 18:09:55 -0800
committerAndres Freund <andres@anarazel.de>2022-12-02 18:10:30 -0800
commitcb2e7ddfe571e2a158725200a33f728232059c2e (patch)
treef42b7e79bcdf0e451944a0e26c1c6f2197a4a252
parent7ac0f8d384a4633c6652ae1f6bba40d42d21ec18 (diff)
downloadpostgresql-cb2e7ddfe571e2a158725200a33f728232059c2e.tar.gz
postgresql-cb2e7ddfe571e2a158725200a33f728232059c2e.zip
Prevent pgstats from getting confused when relkind of a relation changes
When the relkind of a relache entry changes, because a table is converted into a view, pgstats can get confused in 15+, leading to crashes or assertion failures. For HEAD, Tom fixed this in b23cd185fd5, by removing support for converting a table to a view, removing the source of the inconsistency. This commit just adds an assertion that a relcache entry's relkind does not change, just in case we end up with another case of that in the future. As there's no cases of changing relkind anymore, we can't add a test that that's handled correctly. For 15, fix the problem by not maintaining the association with the old pgstat entry when the relkind changes during a relcache invalidation processing. In that case the pgstat entry needs to be unlinked first, to avoid PgStat_TableStatus->relation getting out of sync. Also add a test reproducing the issues. No known problem exists in 11-14, so just add the test there. Reported-by: vignesh C <vignesh21@gmail.com> Author: Andres Freund <andres@anarazel.de> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/CALDaNm2yXz+zOtv7y5zBd5WKT8O0Ld3YxikuU3dcyCvxF7gypA@mail.gmail.com Discussion: https://postgr.es/m/CALDaNm3oZA-8Wbps2Jd1g5_Gjrr-x3YWrJPek-mF5Asrrvz2Dg@mail.gmail.com Backpatch: 15-
-rw-r--r--src/backend/utils/cache/relcache.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index bd6cd4e47b5..a50eecc7c8a 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -2661,6 +2661,13 @@ RelationClearRelation(Relation relation, bool rebuild)
elog(ERROR, "relation %u deleted while still in use", save_relid);
}
+ /*
+ * If we were to, again, have cases of the relkind of a relcache entry
+ * changing, we would need to ensure that pgstats does not get
+ * confused.
+ */
+ Assert(relation->rd_rel->relkind == newrel->rd_rel->relkind);
+
keep_tupdesc = equalTupleDescs(relation->rd_att, newrel->rd_att);
keep_rules = equalRuleLocks(relation->rd_rules, newrel->rd_rules);
keep_policies = equalRSDesc(relation->rd_rsdesc, newrel->rd_rsdesc);