Skip to content

Commit f5bb46f

Browse files
committed
Don't lose partitioned table reltuples=0 after relhassubclass=f.
ANALYZE sets relhassubclass=f when a partitioned table no longer has partitions. An ANALYZE doing that proceeded to apply the inplace update of pg_class.reltuples to the old pg_class tuple instead of the new tuple, losing that reltuples=0 change if the ANALYZE committed. Non-partitioning inheritance trees were unaffected. Back-patch to v14, where commit 375aed3 introduced maintenance of partitioned table pg_class.reltuples. Reported by Alexander Lakhin. Discussion: https://postgr.es/m/a295b499-dcab-6a99-c06e-01cf60593344@gmail.com
1 parent dd12eb3 commit f5bb46f

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

src/backend/commands/analyze.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,11 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
629629
else
630630
relallvisible = 0;
631631

632-
/* Update pg_class for table relation */
632+
/*
633+
* Update pg_class for table relation. CCI first, in case acquirefunc
634+
* updated pg_class.
635+
*/
636+
CommandCounterIncrement();
633637
vac_update_relstats(onerel,
634638
relpages,
635639
totalrows,
@@ -664,6 +668,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
664668
* Partitioned tables don't have storage, so we don't set any fields
665669
* in their pg_class entries except for reltuples and relhasindex.
666670
*/
671+
CommandCounterIncrement();
667672
vac_update_relstats(onerel, -1, totalrows,
668673
0, hasindex, InvalidTransactionId,
669674
InvalidMultiXactId,

src/test/regress/expected/vacuum.out

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,53 @@ BEGIN;
8282
INSERT INTO vactst SELECT generate_series(301, 400);
8383
DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
8484
ANALYZE vactst;
85+
COMMIT;
86+
-- Test ANALYZE setting relhassubclass=f for non-partitioning inheritance
87+
BEGIN;
88+
CREATE TABLE past_inh_parent ();
89+
CREATE TABLE past_inh_child () INHERITS (past_inh_parent);
90+
INSERT INTO past_inh_child DEFAULT VALUES;
91+
INSERT INTO past_inh_child DEFAULT VALUES;
92+
ANALYZE past_inh_parent;
93+
SELECT reltuples, relhassubclass
94+
FROM pg_class WHERE oid = 'past_inh_parent'::regclass;
95+
reltuples | relhassubclass
96+
-----------+----------------
97+
0 | t
98+
(1 row)
99+
100+
DROP TABLE past_inh_child;
101+
ANALYZE past_inh_parent;
102+
SELECT reltuples, relhassubclass
103+
FROM pg_class WHERE oid = 'past_inh_parent'::regclass;
104+
reltuples | relhassubclass
105+
-----------+----------------
106+
0 | f
107+
(1 row)
108+
109+
COMMIT;
110+
-- Test ANALYZE setting relhassubclass=f for partitioning
111+
BEGIN;
112+
CREATE TABLE past_parted (i int) PARTITION BY LIST(i);
113+
CREATE TABLE past_part PARTITION OF past_parted FOR VALUES IN (1);
114+
INSERT INTO past_parted VALUES (1),(1);
115+
ANALYZE past_parted;
116+
DROP TABLE past_part;
117+
SELECT reltuples, relhassubclass
118+
FROM pg_class WHERE oid = 'past_parted'::regclass;
119+
reltuples | relhassubclass
120+
-----------+----------------
121+
2 | t
122+
(1 row)
123+
124+
ANALYZE past_parted;
125+
SELECT reltuples, relhassubclass
126+
FROM pg_class WHERE oid = 'past_parted'::regclass;
127+
reltuples | relhassubclass
128+
-----------+----------------
129+
0 | f
130+
(1 row)
131+
85132
COMMIT;
86133
VACUUM FULL pg_am;
87134
VACUUM FULL pg_class;

src/test/regress/sql/vacuum.sql

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,35 @@ DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
6767
ANALYZE vactst;
6868
COMMIT;
6969

70+
-- Test ANALYZE setting relhassubclass=f for non-partitioning inheritance
71+
BEGIN;
72+
CREATE TABLE past_inh_parent ();
73+
CREATE TABLE past_inh_child () INHERITS (past_inh_parent);
74+
INSERT INTO past_inh_child DEFAULT VALUES;
75+
INSERT INTO past_inh_child DEFAULT VALUES;
76+
ANALYZE past_inh_parent;
77+
SELECT reltuples, relhassubclass
78+
FROM pg_class WHERE oid = 'past_inh_parent'::regclass;
79+
DROP TABLE past_inh_child;
80+
ANALYZE past_inh_parent;
81+
SELECT reltuples, relhassubclass
82+
FROM pg_class WHERE oid = 'past_inh_parent'::regclass;
83+
COMMIT;
84+
85+
-- Test ANALYZE setting relhassubclass=f for partitioning
86+
BEGIN;
87+
CREATE TABLE past_parted (i int) PARTITION BY LIST(i);
88+
CREATE TABLE past_part PARTITION OF past_parted FOR VALUES IN (1);
89+
INSERT INTO past_parted VALUES (1),(1);
90+
ANALYZE past_parted;
91+
DROP TABLE past_part;
92+
SELECT reltuples, relhassubclass
93+
FROM pg_class WHERE oid = 'past_parted'::regclass;
94+
ANALYZE past_parted;
95+
SELECT reltuples, relhassubclass
96+
FROM pg_class WHERE oid = 'past_parted'::regclass;
97+
COMMIT;
98+
7099
VACUUM FULL pg_am;
71100
VACUUM FULL pg_class;
72101
VACUUM FULL pg_database;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy