Coverage Report

Created: 2026-03-31 07:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rocksdb/options/db_options.cc
Line
Count
Source
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
#include "options/db_options.h"
7
8
#include <cinttypes>
9
10
#include "logging/logging.h"
11
#include "options/configurable_helper.h"
12
#include "options/options_helper.h"
13
#include "options/options_parser.h"
14
#include "port/port.h"
15
#include "rocksdb/advanced_cache.h"
16
#include "rocksdb/configurable.h"
17
#include "rocksdb/env.h"
18
#include "rocksdb/file_system.h"
19
#include "rocksdb/listener.h"
20
#include "rocksdb/rate_limiter.h"
21
#include "rocksdb/sst_file_manager.h"
22
#include "rocksdb/statistics.h"
23
#include "rocksdb/system_clock.h"
24
#include "rocksdb/utilities/options_type.h"
25
#include "rocksdb/wal_filter.h"
26
#include "util/string_util.h"
27
28
namespace ROCKSDB_NAMESPACE {
29
static std::unordered_map<std::string, WALRecoveryMode>
30
    wal_recovery_mode_string_map = {
31
        {"kTolerateCorruptedTailRecords",
32
         WALRecoveryMode::kTolerateCorruptedTailRecords},
33
        {"kAbsoluteConsistency", WALRecoveryMode::kAbsoluteConsistency},
34
        {"kPointInTimeRecovery", WALRecoveryMode::kPointInTimeRecovery},
35
        {"kSkipAnyCorruptedRecords",
36
         WALRecoveryMode::kSkipAnyCorruptedRecords}};
37
38
static std::unordered_map<std::string, CacheTier> cache_tier_string_map = {
39
    {"kVolatileTier", CacheTier::kVolatileTier},
40
    {"kVolatileCompressedTier", CacheTier::kVolatileCompressedTier},
41
    {"kNonVolatileBlockTier", CacheTier::kNonVolatileBlockTier}};
42
43
static std::unordered_map<std::string, InfoLogLevel> info_log_level_string_map =
44
    {{"DEBUG_LEVEL", InfoLogLevel::DEBUG_LEVEL},
45
     {"INFO_LEVEL", InfoLogLevel::INFO_LEVEL},
46
     {"WARN_LEVEL", InfoLogLevel::WARN_LEVEL},
47
     {"ERROR_LEVEL", InfoLogLevel::ERROR_LEVEL},
48
     {"FATAL_LEVEL", InfoLogLevel::FATAL_LEVEL},
49
     {"HEADER_LEVEL", InfoLogLevel::HEADER_LEVEL}};
50
51
static std::unordered_map<std::string, OptionTypeInfo>
52
    db_mutable_options_type_info = {
53
        {"allow_os_buffer",
54
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
55
          OptionTypeFlags::kMutable}},
56
        {"base_background_compactions",
57
         {0, OptionType::kInt, OptionVerificationType::kDeprecated,
58
          OptionTypeFlags::kMutable}},
59
        {"max_background_jobs",
60
         {offsetof(struct MutableDBOptions, max_background_jobs),
61
          OptionType::kInt, OptionVerificationType::kNormal,
62
          OptionTypeFlags::kMutable}},
63
        {"max_background_compactions",
64
         {offsetof(struct MutableDBOptions, max_background_compactions),
65
          OptionType::kInt, OptionVerificationType::kNormal,
66
          OptionTypeFlags::kMutable}},
67
        {"max_subcompactions",
68
         {offsetof(struct MutableDBOptions, max_subcompactions),
69
          OptionType::kUInt32T, OptionVerificationType::kNormal,
70
          OptionTypeFlags::kMutable}},
71
        {"avoid_flush_during_shutdown",
72
         {offsetof(struct MutableDBOptions, avoid_flush_during_shutdown),
73
          OptionType::kBoolean, OptionVerificationType::kNormal,
74
          OptionTypeFlags::kMutable}},
75
        {"writable_file_max_buffer_size",
76
         {offsetof(struct MutableDBOptions, writable_file_max_buffer_size),
77
          OptionType::kSizeT, OptionVerificationType::kNormal,
78
          OptionTypeFlags::kMutable}},
79
        {"delayed_write_rate",
80
         {offsetof(struct MutableDBOptions, delayed_write_rate),
81
          OptionType::kUInt64T, OptionVerificationType::kNormal,
82
          OptionTypeFlags::kMutable}},
83
        {"max_total_wal_size",
84
         {offsetof(struct MutableDBOptions, max_total_wal_size),
85
          OptionType::kUInt64T, OptionVerificationType::kNormal,
86
          OptionTypeFlags::kMutable}},
87
        {"delete_obsolete_files_period_micros",
88
         {offsetof(struct MutableDBOptions,
89
                   delete_obsolete_files_period_micros),
90
          OptionType::kUInt64T, OptionVerificationType::kNormal,
91
          OptionTypeFlags::kMutable}},
92
        {"stats_dump_period_sec",
93
         {offsetof(struct MutableDBOptions, stats_dump_period_sec),
94
          OptionType::kUInt, OptionVerificationType::kNormal,
95
          OptionTypeFlags::kMutable}},
96
        {"stats_persist_period_sec",
97
         {offsetof(struct MutableDBOptions, stats_persist_period_sec),
98
          OptionType::kUInt, OptionVerificationType::kNormal,
99
          OptionTypeFlags::kMutable}},
100
        {"stats_history_buffer_size",
101
         {offsetof(struct MutableDBOptions, stats_history_buffer_size),
102
          OptionType::kSizeT, OptionVerificationType::kNormal,
103
          OptionTypeFlags::kMutable}},
104
        {"max_open_files",
105
         {offsetof(struct MutableDBOptions, max_open_files), OptionType::kInt,
106
          OptionVerificationType::kNormal, OptionTypeFlags::kMutable}},
107
        {"bytes_per_sync",
108
         {offsetof(struct MutableDBOptions, bytes_per_sync),
109
          OptionType::kUInt64T, OptionVerificationType::kNormal,
110
          OptionTypeFlags::kMutable}},
111
        {"wal_bytes_per_sync",
112
         {offsetof(struct MutableDBOptions, wal_bytes_per_sync),
113
          OptionType::kUInt64T, OptionVerificationType::kNormal,
114
          OptionTypeFlags::kMutable}},
115
        {"strict_bytes_per_sync",
116
         {offsetof(struct MutableDBOptions, strict_bytes_per_sync),
117
          OptionType::kBoolean, OptionVerificationType::kNormal,
118
          OptionTypeFlags::kMutable}},
119
        {"compaction_readahead_size",
120
         {offsetof(struct MutableDBOptions, compaction_readahead_size),
121
          OptionType::kSizeT, OptionVerificationType::kNormal,
122
          OptionTypeFlags::kMutable}},
123
        {"max_background_flushes",
124
         {offsetof(struct MutableDBOptions, max_background_flushes),
125
          OptionType::kInt, OptionVerificationType::kNormal,
126
          OptionTypeFlags::kMutable}},
127
        {"max_manifest_file_size",
128
         {offsetof(struct MutableDBOptions, max_manifest_file_size),
129
          OptionType::kUInt64T, OptionVerificationType::kNormal,
130
          OptionTypeFlags::kMutable}},
131
        {"max_manifest_space_amp_pct",
132
         {offsetof(struct MutableDBOptions, max_manifest_space_amp_pct),
133
          OptionType::kInt, OptionVerificationType::kNormal,
134
          OptionTypeFlags::kMutable}},
135
        {"manifest_preallocation_size",
136
         {offsetof(struct MutableDBOptions, manifest_preallocation_size),
137
          OptionType::kSizeT, OptionVerificationType::kNormal,
138
          OptionTypeFlags::kMutable}},
139
        {"verify_manifest_content_on_close",
140
         {offsetof(struct MutableDBOptions, verify_manifest_content_on_close),
141
          OptionType::kBoolean, OptionVerificationType::kNormal,
142
          OptionTypeFlags::kMutable}},
143
        {"daily_offpeak_time_utc",
144
         {offsetof(struct MutableDBOptions, daily_offpeak_time_utc),
145
          OptionType::kString, OptionVerificationType::kNormal,
146
          OptionTypeFlags::kMutable}},
147
        {"max_compaction_trigger_wakeup_seconds",
148
         {offsetof(struct MutableDBOptions,
149
                   max_compaction_trigger_wakeup_seconds),
150
          OptionType::kUInt64T, OptionVerificationType::kNormal,
151
          OptionTypeFlags::kMutable}},
152
};
153
154
static std::unordered_map<std::string, OptionTypeInfo>
155
    db_immutable_options_type_info = {
156
        /*
157
         // not yet supported
158
          std::shared_ptr<Cache> row_cache;
159
          std::shared_ptr<DeleteScheduler> delete_scheduler;
160
          std::shared_ptr<Logger> info_log;
161
          std::shared_ptr<RateLimiter> rate_limiter;
162
          std::shared_ptr<Statistics> statistics;
163
          std::vector<DbPath> db_paths;
164
          FileTypeSet checksum_handoff_file_types;
165
          CompactionStyleSet calculate_sst_write_lifetime_hint_set;
166
         */
167
        {"advise_random_on_open",
168
         {offsetof(struct ImmutableDBOptions, advise_random_on_open),
169
          OptionType::kBoolean, OptionVerificationType::kNormal,
170
          OptionTypeFlags::kNone}},
171
        {"allow_mmap_reads",
172
         {offsetof(struct ImmutableDBOptions, allow_mmap_reads),
173
          OptionType::kBoolean, OptionVerificationType::kNormal,
174
          OptionTypeFlags::kNone}},
175
        {"allow_fallocate",
176
         {offsetof(struct ImmutableDBOptions, allow_fallocate),
177
          OptionType::kBoolean, OptionVerificationType::kNormal,
178
          OptionTypeFlags::kNone}},
179
        {"allow_mmap_writes",
180
         {offsetof(struct ImmutableDBOptions, allow_mmap_writes),
181
          OptionType::kBoolean, OptionVerificationType::kNormal,
182
          OptionTypeFlags::kNone}},
183
        {"use_direct_reads",
184
         {offsetof(struct ImmutableDBOptions, use_direct_reads),
185
          OptionType::kBoolean, OptionVerificationType::kNormal,
186
          OptionTypeFlags::kNone}},
187
        {"use_direct_writes",
188
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
189
          OptionTypeFlags::kNone}},
190
        {"use_direct_io_for_flush_and_compaction",
191
         {offsetof(struct ImmutableDBOptions,
192
                   use_direct_io_for_flush_and_compaction),
193
          OptionType::kBoolean, OptionVerificationType::kNormal,
194
          OptionTypeFlags::kNone}},
195
        {"allow_2pc",
196
         {offsetof(struct ImmutableDBOptions, allow_2pc), OptionType::kBoolean,
197
          OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
198
        {"wal_filter",
199
         OptionTypeInfo::AsCustomRawPtr<WalFilter>(
200
             offsetof(struct ImmutableDBOptions, wal_filter),
201
             OptionVerificationType::kByName,
202
             (OptionTypeFlags::kAllowNull | OptionTypeFlags::kCompareNever))},
203
        {"create_if_missing",
204
         {offsetof(struct ImmutableDBOptions, create_if_missing),
205
          OptionType::kBoolean, OptionVerificationType::kNormal,
206
          OptionTypeFlags::kNone}},
207
        {"create_missing_column_families",
208
         {offsetof(struct ImmutableDBOptions, create_missing_column_families),
209
          OptionType::kBoolean, OptionVerificationType::kNormal,
210
          OptionTypeFlags::kNone}},
211
        {"disableDataSync",
212
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
213
          OptionTypeFlags::kNone}},
214
        {"disable_data_sync",  // for compatibility
215
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
216
          OptionTypeFlags::kNone}},
217
        {"enable_thread_tracking",
218
         {offsetof(struct ImmutableDBOptions, enable_thread_tracking),
219
          OptionType::kBoolean, OptionVerificationType::kNormal,
220
          OptionTypeFlags::kNone}},
221
        {"error_if_exists",
222
         {offsetof(struct ImmutableDBOptions, error_if_exists),
223
          OptionType::kBoolean, OptionVerificationType::kNormal,
224
          OptionTypeFlags::kNone}},
225
        {"experimental_allow_mempurge",
226
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
227
          OptionTypeFlags::kNone}},
228
        {"experimental_mempurge_policy",
229
         {0, OptionType::kString, OptionVerificationType::kDeprecated,
230
          OptionTypeFlags::kNone}},
231
        {"experimental_mempurge_threshold",
232
         {0, OptionType::kDouble, OptionVerificationType::kDeprecated,
233
          OptionTypeFlags::kNone}},
234
        {"is_fd_close_on_exec",
235
         {offsetof(struct ImmutableDBOptions, is_fd_close_on_exec),
236
          OptionType::kBoolean, OptionVerificationType::kNormal,
237
          OptionTypeFlags::kNone}},
238
        {"paranoid_checks",
239
         {offsetof(struct ImmutableDBOptions, paranoid_checks),
240
          OptionType::kBoolean, OptionVerificationType::kNormal,
241
          OptionTypeFlags::kNone}},
242
        {"open_files_async",
243
         {offsetof(struct ImmutableDBOptions, open_files_async),
244
          OptionType::kBoolean, OptionVerificationType::kNormal,
245
          OptionTypeFlags::kNone}},
246
        {"flush_verify_memtable_count",
247
         {offsetof(struct ImmutableDBOptions, flush_verify_memtable_count),
248
          OptionType::kBoolean, OptionVerificationType::kNormal,
249
          OptionTypeFlags::kNone}},
250
        {"compaction_verify_record_count",
251
         {offsetof(struct ImmutableDBOptions, compaction_verify_record_count),
252
          OptionType::kBoolean, OptionVerificationType::kNormal,
253
          OptionTypeFlags::kNone}},
254
        {"track_and_verify_wals_in_manifest",
255
         {offsetof(struct ImmutableDBOptions,
256
                   track_and_verify_wals_in_manifest),
257
          OptionType::kBoolean, OptionVerificationType::kNormal,
258
          OptionTypeFlags::kNone}},
259
        {"track_and_verify_wals",
260
         {offsetof(struct ImmutableDBOptions, track_and_verify_wals),
261
          OptionType::kBoolean, OptionVerificationType::kNormal,
262
          OptionTypeFlags::kNone}},
263
        {"verify_sst_unique_id_in_manifest",
264
         {offsetof(struct ImmutableDBOptions, verify_sst_unique_id_in_manifest),
265
          OptionType::kBoolean, OptionVerificationType::kNormal,
266
          OptionTypeFlags::kNone}},
267
        {"skip_log_error_on_recovery",
268
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
269
          OptionTypeFlags::kNone}},
270
        {"skip_stats_update_on_db_open",
271
         {offsetof(struct ImmutableDBOptions, skip_stats_update_on_db_open),
272
          OptionType::kBoolean, OptionVerificationType::kNormal,
273
          OptionTypeFlags::kNone}},
274
        {"skip_checking_sst_file_sizes_on_db_open",
275
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
276
          OptionTypeFlags::kNone}},
277
        {"new_table_reader_for_compaction_inputs",
278
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
279
          OptionTypeFlags::kNone}},
280
        {"random_access_max_buffer_size",
281
         {0, OptionType::kSizeT, OptionVerificationType::kDeprecated,
282
          OptionTypeFlags::kNone}},
283
        {"use_adaptive_mutex",
284
         {offsetof(struct ImmutableDBOptions, use_adaptive_mutex),
285
          OptionType::kBoolean, OptionVerificationType::kNormal,
286
          OptionTypeFlags::kNone}},
