Coverage Report

Created: 2024-07-27 06:53

/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