Add file checksum to stress/crash test (#7343)
Summary: This change has the crash test randomly select from a few file checksum implementations, or nullptr, for DB file_checksum_gen_factory. For compatibility across runs on same DB, each non-null factory can understand all the other functions, but the default changes. Pull Request resolved: https://github.com/facebook/rocksdb/pull/7343 Test Plan: 'make blackbox_crash_test' for a while, including with some debug output to ensure code is being exercised. Reviewed By: zhichao-cao Differential Revision: D23494580 Pulled By: pdillinger fbshipit-source-id: 73bbc7ca32c1adaf619134c0c830f12894880b8a
This commit is contained in:
parent
3f9b75604d
commit
06ad5dd293
@ -10,8 +10,12 @@
|
|||||||
|
|
||||||
#ifdef GFLAGS
|
#ifdef GFLAGS
|
||||||
#include "db_stress_tool/db_stress_common.h"
|
#include "db_stress_tool/db_stress_common.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "util/file_checksum_helper.h"
|
||||||
|
#include "util/xxhash.h"
|
||||||
|
|
||||||
ROCKSDB_NAMESPACE::DbStressEnvWrapper* db_stress_env = nullptr;
|
ROCKSDB_NAMESPACE::DbStressEnvWrapper* db_stress_env = nullptr;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// If non-null, injects read error at a rate specified by the
|
// If non-null, injects read error at a rate specified by the
|
||||||
@ -226,5 +230,106 @@ size_t GenerateValue(uint32_t rand, char* v, size_t max_sz) {
|
|||||||
v[value_sz] = '\0';
|
v[value_sz] = '\0';
|
||||||
return value_sz; // the size of the value set.
|
return value_sz; // the size of the value set.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class MyXXH64Checksum : public FileChecksumGenerator {
|
||||||
|
public:
|
||||||
|
explicit MyXXH64Checksum(bool big) : big_(big) {
|
||||||
|
state_ = XXH64_createState();
|
||||||
|
XXH64_reset(state_, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~MyXXH64Checksum() override { XXH64_freeState(state_); }
|
||||||
|
|
||||||
|
void Update(const char* data, size_t n) override {
|
||||||
|
XXH64_update(state_, data, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Finalize() override {
|
||||||
|
assert(str_.empty());
|
||||||
|
uint64_t digest = XXH64_digest(state_);
|
||||||
|
// Store as little endian raw bytes
|
||||||
|
PutFixed64(&str_, digest);
|
||||||
|
if (big_) {
|
||||||
|
// Throw in some more data for stress testing (448 bits total)
|
||||||
|
PutFixed64(&str_, GetSliceHash64(str_));
|
||||||
|
PutFixed64(&str_, GetSliceHash64(str_));
|
||||||
|
PutFixed64(&str_, GetSliceHash64(str_));
|
||||||
|
PutFixed64(&str_, GetSliceHash64(str_));
|
||||||
|
PutFixed64(&str_, GetSliceHash64(str_));
|
||||||
|
PutFixed64(&str_, GetSliceHash64(str_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetChecksum() const override {
|
||||||
|
assert(!str_.empty());
|
||||||
|
return str_;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Name() const override {
|
||||||
|
return big_ ? "MyBigChecksum" : "MyXXH64Checksum";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool big_;
|
||||||
|
XXH64_state_t* state_;
|
||||||
|
std::string str_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DbStressChecksumGenFactory : public FileChecksumGenFactory {
|
||||||
|
std::string default_func_name_;
|
||||||
|
|
||||||
|
std::unique_ptr<FileChecksumGenerator> CreateFromFuncName(
|
||||||
|
const std::string& func_name) {
|
||||||
|
std::unique_ptr<FileChecksumGenerator> rv;
|
||||||
|
if (func_name == "FileChecksumCrc32c") {
|
||||||
|
rv.reset(new FileChecksumGenCrc32c(FileChecksumGenContext()));
|
||||||
|
} else if (func_name == "MyXXH64Checksum") {
|
||||||
|
rv.reset(new MyXXH64Checksum(false /* big */));
|
||||||
|
} else if (func_name == "MyBigChecksum") {
|
||||||
|
rv.reset(new MyXXH64Checksum(true /* big */));
|
||||||
|
} else {
|
||||||
|
// Should be a recognized function when we get here
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DbStressChecksumGenFactory(const std::string& default_func_name)
|
||||||
|
: default_func_name_(default_func_name) {}
|
||||||
|
|
||||||
|
std::unique_ptr<FileChecksumGenerator> CreateFileChecksumGenerator(
|
||||||
|
const FileChecksumGenContext& context) override {
|
||||||
|
if (context.requested_checksum_func_name.empty()) {
|
||||||
|
return CreateFromFuncName(default_func_name_);
|
||||||
|
} else {
|
||||||
|
return CreateFromFuncName(context.requested_checksum_func_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Name() const override { return "FileChecksumGenCrc32cFactory"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::shared_ptr<FileChecksumGenFactory> GetFileChecksumImpl(
|
||||||
|
const std::string& name) {
|
||||||
|
// Translate from friendly names to internal names
|
||||||
|
std::string internal_name;
|
||||||
|
if (name == "crc32c") {
|
||||||
|
internal_name = "FileChecksumCrc32c";
|
||||||
|
} else if (name == "xxh64") {
|
||||||
|
internal_name = "MyXXH64Checksum";
|
||||||
|
} else if (name == "big") {
|
||||||
|
internal_name = "MyBigChecksum";
|
||||||
|
} else {
|
||||||
|
assert(name.empty() || name == "none");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return std::make_shared<DbStressChecksumGenFactory>(internal_name);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
#endif // GFLAGS
|
#endif // GFLAGS
|
||||||
|
@ -225,6 +225,7 @@ DECLARE_int32(verify_checksum_one_in);
|
|||||||
DECLARE_int32(verify_db_one_in);
|
DECLARE_int32(verify_db_one_in);
|
||||||
DECLARE_int32(continuous_verification_interval);
|
DECLARE_int32(continuous_verification_interval);
|
||||||
DECLARE_int32(get_property_one_in);
|
DECLARE_int32(get_property_one_in);
|
||||||
|
DECLARE_string(file_checksum_impl);
|
||||||
|
|
||||||
#ifndef ROCKSDB_LITE
|
#ifndef ROCKSDB_LITE
|
||||||
DECLARE_bool(use_blob_db);
|
DECLARE_bool(use_blob_db);
|
||||||
@ -541,5 +542,8 @@ extern StressTest* CreateBatchedOpsStressTest();
|
|||||||
extern StressTest* CreateNonBatchedOpsStressTest();
|
extern StressTest* CreateNonBatchedOpsStressTest();
|
||||||
extern void InitializeHotKeyGenerator(double alpha);
|
extern void InitializeHotKeyGenerator(double alpha);
|
||||||
extern int64_t GetOneHotKeyID(double rand_seed, int64_t max_key);
|
extern int64_t GetOneHotKeyID(double rand_seed, int64_t max_key);
|
||||||
|
|
||||||
|
std::shared_ptr<FileChecksumGenFactory> GetFileChecksumImpl(
|
||||||
|
const std::string& name);
|
||||||
} // namespace ROCKSDB_NAMESPACE
|
} // namespace ROCKSDB_NAMESPACE
|
||||||
#endif // GFLAGS
|
#endif // GFLAGS
|
||||||
|
@ -728,4 +728,8 @@ DEFINE_bool(enable_compaction_filter, false,
|
|||||||
"If true, configures a compaction filter that returns a kRemove "
|
"If true, configures a compaction filter that returns a kRemove "
|
||||||
"decision for deleted keys.");
|
"decision for deleted keys.");
|
||||||
|
|
||||||
|
DEFINE_string(file_checksum_impl, "none",
|
||||||
|
"Name of an implementation for file_checksum_gen_factory, or "
|
||||||
|
"\"none\" for null.");
|
||||||
|
|
||||||
#endif // GFLAGS
|
#endif // GFLAGS
|
||||||
|
@ -1838,6 +1838,8 @@ void StressTest::PrintEnv() const {
|
|||||||
bottommost_compression.c_str());
|
bottommost_compression.c_str());
|
||||||
std::string checksum = ChecksumTypeToString(checksum_type_e);
|
std::string checksum = ChecksumTypeToString(checksum_type_e);
|
||||||
fprintf(stdout, "Checksum type : %s\n", checksum.c_str());
|
fprintf(stdout, "Checksum type : %s\n", checksum.c_str());
|
||||||
|
fprintf(stdout, "File checksum impl : %s\n",
|
||||||
|
FLAGS_file_checksum_impl.c_str());
|
||||||
fprintf(stdout, "Bloom bits / key : %s\n",
|
fprintf(stdout, "Bloom bits / key : %s\n",
|
||||||
FormatDoubleParam(FLAGS_bloom_bits).c_str());
|
FormatDoubleParam(FLAGS_bloom_bits).c_str());
|
||||||
fprintf(stdout, "Max subcompactions : %" PRIu64 "\n",
|
fprintf(stdout, "Max subcompactions : %" PRIu64 "\n",
|
||||||
@ -1989,6 +1991,8 @@ void StressTest::Open() {
|
|||||||
FLAGS_max_write_batch_group_size_bytes;
|
FLAGS_max_write_batch_group_size_bytes;
|
||||||
options_.level_compaction_dynamic_level_bytes =
|
options_.level_compaction_dynamic_level_bytes =
|
||||||
FLAGS_level_compaction_dynamic_level_bytes;
|
FLAGS_level_compaction_dynamic_level_bytes;
|
||||||
|
options_.file_checksum_gen_factory =
|
||||||
|
GetFileChecksumImpl(FLAGS_file_checksum_impl);
|
||||||
} else {
|
} else {
|
||||||
#ifdef ROCKSDB_LITE
|
#ifdef ROCKSDB_LITE
|
||||||
fprintf(stderr, "--options_file not supported in lite mode\n");
|
fprintf(stderr, "--options_file not supported in lite mode\n");
|
||||||
|
@ -61,6 +61,7 @@ default_params = {
|
|||||||
"enable_compaction_filter": lambda: random.choice([0, 0, 0, 1]),
|
"enable_compaction_filter": lambda: random.choice([0, 0, 0, 1]),
|
||||||
"expected_values_path": expected_values_file.name,
|
"expected_values_path": expected_values_file.name,
|
||||||
"flush_one_in": 1000000,
|
"flush_one_in": 1000000,
|
||||||
|
"file_checksum_impl": lambda: random.choice(["none", "crc32c", "xxh64", "big"]),
|
||||||
"get_live_files_one_in": 1000000,
|
"get_live_files_one_in": 1000000,
|
||||||
# Note: the following two are intentionally disabled as the corresponding
|
# Note: the following two are intentionally disabled as the corresponding
|
||||||
# APIs are not guaranteed to succeed.
|
# APIs are not guaranteed to succeed.
|
||||||
|
Loading…
Reference in New Issue
Block a user