Flush the log outside of lock

Summary:
Added a new call LogFlush() that flushes the log contents to the OS buffers. We never call it with lock held.

We call it once for every Read/Write and often in compaction/flush process so the frequency should not be a problem.

Test Plan: db_test

Reviewers: dhruba, haobo, kailiu, emayanke

Reviewed By: dhruba

CC: leveldb

Differential Revision: https://reviews.facebook.net/D13935
This commit is contained in:
Igor Canadi
2013-11-07 11:31:56 -08:00
parent fd2044883a
commit 444cf88a56
5 changed files with 50 additions and 7 deletions

View File

@@ -30,6 +30,12 @@ Logger::~Logger() {
FileLock::~FileLock() {
}
void LogFlush(Logger *info_log) {
if (info_log) {
info_log->Flush();
}
}
void Log(Logger* info_log, const char* format, ...) {
if (info_log) {
va_list ap;
@@ -39,6 +45,12 @@ void Log(Logger* info_log, const char* format, ...) {
}
}
void LogFlush(const shared_ptr<Logger>& info_log) {
if (info_log) {
info_log->Flush();
}
}
void Log(const shared_ptr<Logger>& info_log, const char* format, ...) {
if (info_log) {
va_list ap;

View File

@@ -33,8 +33,8 @@ class PosixLogger : public Logger {
uint64_t (*gettid_)(); // Return the thread id for the current thread
std::atomic_size_t log_size_;
int fd_;
const static uint64_t flush_every_seconds_ = 0;
uint64_t last_flush_micros_;
const static uint64_t flush_every_seconds_ = 5;
std::atomic_uint_fast64_t last_flush_micros_;
Env* env_;
public:
PosixLogger(FILE* f, uint64_t (*gettid)(), Env* env) :
@@ -43,6 +43,10 @@ class PosixLogger : public Logger {
virtual ~PosixLogger() {
fclose(file_);
}
virtual void Flush() {
fflush(file_);
last_flush_micros_ = env_->NowMicros();
}
virtual void Logv(const char* format, va_list ap) {
const uint64_t thread_id = (*gettid_)();
@@ -122,13 +126,14 @@ class PosixLogger : public Logger {
size_t sz = fwrite(base, 1, write_size, file_);
assert(sz == write_size);
if (sz > 0) {
if (env_->NowMicros() - last_flush_micros_ >=
flush_every_seconds_ * 1000000) {
fflush(file_);
last_flush_micros_ = env_->NowMicros();
}
log_size_ += write_size;
}
uint64_t now_micros = static_cast<uint64_t>(now_tv.tv_sec) * 1000000 +
now_tv.tv_usec;
if (now_micros - last_flush_micros_ >= flush_every_seconds_ * 1000000) {
fflush(file_);
last_flush_micros_ = now_micros;
}
if (base != buffer) {
delete[] base;
}