Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+20
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

+14-4
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

+2
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

+9-3
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

+6-6
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

+5
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

+6
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

+24-5
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

+2
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

+1-1
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

+3
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

+1
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)