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

Commit030cdaf

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 parent5795773 commit030cdaf

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

‎src/backend/commands/vacuum.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,9 @@ vac_estimate_reltuples(Relation relation, bool is_analyze,
484484

485485
/*
486486
* If scanned_pages is zero but total_pages isn't, keep the existing value
487-
* of reltuples.
487+
* of reltuples. (Note: callers should avoid updating the pg_class
488+
* statistics in this situation, since no new information has been
489+
* provided.)
488490
*/
489491
if (scanned_pages==0)
490492
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
@@ -1415,8 +1415,8 @@ formrdesc(const char *relationName, Oid relationReltype,
14151415
/* formrdesc is used only for permanent relations */
14161416
relation->rd_rel->relpersistence=RELPERSISTENCE_PERMANENT;
14171417

1418-
relation->rd_rel->relpages=1;
1419-
relation->rd_rel->reltuples=1;
1418+
relation->rd_rel->relpages=0;
1419+
relation->rd_rel->reltuples=0;
14201420
relation->rd_rel->relkind=RELKIND_RELATION;
14211421
relation->rd_rel->relhasoids=hasoids;
14221422
relation->rd_rel->relnatts= (int16)natts;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp