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).
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.
14 #include "db/log_format.h"
15 #include "rocksdb/slice.h"
16 #include "rocksdb/status.h"
17 #include "rocksdb/options.h"
21 class SequentialFileReader
;
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.
30 * Please see Writer for details on the file and record layout.
34 // Interface for reporting errors.
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;
44 // Create a reader that will return log records from "*file".
45 // "*file" must remain live while this Reader is in use.
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.
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
);
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
);
68 // Returns the physical offset of the last record returned by ReadRecord.
70 // Undefined before the first call to ReadRecord.
71 uint64_t LastRecordOffset();
73 // returns true if the reader has encountered an eof condition.
78 // returns true if the reader has encountered read error.
79 bool hasReadError() const { return read_error_
; }
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();
88 SequentialFileReader
* file() { return file_
.get(); }
90 Reporter
* GetReporter() const { return reporter_
; }
93 std::shared_ptr
<Logger
> info_log_
;
94 const std::unique_ptr
<SequentialFileReader
> file_
;
95 Reporter
* const reporter_
;
97 char* const backing_store_
;
99 // Internal state variables used for reading records
101 bool eof_
; // Last Read() indicated EOF by returning < kBlockSize
102 bool read_error_
; // Error occurred while reading from file
104 // Offset of the file position indicator within the last block when an
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_
;
113 // which log number this is
114 uint64_t const log_number_
;
116 // Whether this is a recycled log file
119 // Extend record types with the following special values
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,
137 // Return type, or one of the preceding special values
138 unsigned int ReadPhysicalRecord(Slice
* result
, size_t* drop_size
);
141 bool ReadMore(size_t* drop_size
, int *error
);
143 void UnmarkEOFInternal();
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
);
151 // No copying allowed
152 Reader(const Reader
&);
153 void operator=(const Reader
&);
156 class FragmentBufferedReader
: public Reader
{
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
),
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
;
172 std::string fragments_
;
173 bool in_fragmented_record_
;
175 bool TryReadFragment(Slice
* result
, size_t* drop_size
,
176 unsigned int* fragment_type_or_err
);
178 bool TryReadMore(size_t* drop_size
, int* error
);
181 FragmentBufferedReader(const FragmentBufferedReader
&);
182 void operator=(const FragmentBufferedReader
&);
186 } // namespace rocksdb