diff --git a/db/commitlog/commitlog.cc b/db/commitlog/commitlog.cc index 7491f23654..08e8ce7a5a 100644 --- a/db/commitlog/commitlog.cc +++ b/db/commitlog/commitlog.cc @@ -614,11 +614,17 @@ public: future terminate() { assert(_closed); if (!std::exchange(_terminated, true)) { - clogger.trace("{} is closed but not terminated.", *this); - if (_buffer.empty()) { - new_buffer(0); + // write a terminating zero block iff we are ending (a reused) + // block before actual file end. + // we should only get here when all actual data is + // already flushed (see below, close()). + if (size_on_disk() < _segment_manager->max_size) { + clogger.trace("{} is closed but not terminated.", *this); + if (_buffer.empty()) { + new_buffer(0); + } + return cycle(true, true); } - return cycle(true, true); } return make_ready_future(shared_from_this()); } diff --git a/test/boost/commitlog_test.cc b/test/boost/commitlog_test.cc index 7b8e43e127..25b9c63d06 100644 --- a/test/boost/commitlog_test.cc +++ b/test/boost/commitlog_test.cc @@ -296,7 +296,9 @@ SEASTAR_TEST_CASE(test_commitlog_closed) { SEASTAR_TEST_CASE(test_commitlog_delete_when_over_disk_limit) { commitlog::config cfg; - cfg.commitlog_segment_size_in_mb = 2; + + constexpr auto max_size_mb = 2; + cfg.commitlog_segment_size_in_mb = max_size_mb; cfg.commitlog_total_space_in_mb = 1; cfg.commitlog_sync_period_in_ms = 1; return cl_test(cfg, [](commitlog& log) { @@ -306,8 +308,15 @@ SEASTAR_TEST_CASE(test_commitlog_delete_when_over_disk_limit) { // add a flush handler that simply says we're done with the range. auto r = log.add_flush_handler([&log, sem, segments](cf_id_type id, replay_position pos) { *segments = log.get_active_segment_names(); - log.discard_completed_segments(id); - sem->signal(); + // Verify #5899 - file size should not exceed the config max. + return parallel_for_each(*segments, [](sstring filename) { + return file_size(filename).then([](uint64_t size) { + BOOST_REQUIRE_LE(size, max_size_mb * 1024 * 1024); + }); + }).then([&log, sem, id] { + log.discard_completed_segments(id); + sem->signal(); + }); }); auto set = make_lw_shared>();