table: Always use explicit commitlog discard + clear out rp_set

Fixes #8733

If a memtable flush is still pending when we call table::clear(),
we can end up doing a "discard-all" call to commitlog, followed
by a per-segment-count (using rp_set) _later_. This will foobar
our internal usage counts and quite probably cause assertion
failures.
Fixed by always doing per-memtable explicit discard call. But to
ensure this works, since a memtable being flushed remains on
memtable list for a while (why?), we must also ensure we clear
out the rp_set on discard.

Closes #8766
This commit is contained in:
Calle Wilund
2021-05-31 16:18:27 +00:00
committed by Avi Kivity
parent 0944d69475
commit 131da30856
2 changed files with 5 additions and 3 deletions

View File

@@ -272,8 +272,8 @@ public:
const db::replay_position& replay_position() const {
return _replay_position;
}
const db::rp_set& rp_set() const {
return _rp_set;
db::rp_set rp_set() {
return std::exchange(_rp_set, {});
}
friend class iterator_reader;

View File

@@ -1504,7 +1504,9 @@ bool table::can_flush() const {
future<> table::clear() {
_memtables->clear_and_add();
if (_commitlog) {
_commitlog->discard_completed_segments(_schema->id());
for (auto& t : *_memtables) {
_commitlog->discard_completed_segments(_schema->id(), t->rp_set());
}
}
return _cache.invalidate(row_cache::external_updater([] { /* There is no underlying mutation source */ }));
}