From: Justin Pryzby Date: Thu, 19 Mar 2020 15:21:22 -0500 Subject: [PATCH v28 2/5] Save the values of the callback.. ..allowing them to be restored later, rather than setting phase=UNKNOWN. --- src/backend/access/heap/vacuumlazy.c | 74 +++++++++++++++++----------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 768a69120b..141a50e968 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -378,7 +378,8 @@ static LVSharedIndStats *get_indstats(LVShared *lvshared, int n); static bool skip_parallel_vacuum_index(Relation indrel, LVShared *lvshared); static void vacuum_error_callback(void *arg); static void update_vacuum_error_cbarg(LVRelStats *errcbarg, int phase, - BlockNumber blkno, char *indname); + BlockNumber blkno, char *indname, + bool free_oldindname); /* @@ -892,7 +893,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, /* Setup error traceback support for ereport() */ update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_SCAN_HEAP, - InvalidBlockNumber, NULL); + InvalidBlockNumber, NULL, false); errcallback.callback = vacuum_error_callback; errcallback.arg = vacrelstats; errcallback.previous = error_context_stack; @@ -924,7 +925,7 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_SCANNED, blkno); update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_SCAN_HEAP, - blkno, NULL); + blkno, NULL, false); if (blkno == next_unskippable_block) { @@ -1044,10 +1045,6 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, /* Report that we are once again scanning the heap */ pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_SCAN_HEAP); - - /* Set the error context while continuing heap scan */ - update_vacuum_error_cbarg(vacrelstats, - VACUUM_ERRCB_PHASE_SCAN_HEAP, blkno, NULL); } /* @@ -1494,10 +1491,6 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats, lazy_vacuum_page(onerel, blkno, buf, 0, vacrelstats, &vmbuffer); vacuumed_pages++; has_dead_tuples = false; - - /* Set the error context while continuing heap scan */ - update_vacuum_error_cbarg(vacrelstats, - VACUUM_ERRCB_PHASE_SCAN_HEAP, blkno, NULL); } else { @@ -1816,14 +1809,16 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats) int npages; PGRUsage ru0; Buffer vmbuffer = InvalidBuffer; + LVRelStats olderrcbarg; /* Report that we are now vacuuming the heap */ pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_VACUUM_HEAP); /* Setup error traceback support for ereport() */ + olderrcbarg = *vacrelstats; update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_VACUUM_HEAP, - InvalidBlockNumber, NULL); + InvalidBlockNumber, NULL, false); pg_rusage_init(&ru0); npages = 0; @@ -1874,8 +1869,10 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats) /* Clear the error traceback phase */ update_vacuum_error_cbarg(vacrelstats, - VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber, - NULL); + olderrcbarg.phase, + olderrcbarg.blkno, + olderrcbarg.indname, + true); } /* @@ -1898,12 +1895,14 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, int uncnt = 0; TransactionId visibility_cutoff_xid; bool all_frozen; + LVRelStats olderrcbarg; pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_BLKS_VACUUMED, blkno); /* Setup error traceback support for ereport() */ + olderrcbarg = *vacrelstats; update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_VACUUM_HEAP, - blkno, NULL); + blkno, NULL, false); START_CRIT_SECTION(); @@ -1983,9 +1982,10 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer, /* Clear the error traceback phase */ update_vacuum_error_cbarg(vacrelstats, - VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber, - NULL); - + olderrcbarg.phase, + olderrcbarg.blkno, + olderrcbarg.indname, + true); return tupindex; } @@ -2383,6 +2383,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats, IndexVacuumInfo ivinfo; const char *msg; PGRUsage ru0; + LVRelStats olderrcbarg; pg_rusage_init(&ru0); @@ -2395,9 +2396,12 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats, ivinfo.strategy = vac_strategy; /* Setup error traceback support for ereport() */ + olderrcbarg = *vacrelstats; update_vacuum_error_cbarg(vacrelstats, - VACUUM_ERRCB_PHASE_VACUUM_INDEX, InvalidBlockNumber, - RelationGetRelationName(indrel)); + VACUUM_ERRCB_PHASE_VACUUM_INDEX, + InvalidBlockNumber, + RelationGetRelationName(indrel), + false); /* Do bulk deletion */ *stats = index_bulk_delete(&ivinfo, *stats, @@ -2416,8 +2420,10 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats, /* Clear the error traceback phase */ update_vacuum_error_cbarg(vacrelstats, - VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber, - NULL); + olderrcbarg.phase, + olderrcbarg.blkno, + olderrcbarg.indname, + true); } /* @@ -2434,6 +2440,7 @@ lazy_cleanup_index(Relation indrel, IndexVacuumInfo ivinfo; const char *msg; PGRUsage ru0; + LVRelStats olderrcbarg; pg_rusage_init(&ru0); @@ -2447,10 +2454,12 @@ lazy_cleanup_index(Relation indrel, ivinfo.strategy = vac_strategy; /* Setup error traceback support for ereport() */ + olderrcbarg = *vacrelstats; update_vacuum_error_cbarg(vacrelstats, VACUUM_ERRCB_PHASE_INDEX_CLEANUP, InvalidBlockNumber, - RelationGetRelationName(indrel)); + RelationGetRelationName(indrel), + false); *stats = index_vacuum_cleanup(&ivinfo, *stats); @@ -2476,8 +2485,10 @@ lazy_cleanup_index(Relation indrel, /* Clear the error traceback phase */ update_vacuum_error_cbarg(vacrelstats, - VACUUM_ERRCB_PHASE_UNKNOWN, InvalidBlockNumber, - NULL); + olderrcbarg.phase, + olderrcbarg.blkno, + olderrcbarg.indname, + true); } /* @@ -3520,16 +3531,23 @@ vacuum_error_callback(void *arg) } } -/* Update vacuum error callback for current phase, block and index */ +/* + * Update vacuum error callback for current phase, block and index + * + * free_oldindex is true if the previous "indname" should be freed. It must be + * false if the caller has copied the old LVRelSTats, to avoid keeping a + * pointer to a freed allocation. In which case, the caller should call again + * with free_oldindname=true to avoid a leak. + */ static void update_vacuum_error_cbarg(LVRelStats *errcbarg, int phase, BlockNumber blkno, - char *indname) + char *indname, bool free_oldindname) { errcbarg->blkno = blkno; errcbarg->phase = phase; /* Free index name from any previous phase */ - if (errcbarg->indname) + if (free_oldindname && errcbarg->indname) pfree(errcbarg->indname); /* For index phases, save the name of the current index for the callback */ -- 2.17.0 --rG8Oha4Ryswg1dZ8 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v28-0003-Drop-reltuples.patch"