Skip to content

Commit 99f8f3f

Browse files
Add relallfrozen to pg_class
Add relallfrozen, an estimate of the number of pages marked all-frozen in the visibility map. pg_class already has relallvisible, an estimate of the number of pages in the relation marked all-visible in the visibility map. This is used primarily for planning. relallfrozen, together with relallvisible, is useful for estimating the outstanding number of all-visible but not all-frozen pages in the relation for the purposes of scheduling manual VACUUMs and tuning vacuum freeze parameters. A future commit will use relallfrozen to trigger more frequent vacuums on insert-focused workloads with significant volume of frozen data. Bump catalog version Author: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Nathan Bossart <nathandbossart@gmail.com> Reviewed-by: Robert Treat <rob@xzilla.net> Reviewed-by: Corey Huinker <corey.huinker@gmail.com> Reviewed-by: Greg Sabino Mullane <htamfids@gmail.com> Discussion: https://postgr.es/m/flat/CAAKRu_aj-P7YyBz_cPNwztz6ohP%2BvWis%3Diz3YcomkB3NpYA--w%40mail.gmail.com
1 parent 8492feb commit 99f8f3f

File tree

14 files changed

+190
-70
lines changed

14 files changed

+190
-70
lines changed

doc/src/sgml/catalogs.sgml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,26 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
20662066
</para></entry>
20672067
</row>
20682068

2069+
<row>
2070+
<entry role="catalog_table_entry"><para role="column_definition">
2071+
<structfield>relallfrozen</structfield> <type>int4</type>
2072+
</para>
2073+
<para>
2074+
Number of pages that are marked all-frozen in the table's visibility
2075+
map. This is only an estimate and can be used along with
2076+
<structfield>relallvisible</structfield> for scheduling vacuums and
2077+
tuning <link linkend="runtime-config-vacuum-freezing">vacuum's freezing
2078+
behavior</link>.
2079+
2080+
It is updated by
2081+
<link linkend="sql-vacuum"><command>VACUUM</command></link>,
2082+
<link linkend="sql-analyze"><command>ANALYZE</command></link>,
2083+
and a few DDL commands such as
2084+
<link linkend="sql-createindex"><command>CREATE INDEX</command></link>.
2085+
</para></entry>
2086+
</row>
2087+
2088+
20692089
<row>
20702090
<entry role="catalog_table_entry"><para role="column_definition">
20712091
<structfield>reltoastrelid</structfield> <type>oid</type>

src/backend/access/heap/vacuumlazy.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,8 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
623623
minmulti_updated;
624624
BlockNumber orig_rel_pages,
625625
new_rel_pages,
626-
new_rel_allvisible;
626+
new_rel_allvisible,
627+
new_rel_allfrozen;
627628
PGRUsage ru0;
628629
TimestampTz starttime = 0;
629630
PgStat_Counter startreadtime = 0,
@@ -898,10 +899,18 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
898899
* pg_class.relpages to
899900
*/
900901
new_rel_pages = vacrel->rel_pages; /* After possible rel truncation */
901-
visibilitymap_count(rel, &new_rel_allvisible, NULL);
902+
visibilitymap_count(rel, &new_rel_allvisible, &new_rel_allfrozen);
902903
if (new_rel_allvisible > new_rel_pages)
903904
new_rel_allvisible = new_rel_pages;
904905

906+
/*
907+
* An all-frozen block _must_ be all-visible. As such, clamp the count of
908+
* all-frozen blocks to the count of all-visible blocks. This matches the
909+
* clamping of relallvisible above.
910+
*/
911+
if (new_rel_allfrozen > new_rel_allvisible)
912+
new_rel_allfrozen = new_rel_allvisible;
913+
905914
/*
906915
* Now actually update rel's pg_class entry.
907916
*
@@ -910,7 +919,8 @@ heap_vacuum_rel(Relation rel, VacuumParams *params,
910919
* scan every page that isn't skipped using the visibility map.
911920
*/
912921
vac_update_relstats(rel, new_rel_pages, vacrel->new_live_tuples,
913-
new_rel_allvisible, vacrel->nindexes > 0,
922+
new_rel_allvisible, new_rel_allfrozen,
923+
vacrel->nindexes > 0,
914924
vacrel->NewRelfrozenXid, vacrel->NewRelminMxid,
915925
&frozenxid_updated, &minmulti_updated, false);
916926

