fault_injection_secondary_cache.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. #include "rocksdb/secondary_cache.h"
  6. #include "util/random.h"
  7. #include "util/thread_local.h"
  8. namespace ROCKSDB_NAMESPACE {
  9. // This class implements a custom SecondaryCache that randomly injects an
  10. // error status into Inserts/Lookups based on a specified probability.
  11. // Its used by db_stress to verify correctness in the presence of
  12. // secondary cache errors.
  13. //
  14. class FaultInjectionSecondaryCache : public SecondaryCache {
  15. public:
  16. explicit FaultInjectionSecondaryCache(
  17. const std::shared_ptr<SecondaryCache>& base, uint32_t seed, int prob)
  18. : base_(base),
  19. seed_(seed),
  20. prob_(prob),
  21. thread_local_error_(new ThreadLocalPtr(DeleteThreadLocalErrorContext)) {
  22. if (std::strcmp(base_->Name(), "CompressedSecondaryCache") == 0) {
  23. base_is_compressed_sec_cache_ = true;
  24. }
  25. }
  26. ~FaultInjectionSecondaryCache() override {}
  27. const char* Name() const override { return "FaultInjectionSecondaryCache"; }
  28. Status Insert(const Slice& key, Cache::ObjectPtr value,
  29. const Cache::CacheItemHelper* helper,
  30. bool force_insert) override;
  31. Status InsertSaved(const Slice& /*key*/, const Slice& /*saved*/,
  32. CompressionType /*type*/, CacheTier /*source*/) override {
  33. return Status::OK();
  34. }
  35. std::unique_ptr<SecondaryCacheResultHandle> Lookup(
  36. const Slice& key, const Cache::CacheItemHelper* helper,
  37. Cache::CreateContext* create_context, bool wait, bool advise_erase,
  38. Statistics* stats, bool& kept_in_sec_cache) override;
  39. bool SupportForceErase() const override { return base_->SupportForceErase(); }
  40. void Erase(const Slice& key) override;
  41. void WaitAll(std::vector<SecondaryCacheResultHandle*> handles) override;
  42. Status SetCapacity(size_t capacity) override {
  43. return base_->SetCapacity(capacity);
  44. }
  45. Status GetCapacity(size_t& capacity) override {
  46. return base_->GetCapacity(capacity);
  47. }
  48. std::string GetPrintableOptions() const override {
  49. return base_->GetPrintableOptions();
  50. }
  51. private:
  52. class ResultHandle : public SecondaryCacheResultHandle {
  53. public:
  54. ResultHandle(FaultInjectionSecondaryCache* cache,
  55. std::unique_ptr<SecondaryCacheResultHandle>&& base)
  56. : cache_(cache), base_(std::move(base)), value_(nullptr), size_(0) {}
  57. ~ResultHandle() override {}
  58. bool IsReady() override;
  59. void Wait() override;
  60. Cache::ObjectPtr Value() override;
  61. size_t Size() override;
  62. static void WaitAll(FaultInjectionSecondaryCache* cache,
  63. std::vector<SecondaryCacheResultHandle*> handles);
  64. private:
  65. static void UpdateHandleValue(ResultHandle* handle);
  66. FaultInjectionSecondaryCache* cache_;
  67. std::unique_ptr<SecondaryCacheResultHandle> base_;
  68. Cache::ObjectPtr value_;
  69. size_t size_;
  70. };
  71. static void DeleteThreadLocalErrorContext(void* p) {
  72. ErrorContext* ctx = static_cast<ErrorContext*>(p);
  73. delete ctx;
  74. }
  75. const std::shared_ptr<SecondaryCache> base_;
  76. uint32_t seed_;
  77. int prob_;
  78. bool base_is_compressed_sec_cache_{false};
  79. struct ErrorContext {
  80. Random rand;
  81. explicit ErrorContext(uint32_t seed) : rand(seed) {}
  82. };
  83. std::unique_ptr<ThreadLocalPtr> thread_local_error_;
  84. ErrorContext* GetErrorContext();
  85. };
  86. } // namespace ROCKSDB_NAMESPACE