]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db_stress_tool/db_stress_test_base.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / db_stress_tool / db_stress_test_base.h
CommitLineData
f67539c2
TL
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#pragma once
1e59de90 12
f67539c2
TL
13#include "db_stress_tool/db_stress_common.h"
14#include "db_stress_tool/db_stress_shared_state.h"
15
16namespace ROCKSDB_NAMESPACE {
1e59de90 17class SystemClock;
f67539c2
TL
18class Transaction;
19class TransactionDB;
1e59de90 20struct TransactionDBOptions;
f67539c2
TL
21
22class StressTest {
23 public:
24 StressTest();
25
26 virtual ~StressTest();
27
1e59de90
TL
28 std::shared_ptr<Cache> NewCache(size_t capacity, int32_t num_shard_bits);
29
30 static std::vector<std::string> GetBlobCompressionTags();
f67539c2
TL
31
32 bool BuildOptionsTable();
33
1e59de90 34 void InitDb(SharedState*);
20effc67
TL
35 // The initialization work is split into two parts to avoid a circular
36 // dependency with `SharedState`.
1e59de90
TL
37 virtual void FinishInitDb(SharedState*);
38 void TrackExpectedState(SharedState* shared);
f67539c2
TL
39 void OperateDb(ThreadState* thread);
40 virtual void VerifyDb(ThreadState* thread) const = 0;
1e59de90 41 virtual void ContinuouslyVerifyDb(ThreadState* /*thread*/) const = 0;
f67539c2
TL
42 void PrintStatistics();
43
44 protected:
45 Status AssertSame(DB* db, ColumnFamilyHandle* cf,
46 ThreadState::SnapshotState& snap_state);
47
48 // Currently PreloadDb has to be single-threaded.
49 void PreloadDbAndReopenAsReadOnly(int64_t number_of_keys,
50 SharedState* shared);
51
52 Status SetOptions(ThreadState* thread);
53
54#ifndef ROCKSDB_LITE
1e59de90
TL
55 // For transactionsDB, there can be txns prepared but not yet committeed
56 // right before previous stress run crash.
57 // They will be recovered and processed through
58 // ProcessRecoveredPreparedTxnsHelper on the start of current stress run.
59 void ProcessRecoveredPreparedTxns(SharedState* shared);
60
61 // Default implementation will first update ExpectedState to be
62 // `SharedState::UNKNOWN` for each keys in `txn` and then randomly
63 // commit or rollback `txn`.
64 virtual void ProcessRecoveredPreparedTxnsHelper(Transaction* txn,
65 SharedState* shared);
66
f67539c2
TL
67 Status NewTxn(WriteOptions& write_opts, Transaction** txn);
68
1e59de90 69 Status CommitTxn(Transaction* txn, ThreadState* thread = nullptr);
f67539c2
TL
70
71 Status RollbackTxn(Transaction* txn);
72#endif
73
74 virtual void MaybeClearOneColumnFamily(ThreadState* /* thread */) {}
75
76 virtual bool ShouldAcquireMutexOnKey() const { return false; }
77
1e59de90
TL
78 // Returns true if DB state is tracked by the stress test.
79 virtual bool IsStateTracked() const = 0;
80
f67539c2
TL
81 virtual std::vector<int> GenerateColumnFamilies(
82 const int /* num_column_families */, int rand_column_family) const {
83 return {rand_column_family};
84 }
85
86 virtual std::vector<int64_t> GenerateKeys(int64_t rand_key) const {
87 return {rand_key};
88 }
89
90 virtual Status TestGet(ThreadState* thread, const ReadOptions& read_opts,
91 const std::vector<int>& rand_column_families,
92 const std::vector<int64_t>& rand_keys) = 0;
93
94 virtual std::vector<Status> TestMultiGet(
95 ThreadState* thread, const ReadOptions& read_opts,
96 const std::vector<int>& rand_column_families,
97 const std::vector<int64_t>& rand_keys) = 0;
98
99 virtual Status TestPrefixScan(ThreadState* thread,
100 const ReadOptions& read_opts,
101 const std::vector<int>& rand_column_families,
102 const std::vector<int64_t>& rand_keys) = 0;
103
104 virtual Status TestPut(ThreadState* thread, WriteOptions& write_opts,
105 const ReadOptions& read_opts,
106 const std::vector<int>& cf_ids,
1e59de90
TL
107 const std::vector<int64_t>& keys,
108 char (&value)[100]) = 0;
f67539c2
TL
109
110 virtual Status TestDelete(ThreadState* thread, WriteOptions& write_opts,
111 const std::vector<int>& rand_column_families,
1e59de90 112 const std::vector<int64_t>& rand_keys) = 0;
f67539c2
TL
113
114 virtual Status TestDeleteRange(ThreadState* thread, WriteOptions& write_opts,
115 const std::vector<int>& rand_column_families,
1e59de90 116 const std::vector<int64_t>& rand_keys) = 0;
f67539c2
TL
117
118 virtual void TestIngestExternalFile(
119 ThreadState* thread, const std::vector<int>& rand_column_families,
1e59de90 120 const std::vector<int64_t>& rand_keys) = 0;
f67539c2
TL
121
122 // Issue compact range, starting with start_key, whose integer value
123 // is rand_key.
124 virtual void TestCompactRange(ThreadState* thread, int64_t rand_key,
125 const Slice& start_key,
126 ColumnFamilyHandle* column_family);
127
128 // Calculate a hash value for all keys in range [start_key, end_key]
129 // at a certain snapshot.
130 uint32_t GetRangeHash(ThreadState* thread, const Snapshot* snapshot,
131 ColumnFamilyHandle* column_family,
132 const Slice& start_key, const Slice& end_key);
133
134 // Return a column family handle that mirrors what is pointed by
135 // `column_family_id`, which will be used to validate data to be correct.
136 // By default, the column family itself will be returned.
137 virtual ColumnFamilyHandle* GetControlCfh(ThreadState* /* thread*/,
138 int column_family_id) {
139 return column_families_[column_family_id];
140 }
141
142#ifndef ROCKSDB_LITE
143 // Generated a list of keys that close to boundaries of SST keys.
144 // If there isn't any SST file in the DB, return empty list.
145 std::vector<std::string> GetWhiteBoxKeys(ThreadState* thread, DB* db,
146 ColumnFamilyHandle* cfh,
147 size_t num_keys);
148#else // !ROCKSDB_LITE
149 std::vector<std::string> GetWhiteBoxKeys(ThreadState*, DB*,
150 ColumnFamilyHandle*, size_t) {
151 // Not supported in LITE mode.
152 return {};
153 }
154#endif // !ROCKSDB_LITE
155
156 // Given a key K, this creates an iterator which scans to K and then
157 // does a random sequence of Next/Prev operations.
158 virtual Status TestIterate(ThreadState* thread, const ReadOptions& read_opts,
159 const std::vector<int>& rand_column_families,
160 const std::vector<int64_t>& rand_keys);
161
1e59de90
TL
162 virtual Status TestIterateAgainstExpected(
163 ThreadState* /* thread */, const ReadOptions& /* read_opts */,
164 const std::vector<int>& /* rand_column_families */,
165 const std::vector<int64_t>& /* rand_keys */) {
166 return Status::NotSupported();
167 }
168
f67539c2
TL
169 // Enum used by VerifyIterator() to identify the mode to validate.
170 enum LastIterateOp {
171 kLastOpSeek,
172 kLastOpSeekForPrev,
173 kLastOpNextOrPrev,
174 kLastOpSeekToFirst,
175 kLastOpSeekToLast
176 };
177
178 // Compare the two iterator, iter and cmp_iter are in the same position,
179 // unless iter might be made invalidate or undefined because of
180 // upper or lower bounds, or prefix extractor.
181 // Will flag failure if the verification fails.
182 // diverged = true if the two iterator is already diverged.
183 // True if verification passed, false if not.
184 // op_logs is the information to print when validation fails.
185 void VerifyIterator(ThreadState* thread, ColumnFamilyHandle* cmp_cfh,
186 const ReadOptions& ro, Iterator* iter, Iterator* cmp_iter,
187 LastIterateOp op, const Slice& seek_key,
188 const std::string& op_logs, bool* diverged);
189
190 virtual Status TestBackupRestore(ThreadState* thread,
191 const std::vector<int>& rand_column_families,
192 const std::vector<int64_t>& rand_keys);
193
194 virtual Status TestCheckpoint(ThreadState* thread,
195 const std::vector<int>& rand_column_families,
196 const std::vector<int64_t>& rand_keys);
197
198 void TestCompactFiles(ThreadState* thread, ColumnFamilyHandle* column_family);
199
200 Status TestFlush(const std::vector<int>& rand_column_families);
201
202 Status TestPauseBackground(ThreadState* thread);
203
204 void TestAcquireSnapshot(ThreadState* thread, int rand_column_family,
205 const std::string& keystr, uint64_t i);
206
207 Status MaybeReleaseSnapshots(ThreadState* thread, uint64_t i);
208#ifndef ROCKSDB_LITE
20effc67
TL
209 Status VerifyGetLiveFiles() const;
210 Status VerifyGetSortedWalFiles() const;
211 Status VerifyGetCurrentWalFile() const;
212 void TestGetProperty(ThreadState* thread) const;
213
f67539c2
TL
214 virtual Status TestApproximateSize(
215 ThreadState* thread, uint64_t iteration,
216 const std::vector<int>& rand_column_families,
217 const std::vector<int64_t>& rand_keys);
218#endif // !ROCKSDB_LITE
219
1e59de90
TL
220 virtual Status TestCustomOperations(
221 ThreadState* /*thread*/,
222 const std::vector<int>& /*rand_column_families*/) {
223 return Status::NotSupported("TestCustomOperations() must be overridden");
224 }
225
f67539c2
TL
226 void VerificationAbort(SharedState* shared, std::string msg, Status s) const;
227
228 void VerificationAbort(SharedState* shared, std::string msg, int cf,
229 int64_t key) const;
230
1e59de90
TL
231 void VerificationAbort(SharedState* shared, std::string msg, int cf,
232 int64_t key, Slice value_from_db,
233 Slice value_from_expected) const;
234
235 void VerificationAbort(SharedState* shared, int cf, int64_t key,
236 const Slice& value, const WideColumns& columns,
237 const WideColumns& expected_columns) const;
238
239 static std::string DebugString(const Slice& value, const WideColumns& columns,
240 const WideColumns& expected_columns);
241
f67539c2
TL
242 void PrintEnv() const;
243
1e59de90 244 void Open(SharedState* shared);
f67539c2
TL
245
246 void Reopen(ThreadState* thread);
247
1e59de90
TL
248 virtual void RegisterAdditionalListeners() {}
249
250#ifndef ROCKSDB_LITE
251 virtual void PrepareTxnDbOptions(SharedState* /*shared*/,
252 TransactionDBOptions& /*txn_db_opts*/) {}
253#endif
254
255 // Returns whether the timestamp of read_opts is updated.
256 bool MaybeUseOlderTimestampForPointLookup(ThreadState* thread,
257 std::string& ts_str,
258 Slice& ts_slice,
259 ReadOptions& read_opts);
260
261 void MaybeUseOlderTimestampForRangeScan(ThreadState* thread,
262 std::string& ts_str, Slice& ts_slice,
263 ReadOptions& read_opts);
264
f67539c2
TL
265 std::shared_ptr<Cache> cache_;
266 std::shared_ptr<Cache> compressed_cache_;
267 std::shared_ptr<const FilterPolicy> filter_policy_;
268 DB* db_;
269#ifndef ROCKSDB_LITE
270 TransactionDB* txn_db_;
271#endif
1e59de90
TL
272
273 // Currently only used in MultiOpsTxnsStressTest
274 std::atomic<DB*> db_aptr_;
275
f67539c2 276 Options options_;
1e59de90 277 SystemClock* clock_;
f67539c2
TL
278 std::vector<ColumnFamilyHandle*> column_families_;
279 std::vector<std::string> column_family_names_;
280 std::atomic<int> new_column_family_name_;
281 int num_times_reopened_;
282 std::unordered_map<std::string, std::vector<std::string>> options_table_;
283 std::vector<std::string> options_index_;
284 std::atomic<bool> db_preload_finished_;
285
f67539c2
TL
286 // Fields used for continuous verification from another thread
287 DB* cmp_db_;
288 std::vector<ColumnFamilyHandle*> cmp_cfhs_;
1e59de90 289 bool is_db_stopped_;
f67539c2
TL
290};
291
1e59de90
TL
292// Load options from OPTIONS file and populate `options`.
293extern bool InitializeOptionsFromFile(Options& options);
294
295// Initialize `options` using command line arguments.
296// When this function is called, `cache`, `block_cache_compressed`,
297// `filter_policy` have all been initialized. Therefore, we just pass them as
298// input arguments.
299extern void InitializeOptionsFromFlags(
300 const std::shared_ptr<Cache>& cache,
301 const std::shared_ptr<Cache>& block_cache_compressed,
302 const std::shared_ptr<const FilterPolicy>& filter_policy, Options& options);
303
304// Initialize `options` on which `InitializeOptionsFromFile()` and
305// `InitializeOptionsFromFlags()` have both been called already.
306// There are two cases.
307// Case 1: OPTIONS file is not specified. Command line arguments have been used
308// to initialize `options`. InitializeOptionsGeneral() will use
309// `cache`, `block_cache_compressed` and `filter_policy` to initialize
310// corresponding fields of `options`. InitializeOptionsGeneral() will
311// also set up other fields of `options` so that stress test can run.
312// Examples include `create_if_missing` and
313// `create_missing_column_families`, etc.
314// Case 2: OPTIONS file is specified. It is possible that, after loading from
315// the given OPTIONS files, some shared object fields are still not
316// initialized because they are not set in the OPTIONS file. In this
317// case, if command line arguments indicate that the user wants to set
318// up such shared objects, e.g. block cache, compressed block cache,
319// row cache, filter policy, then InitializeOptionsGeneral() will honor
320// the user's choice, thus passing `cache`, `block_cache_compressed`,
321// `filter_policy` as input arguments.
322//
323// InitializeOptionsGeneral() must not overwrite fields of `options` loaded
324// from OPTIONS file.
325extern void InitializeOptionsGeneral(
326 const std::shared_ptr<Cache>& cache,
327 const std::shared_ptr<Cache>& block_cache_compressed,
328 const std::shared_ptr<const FilterPolicy>& filter_policy, Options& options);
329
330// If no OPTIONS file is specified, set up `options` so that we can test
331// user-defined timestamp which requires `-user_timestamp_size=8`.
332// This function also checks for known (currently) incompatible features with
333// user-defined timestamp.
334extern void CheckAndSetOptionsForUserTimestamp(Options& options);
335
f67539c2
TL
336} // namespace ROCKSDB_NAMESPACE
337#endif // GFLAGS