db_test_util.h 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474
  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. #pragma once
  10. #include <fcntl.h>
  11. #include <algorithm>
  12. #include <cinttypes>
  13. #include <map>
  14. #include <memory>
  15. #include <set>
  16. #include <string>
  17. #include <thread>
  18. #include <unordered_set>
  19. #include <utility>
  20. #include <vector>
  21. #include "db/db_impl/db_impl.h"
  22. #include "file/filename.h"
  23. #include "options/options_helper.h"
  24. #include "rocksdb/advanced_options.h"
  25. #include "rocksdb/cache.h"
  26. #include "rocksdb/compaction_filter.h"
  27. #include "rocksdb/convenience.h"
  28. #include "rocksdb/db.h"
  29. #include "rocksdb/env.h"
  30. #include "rocksdb/file_system.h"
  31. #include "rocksdb/filter_policy.h"
  32. #include "rocksdb/io_status.h"
  33. #include "rocksdb/options.h"
  34. #include "rocksdb/slice.h"
  35. #include "rocksdb/sst_file_writer.h"
  36. #include "rocksdb/statistics.h"
  37. #include "rocksdb/table.h"
  38. #include "rocksdb/utilities/checkpoint.h"
  39. #include "table/mock_table.h"
  40. #include "test_util/sync_point.h"
  41. #include "test_util/testharness.h"
  42. #include "util/cast_util.h"
  43. #include "util/compression.h"
  44. #include "util/mutexlock.h"
  45. #include "util/string_util.h"
  46. #include "utilities/merge_operators.h"
  47. // In case defined by Windows headers
  48. #undef small
  49. namespace ROCKSDB_NAMESPACE {
  50. class MockEnv;
  51. namespace anon {
  52. class AtomicCounter {
  53. public:
  54. explicit AtomicCounter(Env* env = NULL)
  55. : env_(env), cond_count_(&mu_), count_(0) {}
  56. void Increment() {
  57. MutexLock l(&mu_);
  58. count_++;
  59. cond_count_.SignalAll();
  60. }
  61. int Read() {
  62. MutexLock l(&mu_);
  63. return count_;
  64. }
  65. bool WaitFor(int count) {
  66. MutexLock l(&mu_);
  67. uint64_t start = env_->NowMicros();
  68. while (count_ < count) {
  69. uint64_t now = env_->NowMicros();
  70. cond_count_.TimedWait(now + /*1s*/ 1 * 1000 * 1000);
  71. if (env_->NowMicros() - start > /*10s*/ 10 * 1000 * 1000) {
  72. return false;
  73. }
  74. if (count_ < count) {
  75. GTEST_LOG_(WARNING) << "WaitFor is taking more time than usual";
  76. }
  77. }
  78. return true;
  79. }
  80. void Reset() {
  81. MutexLock l(&mu_);
  82. count_ = 0;
  83. cond_count_.SignalAll();
  84. }
  85. private:
  86. Env* env_;
  87. port::Mutex mu_;
  88. port::CondVar cond_count_;
  89. int count_;
  90. };
  91. struct OptionsOverride {
  92. std::shared_ptr<const FilterPolicy> filter_policy = nullptr;
  93. // These will be used only if filter_policy is set
  94. bool partition_filters = false;
  95. // Force using a default block cache. (Setting to false allows ASAN build
  96. // use a trivially small block cache for better UAF error detection.)
  97. bool full_block_cache = false;
  98. uint64_t metadata_block_size = 1024;
  99. // Used as a bit mask of individual enums in which to skip an XF test point
  100. int skip_policy = 0;
  101. // The default value for this option is changed from false to true.
  102. // Keeping the default to false for unit tests as old unit tests assume
  103. // this behavior. Tests for level_compaction_dynamic_level_bytes
  104. // will set the option to true explicitly.
  105. bool level_compaction_dynamic_level_bytes = false;
  106. };
  107. } // namespace anon
  108. enum SkipPolicy { kSkipNone = 0, kSkipNoSnapshot = 1, kSkipNoPrefix = 2 };
  109. // Special Env used to delay background operations
  110. class SpecialEnv : public EnvWrapper {
  111. public:
  112. explicit SpecialEnv(Env* base, bool time_elapse_only_sleep = false);
  113. static const char* kClassName() { return "SpecialEnv"; }
  114. const char* Name() const override { return kClassName(); }
  115. Status NewWritableFile(const std::string& f, std::unique_ptr<WritableFile>* r,
  116. const EnvOptions& soptions) override {
  117. class SSTableFile : public WritableFile {
  118. private:
  119. SpecialEnv* env_;
  120. std::unique_ptr<WritableFile> base_;
  121. public:
  122. SSTableFile(SpecialEnv* env, std::unique_ptr<WritableFile>&& base)
  123. : env_(env), base_(std::move(base)) {}
  124. Status Append(const Slice& data) override {
  125. if (env_->table_write_callback_) {
  126. (*env_->table_write_callback_)();
  127. }
  128. if (env_->drop_writes_.load(std::memory_order_acquire)) {
  129. // Drop writes on the floor
  130. return Status::OK();
  131. } else if (env_->no_space_.load(std::memory_order_acquire)) {
  132. return Status::NoSpace("No space left on device");
  133. } else {
  134. env_->bytes_written_ += data.size();
  135. return base_->Append(data);
  136. }
  137. }
  138. Status Append(
  139. const Slice& data,
  140. const DataVerificationInfo& /* verification_info */) override {
  141. return Append(data);
  142. }
  143. Status PositionedAppend(const Slice& data, uint64_t offset) override {
  144. if (env_->table_write_callback_) {
  145. (*env_->table_write_callback_)();
  146. }
  147. if (env_->drop_writes_.load(std::memory_order_acquire)) {
  148. // Drop writes on the floor
  149. return Status::OK();
  150. } else if (env_->no_space_.load(std::memory_order_acquire)) {
  151. return Status::NoSpace("No space left on device");
  152. } else {
  153. env_->bytes_written_ += data.size();
  154. return base_->PositionedAppend(data, offset);
  155. }
  156. }
  157. Status PositionedAppend(
  158. const Slice& data, uint64_t offset,
  159. const DataVerificationInfo& /* verification_info */) override {
  160. return PositionedAppend(data, offset);
  161. }
  162. Status Truncate(uint64_t size) override { return base_->Truncate(size); }
  163. Status RangeSync(uint64_t offset, uint64_t nbytes) override {
  164. Status s = base_->RangeSync(offset, nbytes);
  165. #if !(defined NDEBUG) || !defined(OS_WIN)
  166. TEST_SYNC_POINT_CALLBACK("SpecialEnv::SStableFile::RangeSync", &s);
  167. #endif // !(defined NDEBUG) || !defined(OS_WIN)
  168. return s;
  169. }
  170. Status Close() override {
  171. // SyncPoint is not supported in Released Windows Mode.
  172. #if !(defined NDEBUG) || !defined(OS_WIN)
  173. // Check preallocation size
  174. // preallocation size is never passed to base file.
  175. size_t preallocation_size = preallocation_block_size();
  176. TEST_SYNC_POINT_CALLBACK("DBTestWritableFile.GetPreallocationStatus",
  177. &preallocation_size);
  178. #endif // !(defined NDEBUG) || !defined(OS_WIN)
  179. Status s = base_->Close();
  180. #if !(defined NDEBUG) || !defined(OS_WIN)
  181. TEST_SYNC_POINT_CALLBACK("SpecialEnv::SStableFile::Close", &s);
  182. #endif // !(defined NDEBUG) || !defined(OS_WIN)
  183. return s;
  184. }
  185. Status Flush() override { return base_->Flush(); }
  186. Status Sync() override {
  187. ++env_->sync_counter_;
  188. while (env_->delay_sstable_sync_.load(std::memory_order_acquire)) {
  189. env_->SleepForMicroseconds(100000);
  190. }
  191. Status s;
  192. if (!env_->skip_fsync_) {
  193. s = base_->Sync();
  194. }
  195. #if !(defined NDEBUG) || !defined(OS_WIN)
  196. TEST_SYNC_POINT_CALLBACK("SpecialEnv::SStableFile::Sync", &s);
  197. #endif // !(defined NDEBUG) || !defined(OS_WIN)
  198. return s;
  199. }
  200. void SetIOPriority(Env::IOPriority pri) override {
  201. base_->SetIOPriority(pri);
  202. }
  203. Env::IOPriority GetIOPriority() override {
  204. return base_->GetIOPriority();
  205. }
  206. bool use_direct_io() const override { return base_->use_direct_io(); }
  207. Status Allocate(uint64_t offset, uint64_t len) override {
  208. return base_->Allocate(offset, len);
  209. }
  210. size_t GetUniqueId(char* id, size_t max_size) const override {
  211. return base_->GetUniqueId(id, max_size);
  212. }
  213. uint64_t GetFileSize() final { return base_->GetFileSize(); }
  214. };
  215. class ManifestFile : public WritableFile {
  216. public:
  217. ManifestFile(SpecialEnv* env, std::unique_ptr<WritableFile>&& b)
  218. : env_(env), base_(std::move(b)) {}
  219. Status Append(const Slice& data) override {
  220. if (env_->manifest_write_error_.load(std::memory_order_acquire)) {
  221. return Status::IOError("simulated writer error");
  222. } else {
  223. return base_->Append(data);
  224. }
  225. }
  226. Status Append(
  227. const Slice& data,
  228. const DataVerificationInfo& /*verification_info*/) override {
  229. return Append(data);
  230. }
  231. Status Truncate(uint64_t size) override { return base_->Truncate(size); }
  232. Status Close() override { return base_->Close(); }
  233. Status Flush() override { return base_->Flush(); }
  234. Status Sync() override {
  235. ++env_->sync_counter_;
  236. if (env_->manifest_sync_error_.load(std::memory_order_acquire)) {
  237. return Status::IOError("simulated sync error");
  238. } else {
  239. if (env_->skip_fsync_) {
  240. return Status::OK();
  241. } else {
  242. return base_->Sync();
  243. }
  244. }
  245. }
  246. uint64_t GetFileSize() override { return base_->GetFileSize(); }
  247. Status Allocate(uint64_t offset, uint64_t len) override {
  248. return base_->Allocate(offset, len);
  249. }
  250. private:
  251. SpecialEnv* env_;
  252. std::unique_ptr<WritableFile> base_;
  253. };
  254. class SpecialWalFile : public WritableFile {
  255. public:
  256. SpecialWalFile(SpecialEnv* env, std::unique_ptr<WritableFile>&& b)
  257. : env_(env), base_(std::move(b)) {
  258. env_->num_open_wal_file_.fetch_add(1);
  259. }
  260. virtual ~SpecialWalFile() { env_->num_open_wal_file_.fetch_add(-1); }
  261. Status Append(const Slice& data) override {
  262. #if !(defined NDEBUG) || !defined(OS_WIN)
  263. TEST_SYNC_POINT("SpecialEnv::SpecialWalFile::Append:1");
  264. #endif
  265. Status s;
  266. if (env_->log_write_error_.load(std::memory_order_acquire)) {
  267. s = Status::IOError("simulated writer error");
  268. } else {
  269. int slowdown =
  270. env_->log_write_slowdown_.load(std::memory_order_acquire);
  271. if (slowdown > 0) {
  272. env_->SleepForMicroseconds(slowdown);
  273. }
  274. s = base_->Append(data);
  275. }
  276. #if !(defined NDEBUG) || !defined(OS_WIN)
  277. TEST_SYNC_POINT("SpecialEnv::SpecialWalFile::Append:2");
  278. #endif
  279. return s;
  280. }
  281. Status Append(
  282. const Slice& data,
  283. const DataVerificationInfo& /* verification_info */) override {
  284. return Append(data);
  285. }
  286. Status Truncate(uint64_t size) override { return base_->Truncate(size); }
  287. void PrepareWrite(size_t offset, size_t len) override {
  288. base_->PrepareWrite(offset, len);
  289. }
  290. void SetPreallocationBlockSize(size_t size) override {
  291. base_->SetPreallocationBlockSize(size);
  292. }
  293. Status Close() override {
  294. // SyncPoint is not supported in Released Windows Mode.
  295. #if !(defined NDEBUG) || !defined(OS_WIN)
  296. // Check preallocation size
  297. size_t block_size, last_allocated_block;
  298. base_->GetPreallocationStatus(&block_size, &last_allocated_block);
  299. TEST_SYNC_POINT_CALLBACK("DBTestWalFile.GetPreallocationStatus",
  300. &block_size);
  301. #endif // !(defined NDEBUG) || !defined(OS_WIN)
  302. return base_->Close();
  303. }
  304. Status Flush() override { return base_->Flush(); }
  305. Status Sync() override {
  306. ++env_->sync_counter_;
  307. if (env_->corrupt_in_sync_) {
  308. EXPECT_OK(Append(std::string(33000, ' ')));
  309. return Status::IOError("Ingested Sync Failure");
  310. }
  311. if (env_->skip_fsync_) {
  312. return Status::OK();
  313. } else {
  314. return base_->Sync();
  315. }
  316. }
  317. bool IsSyncThreadSafe() const override {
  318. return env_->is_wal_sync_thread_safe_.load();
  319. }
  320. Status Allocate(uint64_t offset, uint64_t len) override {
  321. return base_->Allocate(offset, len);
  322. }
  323. uint64_t GetFileSize() final { return base_->GetFileSize(); }
  324. private:
  325. SpecialEnv* env_;
  326. std::unique_ptr<WritableFile> base_;
  327. };
  328. class OtherFile : public WritableFile {
  329. public:
  330. OtherFile(SpecialEnv* env, std::unique_ptr<WritableFile>&& b)
  331. : env_(env), base_(std::move(b)) {}
  332. Status Append(const Slice& data) override { return base_->Append(data); }
  333. Status Append(
  334. const Slice& data,
  335. const DataVerificationInfo& /*verification_info*/) override {
  336. return Append(data);
  337. }
  338. Status Truncate(uint64_t size) override { return base_->Truncate(size); }
  339. Status Close() override { return base_->Close(); }
  340. Status Flush() override { return base_->Flush(); }
  341. Status Sync() override {
  342. if (env_->skip_fsync_) {
  343. return Status::OK();
  344. } else {
  345. return base_->Sync();
  346. }
  347. }
  348. uint64_t GetFileSize() override { return base_->GetFileSize(); }
  349. Status Allocate(uint64_t offset, uint64_t len) override {
  350. return base_->Allocate(offset, len);
  351. }
  352. private:
  353. SpecialEnv* env_;
  354. std::unique_ptr<WritableFile> base_;
  355. };
  356. if (no_file_overwrite_.load(std::memory_order_acquire) &&
  357. target()->FileExists(f).ok()) {
  358. return Status::NotSupported("SpecialEnv::no_file_overwrite_ is true.");
  359. }
  360. if (non_writeable_rate_.load(std::memory_order_acquire) > 0) {
  361. uint32_t random_number;
  362. {
  363. MutexLock l(&rnd_mutex_);
  364. random_number = rnd_.Uniform(100);
  365. }
  366. if (random_number < non_writeable_rate_.load()) {
  367. return Status::IOError("simulated random write error");
  368. }
  369. }
  370. new_writable_count_++;
  371. if (non_writable_count_.load() > 0) {
  372. non_writable_count_--;
  373. return Status::IOError("simulated write error");
  374. }
  375. EnvOptions optimized = soptions;
  376. if (strstr(f.c_str(), "MANIFEST") != nullptr ||
  377. strstr(f.c_str(), "log") != nullptr) {
  378. optimized.use_mmap_writes = false;
  379. optimized.use_direct_writes = false;
  380. }
  381. Status s = target()->NewWritableFile(f, r, optimized);
  382. if (s.ok()) {
  383. if (strstr(f.c_str(), ".sst") != nullptr) {
  384. r->reset(new SSTableFile(this, std::move(*r)));
  385. } else if (strstr(f.c_str(), "MANIFEST") != nullptr) {
  386. r->reset(new ManifestFile(this, std::move(*r)));
  387. } else if (strstr(f.c_str(), "log") != nullptr) {
  388. r->reset(new SpecialWalFile(this, std::move(*r)));
  389. } else {
  390. r->reset(new OtherFile(this, std::move(*r)));
  391. }
  392. }
  393. return s;
  394. }
  395. Status NewRandomAccessFile(const std::string& f,
  396. std::unique_ptr<RandomAccessFile>* r,
  397. const EnvOptions& soptions) override {
  398. class CountingFile : public RandomAccessFile {
  399. public:
  400. CountingFile(std::unique_ptr<RandomAccessFile>&& target,
  401. anon::AtomicCounter* counter,
  402. std::atomic<size_t>* bytes_read)
  403. : target_(std::move(target)),
  404. counter_(counter),
  405. bytes_read_(bytes_read) {}
  406. Status Read(uint64_t offset, size_t n, Slice* result,
  407. char* scratch) const override {
  408. counter_->Increment();
  409. Status s = target_->Read(offset, n, result, scratch);
  410. *bytes_read_ += result->size();
  411. return s;
  412. }
  413. Status Prefetch(uint64_t offset, size_t n) override {
  414. Status s = target_->Prefetch(offset, n);
  415. *bytes_read_ += n;
  416. return s;
  417. }
  418. Status GetFileSize(uint64_t* s) override {
  419. return target_->GetFileSize(s);
  420. }
  421. private:
  422. std::unique_ptr<RandomAccessFile> target_;
  423. anon::AtomicCounter* counter_;
  424. std::atomic<size_t>* bytes_read_;
  425. };
  426. class RandomFailureFile : public RandomAccessFile {
  427. public:
  428. RandomFailureFile(std::unique_ptr<RandomAccessFile>&& target,
  429. std::atomic<uint64_t>* failure_cnt, uint32_t fail_odd)
  430. : target_(std::move(target)),
  431. fail_cnt_(failure_cnt),
  432. fail_odd_(fail_odd) {}
  433. Status Read(uint64_t offset, size_t n, Slice* result,
  434. char* scratch) const override {
  435. if (Random::GetTLSInstance()->OneIn(fail_odd_)) {
  436. fail_cnt_->fetch_add(1);
  437. return Status::IOError("random error");
  438. }
  439. return target_->Read(offset, n, result, scratch);
  440. }
  441. Status Prefetch(uint64_t offset, size_t n) override {
  442. return target_->Prefetch(offset, n);
  443. }
  444. Status GetFileSize(uint64_t* s) override {
  445. return target_->GetFileSize(s);
  446. }
  447. private:
  448. std::unique_ptr<RandomAccessFile> target_;
  449. std::atomic<uint64_t>* fail_cnt_;
  450. uint32_t fail_odd_;
  451. };
  452. Status s = target()->NewRandomAccessFile(f, r, soptions);
  453. random_file_open_counter_++;
  454. if (s.ok()) {
  455. if (count_random_reads_) {
  456. r->reset(new CountingFile(std::move(*r), &random_read_counter_,
  457. &random_read_bytes_counter_));
  458. } else if (rand_reads_fail_odd_ > 0) {
  459. r->reset(new RandomFailureFile(std::move(*r), &num_reads_fails_,
  460. rand_reads_fail_odd_));
  461. }
  462. }
  463. if (s.ok() && soptions.compaction_readahead_size > 0) {
  464. compaction_readahead_size_ = soptions.compaction_readahead_size;
  465. }
  466. return s;
  467. }
  468. Status NewSequentialFile(const std::string& f,
  469. std::unique_ptr<SequentialFile>* r,
  470. const EnvOptions& soptions) override {
  471. class CountingFile : public SequentialFile {
  472. public:
  473. CountingFile(std::unique_ptr<SequentialFile>&& target,
  474. anon::AtomicCounter* counter)
  475. : target_(std::move(target)), counter_(counter) {}
  476. Status Read(size_t n, Slice* result, char* scratch) override {
  477. counter_->Increment();
  478. return target_->Read(n, result, scratch);
  479. }
  480. Status Skip(uint64_t n) override { return target_->Skip(n); }
  481. private:
  482. std::unique_ptr<SequentialFile> target_;
  483. anon::AtomicCounter* counter_;
  484. };
  485. Status s = target()->NewSequentialFile(f, r, soptions);
  486. if (s.ok() && count_sequential_reads_) {
  487. r->reset(new CountingFile(std::move(*r), &sequential_read_counter_));
  488. }
  489. return s;
  490. }
  491. void SleepForMicroseconds(int micros) override {
  492. sleep_counter_.Increment();
  493. if (no_slowdown_ || time_elapse_only_sleep_) {
  494. addon_microseconds_.fetch_add(micros);
  495. }
  496. if (!no_slowdown_) {
  497. target()->SleepForMicroseconds(micros);
  498. }
  499. }
  500. void MockSleepForMicroseconds(int64_t micros) {
  501. sleep_counter_.Increment();
  502. assert(no_slowdown_);
  503. addon_microseconds_.fetch_add(micros);
  504. }
  505. void MockSleepForSeconds(int64_t seconds) {
  506. sleep_counter_.Increment();
  507. assert(no_slowdown_);
  508. addon_microseconds_.fetch_add(seconds * 1000000);
  509. }
  510. Status GetCurrentTime(int64_t* unix_time) override {
  511. Status s;
  512. if (time_elapse_only_sleep_) {
  513. *unix_time = maybe_starting_time_;
  514. } else {
  515. s = target()->GetCurrentTime(unix_time);
  516. }
  517. if (s.ok()) {
  518. // mock microseconds elapsed to seconds of time
  519. *unix_time += addon_microseconds_.load() / 1000000;
  520. }
  521. return s;
  522. }
  523. uint64_t NowCPUNanos() override {
  524. now_cpu_count_.fetch_add(1);
  525. return target()->NowCPUNanos();
  526. }
  527. uint64_t NowNanos() override {
  528. return (time_elapse_only_sleep_ ? 0 : target()->NowNanos()) +
  529. addon_microseconds_.load() * 1000;
  530. }
  531. uint64_t NowMicros() override {
  532. return (time_elapse_only_sleep_ ? 0 : target()->NowMicros()) +
  533. addon_microseconds_.load();
  534. }
  535. Status DeleteFile(const std::string& fname) override {
  536. delete_count_.fetch_add(1);
  537. return target()->DeleteFile(fname);
  538. }
  539. void SetMockSleep(bool enabled = true) { no_slowdown_ = enabled; }
  540. Status NewDirectory(const std::string& name,
  541. std::unique_ptr<Directory>* result) override {
  542. if (!skip_fsync_) {
  543. return target()->NewDirectory(name, result);
  544. } else {
  545. class NoopDirectory : public Directory {
  546. public:
  547. NoopDirectory() {}
  548. ~NoopDirectory() {}
  549. Status Fsync() override { return Status::OK(); }
  550. Status Close() override { return Status::OK(); }
  551. };
  552. result->reset(new NoopDirectory());
  553. return Status::OK();
  554. }
  555. }
  556. Status RenameFile(const std::string& src, const std::string& dest) override {
  557. rename_count_.fetch_add(1);
  558. if (rename_error_.load(std::memory_order_acquire)) {
  559. return Status::NotSupported("Simulated `RenameFile()` error.");
  560. }
  561. return target()->RenameFile(src, dest);
  562. }
  563. // Something to return when mocking current time
  564. const int64_t maybe_starting_time_;
  565. Random rnd_;
  566. port::Mutex rnd_mutex_; // Lock to pretect rnd_
  567. // sstable Sync() calls are blocked while this pointer is non-nullptr.
  568. std::atomic<bool> delay_sstable_sync_;
  569. // Drop writes on the floor while this pointer is non-nullptr.
  570. std::atomic<bool> drop_writes_;
  571. // Simulate no-space errors while this pointer is non-nullptr.
  572. std::atomic<bool> no_space_;
  573. // Simulate non-writable file system while this pointer is non-nullptr
  574. std::atomic<bool> non_writable_;
  575. // Force sync of manifest files to fail while this pointer is non-nullptr
  576. std::atomic<bool> manifest_sync_error_;
  577. // Force write to manifest files to fail while this pointer is non-nullptr
  578. std::atomic<bool> manifest_write_error_;
  579. // Force write to log files to fail while this pointer is non-nullptr
  580. std::atomic<bool> log_write_error_;
  581. // Force `RenameFile()` to fail while this pointer is non-nullptr
  582. std::atomic<bool> rename_error_{false};
  583. // Slow down every log write, in micro-seconds.
  584. std::atomic<int> log_write_slowdown_;
  585. // If true, returns Status::NotSupported for file overwrite.
  586. std::atomic<bool> no_file_overwrite_;
  587. // Number of WAL files that are still open for write.
  588. std::atomic<int> num_open_wal_file_;
  589. bool count_random_reads_;
  590. uint32_t rand_reads_fail_odd_ = 0;
  591. std::atomic<uint64_t> num_reads_fails_;
  592. anon::AtomicCounter random_read_counter_;
  593. std::atomic<size_t> random_read_bytes_counter_;
  594. std::atomic<int> random_file_open_counter_;
  595. bool count_sequential_reads_;
  596. anon::AtomicCounter sequential_read_counter_;
  597. anon::AtomicCounter sleep_counter_;
  598. std::atomic<int64_t> bytes_written_;
  599. std::atomic<int> sync_counter_;
  600. // If true, all fsync to files and directories are skipped.
  601. bool skip_fsync_ = false;
  602. // If true, ingest the corruption to file during sync.
  603. bool corrupt_in_sync_ = false;
  604. std::atomic<uint32_t> non_writeable_rate_;
  605. std::atomic<uint32_t> new_writable_count_;
  606. std::atomic<uint32_t> non_writable_count_;
  607. std::function<void()>* table_write_callback_;
  608. std::atomic<int> now_cpu_count_;
  609. std::atomic<int> delete_count_;
  610. std::atomic<int> rename_count_{0};
  611. std::atomic<bool> is_wal_sync_thread_safe_{true};
  612. std::atomic<size_t> compaction_readahead_size_{};
  613. private: // accessing these directly is prone to error
  614. friend class DBTestBase;
  615. std::atomic<int64_t> addon_microseconds_{0};
  616. // Do not modify in the env of a running DB (could cause deadlock)
  617. std::atomic<bool> time_elapse_only_sleep_;
  618. bool no_slowdown_;
  619. };
  620. class FileTemperatureTestFS : public FileSystemWrapper {
  621. public:
  622. explicit FileTemperatureTestFS(const std::shared_ptr<FileSystem>& fs)
  623. : FileSystemWrapper(fs) {}
  624. static const char* kClassName() { return "FileTemperatureTestFS"; }
  625. const char* Name() const override { return kClassName(); }
  626. IOStatus NewSequentialFile(const std::string& fname, const FileOptions& opts,
  627. std::unique_ptr<FSSequentialFile>* result,
  628. IODebugContext* dbg) override {
  629. IOStatus s = target()->NewSequentialFile(fname, opts, result, dbg);
  630. uint64_t number;
  631. FileType type;
  632. if (ParseFileName(GetFileName(fname), &number, &type) &&
  633. type == kTableFile) {
  634. MutexLock lock(&mu_);
  635. requested_sst_file_temperatures_.emplace_back(number, opts.temperature);
  636. if (s.ok()) {
  637. if (opts.temperature != Temperature::kUnknown) {
  638. // Be extra picky and don't open if a wrong non-unknown temperature is
  639. // provided
  640. auto e = current_sst_file_temperatures_.find(number);
  641. if (e != current_sst_file_temperatures_.end() &&
  642. e->second != opts.temperature) {
  643. result->reset();
  644. return IOStatus::PathNotFound(
  645. "Read requested temperature " +
  646. temperature_to_string[opts.temperature] +
  647. " but stored with temperature " +
  648. temperature_to_string[e->second] + " for " + fname);
  649. }
  650. }
  651. *result = WrapWithTemperature<FSSequentialFileOwnerWrapper>(
  652. number, std::move(*result));
  653. }
  654. }
  655. return s;
  656. }
  657. IOStatus NewRandomAccessFile(const std::string& fname,
  658. const FileOptions& opts,
  659. std::unique_ptr<FSRandomAccessFile>* result,
  660. IODebugContext* dbg) override {
  661. IOStatus s = target()->NewRandomAccessFile(fname, opts, result, dbg);
  662. uint64_t number;
  663. FileType type;
  664. if (ParseFileName(GetFileName(fname), &number, &type) &&
  665. type == kTableFile) {
  666. MutexLock lock(&mu_);
  667. requested_sst_file_temperatures_.emplace_back(number, opts.temperature);
  668. if (s.ok()) {
  669. if (opts.temperature != Temperature::kUnknown) {
  670. // Be extra picky and don't open if a wrong non-unknown temperature is
  671. // provided
  672. auto e = current_sst_file_temperatures_.find(number);
  673. if (e != current_sst_file_temperatures_.end() &&
  674. e->second != opts.temperature) {
  675. result->reset();
  676. return IOStatus::PathNotFound(
  677. "Read requested temperature " +
  678. temperature_to_string[opts.temperature] +
  679. " but stored with temperature " +
  680. temperature_to_string[e->second] + " for " + fname);
  681. }
  682. }
  683. *result = WrapWithTemperature<FSRandomAccessFileOwnerWrapper>(
  684. number, std::move(*result));
  685. }
  686. }
  687. return s;
  688. }
  689. void PopRequestedSstFileTemperatures(
  690. std::vector<std::pair<uint64_t, Temperature>>* out = nullptr) {
  691. MutexLock lock(&mu_);
  692. if (out) {
  693. *out = std::move(requested_sst_file_temperatures_);
  694. assert(requested_sst_file_temperatures_.empty());
  695. } else {
  696. requested_sst_file_temperatures_.clear();
  697. }
  698. }
  699. IOStatus NewWritableFile(const std::string& fname, const FileOptions& opts,
  700. std::unique_ptr<FSWritableFile>* result,
  701. IODebugContext* dbg) override {
  702. uint64_t number;
  703. FileType type;
  704. if (ParseFileName(GetFileName(fname), &number, &type) &&
  705. type == kTableFile) {
  706. MutexLock lock(&mu_);
  707. current_sst_file_temperatures_[number] = opts.temperature;
  708. }
  709. return target()->NewWritableFile(fname, opts, result, dbg);
  710. }
  711. IOStatus DeleteFile(const std::string& fname, const IOOptions& options,
  712. IODebugContext* dbg) override {
  713. IOStatus ios = target()->DeleteFile(fname, options, dbg);
  714. if (ios.ok()) {
  715. uint64_t number;
  716. FileType type;
  717. if (ParseFileName(GetFileName(fname), &number, &type) &&
  718. type == kTableFile) {
  719. MutexLock lock(&mu_);
  720. current_sst_file_temperatures_.erase(number);
  721. }
  722. }
  723. return ios;
  724. }
  725. void CopyCurrentSstFileTemperatures(std::map<uint64_t, Temperature>* out) {
  726. MutexLock lock(&mu_);
  727. *out = current_sst_file_temperatures_;
  728. }
  729. size_t CountCurrentSstFilesWithTemperature(Temperature temp) {
  730. MutexLock lock(&mu_);
  731. size_t count = 0;
  732. for (const auto& e : current_sst_file_temperatures_) {
  733. if (e.second == temp) {
  734. ++count;
  735. }
  736. }
  737. return count;
  738. }
  739. std::map<Temperature, size_t> CountCurrentSstFilesByTemp() {
  740. MutexLock lock(&mu_);
  741. std::map<Temperature, size_t> ret;
  742. for (const auto& e : current_sst_file_temperatures_) {
  743. ret[e.second]++;
  744. }
  745. return ret;
  746. }
  747. void OverrideSstFileTemperature(uint64_t number, Temperature temp) {
  748. MutexLock lock(&mu_);
  749. current_sst_file_temperatures_[number] = temp;
  750. }
  751. protected:
  752. port::Mutex mu_;
  753. std::vector<std::pair<uint64_t, Temperature>>
  754. requested_sst_file_temperatures_;
  755. std::map<uint64_t, Temperature> current_sst_file_temperatures_;
  756. static std::string GetFileName(const std::string& fname) {
  757. auto filename = fname.substr(fname.find_last_of(kFilePathSeparator) + 1);
  758. // workaround only for Windows that the file path could contain both Windows
  759. // FilePathSeparator and '/'
  760. filename = filename.substr(filename.find_last_of('/') + 1);
  761. return filename;
  762. }
  763. template <class FileOwnerWrapperT, /*inferred*/ class FileT>
  764. std::unique_ptr<FileT> WrapWithTemperature(uint64_t number,
  765. std::unique_ptr<FileT>&& t) {
  766. class FileWithTemp : public FileOwnerWrapperT {
  767. public:
  768. FileWithTemp(FileTemperatureTestFS* fs, uint64_t number,
  769. std::unique_ptr<FileT>&& t)
  770. : FileOwnerWrapperT(std::move(t)), fs_(fs), number_(number) {}
  771. Temperature GetTemperature() const override {
  772. MutexLock lock(&fs_->mu_);
  773. return fs_->current_sst_file_temperatures_[number_];
  774. }
  775. private:
  776. FileTemperatureTestFS* fs_;
  777. uint64_t number_;
  778. };
  779. return std::make_unique<FileWithTemp>(this, number, std::move(t));
  780. }
  781. };
  782. class OnFileDeletionListener : public EventListener {
  783. public:
  784. OnFileDeletionListener() : matched_count_(0), expected_file_name_("") {}
  785. const char* Name() const override { return kClassName(); }
  786. static const char* kClassName() { return "OnFileDeletionListener"; }
  787. void SetExpectedFileName(const std::string file_name) {
  788. expected_file_name_ = file_name;
  789. }
  790. void VerifyMatchedCount(size_t expected_value) {
  791. ASSERT_EQ(matched_count_, expected_value);
  792. }
  793. void OnTableFileDeleted(const TableFileDeletionInfo& info) override {
  794. if (expected_file_name_ != "") {
  795. ASSERT_EQ(expected_file_name_, info.file_path);
  796. expected_file_name_ = "";
  797. matched_count_++;
  798. }
  799. }
  800. private:
  801. size_t matched_count_;
  802. std::string expected_file_name_;
  803. };
  804. class FlushCounterListener : public EventListener {
  805. public:
  806. const char* Name() const override { return kClassName(); }
  807. static const char* kClassName() { return "FlushCounterListener"; }
  808. std::atomic<int> count{0};
  809. std::atomic<FlushReason> expected_flush_reason{FlushReason::kOthers};
  810. void OnFlushBegin(DB* /*db*/, const FlushJobInfo& flush_job_info) override {
  811. count++;
  812. ASSERT_EQ(expected_flush_reason.load(), flush_job_info.flush_reason);
  813. }
  814. };
  815. // A test merge operator mimics put but also fails if one of merge operands is
  816. // "corrupted", "corrupted_try_merge", or "corrupted_must_merge".
  817. class TestPutOperator : public MergeOperator {
  818. public:
  819. bool FullMergeV2(const MergeOperationInput& merge_in,
  820. MergeOperationOutput* merge_out) const override {
  821. static const std::map<std::string, MergeOperator::OpFailureScope>
  822. bad_operand_to_op_failure_scope = {
  823. {"corrupted", MergeOperator::OpFailureScope::kDefault},
  824. {"corrupted_try_merge", MergeOperator::OpFailureScope::kTryMerge},
  825. {"corrupted_must_merge",
  826. MergeOperator::OpFailureScope::kMustMerge}};
  827. auto check_operand =
  828. [](Slice operand_val,
  829. MergeOperator::OpFailureScope* op_failure_scope) -> bool {
  830. auto iter = bad_operand_to_op_failure_scope.find(operand_val.ToString());
  831. if (iter != bad_operand_to_op_failure_scope.end()) {
  832. *op_failure_scope = iter->second;
  833. return false;
  834. }
  835. return true;
  836. };
  837. if (merge_in.existing_value != nullptr &&
  838. !check_operand(*merge_in.existing_value,
  839. &merge_out->op_failure_scope)) {
  840. return false;
  841. }
  842. for (auto value : merge_in.operand_list) {
  843. if (!check_operand(value, &merge_out->op_failure_scope)) {
  844. return false;
  845. }
  846. }
  847. merge_out->existing_operand = merge_in.operand_list.back();
  848. return true;
  849. }
  850. const char* Name() const override { return "TestPutOperator"; }
  851. };
  852. /*
  853. * A cache wrapper that tracks certain CacheEntryRole's cache charge, its
  854. * peaks and increments
  855. *
  856. * p0
  857. * / \ p1
  858. * / \ /\
  859. * / \/ \
  860. * a / b \
  861. * peaks = {p0, p1}
  862. * increments = {p1-a, p2-b}
  863. */
  864. template <CacheEntryRole R>
  865. class TargetCacheChargeTrackingCache : public CacheWrapper {
  866. public:
  867. explicit TargetCacheChargeTrackingCache(std::shared_ptr<Cache> target);
  868. const char* Name() const override { return "TargetCacheChargeTrackingCache"; }
  869. Status Insert(const Slice& key, ObjectPtr value,
  870. const CacheItemHelper* helper, size_t charge,
  871. Handle** handle = nullptr, Priority priority = Priority::LOW,
  872. const Slice& compressed = Slice(),
  873. CompressionType type = kNoCompression) override;
  874. using Cache::Release;
  875. bool Release(Handle* handle, bool erase_if_last_ref = false) override;
  876. std::size_t GetCacheCharge() { return cur_cache_charge_; }
  877. std::deque<std::size_t> GetChargedCachePeaks() { return cache_charge_peaks_; }
  878. std::size_t GetChargedCacheIncrementSum() {
  879. return cache_charge_increments_sum_;
  880. }
  881. private:
  882. static const Cache::CacheItemHelper* kCrmHelper;
  883. std::size_t cur_cache_charge_;
  884. std::size_t cache_charge_peak_;
  885. std::size_t cache_charge_increment_;
  886. bool last_peak_tracked_;
  887. std::deque<std::size_t> cache_charge_peaks_;
  888. std::size_t cache_charge_increments_sum_;
  889. };
  890. class DBTestBase : public testing::Test {
  891. public:
  892. // Sequence of option configurations to try
  893. enum OptionConfig : int {
  894. kDefault = 0,
  895. kBlockBasedTableWithPrefixHashIndex = 1,
  896. kBlockBasedTableWithWholeKeyHashIndex = 2,
  897. kPlainTableFirstBytePrefix = 3,
  898. kPlainTableCappedPrefix = 4,
  899. kPlainTableCappedPrefixNonMmap = 5,
  900. kPlainTableAllBytesPrefix = 6,
  901. kVectorRep = 7,
  902. kHashLinkList = 8,
  903. kMergePut = 9,
  904. kFilter = 10,
  905. kFullFilterWithNewTableReaderForCompactions = 11,
  906. kUncompressed = 12,
  907. kNumLevel_3 = 13,
  908. kDBLogDir = 14,
  909. kWalDirAndMmapReads = 15,
  910. kManifestFileSize = 16,
  911. kPerfOptions = 17,
  912. kHashSkipList = 18,
  913. kUniversalCompaction = 19,
  914. kUniversalCompactionMultiLevel = 20,
  915. kInfiniteMaxOpenFiles = 21,
  916. kCRC32cChecksum = 22,
  917. kFIFOCompaction = 23,
  918. kOptimizeFiltersForHits = 24,
  919. kRowCache = 25,
  920. kRecycleLogFiles = 26,
  921. kConcurrentSkipList = 27,
  922. kPipelinedWrite = 28,
  923. kConcurrentWALWrites = 29,
  924. kDirectIO,
  925. kLevelSubcompactions,
  926. kBlockBasedTableWithIndexRestartInterval,
  927. kBlockBasedTableWithPartitionedIndex,
  928. kBlockBasedTableWithPartitionedIndexFormat4,
  929. kBlockBasedTableWithLatestFormat,
  930. kPartitionedFilterWithNewTableReaderForCompactions,
  931. kUniversalSubcompactions,
  932. kUnorderedWrite,
  933. kBlockBasedTableWithBinarySearchWithFirstKeyIndex,
  934. // This must be the last line
  935. kEnd,
  936. };
  937. public:
  938. std::string dbname_;
  939. std::string alternative_wal_dir_;
  940. std::string alternative_db_log_dir_;
  941. MockEnv* mem_env_;
  942. Env* encrypted_env_;
  943. SpecialEnv* env_;
  944. std::shared_ptr<Env> env_read_only_;
  945. std::shared_ptr<Env> env_guard_;
  946. DB* db_;
  947. std::vector<ColumnFamilyHandle*> handles_;
  948. int option_config_;
  949. Options last_options_;
  950. // Skip some options, as they may not be applicable to a specific test.
  951. // To add more skip constants, use values 4, 8, 16, etc.
  952. enum OptionSkip {
  953. kNoSkip = 0,
  954. kSkipDeletesFilterFirst = 1,
  955. kSkipUniversalCompaction = 2,
  956. kSkipMergePut = 4,
  957. kSkipPlainTable = 8,
  958. kSkipHashIndex = 16,
  959. kSkipNoSeekToLast = 32,
  960. kSkipFIFOCompaction = 128,
  961. kSkipMmapReads = 256,
  962. kSkipRowCache = 512,
  963. };
  964. const int kRangeDelSkipConfigs =
  965. // Plain tables do not support range deletions.
  966. kSkipPlainTable |
  967. // MmapReads disables the iterator pinning that RangeDelAggregator
  968. // requires.
  969. kSkipMmapReads |
  970. // Not compatible yet.
  971. kSkipRowCache;
  972. // `env_do_fsync` decides whether the special Env would do real
  973. // fsync for files and directories. Skipping fsync can speed up
  974. // tests, but won't cover the exact fsync logic.
  975. DBTestBase(const std::string path, bool env_do_fsync);
  976. ~DBTestBase();
  977. static std::string Key(int i) {
  978. char buf[100];
  979. snprintf(buf, sizeof(buf), "key%06d", i);
  980. return std::string(buf);
  981. }
  982. // Expects valid key created by Key().
  983. static int IdFromKey(const std::string& key) {
  984. return std::stoi(key.substr(3));
  985. }
  986. static bool ShouldSkipOptions(int option_config, int skip_mask = kNoSkip);
  987. // Switch to a fresh database with the next option configuration to
  988. // test. Return false if there are no more configurations to test.
  989. bool ChangeOptions(int skip_mask = kNoSkip);
  990. // Switch between different compaction styles.
  991. bool ChangeCompactOptions();
  992. // Switch between different WAL-realted options.
  993. bool ChangeWalOptions();
  994. // Switch between different filter policy
  995. // Jump from kDefault to kFilter to kFullFilter
  996. bool ChangeFilterOptions();
  997. // Switch between different DB options for file ingestion tests.
  998. bool ChangeOptionsForFileIngestionTest();
  999. // Return the current option configuration.
  1000. Options CurrentOptions(const anon::OptionsOverride& options_override =
  1001. anon::OptionsOverride()) const;
  1002. Options CurrentOptions(const Options& default_options,
  1003. const anon::OptionsOverride& options_override =
  1004. anon::OptionsOverride()) const;
  1005. Options GetDefaultOptions() const;
  1006. Options GetOptions(int option_config) const {
  1007. return GetOptions(option_config, GetDefaultOptions());
  1008. }
  1009. Options GetOptions(int option_config, const Options& default_options,
  1010. const anon::OptionsOverride& options_override =
  1011. anon::OptionsOverride()) const;
  1012. DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
  1013. void CreateColumnFamilies(const std::vector<std::string>& cfs,
  1014. const Options& options);
  1015. void CreateAndReopenWithCF(const std::vector<std::string>& cfs,
  1016. const Options& options);
  1017. void ReopenWithColumnFamilies(const std::vector<std::string>& cfs,
  1018. const std::vector<Options>& options);
  1019. void ReopenWithColumnFamilies(const std::vector<std::string>& cfs,
  1020. const Options& options);
  1021. Status TryReopenWithColumnFamilies(const std::vector<std::string>& cfs,
  1022. const std::vector<Options>& options);
  1023. Status TryReopenWithColumnFamilies(const std::vector<std::string>& cfs,
  1024. const Options& options);
  1025. void Reopen(const Options& options);
  1026. void Close();
  1027. void DestroyAndReopen(const Options& options);
  1028. void Destroy(const Options& options, bool delete_cf_paths = false);
  1029. Status ReadOnlyReopen(const Options& options);
  1030. // With a filesystem wrapper that fails on attempted write
  1031. Status EnforcedReadOnlyReopen(const Options& options);
  1032. Status TryReopen(const Options& options);
  1033. bool IsDirectIOSupported();
  1034. bool IsMemoryMappedAccessSupported() const;
  1035. Status Flush(int cf = 0);
  1036. Status Flush(const std::vector<int>& cf_ids);
  1037. Status Put(const Slice& k, const Slice& v, WriteOptions wo = WriteOptions());
  1038. Status Put(int cf, const Slice& k, const Slice& v,
  1039. WriteOptions wo = WriteOptions());
  1040. Status TimedPut(const Slice& k, const Slice& v, uint64_t write_unix_time,
  1041. WriteOptions wo = WriteOptions());
  1042. Status TimedPut(int cf, const Slice& k, const Slice& v,
  1043. uint64_t write_unix_time, WriteOptions wo = WriteOptions());
  1044. Status Merge(const Slice& k, const Slice& v,
  1045. WriteOptions wo = WriteOptions());
  1046. Status Merge(int cf, const Slice& k, const Slice& v,
  1047. WriteOptions wo = WriteOptions());
  1048. Status Delete(const std::string& k);
  1049. Status Delete(int cf, const std::string& k);
  1050. Status SingleDelete(const std::string& k);
  1051. Status SingleDelete(int cf, const std::string& k);
  1052. std::string Get(const std::string& k, const Snapshot* snapshot = nullptr);
  1053. std::string Get(int cf, const std::string& k,
  1054. const Snapshot* snapshot = nullptr);
  1055. Status Get(const std::string& k, PinnableSlice* v);
  1056. std::vector<std::string> MultiGet(std::vector<int> cfs,
  1057. const std::vector<std::string>& k,
  1058. const Snapshot* snapshot,
  1059. const bool batched,
  1060. const bool async = false);
  1061. std::vector<std::string> MultiGet(const std::vector<std::string>& k,
  1062. const Snapshot* snapshot = nullptr,
  1063. const bool async = false);
  1064. Status CompactRange(const CompactRangeOptions& options,
  1065. std::optional<Slice> begin, std::optional<Slice> end);
  1066. uint64_t GetNumSnapshots();
  1067. uint64_t GetTimeOldestSnapshots();
  1068. uint64_t GetSequenceOldestSnapshots();
  1069. // Return a string that contains all key,value pairs in order,
  1070. // formatted like "(k1->v1)(k2->v2)".
  1071. std::string Contents(int cf = 0);
  1072. std::string AllEntriesFor(const Slice& user_key, int cf = 0);
  1073. // Similar to AllEntriesFor but this function also covers reopen with fifo.
  1074. // Note that test cases with snapshots or entries in memtable should simply
  1075. // use AllEntriesFor instead as snapshots and entries in memtable will
  1076. // survive after db reopen.
  1077. void CheckAllEntriesWithFifoReopen(const std::string& expected_value,
  1078. const Slice& user_key, int cf,
  1079. const std::vector<std::string>& cfs,
  1080. const Options& options);
  1081. int NumSortedRuns(int cf = 0);
  1082. uint64_t TotalSize(int cf = 0);
  1083. uint64_t SizeAtLevel(int level);
  1084. size_t TotalLiveFiles(int cf = 0);
  1085. size_t TotalLiveFilesAtPath(int cf, const std::string& path);
  1086. size_t CountLiveFiles();
  1087. int NumTableFilesAtLevel(int level, int cf = 0);
  1088. int NumTableFilesAtLevel(int level, ColumnFamilyHandle* column_family,
  1089. DB* db = nullptr);
  1090. double CompressionRatioAtLevel(int level, int cf = 0);
  1091. int TotalTableFiles(int cf = 0, int levels = -1);
  1092. std::vector<uint64_t> GetBlobFileNumbers();
  1093. // Return spread of files per level
  1094. std::string FilesPerLevel(int cf = 0);
  1095. std::string FilesPerLevel(ColumnFamilyHandle* cfh, DB* db = nullptr);
  1096. size_t CountFiles();
  1097. Status CountFiles(size_t* count);
  1098. std::vector<FileMetaData*> GetLevelFileMetadatas(int level, int cf = 0);
  1099. Status Size(const Slice& start, const Slice& limit, uint64_t* size) {
  1100. return Size(start, limit, 0, size);
  1101. }
  1102. Status Size(const Slice& start, const Slice& limit, int cf, uint64_t* size);
  1103. void Compact(int cf, const Slice& start, const Slice& limit,
  1104. uint32_t target_path_id);
  1105. void Compact(int cf, const Slice& start, const Slice& limit);
  1106. void Compact(const Slice& start, const Slice& limit);
  1107. // Do n memtable compactions, each of which produces an sstable
  1108. // covering the range [small,large].
  1109. void MakeTables(int n, const std::string& small, const std::string& large,
  1110. int cf = 0);
  1111. // Prevent pushing of new sstables into deeper levels by adding
  1112. // tables that cover a specified range to all levels.
  1113. void FillLevels(const std::string& smallest, const std::string& largest,
  1114. int cf);
  1115. void MoveFilesToLevel(int level, int cf = 0);
  1116. void MoveFilesToLevel(int level, ColumnFamilyHandle* column_family,
  1117. DB* db = nullptr);
  1118. void DumpFileCounts(const char* label);
  1119. std::string DumpSSTableList();
  1120. static void GetSstFiles(Env* env, std::string path,
  1121. std::vector<std::string>* files);
  1122. int GetSstFileCount(std::string path);
  1123. // this will generate non-overlapping files since it keeps increasing key_idx
  1124. void GenerateNewFile(Random* rnd, int* key_idx, bool nowait = false);
  1125. void GenerateNewFile(int fd, Random* rnd, int* key_idx, bool nowait = false);
  1126. static const int kNumKeysByGenerateNewRandomFile;
  1127. static const int KNumKeysByGenerateNewFile = 100;
  1128. void GenerateNewRandomFile(Random* rnd, bool nowait = false);
  1129. std::string IterStatus(Iterator* iter);
  1130. Options OptionsForLogIterTest();
  1131. std::string DummyString(size_t len, char c = 'a');
  1132. void VerifyIterLast(std::string expected_key, int cf = 0);
  1133. // Used to test InplaceUpdate
  1134. // If previous value is nullptr or delta is > than previous value,
  1135. // sets newValue with delta
  1136. // If previous value is not empty,
  1137. // updates previous value with 'b' string of previous value size - 1.
  1138. static UpdateStatus updateInPlaceSmallerSize(char* prevValue,
  1139. uint32_t* prevSize, Slice delta,
  1140. std::string* newValue);
  1141. static UpdateStatus updateInPlaceSmallerVarintSize(char* prevValue,
  1142. uint32_t* prevSize,
  1143. Slice delta,
  1144. std::string* newValue);
  1145. static UpdateStatus updateInPlaceLargerSize(char* prevValue,
  1146. uint32_t* prevSize, Slice delta,
  1147. std::string* newValue);
  1148. static UpdateStatus updateInPlaceNoAction(char* prevValue, uint32_t* prevSize,
  1149. Slice delta, std::string* newValue);
  1150. // Utility method to test InplaceUpdate
  1151. void validateNumberOfEntries(int numValues, int cf = 0);
  1152. void CopyFile(const std::string& source, const std::string& destination,
  1153. uint64_t size = 0);
  1154. Status GetAllDataFiles(const FileType file_type,
  1155. std::unordered_map<std::string, uint64_t>* sst_files,
  1156. uint64_t* total_size = nullptr);
  1157. std::vector<std::uint64_t> ListTableFiles(Env* env, const std::string& path);
  1158. void VerifyDBFromMap(
  1159. std::map<std::string, std::string> true_data,
  1160. size_t* total_reads_res = nullptr, bool tailing_iter = false,
  1161. ReadOptions* ro = nullptr, ColumnFamilyHandle* cf = nullptr,
  1162. std::unordered_set<std::string>* not_found = nullptr) const;
  1163. void VerifyDBInternal(
  1164. std::vector<std::pair<std::string, std::string>> true_data);
  1165. uint64_t GetNumberOfSstFilesForColumnFamily(DB* db,
  1166. std::string column_family_name);
  1167. uint64_t GetSstSizeHelper(Temperature temperature);
  1168. uint64_t TestGetTickerCount(const Options& options, Tickers ticker_type) {
  1169. return options.statistics->getTickerCount(ticker_type);
  1170. }
  1171. uint64_t TestGetAndResetTickerCount(const Options& options,
  1172. Tickers ticker_type) {
  1173. return options.statistics->getAndResetTickerCount(ticker_type);
  1174. }
  1175. // Short name for TestGetAndResetTickerCount
  1176. uint64_t PopTicker(const Options& options, Tickers ticker_type) {
  1177. return options.statistics->getAndResetTickerCount(ticker_type);
  1178. }
  1179. // Note: reverting this setting within the same test run is not yet
  1180. // supported
  1181. void SetTimeElapseOnlySleepOnReopen(DBOptions* options);
  1182. void ResetTableProperties(TableProperties* tp) {
  1183. tp->data_size = 0;
  1184. tp->index_size = 0;
  1185. tp->filter_size = 0;
  1186. tp->raw_key_size = 0;
  1187. tp->raw_value_size = 0;
  1188. tp->num_data_blocks = 0;
  1189. tp->num_entries = 0;
  1190. tp->num_deletions = 0;
  1191. tp->num_merge_operands = 0;
  1192. tp->num_range_deletions = 0;
  1193. }
  1194. void ParseTablePropertiesString(std::string tp_string, TableProperties* tp) {
  1195. double dummy_double;
  1196. std::replace(tp_string.begin(), tp_string.end(), ';', ' ');
  1197. std::replace(tp_string.begin(), tp_string.end(), '=', ' ');
  1198. ResetTableProperties(tp);
  1199. int count = sscanf(
  1200. tp_string.c_str(),
  1201. "# data blocks %" SCNu64 " # entries %" SCNu64 " # deletions %" SCNu64
  1202. " # merge operands %" SCNu64 " # range deletions %" SCNu64
  1203. " raw key size %" SCNu64
  1204. " raw average key size %lf "
  1205. " raw value size %" SCNu64
  1206. " raw average value size %lf "
  1207. " data block size %" SCNu64 " data uncompressed size %" SCNu64
  1208. " index block size (user-key? %" SCNu64 ", delta-value? %" SCNu64
  1209. ") %" SCNu64 " filter block size %" SCNu64,
  1210. &tp->num_data_blocks, &tp->num_entries, &tp->num_deletions,
  1211. &tp->num_merge_operands, &tp->num_range_deletions, &tp->raw_key_size,
  1212. &dummy_double, &tp->raw_value_size, &dummy_double, &tp->data_size,
  1213. &tp->uncompressed_data_size, &tp->index_key_is_user_key,
  1214. &tp->index_value_is_delta_encoded, &tp->index_size, &tp->filter_size);
  1215. ASSERT_EQ(count, 15);
  1216. }
  1217. private: // Prone to error on direct use
  1218. void MaybeInstallTimeElapseOnlySleep(const DBOptions& options);
  1219. bool time_elapse_only_sleep_on_reopen_ = false;
  1220. };
  1221. // For verifying that all files generated by current version have SST
  1222. // unique ids.
  1223. void VerifySstUniqueIds(const TablePropertiesCollection& props);
  1224. // Excludes kUnknown
  1225. extern const std::vector<Temperature> kKnownTemperatures;
  1226. Temperature RandomKnownTemperature();
  1227. } // namespace ROCKSDB_NAMESPACE