287
        {"use_fsync",
288
         {offsetof(struct ImmutableDBOptions, use_fsync), OptionType::kBoolean,
289
          OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
290
        {"max_file_opening_threads",
291
         {offsetof(struct ImmutableDBOptions, max_file_opening_threads),
292
          OptionType::kInt, OptionVerificationType::kNormal,
293
          OptionTypeFlags::kNone}},
294
        {"table_cache_numshardbits",
295
         {offsetof(struct ImmutableDBOptions, table_cache_numshardbits),
296
          OptionType::kInt, OptionVerificationType::kNormal,
297
          OptionTypeFlags::kNone}},
298
        {"db_write_buffer_size",
299
         {offsetof(struct ImmutableDBOptions, db_write_buffer_size),
300
          OptionType::kSizeT, OptionVerificationType::kNormal,
301
          OptionTypeFlags::kNone}},
302
        {"keep_log_file_num",
303
         {offsetof(struct ImmutableDBOptions, keep_log_file_num),
304
          OptionType::kSizeT, OptionVerificationType::kNormal,
305
          OptionTypeFlags::kNone}},
306
        {"recycle_log_file_num",
307
         {offsetof(struct ImmutableDBOptions, recycle_log_file_num),
308
          OptionType::kSizeT, OptionVerificationType::kNormal,
309
          OptionTypeFlags::kNone}},
310
        {"log_file_time_to_roll",
311
         {offsetof(struct ImmutableDBOptions, log_file_time_to_roll),
312
          OptionType::kSizeT, OptionVerificationType::kNormal,
313
          OptionTypeFlags::kNone}},
314
        {"max_log_file_size",
315
         {offsetof(struct ImmutableDBOptions, max_log_file_size),
316
          OptionType::kSizeT, OptionVerificationType::kNormal,
317
          OptionTypeFlags::kNone}},
318
        {"db_log_dir",
319
         {offsetof(struct ImmutableDBOptions, db_log_dir), OptionType::kString,
320
          OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
321
        {"wal_dir",
322
         {offsetof(struct ImmutableDBOptions, wal_dir), OptionType::kString,
323
          OptionVerificationType::kNormal, OptionTypeFlags::kNone}},
324
        {"WAL_size_limit_MB",
325
         {offsetof(struct ImmutableDBOptions, WAL_size_limit_MB),
326
          OptionType::kUInt64T, OptionVerificationType::kNormal,
327
          OptionTypeFlags::kNone}},
328
        {"WAL_ttl_seconds",
329
         {offsetof(struct ImmutableDBOptions, WAL_ttl_seconds),
330
          OptionType::kUInt64T, OptionVerificationType::kNormal,
331
          OptionTypeFlags::kNone}},
332
        {"persist_stats_to_disk",
333
         {offsetof(struct ImmutableDBOptions, persist_stats_to_disk),
334
          OptionType::kBoolean, OptionVerificationType::kNormal,
335
          OptionTypeFlags::kNone}},
336
        {"fail_if_options_file_error",
337
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
338
          OptionTypeFlags::kNone}},
339
        {"enable_pipelined_write",
340
         {offsetof(struct ImmutableDBOptions, enable_pipelined_write),
341
          OptionType::kBoolean, OptionVerificationType::kNormal,
342
          OptionTypeFlags::kNone}},
343
        {"unordered_write",
344
         {offsetof(struct ImmutableDBOptions, unordered_write),
345
          OptionType::kBoolean, OptionVerificationType::kNormal,
346
          OptionTypeFlags::kNone}},
347
        {"allow_concurrent_memtable_write",
348
         {offsetof(struct ImmutableDBOptions, allow_concurrent_memtable_write),
349
          OptionType::kBoolean, OptionVerificationType::kNormal,
350
          OptionTypeFlags::kNone}},
351
        {"wal_recovery_mode",
352
         OptionTypeInfo::Enum<WALRecoveryMode>(
353
             offsetof(struct ImmutableDBOptions, wal_recovery_mode),
354
             &wal_recovery_mode_string_map)},
355
        {"enable_write_thread_adaptive_yield",
356
         {offsetof(struct ImmutableDBOptions,
357
                   enable_write_thread_adaptive_yield),
358
          OptionType::kBoolean, OptionVerificationType::kNormal,
359
          OptionTypeFlags::kNone}},
360
        {"write_thread_slow_yield_usec",
361
         {offsetof(struct ImmutableDBOptions, write_thread_slow_yield_usec),
362
          OptionType::kUInt64T, OptionVerificationType::kNormal,
363
          OptionTypeFlags::kNone}},
364
        {"max_write_batch_group_size_bytes",
365
         {offsetof(struct ImmutableDBOptions, max_write_batch_group_size_bytes),
366
          OptionType::kUInt64T, OptionVerificationType::kNormal,
367
          OptionTypeFlags::kNone}},
368
        {"write_thread_max_yield_usec",
369
         {offsetof(struct ImmutableDBOptions, write_thread_max_yield_usec),
370
          OptionType::kUInt64T, OptionVerificationType::kNormal,
371
          OptionTypeFlags::kNone}},
372
        {"access_hint_on_compaction_start",
373
         OptionTypeInfo::Enum<bool>(0, nullptr, OptionTypeFlags::kNone,
374
                                    OptionVerificationType::kDeprecated)},
375
        {"info_log_level",
376
         OptionTypeInfo::Enum<InfoLogLevel>(
377
             offsetof(struct ImmutableDBOptions, info_log_level),
378
             &info_log_level_string_map)},
379
        {"dump_malloc_stats",
380
         {offsetof(struct ImmutableDBOptions, dump_malloc_stats),
381
          OptionType::kBoolean, OptionVerificationType::kNormal,
382
          OptionTypeFlags::kNone}},
383
        {"avoid_flush_during_recovery",
384
         {offsetof(struct ImmutableDBOptions, avoid_flush_during_recovery),
385
          OptionType::kBoolean, OptionVerificationType::kNormal,
386
          OptionTypeFlags::kNone}},
387
        {"enforce_write_buffer_manager_during_recovery",
388
         {offsetof(struct ImmutableDBOptions,
389
                   enforce_write_buffer_manager_during_recovery),
390
          OptionType::kBoolean, OptionVerificationType::kNormal,
391
          OptionTypeFlags::kNone}},
392
        {"allow_ingest_behind",
393
         {offsetof(struct ImmutableDBOptions, allow_ingest_behind),
394
          OptionType::kBoolean, OptionVerificationType::kNormal,
395
          OptionTypeFlags::kNone}},
396
        {"preserve_deletes",
397
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
398
          OptionTypeFlags::kNone}},
399
        {"concurrent_prepare",  // Deprecated by two_write_queues
400
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
401
          OptionTypeFlags::kNone}},
402
        {"two_write_queues",
403
         {offsetof(struct ImmutableDBOptions, two_write_queues),
404
          OptionType::kBoolean, OptionVerificationType::kNormal,
405
          OptionTypeFlags::kNone}},
406
        {"manual_wal_flush",
407
         {offsetof(struct ImmutableDBOptions, manual_wal_flush),
408
          OptionType::kBoolean, OptionVerificationType::kNormal,
409
          OptionTypeFlags::kNone}},
410
        {"wal_compression",
411
         {offsetof(struct ImmutableDBOptions, wal_compression),
412
          OptionType::kCompressionType, OptionVerificationType::kNormal,
413
          OptionTypeFlags::kNone}},
414
        {"background_close_inactive_wals",
415
         {offsetof(struct ImmutableDBOptions, background_close_inactive_wals),
416
          OptionType::kBoolean, OptionVerificationType::kNormal,
417
          OptionTypeFlags::kNone}},
418
        {"seq_per_batch",
419
         {0, OptionType::kBoolean, OptionVerificationType::kDeprecated,
420
          OptionTypeFlags::kNone}},
421
        {"atomic_flush",
422
         {offsetof(struct ImmutableDBOptions, atomic_flush),
423
          OptionType::kBoolean, OptionVerificationType::kNormal,
424
          OptionTypeFlags::kNone}},
425
        {"avoid_unnecessary_blocking_io",
426
         {offsetof(struct ImmutableDBOptions, avoid_unnecessary_blocking_io),
427
          OptionType::kBoolean, OptionVerificationType::kNormal,
428
          OptionTypeFlags::kNone}},
429
        {"prefix_seek_opt_in_only",
430
         {offsetof(struct ImmutableDBOptions, prefix_seek_opt_in_only),
431
          OptionType::kBoolean, OptionVerificationType::kNormal,
432
          OptionTypeFlags::kNone}},
433
        {"write_dbid_to_manifest",
434
         {offsetof(struct ImmutableDBOptions, write_dbid_to_manifest),
435
          OptionType::kBoolean, OptionVerificationType::kNormal,
436
          OptionTypeFlags::kNone}},
437
        {"write_identity_file",
438
         {offsetof(struct ImmutableDBOptions, write_identity_file),
439
          OptionType::kBoolean, OptionVerificationType::kNormal,
440
          OptionTypeFlags::kNone}},
441
        {"log_readahead_size",
442
         {offsetof(struct ImmutableDBOptions, log_readahead_size),
443
          OptionType::kSizeT, OptionVerificationType::kNormal,
444
          OptionTypeFlags::kNone}},
445
        {"best_efforts_recovery",
446
         {offsetof(struct ImmutableDBOptions, best_efforts_recovery),
447
          OptionType::kBoolean, OptionVerificationType::kNormal,
448
          OptionTypeFlags::kNone}},
449
        {"max_bgerror_resume_count",
450
         {offsetof(struct ImmutableDBOptions, max_bgerror_resume_count),
451
          OptionType::kInt, OptionVerificationType::kNormal,
452
          OptionTypeFlags::kNone}},
453
        {"bgerror_resume_retry_interval",
454
         {offsetof(struct ImmutableDBOptions, bgerror_resume_retry_interval),
455
          OptionType::kUInt64T, OptionVerificationType::kNormal,
456
          OptionTypeFlags::kNone}},
457
        {"db_host_id",
458
         {offsetof(struct ImmutableDBOptions, db_host_id), OptionType::kString,
459
          OptionVerificationType::kNormal, OptionTypeFlags::kCompareNever}},
460
        // Temporarily deprecated due to race conditions (examples in PR 10375).
461
        {"rate_limiter",
462
         {offsetof(struct ImmutableDBOptions, rate_limiter),
463
          OptionType::kUnknown, OptionVerificationType::kDeprecated,
464
          OptionTypeFlags::kDontSerialize | OptionTypeFlags::kCompareNever}},
465
        // The following properties were handled as special cases in ParseOption
466
        // This means that the properties could be read from the options file
467
        // but never written to the file or compared to each other.
468
        {"rate_limiter_bytes_per_sec",
469
         {offsetof(struct ImmutableDBOptions, rate_limiter),
470
          OptionType::kUnknown, OptionVerificationType::kNormal,
471
          (OptionTypeFlags::kDontSerialize | OptionTypeFlags::kCompareNever),
472
          // Parse the input value as a RateLimiter
473
          [](const ConfigOptions& /*opts*/, const std::string& /*name*/,
474
0
             const std::string& value, void* addr) {
475
0
            auto limiter = static_cast<std::shared_ptr<RateLimiter>*>(addr);
476
0
            limiter->reset(NewGenericRateLimiter(
477
0
                static_cast<int64_t>(ParseUint64(value))));
478
0
            return Status::OK();
479
0
          }}},
480
        {"env",  //**TODO: Should this be kCustomizable?
481
         OptionTypeInfo(
482
             offsetof(struct ImmutableDBOptions, env), OptionType::kUnknown,
483
             OptionVerificationType::kNormal,
484
             (OptionTypeFlags::kDontSerialize | OptionTypeFlags::kCompareNever))
485
             .SetParseFunc([](const ConfigOptions& opts,
486
                              const std::string& /*name*/,
487
0
                              const std::string& value, void* addr) {
488
               // Parse the input value as an Env
489
0
               auto old_env = static_cast<Env**>(addr);  // Get the old value
490
0
               Env* new_env = *old_env;                  // Set new to old
491
0
               Status s = Env::CreateFromString(opts, value,
492
0
                                                &new_env);  // Update new value
493
0
               if (s.ok()) {                                // It worked
494
0
                 *old_env = new_env;  // Update the old one
495
0
               }
496
0
               return s;
497
0
             })
498
             .SetPrepareFunc([](const ConfigOptions& opts,
499
69.4k
                                const std::string& /*name*/, void* addr) {
500
69.4k
               auto env = static_cast<Env**>(addr);
501
69.4k
               return (*env)->PrepareOptions(opts);
502
69.4k
             })
503
             .SetValidateFunc([](const DBOptions& db_opts,
504
                                 const ColumnFamilyOptions& cf_opts,
505
                                 const std::string& /*name*/,
506
54.8k
                                 const void* addr) {
507
54.8k
               const auto env = static_cast<const Env* const*>(addr);
508
54.8k
               return (*env)->ValidateOptions(db_opts, cf_opts);
509
54.8k
             })},
510
        {"allow_data_in_errors",
511
         {offsetof(struct ImmutableDBOptions, allow_data_in_errors),
512
          OptionType::kBoolean, OptionVerificationType::kNormal,
513
          OptionTypeFlags::kNone}},
514
        {"file_checksum_gen_factory",
515
         OptionTypeInfo::AsCustomSharedPtr<FileChecksumGenFactory>(
516
             offsetof(struct ImmutableDBOptions, file_checksum_gen_factory),
517
             OptionVerificationType::kByNameAllowFromNull,
518
             OptionTypeFlags::kAllowNull)},
519
        {"statistics",
520
         OptionTypeInfo::AsCustomSharedPtr<Statistics>(
521
             // Statistics should not be compared and can be null
522
             // Statistics are maked "don't serialize" until they can be shared
523
             // between DBs
524
             offsetof(struct ImmutableDBOptions, statistics),
525
             OptionVerificationType::kNormal,
526
             OptionTypeFlags::kCompareNever | OptionTypeFlags::kDontSerialize |
527
                 OptionTypeFlags::kAllowNull)},
528
        // Allow EventListeners that have a non-empty Name() to be read/written
529
        // as options Each listener will either be
530
        // - A simple name (e.g. "MyEventListener")
531
        // - A name with properties (e.g. "{id=MyListener1; timeout=60}"
532
        // Multiple listeners will be separated by a ":":
533
        //   - "MyListener0;{id=MyListener1; timeout=60}
534
        {"listeners",
535
         {offsetof(struct ImmutableDBOptions, listeners), OptionType::kVector,
536
          OptionVerificationType::kByNameAllowNull,
537
          OptionTypeFlags::kCompareNever,
538
          [](const ConfigOptions& opts, const std::string& /*name*/,
539
0
             const std::string& value, void* addr) {
540
0
            ConfigOptions embedded = opts;
541
0
            embedded.ignore_unsupported_options = true;
542
0
            std::vector<std::shared_ptr<EventListener>> listeners;
543
0
            Status s;
544
0
            for (size_t start = 0, end = 0;
545
0
                 s.ok() && start < value.size() && end != std::string::npos;
546
0
                 start = end + 1) {
547
0
              std::string token;
548
0
              s = OptionTypeInfo::NextToken(value, ':', start, &end, &token);
549
0
              if (s.ok() && !token.empty()) {
550
0
                std::shared_ptr<EventListener> listener;
551
0
                s = EventListener::CreateFromString(embedded, token, &listener);
552
0
                if (s.ok() && listener != nullptr) {
553
0
                  listeners.push_back(listener);
554
0
                }
555
0
              }
556
0
            }
557
0
            if (s.ok()) {  // It worked
558
0
              *(static_cast<std::vector<std::shared_ptr<EventListener>>*>(
559
0
                  addr)) = listeners;
560
0
            }
561
0
            return s;
562
0
          },
563
          [](const ConfigOptions& opts, const std::string& /*name*/,
564
138k
             const void* addr, std::string* value) {
565
138k
            const auto listeners =
566
138k
                static_cast<const std::vector<std::shared_ptr<EventListener>>*>(
567
138k
                    addr);
568
138k
            ConfigOptions embedded = opts;
569
138k
            embedded.delimiter = ";";
570
138k
            int printed = 0;
571
138k
            for (const auto& listener : *listeners) {
572
0
              auto id = listener->GetId();
573
0
              if (!id.empty()) {
574
0
                std::string elem_str = listener->ToString(embedded, "");
575
0
                if (printed++ == 0) {
576
0
                  value->append("{");
577
0
                } else {
578
0
                  value->append(":");
579
0
                }
580
0
                value->append(elem_str);
581
0
              }
582
0
            }
583
138k
            if (printed > 0) {
584
0
              value->append("}");
585
0
            }
586
138k
            return Status::OK();
587
138k
          },
588
          nullptr}},
589
        {"lowest_used_cache_tier",
590
         OptionTypeInfo::Enum<CacheTier>(
591
             offsetof(struct ImmutableDBOptions, lowest_used_cache_tier),
592
             &cache_tier_string_map, OptionTypeFlags::kNone)},
593
        {"enforce_single_del_contracts",
594
         {offsetof(struct ImmutableDBOptions, enforce_single_del_contracts),
595
          OptionType::kBoolean, OptionVerificationType::kNormal,
596
          OptionTypeFlags::kNone}},
597
        {"follower_refresh_catchup_period_ms",
598
         {offsetof(struct ImmutableDBOptions,
599
                   follower_refresh_catchup_period_ms),
600
          OptionType::kUInt64T, OptionVerificationType::kNormal,
601
          OptionTypeFlags::kNone}},
602
        {"follower_catchup_retry_count",
603
         {offsetof(struct ImmutableDBOptions, follower_catchup_retry_count),
604
          OptionType::kUInt64T, OptionVerificationType::kNormal,
605
          OptionTypeFlags::kNone}},
606
        {"follower_catchup_retry_wait_ms",
607
         {offsetof(struct ImmutableDBOptions, follower_catchup_retry_wait_ms),
608
          OptionType::kUInt64T, OptionVerificationType::kNormal,
609
          OptionTypeFlags::kNone}},
610
        {"metadata_write_temperature",
611
         {offsetof(struct ImmutableDBOptions, metadata_write_temperature),
612
          OptionType::kTemperature, OptionVerificationType::kNormal,
613
          OptionTypeFlags::kNone}},
614
        {"wal_write_temperature",
615
         {offsetof(struct ImmutableDBOptions, wal_write_temperature),
616
          OptionType::kTemperature, OptionVerificationType::kNormal,
617
          OptionTypeFlags::kNone}},
618
};
619
620
const std::string OptionsHelper::kDBOptionsName = "DBOptions";
621
622
class MutableDBConfigurable : public Configurable {
623
 public:
624
  explicit MutableDBConfigurable(
625
      const MutableDBOptions& mdb,
626
      const std::unordered_map<std::string, std::string>* map = nullptr)
627
332k
      : mutable_(mdb), opt_map_(map) {
628
332k
    RegisterOptions(&mutable_, &db_mutable_options_type_info);
629
332k
  }
630
631
  bool OptionsAreEqual(const ConfigOptions& config_options,
632
                       const OptionTypeInfo& opt_info,
633
                       const std::string& opt_name, const void* const this_ptr,
634
                       const void* const that_ptr,
635
6.38M
                       std::string* mismatch) const override {
636
6.38M
    bool equals = opt_info.AreEqual(config_options, opt_name, this_ptr,
637
6.38M
                                    that_ptr, mismatch);
638
6.38M
    if (!equals && opt_info.IsByName()) {
639
0
      if (opt_map_ == nullptr) {
640
0
        equals = true;
641
0
      } else {
642
0
        const auto& iter = opt_map_->find(opt_name);
643
0
        if (iter == opt_map_->end()) {
644
0
          equals = true;
645
0
        } else {
646
0
          equals = opt_info.AreEqualByName(config_options, opt_name, this_ptr,
647
0
                                           iter->second);
648
0
        }
649
0
      }
650
0
      if (equals) {  // False alarm, clear mismatch
651
0
        *mismatch = "";
652
0
      }
653
0
    }
654
6.38M
    if (equals && opt_info.IsConfigurable() && opt_map_ != nullptr) {
655
69.4k
      const auto* this_config = opt_info.AsRawPointer<Configurable>(this_ptr);
656
69.4k
      if (this_config == nullptr) {
657
69.4k
        const auto& iter = opt_map_->find(opt_name);
658
        // If the name exists in the map and is not empty/null,
659
        // then the this_config should be set.
660
69.4k
        if (iter != opt_map_->end() && !iter->second.empty() &&
661
69.4k
            iter->second != kNullptrString) {
662
0
          *mismatch = opt_name;
663
0
          equals = false;
664
0
        }
665
69.4k
      }
666
69.4k
    }
667
6.38M
    return equals;
668
6.38M
  }
669
670
 protected:
671
  MutableDBOptions mutable_;
672
  const std::unordered_map<std::string, std::string>* opt_map_;
673
};
674
675
class DBOptionsConfigurable : public MutableDBConfigurable {
676
 public:
677
  explicit DBOptionsConfigurable(
678
      const DBOptions& opts,
679
      const std::unordered_map<std::string, std::string>* map = nullptr)
680
332k
      : MutableDBConfigurable(MutableDBOptions{opts}, map), db_options_(opts) {
681
    // The ImmutableDBOptions currently requires the env to be non-null.  Make
682
    // sure it is
683
332k
    if (opts.env != nullptr) {
684
332k
      immutable_ = ImmutableDBOptions(opts);
685
332k
    } else {
686
0
      DBOptions copy = opts;
687
0
      copy.env = Env::Default();
688
0
      immutable_ = ImmutableDBOptions(copy);
689
0
    }
690
332k
    RegisterOptions(&immutable_, &db_immutable_options_type_info);
691
332k
  }
692
693
 protected:
694
  Status ConfigureOptions(
695
      const ConfigOptions& config_options,
696
      const std::unordered_map<std::string, std::string>& opts_map,
697
69.4k
      std::unordered_map<std::string, std::string>* unused) override {
698
69.4k
    Status s = Configurable::ConfigureOptions(config_options, opts_map, unused);
699
69.4k
    if (s.ok()) {
700
69.4k
      db_options_ = BuildDBOptions(immutable_, mutable_);
701
69.4k
      s = PrepareOptions(config_options);
702
69.4k
    }
703
69.4k
    return s;
704
69.4k
  }
705
706
347k
  const void* GetOptionsPtr(const std::string& name) const override {
707
347k
    if (name == OptionsHelper::kDBOptionsName) {
708
69.4k
      return &db_options_;
709
277k
    } else {
710
277k
      return MutableDBConfigurable::GetOptionsPtr(name);
711
277k
    }
712
347k
  }
713
714
 private:
715
  ImmutableDBOptions immutable_;
716
  DBOptions db_options_;
717
};
718
719
std::unique_ptr<Configurable> DBOptionsAsConfigurable(
720
0
    const MutableDBOptions& opts) {
721
0
  std::unique_ptr<Configurable> ptr(new MutableDBConfigurable(opts));
722
0
  return ptr;
723
0
}
724
std::unique_ptr<Configurable> DBOptionsAsConfigurable(
725
    const DBOptions& opts,
726
332k
    const std::unordered_map<std::string, std::string>* opt_map) {
727
332k
  std::unique_ptr<Configurable> ptr(new DBOptionsConfigurable(opts, opt_map));
728
332k
  return ptr;
729
332k
}
730
731
332k
ImmutableDBOptions::ImmutableDBOptions() : ImmutableDBOptions(DBOptions{}) {}
732
733
ImmutableDBOptions::ImmutableDBOptions(const DBOptions& options)
734
767k
    : create_if_missing(options.create_if_missing),
