Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3df51ca

Browse files
committed
Fix CLUSTER progress reporting of number of blocks scanned.
Previously pg_stat_progress_cluster view reported the current block number in heap scan as the number of heap blocks scanned (i.e., heap_blks_scanned). This reported number could be incorrect when synchronize_seqscans is enabled, because it allowed the heap scan to start at block in middle. This could result in wraparounds in the heap_blks_scanned column when the heap scan wrapped around. This commit fixes the bug by calculating the number of blocks from the block that the heap scan starts at to the current block in scan, and reporting that number in the heap_blks_scanned column. Also, in pg_stat_progress_cluster view, previously heap_blks_scanned could not reach heap_blks_total at the end of heap scan phase if the last pages scanned were empty. This commit fixes the bug by manually updating heap_blks_scanned to the same value as heap_blks_total when the heap scan phase finishes. Back-patch to v12 where pg_stat_progress_cluster view was introduced. Reported-by: Matthias van de Meent Author: Matthias van de Meent Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CAEze2WjCBWSGkVfYag001Rc4+-nNLDpWM7QbyD6yPvuhKs-gYQ@mail.gmail.com
1 parent ef848f4 commit 3df51ca

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

src/backend/access/heap/heapam_handler.c

+27-2
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
698698
Datum *values;
699699
bool *isnull;
700700
BufferHeapTupleTableSlot *hslot;
701+
BlockNumber prev_cblock = InvalidBlockNumber;
701702

702703
/* Remember if it's a system catalog */
703704
is_system_catalog = IsSystemRelation(OldHeap);
@@ -793,14 +794,38 @@ heapam_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap,
793794
else
794795
{
795796
if (!table_scan_getnextslot(tableScan, ForwardScanDirection, slot))
797+
{
798+
/*
799+
* If the last pages of the scan were empty, we would go to
800+
* the next phase while heap_blks_scanned != heap_blks_total.
801+
* Instead, to ensure that heap_blks_scanned is equivalent to
802+
* total_heap_blks after the table scan phase, this parameter
803+
* is manually updated to the correct value when the table
804+
* scan finishes.
805+
*/
806+
pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_BLKS_SCANNED,
807+
heapScan->rs_nblocks);
796808
break;
809+
}
797810

798811
/*
799812
* In scan-and-sort mode and also VACUUM FULL, set heap blocks
800813
* scanned
814+
*
815+
* Note that heapScan may start at an offset and wrap around, i.e.
816+
* rs_startblock may be >0, and rs_cblock may end with a number
817+
* below rs_startblock. To prevent showing this wraparound to the
818+
* user, we offset rs_cblock by rs_startblock (modulo rs_nblocks).
801819
*/
802-
pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_BLKS_SCANNED,
803-
heapScan->rs_cblock + 1);
820+
if (prev_cblock != heapScan->rs_cblock)
821+
{
822+
pgstat_progress_update_param(PROGRESS_CLUSTER_HEAP_BLKS_SCANNED,
823+
(heapScan->rs_cblock +
824+
heapScan->rs_nblocks -
825+
heapScan->rs_startblock
826+
) % heapScan->rs_nblocks + 1);
827+
prev_cblock = heapScan->rs_cblock;
828+
}
804829
}
805830

806831
tuple = ExecFetchSlotHeapTuple(slot, false, NULL);

0 commit comments

Comments
 (0)