Merge "Fix disable_sstable_write synchronization with on_compaction_completion" from Benny
" disable_sstable_write needs to acquire _sstable_deletion_sem to properly synchronize with background deletions done by on_compaction_completion to ensure no sstables will be created or deleted during reshuffle_sstables after storage_service::load_new_sstables disables sstable writes. Fixes #4622 Test: unit(dev), nodetool_additional_test.py migration_test.py " * 'scylla-4622-fix-disable-sstable-write' of https://github.com/bhalevy/scylla: table: document _sstables_lock/_sstable_deletion_sem locking order table: disable_sstable_write: acquire _sstable_deletion_sem table: uninline enable_sstable_write table: reshuffle_sstables: add log message
This commit is contained in:
@@ -460,6 +460,7 @@ private:
|
||||
// This semaphore ensures that an operation like snapshot won't have its selected
|
||||
// sstables deleted by compaction in parallel, a race condition which could
|
||||
// easily result in failure.
|
||||
// Locking order: must be acquired either independently or after _sstables_lock
|
||||
seastar::semaphore _sstable_deletion_sem = {1};
|
||||
// There are situations in which we need to stop writing sstables. Flushers will take
|
||||
// the read lock, and the ones that wish to stop that process will take the write lock.
|
||||
@@ -761,13 +762,7 @@ public:
|
||||
|
||||
// SSTable writes are now allowed again, and generation is updated to new_generation if != -1
|
||||
// returns the amount of microseconds elapsed since we disabled writes.
|
||||
std::chrono::steady_clock::duration enable_sstable_write(int64_t new_generation) {
|
||||
if (new_generation != -1) {
|
||||
update_sstables_known_generation(new_generation);
|
||||
}
|
||||
_sstables_lock.write_unlock();
|
||||
return std::chrono::steady_clock::now() - _sstable_writes_disabled_at;
|
||||
}
|
||||
std::chrono::steady_clock::duration enable_sstable_write(int64_t new_generation);
|
||||
|
||||
// Make sure the generation numbers are sequential, starting from "start".
|
||||
// Generations before "start" are left untouched.
|
||||
|
||||
12
table.cc
12
table.cc
@@ -1030,6 +1030,7 @@ table::reshuffle_sstables(std::set<int64_t> all_generations, int64_t start) {
|
||||
};
|
||||
|
||||
return do_with(work(start, std::move(all_generations)), [this] (work& work) {
|
||||
tlogger.info("Reshuffling SSTables in {}...", _config.datadir);
|
||||
return lister::scan_dir(_config.datadir, { directory_entry_type::regular }, [this, &work] (fs::path parent_dir, directory_entry de) {
|
||||
auto comps = sstables::entry_descriptor::make_descriptor(parent_dir.native(), de.name);
|
||||
if (comps.component != component_type::TOC) {
|
||||
@@ -1957,6 +1958,8 @@ future<int64_t>
|
||||
table::disable_sstable_write() {
|
||||
_sstable_writes_disabled_at = std::chrono::steady_clock::now();
|
||||
return _sstables_lock.write_lock().then([this] {
|
||||
// _sstable_deletion_sem must be acquired after _sstables_lock.write_lock
|
||||
return _sstable_deletion_sem.wait().then([this] {
|
||||
if (_sstables->all()->empty()) {
|
||||
return make_ready_future<int64_t>(0);
|
||||
}
|
||||
@@ -1965,9 +1968,18 @@ table::disable_sstable_write() {
|
||||
max = std::max(max, s->generation());
|
||||
}
|
||||
return make_ready_future<int64_t>(max);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
std::chrono::steady_clock::duration table::enable_sstable_write(int64_t new_generation) {
|
||||
if (new_generation != -1) {
|
||||
update_sstables_known_generation(new_generation);
|
||||
}
|
||||
_sstable_deletion_sem.signal();
|
||||
_sstables_lock.write_unlock();
|
||||
return std::chrono::steady_clock::now() - _sstable_writes_disabled_at;
|
||||
}
|
||||
|
||||
void table::set_schema(schema_ptr s) {
|
||||
assert(s->is_counter() == _schema->is_counter());
|
||||
|
||||
Reference in New Issue
Block a user