Skip to content

Commit 876b5d7

Browse files
laanwjl0rinc
authored andcommitted
Add filename to corruption errors
When a corruption happens, report the filename of the file where corruptions happens. This will aid in diagnosing database corruption issues. Adds a GetName() to all the environment file classes to make it possible to report a filename downstream.
1 parent ac69108 commit 876b5d7

File tree

13 files changed

+45
-8
lines changed

13 files changed

+45
-8
lines changed

db/db_impl.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ Status DBImpl::RecoverLogFile(uint64_t log_number, bool last_log,
432432
while (reader.ReadRecord(&record, &scratch) && status.ok()) {
433433
if (record.size() < 12) {
434434
reporter.Corruption(record.size(),
435-
Status::Corruption("log record too small"));
435+
Status::Corruption("log record too small", fname));
436436
continue;
437437
}
438438
WriteBatchInternal::SetContents(&batch, record);

db/db_test.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ class SpecialEnv : public EnvWrapper {
190190
}
191191
return base_->Sync();
192192
}
193+
std::string GetName() const override { return ""; }
193194
};
194195
class ManifestFile : public WritableFile {
195196
private:
@@ -215,6 +216,7 @@ class SpecialEnv : public EnvWrapper {
215216
return base_->Sync();
216217
}
217218
}
219+
std::string GetName() const override { return ""; }
218220
};
219221

220222
if (non_writable_.load(std::memory_order_acquire)) {
@@ -247,6 +249,7 @@ class SpecialEnv : public EnvWrapper {
247249
counter_->Increment();
248250
return target_->Read(offset, n, result, scratch);
249251
}
252+
std::string GetName() const override { return ""; }
250253
};
251254

252255
Status s = target()->NewRandomAccessFile(f, r);

db/fault_injection_test.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class TestWritableFile : public WritableFile {
114114
Status Close() override;
115115
Status Flush() override;
116116
Status Sync() override;
117+
std::string GetName() const override { return ""; }
117118

118119
private:
119120
FileState state_;

db/leveldbutil.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class StdoutPrinter : public WritableFile {
2020
Status Close() override { return Status::OK(); }
2121
Status Flush() override { return Status::OK(); }
2222
Status Sync() override { return Status::OK(); }
23+
std::string GetName() const override { return "[stdout]"; }
2324
};
2425

2526
bool HandleDumpCommand(Env* env, char** files, int num) {

db/log_reader.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ bool Reader::ReadRecord(Slice* record, std::string* scratch) {
176176
uint64_t Reader::LastRecordOffset() { return last_record_offset_; }
177177

178178
void Reader::ReportCorruption(uint64_t bytes, const char* reason) {
179-
ReportDrop(bytes, Status::Corruption(reason));
179+
ReportDrop(bytes, Status::Corruption(reason, file_->GetName()));
180180
}
181181

182182
void Reader::ReportDrop(uint64_t bytes, const Status& reason) {

db/log_test.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ class LogTest : public testing::Test {
168168
contents_.append(slice.data(), slice.size());
169169
return Status::OK();
170170
}
171+
std::string GetName() const override { return ""; }
171172

172173
std::string contents_;
173174
};
@@ -204,6 +205,7 @@ class LogTest : public testing::Test {
204205

205206
return Status::OK();
206207
}
208+
std::string GetName() const { return ""; }
207209

208210
Slice contents_;
209211
bool force_error_;

db/repair.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ class Repairer {
183183
while (reader.ReadRecord(&record, &scratch)) {
184184
if (record.size() < 12) {
185185
reporter.Corruption(record.size(),
186-
Status::Corruption("log record too small"));
186+
Status::Corruption("log record too small", logname));
187187
continue;
188188
}
189189
WriteBatchInternal::SetContents(&batch, record);

helpers/memenv/memenv.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ class SequentialFileImpl : public SequentialFile {
177177
return Status::OK();
178178
}
179179

180+
virtual std::string GetName() const override { return "[memenv]"; }
180181
private:
181182
FileState* file_;
182183
uint64_t pos_;
@@ -193,6 +194,7 @@ class RandomAccessFileImpl : public RandomAccessFile {
193194
return file_->Read(offset, n, result, scratch);
194195
}
195196

197+
virtual std::string GetName() const override { return "[memenv]"; }
196198
private:
197199
FileState* file_;
198200
};
@@ -209,6 +211,7 @@ class WritableFileImpl : public WritableFile {
209211
Status Flush() override { return Status::OK(); }
210212
Status Sync() override { return Status::OK(); }
211213

214+
virtual std::string GetName() const override { return "[memenv]"; }
212215
private:
213216
FileState* file_;
214217
};

include/leveldb/env.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ class LEVELDB_EXPORT SequentialFile {
246246
//
247247
// REQUIRES: External synchronization
248248
virtual Status Skip(uint64_t n) = 0;
249+
250+
// Get a name for the file, only for error reporting
251+
virtual std::string GetName() const = 0;
249252
};
250253

251254
// A file abstraction for randomly reading the contents of a file.
@@ -269,6 +272,9 @@ class LEVELDB_EXPORT RandomAccessFile {
269272
// Safe for concurrent use by multiple threads.
270273
virtual Status Read(uint64_t offset, size_t n, Slice* result,
271274
char* scratch) const = 0;
275+
276+
// Get a name for the file, only for error reporting
277+
virtual std::string GetName() const = 0;
272278
};
273279

274280
// A file abstraction for sequential writing. The implementation
@@ -287,6 +293,9 @@ class LEVELDB_EXPORT WritableFile {
287293
virtual Status Close() = 0;
288294
virtual Status Flush() = 0;
289295
virtual Status Sync() = 0;
296+
297+
// Get a name for the file, only for error reporting
298+
virtual std::string GetName() const = 0;
290299
};
291300

292301
// An interface for writing log messages.

table/format.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
8484
}
8585
if (contents.size() != n + kBlockTrailerSize) {
8686
delete[] buf;
87-
return Status::Corruption("truncated block read");
87+
return Status::Corruption("truncated block read", file->GetName());
8888
}
8989

9090
// Check the crc of the type and the block contents
@@ -94,7 +94,7 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
9494
const uint32_t actual = crc32c::Value(data, n + 1);
9595
if (actual != crc) {
9696
delete[] buf;
97-
s = Status::Corruption("block checksum mismatch");
97+
s = Status::Corruption("block checksum mismatch", file->GetName());
9898
return s;
9999
}
100100
}
@@ -121,7 +121,7 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
121121
size_t ulength = 0;
122122
if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
123123
delete[] buf;
124-
return Status::Corruption("corrupted snappy compressed block length");
124+
return Status::Corruption("corrupted snappy compressed block length", file->GetName());
125125
}
126126
char* ubuf = new char[ulength];
127127
if (!port::Snappy_Uncompress(data, n, ubuf)) {
@@ -145,7 +145,7 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
145145
if (!port::Zstd_Uncompress(data, n, ubuf)) {
146146
delete[] buf;
147147
delete[] ubuf;
148-
return Status::Corruption("corrupted zstd compressed block contents");
148+
return Status::Corruption("corrupted zstd compressed block contents", file->GetName());
149149
}
150150
delete[] buf;
151151
result->data = Slice(ubuf, ulength);
@@ -155,7 +155,7 @@ Status ReadBlock(RandomAccessFile* file, const ReadOptions& options,
155155
}
156156
default:
157157
delete[] buf;
158-
return Status::Corruption("bad block type");
158+
return Status::Corruption("bad block type", file->GetName());
159159
}
160160