735
767k
      create_missing_column_families(options.create_missing_column_families),
736
767k
      error_if_exists(options.error_if_exists),
737
767k
      paranoid_checks(options.paranoid_checks),
738
767k
      open_files_async(options.open_files_async),
739
767k
      flush_verify_memtable_count(options.flush_verify_memtable_count),
740
767k
      compaction_verify_record_count(options.compaction_verify_record_count),
741
      track_and_verify_wals_in_manifest(
742
767k
          options.track_and_verify_wals_in_manifest),
743
767k
      track_and_verify_wals(options.track_and_verify_wals),
744
      verify_sst_unique_id_in_manifest(
745
767k
          options.verify_sst_unique_id_in_manifest),
746
767k
      env(options.env),
747
767k
      rate_limiter(options.rate_limiter),
748
767k
      sst_file_manager(options.sst_file_manager),
749
767k
      info_log(options.info_log),
750
767k
      info_log_level(options.info_log_level),
751
767k
      max_file_opening_threads(options.max_file_opening_threads),
752
767k
      statistics(options.statistics),
753
767k
      use_fsync(options.use_fsync),
754
767k
      db_paths(options.db_paths),
755
767k
      db_log_dir(options.db_log_dir),
756
767k
      wal_dir(options.wal_dir),
757
767k
      max_log_file_size(options.max_log_file_size),
758
767k
      log_file_time_to_roll(options.log_file_time_to_roll),
759
767k
      keep_log_file_num(options.keep_log_file_num),
760
767k
      recycle_log_file_num(options.recycle_log_file_num),
761
767k
      table_cache_numshardbits(options.table_cache_numshardbits),
762
767k
      WAL_ttl_seconds(options.WAL_ttl_seconds),
763
767k
      WAL_size_limit_MB(options.WAL_size_limit_MB),
764
      max_write_batch_group_size_bytes(
765
767k
          options.max_write_batch_group_size_bytes),
766
767k
      allow_mmap_reads(options.allow_mmap_reads),
767
767k
      allow_mmap_writes(options.allow_mmap_writes),
768
767k
      use_direct_reads(options.use_direct_reads),
769
      use_direct_io_for_flush_and_compaction(
770
767k
          options.use_direct_io_for_flush_and_compaction),
771
767k
      allow_fallocate(options.allow_fallocate),
772
767k
      is_fd_close_on_exec(options.is_fd_close_on_exec),
773
767k
      advise_random_on_open(options.advise_random_on_open),
774
767k
      db_write_buffer_size(options.db_write_buffer_size),
775
767k
      write_buffer_manager(options.write_buffer_manager),
776
767k
      use_adaptive_mutex(options.use_adaptive_mutex),
777
767k
      listeners(options.listeners),
778
767k
      enable_thread_tracking(options.enable_thread_tracking),
779
767k
      enable_pipelined_write(options.enable_pipelined_write),
780
767k
      unordered_write(options.unordered_write),
781
767k
      allow_concurrent_memtable_write(options.allow_concurrent_memtable_write),
782
      enable_write_thread_adaptive_yield(
783
767k
          options.enable_write_thread_adaptive_yield),
784
767k
      write_thread_max_yield_usec(options.write_thread_max_yield_usec),
