On Wed, Mar 10, 2021, at 12:46 AM, Masahiko Sawada wrote: > Attached a patch. I've slightly modified the format for consistency > with heap statistics. Since commit 5f8727f5a6, this patch doesn't apply anymore. Fortunately, it is just a small hunk. I reviewed this patch and it looks good to me. There is just a small issue (double space after 'if') that I fixed in the attached version.
-- Euler Taveira EDB https://www.enterprisedb.com/
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 8341879d89..35be34ea06 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -314,6 +314,7 @@ typedef struct LVRelStats int num_index_scans; TransactionId latestRemovedXid; bool lock_waiter_detected; + IndexBulkDeleteResult **indstats; /* used for autovacuum logs */ /* Used for error callback */ char *indname; @@ -531,9 +532,6 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params, /* Do the vacuuming */ lazy_scan_heap(onerel, params, vacrelstats, Irel, nindexes, aggressive); - /* Done with indexes */ - vac_close_indexes(nindexes, Irel, NoLock); - /* * Compute whether we actually scanned the all unfrozen pages. If we did, * we can adjust relfrozenxid and relminmxid. @@ -614,13 +612,18 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params, pgstat_progress_end_command(); /* and log the action if appropriate */ - if (IsAutoVacuumWorkerProcess() && params->log_min_duration >= 0) + if (IsAutoVacuumWorkerProcess()) { - TimestampTz endtime = GetCurrentTimestamp(); + TimestampTz endtime = 0; + int i; - if (params->log_min_duration == 0 || - TimestampDifferenceExceeds(starttime, endtime, - params->log_min_duration)) + if (params->log_min_duration >= 0) + endtime = GetCurrentTimestamp(); + + if (endtime > 0 && + (params->log_min_duration == 0 || + TimestampDifferenceExceeds(starttime, endtime, + params->log_min_duration))) { StringInfoData buf; char *msgfmt; @@ -680,6 +683,21 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params, (long long) VacuumPageHit, (long long) VacuumPageMiss, (long long) VacuumPageDirty); + for (i = 0; i < nindexes; i++) + { + IndexBulkDeleteResult *stats = vacrelstats->indstats[i]; + + if (!stats) + continue; + + appendStringInfo(&buf, + _("index \"%s\": pages: %u remain, %u newly deleted, %u currently deleted, %u reusable\n"), + RelationGetRelationName(Irel[i]), + stats->num_pages, + stats->pages_newly_deleted, + stats->pages_deleted, + stats->pages_free); + } appendStringInfo(&buf, _("avg read rate: %.3f MB/s, avg write rate: %.3f MB/s\n"), read_rate, write_rate); if (track_io_timing) @@ -704,7 +722,17 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params, (errmsg_internal("%s", buf.data))); pfree(buf.data); } + + /* Cleanup index statistics */ + for (i = 0; i < nindexes; i++) + { + if (vacrelstats->indstats[i]) + pfree(vacrelstats->indstats[i]); + } } + + /* Done with indexes */ + vac_close_indexes(nindexes, Irel, NoLock); } /* @@ -1758,7 +1786,10 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, /* Update index statistics */ if (vacrelstats->useindex) + { update_index_statistics(Irel, indstats, nindexes); + vacrelstats->indstats = indstats; + } /* If no indexes, make log report that lazy_vacuum_heap would've made */ if (vacuumed_pages) @@ -3243,7 +3274,13 @@ update_index_statistics(Relation *Irel, IndexBulkDeleteResult **stats, InvalidTransactionId, InvalidMultiXactId, false); - pfree(stats[i]); + + /* + * Autovacuum worker keeps the index statistics until the end + * of lazy vacuum for autovacuum logs. + */ + if (!IsAutoVacuumWorkerProcess()) + pfree(stats[i]); } }