161161
return Status::OK();

table/table_test.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ class StringSink : public WritableFile {
103103
return Status::OK();
104104
}
105105

106+
std::string GetName() const override { return ""; }
106107
private:
107108
std::string contents_;
108109
};
@@ -129,6 +130,7 @@ class StringSource : public RandomAccessFile {
129130
return Status::OK();
130131
}
131132

133+
std::string GetName() const { return ""; }
132134
private:
133135
std::string contents_;
134136
};

util/env_posix.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,8 @@ class PosixSequentialFile final : public SequentialFile {
163163
return Status::OK();
164164
}
165165

166+
virtual std::string GetName() const override { return filename_; }
167+
166168
private:
167169
const int fd_;
168170
const std::string filename_;
@@ -223,6 +225,8 @@ class PosixRandomAccessFile final : public RandomAccessFile {
223225
return status;
224226
}
225227

228+
virtual std::string GetName() const override { return filename_; }
229+
226230
private:
227231
const bool has_permanent_fd_; // If false, the file is opened on every read.
228232
const int fd_; // -1 if has_permanent_fd_ is false.
@@ -267,6 +271,8 @@ class PosixMmapReadableFile final : public RandomAccessFile {
267271
return Status::OK();
268272
}
269273

274+
virtual std::string GetName() const override { return filename_; }
275+
270276
private:
271277
char* const mmap_base_;
272278
const size_t length_;
@@ -454,6 +460,8 @@ class PosixWritableFile final : public WritableFile {
454460
return Basename(filename).starts_with("MANIFEST");
455461
}
456462

463+
virtual std::string GetName() const override { return filename_; }
464+
457465
// buf_[0, pos_ - 1] contains data to be written to fd_.
458466
char buf_[kWritableFileBufferSize];
459467
size_t pos_;

util/env_windows.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ class WindowsSequentialFile : public SequentialFile {
193193
return Status::OK();
194194
}
195195

196+
std::string GetName() const override { return filename_; }
197+
196198
private:
197199
const ScopedHandle handle_;
198200
const std::string filename_;
@@ -225,6 +227,8 @@ class WindowsRandomAccessFile : public RandomAccessFile {
225227
return Status::OK();
226228
}
227229

230+
std::string GetName() const override { return filename_; }
231+
228232
private:
229233
const ScopedHandle handle_;
230234
const std::string filename_;
@@ -256,6 +260,8 @@ class WindowsMmapReadableFile : public RandomAccessFile {
256260
return Status::OK();
257261
}
258262

263+
std::string GetName() const override { return filename_; }
264+
259265
private:
260266
char* const mmap_base_;
261267
const size_t length_;
@@ -325,6 +331,8 @@ class WindowsWritableFile : public WritableFile {
325331
return Status::OK();
326332
}
327333

334+
std::string GetName() const override { return filename_; }
335+
328336
private:
329337
Status FlushBuffer() {
330338
Status status = WriteUnbuffered(buf_, pos_);

0 commit comments

Comments
 (0)