785
767k
      write_thread_slow_yield_usec(options.write_thread_slow_yield_usec),
786
767k
      skip_stats_update_on_db_open(options.skip_stats_update_on_db_open),
787
767k
      wal_recovery_mode(options.wal_recovery_mode),
788
767k
      allow_2pc(options.allow_2pc),
789
767k
      row_cache(options.row_cache),
790
767k
      wal_filter(options.wal_filter),
791
767k
      dump_malloc_stats(options.dump_malloc_stats),
792
767k
      avoid_flush_during_recovery(options.avoid_flush_during_recovery),
793
      enforce_write_buffer_manager_during_recovery(
794
767k
          options.enforce_write_buffer_manager_during_recovery),
795
767k
      allow_ingest_behind(options.allow_ingest_behind),
796
767k
      two_write_queues(options.two_write_queues),
797
767k
      manual_wal_flush(options.manual_wal_flush),
798
767k
      wal_compression(options.wal_compression),
799
767k
      background_close_inactive_wals(options.background_close_inactive_wals),
800
767k
      atomic_flush(options.atomic_flush),
801
767k
      avoid_unnecessary_blocking_io(options.avoid_unnecessary_blocking_io),
802
767k
      prefix_seek_opt_in_only(options.prefix_seek_opt_in_only),
803
767k
      persist_stats_to_disk(options.persist_stats_to_disk),
804
767k
      write_dbid_to_manifest(options.write_dbid_to_manifest),
805
767k
      write_identity_file(options.write_identity_file),
806
767k
      log_readahead_size(options.log_readahead_size),
807
767k
      file_checksum_gen_factory(options.file_checksum_gen_factory),
808
767k
      best_efforts_recovery(options.best_efforts_recovery),
809
767k
      max_bgerror_resume_count(options.max_bgerror_resume_count),
810
767k
      bgerror_resume_retry_interval(options.bgerror_resume_retry_interval),
811
767k
      allow_data_in_errors(options.allow_data_in_errors),
812
767k
      db_host_id(options.db_host_id),
813
767k
      checksum_handoff_file_types(options.checksum_handoff_file_types),
814
767k
      lowest_used_cache_tier(options.lowest_used_cache_tier),
815
767k
      compaction_service(options.compaction_service),
816
767k
      enforce_single_del_contracts(options.enforce_single_del_contracts),
817
      follower_refresh_catchup_period_ms(
818
767k
          options.follower_refresh_catchup_period_ms),
819
767k
      follower_catchup_retry_count(options.follower_catchup_retry_count),
820
767k
      follower_catchup_retry_wait_ms(options.follower_catchup_retry_wait_ms),
821
767k
      metadata_write_temperature(options.metadata_write_temperature),
822
767k
      wal_write_temperature(options.wal_write_temperature),
