@@ -319,6 +319,13 @@ typedef struct LVRelStats
319319 VacErrPhase phase ;
320320} LVRelStats ;
321321
322+ /* Struct for saving and restoring vacuum error information. */
323+ typedef struct LVSavedErrInfo
324+ {
325+ BlockNumber blkno ;
326+ VacErrPhase phase ;
327+ } LVSavedErrInfo ;
328+
322329/* A few variables that don't seem worth passing around as parameters */
323330static int elevel = -1 ;
324331
@@ -388,8 +395,9 @@ static void end_parallel_vacuum(Relation *Irel, IndexBulkDeleteResult **stats,
388395static LVSharedIndStats * get_indstats (LVShared * lvshared , int n );
389396static bool skip_parallel_vacuum_index (Relation indrel , LVShared * lvshared );
390397static void vacuum_error_callback (void * arg );
391- static void update_vacuum_error_info (LVRelStats * errinfo , int phase ,
392- BlockNumber blkno , char * indname );
398+ static void update_vacuum_error_info (LVRelStats * errinfo , LVSavedErrInfo * saved_err_info ,
399+ int phase , BlockNumber blkno );
400+ static void restore_vacuum_error_info (LVRelStats * errinfo , const LVSavedErrInfo * saved_err_info );
393401
394402
395403/*
@@ -538,8 +546,8 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params,
538546 * which we add context information to errors, so we don't need to
539547 * revert to the previous phase.
540548 */
541- update_vacuum_error_info (vacrelstats , VACUUM_ERRCB_PHASE_TRUNCATE ,
542- vacrelstats -> nonempty_pages , NULL );
549+ update_vacuum_error_info (vacrelstats , NULL , VACUUM_ERRCB_PHASE_TRUNCATE ,
550+ vacrelstats -> nonempty_pages );
543551 lazy_truncate_heap (onerel , vacrelstats );
544552 }
545553
@@ -948,8 +956,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
948956
949957 pgstat_progress_update_param (PROGRESS_VACUUM_HEAP_BLKS_SCANNED , blkno );
950958
951- update_vacuum_error_info (vacrelstats , VACUUM_ERRCB_PHASE_SCAN_HEAP ,
952- blkno , NULL );
959+ update_vacuum_error_info (vacrelstats , NULL , VACUUM_ERRCB_PHASE_SCAN_HEAP ,
960+ blkno );
953961
954962 if (blkno == next_unskippable_block )
955963 {
@@ -1820,16 +1828,15 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
18201828 int npages ;
18211829 PGRUsage ru0 ;
18221830 Buffer vmbuffer = InvalidBuffer ;
1823- LVRelStats olderrinfo ;
1831+ LVSavedErrInfo saved_err_info ;
18241832
18251833 /* Report that we are now vacuuming the heap */
18261834 pgstat_progress_update_param (PROGRESS_VACUUM_PHASE ,
18271835 PROGRESS_VACUUM_PHASE_VACUUM_HEAP );
18281836
18291837 /* Update error traceback information */
1830- olderrinfo = * vacrelstats ;
1831- update_vacuum_error_info (vacrelstats , VACUUM_ERRCB_PHASE_VACUUM_HEAP ,
1832- InvalidBlockNumber , NULL );
1838+ update_vacuum_error_info (vacrelstats , & saved_err_info , VACUUM_ERRCB_PHASE_VACUUM_HEAP ,
1839+ InvalidBlockNumber );
18331840
18341841 pg_rusage_init (& ru0 );
18351842 npages = 0 ;
@@ -1879,10 +1886,7 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
18791886 errdetail_internal ("%s" , pg_rusage_show (& ru0 ))));
18801887
18811888 /* Revert to the previous phase information for error traceback */
1882- update_vacuum_error_info (vacrelstats ,
1883- olderrinfo .phase ,
1884- olderrinfo .blkno ,
1885- olderrinfo .indname );
1889+ restore_vacuum_error_info (vacrelstats , & saved_err_info );
18861890}
18871891
18881892/*
@@ -1905,14 +1909,13 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
19051909 int uncnt = 0 ;
19061910 TransactionId visibility_cutoff_xid ;
19071911 bool all_frozen ;
1908- LVRelStats olderrinfo ;
1912+ LVSavedErrInfo saved_err_info ;
19091913
19101914 pgstat_progress_update_param (PROGRESS_VACUUM_HEAP_BLKS_VACUUMED , blkno );
19111915
19121916 /* Update error traceback information */
1913- olderrinfo = * vacrelstats ;
1914- update_vacuum_error_info (vacrelstats , VACUUM_ERRCB_PHASE_VACUUM_HEAP ,
1915- blkno , NULL );
1917+ update_vacuum_error_info (vacrelstats , & saved_err_info , VACUUM_ERRCB_PHASE_VACUUM_HEAP ,
1918+ blkno );
19161919
19171920 START_CRIT_SECTION ();
19181921
@@ -1991,10 +1994,7 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
19911994 }
19921995
19931996 /* Revert to the previous phase information for error traceback */
1994- update_vacuum_error_info (vacrelstats ,
1995- olderrinfo .phase ,
1996- olderrinfo .blkno ,
1997- olderrinfo .indname );
1997+ restore_vacuum_error_info (vacrelstats , & saved_err_info );
19981998 return tupindex ;
19991999}
20002000
@@ -2404,7 +2404,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
24042404 IndexVacuumInfo ivinfo ;
24052405 const char * msg ;
24062406 PGRUsage ru0 ;
2407- LVRelStats olderrinfo ;
2407+ LVSavedErrInfo saved_err_info ;
24082408
24092409 pg_rusage_init (& ru0 );
24102410
@@ -2416,12 +2416,17 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
24162416 ivinfo .num_heap_tuples = reltuples ;
24172417 ivinfo .strategy = vac_strategy ;
24182418
2419- /* Update error traceback information */
2420- olderrinfo = * vacrelstats ;
2421- update_vacuum_error_info (vacrelstats ,
2419+ /*
2420+ * Update error traceback information.
2421+ *
2422+ * The index name is saved during this phase and restored immediately
2423+ * after this phase. See vacuum_error_callback.
2424+ */
2425+ Assert (vacrelstats -> indname == NULL );
2426+ vacrelstats -> indname = pstrdup (RelationGetRelationName (indrel ));
2427+ update_vacuum_error_info (vacrelstats , & saved_err_info ,
24222428 VACUUM_ERRCB_PHASE_VACUUM_INDEX ,
2423- InvalidBlockNumber ,
2424- RelationGetRelationName (indrel ));
2429+ InvalidBlockNumber );
24252430
24262431 /* Do bulk deletion */
24272432 * stats = index_bulk_delete (& ivinfo , * stats ,
@@ -2439,10 +2444,9 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
24392444 errdetail_internal ("%s" , pg_rusage_show (& ru0 ))));
24402445
24412446 /* Revert to the previous phase information for error traceback */
2442- update_vacuum_error_info (vacrelstats ,
2443- olderrinfo .phase ,
2444- olderrinfo .blkno ,
2445- olderrinfo .indname );
2447+ restore_vacuum_error_info (vacrelstats , & saved_err_info );
2448+ pfree (vacrelstats -> indname );
2449+ vacrelstats -> indname = NULL ;
24462450}
24472451
24482452/*
@@ -2459,7 +2463,7 @@ lazy_cleanup_index(Relation indrel,
24592463 IndexVacuumInfo ivinfo ;
24602464 const char * msg ;
24612465 PGRUsage ru0 ;
2462- LVRelStats olderrcbarg ;
2466+ LVSavedErrInfo saved_err_info ;
24632467
24642468 pg_rusage_init (& ru0 );
24652469
@@ -2472,20 +2476,25 @@ lazy_cleanup_index(Relation indrel,
24722476 ivinfo .num_heap_tuples = reltuples ;
24732477 ivinfo .strategy = vac_strategy ;
24742478
2475- /* Update error traceback information */
2476- olderrcbarg = * vacrelstats ;
2477- update_vacuum_error_info (vacrelstats ,
2479+ /*
2480+ * Update error traceback information.
2481+ *
2482+ * The index name is saved during this phase and restored immediately
2483+ * after this phase. See vacuum_error_callback.
2484+ */
2485+ Assert (vacrelstats -> indname == NULL );
2486+ vacrelstats -> indname = pstrdup (RelationGetRelationName (indrel ));
2487+ update_vacuum_error_info (vacrelstats , & saved_err_info ,
24782488 VACUUM_ERRCB_PHASE_INDEX_CLEANUP ,
2479- InvalidBlockNumber ,
2480- RelationGetRelationName (indrel ));
2489+ InvalidBlockNumber );
24812490
24822491 * stats = index_vacuum_cleanup (& ivinfo , * stats );
24832492
24842493 /* Revert back to the old phase information for error traceback */
2485- update_vacuum_error_info (vacrelstats ,
2486- olderrcbarg . phase ,
2487- olderrcbarg . blkno ,
2488- olderrcbarg . indname );
2494+ restore_vacuum_error_info (vacrelstats , & saved_err_info );
2495+ pfree ( vacrelstats -> indname );
2496+ vacrelstats -> indname = NULL ;
2497+
24892498 if (!(* stats ))
24902499 return ;
24912500
@@ -3598,18 +3607,30 @@ vacuum_error_callback(void *arg)
35983607 }
35993608}
36003609
3601- /* Update vacuum error callback for the current phase, block, and index. */
3610+ /*
3611+ * Updates the information required for vacuum error callback. This also saves
3612+ * the current information which can be later restored via restore_vacuum_error_info.
3613+ */
36023614static void
3603- update_vacuum_error_info (LVRelStats * errinfo , int phase , BlockNumber blkno ,
3604- char * indname )
3615+ update_vacuum_error_info (LVRelStats * errinfo , LVSavedErrInfo * saved_err_info , int phase ,
3616+ BlockNumber blkno )
36053617{
3618+ if (saved_err_info )
3619+ {
3620+ saved_err_info -> blkno = errinfo -> blkno ;
3621+ saved_err_info -> phase = errinfo -> phase ;
3622+ }
3623+
36063624 errinfo -> blkno = blkno ;
36073625 errinfo -> phase = phase ;
3626+ }
36083627
3609- /* Free index name from any previous phase */
3610- if (errinfo -> indname )
3611- pfree (errinfo -> indname );
3612-
3613- /* For index phases, save the name of the current index for the callback */
3614- errinfo -> indname = indname ? pstrdup (indname ) : NULL ;
3628+ /*
3629+ * Restores the vacuum information saved via a prior call to update_vacuum_error_info.
3630+ */
3631+ static void
3632+ restore_vacuum_error_info (LVRelStats * errinfo , const LVSavedErrInfo * saved_err_info )
3633+ {
3634+ errinfo -> blkno = saved_err_info -> blkno ;
3635+ errinfo -> phase = saved_err_info -> phase ;
36153636}
0 commit comments