Add inplace_update_support to crash/stress test (#12535)

Summary:
**Context/Summary:**
`inplace_update_support=true` is not tested in crash/stress test. Since it's not compatible with snapshots like compaction_filter, we need to sanitize its value in presence of snapshots-related options. A minor refactoring is added to centralize such sanitization in db_crashtest.py - see `check_multiget_consistency` and `check_multiget_entity_consistency`

Pull Request resolved: https://github.com/facebook/rocksdb/pull/12535

Test Plan: CI

Reviewed By: ajkr

Differential Revision: D56102978

Pulled By: hx235

fbshipit-source-id: 2e2ab6685a65123b14a321b99f45f60bc6509c6b
This commit is contained in:
Hui Xiao 2024-04-15 16:11:58 -07:00 committed by Facebook GitHub Bot
parent 491c4fb0ed
commit d41e568b1c
6 changed files with 37 additions and 17 deletions

View File

@ -402,6 +402,9 @@ DECLARE_uint32(lowest_used_cache_tier);
DECLARE_bool(enable_custom_split_merge); DECLARE_bool(enable_custom_split_merge);
DECLARE_uint32(adm_policy); DECLARE_uint32(adm_policy);
DECLARE_bool(enable_memtable_insert_with_hint_prefix_extractor); DECLARE_bool(enable_memtable_insert_with_hint_prefix_extractor);
DECLARE_bool(check_multiget_consistency);
DECLARE_bool(check_multiget_entity_consistency);
DECLARE_bool(inplace_update_support);
constexpr long KB = 1024; constexpr long KB = 1024;
constexpr int kRandomValueMaxFactor = 3; constexpr int kRandomValueMaxFactor = 3;

View File

@ -1345,4 +1345,16 @@ DEFINE_bool(enable_memtable_insert_with_hint_prefix_extractor,
"If true and FLAGS_prefix_size > 0, set " "If true and FLAGS_prefix_size > 0, set "
"Options.memtable_insert_with_hint_prefix_extractor to " "Options.memtable_insert_with_hint_prefix_extractor to "
"be Options.prefix_extractor"); "be Options.prefix_extractor");
DEFINE_bool(check_multiget_consistency, true,
"If true, check consistency of MultiGet result by comparing it "
"with Get's under a snapshot");
DEFINE_bool(check_multiget_entity_consistency, true,
"If true, check consistency of MultiGetEntity result by comparing "
"it GetEntity's under a snapshot");
DEFINE_bool(inplace_update_support,
ROCKSDB_NAMESPACE::Options().inplace_update_support,
"Options.inplace_update_support");
#endif // GFLAGS #endif // GFLAGS

View File

