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=fd9319767a6d064ac01fa234c39d92cdf5811102;p=ceph.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 efecb14b123..5ca410d04a0 100644 --- a/src/common/options/cephfs-mirror.yaml.in +++ b/src/common/options/cephfs-mirror.yaml.in @@ -25,6 +25,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 b77936a4e1f..424026f61f4 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 8472ad0f9af..10e630e5290 100644 --- a/src/tools/cephfs_mirror/PeerReplayer.h +++ b/src/tools/cephfs_mirror/PeerReplayer.h @@ -514,6 +514,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;