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()) {
// 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
}
}
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();
}
// 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.
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);
}
}
}
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) {
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");