[CP] [4_2_1] fix txdesc.flags_ serialize corrupt due to concurrent modify

This commit is contained in:
chinaxing 2023-11-23 11:41:03 +00:00 committed by ob-robot
parent c83b726c71
commit 8ab8c2a4bb
3 changed files with 98 additions and 5 deletions

View File

@ -194,6 +194,80 @@ OB_SERIALIZE_MEMBER(ObTxReadSnapshot,
parts_,
snapshot_ls_role_);
OB_SERIALIZE_MEMBER(ObTxPart, id_, addr_, epoch_, first_scn_, last_scn_);
DEFINE_SERIALIZE(ObTxDesc::FLAG::FOR_FIXED_SER_VAL)
{
int ret = OB_SUCCESS;
return serialization::encode_i64(buf, buf_len, pos, v_);
}
DEFINE_DESERIALIZE(ObTxDesc::FLAG::FOR_FIXED_SER_VAL)
{
int ret = OB_SUCCESS;
return serialization::decode_i64(buf, data_len, pos, (int64_t*)&v_);
}
DEFINE_GET_SERIALIZE_SIZE(ObTxDesc::FLAG::FOR_FIXED_SER_VAL)
{
return serialization::encoded_length_i64(v_);
}
uint64_t ObTxDesc::FLAG::COMPAT_FOR_EXEC::get_serialize_v_() const
{
FLAG ret_flag;
FLAG this_flag;
this_flag.compat_for_exec_.v_ = v_;
ret_flag.compat_for_exec_.v_ = 0;
#define _SET_FLAG_(x) ret_flag.x = this_flag.x
LST_DO(_SET_FLAG_, (;),
EXPLICIT_,
SHADOW_,
REPLICA_,
TRACING_);
#undef _SET_FLAG_
return ret_flag.compat_for_exec_.v_;
}
uint64_t ObTxDesc::FLAG::COMPAT_FOR_TX_ROUTE::get_serialize_v_() const
{
FLAG ret_flag;
FLAG this_flag;
this_flag.compat_for_tx_route_.v_ = v_;
ret_flag.compat_for_tx_route_.v_ = 0;
#define _SET_FLAG_(x) ret_flag.x = this_flag.x
LST_DO(_SET_FLAG_, (;),
EXPLICIT_,
SHADOW_,
REPLICA_,
TRACING_,
RELEASED_,
PARTS_INCOMPLETE_,
PART_EPOCH_MISMATCH_,
WITH_TEMP_TABLE_,
DEFER_ABORT_);
#undef _SET_FLAG_
return ret_flag.compat_for_tx_route_.v_;
}
#define DEF_SERIALIZE_COMPAT_FOR_TX_DESC_FLAG(THE_TYPE) \
DEFINE_SERIALIZE(ObTxDesc::FLAG::THE_TYPE) \
{ \
int ret = OB_SUCCESS; \
const uint64_t compat_v = get_serialize_v_(); \
return serialization::encode_vi64(buf, buf_len, pos, compat_v); \
} \
DEFINE_DESERIALIZE(ObTxDesc::FLAG::THE_TYPE) \
{ \
int ret = OB_SUCCESS; \
return serialization::decode_vi64(buf, data_len, pos, (int64_t*)&v_); \
} \
DEFINE_GET_SERIALIZE_SIZE(ObTxDesc::FLAG::THE_TYPE) \
{ \
const uint64_t compat_v = get_serialize_v_(); \
return serialization::encoded_length_vi64(compat_v); \
}
DEF_SERIALIZE_COMPAT_FOR_TX_DESC_FLAG(COMPAT_FOR_EXEC)
DEF_SERIALIZE_COMPAT_FOR_TX_DESC_FLAG(COMPAT_FOR_TX_ROUTE)
OB_SERIALIZE_MEMBER(ObTxDesc,
tenant_id_,
cluster_id_,
@ -205,14 +279,15 @@ OB_SERIALIZE_MEMBER(ObTxDesc,
access_mode_,
op_sn_,
state_,
flags_.v_,
flags_.compat_for_exec_,
expire_ts_,
active_ts_,
timeout_us_,
lock_timeout_us_,
active_scn_,
parts_,
xid_);
xid_,
flags_.for_serialize_v_);
OB_SERIALIZE_MEMBER(ObTxParam,
timeout_us_,
lock_timeout_us_,

View File

@ -425,9 +425,25 @@ protected:
union FLAG // flags
{
uint64_t v_;
struct FOR_FIXED_SER_VAL {
uint64_t v_;
TO_STRING_KV(K_(v));
NEED_SERIALIZE_AND_DESERIALIZE;
} for_serialize_v_;
struct COMPAT_FOR_TX_ROUTE {
uint64_t v_;
uint64_t get_serialize_v_() const;
TO_STRING_KV(K_(v));
NEED_SERIALIZE_AND_DESERIALIZE;
} compat_for_tx_route_;
struct COMPAT_FOR_EXEC {
uint64_t v_;
uint64_t get_serialize_v_() const;
NEED_SERIALIZE_AND_DESERIALIZE;
} compat_for_exec_;
struct
{
bool EXPLICIT_:1; // txn is explicted start
bool EXPLICIT_:1; // txn is explicted start
bool SHADOW_:1; // this tx desc is a shadow copy, is not registered with tx_desc_mgr
bool REPLICA_:1; // a replica of primary/original, its state is transient, without whole lifecyle
bool TRACING_:1; // tracing the Tx
@ -443,6 +459,7 @@ protected:
void switch_to_idle_();
FLAG update_with(const FLAG &flag);
} flags_;
static_assert(sizeof(FLAG) == sizeof(int64_t), "ObTxDesc::FLAG should sizeof(int64_t)");
union STATE_CHANGE_FLAG
{
uint8_t v_;

View File

@ -97,11 +97,12 @@ TXN_FREE_ROUTE_MEMBERS(static, PRE_STATIC_DECODE, POST_STATIC_DECODE,
TXN_FREE_ROUTE_MEMBERS(dynamic,PRE_DYNAMIC_DECODE, POST_DYNAMIC_DECODE,
op_sn_,
state_,
flags_.v_,
flags_.compat_for_tx_route_,
active_ts_,
active_scn_,
abort_cause_,
can_elr_);
can_elr_,
flags_.for_serialize_v_);
TXN_FREE_ROUTE_MEMBERS(parts,,,
parts_);
// the fields 'dup with static' are required when preceding of txn is of query like