]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
tools/cephfs_mirror: Don't use blockdiff on smaller files
authorKotresh HR <khiremat@redhat.com>
Sun, 15 Feb 2026 09:37:09 +0000 (15:07 +0530)
committerKotresh HR <khiremat@redhat.com>
Sat, 21 Feb 2026 20:03:59 +0000 (01:33 +0530)
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 <khiremat@redhat.com>
src/common/options/cephfs-mirror.yaml.in
src/tools/cephfs_mirror/PeerReplayer.cc
src/tools/cephfs_mirror/PeerReplayer.h

index 33817d70641f98bbb84f2e798b301a47589871ba..67f3b0ffe54d98996fa64fd7c39e18e30657af38 100644 (file)
@@ -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
index 7b5ac695355c9316fd6919372f6d18a3a1d8e67e..f478ffc0dd304e845d5dcd93e7ed497fcc73891f 100644 (file)
@@ -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<std::chrono::seconds>(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<Option::size_t>(
+                                     "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<Snapshot> prev = boost::none;
     if (last_snap_id != 0) {
       prev = std::make_pair(last_snap_name, last_snap_id);
index bbc2e3c9f825848ce80b684b1fa384fb7bf73bf0..8f170d738169eb400ccd34146a6a45e405346426 100644 (file)
@@ -515,6 +515,8 @@ private:
   ceph::condition_variable smq_cv;
   std::deque<std::shared_ptr<SyncMechanism>> syncm_q;
 
+  uint64_t blockdiff_min_file_size = 0;
+
   ServiceDaemonStats m_service_daemon_stats;
 
   PerfCounters *m_perf_counters;