Skip to content

Commit 35192f0

Browse files
committed
Have VACUUM log number of skipped pages due to pins
Author: Jim Nasby, some kibitzing by Heikki Linnankangas. Discussion leading to current behavior and precise wording fueled by thoughts from Robert Haas and Andres Freund.
1 parent 4a14f13 commit 35192f0

File tree

2 files changed

+72
-28
lines changed

2 files changed

+72
-28
lines changed

doc/src/sgml/ref/vacuum.sgml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ DETAIL: CPU 0.01s/0.06u sec elapsed 0.07 sec.
252252
INFO: "onek": found 3000 removable, 1000 nonremovable tuples in 143 pages
253253
DETAIL: 0 dead tuples cannot be removed yet.
254254
There were 0 unused item pointers.
255+
Skipped 0 pages due to buffer pins.
255256
0 pages are entirely empty.
256257
CPU 0.07s/0.39u sec elapsed 1.56 sec.
257258
INFO: analyzing "public.onek"

src/backend/commands/vacuumlazy.c

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ typedef struct LVRelStats
105105
BlockNumber old_rel_pages; /* previous value of pg_class.relpages */
106106
BlockNumber rel_pages; /* total number of pages */
107107
BlockNumber scanned_pages; /* number of pages we examined */
108+
BlockNumber pinned_pages; /* # of pages we could not initially lock */
108109
double scanned_tuples; /* counts only tuples on scanned pages */
109110
double old_rel_tuples; /* previous value of pg_class.reltuples */
110111
double new_rel_tuples; /* new estimated total # of tuples */
@@ -332,6 +333,7 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
332333
TimestampDifferenceExceeds(starttime, endtime,
333334
Log_autovacuum_min_duration))
334335
{
336+
StringInfoData buf;
335337
TimestampDifference(starttime, endtime, &secs, &usecs);
336338

337339
read_rate = 0;
@@ -343,27 +345,47 @@ lazy_vacuum_rel(Relation onerel, VacuumStmt *vacstmt,
343345
write_rate = (double) BLCKSZ *VacuumPageDirty / (1024 * 1024) /
344346
(secs + usecs / 1000000.0);
345347
}
348+
349+
/*
350+
* This is pretty messy, but we split it up so that we can skip
351+
* emitting individual parts of the message when not applicable.
352+
*/
353+
initStringInfo(&buf);
354+
appendStringInfo(&buf, _("automatic vacuum of table \"%s.%s.%s\": index scans: %d\n"),
355+
get_database_name(MyDatabaseId),
356+
get_namespace_name(RelationGetNamespace(onerel)),
357+
RelationGetRelationName(onerel),
358+
vacrelstats->num_index_scans);
359+
appendStringInfo(&buf, _("pages: %d removed, %d remain\n"),
360+
vacrelstats->pages_removed,
361+
vacrelstats->rel_pages);
362+
if (vacrelstats->pinned_pages > 0)
363+
{
364+
if (scan_all)
365+
appendStringInfo(&buf, _("waited for %d buffer pins\n"),
366+
vacrelstats->pinned_pages);
367+
else
368+
appendStringInfo(&buf,
369+
_("skipped %d pages due to buffer pins\n"),
370+
vacrelstats->pinned_pages);
371+
}
372+
appendStringInfo(&buf,
373+
_("tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable\n"),
374+
vacrelstats->tuples_deleted,
375+
vacrelstats->new_rel_tuples,
376+
vacrelstats->new_dead_tuples);
377+
appendStringInfo(&buf,
378+
_("buffer usage: %d hits, %d misses, %d dirtied\n"),
379+
VacuumPageHit,
380+
VacuumPageMiss,
381+
VacuumPageDirty);
382+
appendStringInfo(&buf, _("avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n"),
383+
read_rate, write_rate);
384+
appendStringInfo(&buf, _("system usage: %s"), pg_rusage_show(&ru0));
385+
346386
ereport(LOG,
347-
(errmsg("automatic vacuum of table \"%s.%s.%s\": index scans: %d\n"
348-
"pages: %d removed, %d remain\n"
349-
"tuples: %.0f removed, %.0f remain, %.0f are dead but not yet removable\n"
350-
"buffer usage: %d hits, %d misses, %d dirtied\n"
351-
"avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n"
352-
"system usage: %s",
353-
get_database_name(MyDatabaseId),
354-
get_namespace_name(RelationGetNamespace(onerel)),
355-
RelationGetRelationName(onerel),
356-
vacrelstats->num_index_scans,
357-
vacrelstats->pages_removed,
358-
vacrelstats->rel_pages,
359-
vacrelstats->tuples_deleted,
360-
vacrelstats->new_rel_tuples,
361-
vacrelstats->new_dead_tuples,
362-
VacuumPageHit,
363-
VacuumPageMiss,
364-
VacuumPageDirty,
365-
read_rate, write_rate,
366-
pg_rusage_show(&ru0))));
387+
(errmsg_internal("%s", buf.data)));
388+
pfree(buf.data);
367389
}
368390
}
369391
}
@@ -438,6 +460,7 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
438460
BlockNumber next_not_all_visible_block;
439461
bool skipping_all_visible_blocks;
440462
xl_heap_freeze_tuple *frozen;
463+
StringInfoData buf;
441464

