Merge 'commitlog: Fix position adjustment in large allocation' from Calle Wilund

Refs SCYLLADB-1815
Refs SCYLLADB-1757

(Together with #29753, should be fix for the latter)

Typo/copy-paste error in previous fix for position checks vs. file max when calculating available allocation space.

Should be backported to same branches as original (broken) fix, #29753

Closes scylladb/scylladb#30179

* github.com:scylladb/scylladb:
  commitlog_test: Add test for segment size overflow
  commitlog: Fix position adjustment in large allocation
This commit is contained in:
Botond Dénes
2026-06-03 12:29:39 +03:00
committed by Avi Kivity
3 changed files with 85 additions and 5 deletions

View File

@@ -340,7 +340,9 @@ public:
future<> oversized_allocation(entry_writer&, db::timeout_clock::time_point timeout);
replay_position min_position();
replay_position min_position() const;
replay_position current_position() const;
size_t sector_overhead(segment_id_type, size_t) const;
template<typename T>
struct byte_flow {
@@ -1508,7 +1510,7 @@ public:
}
};
db::replay_position db::commitlog::segment_manager::min_position() {
db::replay_position db::commitlog::segment_manager::min_position() const {
if (_segments.empty()) {
return {_ids, 0};
} else {
@@ -1516,6 +1518,24 @@ db::replay_position db::commitlog::segment_manager::min_position() {
}
}
db::replay_position db::commitlog::segment_manager::current_position() const {
if (_segments.empty()) {
return {_ids, 0};
} else {
auto s = _segments.front();
return {s->_desc.id, s->position()};
}
}
size_t db::commitlog::segment_manager::sector_overhead(segment_id_type id, size_t size) const {
for (auto& s : _segments) {
if (s->_desc.id == id) {
return s->sector_overhead(size);
}
}
return 0;
}
template<typename T, typename R>
requires std::derived_from<T, db::commitlog::entry_writer> && std::same_as<R, decltype(std::declval<T>().result())>
future<R> db::commitlog::segment_manager::allocate_when_possible(T writer, db::timeout_clock::time_point timeout) {
@@ -1777,7 +1797,7 @@ future<> db::commitlog::segment_manager::oversized_allocation(entry_writer& writ
}
// bytes not counting overhead
auto pos = s->position();
auto max = std::max<size_t>(pos, max_size);
auto max = std::min<size_t>(pos, max_size);
auto buf_rem = std::min(max_size - max, s->_buffer_ostream.size());
size_t avail;
@@ -1791,8 +1811,8 @@ future<> db::commitlog::segment_manager::oversized_allocation(entry_writer& writ
} else {
co_await s->cycle();
auto pos = s->position();
auto max = std::max<size_t>(pos, max_size);
auto file_rem = max - pos;
auto max = std::min<size_t>(pos, max_size);
auto file_rem = max_size - max;
if (file_rem < align) {
co_await s->close();
@@ -3967,6 +3987,14 @@ db::replay_position db::commitlog::min_position() const {
return _segment_manager->min_position();
}
db::replay_position db::commitlog::current_position() const {
return _segment_manager->current_position();
}
size_t db::commitlog::sector_overhead(segment_id_type id, size_t size) const {
return _segment_manager->sector_overhead(id, size);
}
void db::commitlog::update_max_data_lifetime(std::optional<uint64_t> commitlog_data_max_lifetime_in_seconds) {
_segment_manager->cfg.commitlog_data_max_lifetime_in_seconds = commitlog_data_max_lifetime_in_seconds;
}