db_bench_tool_test.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #include "rocksdb/db_bench_tool.h"
  10. #include "db/db_impl/db_impl.h"
  11. #include "options/options_parser.h"
  12. #include "rocksdb/utilities/options_util.h"
  13. #include "test_util/testharness.h"
  14. #include "test_util/testutil.h"
  15. #include "util/random.h"
  16. #ifdef GFLAGS
  17. #include "util/gflags_compat.h"
  18. namespace ROCKSDB_NAMESPACE {
  19. namespace {
  20. static const int kMaxArgCount = 100;
  21. static const size_t kArgBufferSize = 100000;
  22. } // namespace
  23. class DBBenchTest : public testing::Test {
  24. public:
  25. DBBenchTest() : rnd_(0xFB) {
  26. test_path_ = test::PerThreadDBPath("db_bench_test");
  27. Env::Default()->CreateDir(test_path_);
  28. db_path_ = test_path_ + "/db";
  29. wal_path_ = test_path_ + "/wal";
  30. }
  31. ~DBBenchTest() {
  32. // DestroyDB(db_path_, Options());
  33. }
  34. void ResetArgs() {
  35. argc_ = 0;
  36. cursor_ = 0;
  37. memset(arg_buffer_, 0, kArgBufferSize);
  38. }
  39. void AppendArgs(const std::vector<std::string>& args) {
  40. for (const auto& arg : args) {
  41. ASSERT_LE(cursor_ + arg.size() + 1, kArgBufferSize);
  42. ASSERT_LE(argc_ + 1, kMaxArgCount);
  43. snprintf(arg_buffer_ + cursor_, arg.size() + 1, "%s", arg.c_str());
  44. argv_[argc_++] = arg_buffer_ + cursor_;
  45. cursor_ += arg.size() + 1;
  46. }
  47. }
  48. // Gets the default options for this test/db_bench.
  49. // Note that db_bench may change some of the default option values and that
  50. // the database might as well. The options changed by db_bench are
  51. // specified here; the ones by the DB are set via SanitizeOptions
  52. Options GetDefaultOptions(CompactionStyle style = kCompactionStyleLevel,
  53. int levels = 7) const {
  54. Options opt;
  55. opt.create_if_missing = true;
  56. opt.max_open_files = 256;
  57. opt.max_background_compactions = 10;
  58. opt.dump_malloc_stats = true; // db_bench uses a different default
  59. opt.compaction_style = style;
  60. opt.num_levels = levels;
  61. opt.compression = kNoCompression;
  62. opt.arena_block_size = 8388608;
  63. return SanitizeOptions(db_path_, opt);
  64. }
  65. void RunDbBench(const std::string& options_file_name) {
  66. AppendArgs({"./db_bench", "--benchmarks=fillseq", "--use_existing_db=0",
  67. "--num=1000", "--compression_type=none",
  68. std::string(std::string("--db=") + db_path_).c_str(),
  69. std::string(std::string("--wal_dir=") + wal_path_).c_str(),
  70. std::string(std::string("--options_file=") + options_file_name)
  71. .c_str()});
  72. ASSERT_EQ(0, db_bench_tool(argc(), argv()));
  73. }
  74. void VerifyOptions(const Options& opt) {
  75. DBOptions loaded_db_opts;
  76. ConfigOptions config_opts;
  77. config_opts.ignore_unknown_options = false;
  78. config_opts.input_strings_escaped = true;
  79. config_opts.env = Env::Default();
  80. std::vector<ColumnFamilyDescriptor> cf_descs;
  81. ASSERT_OK(
  82. LoadLatestOptions(config_opts, db_path_, &loaded_db_opts, &cf_descs));
  83. ConfigOptions exact;
  84. exact.input_strings_escaped = false;
  85. exact.sanity_level = ConfigOptions::kSanityLevelExactMatch;
  86. ASSERT_OK(RocksDBOptionsParser::VerifyDBOptions(exact, DBOptions(opt),
  87. loaded_db_opts));
  88. ASSERT_OK(RocksDBOptionsParser::VerifyCFOptions(
  89. exact, ColumnFamilyOptions(opt), cf_descs[0].options));
  90. // check with the default rocksdb options and expect failure
  91. ASSERT_NOK(RocksDBOptionsParser::VerifyDBOptions(exact, DBOptions(),
  92. loaded_db_opts));
  93. ASSERT_NOK(RocksDBOptionsParser::VerifyCFOptions(
  94. exact, ColumnFamilyOptions(), cf_descs[0].options));
  95. }
  96. char** argv() { return argv_; }
  97. int argc() { return argc_; }
  98. std::string db_path_;
  99. std::string test_path_;
  100. std::string wal_path_;
  101. char arg_buffer_[kArgBufferSize];
  102. char* argv_[kMaxArgCount];
  103. int argc_ = 0;
  104. int cursor_ = 0;
  105. Random rnd_;
  106. };
  107. namespace {} // namespace
  108. TEST_F(DBBenchTest, OptionsFile) {
  109. const std::string kOptionsFileName = test_path_ + "/OPTIONS_test";
  110. Options opt = GetDefaultOptions();
  111. ASSERT_OK(PersistRocksDBOptions(WriteOptions(), DBOptions(opt), {"default"},
  112. {ColumnFamilyOptions(opt)}, kOptionsFileName,
  113. opt.env->GetFileSystem().get()));
  114. // override the following options as db_bench will not take these
  115. // options from the options file
  116. opt.wal_dir = wal_path_;
  117. RunDbBench(kOptionsFileName);
  118. opt.delayed_write_rate = 16 * 1024 * 1024; // Set by SanitizeOptions
  119. VerifyOptions(opt);
  120. }
  121. TEST_F(DBBenchTest, OptionsFileUniversal) {
  122. const std::string kOptionsFileName = test_path_ + "/OPTIONS_test";
  123. Options opt = GetDefaultOptions(kCompactionStyleUniversal, 1);
  124. ASSERT_OK(PersistRocksDBOptions(WriteOptions(), DBOptions(opt), {"default"},
  125. {ColumnFamilyOptions(opt)}, kOptionsFileName,
  126. opt.env->GetFileSystem().get()));
  127. // override the following options as db_bench will not take these
  128. // options from the options file
  129. opt.wal_dir = wal_path_;
  130. RunDbBench(kOptionsFileName);
  131. VerifyOptions(opt);
  132. }
  133. TEST_F(DBBenchTest, OptionsFileMultiLevelUniversal) {
  134. const std::string kOptionsFileName = test_path_ + "/OPTIONS_test";
  135. Options opt = GetDefaultOptions(kCompactionStyleUniversal, 12);
  136. ASSERT_OK(PersistRocksDBOptions(WriteOptions(), DBOptions(opt), {"default"},
  137. {ColumnFamilyOptions(opt)}, kOptionsFileName,
  138. opt.env->GetFileSystem().get()));
  139. // override the following options as db_bench will not take these
  140. // options from the options file
  141. opt.wal_dir = wal_path_;
  142. RunDbBench(kOptionsFileName);
  143. VerifyOptions(opt);
  144. }
  145. const std::string options_file_content = R"OPTIONS_FILE(
  146. [Version]
  147. rocksdb_version=4.3.1
  148. options_file_version=1.1
  149. [DBOptions]
  150. wal_bytes_per_sync=1048576
  151. delete_obsolete_files_period_micros=0
  152. WAL_ttl_seconds=0
  153. WAL_size_limit_MB=0
  154. db_write_buffer_size=0
  155. max_subcompactions=1
  156. table_cache_numshardbits=4
  157. max_open_files=-1
  158. max_file_opening_threads=10
  159. max_background_compactions=5
  160. use_fsync=false
  161. use_adaptive_mutex=false
  162. max_total_wal_size=18446744073709551615
  163. compaction_readahead_size=0
  164. keep_log_file_num=10
  165. skip_stats_update_on_db_open=false
  166. max_manifest_file_size=18446744073709551615
  167. db_log_dir=
  168. writable_file_max_buffer_size=1048576
  169. paranoid_checks=true
  170. is_fd_close_on_exec=true
  171. bytes_per_sync=1048576
  172. enable_thread_tracking=true
  173. recycle_log_file_num=0
  174. create_missing_column_families=false
  175. log_file_time_to_roll=0
  176. max_background_flushes=1
  177. create_if_missing=true
  178. error_if_exists=false
  179. delayed_write_rate=1048576
  180. manifest_preallocation_size=4194304
  181. allow_mmap_reads=false
  182. allow_mmap_writes=false
  183. use_direct_reads=false
  184. use_direct_io_for_flush_and_compaction=false
  185. stats_dump_period_sec=600
  186. allow_fallocate=true
  187. max_log_file_size=83886080
  188. advise_random_on_open=true
  189. dump_malloc_stats=true
  190. [CFOptions "default"]
  191. compaction_filter_factory=nullptr
  192. table_factory=BlockBasedTable
  193. prefix_extractor=nullptr
  194. comparator=leveldb.BytewiseComparator
  195. compression_per_level=
  196. max_bytes_for_level_base=104857600
  197. bloom_locality=0
  198. target_file_size_base=10485760
  199. memtable_huge_page_size=0
  200. max_successive_merges=1000
  201. max_sequential_skip_in_iterations=8
  202. arena_block_size=52428800
  203. target_file_size_multiplier=1
  204. source_compaction_factor=1
  205. min_write_buffer_number_to_merge=1
  206. max_write_buffer_number=2
  207. write_buffer_size=419430400
  208. max_grandparent_overlap_factor=10
  209. max_bytes_for_level_multiplier=10
  210. memtable_factory=SkipListFactory
  211. compression=kNoCompression
  212. min_partial_merge_operands=2
  213. level0_stop_writes_trigger=100
  214. num_levels=1
  215. level0_slowdown_writes_trigger=50
  216. level0_file_num_compaction_trigger=10
  217. expanded_compaction_factor=25
  218. max_write_buffer_size_to_maintain=0
  219. verify_checksums_in_compaction=true
  220. merge_operator=nullptr
  221. memtable_prefix_bloom_bits=0
  222. memtable_whole_key_filtering=true
  223. paranoid_file_checks=false
  224. inplace_update_num_locks=10000
  225. optimize_filters_for_hits=false
  226. level_compaction_dynamic_level_bytes=false
  227. inplace_update_support=false
  228. compaction_style=kCompactionStyleUniversal
  229. memtable_prefix_bloom_probes=6
  230. filter_deletes=false
  231. hard_pending_compaction_bytes_limit=0
  232. disable_auto_compactions=false
  233. compaction_measure_io_stats=false
  234. enable_blob_files=true
  235. min_blob_size=16
  236. blob_file_size=10485760
  237. blob_compression_type=kNoCompression
  238. enable_blob_garbage_collection=true
  239. blob_garbage_collection_age_cutoff=0.5
  240. blob_garbage_collection_force_threshold=0.75
  241. blob_compaction_readahead_size=262144
  242. blob_file_starting_level=0
  243. prepopulate_blob_cache=kDisable;
  244. [TableOptions/BlockBasedTable "default"]
  245. format_version=0
  246. skip_table_builder_flush=false
  247. cache_index_and_filter_blocks=false
  248. flush_block_policy_factory=FlushBlockBySizePolicyFactory
  249. index_type=kBinarySearch
  250. whole_key_filtering=true
  251. checksum=kCRC32c
  252. no_block_cache=false
  253. block_size=32768
  254. block_size_deviation=10
  255. block_restart_interval=16
  256. filter_policy=rocksdb.BuiltinBloomFilter
  257. )OPTIONS_FILE";
  258. TEST_F(DBBenchTest, OptionsFileFromFile) {
  259. const std::string kOptionsFileName = test_path_ + "/OPTIONS_flash";
  260. std::unique_ptr<WritableFile> writable;
  261. ASSERT_OK(Env::Default()->NewWritableFile(kOptionsFileName, &writable,
  262. EnvOptions()));
  263. ASSERT_OK(writable->Append(options_file_content));
  264. ASSERT_OK(writable->Close());
  265. DBOptions db_opt;
  266. ConfigOptions config_opt;
  267. config_opt.ignore_unknown_options = false;
  268. config_opt.input_strings_escaped = true;
  269. config_opt.env = Env::Default();
  270. std::vector<ColumnFamilyDescriptor> cf_descs;
  271. ASSERT_OK(
  272. LoadOptionsFromFile(config_opt, kOptionsFileName, &db_opt, &cf_descs));
  273. Options opt(db_opt, cf_descs[0].options);
  274. opt.create_if_missing = true;
  275. // override the following options as db_bench will not take these
  276. // options from the options file
  277. opt.wal_dir = wal_path_;
  278. RunDbBench(kOptionsFileName);
  279. VerifyOptions(SanitizeOptions(db_path_, opt));
  280. }
  281. } // namespace ROCKSDB_NAMESPACE
  282. int main(int argc, char** argv) {
  283. ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
  284. ::testing::InitGoogleTest(&argc, argv);
  285. GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
  286. return RUN_ALL_TESTS();
  287. }
  288. #else
  289. int main(int argc, char** argv) {
  290. printf("Skip db_bench_tool_test as the required library GFLAG is missing.");
  291. }
  292. #endif // #ifdef GFLAGS