mirror of https://github.com/facebook/rocksdb.git
Prevent data block compression with `BlockBasedTableOptions::block_align` (#12592)
Summary: Made `BlockBasedTableOptions::block_align` incompatible (i.e., APIs will return `Status::InvalidArgument`) with more ways of enabling compression: `CompactionOptions::compression`, `ColumnFamilyOptions::compression_per_level`, and `ColumnFamilyOptions::bottommost_compression`. Previously it was only incompatible with `ColumnFamilyOptions::compression`. Pull Request resolved: https://github.com/facebook/rocksdb/pull/12592 Reviewed By: hx235 Differential Revision: D56650862 Pulled By: ajkr fbshipit-source-id: f5201602c2ce436e6d8d30893caa6a161a61f141
This commit is contained in:
parent
a82ba52756
commit
2ec25a3e54
|
@ -441,6 +441,50 @@ TEST_F(CompactFilesTest, SentinelCompressionType) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(CompactFilesTest, CompressionWithBlockAlign) {
|
||||||
|
Options options;
|
||||||
|
options.compression = CompressionType::kNoCompression;
|
||||||
|
options.create_if_missing = true;
|
||||||
|
options.disable_auto_compactions = true;
|
||||||
|
|
||||||
|
std::shared_ptr<FlushedFileCollector> collector =
|
||||||
|
std::make_shared<FlushedFileCollector>();
|
||||||
|
options.listeners.push_back(collector);
|
||||||
|
|
||||||
|
{
|
||||||
|
BlockBasedTableOptions bbto;
|
||||||
|
bbto.block_align = true;
|
||||||
|
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<DB> db;
|
||||||
|
{
|
||||||
|
DB* _db = nullptr;
|
||||||
|
ASSERT_OK(DB::Open(options, db_name_, &_db));
|
||||||
|
db.reset(_db);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_OK(db->Put(WriteOptions(), "key", "val"));
|
||||||
|
ASSERT_OK(db->Flush(FlushOptions()));
|
||||||
|
|
||||||
|
// Ensure background work is fully finished including listener callbacks
|
||||||
|
// before accessing listener state.
|
||||||
|
ASSERT_OK(
|
||||||
|
static_cast_with_check<DBImpl>(db.get())->TEST_WaitForBackgroundWork());
|
||||||
|
auto l0_files = collector->GetFlushedFiles();
|
||||||
|
ASSERT_EQ(1, l0_files.size());
|
||||||
|
|
||||||
|
// We can run this test even without Snappy support because we expect the
|
||||||
|
// `CompactFiles()` to fail before actually invoking Snappy compression.
|
||||||
|
CompactionOptions compaction_opts;
|
||||||
|
compaction_opts.compression = CompressionType::kSnappyCompression;
|
||||||
|
ASSERT_TRUE(db->CompactFiles(compaction_opts, l0_files, 1 /* output_level */)
|
||||||
|
.IsInvalidArgument());
|
||||||
|
|
||||||
|
compaction_opts.compression = CompressionType::kDisableCompressionOption;
|
||||||
|
ASSERT_OK(db->CompactFiles(compaction_opts, l0_files, 1 /* output_level */));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(CompactFilesTest, GetCompactionJobInfo) {
|
TEST_F(CompactFilesTest, GetCompactionJobInfo) {
|
||||||
Options options;
|
Options options;
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
|
|
|
@ -1420,6 +1420,14 @@ Status DBImpl::CompactFiles(const CompactionOptions& compact_options,
|
||||||
LogBuffer log_buffer(InfoLogLevel::INFO_LEVEL,
|
LogBuffer log_buffer(InfoLogLevel::INFO_LEVEL,
|
||||||
immutable_db_options_.info_log.get());
|
immutable_db_options_.info_log.get());
|
||||||
|
|
||||||
|
if (compact_options.compression !=
|
||||||
|
CompressionType::kDisableCompressionOption) {
|
||||||
|
ROCKS_LOG_WARN(immutable_db_options_.info_log,
|
||||||
|
"[%s] [JOB %d] Found use of deprecated option "
|
||||||
|
"`CompactionOptions::compression`",
|
||||||
|
cfd->GetName().c_str(), job_context.job_id);
|
||||||
|
}
|
||||||
|
|
||||||
// Perform CompactFiles
|
// Perform CompactFiles
|
||||||
TEST_SYNC_POINT("TestCompactFiles::IngestExternalFile2");
|
TEST_SYNC_POINT("TestCompactFiles::IngestExternalFile2");
|
||||||
TEST_SYNC_POINT_CALLBACK("TestCompactFiles:PausingManualCompaction:3",
|
TEST_SYNC_POINT_CALLBACK("TestCompactFiles:PausingManualCompaction:3",
|
||||||
|
|
|
@ -626,6 +626,14 @@ struct BlockBasedTableBuilder::Rep {
|
||||||
} else {
|
} else {
|
||||||
base_context_checksum = 0;
|
base_context_checksum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (alignment > 0 && compression_type != kNoCompression) {
|
||||||
|
// With better sanitization in `CompactionPicker::CompactFiles()`, we
|
||||||
|
// would not need to handle this case here and could change it to an
|
||||||
|
// assertion instead.
|
||||||
|
SetStatus(Status::InvalidArgument(
|
||||||
|
"Enable block_align, but compression enabled"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rep(const Rep&) = delete;
|
Rep(const Rep&) = delete;
|
||||||
|
|
|
@ -619,6 +619,21 @@ Status BlockBasedTableFactory::ValidateOptions(
|
||||||
"Enable block_align, but compression "
|
"Enable block_align, but compression "
|
||||||
"enabled");
|
"enabled");
|
||||||
}
|
}
|
||||||
|
if (table_options_.block_align &&
|
||||||
|
cf_opts.bottommost_compression != kDisableCompressionOption &&
|
||||||
|
cf_opts.bottommost_compression != kNoCompression) {
|
||||||
|
return Status::InvalidArgument(
|
||||||
|
"Enable block_align, but bottommost_compression enabled");
|
||||||
|
}
|
||||||
|
if (table_options_.block_align) {
|
||||||
|
for (auto level_compression : cf_opts.compression_per_level) {
|
||||||
|
if (level_compression != kDisableCompressionOption &&
|
||||||
|
level_compression != kNoCompression) {
|
||||||
|
return Status::InvalidArgument(
|
||||||
|
"Enable block_align, but compression_per_level enabled");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (table_options_.block_align &&
|
if (table_options_.block_align &&
|
||||||
(table_options_.block_size & (table_options_.block_size - 1))) {
|
(table_options_.block_size & (table_options_.block_size - 1))) {
|
||||||
return Status::InvalidArgument(
|
return Status::InvalidArgument(
|
||||||
|
|
|
@ -3188,6 +3188,7 @@ TEST_P(BlockBasedTableTest, BlockCacheLookupSeqScans) {
|
||||||
Options options;
|
Options options;
|
||||||
BlockBasedTableOptions table_options = GetBlockBasedTableOptions();
|
BlockBasedTableOptions table_options = GetBlockBasedTableOptions();
|
||||||
options.create_if_missing = true;
|
options.create_if_missing = true;
|
||||||
|
options.compression = kNoCompression;
|
||||||
options.statistics = CreateDBStatistics();
|
options.statistics = CreateDBStatistics();
|
||||||
table_options.index_type =
|
table_options.index_type =
|
||||||
BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
|
BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
|
||||||
|
@ -3196,6 +3197,8 @@ TEST_P(BlockBasedTableTest, BlockCacheLookupSeqScans) {
|
||||||
table_options.filter_policy.reset(NewBloomFilterPolicy(10, true));
|
table_options.filter_policy.reset(NewBloomFilterPolicy(10, true));
|
||||||
table_options.block_align = true;
|
table_options.block_align = true;
|
||||||
options.table_factory.reset(new BlockBasedTableFactory(table_options));
|
options.table_factory.reset(new BlockBasedTableFactory(table_options));
|
||||||
|
ASSERT_OK(options.table_factory->ValidateOptions(
|
||||||
|
DBOptions(options), ColumnFamilyOptions(options)));
|
||||||
|
|
||||||
TableConstructor c(BytewiseComparator());
|
TableConstructor c(BytewiseComparator());
|
||||||
GenerateKVMap(&c);
|
GenerateKVMap(&c);
|
||||||
|
@ -3326,6 +3329,7 @@ TEST_P(BlockBasedTableTest, BlockCacheLookupAsyncScansSeek) {
|
||||||
std::unique_ptr<Env> env(
|
std::unique_ptr<Env> env(
|
||||||
new CompositeEnvWrapper(c.env_, FileSystem::Default()));
|
new CompositeEnvWrapper(c.env_, FileSystem::Default()));
|
||||||
options.env = env.get();
|
options.env = env.get();
|
||||||
|
options.compression = kNoCompression;
|
||||||
options.statistics = CreateDBStatistics();
|
options.statistics = CreateDBStatistics();
|
||||||
c.env_ = env.get();
|
c.env_ = env.get();
|
||||||
|
|
||||||
|
@ -3338,6 +3342,8 @@ TEST_P(BlockBasedTableTest, BlockCacheLookupAsyncScansSeek) {
|
||||||
table_options.filter_policy.reset(NewBloomFilterPolicy(10, true));
|
table_options.filter_policy.reset(NewBloomFilterPolicy(10, true));
|
||||||
table_options.block_align = true;
|
table_options.block_align = true;
|
||||||
options.table_factory.reset(new BlockBasedTableFactory(table_options));
|
options.table_factory.reset(new BlockBasedTableFactory(table_options));
|
||||||
|
ASSERT_OK(options.table_factory->ValidateOptions(
|
||||||
|
DBOptions(options), ColumnFamilyOptions(options)));
|
||||||
|
|
||||||
GenerateKVMap(&c);
|
GenerateKVMap(&c);
|
||||||
|
|
||||||
|
@ -5425,6 +5431,8 @@ TEST_P(BlockBasedTableTest, BlockAlignTest) {
|
||||||
Options options;
|
Options options;
|
||||||
options.compression = kNoCompression;
|
options.compression = kNoCompression;
|
||||||
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
|
ASSERT_OK(options.table_factory->ValidateOptions(
|
||||||
|
DBOptions(options), ColumnFamilyOptions(options)));
|
||||||
const ImmutableOptions ioptions(options);
|
const ImmutableOptions ioptions(options);
|
||||||
const MutableCFOptions moptions(options);
|
const MutableCFOptions moptions(options);
|
||||||
InternalKeyComparator ikc(options.comparator);
|
InternalKeyComparator ikc(options.comparator);
|
||||||
|
@ -5475,7 +5483,10 @@ TEST_P(BlockBasedTableTest, BlockAlignTest) {
|
||||||
std::unique_ptr<TableReader> table_reader;
|
std::unique_ptr<TableReader> table_reader;
|
||||||
bbto.block_align = false;
|
bbto.block_align = false;
|
||||||
Options options2;
|
Options options2;
|
||||||
|
options2.compression = kNoCompression;
|
||||||
options2.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
options2.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
|
ASSERT_OK(options2.table_factory->ValidateOptions(
|
||||||
|
DBOptions(options2), ColumnFamilyOptions(options2)));
|
||||||
ImmutableOptions ioptions2(options2);
|
ImmutableOptions ioptions2(options2);
|
||||||
const MutableCFOptions moptions2(options2);
|
const MutableCFOptions moptions2(options2);
|
||||||
|
|
||||||
|
@ -5514,6 +5525,8 @@ TEST_P(BlockBasedTableTest, FixBlockAlignMismatchedFileChecksums) {
|
||||||
bbto.block_align = true;
|
bbto.block_align = true;
|
||||||
bbto.block_size = 1024;
|
bbto.block_size = 1024;
|
||||||
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
|
ASSERT_OK(options.table_factory->ValidateOptions(
|
||||||
|
DBOptions(options), ColumnFamilyOptions(options)));
|
||||||
const std::string kDBPath =
|
const std::string kDBPath =
|
||||||
test::PerThreadDBPath("block_align_padded_bytes_verify_file_checksums");
|
test::PerThreadDBPath("block_align_padded_bytes_verify_file_checksums");
|
||||||
ASSERT_OK(DestroyDB(kDBPath, options));
|
ASSERT_OK(DestroyDB(kDBPath, options));
|
||||||
|
@ -5539,6 +5552,8 @@ TEST_P(BlockBasedTableTest, PropertiesBlockRestartPointTest) {
|
||||||
Options options;
|
Options options;
|
||||||
options.compression = kNoCompression;
|
options.compression = kNoCompression;
|
||||||
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
|
ASSERT_OK(options.table_factory->ValidateOptions(
|
||||||
|
DBOptions(options), ColumnFamilyOptions(options)));
|
||||||
|
|
||||||
const ImmutableOptions ioptions(options);
|
const ImmutableOptions ioptions(options);
|
||||||
const MutableCFOptions moptions(options);
|
const MutableCFOptions moptions(options);
|
||||||
|
@ -5845,6 +5860,7 @@ TEST_P(BlockBasedTableTest, SeekMetaBlocks) {
|
||||||
TEST_P(BlockBasedTableTest, BadOptions) {
|
TEST_P(BlockBasedTableTest, BadOptions) {
|
||||||
ROCKSDB_NAMESPACE::Options options;
|
ROCKSDB_NAMESPACE::Options options;
|
||||||
options.compression = kNoCompression;
|
options.compression = kNoCompression;
|
||||||
|
options.create_if_missing = true;
|
||||||
BlockBasedTableOptions bbto = GetBlockBasedTableOptions();
|
BlockBasedTableOptions bbto = GetBlockBasedTableOptions();
|
||||||
bbto.block_size = 4000;
|
bbto.block_size = 4000;
|
||||||
bbto.block_align = true;
|
bbto.block_align = true;
|
||||||
|
@ -5853,13 +5869,29 @@ TEST_P(BlockBasedTableTest, BadOptions) {
|
||||||
test::PerThreadDBPath("block_based_table_bad_options_test");
|
test::PerThreadDBPath("block_based_table_bad_options_test");
|
||||||
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
ASSERT_OK(DestroyDB(kDBPath, options));
|
ASSERT_OK(DestroyDB(kDBPath, options));
|
||||||
ROCKSDB_NAMESPACE::DB* db;
|
|
||||||
ASSERT_NOK(ROCKSDB_NAMESPACE::DB::Open(options, kDBPath, &db));
|
|
||||||
|
|
||||||
bbto.block_size = 4096;
|
std::unique_ptr<DB> db;
|
||||||
options.compression = kSnappyCompression;
|
{
|
||||||
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
ROCKSDB_NAMESPACE::DB* _db;
|
||||||
ASSERT_NOK(ROCKSDB_NAMESPACE::DB::Open(options, kDBPath, &db));
|
ASSERT_NOK(ROCKSDB_NAMESPACE::DB::Open(options, kDBPath, &_db));
|
||||||
|
|
||||||
|
bbto.block_size = 4096;
|
||||||
|
options.compression = kSnappyCompression;
|
||||||
|
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
|
||||||
|
ASSERT_NOK(ROCKSDB_NAMESPACE::DB::Open(options, kDBPath, &_db));
|
||||||
|
|
||||||
|
options.compression = kNoCompression;
|
||||||
|
options.bottommost_compression = kSnappyCompression;
|
||||||
|
ASSERT_NOK(ROCKSDB_NAMESPACE::DB::Open(options, kDBPath, &_db));
|
||||||
|
|
||||||
|
options.bottommost_compression = kNoCompression;
|
||||||
|
options.compression_per_level.emplace_back(kSnappyCompression);
|
||||||
|
ASSERT_NOK(ROCKSDB_NAMESPACE::DB::Open(options, kDBPath, &_db));
|
||||||
|
|
||||||
|
options.compression_per_level.clear();
|
||||||
|
ASSERT_OK(ROCKSDB_NAMESPACE::DB::Open(options, kDBPath, &_db));
|
||||||
|
db.reset(_db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BBTTailPrefetchTest, TestTailPrefetchStats) {
|
TEST_F(BBTTailPrefetchTest, TestTailPrefetchStats) {
|
||||||
|
|
|
@ -837,6 +837,7 @@ def finalize_and_sanitize(src_params):
|
||||||
# Enabling block_align with compression is not supported
|
# Enabling block_align with compression is not supported
|
||||||
if dest_params.get("block_align") == 1:
|
if dest_params.get("block_align") == 1:
|
||||||
dest_params["compression_type"] = "none"
|
dest_params["compression_type"] = "none"
|
||||||
|
dest_params["bottommost_compression_type"] = "none"
|
||||||
# If periodic_compaction_seconds is not set, daily_offpeak_time_utc doesn't do anything
|
# If periodic_compaction_seconds is not set, daily_offpeak_time_utc doesn't do anything
|
||||||
if dest_params.get("periodic_compaction_seconds") == 0:
|
if dest_params.get("periodic_compaction_seconds") == 0:
|
||||||
dest_params["daily_offpeak_time_utc"] = ""
|
dest_params["daily_offpeak_time_utc"] = ""
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
* Enabling `BlockBasedTableOptions::block_align` is now incompatible (i.e., APIs will return `Status::InvalidArgument`) with more ways of enabling compression: `CompactionOptions::compression`, `ColumnFamilyOptions::compression_per_level`, and `ColumnFamilyOptions::bottommost_compression`.
|
Loading…
Reference in New Issue