| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- // WAL related classes used in VersionEdit and VersionSet.
- // Modifications to WalAddition and WalDeletion may need to update
- // VersionEdit and its related tests.
- #pragma once
- #include <map>
- #include <ostream>
- #include <string>
- #include <unordered_map>
- #include <vector>
- #include "logging/event_logger.h"
- #include "port/port.h"
- #include "rocksdb/rocksdb_namespace.h"
- namespace ROCKSDB_NAMESPACE {
- class JSONWriter;
- class Slice;
- class Status;
- using WalNumber = uint64_t;
- // Metadata of a WAL.
- class WalMetadata {
- public:
- WalMetadata() = default;
- explicit WalMetadata(uint64_t synced_size_bytes)
- : synced_size_bytes_(synced_size_bytes) {}
- bool HasSyncedSize() const { return synced_size_bytes_ != kUnknownWalSize; }
- void SetSyncedSizeInBytes(uint64_t bytes) { synced_size_bytes_ = bytes; }
- uint64_t GetSyncedSizeInBytes() const { return synced_size_bytes_; }
- private:
- friend bool operator==(const WalMetadata& lhs, const WalMetadata& rhs);
- friend bool operator!=(const WalMetadata& lhs, const WalMetadata& rhs);
- // The size of WAL is unknown, used when the WAL is not synced yet or is
- // empty.
- constexpr static uint64_t kUnknownWalSize =
- std::numeric_limits<uint64_t>::max();
- // Size of the most recently synced WAL in bytes.
- uint64_t synced_size_bytes_ = kUnknownWalSize;
- };
- inline bool operator==(const WalMetadata& lhs, const WalMetadata& rhs) {
- return lhs.synced_size_bytes_ == rhs.synced_size_bytes_;
- }
- inline bool operator!=(const WalMetadata& lhs, const WalMetadata& rhs) {
- return !(lhs == rhs);
- }
- // These tags are persisted to MANIFEST, so it's part of the user API.
- enum class WalAdditionTag : uint32_t {
- // Indicates that there are no more tags.
- kTerminate = 1,
- // Synced Size in bytes.
- kSyncedSize = 2,
- // Add tags in the future, such as checksum?
- };
- // Records the event of adding a WAL in VersionEdit.
- class WalAddition {
- public:
- WalAddition() : number_(0), metadata_() {}
- explicit WalAddition(WalNumber number) : number_(number), metadata_() {}
- WalAddition(WalNumber number, WalMetadata meta)
- : number_(number), metadata_(std::move(meta)) {}
- WalNumber GetLogNumber() const { return number_; }
- const WalMetadata& GetMetadata() const { return metadata_; }
- void EncodeTo(std::string* dst) const;
- Status DecodeFrom(Slice* src);
- std::string DebugString() const;
- private:
- WalNumber number_;
- WalMetadata metadata_;
- };
- std::ostream& operator<<(std::ostream& os, const WalAddition& wal);
- JSONWriter& operator<<(JSONWriter& jw, const WalAddition& wal);
- using WalAdditions = std::vector<WalAddition>;
- // Records the event of deleting WALs before the specified log number.
- class WalDeletion {
- public:
- WalDeletion() : number_(kEmpty) {}
- explicit WalDeletion(WalNumber number) : number_(number) {}
- WalNumber GetLogNumber() const { return number_; }
- void EncodeTo(std::string* dst) const;
- Status DecodeFrom(Slice* src);
- std::string DebugString() const;
- bool IsEmpty() const { return number_ == kEmpty; }
- void Reset() { number_ = kEmpty; }
- private:
- static constexpr WalNumber kEmpty = 0;
- WalNumber number_;
- };
- std::ostream& operator<<(std::ostream& os, const WalDeletion& wal);
- JSONWriter& operator<<(JSONWriter& jw, const WalDeletion& wal);
- // Used in VersionSet to keep the current set of WALs.
- //
- // When a WAL is synced or becomes obsoleted,
- // a VersionEdit is logged to MANIFEST and
- // the WAL is added to or deleted from WalSet.
- //
- // Not thread safe, needs external synchronization such as holding DB mutex.
- class WalSet {
- public:
- // Add WAL(s).
- // If the WAL is closed,
- // then there must be an existing unclosed WAL,
- // otherwise, return Status::Corruption.
- // Can happen when applying a VersionEdit or recovering from MANIFEST.
- Status AddWal(const WalAddition& wal);
- Status AddWals(const WalAdditions& wals);
- // Delete WALs with log number smaller than the specified wal number.
- // Can happen when applying a VersionEdit or recovering from MANIFEST.
- Status DeleteWalsBefore(WalNumber wal);
- // Resets the internal state.
- void Reset();
- // WALs with number less than MinWalNumberToKeep should not exist in WalSet.
- WalNumber GetMinWalNumberToKeep() const { return min_wal_number_to_keep_; }
- const std::map<WalNumber, WalMetadata>& GetWals() const { return wals_; }
- // Checks whether there are missing or corrupted WALs.
- // Returns Status::OK if there is no missing nor corrupted WAL,
- // otherwise returns Status::Corruption.
- // logs_on_disk is a map from log number to the log filename.
- // Note that logs_on_disk may contain logs that is obsolete but
- // haven't been deleted from disk.
- Status CheckWals(
- Env* env,
- const std::unordered_map<WalNumber, std::string>& logs_on_disk) const;
- private:
- std::map<WalNumber, WalMetadata> wals_;
- // WAL number < min_wal_number_to_keep_ should not exist in wals_.
- // It's monotonically increasing, in-memory only, not written to MANIFEST.
- WalNumber min_wal_number_to_keep_ = 0;
- };
- } // namespace ROCKSDB_NAMESPACE
|