@@ -3720,7 +3730,7 @@ update_relstats_all_indexes(LVRelState *vacrel)
37203730
vac_update_relstats(indrel,
37213731
istat->num_pages,
37223732
istat->num_index_tuples,
3723-
0,
3733+
0, 0,
37243734
false,
37253735
InvalidTransactionId,
37263736
InvalidMultiXactId,

src/backend/catalog/heap.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -924,6 +924,7 @@ InsertPgClassTuple(Relation pg_class_desc,
924924
values[Anum_pg_class_relpages - 1] = Int32GetDatum(rd_rel->relpages);
925925
values[Anum_pg_class_reltuples - 1] = Float4GetDatum(rd_rel->reltuples);
926926
values[Anum_pg_class_relallvisible - 1] = Int32GetDatum(rd_rel->relallvisible);
927+
values[Anum_pg_class_relallfrozen - 1] = Int32GetDatum(rd_rel->relallfrozen);
927928
values[Anum_pg_class_reltoastrelid - 1] = ObjectIdGetDatum(rd_rel->reltoastrelid);
928929
values[Anum_pg_class_relhasindex - 1] = BoolGetDatum(rd_rel->relhasindex);
929930
values[Anum_pg_class_relisshared - 1] = BoolGetDatum(rd_rel->relisshared);
@@ -994,6 +995,7 @@ AddNewRelationTuple(Relation pg_class_desc,
994995
new_rel_reltup->relpages = 0;
995996
new_rel_reltup->reltuples = -1;
996997
new_rel_reltup->relallvisible = 0;
998+
new_rel_reltup->relallfrozen = 0;
997999

9981000
/* Sequences always have a known size */
9991001
if (relkind == RELKIND_SEQUENCE)

src/backend/catalog/index.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,8 +2793,8 @@ FormIndexDatum(IndexInfo *indexInfo,
27932793
* hasindex: set relhasindex to this value
27942794
* reltuples: if >= 0, set reltuples to this value; else no change
27952795
*
2796-
* If reltuples >= 0, relpages and relallvisible are also updated (using
2797-
* RelationGetNumberOfBlocks() and visibilitymap_count()).
2796+
* If reltuples >= 0, relpages, relallvisible, and relallfrozen are also
2797+
* updated (using RelationGetNumberOfBlocks() and visibilitymap_count()).
27982798
*
27992799
* NOTE: an important side-effect of this operation is that an SI invalidation
28002800
* message is sent out to all backends --- including me --- causing relcache
@@ -2812,6 +2812,7 @@ index_update_stats(Relation rel,
28122812
bool update_stats;
28132813
BlockNumber relpages = 0; /* keep compiler quiet */
28142814
BlockNumber relallvisible = 0;
2815+
BlockNumber relallfrozen = 0;
28152816
Oid relid = RelationGetRelid(rel);
28162817
Relation pg_class;
28172818
ScanKeyData key[1];
@@ -2851,7 +2852,7 @@ index_update_stats(Relation rel,
28512852
relpages = RelationGetNumberOfBlocks(rel);
28522853

28532854
if (rel->rd_rel->relkind != RELKIND_INDEX)
2854-
visibilitymap_count(rel, &relallvisible, NULL);
2855+
visibilitymap_count(rel, &relallvisible, &relallfrozen);
28552856
}
28562857

28572858
/*
@@ -2924,6 +2925,11 @@ index_update_stats(Relation rel,
29242925
rd_rel->relallvisible = (int32) relallvisible;
29252926
dirty = true;
29262927
}
2928+
if (rd_rel->relallfrozen != (int32) relallfrozen)
2929+
{
2930+
rd_rel->relallfrozen = (int32) relallfrozen;
2931+
dirty = true;
2932+
}
29272933
}
29282934

29292935
/*

src/backend/commands/analyze.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -630,12 +630,11 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
630630
*/
631631
if (!inh)
632632
{
633-
BlockNumber relallvisible;
633+
BlockNumber relallvisible = 0;
634+
BlockNumber relallfrozen = 0;
634635

635636
if (RELKIND_HAS_STORAGE(onerel->rd_rel->relkind))
636-
visibilitymap_count(onerel, &relallvisible, NULL);
637-
else
638-
relallvisible = 0;
637+
visibilitymap_count(onerel, &relallvisible, &relallfrozen);
639638

640639
/*
641640
* Update pg_class for table relation. CCI first, in case acquirefunc
@@ -646,6 +645,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
646645
relpages,
647646
totalrows,
648647
relallvisible,
648+
relallfrozen,
649649
hasindex,
650650
InvalidTransactionId,
651651
InvalidMultiXactId,
@@ -662,7 +662,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
662662
vac_update_relstats(Irel[ind],
663663
RelationGetNumberOfBlocks(Irel[ind]),
664664
totalindexrows,
665-
0,
665+
0, 0,
666666
false,
667667
InvalidTransactionId,
668668
InvalidMultiXactId,
@@ -678,7 +678,7 @@ do_analyze_rel(Relation onerel, VacuumParams *params,
678678
*/
679679
CommandCounterIncrement();
680680
vac_update_relstats(onerel, -1, totalrows,
681-
0, hasindex, InvalidTransactionId,
681+
0, 0, hasindex, InvalidTransactionId,
682682
InvalidMultiXactId,
683683
NULL, NULL,
684684
in_outer_xact);

src/backend/commands/cluster.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,7 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
12261226
int32 swap_pages;
12271227
float4 swap_tuples;
12281228
int32 swap_allvisible;
1229+
int32 swap_allfrozen;
12291230

12301231
swap_pages = relform1->relpages;
12311232
relform1->relpages = relform2->relpages;
@@ -1238,6 +1239,10 @@ swap_relation_files(Oid r1, Oid r2, bool target_is_pg_class,
12381239
swap_allvisible = relform1->relallvisible;
12391240
relform1->relallvisible = relform2->relallvisible;
12401241
relform2->relallvisible = swap_allvisible;
1242+
1243+
swap_allfrozen = relform1->relallfrozen;
1244+
relform1->relallfrozen = relform2->relallfrozen;
1245+
relform2->relallfrozen = swap_allfrozen;
12411246
}
12421247

12431248
/*

src/backend/commands/vacuum.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,7 @@ void
14271427
vac_update_relstats(Relation relation,
14281428
BlockNumber num_pages, double num_tuples,
14291429
BlockNumber num_all_visible_pages,
1430+
BlockNumber num_all_frozen_pages,
14301431
bool hasindex, TransactionId frozenxid,
14311432
MultiXactId minmulti,
14321433
bool *frozenxid_updated, bool *minmulti_updated,
@@ -1476,6 +1477,11 @@ vac_update_relstats(Relation relation,
14761477
pgcform->relallvisible = (int32) num_all_visible_pages;
14771478
dirty = true;
14781479
}
1480+
if (pgcform->relallfrozen != (int32) num_all_frozen_pages)
1481+
{
1482+
pgcform->relallfrozen = (int32) num_all_frozen_pages;
1483+
dirty = true;
1484+
}
14791485

14801486
/* Apply DDL updates, but not inside an outer transaction (see above) */
14811487

src/backend/statistics/relation_stats.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ enum relation_stats_argnum
3636
RELPAGES_ARG,
3737
RELTUPLES_ARG,
3838
RELALLVISIBLE_ARG,
39+
RELALLFROZEN_ARG,
3940
NUM_RELATION_STATS_ARGS
4041
};
4142

@@ -45,6 +46,7 @@ static struct StatsArgInfo relarginfo[] =
4546
[RELPAGES_ARG] = {"relpages", INT4OID},
4647
[RELTUPLES_ARG] = {"reltuples", FLOAT4OID},
4748
[RELALLVISIBLE_ARG] = {"relallvisible", INT4OID},
49+
[RELALLFROZEN_ARG] = {"relallfrozen", INT4OID},
4850
[NUM_RELATION_STATS_ARGS] = {0}
4951
};
5052

@@ -65,11 +67,13 @@ relation_statistics_update(FunctionCallInfo fcinfo)
6567
bool update_reltuples = false;
6668
BlockNumber relallvisible = 0;
6769
bool update_relallvisible = false;
70+
BlockNumber relallfrozen = 0;
71+
bool update_relallfrozen = false;
6872
HeapTuple ctup;
6973
Form_pg_class pgcform;
70-
int replaces[3] = {0};
71-
Datum values[3] = {0};
72-
bool nulls[3] = {0};
74+
int replaces[4] = {0};
75+
Datum values[4] = {0};
76+
bool nulls[4] = {0};
7377
int nreplaces = 0;
7478

7579
if (!PG_ARGISNULL(RELPAGES_ARG))
@@ -98,6 +102,12 @@ relation_statistics_update(FunctionCallInfo fcinfo)
98102
update_relallvisible = true;
99103
}
100104

105+
if (!PG_ARGISNULL(RELALLFROZEN_ARG))
106+
{
107+
relallfrozen = PG_GETARG_UINT32(RELALLFROZEN_ARG);
108+
update_relallfrozen = true;
109+
}
110+
101111
stats_check_required_arg(fcinfo, relarginfo, RELATION_ARG);
102112
reloid = PG_GETARG_OID(RELATION_ARG);
103113

@@ -148,6 +158,13 @@ relation_statistics_update(FunctionCallInfo fcinfo)
148158
nreplaces++;
149159
}
150160

161+
if (update_relallfrozen && relallfrozen != pgcform->relallfrozen)
162+
{
163+
replaces[nreplaces] = Anum_pg_class_relallfrozen;
164+
values[nreplaces] = UInt32GetDatum(relallfrozen);
165+
nreplaces++;
166+
}
167+
151168
if (nreplaces > 0)
152169
{
153170
TupleDesc tupdesc = RelationGetDescr(crel);
@@ -176,9 +193,9 @@ relation_statistics_update(FunctionCallInfo fcinfo)
176193
Datum
177194
pg_clear_relation_stats(PG_FUNCTION_ARGS)
178195
{
179-
LOCAL_FCINFO(newfcinfo, 4);
196+
LOCAL_FCINFO(newfcinfo, 5);
180197

181-
InitFunctionCallInfoData(*newfcinfo, NULL, 4, InvalidOid, NULL, NULL);
198+
InitFunctionCallInfoData(*newfcinfo, NULL, 5, InvalidOid, NULL, NULL);
182199

183200
newfcinfo->args[0].value = PG_GETARG_OID(0);
184201
newfcinfo->args[0].isnull = PG_ARGISNULL(0);
@@ -188,6 +205,8 @@ pg_clear_relation_stats(PG_FUNCTION_ARGS)
188205
newfcinfo->args[2].isnull = false;
189206
newfcinfo->args[3].value = UInt32GetDatum(0);
190207
newfcinfo->args[3].isnull = false;
208+
newfcinfo->args[4].value = UInt32GetDatum(0);
209+
newfcinfo->args[4].isnull = false;
191210

192211
relation_statistics_update(newfcinfo);
193212
PG_RETURN_VOID();

src/backend/utils/cache/relcache.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1928,6 +1928,7 @@ formrdesc(const char *relationName, Oid relationReltype,
19281928
relation->rd_rel->relpages = 0;
19291929
relation->rd_rel->reltuples = -1;
19301930
relation->rd_rel->relallvisible = 0;
1931+
relation->rd_rel->relallfrozen = 0;
19311932
relation->rd_rel->relkind = RELKIND_RELATION;
19321933
relation->rd_rel->relnatts = (int16) natts;
19331934

@@ -3885,6 +3886,7 @@ RelationSetNewRelfilenumber(Relation relation, char persistence)
38853886
classform->relpages = 0; /* it's empty until further notice */
38863887
classform->reltuples = -1;
38873888
classform->relallvisible = 0;
3889+
classform->relallfrozen = 0;
38883890
}
38893891
classform->relfrozenxid = freezeXid;
38903892
classform->relminmxid = minmulti;

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,6 @@
5757
*/
5858

5959
/* yyyymmddN */
60-
#define CATALOG_VERSION_NO 202502242
60+
#define CATALOG_VERSION_NO 202503031
6161

6262
#endif

src/include/catalog/pg_class.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
6868
/* # of all-visible blocks (not always up-to-date) */
6969
int32 relallvisible BKI_DEFAULT(0);
7070

71+
/* # of all-frozen blocks (not always up-to-date) */
72+
int32 relallfrozen BKI_DEFAULT(0);
73+
7174
/* OID of toast table; 0 if none */
7275
Oid reltoastrelid BKI_DEFAULT(0) BKI_LOOKUP_OPT(pg_class);
7376

src/include/commands/vacuum.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ extern void vac_update_relstats(Relation relation,
349349
BlockNumber num_pages,
350350
double num_tuples,
351351
BlockNumber num_all_visible_pages,
352+
BlockNumber num_all_frozen_pages,
352353
bool hasindex,
353354
TransactionId frozenxid,
354355
MultiXactId minmulti,

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