mirror of
https://github.com/dragonflydb/dragonfly.git
synced 2025-05-10 18:05:44 +02:00
feat(replica): support multi transaction command (#634)
This commit is contained in:
parent
b944324bbf
commit
3065946b9a
16 changed files with 223 additions and 106 deletions
|
@ -328,7 +328,8 @@ bool Transaction::RunInShard(EngineShard* shard) {
|
|||
// runnable concludes current operation, and should_release which tells
|
||||
// whether we should unlock the keys. should_release is false for multi and
|
||||
// equal to concluding otherwise.
|
||||
bool should_release = (coordinator_state_ & COORD_EXEC_CONCLUDING) && !multi_;
|
||||
bool is_concluding = (coordinator_state_ & COORD_EXEC_CONCLUDING);
|
||||
bool should_release = is_concluding && !multi_;
|
||||
IntentLock::Mode mode = Mode();
|
||||
|
||||
// We make sure that we lock exactly once for each (multi-hop) transaction inside
|
||||
|
@ -373,7 +374,7 @@ bool Transaction::RunInShard(EngineShard* shard) {
|
|||
|
||||
/*************************************************************************/
|
||||
|
||||
if (!was_suspended && should_release) // Check last hop & non suspended.
|
||||
if (!was_suspended && is_concluding) // Check last hop & non suspended.
|
||||
LogJournalOnShard(shard);
|
||||
|
||||
// at least the coordinator thread owns the reference.
|
||||
|
@ -631,6 +632,10 @@ void Transaction::UnlockMulti() {
|
|||
sharded_keys[sid].push_back(k_v);
|
||||
}
|
||||
|
||||
if (ServerState::tlocal()->journal()) {
|
||||
SetMultiUniqueShardCount();
|
||||
}
|
||||
|
||||
uint32_t prev = run_count_.fetch_add(shard_data_.size(), memory_order_relaxed);
|
||||
DCHECK_EQ(prev, 0u);
|
||||
|
||||
|
@ -643,6 +648,33 @@ void Transaction::UnlockMulti() {
|
|||
VLOG(1) << "UnlockMultiEnd " << DebugId();
|
||||
}
|
||||
|
||||
void Transaction::SetMultiUniqueShardCount() {
|
||||
uint32_t prev = run_count_.fetch_add(shard_data_.size(), memory_order_relaxed);
|
||||
DCHECK_EQ(prev, 0u);
|
||||
|
||||
std::atomic<uint32_t> unique_shard_cnt = 0;
|
||||
|
||||
auto update_shard_cnd = [&] {
|
||||
EngineShard* shard = EngineShard::tlocal();
|
||||
auto journal = shard->journal();
|
||||
|
||||
if (journal != nullptr) {
|
||||
TxId last_tx = journal->GetLastTxId();
|
||||
if (last_tx == txid_) {
|
||||
unique_shard_cnt.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
}
|
||||
this->DecreaseRunCnt();
|
||||
};
|
||||
|
||||
for (ShardId i = 0; i < shard_data_.size(); ++i) {
|
||||
shard_set->Add(i, std::move(update_shard_cnd));
|
||||
}
|
||||
WaitForShardCallbacks();
|
||||
|
||||
unique_shard_cnt_ = unique_shard_cnt.load(std::memory_order_release);
|
||||
}
|
||||
|
||||
void Transaction::Schedule() {
|
||||
if (multi_ && multi_->is_expanding) {
|
||||
LockMulti();
|
||||
|
@ -1080,6 +1112,11 @@ void Transaction::ExpireShardCb(EngineShard* shard) {
|
|||
}
|
||||
|
||||
void Transaction::UnlockMultiShardCb(const std::vector<KeyList>& sharded_keys, EngineShard* shard) {
|
||||
auto journal = shard->journal();
|
||||
if (journal != nullptr && journal->GetLastTxId() == txid_) {
|
||||
journal->RecordEntry(journal::Entry{txid_, journal::Op::EXEC, db_index_, unique_shard_cnt_});
|
||||
}
|
||||
|
||||
if (multi_->multi_opts & CO::GLOBAL_TRANS) {
|
||||
shard->shard_lock()->Release(IntentLock::EXCLUSIVE);
|
||||
}
|
||||
|
@ -1221,7 +1258,12 @@ void Transaction::LogJournalOnShard(EngineShard* shard) {
|
|||
entry_payload =
|
||||
make_pair(facade::ToSV(cmd_with_full_args_.front()), ShardArgsInShard(shard->shard_id()));
|
||||
}
|
||||
journal->RecordEntry(journal::Entry{txid_, db_index_, entry_payload, unique_shard_cnt_});
|
||||
journal::Op opcode = journal::Op::COMMAND;
|
||||
if (multi_) {
|
||||
opcode = journal::Op::MULTI_COMMAND;
|
||||
}
|
||||
|
||||
journal->RecordEntry(journal::Entry{txid_, opcode, db_index_, unique_shard_cnt_, entry_payload});
|
||||
}
|
||||
|
||||
void Transaction::BreakOnShutdown() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue