mirror of
https://github.com/scylladb/scylladb.git
synced 2026-05-12 19:02:12 +00:00
commitlog: Make pre-allocation drop O_DSYNC while pre-filling
Refs #7794 Iff we need to pre-fill segment file ni O_DSYNC mode, we should drop this for the pre-fill, to avoid issuing flushes until the file is filled. Done by temporarily closing, re-opening in "normal" mode, filling, then re-opening. v2: * More comment v3: * Add missing flush v4: * comment v5: * Split coroutine and fix into separate patches
This commit is contained in:
@@ -1418,6 +1418,13 @@ future<db::commitlog::segment_manager::sseg_ptr> db::commitlog::segment_manager:
|
||||
|
||||
clogger.trace("Pre-writing {} of {} KB to segment {}", (max_size - existing_size)/1024, max_size/1024, filename);
|
||||
|
||||
// re-open without o_dsync for pre-alloc. The reason/rationale
|
||||
// being that we want automatic (meta)data sync from O_DSYNC for when
|
||||
// we do actual CL flushes, but here it would just result in
|
||||
// data being committed before we've reached eof/finished writing.
|
||||
// Again an argument for sendfile-like constructs I guess...
|
||||
co_await f.close();
|
||||
f = co_await open_file_dma(filename, flags & open_flags(~int(open_flags::dsync)), opt);
|
||||
co_await f.allocate(existing_size, max_size - existing_size);
|
||||
|
||||
static constexpr size_t buf_size = 4 * segment::alignment;
|
||||
@@ -1443,6 +1450,8 @@ future<db::commitlog::segment_manager::sseg_ptr> db::commitlog::segment_manager:
|
||||
|
||||
// sync metadata (size/written)
|
||||
co_await f.flush();
|
||||
co_await f.close();
|
||||
f = co_await open_file_dma(filename, flags, opt);
|
||||
}
|
||||
} else {
|
||||
co_await f.truncate(max_size);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <set>
|
||||
|
||||
#include <seastar/testing/test_case.hh>
|
||||
#include <seastar/core/coroutine.hh>
|
||||
#include <seastar/core/future-util.hh>
|
||||
#include <seastar/core/do_with.hh>
|
||||
#include <seastar/core/scollectd_api.hh>
|
||||
@@ -719,3 +720,31 @@ SEASTAR_TEST_CASE(test_commitlog_add_entries) {
|
||||
});
|
||||
}
|
||||
|
||||
SEASTAR_TEST_CASE(test_commitlog_new_segment_odsync){
|
||||
commitlog::config cfg;
|
||||
cfg.commitlog_segment_size_in_mb = 1;
|
||||
cfg.use_o_dsync = true;
|
||||
|
||||
return cl_test(cfg, [](commitlog& log) -> future<> {
|
||||
auto uuid = utils::UUID_gen::get_time_UUID();
|
||||
rp_set set;
|
||||
while (set.size() <= 1) {
|
||||
sstring tmp = "hej bubba cow";
|
||||
rp_handle h = co_await log.add_mutation(uuid, tmp.size(), db::commitlog::force_sync::no, [tmp](db::commitlog::output& dst) {
|
||||
dst.write(tmp.data(), tmp.size());
|
||||
});
|
||||
set.put(std::move(h));
|
||||
}
|
||||
|
||||
auto names = log.get_active_segment_names();
|
||||
BOOST_REQUIRE(names.size() > 1);
|
||||
|
||||
// check that all the segments are pre-allocated.
|
||||
for (auto& name : names) {
|
||||
auto f = co_await seastar::open_file_dma(name, seastar::open_flags::ro);
|
||||
auto s = co_await f.size();
|
||||
co_await f.close();
|
||||
BOOST_CHECK_EQUAL(s, 1024u*1024u);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user