diff --git a/db/auto_roll_logger.cc b/db/auto_roll_logger.cc index cf92f34c8..c984b4810 100644 --- a/db/auto_roll_logger.cc +++ b/db/auto_roll_logger.cc @@ -32,8 +32,17 @@ Status AutoRollLogger::ResetLogger() { } void AutoRollLogger::RollLogFile() { - std::string old_fname = OldInfoLogFileName( - dbname_, env_->NowMicros(), db_absolute_path_, db_log_dir_); + uint64_t now = env_->NowMicros(); + std::string old_fname; + // Try to check target name only 10 times at most + for (int i = 0; i < 10; i++) { + old_fname = OldInfoLogFileName( + dbname_, now, db_absolute_path_, db_log_dir_); + if (!env_->FileExists(old_fname).ok()) { + break; + } + now++; + }; env_->RenameFile(log_fname_, old_fname); } diff --git a/port/win/env_win.cc b/port/win/env_win.cc index 50059a98f..87a25569c 100644 --- a/port/win/env_win.cc +++ b/port/win/env_win.cc @@ -1138,6 +1138,8 @@ void WinthreadCall(const char* label, std::error_code result) { } } +typedef VOID(WINAPI * FnGetSystemTimePreciseAsFileTime)(LPFILETIME); + class WinEnv : public Env { public: WinEnv(); @@ -1676,25 +1678,29 @@ class WinEnv : public Env { } virtual uint64_t NowMicros() override { - // all std::chrono clocks on windows proved to return - // values that may repeat that is not good enough for some uses. - const int64_t c_UnixEpochStartTicks = 116444736000000000i64; - const int64_t c_FtToMicroSec = 10; - - // This interface needs to return system time and not - // just any microseconds because it is often used as an argument - // to TimedWait() on condition variable - FILETIME ftSystemTime; - GetSystemTimePreciseAsFileTime(&ftSystemTime); - - LARGE_INTEGER li; - li.LowPart = ftSystemTime.dwLowDateTime; - li.HighPart = ftSystemTime.dwHighDateTime; - // Subtract unix epoch start - li.QuadPart -= c_UnixEpochStartTicks; - // Convert to microsecs - li.QuadPart /= c_FtToMicroSec; - return li.QuadPart; + if (GetSystemTimePreciseAsFileTime_ != NULL) { + // all std::chrono clocks on windows proved to return + // values that may repeat that is not good enough for some uses. + const int64_t c_UnixEpochStartTicks = 116444736000000000i64; + const int64_t c_FtToMicroSec = 10; + + // This interface needs to return system time and not + // just any microseconds because it is often used as an argument + // to TimedWait() on condition variable + FILETIME ftSystemTime; + GetSystemTimePreciseAsFileTime_(&ftSystemTime); + + LARGE_INTEGER li; + li.LowPart = ftSystemTime.dwLowDateTime; + li.HighPart = ftSystemTime.dwHighDateTime; + // Subtract unix epoch start + li.QuadPart -= c_UnixEpochStartTicks; + // Convert to microsecs + li.QuadPart /= c_FtToMicroSec; + return li.QuadPart; + } + using namespace std::chrono; + return duration_cast(system_clock::now().time_since_epoch()).count(); } virtual uint64_t NowNanos() override { @@ -2104,8 +2110,13 @@ class WinEnv : public Env { std::vector thread_pools_; mutable std::mutex mu_; std::vector threads_to_join_; + static FnGetSystemTimePreciseAsFileTime GetSystemTimePreciseAsFileTime_; + static bool GetSystemTimePreciseAsFileTimeInitialized_; }; +FnGetSystemTimePreciseAsFileTime WinEnv::GetSystemTimePreciseAsFileTime_ = NULL; +bool WinEnv::GetSystemTimePreciseAsFileTimeInitialized_ = false; + WinEnv::WinEnv() : checkedDiskForMmap_(false), forceMmapOff(false), @@ -2113,6 +2124,16 @@ WinEnv::WinEnv() allocation_granularity_(page_size_), perf_counter_frequency_(0), thread_pools_(Priority::TOTAL) { + + if (!GetSystemTimePreciseAsFileTimeInitialized_) { + HMODULE module = GetModuleHandle("kernel32.dll"); + if (module != NULL) { + GetSystemTimePreciseAsFileTime_ = (FnGetSystemTimePreciseAsFileTime)GetProcAddress( + module, "GetSystemTimePreciseAsFileTime"); + } + GetSystemTimePreciseAsFileTimeInitialized_ = true; + } + SYSTEM_INFO sinfo; GetSystemInfo(&sinfo);