From: Kotresh HR Date: Sun, 15 Feb 2026 09:37:09 +0000 (+0530) Subject: tools/cephfs_mirror: Don't use blockdiff on smaller files X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=34718c68d34efcef609bf026ae9d59710c941029;p=ceph-ci.git tools/cephfs_mirror: Don't use blockdiff on smaller files Introduce a new configuration option, 'cephfs_mirror_blockdiff_min_file_size', to control the minimum file size above which block-level diff is used during CephFS mirroring. Files smaller than the configured threshold are synchronized using full file copy, while larger files attempt block-level delta sync. This provides better flexibility across environments with varying file size distributions and performance constraints. The default value is set to 16_M (16 MiB). The value is read once at beginning of every snapshot sync. Fixes: https://tracker.ceph.com/issues/73452 Signed-off-by: Kotresh HR --- diff --git a/src/common/options/cephfs-mirror.yaml.in b/src/common/options/cephfs-mirror.yaml.in index 33817d70641..67f3b0ffe54 100644 --- a/src/common/options/cephfs-mirror.yaml.in +++ b/src/common/options/cephfs-mirror.yaml.in @@ -29,6 +29,18 @@ options: services: - cephfs-mirror min: 1 +- name: cephfs_mirror_blockdiff_min_file_size + type: size + level: advanced + desc: minimum file size threshold in bytes above which block-level diff is used during CephFS mirroring. + long_desc: defines the minimum file size, in bytes, required for CephFS mirroring to use block-level + delta synchronization instead of performing a full file copy. When a file’s size is greater than to + this threshold, the mirroring engine attempts to synchronize only the modified block extents between + snapshots. For files smaller than or equal to this value, a full file copy is performed instead, as + block-level diff may not provide meaningful performance benefits for small files. + default: 16_M + services: + - cephfs-mirror - name: cephfs_mirror_action_update_interval type: secs level: advanced diff --git a/src/tools/cephfs_mirror/PeerReplayer.cc b/src/tools/cephfs_mirror/PeerReplayer.cc index 7b5ac695355..f478ffc0dd3 100644 --- a/src/tools/cephfs_mirror/PeerReplayer.cc +++ b/src/tools/cephfs_mirror/PeerReplayer.cc @@ -1700,7 +1700,7 @@ int PeerReplayer::SnapDiffSync::get_changed_blocks(const std::string &epath, dout(20) << ": dir_root=" << m_dir_root << ", epath=" << epath << ", sync_check=" << sync_check << dendl; - if (!sync_check) { + if (!sync_check || stx.stx_size <= m_peer_replayer.blockdiff_min_file_size) { return SyncMechanism::get_changed_blocks(epath, stx, sync_check, callback); } @@ -2146,6 +2146,7 @@ int PeerReplayer::do_sync_snaps(const std::string &dir_root) { double start = 0; double end = 0; double duration = 0; + uint64_t blockdiff_min_file_size_conf = 0; for (; it != local_snap_map.end(); ++it) { if (m_perf_counters) { start = std::chrono::duration_cast(clock::now().time_since_epoch()).count(); @@ -2154,6 +2155,17 @@ int PeerReplayer::do_sync_snaps(const std::string &dir_root) { m_perf_counters->tset(l_cephfs_mirror_peer_replayer_last_synced_start, t); } set_current_syncing_snap(dir_root, it->first, it->second); + // Check for blockdiff_min_file_size config change at the beginning of snapshot sync + blockdiff_min_file_size_conf = g_ceph_context->_conf.get_val( + "cephfs_mirror_blockdiff_min_file_size"); + { + std::scoped_lock locker(m_lock); + if (blockdiff_min_file_size != blockdiff_min_file_size_conf) { + dout(10) << ": blockdiff_min_file_size changed" << " old=" << blockdiff_min_file_size + << " new=" << blockdiff_min_file_size_conf << dendl; + blockdiff_min_file_size = blockdiff_min_file_size_conf; + } + } boost::optional prev = boost::none; if (last_snap_id != 0) { prev = std::make_pair(last_snap_name, last_snap_id); diff --git a/src/tools/cephfs_mirror/PeerReplayer.h b/src/tools/cephfs_mirror/PeerReplayer.h index bbc2e3c9f82..8f170d73816 100644 --- a/src/tools/cephfs_mirror/PeerReplayer.h +++ b/src/tools/cephfs_mirror/PeerReplayer.h @@ -515,6 +515,8 @@ private: ceph::condition_variable smq_cv; std::deque> syncm_q; + uint64_t blockdiff_min_file_size = 0; + ServiceDaemonStats m_service_daemon_stats; PerfCounters *m_perf_counters;