]> 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>
Sun, 22 Feb 2026 18:56:35 +0000 (00:26 +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 efecb14b1230263f845a98245168cf8d861a0bc0..5ca410d04a0b2b47e6132de829bcb77ed838ea7e 100644 (file)
@@ -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
index b77936a4e1ff965d74c87e558e03a7426488919a..424026f61f450ac33ac9595232905b6b65fec9d3 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 8472ad0f9afa7cb854c633586684e93bde691d95..10e630e52903618ebc661868a216447ccdc7988f 100644 (file)
@@ -514,6 +514,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;