Output more debug on Binlog corruption.
GitOrigin-RevId: faae21038add485d80c668e2dd4317710daeb566
This commit is contained in:
parent
b06a08b106
commit
b155cfe645
@ -14,6 +14,7 @@
|
|||||||
#include "td/utils/logging.h"
|
#include "td/utils/logging.h"
|
||||||
#include "td/utils/misc.h"
|
#include "td/utils/misc.h"
|
||||||
#include "td/utils/port/Clocks.h"
|
#include "td/utils/port/Clocks.h"
|
||||||
|
#include "td/utils/port/FileFd.h"
|
||||||
#include "td/utils/port/path.h"
|
#include "td/utils/port/path.h"
|
||||||
#include "td/utils/port/PollFlags.h"
|
#include "td/utils/port/PollFlags.h"
|
||||||
#include "td/utils/port/Stat.h"
|
#include "td/utils/port/Stat.h"
|
||||||
@ -380,12 +381,14 @@ void Binlog::do_event(BinlogEvent &&event) {
|
|||||||
auto status = processor_->add_event(std::move(event));
|
auto status = processor_->add_event(std::move(event));
|
||||||
if (status.is_error()) {
|
if (status.is_error()) {
|
||||||
auto old_size = detail::file_size(path_);
|
auto old_size = detail::file_size(path_);
|
||||||
|
auto data = debug_get_binlog_data(fd_size_, old_size);
|
||||||
if (state_ == State::Load) {
|
if (state_ == State::Load) {
|
||||||
fd_.seek(fd_size_).ensure();
|
fd_.seek(fd_size_).ensure();
|
||||||
fd_.truncate_to_current_position(fd_size_).ensure();
|
fd_.truncate_to_current_position(fd_size_).ensure();
|
||||||
}
|
}
|
||||||
LOG(FATAL) << "Truncate binlog \"" << path_ << "\" from size " << old_size << " to size " << fd_size_
|
LOG(FATAL) << "Truncate binlog \"" << path_ << "\" from size " << old_size << " to size " << fd_size_
|
||||||
<< " in state " << static_cast<int32>(state_) << " due to error: " << status;
|
<< " in state " << static_cast<int32>(state_) << " due to error: " << status << " after reading "
|
||||||
|
<< data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,10 +495,12 @@ Status Binlog::load_binlog(const Callback &callback, const Callback &debug_callb
|
|||||||
if (r_need_size.is_error()) {
|
if (r_need_size.is_error()) {
|
||||||
if (r_need_size.error().code() == -2) {
|
if (r_need_size.error().code() == -2) {
|
||||||
auto old_size = detail::file_size(path_);
|
auto old_size = detail::file_size(path_);
|
||||||
fd_.seek(reader.offset()).ensure();
|
auto offset = reader.offset();
|
||||||
fd_.truncate_to_current_position(reader.offset()).ensure();
|
auto data = debug_get_binlog_data(offset, old_size);
|
||||||
LOG(FATAL) << "Truncate binlog \"" << path_ << "\" from size " << old_size << " to size " << reader.offset()
|
fd_.seek(offset).ensure();
|
||||||
<< " due to error: " << r_need_size.error();
|
fd_.truncate_to_current_position(offset).ensure();
|
||||||
|
LOG(FATAL) << "Truncate binlog \"" << path_ << "\" from size " << old_size << " to size " << offset
|
||||||
|
<< " due to error: " << r_need_size.error() << " after reading " << data;
|
||||||
}
|
}
|
||||||
LOG(ERROR) << r_need_size.error();
|
LOG(ERROR) << r_need_size.error();
|
||||||
break;
|
break;
|
||||||
@ -664,4 +669,43 @@ void Binlog::do_reindex() {
|
|||||||
update_write_encryption();
|
update_write_encryption();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string Binlog::debug_get_binlog_data(int64 begin_offset, int64 end_offset) {
|
||||||
|
if (begin_offset > end_offset) {
|
||||||
|
return "Begin offset is bigger than end_offset";
|
||||||
|
}
|
||||||
|
if (begin_offset == end_offset) {
|
||||||
|
return string();
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64 MAX_DATA_LENGTH = 512;
|
||||||
|
if (end_offset - begin_offset > MAX_DATA_LENGTH) {
|
||||||
|
end_offset = begin_offset + MAX_DATA_LENGTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto r_fd = FileFd::open(path_, FileFd::Flags::Read);
|
||||||
|
if (r_fd.is_error()) {
|
||||||
|
return PSTRING() << "Failed to open binlog: " << r_fd.error();
|
||||||
|
}
|
||||||
|
auto fd = r_fd.move_as_ok();
|
||||||
|
|
||||||
|
fd_.lock(FileFd::LockFlags::Unlock, path_, 1).ignore();
|
||||||
|
SCOPE_EXIT {
|
||||||
|
fd_.lock(FileFd::LockFlags::Write, path_, 1).ensure();
|
||||||
|
};
|
||||||
|
size_t expected_data_length = narrow_cast<size_t>(end_offset - begin_offset);
|
||||||
|
string data(expected_data_length, '\0');
|
||||||
|
auto r_data_size = fd.pread(data, begin_offset);
|
||||||
|
if (r_data_size.is_error()) {
|
||||||
|
return PSTRING() << "Failed to read binlog: " << r_data_size.error();
|
||||||
|
}
|
||||||
|
if (r_data_size.ok() < expected_data_length) {
|
||||||
|
data.resize(r_data_size.ok());
|
||||||
|
data = PSTRING() << format::as_hex_dump<4>(Slice(data)) << " | with " << expected_data_length - r_data_size.ok()
|
||||||
|
<< " missed bytes";
|
||||||
|
} else {
|
||||||
|
data = PSTRING() << format::as_hex_dump<4>(Slice(data));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace td {
|
namespace td {
|
||||||
|
|
||||||
struct BinlogInfo {
|
struct BinlogInfo {
|
||||||
bool was_created{false};
|
bool was_created{false};
|
||||||
uint64 last_id{0};
|
uint64 last_id{0};
|
||||||
@ -144,5 +145,8 @@ class Binlog {
|
|||||||
void reset_encryption();
|
void reset_encryption();
|
||||||
void update_read_encryption();
|
void update_read_encryption();
|
||||||
void update_write_encryption();
|
void update_write_encryption();
|
||||||
|
|
||||||
|
string debug_get_binlog_data(int64 begin_offset, int64 end_offset);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
Loading…
Reference in New Issue
Block a user