]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/rocksdb/utilities/option_change_migration/option_change_migration.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / utilities / option_change_migration / option_change_migration.cc
index f2382297bf30765fc2e47c32c6f055a87daf82ff..e93d2152dc1f97f0a8b19b320545bc4e6f1995db 100644 (file)
@@ -35,18 +35,26 @@ Status OpenDb(const Options& options, const std::string& dbname,
   return s;
 }
 
+// l0_file_size specifies size of file on L0. Files will be range partitioned
+// after a full compaction so they are likely qualified to put on L0. If
+// left as 0, the files are compacted in a single file and put to L0. Otherwise,
+// will try to compact the files as size l0_file_size.
 Status CompactToLevel(const Options& options, const std::string& dbname,
-                      int dest_level, bool need_reopen) {
+                      int dest_level, uint64_t l0_file_size, bool need_reopen) {
   std::unique_ptr<DB> db;
   Options no_compact_opts = GetNoCompactionOptions(options);
   if (dest_level == 0) {
+    if (l0_file_size == 0) {
+      // Single file.
+      l0_file_size = 999999999999999;
+    }
     // L0 has strict sequenceID requirements to files to it. It's safer
     // to only put one compacted file to there.
     // This is only used for converting to universal compaction with
     // only one level. In this case, compacting to one file is also
     // optimal.
-    no_compact_opts.target_file_size_base = 999999999999999;
-    no_compact_opts.max_compaction_bytes = 999999999999999;
+    no_compact_opts.target_file_size_base = l0_file_size;
+    no_compact_opts.max_compaction_bytes = l0_file_size;
   }
   Status s = OpenDb(no_compact_opts, dbname, &db);
   if (!s.ok()) {
@@ -60,9 +68,9 @@ Status CompactToLevel(const Options& options, const std::string& dbname,
     // generate one output file
     cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
   }
-  db->CompactRange(cro, nullptr, nullptr);
+  s = db->CompactRange(cro, nullptr, nullptr);
 
-  if (need_reopen) {
+  if (s.ok() && need_reopen) {
     // Need to restart DB to rewrite the manifest file.
     // In order to open a DB with specific num_levels, the manifest file should
     // contain no record that mentiones any level beyond num_levels. Issuing a
@@ -98,7 +106,8 @@ Status MigrateToUniversal(std::string dbname, const Options& old_opts,
       }
     }
     if (need_compact) {
-      return CompactToLevel(old_opts, dbname, new_opts.num_levels - 1, true);
+      return CompactToLevel(old_opts, dbname, new_opts.num_levels - 1,
+                            /*l0_file_size=*/0, true);
     }
     return Status::OK();
   }
@@ -119,7 +128,7 @@ Status MigrateToLevelBase(std::string dbname, const Options& old_opts,
     // multiplier from 4 to 8, with the same data, we will have fewer
     // levels. Unless we issue a full comaction, the LSM tree may stuck
     // with more levels than needed and it won't recover automatically.
-    return CompactToLevel(opts, dbname, 1, true);
+    return CompactToLevel(opts, dbname, 1, /*l0_file_size=*/0, true);
   } else {
     // Compact everything to the last level to guarantee it can be safely
     // opened.
@@ -127,11 +136,13 @@ Status MigrateToLevelBase(std::string dbname, const Options& old_opts,
       return Status::OK();
     } else if (new_opts.num_levels > old_opts.num_levels) {
       // Dynamic level mode requires data to be put in the last level first.
-      return CompactToLevel(new_opts, dbname, new_opts.num_levels - 1, false);
+      return CompactToLevel(new_opts, dbname, new_opts.num_levels - 1,
+                            /*l0_file_size=*/0, false);
     } else {
       Options opts = old_opts;
       opts.target_file_size_base = new_opts.target_file_size_base;
-      return CompactToLevel(opts, dbname, new_opts.num_levels - 1, true);
+      return CompactToLevel(opts, dbname, new_opts.num_levels - 1,
+                            /*l0_file_size=*/0, true);
     }
   }
 }
@@ -140,7 +151,7 @@ Status MigrateToLevelBase(std::string dbname, const Options& old_opts,
 Status OptionChangeMigration(std::string dbname, const Options& old_opts,
                              const Options& new_opts) {
   if (old_opts.compaction_style == CompactionStyle::kCompactionStyleFIFO) {
-    // LSM generated by FIFO compation can be opened by any compaction.
+    // LSM generated by FIFO compaction can be opened by any compaction.
     return Status::OK();
   } else if (new_opts.compaction_style ==
              CompactionStyle::kCompactionStyleUniversal) {
@@ -150,7 +161,14 @@ Status OptionChangeMigration(std::string dbname, const Options& old_opts,
     return MigrateToLevelBase(dbname, old_opts, new_opts);
   } else if (new_opts.compaction_style ==
              CompactionStyle::kCompactionStyleFIFO) {
-    return CompactToLevel(old_opts, dbname, 0, true);
+    uint64_t l0_file_size = 0;
+    if (new_opts.compaction_options_fifo.max_table_files_size > 0) {
+      // Create at least 8 files when max_table_files_size hits, so that the DB
+      // doesn't just disappear. This in fact violates the FIFO condition, but
+      // otherwise, the migrated DB is unlikley to be usable.
+      l0_file_size = new_opts.compaction_options_fifo.max_table_files_size / 8;
+    }
+    return CompactToLevel(old_opts, dbname, 0, l0_file_size, true);
   } else {
     return Status::NotSupported(
         "Do not how to migrate to this compaction style");