diff --git a/src/sql/code_generator/ob_dml_cg_service.cpp b/src/sql/code_generator/ob_dml_cg_service.cpp index bfd8643e0e..2af5822904 100644 --- a/src/sql/code_generator/ob_dml_cg_service.cpp +++ b/src/sql/code_generator/ob_dml_cg_service.cpp @@ -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(op); + if (log_ins_op.get_insert_up()) { + dml_base_ctdef.das_base_ctdef_.is_insert_up_ = true; + } + } + return ret; } diff --git a/src/sql/das/ob_das_dml_ctx_define.h b/src/sql/das/ob_das_dml_ctx_define.h index 7f8b90c0a2..40366da173 100644 --- a/src/sql/das/ob_das_dml_ctx_define.h +++ b/src/sql/das/ob_das_dml_ctx_define.h @@ -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; }; }; diff --git a/src/sql/engine/dml/ob_dml_service.cpp b/src/sql/engine/dml/ob_dml_service.cpp index 4ab20f6148..ac23e8e8e8 100644 --- a/src/sql/engine/dml/ob_dml_service.cpp +++ b/src/sql/engine/dml/ob_dml_service.cpp @@ -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; } diff --git a/src/storage/memtable/ob_concurrent_control.cpp b/src/storage/memtable/ob_concurrent_control.cpp index 618e119ea4..95e688eda2 100644 --- a/src/storage/memtable/ob_concurrent_control.cpp +++ b/src/storage/memtable/ob_concurrent_control.cpp @@ -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. diff --git a/src/storage/memtable/ob_concurrent_control.h b/src/storage/memtable/ob_concurrent_control.h index 4ec3364651..631cff0fef 100644 --- a/src/storage/memtable/ob_concurrent_control.h +++ b/src/storage/memtable/ob_concurrent_control.h @@ -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); };