[BUG] prevent multiple update error on one row for duplicate update

This commit is contained in:
Handora
2023-04-26 15:16:31 +00:00
committed by ob-robot
parent 3efcefc29e
commit 9ff3425602
5 changed files with 30 additions and 1 deletions

View File

@ -1625,6 +1625,15 @@ int ObDmlCgService::generate_dml_base_ctdef(ObLogicalOperator &op,
dml_base_ctdef.is_heap_table_ = is_heap_table;
}
}
if (OB_SUCC(ret) &&
log_op_def::LOG_INSERT == op.get_type()) {
ObLogInsert &log_ins_op = static_cast<ObLogInsert &>(op);
if (log_ins_op.get_insert_up()) {
dml_base_ctdef.das_base_ctdef_.is_insert_up_ = true;
}
}
return ret;
}

View File

@ -50,6 +50,7 @@ public:
K_(is_total_quantity_log),
K_(is_ignore),
K_(is_batch_stmt),
K_(is_insert_up),
K_(tz_info),
K_(table_param),
K_(encrypt_meta));
@ -72,6 +73,7 @@ public:
uint64_t is_total_quantity_log_ : 1;
uint64_t is_ignore_ : 1;
uint64_t is_batch_stmt_ : 1;
uint64_t is_insert_up_ : 1;
uint64_t reserved_ : 61;
};
};

View File

@ -1112,6 +1112,9 @@ int ObDMLService::init_dml_param(const ObDASDMLBaseCtDef &base_ctdef,
if (base_ctdef.is_batch_stmt_) {
dml_param.write_flag_.set_is_dml_batch_opt();
}
if (base_ctdef.is_insert_up_) {
dml_param.write_flag_.set_is_insert_up();
}
return ret;
}

View File

@ -125,6 +125,14 @@ int check_sequence_set_violation(const concurrent_control::ObWriteFlag write_fla
TRANS_LOG(WARN, "batch multi stmt rollback found", K(ret),
K(writer_tx_id), K(writer_dml_flag), K(writer_seq_no),
K(locker_tx_id), K(locker_dml_flag), K(locker_seq_no));
// Case 8: For the case of on duplicate key update, it may operate the
// same row more than once if the sql insert onto duplicate with the
// same row more than once. It may have no chance to batch the same row.
// So we need bypass this case.
} else if (write_flag.is_insert_up()
&& blocksstable::ObDmlFlag::DF_UPDATE == writer_dml_flag
&& blocksstable::ObDmlFlag::DF_UPDATE == locker_dml_flag) {
// bypass the case
} else {
// Others: It will never happen that two operaions on the same row for the
// same txn except the above cases. So we should report unexpected error.

View File

@ -28,12 +28,14 @@ struct ObWriteFlag
#define OBWF_BIT_TABLE_LOCK 1
#define OBWF_BIT_MDS 1
#define OBWF_BIT_DML_BATCH_OPT 1
#define OBWF_BIT_INSERT_UP 1
#define OBWF_BIT_RESERVED 61
static const uint64_t OBWF_MASK_TABLE_API = (0x1UL << OBWF_BIT_TABLE_API) - 1;
static const uint64_t OBWF_MASK_TABLE_LOCK = (0x1UL << OBWF_BIT_TABLE_LOCK) - 1;
static const uint64_t OBWF_MASK_MDS = (0x1UL << OBWF_BIT_MDS) - 1;
static const uint64_t OBWF_MASK_DML_BATCH_OPT = (0x1UL << OBWF_BIT_DML_BATCH_OPT) - 1;
static const uint64_t OBWF_MASK_INSERT_UP = (0x1UL << OBWF_BIT_INSERT_UP) - 1;
union
{
@ -44,6 +46,7 @@ struct ObWriteFlag
uint64_t is_table_lock_ : OBWF_BIT_TABLE_LOCK; // 0: false(default), 1: true
uint64_t is_mds_ : OBWF_BIT_MDS; // 0: false(default), 1: true
uint64_t is_dml_batch_opt_ : OBWF_BIT_DML_BATCH_OPT; // 0: false(default), 1: true
uint64_t is_insert_up_ : OBWF_BIT_INSERT_UP; // 0: false(default), 1: true
uint64_t reserved_ : OBWF_BIT_RESERVED;
};
};
@ -58,11 +61,15 @@ struct ObWriteFlag
inline void set_is_mds() { is_mds_ = true; }
inline bool is_dml_batch_opt() const { return is_dml_batch_opt_; }
inline void set_is_dml_batch_opt() { is_dml_batch_opt_ = true; }
inline bool is_insert_up() const { return is_insert_up_; }
inline void set_is_insert_up() { is_insert_up_ = true; }
TO_STRING_KV("is_table_api", is_table_api_,
"is_table_lock", is_table_lock_,
"is_mds", is_mds_,
"is_dml_batch_opt", is_dml_batch_opt_);
"is_dml_batch_opt", is_dml_batch_opt_,
"is_insert_up", is_insert_up_);
OB_UNIS_VERSION(1);
};