823
767k
      calculate_sst_write_lifetime_hint_set(
824
767k
          options.calculate_sst_write_lifetime_hint_set) {
825
767k
  fs = env->GetFileSystem();
826
767k
  clock = env->GetSystemClock().get();
827
767k
  logger = info_log.get();
828
767k
  stats = statistics.get();
829
767k
}
830
831
40.2k
void ImmutableDBOptions::Dump(Logger* log) const {
832
40.2k
  ROCKS_LOG_HEADER(log, "                        Options.error_if_exists: %d",
833
40.2k
                   error_if_exists);
834
40.2k
  ROCKS_LOG_HEADER(log, "                      Options.create_if_missing: %d",
835
40.2k
                   create_if_missing);
836
40.2k
  ROCKS_LOG_HEADER(log, "                        Options.paranoid_checks: %d",
837
40.2k
                   paranoid_checks);
838
40.2k
  ROCKS_LOG_HEADER(log, "                       Options.open_files_async: %d",
839
40.2k
                   open_files_async);
840
40.2k
  ROCKS_LOG_HEADER(log, "            Options.flush_verify_memtable_count: %d",
841
40.2k
                   flush_verify_memtable_count);
842
40.2k
  ROCKS_LOG_HEADER(log, "         Options.compaction_verify_record_count: %d",
843
40.2k
                   compaction_verify_record_count);
844
40.2k
  ROCKS_LOG_HEADER(log,
845
40.2k
                   "                              "
846
40.2k
                   "Options.track_and_verify_wals_in_manifest: %d",
847
40.2k
                   track_and_verify_wals_in_manifest);
848
40.2k
  ROCKS_LOG_HEADER(log,
849
40.2k
                   "                              "
850
40.2k
                   "Options.track_and_verify_wals: %d",
851
40.2k
                   track_and_verify_wals);
852
40.2k
  ROCKS_LOG_HEADER(log, "       Options.verify_sst_unique_id_in_manifest: %d",
853
40.2k
                   verify_sst_unique_id_in_manifest);
854
40.2k
  ROCKS_LOG_HEADER(log, "                                    Options.env: %p",
855
40.2k
                   env);
856
40.2k
  ROCKS_LOG_HEADER(log, "                                     Options.fs: %s",
857
40.2k
                   fs->Name());
858
40.2k
  ROCKS_LOG_HEADER(log, "                               Options.info_log: %p",
859
40.2k
                   info_log.get());
860
40.2k
  ROCKS_LOG_HEADER(log, "               Options.max_file_opening_threads: %d",
861
40.2k
                   max_file_opening_threads);
862
40.2k
  ROCKS_LOG_HEADER(log, "                             Options.statistics: %p",
863
40.2k
                   stats);
864
40.2k
  if (stats) {
865
0
    ROCKS_LOG_HEADER(
866
0
        log, "                             Options.statistics stats level: %u",
867
0
        stats->get_stats_level());
868
0
  }
869
40.2k
  ROCKS_LOG_HEADER(log, "                              Options.use_fsync: %d",
870
40.2k
                   use_fsync);
871
40.2k
  ROCKS_LOG_HEADER(
872
40.2k
      log, "                      Options.max_log_file_size: %" ROCKSDB_PRIszt,
873
40.2k
      max_log_file_size);
874
40.2k
  ROCKS_LOG_HEADER(
875
40.2k
      log, "                  Options.log_file_time_to_roll: %" ROCKSDB_PRIszt,
876
40.2k
      log_file_time_to_roll);
877
40.2k
  ROCKS_LOG_HEADER(
878
40.2k
      log, "                      Options.keep_log_file_num: %" ROCKSDB_PRIszt,
879
40.2k
      keep_log_file_num);
880
40.2k
  ROCKS_LOG_HEADER(
881
40.2k
      log, "                   Options.recycle_log_file_num: %" ROCKSDB_PRIszt,
882
40.2k
      recycle_log_file_num);
883
40.2k
  ROCKS_LOG_HEADER(log, "                        Options.allow_fallocate: %d",
884
40.2k
                   allow_fallocate);
885
40.2k
  ROCKS_LOG_HEADER(log, "                       Options.allow_mmap_reads: %d",
886
40.2k
                   allow_mmap_reads);
887
40.2k
  ROCKS_LOG_HEADER(log, "                      Options.allow_mmap_writes: %d",
888
40.2k
                   allow_mmap_writes);
889
40.2k
  ROCKS_LOG_HEADER(log, "                       Options.use_direct_reads: %d",
890
40.2k
                   use_direct_reads);
891
40.2k
  ROCKS_LOG_HEADER(log,
892
40.2k
                   "                       "
893
40.2k
                   "Options.use_direct_io_for_flush_and_compaction: %d",
894
40.2k
                   use_direct_io_for_flush_and_compaction);
895
40.2k
  ROCKS_LOG_HEADER(log, "         Options.create_missing_column_families: %d",
896
40.2k
                   create_missing_column_families);
897
40.2k
  ROCKS_LOG_HEADER(log, "                             Options.db_log_dir: %s",
898
40.2k
                   db_log_dir.c_str());
899
40.2k
  ROCKS_LOG_HEADER(log, "                                Options.wal_dir: %s",
900
40.2k
                   wal_dir.c_str());
901
40.2k
  ROCKS_LOG_HEADER(log, "               Options.table_cache_numshardbits: %d",
902
40.2k
                   table_cache_numshardbits);
903
40.2k
  ROCKS_LOG_HEADER(log,
904
40.2k
                   "                        Options.WAL_ttl_seconds: %" PRIu64,
905
40.2k
                   WAL_ttl_seconds);
906
40.2k
  ROCKS_LOG_HEADER(log,
907
40.2k
                   "                      Options.WAL_size_limit_MB: %" PRIu64,
908
40.2k
                   WAL_size_limit_MB);
909
40.2k
  ROCKS_LOG_HEADER(log,
910
40.2k
                   "                       "
911
40.2k
                   "Options.max_write_batch_group_size_bytes: %" PRIu64,
912
40.2k
                   max_write_batch_group_size_bytes);
913
40.2k
  ROCKS_LOG_HEADER(log, "                    Options.is_fd_close_on_exec: %d",
914
40.2k
                   is_fd_close_on_exec);
915
40.2k
  ROCKS_LOG_HEADER(log, "                  Options.advise_random_on_open: %d",
916
40.2k
                   advise_random_on_open);
917
40.2k
  ROCKS_LOG_HEADER(
918
40.2k
      log, "                   Options.db_write_buffer_size: %" ROCKSDB_PRIszt,
919
40.2k
      db_write_buffer_size);
920
40.2k
  ROCKS_LOG_HEADER(log, "                   Options.write_buffer_manager: %p",
921
40.2k
                   write_buffer_manager.get());
922
40.2k
  ROCKS_LOG_HEADER(log, "                     Options.use_adaptive_mutex: %d",
923
40.2k
                   use_adaptive_mutex);
924
40.2k
  ROCKS_LOG_HEADER(log, "                           Options.rate_limiter: %p",
925
40.2k
                   rate_limiter.get());
926
40.2k
  Header(
927
40.2k
      log, "    Options.sst_file_manager.rate_bytes_per_sec: %" PRIi64,
928
40.2k
      sst_file_manager ? sst_file_manager->GetDeleteRateBytesPerSecond() : 0);
929
40.2k
  ROCKS_LOG_HEADER(log, "                      Options.wal_recovery_mode: %d",
930
40.2k
                   static_cast<int>(wal_recovery_mode));
931
40.2k
  ROCKS_LOG_HEADER(log, "                 Options.enable_thread_tracking: %d",
932
40.2k
                   enable_thread_tracking);
933
40.2k
  ROCKS_LOG_HEADER(log, "                 Options.enable_pipelined_write: %d",
934
40.2k
                   enable_pipelined_write);
935
40.2k
  ROCKS_LOG_HEADER(log, "                 Options.unordered_write: %d",
936
40.2k
                   unordered_write);
937
40.2k
  ROCKS_LOG_HEADER(log, "        Options.allow_concurrent_memtable_write: %d",
938
40.2k
                   allow_concurrent_memtable_write);
939
40.2k
  ROCKS_LOG_HEADER(log, "     Options.enable_write_thread_adaptive_yield: %d",
940
40.2k
                   enable_write_thread_adaptive_yield);
941
40.2k
  ROCKS_LOG_HEADER(log,
942
40.2k
                   "            Options.write_thread_max_yield_usec: %" PRIu64,
943
40.2k
                   write_thread_max_yield_usec);
944
40.2k
  ROCKS_LOG_HEADER(log,
945
40.2k
                   "           Options.write_thread_slow_yield_usec: %" PRIu64,
946
40.2k
                   write_thread_slow_yield_usec);
947
40.2k
  if (row_cache) {
948
0
    ROCKS_LOG_HEADER(
949
0
        log,
950
0
        "                              Options.row_cache: %" ROCKSDB_PRIszt,
951
0
        row_cache->GetCapacity());
952
40.2k
  } else {
953
40.2k
    ROCKS_LOG_HEADER(log,
954
40.2k
                     "                              Options.row_cache: None");
955
40.2k
  }
956
40.2k
  ROCKS_LOG_HEADER(log, "                             Options.wal_filter: %s",
957
40.2k
                   wal_filter ? wal_filter->Name() : "None");
958
959
40.2k
  ROCKS_LOG_HEADER(log, "            Options.avoid_flush_during_recovery: %d",
960
40.2k
                   avoid_flush_during_recovery);
961
40.2k
  ROCKS_LOG_HEADER(
962
40.2k
      log, "        Options.enforce_write_buffer_manager_during_recovery: %d",
963
40.2k
      enforce_write_buffer_manager_during_recovery);
964
40.2k
  ROCKS_LOG_HEADER(log, "            Options.allow_ingest_behind: %d",
965
40.2k
                   allow_ingest_behind);
966
40.2k
  ROCKS_LOG_HEADER(log, "            Options.two_write_queues: %d",
967
40.2k
                   two_write_queues);
968
40.2k
  ROCKS_LOG_HEADER(log, "            Options.manual_wal_flush: %d",
969
40.2k
                   manual_wal_flush);
970
40.2k
  ROCKS_LOG_HEADER(log, "            Options.wal_compression: %d",
971
40.2k
                   wal_compression);
972
40.2k
  ROCKS_LOG_HEADER(log,
973
40.2k
                   "            Options.background_close_inactive_wals: %d",
974
40.2k
                   background_close_inactive_wals);
975
40.2k
  ROCKS_LOG_HEADER(log, "            Options.atomic_flush: %d", atomic_flush);
976
40.2k
  ROCKS_LOG_HEADER(log, "            Options.avoid_unnecessary_blocking_io: %d",
977
40.2k
                   avoid_unnecessary_blocking_io);
978
40.2k
  ROCKS_LOG_HEADER(log, "            Options.prefix_seek_opt_in_only: %d",
979
40.2k
                   prefix_seek_opt_in_only);
980
40.2k
  ROCKS_LOG_HEADER(log, "                Options.persist_stats_to_disk: %u",
981
40.2k
                   persist_stats_to_disk);
982
40.2k
  ROCKS_LOG_HEADER(log, "                Options.write_dbid_to_manifest: %d",
983
40.2k
                   write_dbid_to_manifest);
984
40.2k
  ROCKS_LOG_HEADER(log, "                Options.write_identity_file: %d",
985
40.2k
                   write_identity_file);
986
40.2k
  ROCKS_LOG_HEADER(
987
40.2k
      log, "                Options.log_readahead_size: %" ROCKSDB_PRIszt,
988
40.2k
      log_readahead_size);
989
40.2k
  ROCKS_LOG_HEADER(log, "                Options.file_checksum_gen_factory: %s",
990
40.2k
                   file_checksum_gen_factory ? file_checksum_gen_factory->Name()
991
40.2k
                                             : kUnknownFileChecksumFuncName);
992
40.2k
  ROCKS_LOG_HEADER(log, "                Options.best_efforts_recovery: %d",
993
40.2k
                   static_cast<int>(best_efforts_recovery));
994
40.2k
  ROCKS_LOG_HEADER(log, "               Options.max_bgerror_resume_count: %d",
995
40.2k
                   max_bgerror_resume_count);
996
40.2k
  ROCKS_LOG_HEADER(log,
997
40.2k
                   "           Options.bgerror_resume_retry_interval: %" PRIu64,
998
40.2k
                   bgerror_resume_retry_interval);
999
40.2k
  ROCKS_LOG_HEADER(log, "            Options.allow_data_in_errors: %d",
1000
40.2k
                   allow_data_in_errors);
1001
40.2k
  ROCKS_LOG_HEADER(log, "            Options.db_host_id: %s",
1002
40.2k
                   db_host_id.c_str());
1003
40.2k
  ROCKS_LOG_HEADER(log, "            Options.enforce_single_del_contracts: %s",
1004
40.2k
                   enforce_single_del_contracts ? "true" : "false");
1005
40.2k
  ROCKS_LOG_HEADER(log, "            Options.metadata_write_temperature: %s",
1006
40.2k
                   temperature_to_string[metadata_write_temperature].c_str());
1007
40.2k
  ROCKS_LOG_HEADER(log, "            Options.wal_write_temperature: %s",
1008
40.2k
                   temperature_to_string[wal_write_temperature].c_str());
1009
40.2k
}
1010
1011
135k
bool ImmutableDBOptions::IsWalDirSameAsDBPath() const {
1012
135k
  assert(!db_paths.empty());
1013
135k
  return IsWalDirSameAsDBPath(db_paths[0].path);
1014
135k
}
1015
1016
bool ImmutableDBOptions::IsWalDirSameAsDBPath(
1017
263k
    const std::string& db_path) const {
1018
263k
  bool same = wal_dir.empty();
1019
263k
  if (!same) {
1020
0
    Status s = env->AreFilesSame(wal_dir, db_path, &same);
1021
0
    if (s.IsNotSupported()) {
1022
0
      same = wal_dir == db_path;
1023
0
    }
1024
0
  }
1025
263k
  return same;
1026
263k
}
1027
1028
315k
const std::string& ImmutableDBOptions::GetWalDir() const {
1029
315k
  if (wal_dir.empty()) {
1030
315k
    assert(!db_paths.empty());
1031
315k
    return db_paths[0].path;
1032
315k
  } else {
1033
0
    return wal_dir;
1034
0
  }
1035
315k
}
1036
1037
const std::string& ImmutableDBOptions::GetWalDir(
1038
40.2k
    const std::string& path) const {
1039
40.2k
  if (wal_dir.empty()) {
1040
40.2k
    return path;
1041
40.2k
  } else {
1042
0
    return wal_dir;
1043
0
  }
1044
40.2k
}
1045
1046
0
MutableDBOptions::MutableDBOptions() : MutableDBOptions(DBOptions{}) {}
1047
1048
MutableDBOptions::MutableDBOptions(const DBOptions& options)
1049
372k
    : max_background_jobs(options.max_background_jobs),
