From b3aba49ab081e3f642d8db9b84f3a4a50ebd8762 Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Wed, 7 Apr 2021 15:10:59 +0300 Subject: [PATCH] commitlog: segment_manager: max_size must be aligned This was triggered by the test_total_space_limit_of_commitlog dtest. When it passes a very large commitlog_segment_size_in_mb (1/6th of the free memory size, in mb), segment_manager constructor limits max_size to std::numeric_limits::max() which is 0xffffffff. This causes allocate_segment_ex to loop forever when writing the segment file since `dma_write` returns 0 when the count is unaligned (seen 4095). The fix here is to select a sligtly small maxsize that is aligned down to a multiple of 1MB. Signed-off-by: Benny Halevy Message-Id: <20210407121059.277912-1-bhalevy@scylladb.com> (cherry picked from commit 705f9c4f79293011fedd775187208db170f1326c) --- db/commitlog/commitlog.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/db/commitlog/commitlog.cc b/db/commitlog/commitlog.cc index 6d5a507c31..aa9d5c6439 100644 --- a/db/commitlog/commitlog.cc +++ b/db/commitlog/commitlog.cc @@ -1137,7 +1137,7 @@ db::commitlog::segment_manager::segment_manager(config c) return cfg; }()) - , max_size(std::min(std::numeric_limits::max(), std::max(cfg.commitlog_segment_size_in_mb, 1) * 1024 * 1024)) + , max_size(std::min(std::numeric_limits::max() / (1024 * 1024), std::max(cfg.commitlog_segment_size_in_mb, 1)) * 1024 * 1024) , max_mutation_size(max_size >> 1) , max_disk_size(size_t(std::ceil(cfg.commitlog_total_space_in_mb / double(smp::count))) * 1024 * 1024) // our threshold for trying to force a flush. needs heristics, for now max - segment_size/2. @@ -1446,6 +1446,9 @@ future db::commitlog::segment_manager: m += s; } auto s = co_await f.dma_write(max_size - rem, std::move(v), service::get_local_commitlog_priority()); + if (!s) [[unlikely]] { + on_internal_error(clogger, format("dma_write returned 0: max_size={} rem={} iovec.n={}", max_size, rem, n)); + } rem -= s; }