From 33a4d428f943ea49121ce0fa3daa702f3c43271a Mon Sep 17 00:00:00 2001 From: Arseny Smirnov Date: Fri, 16 Feb 2018 12:13:04 +0300 Subject: [PATCH] Binlog: call fsync only if it is necessary GitOrigin-RevId: 2081799ad27c62950d029ebeb13d19f343be024d --- tddb/td/db/binlog/Binlog.cpp | 28 +++++++++++++++++++--------- tddb/td/db/binlog/Binlog.h | 1 + 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/tddb/td/db/binlog/Binlog.cpp b/tddb/td/db/binlog/Binlog.cpp index 675c78f52..5d76028db 100644 --- a/tddb/td/db/binlog/Binlog.cpp +++ b/tddb/td/db/binlog/Binlog.cpp @@ -258,10 +258,12 @@ Status Binlog::close(bool need_sync) { path_ = ""; info_.is_opened = false; fd_.close(); + need_sync_ = false; }; - flush(); if (need_sync) { - TRY_STATUS(fd_.sync()); + sync(); + } else { + flush(); } return Status::OK(); } @@ -353,7 +355,11 @@ void Binlog::do_event(BinlogEvent &&event) { void Binlog::sync() { flush(); - fd_.sync().ensure(); + if (need_sync_) { + auto status = fd_.sync(); + LOG_IF(FATAL, status.is_error()) << "Failed to sync binlog: " << status; + need_sync_ = false; + } } void Binlog::flush() { @@ -365,8 +371,14 @@ void Binlog::flush() { if (byte_flow_flag_) { byte_flow_source_.wakeup(); } - fd_.flush_write().ensure(); + auto r_written = fd_.flush_write(); + r_written.ensure(); + auto written = r_written.ok(); + if (written > 0) { + need_sync_ = true; + } need_flush_since_ = 0; + LOG_IF(FATAL, fd_.need_flush_write()) << "Failed to flush binlog"; } void Binlog::lazy_flush() { @@ -584,13 +596,11 @@ void Binlog::do_reindex() { processor_->for_each([&](BinlogEvent &event) { do_event(std::move(event)); // NB: no move is actually happens }); - flush(); - LOG_IF(FATAL, fd_.need_flush_write()) << "Reindex failed: failed to flush everything on disk"; - auto status = fd_.sync(); - LOG_IF(FATAL, status.is_error()) << "Failed to sync binlog: " << status; + need_sync_ = true; // must sync creation of the file + sync(); // finish_reindex - status = unlink(path_); + auto status = unlink(path_); LOG_IF(FATAL, status.is_error()) << "Failed to unlink old binlog: " << status; status = rename(new_path, path_); LOG_IF(FATAL, status.is_error()) << "Failed to rename binlog: " << status; diff --git a/tddb/td/db/binlog/Binlog.h b/tddb/td/db/binlog/Binlog.h index 87aed9a7a..7a286f9e1 100644 --- a/tddb/td/db/binlog/Binlog.h +++ b/tddb/td/db/binlog/Binlog.h @@ -123,6 +123,7 @@ class Binlog { bool in_flush_events_buffer_{false}; uint64 last_id_{0}; double need_flush_since_ = 0; + bool need_sync_{false}; enum class State { Empty, Load, Reindex, Run } state_{State::Empty}; static constexpr uint32 MAX_EVENT_SIZE = 65536;