1050
372k
      max_background_compactions(options.max_background_compactions),
1051
372k
      max_subcompactions(options.max_subcompactions),
1052
372k
      avoid_flush_during_shutdown(options.avoid_flush_during_shutdown),
1053
372k
      writable_file_max_buffer_size(options.writable_file_max_buffer_size),
1054
372k
      delayed_write_rate(options.delayed_write_rate),
1055
372k
      max_total_wal_size(options.max_total_wal_size),
1056
      delete_obsolete_files_period_micros(
1057
372k
          options.delete_obsolete_files_period_micros),
1058
372k
      stats_dump_period_sec(options.stats_dump_period_sec),
1059
372k
      stats_persist_period_sec(options.stats_persist_period_sec),
1060
372k
      stats_history_buffer_size(options.stats_history_buffer_size),
1061
372k
      max_open_files(options.max_open_files),
1062
372k
      bytes_per_sync(options.bytes_per_sync),
1063
372k
      wal_bytes_per_sync(options.wal_bytes_per_sync),
1064
372k
      strict_bytes_per_sync(options.strict_bytes_per_sync),
1065
372k
      compaction_readahead_size(options.compaction_readahead_size),
1066
372k
      max_background_flushes(options.max_background_flushes),
1067
372k
      max_manifest_file_size(options.max_manifest_file_size),
1068
372k
      max_manifest_space_amp_pct(options.max_manifest_space_amp_pct),
1069
372k
      manifest_preallocation_size(options.manifest_preallocation_size),
1070
      verify_manifest_content_on_close(
1071
372k
          options.verify_manifest_content_on_close),
1072
372k
      daily_offpeak_time_utc(options.daily_offpeak_time_utc),
1073
      max_compaction_trigger_wakeup_seconds(
1074
372k
          options.max_compaction_trigger_wakeup_seconds) {}
1075
1076
40.2k
void MutableDBOptions::Dump(Logger* log) const {
1077
40.2k
  ROCKS_LOG_HEADER(log, "            Options.max_background_jobs: %d",
1078
40.2k
                   max_background_jobs);
1079
40.2k
  ROCKS_LOG_HEADER(log, "            Options.max_background_compactions: %d",
1080
40.2k
                   max_background_compactions);
1081
40.2k
  ROCKS_LOG_HEADER(log, "            Options.max_subcompactions: %" PRIu32,
1082
40.2k
                   max_subcompactions);
1083
40.2k
  ROCKS_LOG_HEADER(log, "            Options.avoid_flush_during_shutdown: %d",
1084
40.2k
                   avoid_flush_during_shutdown);
1085
40.2k
  ROCKS_LOG_HEADER(
1086
40.2k
      log, "          Options.writable_file_max_buffer_size: %" ROCKSDB_PRIszt,
1087
40.2k
      writable_file_max_buffer_size);
1088
40.2k
  ROCKS_LOG_HEADER(log, "            Options.delayed_write_rate : %" PRIu64,
1089
40.2k
                   delayed_write_rate);
1090
40.2k
  ROCKS_LOG_HEADER(log, "            Options.max_total_wal_size: %" PRIu64,
1091
40.2k
                   max_total_wal_size);
1092
40.2k
  ROCKS_LOG_HEADER(
1093
40.2k
      log, "            Options.delete_obsolete_files_period_micros: %" PRIu64,
1094
40.2k
      delete_obsolete_files_period_micros);
1095
40.2k
  ROCKS_LOG_HEADER(log, "                  Options.stats_dump_period_sec: %u",
1096
40.2k
                   stats_dump_period_sec);
1097
40.2k
  ROCKS_LOG_HEADER(log, "                Options.stats_persist_period_sec: %d",
1098
40.2k
                   stats_persist_period_sec);
1099
40.2k
  ROCKS_LOG_HEADER(
1100
40.2k
      log,
1101
40.2k
      "                Options.stats_history_buffer_size: %" ROCKSDB_PRIszt,
1102
40.2k
      stats_history_buffer_size);
1103
40.2k
  ROCKS_LOG_HEADER(log, "                         Options.max_open_files: %d",
1104
40.2k
                   max_open_files);
1105
40.2k
  ROCKS_LOG_HEADER(log,
1106
40.2k
                   "                         Options.bytes_per_sync: %" PRIu64,
1107
40.2k
                   bytes_per_sync);
1108
40.2k
  ROCKS_LOG_HEADER(log,
1109
40.2k
                   "                     Options.wal_bytes_per_sync: %" PRIu64,
1110
40.2k
                   wal_bytes_per_sync);
1111
40.2k
  ROCKS_LOG_HEADER(log, "                  Options.strict_bytes_per_sync: %d",
1112
40.2k
                   strict_bytes_per_sync);
1113
40.2k
  ROCKS_LOG_HEADER(log,
1114
40.2k
                   "      Options.compaction_readahead_size: %" ROCKSDB_PRIszt,
1115
40.2k
                   compaction_readahead_size);
1116
40.2k
  ROCKS_LOG_HEADER(log, "                 Options.max_background_flushes: %d",
1117
40.2k
                   max_background_flushes);
1118
40.2k
  ROCKS_LOG_HEADER(log,
1119
40.2k
                   "                 Options.max_manifest_file_size: %" PRIu64,
1120
40.2k
                   max_manifest_file_size);
1121
40.2k
  ROCKS_LOG_HEADER(log,
1122
40.2k
                   "                 Options.max_manifest_space_amp_pct: %d",
1123
40.2k
                   max_manifest_space_amp_pct);
1124
40.2k
  ROCKS_LOG_HEADER(
1125
40.2k
      log, "            Options.manifest_preallocation_size: %" ROCKSDB_PRIszt,
1126
40.2k
      manifest_preallocation_size);
1127
40.2k
  ROCKS_LOG_HEADER(log, "      Options.verify_manifest_content_on_close: %d",
1128
40.2k
                   verify_manifest_content_on_close);
1129
40.2k
  ROCKS_LOG_HEADER(log, "Options.daily_offpeak_time_utc: %s",
1130
40.2k
                   daily_offpeak_time_utc.c_str());
1131
40.2k
  ROCKS_LOG_HEADER(log,
1132
40.2k
                   "Options.max_compaction_trigger_wakeup_seconds: %" PRIu64,
1133
40.2k
                   max_compaction_trigger_wakeup_seconds);
1134
40.2k
}
1135
1136
Status GetMutableDBOptionsFromStrings(
1137
    const MutableDBOptions& base_options,
1138
    const std::unordered_map<std::string, std::string>& options_map,
1139
0
    MutableDBOptions* new_options) {
1140
0
  assert(new_options);
1141
0
  *new_options = base_options;
1142
0
  ConfigOptions config_options;
1143
0
  Status s = OptionTypeInfo::ParseType(
1144
0
      config_options, options_map, db_mutable_options_type_info, new_options);
1145
0
  if (!s.ok()) {
1146
0
    *new_options = base_options;
1147
0
  }
1148
0
  return s;
1149
0
}
1150
1151
bool MutableDBOptionsAreEqual(const MutableDBOptions& this_options,
1152
0
                              const MutableDBOptions& that_options) {
1153
0
  ConfigOptions config_options;
1154
0
  std::string mismatch;
1155
0
  return OptionTypeInfo::StructsAreEqual(
1156
0
      config_options, "MutableDBOptions", &db_mutable_options_type_info,
1157
0
      "MutableDBOptions", &this_options, &that_options, &mismatch);
1158
0
}
1159
1160
Status GetStringFromMutableDBOptions(const ConfigOptions& config_options,
1161
                                     const MutableDBOptions& mutable_opts,
1162
0
                                     std::string* opt_string) {
1163
0
  return OptionTypeInfo::SerializeType(
1164
0
      config_options, db_mutable_options_type_info, &mutable_opts, opt_string);
1165
0
}
1166
}  // namespace ROCKSDB_NAMESPACE