1
0
Fork 0
mirror of https://github.com/dragonflydb/dragonfly.git synced 2024-12-15 17:51:06 +00:00

fix(tx): guard parallel writes to local result (#2417)

This commit is contained in:
Vladislav 2024-01-15 13:51:30 +03:00 committed by GitHub
parent 39e7e5ad87
commit 078db5caae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 8 additions and 4 deletions

View file

@ -484,14 +484,16 @@ bool Transaction::RunInShard(EngineShard* shard, bool txq_ooo) {
local_result_ = status;
} else {
if (status == OpStatus::OUT_OF_MEMORY) {
absl::base_internal::SpinLockHolder lk{&local_result_mu_};
CHECK(local_result_ == OpStatus::OK || local_result_ == OpStatus::OUT_OF_MEMORY);
local_result_ = status;
} else {
CHECK_EQ(OpStatus::OK, status);
}
}
} catch (std::bad_alloc&) {
// TODO: to log at most once per sec.
LOG_FIRST_N(ERROR, 16) << " out of memory";
LOG_FIRST_N(ERROR, 16) << " out of memory"; // TODO: to log at most once per sec.
absl::base_internal::SpinLockHolder lk{&local_result_mu_};
local_result_ = OpStatus::OUT_OF_MEMORY;
} catch (std::exception& e) {
LOG(FATAL) << "Unexpected exception " << e.what();

View file

@ -4,6 +4,7 @@
#pragma once
#include <absl/base/internal/spinlock.h>
#include <absl/container/flat_hash_map.h>
#include <absl/container/flat_hash_set.h>
#include <absl/container/inlined_vector.h>
@ -569,7 +570,7 @@ class Transaction {
DbIndex db_index_{0};
uint64_t time_now_ms_{0};
std::atomic<uint32_t> wakeup_requested_{0}; // whether tx was woken up
std::atomic_uint32_t wakeup_requested_{0}; // whether tx was woken up
std::atomic_uint32_t use_count_{0}, run_count_{0}, seqlock_{0};
// unique_shard_cnt_ and unique_shard_id_ are accessed only by coordinator thread.
@ -586,8 +587,9 @@ class Transaction {
// If COORDINATOR_XXX has been set, it means we passed or crossed stage XXX.
uint8_t coordinator_state_ = 0;
// Used for single-hop transactions with unique_shards_ == 1, hence no data-race.
// Result of callbacks. Usually written by single shard only, lock below for multishard oom error
OpStatus local_result_ = OpStatus::OK;
absl::base_internal::SpinLock local_result_mu_;
private:
struct TLTmpSpace {