|
|
@ -24,6 +24,10 @@ import argparse |
|
|
|
# cf_consistency_params < args |
|
|
|
# cf_consistency_params < args |
|
|
|
# for txn: |
|
|
|
# for txn: |
|
|
|
# default_params < {blackbox,whitebox}_default_params < txn_params < args |
|
|
|
# default_params < {blackbox,whitebox}_default_params < txn_params < args |
|
|
|
|
|
|
|
# for ts: |
|
|
|
|
|
|
|
# default_params < {blackbox,whitebox}_default_params < ts_params < args |
|
|
|
|
|
|
|
# for multiops_txn: |
|
|
|
|
|
|
|
# default_params < {blackbox,whitebox}_default_params < multiops_txn_params < args |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default_params = { |
|
|
|
default_params = { |
|
|
@ -199,6 +203,21 @@ def setup_expected_values_dir(): |
|
|
|
os.mkdir(expected_values_dir) |
|
|
|
os.mkdir(expected_values_dir) |
|
|
|
return expected_values_dir |
|
|
|
return expected_values_dir |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
multiops_txn_key_spaces_file = None |
|
|
|
|
|
|
|
def setup_multiops_txn_key_spaces_file(): |
|
|
|
|
|
|
|
global multiops_txn_key_spaces_file |
|
|
|
|
|
|
|
if multiops_txn_key_spaces_file is not None: |
|
|
|
|
|
|
|
return multiops_txn_key_spaces_file |
|
|
|
|
|
|
|
key_spaces_file_prefix = "rocksdb_crashtest_multiops_txn_key_spaces" |
|
|
|
|
|
|
|
test_tmpdir = os.environ.get(_TEST_DIR_ENV_VAR) |
|
|
|
|
|
|
|
if test_tmpdir is None or test_tmpdir == "": |
|
|
|
|
|
|
|
multiops_txn_key_spaces_file = tempfile.mkstemp( |
|
|
|
|
|
|
|
prefix=key_spaces_file_prefix)[1] |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
multiops_txn_key_spaces_file = tempfile.mkstemp( |
|
|
|
|
|
|
|
prefix=key_spaces_file_prefix, dir=test_tmpdir)[1] |
|
|
|
|
|
|
|
return multiops_txn_key_spaces_file |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def is_direct_io_supported(dbname): |
|
|
|
def is_direct_io_supported(dbname): |
|
|
|
with tempfile.NamedTemporaryFile(dir=dbname) as f: |
|
|
|
with tempfile.NamedTemporaryFile(dir=dbname) as f: |
|
|
@ -323,6 +342,61 @@ ts_params = { |
|
|
|
"use_block_based_filter": 0, |
|
|
|
"use_block_based_filter": 0, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
multiops_txn_default_params = { |
|
|
|
|
|
|
|
"test_cf_consistency": 0, |
|
|
|
|
|
|
|
"test_batches_snapshots": 0, |
|
|
|
|
|
|
|
"test_multi_ops_txns": 1, |
|
|
|
|
|
|
|
"use_txn": 1, |
|
|
|
|
|
|
|
"two_write_queues": lambda: random.choice([0, 1]), |
|
|
|
|
|
|
|
# TODO: enable write-prepared |
|
|
|
|
|
|
|
"disable_wal": 0, |
|
|
|
|
|
|
|
"use_only_the_last_commit_time_batch_for_recovery": lambda: random.choice([0, 1]), |
|
|
|
|
|
|
|
"clear_column_family_one_in": 0, |
|
|
|
|
|
|
|
"column_families": 1, |
|
|
|
|
|
|
|
"enable_pipelined_write": lambda: random.choice([0, 1]), |
|
|
|
|
|
|
|
# This test already acquires snapshots in reads |
|
|
|
|
|
|
|
"acquire_snapshot_one_in": 0, |
|
|
|
|
|
|
|
"backup_one_in": 0, |
|
|
|
|
|
|
|
"writepercent": 0, |
|
|
|
|
|
|
|
"delpercent": 0, |
|
|
|
|
|
|
|
"delrangepercent": 0, |
|
|
|
|
|
|
|
"customopspercent": 80, |
|
|
|
|
|
|
|
"readpercent": 5, |
|
|
|
|
|
|
|
"iterpercent": 15, |
|
|
|
|
|
|
|
"prefixpercent": 0, |
|
|
|
|
|
|
|
"verify_db_one_in": 1000, |
|
|
|
|
|
|
|
"continuous_verification_interval": 1000, |
|
|
|
|
|
|
|
"delay_snapshot_read_one_in": 3, |
|
|
|
|
|
|
|
# 65536 is the smallest possible value for write_buffer_size. Smaller |
|
|
|
|
|
|
|
# values will be sanitized to 65536 during db open. SetOptions currently |
|
|
|
|
|
|
|
# does not sanitize options, but very small write_buffer_size may cause |
|
|
|
|
|
|
|
# assertion failure in |
|
|
|
|
|
|
|
# https://github.com/facebook/rocksdb/blob/7.0.fb/db/memtable.cc#L117. |
|
|
|
|
|
|
|
"write_buffer_size": 65536, |
|
|
|
|
|
|
|
# flush more frequently to generate more files, thus trigger more |
|
|
|
|
|
|
|
# compactions. |
|
|
|
|
|
|
|
"flush_one_in": 1000, |
|
|
|
|
|
|
|
"key_spaces_path": setup_multiops_txn_key_spaces_file(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
multiops_wc_txn_params = { |
|
|
|
|
|
|
|
"txn_write_policy": 0, |
|
|
|
|
|
|
|
# TODO re-enable pipelined write. Not well tested atm |
|
|
|
|
|
|
|
"enable_pipelined_write": 0, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
multiops_wp_txn_params = { |
|
|
|
|
|
|
|
"txn_write_policy": 1, |
|
|
|
|
|
|
|
"wp_snapshot_cache_bits": 1, |
|
|
|
|
|
|
|
# try small wp_commit_cache_bits, e.g. 0 once we explore storing full |
|
|
|
|
|
|
|
# commit sequence numbers in commit cache |
|
|
|
|
|
|
|
"wp_commit_cache_bits": 10, |
|
|
|
|
|
|
|
# pipeline write is not currnetly compatible with WritePrepared txns |
|
|
|
|
|
|
|
"enable_pipelined_write": 0, |
|
|
|
|
|
|
|
# OpenReadOnly after checkpoint is not currnetly compatible with WritePrepared txns |
|
|
|
|
|
|
|
"checkpoint_one_in": 0, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
def finalize_and_sanitize(src_params): |
|
|
|
def finalize_and_sanitize(src_params): |
|
|
|
dest_params = dict([(k, v() if callable(v) else v) |
|
|
|
dest_params = dict([(k, v() if callable(v) else v) |
|
|
|
for (k, v) in src_params.items()]) |
|
|
|
for (k, v) in src_params.items()]) |
|
|
@ -407,6 +481,8 @@ def finalize_and_sanitize(src_params): |
|
|
|
if (dest_params.get("prefix_size") == -1 and |
|
|
|
if (dest_params.get("prefix_size") == -1 and |
|
|
|
dest_params.get("memtable_whole_key_filtering") == 0): |
|
|
|
dest_params.get("memtable_whole_key_filtering") == 0): |
|
|
|
dest_params["memtable_prefix_bloom_size_ratio"] = 0 |
|
|
|
dest_params["memtable_prefix_bloom_size_ratio"] = 0 |
|
|
|
|
|
|
|
if dest_params.get("two_write_queues") == 1: |
|
|
|
|
|
|
|
dest_params["enable_pipelined_write"] = 0 |
|
|
|
return dest_params |
|
|
|
return dest_params |
|
|
|
|
|
|
|
|
|
|
|
def gen_cmd_params(args): |
|
|
|
def gen_cmd_params(args): |
|
|
@ -431,6 +507,12 @@ def gen_cmd_params(args): |
|
|
|
params.update(best_efforts_recovery_params) |
|
|
|
params.update(best_efforts_recovery_params) |
|
|
|
if args.enable_ts: |
|
|
|
if args.enable_ts: |
|
|
|
params.update(ts_params) |
|
|
|
params.update(ts_params) |
|
|
|
|
|
|
|
if args.test_multiops_txn: |
|
|
|
|
|
|
|
params.update(multiops_txn_default_params) |
|
|
|
|
|
|
|
if args.write_policy == 'write_committed': |
|
|
|
|
|
|
|
params.update(multiops_wc_txn_params) |
|
|
|
|
|
|
|
elif args.write_policy == 'write_prepared': |
|
|
|
|
|
|
|
params.update(multiops_wp_txn_params) |
|
|
|
|
|
|
|
|
|
|
|
# Best-effort recovery and BlobDB are currently incompatible. Test BE recovery |
|
|
|
# Best-effort recovery and BlobDB are currently incompatible. Test BE recovery |
|
|
|
# if specified on the command line; otherwise, apply BlobDB related overrides |
|
|
|
# if specified on the command line; otherwise, apply BlobDB related overrides |
|
|
@ -453,7 +535,8 @@ def gen_cmd(params, unknown_params): |
|
|
|
for k, v in [(k, finalzied_params[k]) for k in sorted(finalzied_params)] |
|
|
|
for k, v in [(k, finalzied_params[k]) for k in sorted(finalzied_params)] |
|
|
|
if k not in set(['test_type', 'simple', 'duration', 'interval', |
|
|
|
if k not in set(['test_type', 'simple', 'duration', 'interval', |
|
|
|
'random_kill_odd', 'cf_consistency', 'txn', |
|
|
|
'random_kill_odd', 'cf_consistency', 'txn', |
|
|
|
'test_best_efforts_recovery', 'enable_ts', 'stress_cmd']) |
|
|
|
'test_best_efforts_recovery', 'enable_ts', |
|
|
|
|
|
|
|
'test_multiops_txn', 'write_policy', 'stress_cmd']) |
|
|
|
and v is not None] + unknown_params |
|
|
|
and v is not None] + unknown_params |
|
|
|
return cmd |
|
|
|
return cmd |
|
|
|
|
|
|
|
|
|
|
@ -713,6 +796,8 @@ def main(): |
|
|
|
parser.add_argument("--txn", action='store_true') |
|
|
|
parser.add_argument("--txn", action='store_true') |
|
|
|
parser.add_argument("--test_best_efforts_recovery", action='store_true') |
|
|
|
parser.add_argument("--test_best_efforts_recovery", action='store_true') |
|
|
|
parser.add_argument("--enable_ts", action='store_true') |
|
|
|
parser.add_argument("--enable_ts", action='store_true') |
|
|
|
|
|
|
|
parser.add_argument("--test_multiops_txn", action='store_true') |
|
|
|
|
|
|
|
parser.add_argument("--write_policy", choices=["write_committed", "write_prepared"]) |
|
|
|
parser.add_argument("--stress_cmd") |
|
|
|
parser.add_argument("--stress_cmd") |
|
|
|
|
|
|
|
|
|
|
|
all_params = dict(list(default_params.items()) |
|
|
|
all_params = dict(list(default_params.items()) |
|
|
@ -722,7 +807,10 @@ def main(): |
|
|
|
+ list(blackbox_simple_default_params.items()) |
|
|
|
+ list(blackbox_simple_default_params.items()) |
|
|
|
+ list(whitebox_simple_default_params.items()) |
|
|
|
+ list(whitebox_simple_default_params.items()) |
|
|
|
+ list(blob_params.items()) |
|
|
|
+ list(blob_params.items()) |
|
|
|
+ list(ts_params.items())) |
|
|
|
+ list(ts_params.items()) |
|
|
|
|
|
|
|
+ list(multiops_txn_default_params.items()) |
|
|
|
|
|
|
|
+ list(multiops_wc_txn_params.items()) |
|
|
|
|
|
|
|
+ list(multiops_wp_txn_params.items())) |
|
|
|
|
|
|
|
|
|
|
|
for k, v in all_params.items(): |
|
|
|
for k, v in all_params.items(): |
|
|
|
parser.add_argument("--" + k, type=type(v() if callable(v) else v)) |
|
|
|
parser.add_argument("--" + k, type=type(v() if callable(v) else v)) |
|
|
@ -744,6 +832,8 @@ def main(): |
|
|
|
# Only delete the `expected_values_dir` if test passes |
|
|
|
# Only delete the `expected_values_dir` if test passes |
|
|
|
if expected_values_dir is not None: |
|
|
|
if expected_values_dir is not None: |
|
|
|
shutil.rmtree(expected_values_dir) |
|
|
|
shutil.rmtree(expected_values_dir) |
|
|
|
|
|
|
|
if multiops_txn_key_spaces_file is not None: |
|
|
|
|
|
|
|
os.remove(multiops_txn_key_spaces_file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__': |
|
|
|
if __name__ == '__main__': |
|
|
|