mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-27 11:55:15 +00:00
db::commitlog: Don't write trailing zero block unless needed
Fixes #5899
When terminating (closing) a segment, we write a trailing block
of zero so reader can have an empty region after last used chunk
as end marker. This is due to using recycled, pre-allocated
segments with potentially non-zero data extending over the point
where we are ending the segment (i.e. we are not fully filling
the segment due to a huge mutation or similar).
However, if we reach end of segment writing the final block
(typically many small mutations), the file will end naturally
after the data written, and any trailing zero block would in fact
just extend the file further. While this will only happen once per
segment recycled (independent on how many times it is recycled),
it is still both slightly breaking the disk usage contract and
also potentially causing some disk stalls due to metadata changes
(though of course very infrequent).
We should only write trailing zero if we are below the max_size
file size when terminating
Adds a small size check to commitlog test to verify size bounds.
(Which breaks without the patch)
v2:
- Fix test to take into account that files might be deleted
behind our backs.
v3:
- Fix test better, by doing verification _before_ segments are
queued for delete.
Message-Id: <20200226121601.15347-2-calle@scylladb.com>
Message-Id: <20200324100235.23982-1-calle@scylladb.com>
(cherry picked from commit 9fee712d62)
This commit is contained in:
@@ -614,11 +614,17 @@ public:
|
||||
future<sseg_ptr> 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<sseg_ptr>(shared_from_this());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user