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 
10 #ifdef GFLAGS
11 #include "db_stress_tool/db_stress_common.h"
12 
ValidateUint32Range(const char * flagname,uint64_t value)13 static bool ValidateUint32Range(const char* flagname, uint64_t value) {
14   if (value > std::numeric_limits<uint32_t>::max()) {
15     fprintf(stderr, "Invalid value for --%s: %lu, overflow\n", flagname,
16             (unsigned long)value);
17     return false;
18   }
19   return true;
20 }
21 
22 DEFINE_uint64(seed, 2341234, "Seed for PRNG");
23 static const bool FLAGS_seed_dummy __attribute__((__unused__)) =
24     RegisterFlagValidator(&FLAGS_seed, &ValidateUint32Range);
25 
26 DEFINE_bool(read_only, false, "True if open DB in read-only mode during tests");
27 
28 DEFINE_int64(max_key, 1 * KB * KB,
29              "Max number of key/values to place in database");
30 
31 DEFINE_int32(max_key_len, 3, "Maximum length of a key in 8-byte units");
32 
33 DEFINE_string(key_len_percent_dist, "",
34               "Percentages of keys of various lengths. For example, 1,30,69 "
35               "means 1% of keys are 8 bytes, 30% are 16 bytes, and 69% are "
36               "24 bytes. If not specified, it will be evenly distributed");
37 
38 DEFINE_int32(key_window_scale_factor, 10,
39               "This value will be multiplied by 100 to come up with a window "
40               "size for varying the key length");
41 
42 DEFINE_int32(column_families, 10, "Number of column families");
43 
44 DEFINE_double(
45     hot_key_alpha, 0,
46     "Use Zipfian distribution to generate the key "
47     "distribution. If it is not specified, write path will use random "
48     "distribution to generate the keys. The parameter is [0, double_max]). "
49     "However, the larger alpha is, the more shewed will be. If alpha is "
50     "larger than 2, it is likely that only 1 key will be accessed. The "
51     "Recommended value is [0.8-1.5]. The distribution is also related to "
52     "max_key and total iterations of generating the hot key. ");
53 
54 DEFINE_string(
55     options_file, "",
56     "The path to a RocksDB options file.  If specified, then db_stress will "
57     "run with the RocksDB options in the default column family of the "
58     "specified options file. Note that, when an options file is provided, "
59     "db_stress will ignore the flag values for all options that may be passed "
60     "via options file.");
61 
62 DEFINE_int64(
63     active_width, 0,
64     "Number of keys in active span of the key-range at any given time. The "
65     "span begins with its left endpoint at key 0, gradually moves rightwards, "
66     "and ends with its right endpoint at max_key. If set to 0, active_width "
67     "will be sanitized to be equal to max_key.");
68 
69 // TODO(noetzli) Add support for single deletes
70 DEFINE_bool(test_batches_snapshots, false,
71             "If set, the test uses MultiGet(), MultiPut() and MultiDelete()"
72             " which read/write/delete multiple keys in a batch. In this mode,"
73             " we do not verify db content by comparing the content with the "
74             "pre-allocated array. Instead, we do partial verification inside"
75             " MultiGet() by checking various values in a batch. Benefit of"
76             " this mode:\n"
77             "\t(a) No need to acquire mutexes during writes (less cache "
78             "flushes in multi-core leading to speed up)\n"
79             "\t(b) No long validation at the end (more speed up)\n"
80             "\t(c) Test snapshot and atomicity of batch writes");
81 
82 DEFINE_bool(atomic_flush, false,
83             "If set, enables atomic flush in the options.\n");
84 
85 DEFINE_bool(test_cf_consistency, false,
86             "If set, runs the stress test dedicated to verifying writes to "
87             "multiple column families are consistent. Setting this implies "
88             "`atomic_flush=true` is set true if `disable_wal=false`.\n");
89 
90 DEFINE_int32(threads, 32, "Number of concurrent threads to run.");
91 
92 DEFINE_int32(ttl, -1,
93              "Opens the db with this ttl value if this is not -1. "
94              "Carefully specify a large value such that verifications on "
95              "deleted values don't fail");
96 
97 DEFINE_int32(value_size_mult, 8,
98              "Size of value will be this number times rand_int(1,3) bytes");
99 
100 DEFINE_int32(compaction_readahead_size, 0, "Compaction readahead size");
101 
102 DEFINE_bool(enable_pipelined_write, false, "Pipeline WAL/memtable writes");
103 
104 DEFINE_bool(verify_before_write, false, "Verify before write");
105 
106 DEFINE_bool(histogram, false, "Print histogram of operation timings");
107 
108 DEFINE_bool(destroy_db_initially, true,
109             "Destroys the database dir before start if this is true");
110 
111 DEFINE_bool(verbose, false, "Verbose");
112 
113 DEFINE_bool(progress_reports, true,
114             "If true, db_stress will report number of finished operations");
115 
116 DEFINE_uint64(db_write_buffer_size,
117               ROCKSDB_NAMESPACE::Options().db_write_buffer_size,
118               "Number of bytes to buffer in all memtables before compacting");
119 
120 DEFINE_int32(
121     write_buffer_size,
122     static_cast<int32_t>(ROCKSDB_NAMESPACE::Options().write_buffer_size),
123     "Number of bytes to buffer in memtable before compacting");
124 
125 DEFINE_int32(max_write_buffer_number,
126              ROCKSDB_NAMESPACE::Options().max_write_buffer_number,
127              "The number of in-memory memtables. "
128              "Each memtable is of size FLAGS_write_buffer_size.");
129 
130 DEFINE_int32(min_write_buffer_number_to_merge,
131              ROCKSDB_NAMESPACE::Options().min_write_buffer_number_to_merge,
132              "The minimum number of write buffers that will be merged together "
133              "before writing to storage. This is cheap because it is an "
134              "in-memory merge. If this feature is not enabled, then all these "
135              "write buffers are flushed to L0 as separate files and this "
136              "increases read amplification because a get request has to check "
137              "in all of these files. Also, an in-memory merge may result in "
138              "writing less data to storage if there are duplicate records in"
139              " each of these individual write buffers.");
140 
141 DEFINE_int32(max_write_buffer_number_to_maintain,
142              ROCKSDB_NAMESPACE::Options().max_write_buffer_number_to_maintain,
143              "The total maximum number of write buffers to maintain in memory "
144              "including copies of buffers that have already been flushed. "
145              "Unlike max_write_buffer_number, this parameter does not affect "
146              "flushing. This controls the minimum amount of write history "
147              "that will be available in memory for conflict checking when "
148              "Transactions are used. If this value is too low, some "
149              "transactions may fail at commit time due to not being able to "
150              "determine whether there were any write conflicts. Setting this "
151              "value to 0 will cause write buffers to be freed immediately "
152              "after they are flushed.  If this value is set to -1, "
153              "'max_write_buffer_number' will be used.");
154 
155 DEFINE_int64(max_write_buffer_size_to_maintain,
156              ROCKSDB_NAMESPACE::Options().max_write_buffer_size_to_maintain,
157              "The total maximum size of write buffers to maintain in memory "
158              "including copies of buffers that have already been flushed. "
159              "Unlike max_write_buffer_number, this parameter does not affect "
160              "flushing. This controls the minimum amount of write history "
161              "that will be available in memory for conflict checking when "
162              "Transactions are used. If this value is too low, some "
163              "transactions may fail at commit time due to not being able to "
164              "determine whether there were any write conflicts. Setting this "
165              "value to 0 will cause write buffers to be freed immediately "
166              "after they are flushed.  If this value is set to -1, "
167              "'max_write_buffer_number' will be used.");
168 
169 DEFINE_double(memtable_prefix_bloom_size_ratio,
170               ROCKSDB_NAMESPACE::Options().memtable_prefix_bloom_size_ratio,
171               "creates prefix blooms for memtables, each with size "
172               "`write_buffer_size * memtable_prefix_bloom_size_ratio`.");
173 
174 DEFINE_bool(memtable_whole_key_filtering,
175             ROCKSDB_NAMESPACE::Options().memtable_whole_key_filtering,
176             "Enable whole key filtering in memtables.");
177 
178 DEFINE_int32(open_files, ROCKSDB_NAMESPACE::Options().max_open_files,
179              "Maximum number of files to keep open at the same time "
180              "(use default if == 0)");
181 
182 DEFINE_int64(compressed_cache_size, -1,
183              "Number of bytes to use as a cache of compressed data."
184              " Negative means use default settings.");
185 
186 DEFINE_int32(compaction_style, ROCKSDB_NAMESPACE::Options().compaction_style,
187              "");
188 
189 DEFINE_int32(level0_file_num_compaction_trigger,
190              ROCKSDB_NAMESPACE::Options().level0_file_num_compaction_trigger,
191              "Level0 compaction start trigger");
192 
193 DEFINE_int32(level0_slowdown_writes_trigger,
194              ROCKSDB_NAMESPACE::Options().level0_slowdown_writes_trigger,
195              "Number of files in level-0 that will slow down writes");
196 
197 DEFINE_int32(level0_stop_writes_trigger,
198              ROCKSDB_NAMESPACE::Options().level0_stop_writes_trigger,
199              "Number of files in level-0 that will trigger put stop.");
200 
201 DEFINE_int32(block_size,
202              static_cast<int32_t>(
203                  ROCKSDB_NAMESPACE::BlockBasedTableOptions().block_size),
204              "Number of bytes in a block.");
205 
206 DEFINE_int32(format_version,
207              static_cast<int32_t>(
208                  ROCKSDB_NAMESPACE::BlockBasedTableOptions().format_version),
209              "Format version of SST files.");
210 
211 DEFINE_int32(
212     index_block_restart_interval,
213     ROCKSDB_NAMESPACE::BlockBasedTableOptions().index_block_restart_interval,
214     "Number of keys between restart points "
215     "for delta encoding of keys in index block.");
216 
217 DEFINE_int32(max_background_compactions,
218              ROCKSDB_NAMESPACE::Options().max_background_compactions,
219              "The maximum number of concurrent background compactions "
220              "that can occur in parallel.");
221 
222 DEFINE_int32(num_bottom_pri_threads, 0,
223              "The number of threads in the bottom-priority thread pool (used "
224              "by universal compaction only).");
225 
226 DEFINE_int32(compaction_thread_pool_adjust_interval, 0,
227              "The interval (in milliseconds) to adjust compaction thread pool "
228              "size. Don't change it periodically if the value is 0.");
229 
230 DEFINE_int32(compaction_thread_pool_variations, 2,
231              "Range of background thread pool size variations when adjusted "
232              "periodically.");
233 
234 DEFINE_int32(max_background_flushes,
235              ROCKSDB_NAMESPACE::Options().max_background_flushes,
236              "The maximum number of concurrent background flushes "
237              "that can occur in parallel.");
238 
239 DEFINE_int32(universal_size_ratio, 0,
240              "The ratio of file sizes that trigger"
241              " compaction in universal style");
242 
243 DEFINE_int32(universal_min_merge_width, 0,
244              "The minimum number of files to "
245              "compact in universal style compaction");
246 
247 DEFINE_int32(universal_max_merge_width, 0,
248              "The max number of files to compact"
249              " in universal style compaction");
250 
251 DEFINE_int32(universal_max_size_amplification_percent, 0,
252              "The max size amplification for universal style compaction");
253 
254 DEFINE_int32(clear_column_family_one_in, 1000000,
255              "With a chance of 1/N, delete a column family and then recreate "
256              "it again. If N == 0, never drop/create column families. "
257              "When test_batches_snapshots is true, this flag has no effect");
258 
259 DEFINE_int32(get_live_files_one_in, 1000000,
260              "With a chance of 1/N, call GetLiveFiles to verify if it returns "
261              "correctly. If N == 0, do not call the interface.");
262 
263 DEFINE_int32(
264     get_sorted_wal_files_one_in, 1000000,
265     "With a chance of 1/N, call GetSortedWalFiles to verify if it returns "
266     "correctly. (Note that this API may legitimately return an error.) If N == "
267     "0, do not call the interface.");
268 
269 DEFINE_int32(
270     get_current_wal_file_one_in, 1000000,
271     "With a chance of 1/N, call GetCurrentWalFile to verify if it returns "
272     "correctly. (Note that this API may legitimately return an error.) If N == "
273     "0, do not call the interface.");
274 
275 DEFINE_int32(set_options_one_in, 0,
276              "With a chance of 1/N, change some random options");
277 
278 DEFINE_int32(set_in_place_one_in, 0,
279              "With a chance of 1/N, toggle in place support option");
280 
281 DEFINE_int64(cache_size, 2LL * KB * KB * KB,
282              "Number of bytes to use as a cache of uncompressed data.");
283 
284 DEFINE_bool(cache_index_and_filter_blocks, false,
285             "True if indexes/filters should be cached in block cache.");
286 
287 DEFINE_bool(use_clock_cache, false,
288             "Replace default LRU block cache with clock cache.");
289 
290 DEFINE_uint64(subcompactions, 1,
291               "Maximum number of subcompactions to divide L0-L1 compactions "
292               "into.");
293 
294 DEFINE_uint64(periodic_compaction_seconds, 1000,
295               "Files older than this value will be picked up for compaction.");
296 
297 DEFINE_uint64(compaction_ttl, 1000,
298               "Files older than TTL will be compacted to the next level.");
299 
300 DEFINE_bool(allow_concurrent_memtable_write, false,
301             "Allow multi-writers to update mem tables in parallel.");
302 
303 DEFINE_bool(enable_write_thread_adaptive_yield, true,
304             "Use a yielding spin loop for brief writer thread waits.");
305 
306 #ifndef ROCKSDB_LITE
307 // BlobDB Options
308 DEFINE_bool(use_blob_db, false, "Use BlobDB.");
309 
310 DEFINE_uint64(blob_db_min_blob_size,
311               ROCKSDB_NAMESPACE::blob_db::BlobDBOptions().min_blob_size,
312               "Smallest blob to store in a file. Blobs smaller than this "
313               "will be inlined with the key in the LSM tree.");
314 
315 DEFINE_uint64(blob_db_bytes_per_sync,
316               ROCKSDB_NAMESPACE::blob_db::BlobDBOptions().bytes_per_sync,
317               "Sync blob files once per every N bytes written.");
318 
319 DEFINE_uint64(blob_db_file_size,
320               ROCKSDB_NAMESPACE::blob_db::BlobDBOptions().blob_file_size,
321               "Target size of each blob file.");
322 
323 DEFINE_bool(
324     blob_db_enable_gc,
325     ROCKSDB_NAMESPACE::blob_db::BlobDBOptions().enable_garbage_collection,
326     "Enable BlobDB garbage collection.");
327 
328 DEFINE_double(
329     blob_db_gc_cutoff,
330     ROCKSDB_NAMESPACE::blob_db::BlobDBOptions().garbage_collection_cutoff,
331     "Cutoff ratio for BlobDB garbage collection.");
332 #endif  // !ROCKSDB_LITE
333 
334 static const bool FLAGS_subcompactions_dummy __attribute__((__unused__)) =
335     RegisterFlagValidator(&FLAGS_subcompactions, &ValidateUint32Range);
336 
ValidateInt32Positive(const char * flagname,int32_t value)337 static bool ValidateInt32Positive(const char* flagname, int32_t value) {
338   if (value < 0) {
339     fprintf(stderr, "Invalid value for --%s: %d, must be >=0\n", flagname,
340             value);
341     return false;
342   }
343   return true;
344 }
345 DEFINE_int32(reopen, 10, "Number of times database reopens");
346 static const bool FLAGS_reopen_dummy __attribute__((__unused__)) =
347     RegisterFlagValidator(&FLAGS_reopen, &ValidateInt32Positive);
348 
349 DEFINE_double(bloom_bits, 10,
350               "Bloom filter bits per key. "
351               "Negative means use default settings.");
352 
353 DEFINE_bool(use_block_based_filter, false,
354             "use block based filter"
355             "instead of full filter for block based table");
356 
357 DEFINE_bool(partition_filters, false,
358             "use partitioned filters "
359             "for block-based table");
360 
361 DEFINE_int32(
362     index_type,
363     static_cast<int32_t>(
364         ROCKSDB_NAMESPACE::BlockBasedTableOptions::kBinarySearch),
365     "Type of block-based table index (see `enum IndexType` in table.h)");
366 
367 DEFINE_string(db, "", "Use the db with the following name.");
368 
369 DEFINE_string(secondaries_base, "",
370               "Use this path as the base path for secondary instances.");
371 
372 DEFINE_bool(test_secondary, false, "Test secondary instance.");
373 
374 DEFINE_string(
375     expected_values_path, "",
376     "File where the array of expected uint32_t values will be stored. If "
377     "provided and non-empty, the DB state will be verified against these "
378     "values after recovery. --max_key and --column_family must be kept the "
379     "same across invocations of this program that use the same "
380     "--expected_values_path.");
381 
382 DEFINE_bool(verify_checksum, false,
383             "Verify checksum for every block read from storage");
384 
385 DEFINE_bool(mmap_read, ROCKSDB_NAMESPACE::Options().allow_mmap_reads,
386             "Allow reads to occur via mmap-ing files");
387 
388 DEFINE_bool(mmap_write, ROCKSDB_NAMESPACE::Options().allow_mmap_writes,
389             "Allow writes to occur via mmap-ing files");
390 
391 DEFINE_bool(use_direct_reads, ROCKSDB_NAMESPACE::Options().use_direct_reads,
392             "Use O_DIRECT for reading data");
393 
394 DEFINE_bool(use_direct_io_for_flush_and_compaction,
395             ROCKSDB_NAMESPACE::Options().use_direct_io_for_flush_and_compaction,
396             "Use O_DIRECT for writing data");
397 
398 DEFINE_bool(statistics, false, "Create database statistics");
399 
400 DEFINE_bool(sync, false, "Sync all writes to disk");
401 
402 DEFINE_bool(use_fsync, false, "If true, issue fsync instead of fdatasync");
403 
404 DEFINE_int32(kill_random_test, 0,
405              "If non-zero, kill at various points in source code with "
406              "probability 1/this");
407 static const bool FLAGS_kill_random_test_dummy __attribute__((__unused__)) =
408     RegisterFlagValidator(&FLAGS_kill_random_test, &ValidateInt32Positive);
409 extern int rocksdb_kill_odds;
410 
411 DEFINE_string(kill_prefix_blacklist, "",
412               "If non-empty, kill points with prefix in the list given will be"
413               " skipped. Items are comma-separated.");
414 extern std::vector<std::string> rocksdb_kill_prefix_blacklist;
415 
416 DEFINE_bool(disable_wal, false, "If true, do not write WAL for write.");
417 
418 DEFINE_uint64(recycle_log_file_num,
419               ROCKSDB_NAMESPACE::Options().recycle_log_file_num,
420               "Number of old WAL files to keep around for later recycling");
421 
422 DEFINE_int64(target_file_size_base,
423              ROCKSDB_NAMESPACE::Options().target_file_size_base,
424              "Target level-1 file size for compaction");
425 
426 DEFINE_int32(target_file_size_multiplier, 1,
427              "A multiplier to compute target level-N file size (N >= 2)");
428 
429 DEFINE_uint64(max_bytes_for_level_base,
430               ROCKSDB_NAMESPACE::Options().max_bytes_for_level_base,
431               "Max bytes for level-1");
432 
433 DEFINE_double(max_bytes_for_level_multiplier, 2,
434               "A multiplier to compute max bytes for level-N (N >= 2)");
435 
436 DEFINE_int32(range_deletion_width, 10,
437              "The width of the range deletion intervals.");
438 
439 DEFINE_uint64(rate_limiter_bytes_per_sec, 0, "Set options.rate_limiter value.");
440 
441 DEFINE_bool(rate_limit_bg_reads, false,
442             "Use options.rate_limiter on compaction reads");
443 
444 DEFINE_uint64(sst_file_manager_bytes_per_sec, 0,
445               "Set `Options::sst_file_manager` to delete at this rate. By "
446               "default the deletion rate is unbounded.");
447 
448 DEFINE_uint64(sst_file_manager_bytes_per_truncate, 0,
449               "Set `Options::sst_file_manager` to delete in chunks of this "
450               "many bytes. By default whole files will be deleted.");
451 
452 DEFINE_bool(use_txn, false,
453             "Use TransactionDB. Currently the default write policy is "
454             "TxnDBWritePolicy::WRITE_PREPARED");
455 
456 DEFINE_uint64(txn_write_policy, 0,
457               "The transaction write policy. Default is "
458               "TxnDBWritePolicy::WRITE_COMMITTED. Note that this should not be "
459               "changed accross crashes.");
460 
461 DEFINE_bool(unordered_write, false,
462             "Turn on the unordered_write feature. This options is currently "
463             "tested only in combination with use_txn=true and "
464             "txn_write_policy=TxnDBWritePolicy::WRITE_PREPARED.");
465 
466 DEFINE_int32(backup_one_in, 0,
467              "If non-zero, then CreateNewBackup() will be called once for "
468              "every N operations on average.  0 indicates CreateNewBackup() "
469              "is disabled.");
470 
471 DEFINE_int32(checkpoint_one_in, 0,
472              "If non-zero, then CreateCheckpoint() will be called once for "
473              "every N operations on average.  0 indicates CreateCheckpoint() "
474              "is disabled.");
475 
476 DEFINE_int32(ingest_external_file_one_in, 0,
477              "If non-zero, then IngestExternalFile() will be called once for "
478              "every N operations on average.  0 indicates IngestExternalFile() "
479              "is disabled.");
480 
481 DEFINE_int32(ingest_external_file_width, 1000,
482              "The width of the ingested external files.");
483 
484 DEFINE_int32(compact_files_one_in, 0,
485              "If non-zero, then CompactFiles() will be called once for every N "
486              "operations on average.  0 indicates CompactFiles() is disabled.");
487 
488 DEFINE_int32(compact_range_one_in, 0,
489              "If non-zero, then CompactRange() will be called once for every N "
490              "operations on average.  0 indicates CompactRange() is disabled.");
491 
492 DEFINE_int32(flush_one_in, 0,
493              "If non-zero, then Flush() will be called once for every N ops "
494              "on average.  0 indicates calls to Flush() are disabled.");
495 
496 DEFINE_int32(pause_background_one_in, 0,
497              "If non-zero, then PauseBackgroundWork()+Continue will be called "
498              "once for every N ops on average.  0 disables.");
499 
500 DEFINE_int32(compact_range_width, 10000,
501              "The width of the ranges passed to CompactRange().");
502 
503 DEFINE_int32(acquire_snapshot_one_in, 0,
504              "If non-zero, then acquires a snapshot once every N operations on "
505              "average.");
506 
507 DEFINE_bool(compare_full_db_state_snapshot, false,
508             "If set we compare state of entire db (in one of the threads) with"
509             "each snapshot.");
510 
511 DEFINE_uint64(snapshot_hold_ops, 0,
512               "If non-zero, then releases snapshots N operations after they're "
513               "acquired.");
514 
515 DEFINE_bool(long_running_snapshots, false,
516             "If set, hold on some some snapshots for much longer time.");
517 
518 DEFINE_bool(use_multiget, false,
519             "If set, use the batched MultiGet API for reads");
520 
ValidateInt32Percent(const char * flagname,int32_t value)521 static bool ValidateInt32Percent(const char* flagname, int32_t value) {
522   if (value < 0 || value > 100) {
523     fprintf(stderr, "Invalid value for --%s: %d, 0<= pct <=100 \n", flagname,
524             value);
525     return false;
526   }
527   return true;
528 }
529 
530 DEFINE_int32(readpercent, 10,
531              "Ratio of reads to total workload (expressed as a percentage)");
532 static const bool FLAGS_readpercent_dummy __attribute__((__unused__)) =
533     RegisterFlagValidator(&FLAGS_readpercent, &ValidateInt32Percent);
534 
535 DEFINE_int32(prefixpercent, 20,
536              "Ratio of prefix iterators to total workload (expressed as a"
537              " percentage)");
538 static const bool FLAGS_prefixpercent_dummy __attribute__((__unused__)) =
539     RegisterFlagValidator(&FLAGS_prefixpercent, &ValidateInt32Percent);
540 
541 DEFINE_int32(writepercent, 45,
542              "Ratio of writes to total workload (expressed as a percentage)");
543 static const bool FLAGS_writepercent_dummy __attribute__((__unused__)) =
544     RegisterFlagValidator(&FLAGS_writepercent, &ValidateInt32Percent);
545 
546 DEFINE_int32(delpercent, 15,
547              "Ratio of deletes to total workload (expressed as a percentage)");
548 static const bool FLAGS_delpercent_dummy __attribute__((__unused__)) =
549     RegisterFlagValidator(&FLAGS_delpercent, &ValidateInt32Percent);
550 
551 DEFINE_int32(delrangepercent, 0,
552              "Ratio of range deletions to total workload (expressed as a "
553              "percentage). Cannot be used with test_batches_snapshots");
554 static const bool FLAGS_delrangepercent_dummy __attribute__((__unused__)) =
555     RegisterFlagValidator(&FLAGS_delrangepercent, &ValidateInt32Percent);
556 
557 DEFINE_int32(nooverwritepercent, 60,
558              "Ratio of keys without overwrite to total workload (expressed as "
559              " a percentage)");
560 static const bool FLAGS_nooverwritepercent_dummy __attribute__((__unused__)) =
561     RegisterFlagValidator(&FLAGS_nooverwritepercent, &ValidateInt32Percent);
562 
563 DEFINE_int32(iterpercent, 10,
564              "Ratio of iterations to total workload"
565              " (expressed as a percentage)");
566 static const bool FLAGS_iterpercent_dummy __attribute__((__unused__)) =
567     RegisterFlagValidator(&FLAGS_iterpercent, &ValidateInt32Percent);
568 
569 DEFINE_uint64(num_iterations, 10, "Number of iterations per MultiIterate run");
570 static const bool FLAGS_num_iterations_dummy __attribute__((__unused__)) =
571     RegisterFlagValidator(&FLAGS_num_iterations, &ValidateUint32Range);
572 
573 DEFINE_string(compression_type, "snappy",
574               "Algorithm to use to compress the database");
575 
576 DEFINE_int32(compression_max_dict_bytes, 0,
577              "Maximum size of dictionary used to prime the compression "
578              "library.");
579 
580 DEFINE_int32(compression_zstd_max_train_bytes, 0,
581              "Maximum size of training data passed to zstd's dictionary "
582              "trainer.");
583 
584 DEFINE_string(bottommost_compression_type, "disable",
585               "Algorithm to use to compress bottommost level of the database. "
586               "\"disable\" means disabling the feature");
587 
588 DEFINE_string(checksum_type, "kCRC32c", "Algorithm to use to checksum blocks");
589 
590 DEFINE_string(hdfs, "", "Name of hdfs environment");
591 
592 DEFINE_string(env_uri, "",
593               "URI for env lookup. Mutually exclusive with --hdfs");
594 
595 DEFINE_uint64(ops_per_thread, 1200000, "Number of operations per thread.");
596 static const bool FLAGS_ops_per_thread_dummy __attribute__((__unused__)) =
597     RegisterFlagValidator(&FLAGS_ops_per_thread, &ValidateUint32Range);
598 
599 DEFINE_uint64(log2_keys_per_lock, 2, "Log2 of number of keys per lock");
600 static const bool FLAGS_log2_keys_per_lock_dummy __attribute__((__unused__)) =
601     RegisterFlagValidator(&FLAGS_log2_keys_per_lock, &ValidateUint32Range);
602 
603 DEFINE_uint64(max_manifest_file_size, 16384, "Maximum size of a MANIFEST file");
604 
605 DEFINE_bool(in_place_update, false, "On true, does inplace update in memtable");
606 
607 DEFINE_int32(secondary_catch_up_one_in, 0,
608              "If non-zero, the secondaries attemp to catch up with the primary "
609              "once for every N operations on average. 0 indicates the "
610              "secondaries do not try to catch up after open.");
611 
612 DEFINE_string(memtablerep, "skip_list", "");
613 
ValidatePrefixSize(const char * flagname,int32_t value)614 inline static bool ValidatePrefixSize(const char* flagname, int32_t value) {
615   if (value < -1 || value > 8) {
616     fprintf(stderr, "Invalid value for --%s: %d. -1 <= PrefixSize <= 8\n",
617             flagname, value);
618     return false;
619   }
620   return true;
621 }
622 DEFINE_int32(prefix_size, 7,
623              "Control the prefix size for HashSkipListRep. "
624              "-1 is disabled.");
625 static const bool FLAGS_prefix_size_dummy __attribute__((__unused__)) =
626     RegisterFlagValidator(&FLAGS_prefix_size, &ValidatePrefixSize);
627 
628 DEFINE_bool(use_merge, false,
629             "On true, replaces all writes with a Merge "
630             "that behaves like a Put");
631 
632 DEFINE_bool(use_full_merge_v1, false,
633             "On true, use a merge operator that implement the deprecated "
634             "version of FullMerge");
635 
636 DEFINE_int32(sync_wal_one_in, 0,
637              "If non-zero, then SyncWAL() will be called once for every N ops "
638              "on average. 0 indicates that calls to SyncWAL() are disabled.");
639 
640 DEFINE_bool(avoid_unnecessary_blocking_io,
641             ROCKSDB_NAMESPACE::Options().avoid_unnecessary_blocking_io,
642             "If true, some expensive cleaning up operations will be moved from "
643             "user reads to high-pri background threads.");
644 
645 DEFINE_bool(write_dbid_to_manifest,
646             ROCKSDB_NAMESPACE::Options().write_dbid_to_manifest,
647             "Write DB_ID to manifest");
648 
649 DEFINE_uint64(max_write_batch_group_size_bytes,
650               ROCKSDB_NAMESPACE::Options().max_write_batch_group_size_bytes,
651               "Max write batch group size");
652 
653 DEFINE_bool(level_compaction_dynamic_level_bytes,
654             ROCKSDB_NAMESPACE::Options().level_compaction_dynamic_level_bytes,
655             "Use dynamic level");
656 
657 DEFINE_int32(verify_checksum_one_in, 0,
658              "If non-zero, then DB::VerifyChecksum() will be called to do"
659              " checksum verification of all the files in the database once for"
660              " every N ops on average. 0 indicates that calls to"
661              " VerifyChecksum() are disabled.");
662 DEFINE_int32(verify_db_one_in, 0,
663              "If non-zero, call VerifyDb() once for every N ops. 0 indicates "
664              "that VerifyDb() will not be called in OperateDb(). Note that "
665              "enabling this can slow down tests.");
666 
667 DEFINE_int32(continuous_verification_interval, 1000,
668              "While test is running, verify db every N milliseconds. 0 "
669              "disables continuous verification.");
670 
671 DEFINE_int32(approximate_size_one_in, 64,
672              "If non-zero, DB::GetApproximateSizes() will be called against"
673              " random key ranges.");
674 #endif  // GFLAGS
675