mirror of
https://github.com/postgres/postgres.git
synced 2025-06-01 14:21:49 +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);
|
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,
|
vac_update_relstats(onerel,
|
||||||
relpages,
|
relpages,
|
||||||
totalrows,
|
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
|
* Partitioned tables don't have storage, so we don't set any fields
|
||||||
* in their pg_class entries except for reltuples and relhasindex.
|
* in their pg_class entries except for reltuples and relhasindex.
|
||||||
*/
|
*/
|
||||||
|
CommandCounterIncrement();
|
||||||
vac_update_relstats(onerel, -1, totalrows,
|
vac_update_relstats(onerel, -1, totalrows,
|
||||||
0, hasindex, InvalidTransactionId,
|
0, hasindex, InvalidTransactionId,
|
||||||
InvalidMultiXactId,
|
InvalidMultiXactId,
|
||||||
|
@ -82,6 +82,53 @@ BEGIN;
|
|||||||
INSERT INTO vactst SELECT generate_series(301, 400);
|
INSERT INTO vactst SELECT generate_series(301, 400);
|
||||||
DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
|
DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
|
||||||
ANALYZE vactst;
|
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;
|
COMMIT;
|
||||||
VACUUM FULL pg_am;
|
VACUUM FULL pg_am;
|
||||||
VACUUM FULL pg_class;
|
VACUUM FULL pg_class;
|
||||||
|
@ -67,6 +67,35 @@ DELETE FROM vactst WHERE i % 5 <> 0; -- delete a few rows inside
|
|||||||
ANALYZE vactst;
|
ANALYZE vactst;
|
||||||
COMMIT;
|
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_am;
|
||||||
VACUUM FULL pg_class;
|
VACUUM FULL pg_class;
|
||||||
VACUUM FULL pg_database;
|
VACUUM FULL pg_database;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user