]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/db/log_reader.h
058382b8a3a082ba28d5a72337f0676923429889
[ceph.git] / ceph / src / rocksdb / db / log_reader.h
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 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9
10 #pragma once
11 #include <memory>
12 #include <stdint.h>
13
14 #include "db/log_format.h"
15 #include "rocksdb/slice.h"
16 #include "rocksdb/status.h"
17 #include "rocksdb/options.h"
18
19 namespace rocksdb {
20
21 class SequentialFileReader;
22 class Logger;
23
24 namespace log {
25
26 /**
27 * Reader is a general purpose log stream reader implementation. The actual job
28 * of reading from the device is implemented by the SequentialFile interface.
29 *
30 * Please see Writer for details on the file and record layout.
31 */
32 class Reader {
33 public:
34 // Interface for reporting errors.
35 class Reporter {
36 public:
37 virtual ~Reporter();
38
39 // Some corruption was detected. "size" is the approximate number
40 // of bytes dropped due to the corruption.
41 virtual void Corruption(size_t bytes, const Status& status) = 0;
42 };
43
44 // Create a reader that will return log records from "*file".
45 // "*file" must remain live while this Reader is in use.
46 //
47 // If "reporter" is non-nullptr, it is notified whenever some data is
48 // dropped due to a detected corruption. "*reporter" must remain
49 // live while this Reader is in use.
50 //
51 // If "checksum" is true, verify checksums if available.
52 Reader(std::shared_ptr<Logger> info_log,
53 // @lint-ignore TXT2 T25377293 Grandfathered in
54 std::unique_ptr<SequentialFileReader>&& file, Reporter* reporter,
55 bool checksum, uint64_t log_num);
56
57 virtual ~Reader();
58
59 // Read the next record into *record. Returns true if read
60 // successfully, false if we hit end of the input. May use
61 // "*scratch" as temporary storage. The contents filled in *record
62 // will only be valid until the next mutating operation on this
63 // reader or the next mutation to *scratch.
64 virtual bool ReadRecord(Slice* record, std::string* scratch,
65 WALRecoveryMode wal_recovery_mode =
66 WALRecoveryMode::kTolerateCorruptedTailRecords);
67
68 // Returns the physical offset of the last record returned by ReadRecord.
69 //
70 // Undefined before the first call to ReadRecord.
71 uint64_t LastRecordOffset();
72
73 // returns true if the reader has encountered an eof condition.
74 bool IsEOF() {
75 return eof_;
76 }
77
78 // returns true if the reader has encountered read error.
79 bool hasReadError() const { return read_error_; }
80
81 // when we know more data has been written to the file. we can use this
82 // function to force the reader to look again in the file.
83 // Also aligns the file position indicator to the start of the next block
84 // by reading the rest of the data from the EOF position to the end of the
85 // block that was partially read.
86 virtual void UnmarkEOF();
87
88 SequentialFileReader* file() { return file_.get(); }
89
90 Reporter* GetReporter() const { return reporter_; }
91
92 protected:
93 std::shared_ptr<Logger> info_log_;
94 const std::unique_ptr<SequentialFileReader> file_;
95 Reporter* const reporter_;
96 bool const checksum_;
97 char* const backing_store_;
98
99 // Internal state variables used for reading records
100 Slice buffer_;
101 bool eof_; // Last Read() indicated EOF by returning < kBlockSize
102 bool read_error_; // Error occurred while reading from file
103
104 // Offset of the file position indicator within the last block when an
105 // EOF was detected.
106 size_t eof_offset_;
107
108 // Offset of the last record returned by ReadRecord.
109 uint64_t last_record_offset_;
110 // Offset of the first location past the end of buffer_.
111 uint64_t end_of_buffer_offset_;
112
113 // which log number this is
114 uint64_t const log_number_;
115
116 // Whether this is a recycled log file
117 bool recycled_;
118
119 // Extend record types with the following special values
120 enum {
121 kEof = kMaxRecordType + 1,
122 // Returned whenever we find an invalid physical record.
123 // Currently there are three situations in which this happens:
124 // * The record has an invalid CRC (ReadPhysicalRecord reports a drop)
125 // * The record is a 0-length record (No drop is reported)
126 kBadRecord = kMaxRecordType + 2,
127 // Returned when we fail to read a valid header.
128 kBadHeader = kMaxRecordType + 3,
129 // Returned when we read an old record from a previous user of the log.
130 kOldRecord = kMaxRecordType + 4,
131 // Returned when we get a bad record length
132 kBadRecordLen = kMaxRecordType + 5,
133 // Returned when we get a bad record checksum
134 kBadRecordChecksum = kMaxRecordType + 6,
135 };
136
137 // Return type, or one of the preceding special values
138 unsigned int ReadPhysicalRecord(Slice* result, size_t* drop_size);
139
140 // Read some more
141 bool ReadMore(size_t* drop_size, int *error);
142
143 void UnmarkEOFInternal();
144
145 // Reports dropped bytes to the reporter.
146 // buffer_ must be updated to remove the dropped bytes prior to invocation.
147 void ReportCorruption(size_t bytes, const char* reason);
148 void ReportDrop(size_t bytes, const Status& reason);
149
150 private:
151 // No copying allowed
152 Reader(const Reader&);
153 void operator=(const Reader&);
154 };
155
156 class FragmentBufferedReader : public Reader {
157 public:
158 FragmentBufferedReader(std::shared_ptr<Logger> info_log,
159 // @lint-ignore TXT2 T25377293 Grandfathered in
160 std::unique_ptr<SequentialFileReader>&& _file,
161 Reporter* reporter, bool checksum, uint64_t log_num)
162 : Reader(info_log, std::move(_file), reporter, checksum, log_num),
163 fragments_(),
164 in_fragmented_record_(false) {}
165 ~FragmentBufferedReader() override {}
166 bool ReadRecord(Slice* record, std::string* scratch,
167 WALRecoveryMode wal_recovery_mode =
168 WALRecoveryMode::kTolerateCorruptedTailRecords) override;
169 void UnmarkEOF() override;
170
171 private:
172 std::string fragments_;
173 bool in_fragmented_record_;
174
175 bool TryReadFragment(Slice* result, size_t* drop_size,
176 unsigned int* fragment_type_or_err);
177
178 bool TryReadMore(size_t* drop_size, int* error);
179
180 // No copy allowed
181 FragmentBufferedReader(const FragmentBufferedReader&);
182 void operator=(const FragmentBufferedReader&);
183 };
184
185 } // namespace log
186 } // namespace rocksdb