fix: fix RegisterOnChange methods for journal and db_slice (#3171)

* fix: fix RegisterOnChange methods for journal and db_slice. Call db_slice and journal callbacks atomically. Made a hack to avoid deadlock during SAVE
This commit is contained in:
Borys 2024-06-20 12:37:37 +03:00 committed by GitHub
parent f66ee5f47d
commit d75c79ce5c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 50 additions and 13 deletions

View file

@ -469,6 +469,14 @@ class DbSlice {
void PerformDeletion(Iterator del_it, DbTable* table);
void PerformDeletion(PrimeIterator del_it, DbTable* table);
void LockChangeCb() const {
return cb_mu_.lock_shared();
}
void UnlockChangeCb() const {
return cb_mu_.unlock_shared();
}
private:
void PreUpdate(DbIndex db_ind, Iterator it, std::string_view key);
void PostUpdate(DbIndex db_ind, Iterator it, std::string_view key, size_t orig_size);
@ -523,6 +531,8 @@ class DbSlice {
return version_++;
}
void CallChangeCallbacks(DbIndex id, const ChangeReq& cr) const;
private:
ShardId shard_id_;
uint8_t caching_mode_ : 1;
@ -544,6 +554,12 @@ class DbSlice {
// Used in temporary computations in Acquire/Release.
mutable absl::flat_hash_set<uint64_t> uniq_fps_;
// To ensure correct data replication, we must serialize the buckets that each running command
// will modify, followed by serializing the command to the journal. We use a mutex to prevent
// interleaving between bucket and journal registrations, and the command execution with its
// journaling. LockChangeCb is called before the callback, and UnlockChangeCb is called after
// journaling is completed. Register to bucket and journal changes is also does without preemption
mutable util::fb2::SharedMutex cb_mu_;
// ordered from the smallest to largest version.
std::vector<std::pair<uint64_t, ChangeCallback>> change_cb_;