@ -3693,6 +3693,7 @@ void InitializeOptionsFromFlags(
} }
options.lowest_used_cache_tier = options.lowest_used_cache_tier =
static_cast<CacheTier>(FLAGS_lowest_used_cache_tier); static_cast<CacheTier>(FLAGS_lowest_used_cache_tier);
options.inplace_update_support = FLAGS_inplace_update_support;
} }
void InitializeOptionsGeneral( void InitializeOptionsGeneral(

View File

@ -249,14 +249,17 @@ int db_stress_tool(int argc, char** argv) {
exit(1); exit(1);
} }
} }
if (FLAGS_enable_compaction_filter && if ((FLAGS_enable_compaction_filter || FLAGS_inplace_update_support) &&
(FLAGS_acquire_snapshot_one_in > 0 || FLAGS_compact_range_one_in > 0 || (FLAGS_acquire_snapshot_one_in > 0 || FLAGS_compact_range_one_in > 0 ||
FLAGS_iterpercent > 0 || FLAGS_test_batches_snapshots || FLAGS_iterpercent > 0 || FLAGS_test_batches_snapshots ||
FLAGS_test_cf_consistency)) { FLAGS_test_cf_consistency || FLAGS_check_multiget_consistency ||
FLAGS_check_multiget_entity_consistency)) {
fprintf( fprintf(
stderr, stderr,
"Error: acquire_snapshot_one_in, compact_range_one_in, iterpercent, " "Error: acquire_snapshot_one_in, compact_range_one_in, iterpercent, "
"test_batches_snapshots must all be 0 when using compaction filter\n"); "test_batches_snapshots, test_cf_consistency, "
"check_multiget_consistency, check_multiget_entity_consistency must "
"all be 0 when using compaction filter or inplace update support\n");
exit(1); exit(1);
} }
if (FLAGS_test_multi_ops_txns) { if (FLAGS_test_multi_ops_txns) {

View File

@ -580,13 +580,8 @@ class NonBatchedOpsStressTest : public StressTest {
int column_family = rand_column_families[0]; int column_family = rand_column_families[0];
ColumnFamilyHandle* cfh = column_families_[column_family]; ColumnFamilyHandle* cfh = column_families_[column_family];
int error_count = 0; int error_count = 0;
// Do a consistency check between Get and MultiGet. Don't do it too
// often as it will slow db_stress down bool do_consistency_check = FLAGS_check_multiget_consistency;
//
// CompactionFilter can make snapshot non-repeatable by removing keys
// protected by snapshot
bool do_consistency_check =
!FLAGS_enable_compaction_filter && thread->rand.OneIn(4);
ReadOptions readoptionscopy = read_opts; ReadOptions readoptionscopy = read_opts;
@ -1075,10 +1070,8 @@ class NonBatchedOpsStressTest : public StressTest {
fault_fs_guard->DisableErrorInjection(); fault_fs_guard->DisableErrorInjection();
} }
// CompactionFilter can make snapshot non-repeatable by removing keys const bool check_get_entity =
// protected by snapshot !error_count && FLAGS_check_multiget_entity_consistency;
const bool check_get_entity = !FLAGS_enable_compaction_filter &&
!error_count && thread->rand.OneIn(4);
for (size_t i = 0; i < num_keys; ++i) { for (size_t i = 0; i < num_keys; ++i) {
const Status& s = statuses[i]; const Status& s = statuses[i];

View File

@ -74,6 +74,7 @@ default_params = {
"destroy_db_initially": 0, "destroy_db_initially": 0,
"enable_pipelined_write": lambda: random.randint(0, 1), "enable_pipelined_write": lambda: random.randint(0, 1),
"enable_compaction_filter": lambda: random.choice([0, 0, 0, 1]), "enable_compaction_filter": lambda: random.choice([0, 0, 0, 1]),
"inplace_update_support": lambda: random.randint(0, 1),
"expected_values_dir": lambda: setup_expected_values_dir(), "expected_values_dir": lambda: setup_expected_values_dir(),
"fail_if_options_file_error": lambda: random.randint(0, 1), "fail_if_options_file_error": lambda: random.randint(0, 1),
"flush_one_in": lambda: random.choice([1000, 1000000]), "flush_one_in": lambda: random.choice([1000, 1000000]),
@ -280,6 +281,8 @@ default_params = {
# TODO(hx235): enable `enable_memtable_insert_with_hint_prefix_extractor` # TODO(hx235): enable `enable_memtable_insert_with_hint_prefix_extractor`
# after fixing the surfaced issue with delete range # after fixing the surfaced issue with delete range
"enable_memtable_insert_with_hint_prefix_extractor": 0, "enable_memtable_insert_with_hint_prefix_extractor": 0,
"check_multiget_consistency": lambda: random.choice([0, 0, 0, 1]),
"check_multiget_entity_consistency": lambda: random.choice([0, 0, 0, 1]),
} }
_TEST_DIR_ENV_VAR = "TEST_TMPDIR" _TEST_DIR_ENV_VAR = "TEST_TMPDIR"
# If TEST_TMPDIR_EXPECTED is not specified, default value will be TEST_TMPDIR # If TEST_TMPDIR_EXPECTED is not specified, default value will be TEST_TMPDIR
@ -437,8 +440,9 @@ cf_consistency_params = {
"write_buffer_size": 1024 * 1024, "write_buffer_size": 1024 * 1024,
"enable_pipelined_write": lambda: random.randint(0, 1), "enable_pipelined_write": lambda: random.randint(0, 1),
# Snapshots are used heavily in this test mode, while they are incompatible # Snapshots are used heavily in this test mode, while they are incompatible
# with compaction filter. # with compaction filter, inplace_update_support
"enable_compaction_filter": 0, "enable_compaction_filter": 0,
"inplace_update_support": 0,
# `CfConsistencyStressTest::TestIngestExternalFile()` is not implemented. # `CfConsistencyStressTest::TestIngestExternalFile()` is not implemented.
"ingest_external_file_one_in": 0, "ingest_external_file_one_in": 0,
# `CfConsistencyStressTest::TestIterateAgainstExpected()` is not implemented. # `CfConsistencyStressTest::TestIterateAgainstExpected()` is not implemented.
@ -639,6 +643,7 @@ def finalize_and_sanitize(src_params):
if dest_params["test_batches_snapshots"] == 1: if dest_params["test_batches_snapshots"] == 1:
dest_params["enable_compaction_filter"] = 0 dest_params["enable_compaction_filter"] = 0
dest_params["inplace_update_support"] = 0
if dest_params["prefix_size"] < 0: if dest_params["prefix_size"] < 0:
dest_params["prefix_size"] = 1 dest_params["prefix_size"] = 1
@ -699,8 +704,9 @@ def finalize_and_sanitize(src_params):
dest_params["enable_pipelined_write"] = 0 dest_params["enable_pipelined_write"] = 0
if dest_params.get("sst_file_manager_bytes_per_sec", 0) == 0: if dest_params.get("sst_file_manager_bytes_per_sec", 0) == 0:
dest_params["sst_file_manager_bytes_per_truncate"] = 0 dest_params["sst_file_manager_bytes_per_truncate"] = 0
if dest_params.get("enable_compaction_filter", 0) == 1: if (dest_params.get("enable_compaction_filter", 0) == 1
# Compaction filter is incompatible with snapshots. Need to avoid taking or dest_params.get("inplace_update_support", 0) == 1):
# Compaction filter, inplace update support are incompatible with snapshots. Need to avoid taking
# snapshots, as well as avoid operations that use snapshots for # snapshots, as well as avoid operations that use snapshots for
# verification. # verification.
dest_params["acquire_snapshot_one_in"] = 0 dest_params["acquire_snapshot_one_in"] = 0
@ -708,6 +714,8 @@ def finalize_and_sanitize(src_params):
# Give the iterator ops away to reads. # Give the iterator ops away to reads.
dest_params["readpercent"] += dest_params.get("iterpercent", 10) dest_params["readpercent"] += dest_params.get("iterpercent", 10)
dest_params["iterpercent"] = 0 dest_params["iterpercent"] = 0
dest_params["check_multiget_consistency"] = 0
dest_params["check_multiget_entity_consistency"] = 0
if dest_params.get("prefix_size") == -1: if dest_params.get("prefix_size") == -1:
dest_params["readpercent"] += dest_params.get("prefixpercent", 20) dest_params["readpercent"] += dest_params.get("prefixpercent", 20)
dest_params["prefixpercent"] = 0 dest_params["prefixpercent"] = 0