442465
pg_rusage_init(&ru0);
443466

@@ -611,6 +634,8 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
611634
/* We need buffer cleanup lock so that we can prune HOT chains. */
612635
if (!ConditionalLockBufferForCleanup(buf))
613636
{
637+
vacrelstats->pinned_pages++;
638+
614639
/*
615640
* If we're not scanning the whole relation to guard against XID
616641
* wraparound, it's OK to skip vacuuming a page. The next vacuum
@@ -1094,19 +1119,37 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
10941119
RelationGetRelationName(onerel),
10951120
tups_vacuumed, vacuumed_pages)));
10961121

1122+
/*
1123+
* This is pretty messy, but we split it up so that we can skip emitting
1124+
* individual parts of the message when not applicable.
1125+
*/
1126+
initStringInfo(&buf);
1127+
appendStringInfo(&buf,
1128+
_("%.0f dead row versions cannot be removed yet.\n"),
1129+
nkeep);
1130+
appendStringInfo(&buf, _("There were %.0f unused item pointers.\n"),
1131+
nunused);
1132+
if (vacrelstats->pinned_pages > 0)
1133+
{
1134+
if (scan_all)
1135+
appendStringInfo(&buf, _("Waited for %d buffer pins.\n"),
1136+
vacrelstats->pinned_pages);
1137+
else
1138+
appendStringInfo(&buf, _("Skipped %u pages due to buffer pins.\n"),
1139+
vacrelstats->pinned_pages);
1140+
}
1141+
appendStringInfo(&buf, _("%u pages are entirely empty.\n"),
1142+
empty_pages);
1143+
appendStringInfo(&buf, _("%s."),
1144+
pg_rusage_show(&ru0));
1145+
10971146
ereport(elevel,
10981147
(errmsg("\"%s\": found %.0f removable, %.0f nonremovable row versions in %u out of %u pages",
10991148
RelationGetRelationName(onerel),
11001149
tups_vacuumed, num_tuples,
11011150
vacrelstats->scanned_pages, nblocks),
1102-
errdetail("%.0f dead row versions cannot be removed yet.\n"
1103-
"There were %.0f unused item pointers.\n"
1104-
"%u pages are entirely empty.\n"
1105-
"%s.",
1106-
nkeep,
1107-
nunused,
1108-
empty_pages,
1109-
pg_rusage_show(&ru0))));
1151+
errdetail_internal("%s", buf.data)));
1152+
pfree(buf.data);
11101153
}
11111154

11121155

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