mirror of
https://github.com/postgres/postgres.git
synced 2025-05-28 05:21:27 +03:00
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 375aed36ad83f0e021e9bdd3a0034c0c992c66dc introduced maintenance of partitioned table pg_class.reltuples. Reported by Alexander Lakhin. Discussion: https://postgr.es/m/a295b499-dcab-6a99-c06e-01cf60593344@gmail.com
This commit is contained in:
parent
6f55b4f112
commit
2b4a2a79ed
@ -637,7 +637,11 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
|
||||
|
||||
visibilitymap_count(onerel, &relallvisible, NULL);
|
||||
|
||||
/* Update pg_class for table relation */
|
||||
/*
|
||||
* Update pg_class for table relation. CCI first, in case acquirefunc
|
||||
* updated pg_class.
|
||||
*/
|
||||
CommandCounterIncrement();
|
||||
vac_update_relstats(onerel,
|
||||
relpages,
|
||||
totalrows,
|
||||
@ -672,6 +676,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
|
||||
* Partitioned tables don't have storage, so we don't set any fields
|
||||
* in their pg_class entries except for reltuples and relhasindex.
|
||||
*/
|
||||
CommandCounterIncrement();
|
||||
vac_update_relstats(onerel, -1, totalrows,
|
||||
0, hasindex, InvalidTransactionId,
|
||||
InvalidMultiXactId,
|
||||
|
@ -82,6 +82,53 @@ BEGIN;
|
||||
INSERT INTO vactst SELECT generate_series(301, 400);
|
||||
DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
|
||||
ANALYZE vactst;
|
||||
COMMIT;
|
||||
-- Test ANALYZE setting relhassubclass=f for non-partitioning inheritance
|
||||
BEGIN;
|
||||
CREATE TABLE past_inh_parent ();
|
||||
CREATE TABLE past_inh_child () INHERITS (past_inh_parent);
|
||||
INSERT INTO past_inh_child DEFAULT VALUES;
|
||||
INSERT INTO past_inh_child DEFAULT VALUES;
|
||||
ANALYZE past_inh_parent;
|
||||
SELECT reltuples, relhassubclass
|
||||
FROM pg_class WHERE oid = 'past_inh_parent'::regclass;
|
||||
reltuples | relhassubclass
|
||||
-----------+----------------
|
||||
0 | t
|
||||
(1 row)
|
||||
|
||||
DROP TABLE past_inh_child;
|
||||
ANALYZE past_inh_parent;
|
||||
SELECT reltuples, relhassubclass
|
||||
FROM pg_class WHERE oid = 'past_inh_parent'::regclass;
|
||||
reltuples | relhassubclass
|
||||
-----------+----------------
|
||||
0 | f
|
||||
(1 row)
|
||||
|
||||
COMMIT;
|
||||
-- Test ANALYZE setting relhassubclass=f for partitioning
|
||||
BEGIN;
|
||||
CREATE TABLE past_parted (i int) PARTITION BY LIST(i);
|
||||
CREATE TABLE past_part PARTITION OF past_parted FOR VALUES IN (1);
|
||||
INSERT INTO past_parted VALUES (1),(1);
|
||||
ANALYZE past_parted;
|
||||
DROP TABLE past_part;
|
||||
SELECT reltuples, relhassubclass
|
||||
FROM pg_class WHERE oid = 'past_parted'::regclass;
|
||||
reltuples | relhassubclass
|
||||
-----------+----------------
|
||||
2 | t
|
||||
(1 row)
|
||||
|
||||
ANALYZE past_parted;
|
||||
SELECT reltuples, relhassubclass
|
||||
FROM pg_class WHERE oid = 'past_parted'::regclass;
|
||||
reltuples | relhassubclass
|
||||
-----------+----------------
|
||||
0 | f
|
||||
(1 row)
|
||||
|
||||
COMMIT;
|
||||
VACUUM FULL pg_am;
|
||||
VACUUM FULL pg_class;
|
||||
|
@ -67,6 +67,35 @@ DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
|
||||
ANALYZE vactst;
|
||||
COMMIT;
|
||||
|
||||
-- Test ANALYZE setting relhassubclass=f for non-partitioning inheritance
|
||||
BEGIN;
|
||||
CREATE TABLE past_inh_parent ();
|
||||
CREATE TABLE past_inh_child () INHERITS (past_inh_parent);
|
||||
INSERT INTO past_inh_child DEFAULT VALUES;
|
||||
INSERT INTO past_inh_child DEFAULT VALUES;
|
||||
ANALYZE past_inh_parent;
|
||||
SELECT reltuples, relhassubclass
|
||||
FROM pg_class WHERE oid = 'past_inh_parent'::regclass;
|
||||
DROP TABLE past_inh_child;
|
||||
ANALYZE past_inh_parent;
|
||||
SELECT reltuples, relhassubclass
|
||||
FROM pg_class WHERE oid = 'past_inh_parent'::regclass;
|
||||
COMMIT;
|
||||
|
||||
-- Test ANALYZE setting relhassubclass=f for partitioning
|
||||
BEGIN;
|
||||
CREATE TABLE past_parted (i int) PARTITION BY LIST(i);
|
||||
CREATE TABLE past_part PARTITION OF past_parted FOR VALUES IN (1);
|
||||
INSERT INTO past_parted VALUES (1),(1);
|
||||
ANALYZE past_parted;
|
||||
DROP TABLE past_part;
|
||||
SELECT reltuples, relhassubclass
|
||||
FROM pg_class WHERE oid = 'past_parted'::regclass;
|
||||
ANALYZE past_parted;
|
||||
SELECT reltuples, relhassubclass
|
||||
FROM pg_class WHERE oid = 'past_parted'::regclass;
|
||||
COMMIT;
|
||||
|
||||
VACUUM FULL pg_am;
|
||||
VACUUM FULL pg_class;
|
||||
VACUUM FULL pg_database;
|
||||
|
Loading…
x
Reference in New Issue
Block a user