mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Improve resilver ETAs
When resilvering the estimated time remaining is calculated using the average issue rate over the current pass. Where the current pass starts when a scan was started, or restarted, if the pool was exported/imported. For dRAID pools in particular this can result in wildly optimistic estimates since the issue rate will be very high while scanning when non-degraded regions of the pool are scanned. Once repair I/O starts being issued performance drops to a realistic number but the estimated performance is still significantly skewed. To address this we redefine a pass such that it starts after a scanning phase completes so the issue rate is more reflective of recent performance. Additionally, the zfs_scan_report_txgs module option can be set to reset the pass statistics more often. Reviewed-by: Akash B <akash-b@hpe.com> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #14410
This commit is contained in:
@@ -131,6 +131,15 @@ static uint64_t dsl_scan_count_data_disks(vdev_t *vd);
|
||||
extern uint_t zfs_vdev_async_write_active_min_dirty_percent;
|
||||
static int zfs_scan_blkstats = 0;
|
||||
|
||||
/*
|
||||
* 'zpool status' uses bytes processed per pass to report throughput and
|
||||
* estimate time remaining. We define a pass to start when the scanning
|
||||
* phase completes for a sequential resilver. Optionally, this value
|
||||
* may be used to reset the pass statistics every N txgs to provide an
|
||||
* estimated completion time based on currently observed performance.
|
||||
*/
|
||||
static uint_t zfs_scan_report_txgs = 0;
|
||||
|
||||
/*
|
||||
* By default zfs will check to ensure it is not over the hard memory
|
||||
* limit before each txg. If finer-grained control of this is needed
|
||||
@@ -604,6 +613,8 @@ dsl_scan_init(dsl_pool_t *dp, uint64_t txg)
|
||||
}
|
||||
|
||||
spa_scan_stat_init(spa);
|
||||
vdev_scan_stat_init(spa->spa_root_vdev);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -763,6 +774,7 @@ dsl_scan_setup_sync(void *arg, dmu_tx_t *tx)
|
||||
scn->scn_last_checkpoint = 0;
|
||||
scn->scn_checkpointing = B_FALSE;
|
||||
spa_scan_stat_init(spa);
|
||||
vdev_scan_stat_init(spa->spa_root_vdev);
|
||||
|
||||
if (DSL_SCAN_IS_SCRUB_RESILVER(scn)) {
|
||||
scn->scn_phys.scn_ddt_class_max = zfs_scrub_ddt_class_max;
|
||||
@@ -3652,6 +3664,16 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disabled by default, set zfs_scan_report_txgs to report
|
||||
* average performance over the last zfs_scan_report_txgs TXGs.
|
||||
*/
|
||||
if (!dsl_scan_is_paused_scrub(scn) && zfs_scan_report_txgs != 0 &&
|
||||
tx->tx_txg % zfs_scan_report_txgs == 0) {
|
||||
scn->scn_issued_before_pass += spa->spa_scan_pass_issued;
|
||||
spa_scan_stat_init(spa);
|
||||
}
|
||||
|
||||
/*
|
||||
* It is possible to switch from unsorted to sorted at any time,
|
||||
* but afterwards the scan will remain sorted unless reloaded from
|
||||
@@ -3780,6 +3802,9 @@ dsl_scan_sync(dsl_pool_t *dp, dmu_tx_t *tx)
|
||||
if (scn->scn_is_sorted) {
|
||||
scn->scn_checkpointing = B_TRUE;
|
||||
scn->scn_clearing = B_TRUE;
|
||||
scn->scn_issued_before_pass +=
|
||||
spa->spa_scan_pass_issued;
|
||||
spa_scan_stat_init(spa);
|
||||
}
|
||||
zfs_dbgmsg("scan complete for %s txg %llu",
|
||||
spa->spa_name,
|
||||
@@ -4507,5 +4532,8 @@ ZFS_MODULE_PARAM(zfs, zfs_, scan_strict_mem_lim, INT, ZMOD_RW,
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, scan_fill_weight, UINT, ZMOD_RW,
|
||||
"Tunable to adjust bias towards more filled segments during scans");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, scan_report_txgs, UINT, ZMOD_RW,
|
||||
"Tunable to report resilver performance over the last N txgs");
|
||||
|
||||
ZFS_MODULE_PARAM(zfs, zfs_, resilver_disable_defer, INT, ZMOD_RW,
|
||||
"Process all resilvers immediately");
|
||||
|
||||
@@ -2556,7 +2556,6 @@ spa_scan_stat_init(spa_t *spa)
|
||||
spa->spa_scan_pass_scrub_spent_paused = 0;
|
||||
spa->spa_scan_pass_exam = 0;
|
||||
spa->spa_scan_pass_issued = 0;
|
||||
vdev_scan_stat_init(spa->spa_root_vdev);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user