transaction_util.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. #pragma once
  6. #ifndef ROCKSDB_LITE
  7. #include <string>
  8. #include <unordered_map>
  9. #include "db/dbformat.h"
  10. #include "db/read_callback.h"
  11. #include "rocksdb/db.h"
  12. #include "rocksdb/slice.h"
  13. #include "rocksdb/status.h"
  14. #include "rocksdb/types.h"
  15. namespace ROCKSDB_NAMESPACE {
  16. struct TransactionKeyMapInfo {
  17. // Earliest sequence number that is relevant to this transaction for this key
  18. SequenceNumber seq;
  19. uint32_t num_writes;
  20. uint32_t num_reads;
  21. bool exclusive;
  22. explicit TransactionKeyMapInfo(SequenceNumber seq_no)
  23. : seq(seq_no), num_writes(0), num_reads(0), exclusive(false) {}
  24. // Used in PopSavePoint to collapse two savepoints together.
  25. void Merge(const TransactionKeyMapInfo& info) {
  26. assert(seq <= info.seq);
  27. num_reads += info.num_reads;
  28. num_writes += info.num_writes;
  29. exclusive |= info.exclusive;
  30. }
  31. };
  32. using TransactionKeyMap =
  33. std::unordered_map<uint32_t,
  34. std::unordered_map<std::string, TransactionKeyMapInfo>>;
  35. class DBImpl;
  36. struct SuperVersion;
  37. class WriteBatchWithIndex;
  38. class TransactionUtil {
  39. public:
  40. // Verifies there have been no commits to this key in the db since this
  41. // sequence number.
  42. //
  43. // If cache_only is true, then this function will not attempt to read any
  44. // SST files. This will make it more likely this function will
  45. // return an error if it is unable to determine if there are any conflicts.
  46. //
  47. // See comment of CheckKey() for explanation of `snap_seq`, `snap_checker`
  48. // and `min_uncommitted`.
  49. //
  50. // Returns OK on success, BUSY if there is a conflicting write, or other error
  51. // status for any unexpected errors.
  52. static Status CheckKeyForConflicts(
  53. DBImpl* db_impl, ColumnFamilyHandle* column_family,
  54. const std::string& key, SequenceNumber snap_seq, bool cache_only,
  55. ReadCallback* snap_checker = nullptr,
  56. SequenceNumber min_uncommitted = kMaxSequenceNumber);
  57. // For each key,SequenceNumber pair in the TransactionKeyMap, this function
  58. // will verify there have been no writes to the key in the db since that
  59. // sequence number.
  60. //
  61. // Returns OK on success, BUSY if there is a conflicting write, or other error
  62. // status for any unexpected errors.
  63. //
  64. // REQUIRED: this function should only be called on the write thread or if the
  65. // mutex is held.
  66. static Status CheckKeysForConflicts(DBImpl* db_impl,
  67. const TransactionKeyMap& keys,
  68. bool cache_only);
  69. private:
  70. // If `snap_checker` == nullptr, writes are always commited in sequence number
  71. // order. All sequence number <= `snap_seq` will not conflict with any
  72. // write, and all keys > `snap_seq` of `key` will trigger conflict.
  73. // If `snap_checker` != nullptr, writes may not commit in sequence number
  74. // order. In this case `min_uncommitted` is a lower bound.
  75. // seq < `min_uncommitted`: no conflict
  76. // seq > `snap_seq`: applicable to conflict
  77. // `min_uncommitted` <= seq <= `snap_seq`: call `snap_checker` to determine.
  78. static Status CheckKey(DBImpl* db_impl, SuperVersion* sv,
  79. SequenceNumber earliest_seq, SequenceNumber snap_seq,
  80. const std::string& key, bool cache_only,
  81. ReadCallback* snap_checker = nullptr,
  82. SequenceNumber min_uncommitted = kMaxSequenceNumber);
  83. };
  84. } // namespace ROCKSDB_NAMESPACE
  85. #endif // ROCKSDB_LITE