Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit047f205

Browse files
committed
Fix a missed case in code for "moving average" estimate of reltuples.
It is possible for VACUUM to scan no pages at all, if the visibility mapshows that all pages are all-visible. In this situation VACUUM has no newinformation to report about the relation's tuple density, so it wasn'tchanging pg_class.reltuples ... but it updated pg_class.relpages anyway.That's wrong in general, since there is no evidence to justify changing thedensity ratio reltuples/relpages, but it's particularly bad if the previousstate was relpages=reltuples=0, which means "unknown tuple density".We just replaced "unknown" with "zero". ANALYZE would eventually recoverfrom this, but it could take a lot of repetitions of ANALYZE to do so ifthe relation size is much larger than the maximum number of pages ANALYZEwill scan, because of the moving-average behavior introduced by commitb4b6923.The only known situation where we could have relpages=reltuples=0 and yetthe visibility map asserts everything's visible is immediately followinga pg_upgrade. It might be advisable for pg_upgrade to try to preserve therelpages/reltuples statistics; but in any case this code is wrong on itsown terms, so fix it. Per report from Sergey Koposov.Back-patch to 8.4, where the visibility map was introduced, same as theprevious change.
1 parent2de0fde commit047f205

File tree

3 files changed

+38
-12
lines changed

3 files changed

+38
-12
lines changed

‎src/backend/commands/vacuum.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,10 @@ vac_estimate_reltuples(Relation relation, bool is_analyze,
485485
returnscanned_tuples;
486486

487487
/*
488-
* If scanned_pages is zero but total_pages isn't, keep the existing
489-
* value of reltuples.
488+
* If scanned_pages is zero but total_pages isn't, keep the existing value
489+
* of reltuples. (Note: callers should avoid updating the pg_class
490+
* statistics in this situation, since no new information has been
491+
* provided.)
490492
*/
491493
if (scanned_pages==0)
492494
returnold_rel_tuples;

‎src/backend/commands/vacuumlazy.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ typedef struct LVRelStats
8484
/* hasindex = true means two-pass strategy; false means one-pass */
8585
boolhasindex;
8686
/* Overall statistics about rel */
87+
BlockNumberold_rel_pages;/* previous value of pg_class.relpages */
8788
BlockNumberrel_pages;/* total number of pages */
8889
BlockNumberscanned_pages;/* number of pages we examined */
8990
doublescanned_tuples;/* counts only tuples on scanned pages */
@@ -154,6 +155,9 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
154155
TimestampTzstarttime=0;
155156
boolscan_all;
156157
TransactionIdfreezeTableLimit;
158+
BlockNumbernew_rel_pages;
159+
doublenew_rel_tuples;
160+
TransactionIdnew_frozen_xid;
157161

158162
pg_rusage_init(&ru0);
159163

@@ -176,6 +180,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
176180

177181
vacrelstats= (LVRelStats*)palloc0(sizeof(LVRelStats));
178182

183+
vacrelstats->old_rel_pages=onerel->rd_rel->relpages;
179184
vacrelstats->old_rel_tuples=onerel->rd_rel->reltuples;
180185
vacrelstats->num_index_scans=0;
181186

@@ -205,20 +210,39 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
205210
FreeSpaceMapVacuum(onerel);
206211

207212
/*
208-
* Update statistics in pg_class. But don't change relfrozenxid if we
209-
* skipped any pages.
213+
* Update statistics in pg_class.
214+
*
215+
* A corner case here is that if we scanned no pages at all because every
216+
* page is all-visible, we should not update relpages/reltuples, because
217+
* we have no new information to contribute. In particular this keeps
218+
* us from replacing relpages=reltuples=0 (which means "unknown tuple
219+
* density") with nonzero relpages and reltuples=0 (which means "zero
220+
* tuple density") unless there's some actual evidence for the latter.
221+
*
222+
* Also, don't change relfrozenxid if we skipped any pages, since then
223+
* we don't know for certain that all tuples have a newer xmin.
210224
*/
225+
new_rel_pages=vacrelstats->rel_pages;
226+
new_rel_tuples=vacrelstats->new_rel_tuples;
227+
if (vacrelstats->scanned_pages==0&&new_rel_pages>0)
228+
{
229+
new_rel_pages=vacrelstats->old_rel_pages;
230+
new_rel_tuples=vacrelstats->old_rel_tuples;
231+
}
232+
233+
new_frozen_xid=FreezeLimit;
234+
if (vacrelstats->scanned_pages<vacrelstats->rel_pages)
235+
new_frozen_xid=InvalidTransactionId;
236+
211237
vac_update_relstats(onerel,
212-
vacrelstats->rel_pages,vacrelstats->new_rel_tuples,
238+
new_rel_pages,new_rel_tuples,
213239
vacrelstats->hasindex,
214-
(vacrelstats->scanned_pages<vacrelstats->rel_pages) ?
215-
InvalidTransactionId :
216-
FreezeLimit);
240+
new_frozen_xid);
217241

218242
/* report results to the stats collector, too */
219243
pgstat_report_vacuum(RelationGetRelid(onerel),
220244
onerel->rd_rel->relisshared,
221-
vacrelstats->new_rel_tuples);
245+
new_rel_tuples);
222246

223247
/* and log the action if appropriate */
224248
if (IsAutoVacuumWorkerProcess()&&Log_autovacuum_min_duration >=0)
@@ -238,7 +262,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
238262
vacrelstats->pages_removed,
239263
vacrelstats->rel_pages,
240264
vacrelstats->tuples_deleted,
241-
vacrelstats->new_rel_tuples,
265+
new_rel_tuples,
242266
pg_rusage_show(&ru0))));
243267
}
244268
}

‎src/backend/utils/cache/relcache.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1454,8 +1454,8 @@ formrdesc(const char *relationName, Oid relationReltype,
14541454
*/
14551455
relation->rd_rel->relistemp= false;
14561456

1457-
relation->rd_rel->relpages=1;
1458-
relation->rd_rel->reltuples=1;
1457+
relation->rd_rel->relpages=0;
1458+
relation->rd_rel->reltuples=0;
14591459
relation->rd_rel->relkind=RELKIND_RELATION;
14601460
relation->rd_rel->relhasoids=hasoids;
14611461
relation->rd_rel->relnatts= (int16)natts;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp