commitlog_replayer: differentiate between truncated file and corrupt entries

Refs #11845

When replaying, differentiate between the two cases for failure we have:
 - A broken actual entry - i.e. entry header/data does not hold up to
   crc scrutiny
 - Truncated file - i.e. a chunk header is broken or unreadable. This can
   be due to either "corruption" (i.e. borked write, post-corruption, hw
   whatever), or simply an unterminated segment.

The difference is that the former is recoverable, the latter is not.
We now signal and report the two separately. The end result for a user
is not much different, in either case they imply data loss and the
need for repair. But there is some value in differentiating which
of the two we encountered.

Modifies and adds test cases.
This commit is contained in:
Calle Wilund
2023-09-19 08:39:18 +00:00
parent 691f7f6edb
commit 862f4f2ed3
4 changed files with 90 additions and 4 deletions

View File

@@ -373,7 +373,7 @@ public:
uint64_t bytes() const {
return _bytes;
}
virtual const char* what() const noexcept {
const char* what() const noexcept override {
return _msg.c_str();
}
private:
@@ -383,7 +383,7 @@ public:
class invalid_segment_format : public segment_error {
static constexpr const char* _msg = "Not a scylla format commitlog file";
public:
virtual const char* what() const noexcept {
const char* what() const noexcept override {
return _msg;
}
};
@@ -391,11 +391,21 @@ public:
class header_checksum_error : public segment_error {
static constexpr const char* _msg = "Checksum error in file header";
public:
virtual const char* what() const noexcept {
const char* what() const noexcept override {
return _msg;
}
};
class segment_truncation : public segment_error {
std::string _msg;
uint64_t _pos;
public:
segment_truncation(uint64_t);
uint64_t position() const;
const char* what() const noexcept override;
};
static future<> read_log_file(sstring filename, sstring prefix, commit_load_reader_func, position_type = 0, const db::extensions* = nullptr);
private:
commitlog(config);