/src/rocksdb/db/wal_edit.h
Line | Count | Source (jump to first uncovered line) |
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 | | // WAL related classes used in VersionEdit and VersionSet. |
7 | | // Modifications to WalAddition and WalDeletion may need to update |
8 | | // VersionEdit and its related tests. |
9 | | |
10 | | #pragma once |
11 | | |
12 | | #include <map> |
13 | | #include <ostream> |
14 | | #include <string> |
15 | | #include <unordered_map> |
16 | | #include <vector> |
17 | | |
18 | | #include "logging/event_logger.h" |
19 | | #include "port/port.h" |
20 | | #include "rocksdb/rocksdb_namespace.h" |
21 | | |
22 | | namespace ROCKSDB_NAMESPACE { |
23 | | |
24 | | class JSONWriter; |
25 | | class Slice; |
26 | | class Status; |
27 | | |
28 | | using WalNumber = uint64_t; |
29 | | |
30 | | // Metadata of a WAL. |
31 | | class WalMetadata { |
32 | | public: |
33 | 0 | WalMetadata() = default; |
34 | | |
35 | | explicit WalMetadata(uint64_t synced_size_bytes) |
36 | 0 | : synced_size_bytes_(synced_size_bytes) {} |
37 | | |
38 | 0 | bool HasSyncedSize() const { return synced_size_bytes_ != kUnknownWalSize; } |
39 | | |
40 | 0 | void SetSyncedSizeInBytes(uint64_t bytes) { synced_size_bytes_ = bytes; } |
41 | | |
42 | 0 | uint64_t GetSyncedSizeInBytes() const { return synced_size_bytes_; } |
43 | | |
44 | | private: |
45 | | friend bool operator==(const WalMetadata& lhs, const WalMetadata& rhs); |
46 | | friend bool operator!=(const WalMetadata& lhs, const WalMetadata& rhs); |
47 | | // The size of WAL is unknown, used when the WAL is not synced yet or is |
48 | | // empty. |
49 | | constexpr static uint64_t kUnknownWalSize = |
50 | | std::numeric_limits<uint64_t>::max(); |
51 | | |
52 | | // Size of the most recently synced WAL in bytes. |
53 | | uint64_t synced_size_bytes_ = kUnknownWalSize; |
54 | | }; |
55 | | |
56 | 0 | inline bool operator==(const WalMetadata& lhs, const WalMetadata& rhs) { |
57 | 0 | return lhs.synced_size_bytes_ == rhs.synced_size_bytes_; |
58 | 0 | } |
59 | | |
60 | 0 | inline bool operator!=(const WalMetadata& lhs, const WalMetadata& rhs) { |
61 | 0 | return !(lhs == rhs); |
62 | 0 | } |
63 | | |
64 | | // These tags are persisted to MANIFEST, so it's part of the user API. |
65 | | enum class WalAdditionTag : uint32_t { |
66 | | // Indicates that there are no more tags. |
67 | | kTerminate = 1, |
68 | | // Synced Size in bytes. |
69 | | kSyncedSize = 2, |
70 | | // Add tags in the future, such as checksum? |
71 | | }; |
72 | | |
73 | | // Records the event of adding a WAL in VersionEdit. |
74 | | class WalAddition { |
75 | | public: |
76 | 0 | WalAddition() : number_(0), metadata_() {} |
77 | | |
78 | 0 | explicit WalAddition(WalNumber number) : number_(number), metadata_() {} |
79 | | |
80 | | WalAddition(WalNumber number, WalMetadata meta) |
81 | 0 | : number_(number), metadata_(std::move(meta)) {} |
82 | | |
83 | 0 | WalNumber GetLogNumber() const { return number_; } |
84 | | |
85 | 0 | const WalMetadata& GetMetadata() const { return metadata_; } |
86 | | |
87 | | void EncodeTo(std::string* dst) const; |
88 | | |
89 | | Status DecodeFrom(Slice* src); |
90 | | |
91 | | std::string DebugString() const; |
92 | | |
93 | | private: |
94 | | WalNumber number_; |
95 | | WalMetadata metadata_; |
96 | | }; |
97 | | |
98 | | std::ostream& operator<<(std::ostream& os, const WalAddition& wal); |
99 | | JSONWriter& operator<<(JSONWriter& jw, const WalAddition& wal); |
100 | | |
101 | | using WalAdditions = std::vector<WalAddition>; |
102 | | |
103 | | // Records the event of deleting WALs before the specified log number. |
104 | | class WalDeletion { |
105 | | public: |
106 | 339k | WalDeletion() : number_(kEmpty) {} |
107 | | |
108 | 13.9k | explicit WalDeletion(WalNumber number) : number_(number) {} |
109 | | |
110 | 9.28k | WalNumber GetLogNumber() const { return number_; } |
111 | | |
112 | | void EncodeTo(std::string* dst) const; |
113 | | |
114 | | Status DecodeFrom(Slice* src); |
115 | | |
116 | | std::string DebugString() const; |
117 | | |
118 | 291k | bool IsEmpty() const { return number_ == kEmpty; } |
119 | | |
120 | 101k | void Reset() { number_ = kEmpty; } |
121 | | |
122 | | private: |
123 | | static constexpr WalNumber kEmpty = 0; |
124 | | |
125 | | WalNumber number_; |
126 | | }; |
127 | | |
128 | | std::ostream& operator<<(std::ostream& os, const WalDeletion& wal); |
129 | | JSONWriter& operator<<(JSONWriter& jw, const WalDeletion& wal); |
130 | | |
131 | | // Used in VersionSet to keep the current set of WALs. |
132 | | // |
133 | | // When a WAL is synced or becomes obsoleted, |
134 | | // a VersionEdit is logged to MANIFEST and |
135 | | // the WAL is added to or deleted from WalSet. |
136 | | // |
137 | | // Not thread safe, needs external synchronization such as holding DB mutex. |
138 | | class WalSet { |
139 | | public: |
140 | | // Add WAL(s). |
141 | | // If the WAL is closed, |
142 | | // then there must be an existing unclosed WAL, |
143 | | // otherwise, return Status::Corruption. |
144 | | // Can happen when applying a VersionEdit or recovering from MANIFEST. |
145 | | Status AddWal(const WalAddition& wal); |
146 | | Status AddWals(const WalAdditions& wals); |
147 | | |
148 | | // Delete WALs with log number smaller than the specified wal number. |
149 | | // Can happen when applying a VersionEdit or recovering from MANIFEST. |
150 | | Status DeleteWalsBefore(WalNumber wal); |
151 | | |
152 | | // Resets the internal state. |
153 | | void Reset(); |
154 | | |
155 | | // WALs with number less than MinWalNumberToKeep should not exist in WalSet. |
156 | 0 | WalNumber GetMinWalNumberToKeep() const { return min_wal_number_to_keep_; } |
157 | | |
158 | 27.9k | const std::map<WalNumber, WalMetadata>& GetWals() const { return wals_; } |
159 | | |
160 | | // Checks whether there are missing or corrupted WALs. |
161 | | // Returns Status::OK if there is no missing nor corrupted WAL, |
162 | | // otherwise returns Status::Corruption. |
163 | | // logs_on_disk is a map from log number to the log filename. |
164 | | // Note that logs_on_disk may contain logs that is obsolete but |
165 | | // haven't been deleted from disk. |
166 | | Status CheckWals( |
167 | | Env* env, |
168 | | const std::unordered_map<WalNumber, std::string>& logs_on_disk) const; |
169 | | |
170 | | private: |
171 | | std::map<WalNumber, WalMetadata> wals_; |
172 | | // WAL number < min_wal_number_to_keep_ should not exist in wals_. |
173 | | // It's monotonically increasing, in-memory only, not written to MANIFEST. |
174 | | WalNumber min_wal_number_to_keep_ = 0; |
175 | | }; |
176 | | |
177 | | } // namespace ROCKSDB_NAMESPACE |