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

Commit5bba65d

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 parentb83bb97 commit5bba65d

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
@@ -493,7 +493,9 @@ vac_estimate_reltuples(Relation relation, bool is_analyze,
493493

494494
/*
495495
* If scanned_pages is zero but total_pages isn't, keep the existing value
496-
* of reltuples.
496+
* of reltuples. (Note: callers should avoid updating the pg_class
497+
* statistics in this situation, since no new information has been
498+
* provided.)
497499
*/
498500
if (scanned_pages==0)
499501
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
/* measure elapsed time iff autovacuum logging requires it */
159163
if (IsAutoVacuumWorkerProcess()&&Log_autovacuum_min_duration >=0)
@@ -178,6 +182,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
178182

179183
vacrelstats= (LVRelStats*)palloc0(sizeof(LVRelStats));
180184

185+
vacrelstats->old_rel_pages=onerel->rd_rel->relpages;
181186
vacrelstats->old_rel_tuples=onerel->rd_rel->reltuples;
182187
vacrelstats->num_index_scans=0;
183188

@@ -207,20 +212,39 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
207212
FreeSpaceMapVacuum(onerel);
208213

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

220244
/* report results to the stats collector, too */
221245
pgstat_report_vacuum(RelationGetRelid(onerel),
222246
onerel->rd_rel->relisshared,
223-
vacrelstats->new_rel_tuples);
247+
new_rel_tuples);
224248

225249
/* and log the action if appropriate */
226250
if (IsAutoVacuumWorkerProcess()&&Log_autovacuum_min_duration >=0)
@@ -240,7 +264,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
240264
vacrelstats->pages_removed,
241265
vacrelstats->rel_pages,
242266
vacrelstats->tuples_deleted,
243-
vacrelstats->new_rel_tuples,
267+
new_rel_tuples,
244268
pg_rusage_show(&ru0))));
245269
}
246270
}

‎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