Skip to content

Commit 1bfade5

Browse files
Merge pull request #7600 from azat/DirectoryMonitor-current_batch.txt-corruption
Write current batch for distributed send atomically (using .tmp + rename)
2 parents 472cf81 + 4dfffdd commit 1bfade5

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

dbms/src/Storages/Distributed/DirectoryMonitor.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -355,8 +355,19 @@ struct StorageDistributedDirectoryMonitor::Batch
355355
/// we must try to re-send exactly the same batches.
356356
/// So we save contents of the current batch into the current_batch_file_path file
357357
/// and truncate it afterwards if all went well.
358-
WriteBufferFromFile out{parent.current_batch_file_path};
359-
writeText(out);
358+
359+
/// Temporary file is required for atomicity.
360+
String tmp_file{parent.current_batch_file_path + ".tmp"};
361+
362+
if (Poco::File{tmp_file}.exists())
363+
LOG_ERROR(parent.log, "Temporary file `" << tmp_file << "` exists. Unclean shutdown?");
364+
365+
{
366+
WriteBufferFromFile out{tmp_file, O_WRONLY | O_TRUNC | O_CREAT};
367+
writeText(out);
368+
}
369+
370+
Poco::File{tmp_file}.renameTo(parent.current_batch_file_path);
360371
}
361372
auto timeouts = ConnectionTimeouts::getTCPTimeoutsWithFailover(parent.storage.global_context.getSettingsRef());
362373
auto connection = parent.pool->get(timeouts);

0 commit comments

Comments
 (0)