Add better support for state disks

This commit is contained in:
Antonio Andelic 2023-06-01 14:39:01 +00:00
parent 92ee24acd3
commit ffd4f7f196
2 changed files with 27 additions and 8 deletions

View File

@ -38,8 +38,6 @@ namespace ProfileEvents
extern const Event MemoryAllocatorPurgeTimeMicroseconds; extern const Event MemoryAllocatorPurgeTimeMicroseconds;
} }
namespace fs = std::filesystem;
namespace DB namespace DB
{ {

View File

@ -23,6 +23,8 @@ namespace ErrorCodes
namespace namespace
{ {
const std::string copy_lock_file = "STATE_COPY_LOCK";
bool isLocalhost(const std::string & hostname) bool isLocalhost(const std::string & hostname)
{ {
try try
@ -324,7 +326,13 @@ void KeeperStateManager::save_state(const nuraft::srv_state & state)
auto disk = getStateFileDisk(); auto disk = getStateFileDisk();
if (disk->exists(server_state_file_name)) if (disk->exists(server_state_file_name))
disk->moveFile(server_state_file_name, old_path); {
auto buf = disk->writeFile(copy_lock_file);
buf->finalize();
disk->copyFile(server_state_file_name, *disk, old_path);
disk->removeFile(copy_lock_file);
disk->removeFile(old_path);
}
auto server_state_file = disk->writeFile(server_state_file_name); auto server_state_file = disk->writeFile(server_state_file_name);
auto buf = state.serialize(); auto buf = state.serialize();
@ -339,6 +347,7 @@ void KeeperStateManager::save_state(const nuraft::srv_state & state)
server_state_file->write(reinterpret_cast<const char *>(buf->data_begin()), buf->size()); server_state_file->write(reinterpret_cast<const char *>(buf->data_begin()), buf->size());
server_state_file->sync(); server_state_file->sync();
server_state_file->finalize();
disk->removeFileIfExists(old_path); disk->removeFileIfExists(old_path);
} }
@ -417,13 +426,25 @@ nuraft::ptr<nuraft::srv_state> KeeperStateManager::read_state()
if (disk->exists(old_path)) if (disk->exists(old_path))
{ {
auto state = try_read_file(old_path); if (disk->exists(copy_lock_file))
if (state)
{ {
disk->moveFile(old_path, server_state_file_name); disk->removeFile(old_path);
return state; disk->removeFile(copy_lock_file);
} }
disk->removeFile(old_path); else
{
auto state = try_read_file(old_path);
if (state)
{
disk->moveFile(old_path, server_state_file_name);
return state;
}
disk->removeFile(old_path);
}
}
else if (disk->exists(copy_lock_file))
{
disk->removeFile(copy_lock_file);
} }
LOG_WARNING(logger, "No state was read"); LOG_WARNING(logger, "No state was read");