@@ -319,6 +319,13 @@ typedef struct LVRelStats
319
319
VacErrPhase phase ;
320
320
} LVRelStats ;
321
321
322
+ /* Struct for saving and restoring vacuum error information. */
323
+ typedef struct LVSavedErrInfo
324
+ {
325
+ BlockNumber blkno ;
326
+ VacErrPhase phase ;
327
+ } LVSavedErrInfo ;
328
+
322
329
/* A few variables that don't seem worth passing around as parameters */
323
330
static int elevel = -1 ;
324
331
@@ -388,8 +395,9 @@ static void end_parallel_vacuum(Relation *Irel, IndexBulkDeleteResult **stats,
388
395
static LVSharedIndStats * get_indstats (LVShared * lvshared , int n );
389
396
static bool skip_parallel_vacuum_index (Relation indrel , LVShared * lvshared );
390
397
static 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 );
393
401
394
402
395
403
/*
@@ -538,8 +546,8 @@ heap_vacuum_rel(Relation onerel, VacuumParams *params,
538
546
* which we add context information to errors, so we don't need to
539
547
* revert to the previous phase.
540
548
*/
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 );
543
551
lazy_truncate_heap (onerel , vacrelstats );
544
552
}
545
553
@@ -948,8 +956,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
948
956
949
957
pgstat_progress_update_param (PROGRESS_VACUUM_HEAP_BLKS_SCANNED , blkno );
950
958
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 );
953
961
954
962
if (blkno == next_unskippable_block )
955
963
{
@@ -1820,16 +1828,15 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
1820
1828
int npages ;
1821
1829
PGRUsage ru0 ;
1822
1830
Buffer vmbuffer = InvalidBuffer ;
1823
- LVRelStats olderrinfo ;
1831
+ LVSavedErrInfo saved_err_info ;
1824
1832
1825
1833
/* Report that we are now vacuuming the heap */
1826
1834
pgstat_progress_update_param (PROGRESS_VACUUM_PHASE ,
1827
1835
PROGRESS_VACUUM_PHASE_VACUUM_HEAP );
1828
1836
1829
1837
/* 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 );
1833
1840
1834
1841
pg_rusage_init (& ru0 );
1835
1842
npages = 0 ;
@@ -1879,10 +1886,7 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
1879
1886
errdetail_internal ("%s" , pg_rusage_show (& ru0 ))));
1880
1887
1881
1888
/* 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 );
1886
1890
}
1887
1891
1888
1892
/*
@@ -1905,14 +1909,13 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
1905
1909
int uncnt = 0 ;
1906
1910
TransactionId visibility_cutoff_xid ;
1907
1911
bool all_frozen ;
1908
- LVRelStats olderrinfo ;
1912
+ LVSavedErrInfo saved_err_info ;
1909
1913
1910
1914
pgstat_progress_update_param (PROGRESS_VACUUM_HEAP_BLKS_VACUUMED , blkno );
1911
1915
1912
1916
/* 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 );
1916
1919
1917
1920
START_CRIT_SECTION ();
1918
1921
@@ -1991,10 +1994,7 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
1991
1994
}
1992
1995
1993
1996
/* 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 );
1998
1998
return tupindex ;
1999
1999
}
2000
2000
@@ -2404,7 +2404,7 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
2404
2404
IndexVacuumInfo ivinfo ;
2405
2405
const char * msg ;
2406
2406
PGRUsage ru0 ;
2407
- LVRelStats olderrinfo ;
2407
+ LVSavedErrInfo saved_err_info ;
2408
2408
2409
2409
pg_rusage_init (& ru0 );
2410
2410
@@ -2416,12 +2416,17 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
2416
2416
ivinfo .num_heap_tuples = reltuples ;
2417
2417
ivinfo .strategy = vac_strategy ;
2418
2418
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 ,
2422
2428
VACUUM_ERRCB_PHASE_VACUUM_INDEX ,
2423
- InvalidBlockNumber ,
2424
- RelationGetRelationName (indrel ));
2429
+ InvalidBlockNumber );
2425
2430
2426
2431
/* Do bulk deletion */
2427
2432
* stats = index_bulk_delete (& ivinfo , * stats ,
@@ -2439,10 +2444,9 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
2439
2444
errdetail_internal ("%s" , pg_rusage_show (& ru0 ))));
2440
2445
2441
2446
/* 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 ;
2446
2450
}
2447
2451
2448
2452
/*
@@ -2459,7 +2463,7 @@ lazy_cleanup_index(Relation indrel,
2459
2463
IndexVacuumInfo ivinfo ;
2460
2464
const char * msg ;
2461
2465
PGRUsage ru0 ;
2462
- LVRelStats olderrcbarg ;
2466
+ LVSavedErrInfo saved_err_info ;
2463
2467
2464
2468
pg_rusage_init (& ru0 );
2465
2469
@@ -2472,20 +2476,25 @@ lazy_cleanup_index(Relation indrel,
2472
2476
ivinfo .num_heap_tuples = reltuples ;
2473
2477
ivinfo .strategy = vac_strategy ;
2474
2478
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 ,
2478
2488
VACUUM_ERRCB_PHASE_INDEX_CLEANUP ,
2479
- InvalidBlockNumber ,
2480
- RelationGetRelationName (indrel ));
2489
+ InvalidBlockNumber );
2481
2490
2482
2491
* stats = index_vacuum_cleanup (& ivinfo , * stats );
2483
2492
2484
2493
/* 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
+
2489
2498
if (!(* stats ))
2490
2499
return ;
2491
2500
@@ -3598,18 +3607,30 @@ vacuum_error_callback(void *arg)
3598
3607
}
3599
3608
}
3600
3609
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
+ */
3602
3614
static 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 )
3605
3617
{
3618
+ if (saved_err_info )
3619
+ {
3620
+ saved_err_info -> blkno = errinfo -> blkno ;
3621
+ saved_err_info -> phase = errinfo -> phase ;
3622
+ }
3623
+
3606
3624
errinfo -> blkno = blkno ;
3607
3625
errinfo -> phase = phase ;
3626
+ }
3608
3627
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 ;
3615
3636
}
0 commit comments