diff --git a/.secignore b/.secignore index 04cf3e9b8..d74b8887b 100644 --- a/.secignore +++ b/.secignore @@ -23,8 +23,8 @@ https://github.com/mcmilk/zstdmt http://www.xxhash.com http://www.example.com* - https://yuque.antfin-inc.com* - https://yuque.antfin.com* + + @@ -36,7 +36,7 @@ https://github.com/akopytov/sysbench* http://foo.bar.com* https://github.com/google/* - + issue* http://llvm.org/bugs* https://bugs.llvm.org/* http://www.apache.org/licenses/* @@ -177,9 +177,9 @@ http://docs.oracle.com/* https://oracle-base.com/* https://www.kernel.org/doc/* - https://www.atatech.org/* - http://www.atatech.org/* - http://oceanbase.alibaba-inc.com/* + + + https://community.oracle.com/tech/* https://docs.docker.com/* http://helloworld.com/* @@ -214,9 +214,9 @@ https://www.mathjax.org https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/. https://issues.apache.org/* - https://www.atatech.org/* -**/*.result +**/*.result + * http://oracle.chinaitlab.com* http://bugfree.corp.taobao.com* https://www.baidu.com/* @@ -291,7 +291,7 @@ 14844887@sina.com **/*.test http://trade.taobao.com/trade/* - + * http://oracle.chinaitlab.com* http://bugfree.corp.taobao.com* https://www.baidu.com/* @@ -366,7 +366,7 @@ 14844887@sina.com **/*.inc http://trade.taobao.com/trade/* - + * http://oracle.chinaitlab.com* http://bugfree.corp.taobao.com* https://www.baidu.com/* diff --git a/deps/oblib/src/lib/container/ob_ext_ring_buffer_impl.h b/deps/oblib/src/lib/container/ob_ext_ring_buffer_impl.h index 63ce6f65a..9b86745f6 100644 --- a/deps/oblib/src/lib/container/ob_ext_ring_buffer_impl.h +++ b/deps/oblib/src/lib/container/ob_ext_ring_buffer_impl.h @@ -613,7 +613,7 @@ private: WLockGuard guard(sn_dir_lock_); set_dir_(new_dir); // Replace. It's caller's duty to retire Dir & Segment. // Ensure atomicity of updating begin_sn_ & Dir - // https://yuque.antfin.com/docs/share/22158f7c-5375-4d0c-953a-d43b7614d2dc?# + // update_begin_sn_(ctrl_sn+1); } esunlock_(); diff --git a/src/observer/mysql/ob_query_retry_ctrl.cpp b/src/observer/mysql/ob_query_retry_ctrl.cpp index 5d1edbca2..fdbb76301 100644 --- a/src/observer/mysql/ob_query_retry_ctrl.cpp +++ b/src/observer/mysql/ob_query_retry_ctrl.cpp @@ -39,6 +39,9 @@ void ObRetryPolicy::try_packet_retry(ObRetryParam &v) const const ObMultiStmtItem &multi_stmt_item = v.ctx_.multi_stmt_item_; if (v.force_local_retry_) { v.retry_type_ = RETRY_TYPE_LOCAL; + } else if (multi_stmt_item.is_batched_multi_stmt()) { + // in batch optimization, can't do packet retry + v.retry_type_ = RETRY_TYPE_LOCAL; } else if (multi_stmt_item.is_part_of_multi_stmt() && multi_stmt_item.get_seq_num() > 0) { // muti stmt,并且不是第一句,不能扔回队列重试,因为前面的无法回滚 v.retry_type_ = RETRY_TYPE_LOCAL; diff --git a/src/observer/mysql/ob_sync_plan_driver.cpp b/src/observer/mysql/ob_sync_plan_driver.cpp index 86913502a..cac10161f 100644 --- a/src/observer/mysql/ob_sync_plan_driver.cpp +++ b/src/observer/mysql/ob_sync_plan_driver.cpp @@ -239,10 +239,15 @@ int ObSyncPlanDriver::response_result(ObMySQLResultSet &result) !admission_fail_and_need_retry && OB_BATCHED_MULTI_STMT_ROLLBACK != ret) { //OB_BATCHED_MULTI_STMT_ROLLBACK如果是batch stmt rollback错误,不要返回给客户端,退回到mpquery上重试 - int sret = OB_SUCCESS; - bool is_partition_hit = session_.get_err_final_partition_hit(ret); - if (OB_SUCCESS != (sret = sender_.send_error_packet(ret, NULL, is_partition_hit))) { - LOG_WARN("send error packet fail", K(sret), K(ret)); + if (ctx_.multi_stmt_item_.is_batched_multi_stmt()) { + // The error of batch optimization execution does not need to send error packet here, + // because the upper layer will force a fallback to a single line execution retry + } else { + int sret = OB_SUCCESS; + bool is_partition_hit = session_.get_err_final_partition_hit(ret); + if (OB_SUCCESS != (sret = sender_.send_error_packet(ret, NULL, is_partition_hit))) { + LOG_WARN("send error packet fail", K(sret), K(ret)); + } } } ObActiveSessionGuard::get_stat().in_sql_execution_ = false; diff --git a/src/observer/mysql/obmp_connect.cpp b/src/observer/mysql/obmp_connect.cpp index a360f7993..eaf6cd915 100644 --- a/src/observer/mysql/obmp_connect.cpp +++ b/src/observer/mysql/obmp_connect.cpp @@ -2057,7 +2057,7 @@ int ObMPConnect::update_charset_sys_vars(ObSMConnection &conn, ObSQLSessionInfo // default charset for mysqltest //TODO: after obclient&mysqltest support default charset = utf8 // login for cs_type != LATIN1_CS would be deleted - if (cs_type != LATIN1_CS && ObCharset::is_valid_collation(cs_type)) { + if (ObCharset::is_valid_collation(cs_type)) { if (OB_FAIL(sess_info.update_sys_variable(SYS_VAR_CHARACTER_SET_CLIENT, cs_type))) { SQL_ENG_LOG(WARN, "failed to update sys var", K(ret)); } else if (OB_FAIL(sess_info.update_sys_variable(SYS_VAR_CHARACTER_SET_RESULTS, cs_type))) { diff --git a/src/observer/mysql/obmp_packet_sender.cpp b/src/observer/mysql/obmp_packet_sender.cpp index b682a1e2a..09868531b 100644 --- a/src/observer/mysql/obmp_packet_sender.cpp +++ b/src/observer/mysql/obmp_packet_sender.cpp @@ -611,6 +611,7 @@ int ObMPPacketSender::send_ok_packet(ObSQLSessionInfo &session, ObOKPParam &ok_p } } else if (conn_->is_driver_client()) { // will not track session variables, do nothing + okp.set_use_standard_serialize(true); } else { if (OB_FAIL(ObMPUtils::add_changed_session_info(okp, session))) { SERVER_LOG(WARN, "fail to add changed session info", K(ret)); diff --git a/src/observer/mysql/obmp_query.cpp b/src/observer/mysql/obmp_query.cpp index 177ca5286..6a1e4161e 100644 --- a/src/observer/mysql/obmp_query.cpp +++ b/src/observer/mysql/obmp_query.cpp @@ -480,17 +480,16 @@ int ObMPQuery::try_batched_multi_stmt_optimization(sql::ObSQLSessionInfo &sessio force_sync_resp, async_resp_used, need_disconnect))) { - if (OB_BATCHED_MULTI_STMT_ROLLBACK == ret) { - ret = OB_SUCCESS; - LOG_TRACE("batched multi_stmt needs rollback", K(ret)); - } else { - LOG_WARN("failed to process single stmt", K(ret)); - } + int tmp_ret = ret; + ret = OB_SUCCESS; + LOG_WARN("failed to process batch stmt, cover the error code and reset retry flag", + K(tmp_ret), K(ret), K(THIS_WORKER.need_retry())); } else { optimization_done = true; } - LOG_TRACE("succeed to try batched multi-stmt optimization", K(optimization_done), - K(ret), K(queries.count()), K(enable_batch_opt)); + + LOG_TRACE("after to try batched multi-stmt optimization", K(optimization_done), + K(queries), K(enable_batch_opt), K(ret), K(THIS_WORKER.need_retry()), K(retry_ctrl_.need_retry()), K(retry_ctrl_.get_retry_type())); return ret; } @@ -795,6 +794,9 @@ OB_INLINE int ObMPQuery::do_process(ObSQLSessionInfo &session, // 所以此时可以同步回包,设置need_response_error // 向客户端返回一个error包,表示需要二次路由 need_response_error = true; + } else if (ctx_.multi_stmt_item_.is_batched_multi_stmt()) { + // batch execute with error,should not response error packet + need_response_error = false; } else if (OB_BATCHED_MULTI_STMT_ROLLBACK == ret) { need_response_error = false; } diff --git a/src/observer/mysql/obmp_stmt_execute.cpp b/src/observer/mysql/obmp_stmt_execute.cpp index 21be2e81c..9b0c5078c 100644 --- a/src/observer/mysql/obmp_stmt_execute.cpp +++ b/src/observer/mysql/obmp_stmt_execute.cpp @@ -1542,13 +1542,17 @@ int ObMPStmtExecute::try_batch_multi_stmt_optimization(ObSQLSessionInfo &session LOG_TRACE("batched multi_stmt needs rollback", K(ret)); ret = OB_SUCCESS; } else { - LOG_WARN("failed to process single stmt", K(ret)); + // 无论什么报错,都走单行执行一次,用于容错 + int ret_tmp = ret; + ret = OB_SUCCESS; + LOG_WARN("failed to process batch stmt, cover the error code, reset retry flag, then execute with single row", + K(ret_tmp), K(ret), K(THIS_WORKER.need_retry())); } } else { optimization_done = true; } LOG_TRACE("after try batched multi-stmt optimization", K(ret), K(stmt_type_), K(use_plan_cache), - K(optimization_done), K(enable_batch_opt), K(is_ab_returning), K(arraybinding_size_)); + K(optimization_done), K(enable_batch_opt), K(is_ab_returning), K(THIS_WORKER.need_retry()), K(arraybinding_size_)); return ret; } diff --git a/src/observer/mysql/obmp_stmt_prexecute.cpp b/src/observer/mysql/obmp_stmt_prexecute.cpp index 5772cbab1..999973c79 100644 --- a/src/observer/mysql/obmp_stmt_prexecute.cpp +++ b/src/observer/mysql/obmp_stmt_prexecute.cpp @@ -285,7 +285,7 @@ int ObMPStmtPrexecute::before_process() LOG_WARN("prepare-execute protocol get params request failed", K(ret)); } else { ObMySQLUtil::get_uint4(pos, exec_mode_); - // https://yuque.antfin.com/docs/share/a5705d97-1d74-4b90-8be2-6e500249345f?# + // // is_commit_on_success_ is not use yet // other exec_mode set use == is_commit_on_success_ = exec_mode_ & OB_OCI_COMMIT_ON_SUCCESS; diff --git a/src/observer/omt/ob_tenant_config_mgr.cpp b/src/observer/omt/ob_tenant_config_mgr.cpp index 3d044d6f7..ae1892d73 100644 --- a/src/observer/omt/ob_tenant_config_mgr.cpp +++ b/src/observer/omt/ob_tenant_config_mgr.cpp @@ -176,7 +176,7 @@ void ObTenantConfigMgr::refresh_config_version_map(const ObIArray &ten // 背景:每个 server 上需要保存所有租户的 config 信息 // 当新建租户/删除租户时需要对应维护 config 状态。 -// https://yuque.antfin-inc.com/xiaochu.yh/doc/zf2eqy/ +// // IN: 当前活跃租户 // ACTION: 根据 tenants 信息,决定要添加/删除哪些租户配置项 int ObTenantConfigMgr::refresh_tenants(const ObIArray &tenants) diff --git a/src/observer/table_load/ob_table_load_merger.cpp b/src/observer/table_load/ob_table_load_merger.cpp index 447c61b14..b3f5c842e 100644 --- a/src/observer/table_load/ob_table_load_merger.cpp +++ b/src/observer/table_load/ob_table_load_merger.cpp @@ -223,6 +223,7 @@ int ObTableLoadMerger::build_merge_ctx() table_array = &empty_table_array; } if (!merge_param.is_heap_table_ && !table_array->empty()) { + // for optimize split range is too slow ObArray multiple_sstable_array; ObDirectLoadMultipleMergeRangeSplitter range_splitter; for (int64_t i = 0; OB_SUCC(ret) && i < table_array->count(); ++i) { @@ -247,6 +248,16 @@ int ObTableLoadMerger::build_merge_ctx() LOG_WARN("fail to build merge task for multiple pk table", KR(ret)); } } + } else if (merge_param.is_heap_table_ && !table_array->empty() && + tablet_merge_ctxs.count() > param_.session_count_ * 2) { + // for optimize the super multi-partition heap table space serious enlargement + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_merge_ctxs.count(); ++i) { + ObDirectLoadTabletMergeCtx *tablet_merge_ctx = tablet_merge_ctxs.at(i); + if (OB_FAIL( + tablet_merge_ctx->build_aggregate_merge_task_for_multiple_heap_table(*table_array))) { + LOG_WARN("fail to build aggregate merge task for multiple heap table", KR(ret)); + } + } } else { for (int64_t i = 0; OB_SUCC(ret) && i < tablet_merge_ctxs.count(); ++i) { ObDirectLoadTabletMergeCtx *tablet_merge_ctx = tablet_merge_ctxs.at(i); diff --git a/src/observer/virtual_table/ob_virtual_sql_plan_monitor.cpp b/src/observer/virtual_table/ob_virtual_sql_plan_monitor.cpp index ec4f92297..6f157a3cf 100644 --- a/src/observer/virtual_table/ob_virtual_sql_plan_monitor.cpp +++ b/src/observer/virtual_table/ob_virtual_sql_plan_monitor.cpp @@ -732,7 +732,7 @@ int ObVirtualSqlPlanMonitor::convert_node_to_row(ObMonitorNode &node, ObNewRow * break; } case DB_TIME: { - // concept: https://yuque.antfin.com/xiaochu.yh/doc/lt4toe/ + // concept: cells[cell_idx].set_int(node.db_time_); break; } diff --git a/src/pl/ob_pl.h b/src/pl/ob_pl.h index 8118f786d..47f7cdad4 100644 --- a/src/pl/ob_pl.h +++ b/src/pl/ob_pl.h @@ -591,7 +591,7 @@ public: * some package subprogram has special invoker right, though the package may have definer privs * for example: dbms_utility package is definer privs, but some function such as * name_resolve must be run as current_user, oracle do it in interface functions - * see: https://yuque.antfin.com/docs/share/990f729a-d21b-47f1-94ec-6b4b5cda950f?# 《oracle如何实现一个包中同时控制多个权限(sys, current_user)》 + * see: * we hacked it using name compared, for the interface funtion can't get the origin db name and id * test -> oceanbase, we see oceanbase in interface but can't see test. */ diff --git a/src/rootserver/ob_unit_manager.h b/src/rootserver/ob_unit_manager.h index e0d3f6efb..bb55b1533 100644 --- a/src/rootserver/ob_unit_manager.h +++ b/src/rootserver/ob_unit_manager.h @@ -518,7 +518,7 @@ protected: // for ObServerBalancer IdPoolMap& get_id_pool_map() { return id_pool_map_; } TenantPoolsMap& get_tenant_pools_map() { return tenant_pools_map_; } - // bug#11873101 + // bug#11873101 issue/11873101 // Before attempting to migrate the unit, // check whether the target unit space is sufficient, // if it is insufficient, do not migrate, diff --git a/src/share/inner_table/ob_inner_table_schema_def.py b/src/share/inner_table/ob_inner_table_schema_def.py index df37933f1..1d7a20ef5 100644 --- a/src/share/inner_table/ob_inner_table_schema_def.py +++ b/src/share/inner_table/ob_inner_table_schema_def.py @@ -28,7 +28,7 @@ # sys_agent access tables belong to sys tenant only # real_agent access tables belong to current tenant # 8. Virtual table system design summary: -# https://yuque.antfin.com/docs/share/876fb26e-7466-476f-bd67-b3c4860fbdb8?# +# # 9. For compatibility, when add new column for system table, new column's definition should be "not null + default value" or "nullable". # Specially, when column types are as follows: # 1. double、number:default value is not supported, so new column definition should be "nullable". diff --git a/src/share/ob_autoincrement_service.h b/src/share/ob_autoincrement_service.h index 9d57d5d6f..cf04b085e 100644 --- a/src/share/ob_autoincrement_service.h +++ b/src/share/ob_autoincrement_service.h @@ -167,7 +167,7 @@ struct TableNode: public common::LinkHashValue // we are not sure if curr_node is avaliable. // it will become avaliable again after fetch a new node // and combine them together. - // ref: https://yuque.antfin-inc.com/xiaochu.yh/doc/eqnlv0 + // ref: bool curr_node_state_is_pending_; int64_t autoinc_version_; }; diff --git a/src/share/ob_errno.def b/src/share/ob_errno.def index e98319d95..901b491c0 100644 --- a/src/share/ob_errno.def +++ b/src/share/ob_errno.def @@ -1,4 +1,4 @@ -// @see http://oceanbase.alibaba-inc.com/wiki/index.php?title=%E9%94%99%E8%AF%AF%E7%A0%81%E7%9A%84%E8%A7%84%E8%8C%83 +// @see // 错误码总数不超过10000个 // 不能使用的值域[-1, -4000),这一段值为兼容MySQL目的使用。MySQL Server端错误码范围1000-3000,客户端错误码2000-3000, 1-1000预留。实际上,Oracle的常用错误码的范围大约在这个范围内。 // 通用错误码值域[-4000, -4500),含sstable等 diff --git a/src/share/object/ob_obj_cast.cpp b/src/share/object/ob_obj_cast.cpp index 81a985d21..d94381e25 100644 --- a/src/share/object/ob_obj_cast.cpp +++ b/src/share/object/ob_obj_cast.cpp @@ -12490,7 +12490,7 @@ int ObObjCaster::to_type(const ObObjType expect_type, const ObObjTypeClass out_tc = ob_obj_type_class(expect_type); cast_ctx.warning_ = OB_SUCCESS; /* expect_cs_type has higer priority than cast_ctx.dest_collation_ - + */ if (CS_TYPE_INVALID != expect_cs_type) { cast_ctx.dest_collation_ = expect_cs_type; } else { @@ -12794,7 +12794,7 @@ int ObObjCaster::is_const_consistent(const ObObjMeta &const_mt, /* make sure that you have read the doc before you call these functions ! * - * doc: http://www.atatech.org/articles/56575 + * doc: */ int ObObjCaster::is_order_consistent(const ObObjMeta &from, @@ -12842,7 +12842,7 @@ int ObObjCaster::is_order_consistent(const ObObjMeta &from, /* make sure that you have read the doc before you call these functions ! * - * doc: http://www.atatech.org/articles/56575 + * doc: */ int ObObjCaster::is_injection(const ObObjMeta &from, diff --git a/src/share/schema/ob_schema_struct.cpp b/src/share/schema/ob_schema_struct.cpp index 16df14377..6a670515e 100644 --- a/src/share/schema/ob_schema_struct.cpp +++ b/src/share/schema/ob_schema_struct.cpp @@ -7212,7 +7212,7 @@ int ObPartitionUtils::calc_hash_part_idx(const uint64_t val, const static int64_t max_part_num_log2 = 64; // This function is used by SQL. Should ensure SQL runs in MySQL mode when query sys table. if (lib::is_oracle_mode()) { - // https://yuque.antfin-inc.com/ob-public/sql/sfaedg + // // It will not be a negative number, so use forced conversion instead of floor N = static_cast(std::log(part_num) / std::log(2)); if (N >= max_part_num_log2) { diff --git a/src/share/stat/ob_dbms_stats_maintenance_window.cpp b/src/share/stat/ob_dbms_stats_maintenance_window.cpp index 8181209ae..71ca76450 100644 --- a/src/share/stat/ob_dbms_stats_maintenance_window.cpp +++ b/src/share/stat/ob_dbms_stats_maintenance_window.cpp @@ -276,7 +276,7 @@ int ObDbmsStatsMaintenanceWindow::get_dummy_guard_job_sql(const uint64_t tenant_ * FRIDAY_WINDOW freq=daily;byday=FRI;byhour=22; 4 hours * SATURDAY_WINDOW freq=daily;byday=SAT;byhour=6; 20 hours * SUNDAY_WINDOW freq=daily;byday=SUN;byhour=6; 20 hours - * https://yuque.antfin-inc.com/docs/share/05d01692-f9e6-42de-99cf-365fccc45974?# 《统计信息maintenance window设计与实现》 + * */ int ObDbmsStatsMaintenanceWindow::get_window_job_info(const int64_t current_time, const int64_t nth_window, diff --git a/src/share/stat/ob_dbms_stats_utils.cpp b/src/share/stat/ob_dbms_stats_utils.cpp index 5747bd856..edcb85504 100644 --- a/src/share/stat/ob_dbms_stats_utils.cpp +++ b/src/share/stat/ob_dbms_stats_utils.cpp @@ -319,7 +319,7 @@ bool ObDbmsStatsUtils::is_virtual_index_table(const int64_t table_id) * PARTITION: Gather partition-level * SUBPARTITION: Gather subpartition-level * Oracle granularity actual behavior survey: - * https://yuque.antfin-inc.com/docs/share/3eeffde1-7182-4b2a-8f01-e7a3045d4d1e?# + * * @return */ int ObDbmsStatsUtils::parse_granularity(const ObString &granularity, diff --git a/src/share/system_variable/ob_system_variable.cpp b/src/share/system_variable/ob_system_variable.cpp index 3112c4008..c7f61bfed 100644 --- a/src/share/system_variable/ob_system_variable.cpp +++ b/src/share/system_variable/ob_system_variable.cpp @@ -393,7 +393,7 @@ int ObBasicSysVar::session_update(ObExecContext &ctx, } } else if (set_var.var_name_ == OB_SV__ENABLE_PARALLEL_QUERY) { should_update_extra_var = true; - // https://yuque.antfin-inc.com/xiaochu.yh/doc/exgk9g/ + // // 实现 Oracle 兼容行为方式如下:有变量 enable 和 parallel // alter session enable parallel query 时 enable = true, parallel = 1 => 走 manual table dop 规则 // alter session disable parallel query 时 enable = false, parallel = 1 => 走 no parallel 规则 diff --git a/src/share/system_variable/ob_system_variable_init.json b/src/share/system_variable/ob_system_variable_init.json index 605ee04c7..c2fcd831e 100644 --- a/src/share/system_variable/ob_system_variable_init.json +++ b/src/share/system_variable/ob_system_variable_init.json @@ -650,7 +650,7 @@ "publish_version": "", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "query_cache_type": { "id": 45, @@ -667,7 +667,7 @@ "publish_version": "", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "sql_quote_show_create": { "id": 46, @@ -916,7 +916,7 @@ "publish_version": "", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "ssl_ca": { "id": 66, @@ -1110,7 +1110,7 @@ "publish_version": "312", "info_cn": "控制返回的ok包中是否包含schema变更的信息", "background_cn": "", - "ref_url": " + "ref_url": "" }, "session_track_system_variables": { "id": 82, @@ -1122,7 +1122,7 @@ "publish_version": "312", "info_cn": "控制返回的ok包中是否包含系统变量变更的信息", "background_cn": "", - "ref_url": " + "ref_url": "" }, "session_track_state_change": { "id": 83, @@ -1134,7 +1134,7 @@ "publish_version": "312", "info_cn": "控制返回的ok包中是否包含session状态变更的信息", "background_cn": "", - "ref_url": " + "ref_url": "" }, "have_query_cache": { "id": 84, @@ -1146,7 +1146,7 @@ "publish_version": "323", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "query_cache_limit": { "id": 85, @@ -1160,7 +1160,7 @@ "publish_version": "323", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "query_cache_min_res_unit": { "id": 86, @@ -1174,7 +1174,7 @@ "publish_version": "323", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "query_cache_wlock_invalidate": { "id": 87, @@ -1186,7 +1186,7 @@ "publish_version": "323", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "binlog_format": { "id": 88, @@ -1203,7 +1203,7 @@ "publish_version": "324", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "binlog_checksum": { "id": 89, @@ -1215,7 +1215,7 @@ "publish_version": "324", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "binlog_rows_query_log_events": { "id": 90, @@ -1227,7 +1227,7 @@ "publish_version": "324", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "log_bin": { "id": 91, @@ -1239,7 +1239,7 @@ "publish_version": "324", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "server_uuid": { "id": 92, @@ -1251,7 +1251,7 @@ "publish_version": "324", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "default_storage_engine": { "id": 93, @@ -1277,7 +1277,7 @@ "publish_version": "400", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "regexp_stack_limit": { "id": 95, @@ -2494,7 +2494,7 @@ "publish_version": "226", "info_cn": "限制导入导出功能访问的路径", "background_cn": "导入导出功能未限制文件访问可能存在漏洞", - "ref_url": " + "ref_url": "" }, "plsql_warnings": { "id": 10103, @@ -2507,7 +2507,7 @@ "publish_version": "3.1.0", "info_cn": "控制pl/sql编译器的报错行为,可以指定某类型或某个warning码的状态为:enable,disable,error", "background_cn": "pl/sql编译器的警告信息分成了几个分类,这个系统参数可以控制这些警告信息的行为", - "ref_url": " + "ref_url": "" }, "_enable_parallel_query": { "id": 10104, @@ -2519,7 +2519,7 @@ "publish_version": "227", "info_cn": "在session上打开parallel query配置项,查询默认情况下才可以被并行执行(parallel>=2)", "background_cn": "px上控制parallel的方式有很多,session上有对应的parallel的控制开关,这个开关用于控制session级别的默认并行度是否可以大于等于2", - "ref_url": " + "ref_url": "" }, "_force_parallel_query_dop": { "id": 10105, @@ -2531,7 +2531,7 @@ "publish_version": "310", "info_cn": "在session上打开parallel query配置项,并指定默认并行度", "background_cn": "px上控制parallel的方式有很多,session上有对应的parallel的控制开关,这个变量用于设置session级别的 query 默认并行度大小", - "ref_url": " + "ref_url": "" }, "_force_parallel_dml_dop": { "id": 10106, @@ -2543,7 +2543,7 @@ "publish_version": "310", "info_cn": "在session上打开parallel dml配置项,并指定默认并行度。当未通过 hint 指定 dml 并行度时,会使用本变量值作为默认并行度", "background_cn": "px上控制parallel的方式有很多,session上有对应的parallel的控制开关,这个变量用于设置session级别的 dml 默认并行度大小", - "ref_url": " + "ref_url": "" }, "ob_pl_block_timeout": { "id": 10107, @@ -2558,7 +2558,7 @@ "publish_version": "227", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "transaction_read_only": { "id": 10108, @@ -2574,7 +2574,7 @@ "publish_version": "320", "info_cn": "控制是否只允许开启只读事务", "background_cn": "用户可以通过这两个变量访问或者设置事务的访问模式,当transaction_read_only设置为true时,不允许执行dml语句", - "ref_url": " + "ref_url": "" }, "resource_manager_plan": { "id": 10109, @@ -2587,7 +2587,7 @@ "publish_version": "320", "info_cn": "指定租户的资源隔离计划", "background_cn": "租户内的普通线程和并行执行线程会相互抢占CPU资源,通过给租户指定资源隔离计划,可以控制资源抢占策略,隔离资源使用量", - "ref_url": " + "ref_url": "" }, "performance_schema": { "id": 10110, @@ -2599,7 +2599,7 @@ "publish_version": "227", "info_cn": "向客户端声明是否支持 performance 信息查询", "background_cn": "纯兼容性变量。不支持 performance_schema 系统变量,导致 8.0 JDBC 驱动在连接认证后初始化系统变量阶段执行 select @performance_schema 抛出异常", - "ref_url": " + "ref_url": "" }, "nls_currency": { "id": 10111, @@ -2612,7 +2612,7 @@ "publish_version": "320", "info_cn": "L数字格式元素的本地货币符号", "background_cn": "兼容 oracle number format model L 数字格式元素", - "ref_url": " + "ref_url": "" }, "nls_iso_currency": { "id": 10112, @@ -2625,7 +2625,7 @@ "publish_version": "320", "info_cn": "C数字格式元素的国际货币符号", "background_cn": "兼容 oracle number format model C 数字格式元素", - "ref_url": " + "ref_url": "" }, "nls_dual_currency": { "id": 10113, @@ -2638,7 +2638,7 @@ "publish_version": "320", "info_cn": "U数字格式元素的双货币符号", "background_cn": "兼容 oracle number format model U 数字格式元素", - "ref_url": " + "ref_url": "" }, "plsql_ccflags" : { "id": 10115, @@ -2651,7 +2651,7 @@ "publish_version": "330", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "_ob_proxy_session_temporary_table_used": { "id": 10116, @@ -2663,7 +2663,7 @@ "publish_version": "310", "info_cn": "标记当前Session是否使用过Session级别临时表,用于告知proxy并修改路由决策", "background_cn": "为了解决Session临时表断链接时可能导致的问题,当Session临时表第一次使用后,后续请求Proxy只会路由到同一个Session", - "ref_url": " + "ref_url": "" }, "_enable_parallel_ddl": { "id": 10117, @@ -2675,7 +2675,7 @@ "publish_version": "330", "info_cn": "标记Session上并行DDL是否被打开", "background_cn": "", - "ref_url": " + "ref_url": "" }, "_force_parallel_ddl_dop": { "id": 10118, @@ -2687,7 +2687,7 @@ "publish_version": "330", "info_cn": "在session上打开parallel ddl配置项,并指定默认并行度。当未通过 hint 指定 ddl 并行度时,会使用本变量值作为默认并行度", "background_cn": "ddl上控制parallel的方式有很多,session上有对应的parallel的控制开关,这个变量用于设置session级别的 ddl 默认并行度大小", - "ref_url": " + "ref_url": "" }, "cursor_sharing": { "id": 10119, @@ -2703,7 +2703,7 @@ "publish_version": "330", "info_cn": "在session上打开控制是否参数化的配置项。当处于exact模式时,不进行参数化;处于Force模式时,进行参数化。默认进行参数化。", "background_cn": "", - "ref_url": " + "ref_url": "" }, "_optimizer_null_aware_antijoin": { "id": 10120, @@ -2715,7 +2715,7 @@ "publish_version": "330", "info_cn": "控制优化器能否生成null aware anti join 的计划", "background_cn": "", - "ref_url": " + "ref_url": "" }, "_px_partial_rollup_pushdown": { "id": 10121, @@ -2759,7 +2759,7 @@ "publish_version": "330", "info_cn": "创建mysql模式的审计日志定期清理任务", "background_cn": "示例: create_audit_purge_job='trail_type:interval:jobname:use_last_archive_timestamp'", - "ref_url": " + "ref_url": "" }, "_drop_audit_purge_job": { "id": 10124, @@ -2771,7 +2771,7 @@ "publish_version": "330", "info_cn": "删除mysql模式的审计日志定期清理任务", "background_cn": "示例: drop_audit_purge_job='jobname'", - "ref_url": " + "ref_url": "" }, "_set_purge_job_interval": { "id": 10125, @@ -2783,7 +2783,7 @@ "publish_version": "330", "info_cn": "更新purge job的interval时间", "background_cn": "示例: set_purge_job_interval='jobname:interval'", - "ref_url": " + "ref_url": "" }, "_set_purge_job_status": { "id": 10126, @@ -2795,7 +2795,7 @@ "publish_version": "330", "info_cn": "更新purge job的状态,控制job是否生效", "background_cn": "示例: set_purge_job_status='jobname:status'", - "ref_url": " + "ref_url": "" }, "_set_last_archive_timestamp": { "id": 10127, @@ -2807,7 +2807,7 @@ "publish_version": "330", "info_cn": "设置删除的时间点信息,需要使用从1970开始的utc时间,微妙为单位", "background_cn": "示例: set_last_archive_timestamp='trail_type:timestamp'", - "ref_url": " + "ref_url": "" }, "_clear_last_archive_timestamp": { "id": 10128, @@ -2819,7 +2819,7 @@ "publish_version": "330", "info_cn": "清除删除的时间点信息", "background_cn": "示例: clear_last_archive_timestamp='trail_type'", - "ref_url": " + "ref_url": "" }, "_aggregation_optimization_settings": { "id": 10129, @@ -2831,7 +2831,7 @@ "publish_version": "330", "info_cn": "", "background_cn": "用于调优group by 和distinct的执行行为", - "ref_url": " + "ref_url": "" }, "_px_shared_hash_join": { "id": 10130, @@ -2855,7 +2855,7 @@ "publish_version": "", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "innodb_strict_mode": { "id": 10132, @@ -2867,7 +2867,7 @@ "publish_version": "400", "info_cn": "特定场合下,警告会当成错误返回", "background_cn": "", - "ref_url": " + "ref_url": "" }, "_windowfunc_optimization_settings": { "id": 10133, @@ -2881,7 +2881,7 @@ "publish_version": "400", "info_cn": "window function优化设置", "background_cn": "", - "ref_url": " + "ref_url": "" }, "ob_enable_rich_error_msg": { "id": 10134, @@ -2893,7 +2893,7 @@ "publish_version": "", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "log_row_value_options": { "id": 10136, @@ -2906,7 +2906,7 @@ "publish_version": "", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "ob_max_read_stale_time": { "id": 10137, @@ -2919,7 +2919,7 @@ "publish_version": "410", "info_cn": "", "background_cn": "", - "ref_url": " + "ref_url": "" }, "_optimizer_gather_stats_on_load": { "id": 10138, @@ -2931,7 +2931,7 @@ "publish_version": "400", "info_cn": "控制在insert into select下是否默认收集统计信息", "background_cn": "", - "ref_url": " + "ref_url": "" }, "_set_reverse_dblink_infos": { "id": 10139, @@ -2943,6 +2943,6 @@ "publish_version": "410", "info_cn": "用于dblink写事务中, TM端通过设置系统变量的方式告知RM端关于建立反向dblink的必要信息", "background_cn": "", - "ref_url": " + "ref_url": "" } } diff --git a/src/share/table/ob_table.h b/src/share/table/ob_table.h index 06b247fb1..01fe1a16d 100644 --- a/src/share/table/ob_table.h +++ b/src/share/table/ob_table.h @@ -403,7 +403,7 @@ class ObNoRetry : public ObIRetryPolicy {}; /// consistency levels -/// @see https://www.atatech.org/articles/102030 +/// @see enum class ObTableConsistencyLevel { STRONG = 0, diff --git a/src/sql/code_generator/ob_dml_cg_service.cpp b/src/sql/code_generator/ob_dml_cg_service.cpp index 0580899b9..bfd8643e0 100644 --- a/src/sql/code_generator/ob_dml_cg_service.cpp +++ b/src/sql/code_generator/ob_dml_cg_service.cpp @@ -2566,7 +2566,7 @@ int ObDmlCgService::generate_fk_arg(ObForeignKeyArg &fk_arg, } else if (fk_arg.is_self_ref_ && !var_exist_in_array(column_ids, name_column_ids.at(i), fk_column.name_idx_)) { /** - * + * issue/18132630 * fk_column.name_idx_ is used only for self ref row, that is to say name table and * value table is same table. * otherwise name_column_ids.at(i) will indicate columns in name table, not value table, diff --git a/src/sql/dblink/ob_dblink_utils.cpp b/src/sql/dblink/ob_dblink_utils.cpp index 21d3c5b58..6cb73d71c 100644 --- a/src/sql/dblink/ob_dblink_utils.cpp +++ b/src/sql/dblink/ob_dblink_utils.cpp @@ -312,7 +312,7 @@ int ObDblinkUtils::process_dblink_errno(common::sqlclient::DblinkDriverProto dbl return OB_SUCCESS; } -int ObDblinkUtils::has_reverse_link(const ObDMLStmt *stmt, bool &has) { +int ObDblinkUtils::has_reverse_link_or_any_dblink(const ObDMLStmt *stmt, bool &has, bool has_any_dblink) { int ret = OB_SUCCESS; const common::ObIArray &table_items = stmt->get_table_items(); ObArray child_stmts; @@ -321,12 +321,16 @@ int ObDblinkUtils::has_reverse_link(const ObDMLStmt *stmt, bool &has) { if (OB_ISNULL(table_item)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get null ptr", K(ret)); - } else if (table_item->is_reverse_link_) { + } else if (has_any_dblink && (table_item->is_reverse_link_ || OB_INVALID_ID != table_item->dblink_id_)) { + has = true; + LOG_DEBUG("succ to find reverse link", K(table_item), K(i)); + break; + } else if (!has_any_dblink && table_item->is_reverse_link_) { has = true; LOG_DEBUG("succ to find reverse link", K(table_item), K(i)); break; } else if (table_item->is_temp_table()) { - if (OB_FAIL(SMART_CALL(has_reverse_link(table_item->ref_query_, has)))) { + if (OB_FAIL(SMART_CALL(has_reverse_link_or_any_dblink(table_item->ref_query_, has, has_any_dblink)))) { LOG_WARN("failed to exec has_reverse_link", K(ret)); } else if (has) { break; @@ -342,7 +346,7 @@ int ObDblinkUtils::has_reverse_link(const ObDMLStmt *stmt, bool &has) { if (OB_ISNULL(child_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get null ptr", K(ret)); - } else if (OB_FAIL(SMART_CALL(has_reverse_link(child_stmt, has)))) { + } else if (OB_FAIL(SMART_CALL(has_reverse_link_or_any_dblink(child_stmt, has, has_any_dblink)))) { LOG_WARN("failed to exec has_reverse_link", K(ret)); } else if (has) { break; diff --git a/src/sql/dblink/ob_dblink_utils.h b/src/sql/dblink/ob_dblink_utils.h index ef8029e80..dea47b95c 100644 --- a/src/sql/dblink/ob_dblink_utils.h +++ b/src/sql/dblink/ob_dblink_utils.h @@ -101,7 +101,7 @@ class ObDblinkUtils public: static int process_dblink_errno(common::sqlclient::DblinkDriverProto dblink_type, common::sqlclient::ObISQLConnection *dblink_conn, int &ob_errno); static int process_dblink_errno(common::sqlclient::DblinkDriverProto dblink_type, int &ob_errno); - static int has_reverse_link(const ObDMLStmt *stmt, bool &has); + static int has_reverse_link_or_any_dblink(const ObDMLStmt *stmt, bool &has, bool has_any_dblink = false); }; class ObSQLSessionInfo; diff --git a/src/sql/dtl/ob_dtl_channel_group.cpp b/src/sql/dtl/ob_dtl_channel_group.cpp index 5129a48ea..9d9ca080b 100644 --- a/src/sql/dtl/ob_dtl_channel_group.cpp +++ b/src/sql/dtl/ob_dtl_channel_group.cpp @@ -29,7 +29,7 @@ namespace dtl { * transmit和receive端直接根据创建好的channel信息来new channel实例。但这种方式存在性能问题 * 之前方式实现算法复杂度是:transmit_dfo_task_cnt * receive_dfo_task_cnt,假设dop=512,则至少512*512 * 随着dop增大耗时更长。见bug - * 新方案:https://yuque.antfin-inc.com/docs/share/fd7b13c8-9e42-4950-a642-5627db3abb2c?# 《DTL channel map优化设计》 + * 新方案: * 新方案从PX端不再构建所有channel具体信息, * 而是PX构建channel的总体信息,将channel总体信息发给所有的dfo的sqc, * 然后每个(task)worker根据channel总体信息各自构建自己的信息, diff --git a/src/sql/engine/dml/ob_table_insert_op.cpp b/src/sql/engine/dml/ob_table_insert_op.cpp index 027c5101b..95e640ade 100644 --- a/src/sql/engine/dml/ob_table_insert_op.cpp +++ b/src/sql/engine/dml/ob_table_insert_op.cpp @@ -170,7 +170,7 @@ OB_INLINE int ObTableInsertOp::open_table_for_each() //this table is being accessed by dml operator, mark its table location as writing //but single value insert in oracle allow the nested sql modify its insert table //clear the writing flag in table location before the trigger execution - //see it:https://yuque.antfin-inc.com/docs/share/40291dac-859c-48de-8a31-79bb7ca7c571 + //see it: primary_ins_rtdef.das_rtdef_.table_loc_->is_writing_ = !(primary_ins_ctdef.is_single_value_ && lib::is_oracle_mode()); } @@ -341,15 +341,6 @@ int ObTableInsertOp::write_rows_post_proc(int last_errno) } } } - // all error, we must rollback with single execute when batch executed - if (OB_SUCCESS != ret && OB_ITER_END != ret) { - ObMultiStmtItem &multi_stmt_item = ctx_.get_sql_ctx()->multi_stmt_item_; - if (MY_SPEC.ins_ctdefs_.at(0).at(0)->das_ctdef_.is_batch_stmt_ && !multi_stmt_item.is_ins_multi_val_opt()) { - int tmp_ret = ret; - ret = OB_BATCHED_MULTI_STMT_ROLLBACK; - LOG_TRACE("batch exec with some exception, rollback with single execute", K(ret), K(tmp_ret)); - } - } return ret; } diff --git a/src/sql/engine/expr/ob_expr_char.cpp b/src/sql/engine/expr/ob_expr_char.cpp index eeafb27e2..1aa5e0db6 100644 --- a/src/sql/engine/expr/ob_expr_char.cpp +++ b/src/sql/engine/expr/ob_expr_char.cpp @@ -68,7 +68,6 @@ int ObExprChar::calc_result_typeN(ObExprResType &type, ObExprResType *types, int } else { //set calc type //i starts from 1 rather than 0 since the first param is obvarchar always. - //see http://review.alibaba-inc.com/r/21109/ for more details when necessary. for (int64_t i = 0; i < param_num-1; ++i) { types[i].set_calc_type(ObIntType); } diff --git a/src/sql/engine/expr/ob_expr_orahash.cpp b/src/sql/engine/expr/ob_expr_orahash.cpp index 2782f98df..a4811af10 100644 --- a/src/sql/engine/expr/ob_expr_orahash.cpp +++ b/src/sql/engine/expr/ob_expr_orahash.cpp @@ -66,7 +66,7 @@ int ObExprOrahash::calc_result_typeN(ObExprResType &type, return ret; } -//算法详见 https://yuque.antfin-inc.com/ob-public/sql/sfaedg +//算法详见 uint64_t ObExprOrahash::hash_mod_oracle(uint64_t val, uint64_t buckets) const { uint64_t N = 1; diff --git a/src/sql/engine/ob_operator.cpp b/src/sql/engine/ob_operator.cpp index ae7a3eda0..efb7a4d60 100644 --- a/src/sql/engine/ob_operator.cpp +++ b/src/sql/engine/ob_operator.cpp @@ -919,7 +919,7 @@ int ObOperator::submit_op_monitor_node() if (GCONF.enable_sql_audit) { // Record monitor info in sql_plan_monitor // Some records that meets the conditions needs to be archived - // Reference document: https://yuque.antfin.com/baixian.zr/brtfzn/ppx26a + // Reference document: op_monitor_info_.close_time_ = oceanbase::common::ObClockGenerator::getClock(); ObPlanMonitorNodeList *list = MTL(ObPlanMonitorNodeList*); if (list && spec_.plan_) { diff --git a/src/sql/engine/px/exchange/ob_px_receive_op.h b/src/sql/engine/px/exchange/ob_px_receive_op.h index ed8e8bacc..097e9455f 100644 --- a/src/sql/engine/px/exchange/ob_px_receive_op.h +++ b/src/sql/engine/px/exchange/ob_px_receive_op.h @@ -186,7 +186,7 @@ protected: int64_t bf_ctx_idx_; // the idx of bloom_filter_id_array_ in spec int64_t bf_send_idx_; // the idx of bf_send_ctx_array_ in sqc proxy // each_group_size_ only used in ObPxMsgProc::mark_rpc_filter()(this func will calc group_size, then each_group_size_ keep it for next use) - // means how many node(sqc level) in this group https://yuque.antfin.com/mingdou.tmd/px/gcu6uz + // means how many node(sqc level) in this group int64_t each_group_size_; }; diff --git a/src/sql/engine/px/ob_granule_pump.h b/src/sql/engine/px/ob_granule_pump.h index feaeb6c18..5fe942687 100644 --- a/src/sql/engine/px/ob_granule_pump.h +++ b/src/sql/engine/px/ob_granule_pump.h @@ -322,7 +322,7 @@ class ObGranulePump private: static const int64_t OB_GRANULE_SHARED_POOL_POS = 0; - // https://yuque.antfin-inc.com/docs/share/9b5fea38-dab7-46ee-bf02-98851def2de1?# + // // 《PX的GI详细实现》 enum ObGranuleSplitterType { diff --git a/src/sql/engine/px/ob_px_interruption.cpp b/src/sql/engine/px/ob_px_interruption.cpp index c0b8c37ef..0695bc391 100644 --- a/src/sql/engine/px/ob_px_interruption.cpp +++ b/src/sql/engine/px/ob_px_interruption.cpp @@ -235,7 +235,7 @@ int ObInterruptUtil::generate_px_interrupt_id(const uint32_t server_id, // 取低12位 timestamp = (uint64_t)0xfff & timestamp; interrupt_id.first_ = px_sequence_id; - // https://yuque.antfin-inc.com/mingdou.tmd/px/xc70bl + // // [ server_id (32bits) ][ qc_id (10bits)][ dfo_id (10bits) ][ timestamp (12bits) ] interrupt_id.last_ = ((uint64_t)server_id) << 32 | (uint64_t)qc_id << 22 | (uint64_t)dfo_id << 12 | (uint64_t)timestamp; diff --git a/src/sql/ob_sql_define.h b/src/sql/ob_sql_define.h index 6a6e62d36..6a223c653 100644 --- a/src/sql/ob_sql_define.h +++ b/src/sql/ob_sql_define.h @@ -513,6 +513,7 @@ enum PXParallelRule SESSION_FORCE_PARALLEL, // alter session force parallel query parallel 3; MANUAL_TABLE_DOP, // create table t1 (...) parallel 3; PL_UDF_DAS_FORCE_SERIALIZE, //stmt has_pl_udf will use das, force serialize; + DBLINK_FORCE_SERIALIZE, //stmt has dblink will use das, force seialize; MAX_OPTION }; @@ -528,6 +529,7 @@ inline const char *ob_px_parallel_rule_str(PXParallelRule px_parallel_ruel) "SESSION_FORCE_PARALLEL", "MANUAL_TABLE_DOP", "PL_UDF_DAS_FORCE_SERIALIZE", + "DBLINK_FORCE_SERIALIZE", "MAX_OPTION", }; if (OB_LIKELY(px_parallel_ruel >= NOT_USE_PX) diff --git a/src/sql/ob_sql_trans_control.cpp b/src/sql/ob_sql_trans_control.cpp index 0d23c7a18..e022b6d28 100644 --- a/src/sql/ob_sql_trans_control.cpp +++ b/src/sql/ob_sql_trans_control.cpp @@ -663,7 +663,7 @@ int ObSqlTransControl::stmt_setup_snapshot_(ObSQLSessionInfo *session, bool local_single_ls_plan = plan->is_local_plan() && OB_PHY_PLAN_LOCAL == plan->get_location_type() && das_ctx.has_same_lsid(&local_ls_id); - if (local_single_ls_plan && !tx_desc.is_can_elr()) { + if (local_single_ls_plan) { ret = txs->get_ls_read_snapshot(tx_desc, session->get_tx_isolation(), local_ls_id, diff --git a/src/sql/optimizer/ob_del_upd_log_plan.cpp b/src/sql/optimizer/ob_del_upd_log_plan.cpp index f1f1bab37..789c6384c 100644 --- a/src/sql/optimizer/ob_del_upd_log_plan.cpp +++ b/src/sql/optimizer/ob_del_upd_log_plan.cpp @@ -112,7 +112,7 @@ int ObDelUpdLogPlan::generate_dblink_raw_plan() } else { set_plan_root(top); bool has_reverse_link = false; - if (OB_FAIL(ObDblinkUtils::has_reverse_link(stmt, has_reverse_link))) { + if (OB_FAIL(ObDblinkUtils::has_reverse_link_or_any_dblink(stmt, has_reverse_link))) { LOG_WARN("failed to exec has_reverse_link", K(ret)); } else { uint64_t dblink_id = stmt->get_dblink_id(); diff --git a/src/sql/optimizer/ob_explain_note.h b/src/sql/optimizer/ob_explain_note.h index c5771dd0f..57cbcff90 100644 --- a/src/sql/optimizer/ob_explain_note.h +++ b/src/sql/optimizer/ob_explain_note.h @@ -32,6 +32,7 @@ namespace sql #define PARALLEL_ENABLED_BY_TABLE_PROPERTY "Degree of Parallelisim is %ld because of table property" #define PARALLEL_DISABLED_BY_PL_UDF_DAS "Degree of Parallelisim is %ld because stmt contain pl_udf which force das scan" #define DIRECT_MODE_INSERT_INTO_SELECT "Direct-mode is enabled in insert into select" +#define PARALLEL_DISABLED_BY_DBLINK "Degree of Parallelisim is %ld because stmt contain dblink which force das scan" } } diff --git a/src/sql/optimizer/ob_join_order.cpp b/src/sql/optimizer/ob_join_order.cpp index 24f96a338..4eb963fdd 100644 --- a/src/sql/optimizer/ob_join_order.cpp +++ b/src/sql/optimizer/ob_join_order.cpp @@ -1270,6 +1270,7 @@ int ObJoinOrder::will_use_das(const uint64_t table_id, bool hint_force_no_das = false; force_das_tsc = get_plan()->get_optimizer_context().in_nested_sql() || get_plan()->get_optimizer_context().has_pl_udf() || + get_plan()->get_optimizer_context().has_dblink() || get_plan()->get_optimizer_context().has_subquery_in_function_table() || is_batch_update_table; //this sql force to use DAS TSC: diff --git a/src/sql/optimizer/ob_log_link.cpp b/src/sql/optimizer/ob_log_link.cpp index ccecf6061..57a65e7b6 100644 --- a/src/sql/optimizer/ob_log_link.cpp +++ b/src/sql/optimizer/ob_log_link.cpp @@ -47,6 +47,14 @@ int ObLogLink::compute_sharding_info() return ret; } +int ObLogLink::compute_op_parallel_and_server_info() +{ + int ret = OB_SUCCESS; + set_parallel(1); + set_server_cnt(1); + return ret; +} + int ObLogLink::est_cost() { int ret = OB_SUCCESS; diff --git a/src/sql/optimizer/ob_log_link.h b/src/sql/optimizer/ob_log_link.h index c8f20dffc..1465a5e06 100644 --- a/src/sql/optimizer/ob_log_link.h +++ b/src/sql/optimizer/ob_log_link.h @@ -38,6 +38,7 @@ public: virtual ~ObLogLink() {} virtual int est_cost() override; virtual int compute_sharding_info() override; + virtual int compute_op_parallel_and_server_info() override; inline const common::ObIArray &get_param_infos() const { return param_infos_; } inline const char *get_stmt_fmt_buf() const { return stmt_fmt_buf_; } inline int32_t get_stmt_fmt_len() const { return stmt_fmt_len_; } diff --git a/src/sql/optimizer/ob_optimizer.cpp b/src/sql/optimizer/ob_optimizer.cpp index f492c9f5f..c953ce5a1 100644 --- a/src/sql/optimizer/ob_optimizer.cpp +++ b/src/sql/optimizer/ob_optimizer.cpp @@ -23,6 +23,7 @@ #include "common/ob_smart_call.h" #include "sql/ob_optimizer_trace_impl.h" #include "sql/engine/cmd/ob_table_direct_insert_service.h" +#include "sql/dblink/ob_dblink_utils.h" using namespace oceanbase; using namespace sql; using namespace oceanbase::common; @@ -400,7 +401,7 @@ int ObOptimizer::check_pdml_enabled(const ObDMLStmt &stmt, const ObSQLSessionInfo &session, bool &is_use_pdml) { - // https://yuque.antfin-inc.com/xiaochu.yh/doc/ii6elo + // // 1. pdml: force parallel dml & no DISABLE_PARALLEL_DML hint // 2. enable parallel query: parallel hint | sess enable_parallel_query // pdml: enable parallel dml + enable parallel query @@ -481,6 +482,7 @@ int ObOptimizer::check_pdml_supported_feature(const ObDMLStmt &stmt, const ObDelUpdStmt &pdml_stmt = static_cast(stmt); ObSEArray table_infos; bool enable_all_pdml_feature = false; // 默认非注入错误情况下,关闭PDML不稳定feature + bool stmt_has_dblink = false; // 目前通过注入错误的方式来打开PDML不稳定功能,用于PDML全部功能的case回归 // 对应的event注入任何类型的错误,都会打开PDML非稳定功能 ret = OB_E(EventTable::EN_ENABLE_PDML_ALL_FEATURE) OB_SUCCESS; @@ -511,6 +513,12 @@ int ObOptimizer::check_pdml_supported_feature(const ObDMLStmt &stmt, static_cast< const ObInsertStmt &>(stmt).is_insert_up()) { is_use_pdml = false; ctx_.add_plan_note(PDML_DISABLED_BY_INSERT_UP); + } else if (OB_FAIL(ObDblinkUtils::has_reverse_link_or_any_dblink(&stmt, stmt_has_dblink, true))) { + LOG_WARN("failed to find dblink in stmt", K(ret)); + } else if (stmt_has_dblink) { + is_use_pdml = false; + ctx_.add_plan_note(PARALLEL_DISABLED_BY_DBLINK); + ctx_.set_has_dblink(true); } else if (ctx_.contain_user_nested_sql()) { //user nested sql can't use PDML plan, force to use DAS plan //if online ddl has pl udf, only this way, allow it use PDML plan @@ -615,6 +623,7 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt) bool session_enable_parallel = false; bool has_var_assign = false; bool is_var_assign_only_in_root_stmt = false; + bool stmt_has_dblink = false; uint64_t session_force_parallel_dop = 1; int64_t max_table_dop = 1; int64_t max_table_hint = 1; @@ -676,6 +685,12 @@ int ObOptimizer::init_env_info(ObDMLStmt &stmt) ctx_.set_parallel(1); ctx_.add_plan_note(PARALLEL_DISABLED_BY_PL_UDF_DAS, 1); } + if (ctx_.has_dblink()) { + //if stmt contain dblink, force das, parallel should be 1 + ctx_.set_parallel_rule(PXParallelRule::DBLINK_FORCE_SERIALIZE); + ctx_.set_parallel(1); + ctx_.add_plan_note(PARALLEL_DISABLED_BY_DBLINK, 1); + } bool is_direct_insert = false; if (OB_FAIL(ObTableDirectInsertService::check_direct_insert(ctx_, stmt, is_direct_insert))) { LOG_WARN("failed to check direct insert", KR(ret)); diff --git a/src/sql/optimizer/ob_optimizer_context.h b/src/sql/optimizer/ob_optimizer_context.h index e4a47d257..0df1d10e7 100644 --- a/src/sql/optimizer/ob_optimizer_context.h +++ b/src/sql/optimizer/ob_optimizer_context.h @@ -227,7 +227,8 @@ ObOptimizerContext(ObSQLSessionInfo *session_info, px_parallel_rule_ == MANUAL_TABLE_HINT || px_parallel_rule_ == SESSION_FORCE_PARALLEL || px_parallel_rule_ == MANUAL_TABLE_DOP || - px_parallel_rule_ == PL_UDF_DAS_FORCE_SERIALIZE; + px_parallel_rule_ == PL_UDF_DAS_FORCE_SERIALIZE || + px_parallel_rule_ == DBLINK_FORCE_SERIALIZE; } inline bool use_intra_parallel() const { @@ -461,6 +462,8 @@ ObOptimizerContext(ObSQLSessionInfo *session_info, bool has_trigger() const { return has_trigger_; } void set_has_pl_udf(bool v) { has_pl_udf_ = v; } bool has_pl_udf() const { return has_pl_udf_; } + void set_has_dblink(bool v) { has_dblink_ = v; } + bool has_dblink() const { return has_dblink_; } void set_has_subquery_in_function_table(bool v) { has_subquery_in_function_table_ = v; } bool has_subquery_in_function_table() const { return has_subquery_in_function_table_; } bool contain_nested_sql() const { return nested_sql_flags_ > 0; } @@ -537,6 +540,7 @@ private: int8_t has_trigger_ : 1; //this sql has trigger object int8_t has_pl_udf_ : 1; //this sql has pl user defined function int8_t has_subquery_in_function_table_ : 1; //this stmt has function table + int8_t has_dblink_ : 1; //this stmt has dblink table }; }; bool has_for_update_; diff --git a/src/sql/optimizer/ob_px_resource_analyzer.cpp b/src/sql/optimizer/ob_px_resource_analyzer.cpp index 4c5412bd5..09c686e4c 100644 --- a/src/sql/optimizer/ob_px_resource_analyzer.cpp +++ b/src/sql/optimizer/ob_px_resource_analyzer.cpp @@ -132,7 +132,7 @@ int ObPxResourceAnalyzer::analyze( // 2. 然后模拟调度,每调度一对 dfo,就将 child 设置为 done,然后统计当前时刻多少个未完成 dfo // 3. 如此继续调度,直至所有 dfo 调度完成 // - // ref: https://yuque.antfin-inc.com/xiaochu.yh/doc/dlmg3w + // ref: ObArray px_trees; if (OB_FAIL(convert_log_plan_to_nested_px_tree(px_trees, root_op))) { LOG_WARN("fail convert log plan to nested px tree", K(ret)); diff --git a/src/sql/parser/sql_parser_base.h b/src/sql/parser/sql_parser_base.h index 0c2dcc50e..92c57e3cc 100644 --- a/src/sql/parser/sql_parser_base.h +++ b/src/sql/parser/sql_parser_base.h @@ -304,7 +304,7 @@ do { yyerror(NULL, result, "node or result is NULL\n"); \ YYABORT_UNEXPECTED; \ } else if (OB_UNLIKELY(!result->pl_parse_info_.is_pl_parse_ && 0 != result->question_mark_ctx_.count_)) { \ - /* 如果是PL过来的sql语句,不要检查: + /* 如果是PL过来的sql语句,不要检查:*/ \ yyerror(NULL, result, "Unknown column '?'\n"); \ YYABORT_UNEXPECTED; \ } else { \ diff --git a/src/sql/rewrite/ob_transform_utils.cpp b/src/sql/rewrite/ob_transform_utils.cpp index 167cbb844..98e60acfb 100644 --- a/src/sql/rewrite/ob_transform_utils.cpp +++ b/src/sql/rewrite/ob_transform_utils.cpp @@ -4406,7 +4406,7 @@ int ObTransformUtils::compute_table_property(const ObDMLStmt *stmt, { int ret = OB_SUCCESS; const JoinedTable *joined_table = NULL; - if (OB_ISNULL(table)) { + if (OB_ISNULL(table) || OB_ISNULL(stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected stmt", K(ret)); } else if (table->is_basic_table() @@ -4418,7 +4418,12 @@ int ObTransformUtils::compute_table_property(const ObDMLStmt *stmt, cond_exprs, res_info)))) { LOG_WARN("failed to compute generate table property", K(ret)); } else if (!table->is_joined_table()) { - /*do nothing*/ + ObSqlBitSet<> rel_ids; + if (OB_FAIL(stmt->get_table_rel_ids(*table, rel_ids))) { + LOG_WARN("failed to get table ids", K(ret)); + } else if (OB_FAIL(res_info.table_set_.add_members(rel_ids))) { + LOG_WARN("failed to add members", K(ret)); + } } else if (FALSE_IT(joined_table = static_cast(table))) { } else if (joined_table->is_inner_join()) { ret = SMART_CALL(compute_inner_join_property(stmt, check_helper, joined_table, diff --git a/src/sql/session/ObSQLSessionMgr实现思路.md b/src/sql/session/ObSQLSessionMgr实现思路.md index 3b802f129..e1fe0a0ae 100755 --- a/src/sql/session/ObSQLSessionMgr实现思路.md +++ b/src/sql/session/ObSQLSessionMgr实现思路.md @@ -48,7 +48,7 @@ observer采用16位递增id表示当前server分配的sessid_seq。分配策略 #### session_key -为了解决ObServer在接收客户端断连接请求后,未能及时释放sessid的问题([详情](http://review.alibaba-inc.com/r/29086/)),引入了session_key的概念; +为了解决ObServer在接收客户端断连接请求后,未能及时释放sessid的问题,引入了session_key的概念; - session_key为含有version和sessid两个成员变量的结构体,session_key作为ObSQLSessionInfo在session map中的key;通过session_key对ObSQLSessioInfo进行create_session/get_session/free_session; - 当ObServer接收到断连接请求后,在on_disconnect接口中,对sessid 进行unused,并将相应的ObSQLSessionInfo设置为shadow - 如果proxy采取saved_login,并使用相同的sessid,observer如果判断出当前full_sessid对应的ObSQLSessionInfo为shadow,则会创建一个新的ObSQLSessionInfo,并指定一个可用的version。 diff --git a/src/sql/session/ob_sql_session_mgr.h b/src/sql/session/ob_sql_session_mgr.h index 072070f3d..3cad895b4 100644 --- a/src/sql/session/ob_sql_session_mgr.h +++ b/src/sql/session/ob_sql_session_mgr.h @@ -268,7 +268,7 @@ private: //ObNullEndTransCallback null_callback_; // used for manage ObSQLSessionInfo HashMap sessinfo_map_; - // design doc: https://yuque.antfin-inc.com/docs/share/820fa006-f85a-4530-8e2b-fe3c90271404 + // design doc: // |<---------------------------------32bit---------------------------->| // 31b 30b 29b 18b 16b 0b // +----+------------------------------+--------------------------------+ diff --git a/src/storage/direct_load/ob_direct_load_merge_ctx.cpp b/src/storage/direct_load/ob_direct_load_merge_ctx.cpp index 96cd28315..4db2dd3a6 100644 --- a/src/storage/direct_load/ob_direct_load_merge_ctx.cpp +++ b/src/storage/direct_load/ob_direct_load_merge_ctx.cpp @@ -303,6 +303,54 @@ int ObDirectLoadTabletMergeCtx::collect_sql_statistics( return ret; } +int ObDirectLoadTabletMergeCtx::init_sstable_array( + const ObIArray &table_array) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < table_array.count(); ++i) { + ObDirectLoadSSTable *sstable = nullptr; + if (OB_ISNULL(sstable = dynamic_cast(table_array.at(i)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table", KR(ret), K(i), K(table_array)); + } else if (OB_FAIL(sstable_array_.push_back(sstable))) { + LOG_WARN("fail to push back sstable", KR(ret)); + } + } + return ret; +} + +int ObDirectLoadTabletMergeCtx::init_multiple_sstable_array( + const ObIArray &table_array) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < table_array.count(); ++i) { + ObDirectLoadMultipleSSTable *sstable = nullptr; + if (OB_ISNULL(sstable = dynamic_cast(table_array.at(i)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table", KR(ret), K(i), K(table_array)); + } else if (OB_FAIL(multiple_sstable_array_.push_back(sstable))) { + LOG_WARN("fail to push back multiple sstable", KR(ret)); + } + } + return ret; +} + +int ObDirectLoadTabletMergeCtx::init_multiple_heap_table_array( + const ObIArray &table_array) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < table_array.count(); ++i) { + ObDirectLoadMultipleHeapTable *heap_table = nullptr; + if (OB_ISNULL(heap_table = dynamic_cast(table_array.at(i)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table", KR(ret), K(i), K(table_array)); + } else if (OB_FAIL(multiple_heap_table_array_.push_back(heap_table))) { + LOG_WARN("fail to push back multiple heap table", KR(ret)); + } + } + return ret; +} + int ObDirectLoadTabletMergeCtx::build_merge_task( const ObIArray &table_array, const ObIArray &col_descs, @@ -393,16 +441,10 @@ int ObDirectLoadTabletMergeCtx::build_pk_table_merge_task( int64_t max_parallel_degree) { int ret = OB_SUCCESS; - // split range - for (int64_t i = 0; OB_SUCC(ret) && i < table_array.count(); ++i) { - ObDirectLoadSSTable *sstable = nullptr; - if (OB_ISNULL(sstable = dynamic_cast(table_array.at(i)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected table", KR(ret), K(i), K(table_array)); - } else if (OB_FAIL(sstable_array_.push_back(sstable))) { - LOG_WARN("fail to push back sstable", KR(ret)); - } + if (OB_FAIL(init_sstable_array(table_array))) { + LOG_WARN("fail to init sstable array", KR(ret)); } + // split range if (OB_SUCC(ret)) { ObDirectLoadMergeRangeSplitter range_splitter; if (OB_FAIL( @@ -444,16 +486,10 @@ int ObDirectLoadTabletMergeCtx::build_pk_table_multiple_merge_task( int64_t max_parallel_degree) { int ret = OB_SUCCESS; - // split range - for (int64_t i = 0; OB_SUCC(ret) && i < table_array.count(); ++i) { - ObDirectLoadMultipleSSTable *sstable = nullptr; - if (OB_ISNULL(sstable = dynamic_cast(table_array.at(i)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected table", KR(ret), K(i), K(table_array)); - } else if (OB_FAIL(multiple_sstable_array_.push_back(sstable))) { - LOG_WARN("fail to push back sstable", KR(ret)); - } + if (OB_FAIL(init_multiple_sstable_array(table_array))) { + LOG_WARN("fail to init multiple sstable array", KR(ret)); } + // split range if (OB_SUCC(ret)) { ObDirectLoadMultipleMergeTabletRangeSplitter range_splitter; if (OB_FAIL(range_splitter.init(tablet_id_, &origin_table_, multiple_sstable_array_, @@ -617,6 +653,9 @@ int ObDirectLoadTabletMergeCtx::build_heap_table_multiple_merge_task( { int ret = OB_SUCCESS; int64_t parallel_idx = 0; + if (OB_FAIL(init_multiple_heap_table_array(table_array))) { + LOG_WARN("fail to init multiple heap table array", KR(ret)); + } // for existing data, construct task by split range if (OB_SUCC(ret)) { ObDirectLoadMergeRangeSplitter range_splitter; @@ -651,16 +690,12 @@ int ObDirectLoadTabletMergeCtx::build_heap_table_multiple_merge_task( } } // for imported data, construct task by multiple heap table - for (int64_t i = 0; OB_SUCC(ret) && !param_.is_fast_heap_table_ && i < table_array.count(); ++i) { - ObDirectLoadMultipleHeapTable *heap_table = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && !param_.is_fast_heap_table_ && i < multiple_heap_table_array_.count(); ++i) { + ObDirectLoadMultipleHeapTable *heap_table = multiple_heap_table_array_.at(i); ObDirectLoadPartitionHeapTableMultipleMergeTask *merge_task = nullptr; int64_t row_count = 0; ObTabletCacheInterval pk_interval; - if (OB_ISNULL(heap_table = dynamic_cast(table_array.at(i)))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected table", KR(ret), K(i), K(table_array)); - } else if (OB_FAIL(heap_table->get_tablet_row_count(tablet_id_, param_.table_data_desc_, - row_count))) { + if (OB_FAIL(heap_table->get_tablet_row_count(tablet_id_, param_.table_data_desc_, row_count))) { LOG_WARN("fail to get tablet row count", KR(ret), K(tablet_id_)); } else if (0 == row_count) { // ignore @@ -686,6 +721,50 @@ int ObDirectLoadTabletMergeCtx::build_heap_table_multiple_merge_task( return ret; } +int ObDirectLoadTabletMergeCtx::build_aggregate_merge_task_for_multiple_heap_table( + const ObIArray &table_array) +{ + int ret = OB_SUCCESS; + int64_t total_row_count = 0; + ObTabletCacheInterval pk_interval; + ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask *merge_task = nullptr; + if (OB_FAIL(init_multiple_heap_table_array(table_array))) { + LOG_WARN("fail to init multiple heap table array", KR(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < multiple_heap_table_array_.count(); ++i) { + ObDirectLoadMultipleHeapTable *heap_table = multiple_heap_table_array_.at(i); + int64_t row_count = 0; + if (OB_FAIL(heap_table->get_tablet_row_count(tablet_id_, param_.table_data_desc_, row_count))) { + LOG_WARN("fail to get tablet row count", KR(ret), K(tablet_id_)); + } else { + total_row_count += row_count; + } + } + if (OB_SUCC(ret)) { + if (total_row_count > 0 && OB_FAIL(get_autoincrement_value(total_row_count, pk_interval))) { + LOG_WARN("fail to get autoincrement value", KR(ret), K(total_row_count)); + } else if (OB_ISNULL(merge_task = + OB_NEWx(ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask, + (&allocator_)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask", KR(ret)); + } else if (OB_FAIL(merge_task->init(param_, this, &origin_table_, multiple_heap_table_array_, + pk_interval))) { + LOG_WARN("fail to init merge task", KR(ret)); + } else if (OB_FAIL(task_array_.push_back(merge_task))) { + LOG_WARN("fail to push back merge task", KR(ret)); + } + } + if (OB_FAIL(ret)) { + if (nullptr != merge_task) { + merge_task->~ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask(); + allocator_.free(merge_task); + merge_task = nullptr; + } + } + return ret; +} + int ObDirectLoadTabletMergeCtx::get_autoincrement_value(uint64_t count, ObTabletCacheInterval &interval) { diff --git a/src/storage/direct_load/ob_direct_load_merge_ctx.h b/src/storage/direct_load/ob_direct_load_merge_ctx.h index 3876c92a7..4a2bbcdfe 100644 --- a/src/storage/direct_load/ob_direct_load_merge_ctx.h +++ b/src/storage/direct_load/ob_direct_load_merge_ctx.h @@ -34,6 +34,7 @@ class ObDirectLoadTabletMergeCtx; class ObIDirectLoadPartitionTable; class ObDirectLoadSSTable; class ObDirectLoadMultipleSSTable; +class ObDirectLoadMultipleHeapTable; class ObDirectLoadMultipleMergeRangeSplitter; struct ObDirectLoadMergeParam @@ -99,6 +100,8 @@ public: const common::ObIArray &multiple_sstable_array, ObDirectLoadMultipleMergeRangeSplitter &range_splitter, int64_t max_parallel_degree); + int build_aggregate_merge_task_for_multiple_heap_table( + const common::ObIArray &table_array); int inc_finish_count(bool &is_ready); int collect_sql_statistics( const common::ObIArray &fast_heap_table_array, table::ObTableLoadSqlStatistics &sql_statistics); @@ -111,6 +114,11 @@ public: } TO_STRING_KV(K_(param), K_(target_partition_id), K_(tablet_id), K_(target_tablet_id)); private: + int init_sstable_array(const common::ObIArray &table_array); + int init_multiple_sstable_array( + const common::ObIArray &table_array); + int init_multiple_heap_table_array( + const common::ObIArray &table_array); int build_empty_data_merge_task(const common::ObIArray &col_descs, int64_t max_parallel_degree); int build_pk_table_merge_task(const common::ObIArray &table_array, @@ -138,6 +146,7 @@ private: ObDirectLoadOriginTable origin_table_; common::ObSEArray sstable_array_; common::ObSEArray multiple_sstable_array_; + common::ObSEArray multiple_heap_table_array_; common::ObSEArray range_array_; common::ObSEArray task_array_; int64_t task_finish_count_ CACHE_ALIGNED; diff --git a/src/storage/direct_load/ob_direct_load_partition_merge_task.cpp b/src/storage/direct_load/ob_direct_load_partition_merge_task.cpp index fc5a37c5d..90c3c61b3 100644 --- a/src/storage/direct_load/ob_direct_load_partition_merge_task.cpp +++ b/src/storage/direct_load/ob_direct_load_partition_merge_task.cpp @@ -5,13 +5,14 @@ #define USING_LOG_PREFIX STORAGE #include "storage/direct_load/ob_direct_load_partition_merge_task.h" +#include "share/stat/ob_opt_column_stat.h" +#include "share/stat/ob_stat_define.h" #include "storage/ddl/ob_direct_insert_sstable_ctx.h" #include "storage/direct_load/ob_direct_load_external_table.h" #include "storage/direct_load/ob_direct_load_insert_table_ctx.h" -#include "storage/direct_load/ob_direct_load_multiple_heap_table.h" #include "storage/direct_load/ob_direct_load_merge_ctx.h" -#include "share/stat/ob_opt_column_stat.h" -#include "share/stat/ob_stat_define.h" +#include "storage/direct_load/ob_direct_load_multiple_heap_table.h" +#include "storage/direct_load/ob_direct_load_origin_table.h" namespace oceanbase { @@ -822,5 +823,233 @@ int ObDirectLoadPartitionHeapTableMultipleMergeTask::construct_row_iter( return ret; } +/** + * ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask + */ + +ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask::RowIterator::RowIterator() + : origin_iter_(nullptr), + rowkey_column_num_(0), + store_column_count_(0), + heap_table_array_(nullptr), + pos_(0), + deserialize_datums_(nullptr), + deserialize_datum_cnt_(0), + result_info_(nullptr), + is_inited_(false) +{ +} + +ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask::RowIterator::~RowIterator() +{ +} + +int ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask::RowIterator::init( + const ObDirectLoadMergeParam &merge_param, const ObTabletID &tablet_id, + ObDirectLoadOriginTable *origin_table, + const ObIArray *heap_table_array, + const ObTabletCacheInterval &pk_interval) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObDirectLoadPartitionHeapTableMultipleMergeTask::RowIterator init twice", KR(ret), + KP(this)); + } else if (OB_UNLIKELY(!merge_param.is_valid() || !tablet_id.is_valid() || + nullptr == origin_table || nullptr == heap_table_array)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(merge_param), K(tablet_id), KP(origin_table), + KP(heap_table_array)); + } else { + range_.set_whole_range(); + if (OB_FAIL(origin_table->scan(range_, allocator_, origin_iter_))) { + LOG_WARN("fail to scan origin table", KR(ret)); + } + // init datum_row_ + else if (OB_FAIL(datum_row_.init(merge_param.store_column_count_ + + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt()))) { + LOG_WARN("fail to init datum row", KR(ret)); + } else { + datum_row_.row_flag_.set_flag(ObDmlFlag::DF_INSERT); + datum_row_.mvcc_row_flag_.set_last_multi_version_row(true); + datum_row_.storage_datums_[merge_param.rowkey_column_num_].set_int( + -merge_param.snapshot_version_); // fill trans_version + datum_row_.storage_datums_[merge_param.rowkey_column_num_ + 1].set_int(0); // fill sql_no + deserialize_datums_ = datum_row_.storage_datums_ + merge_param.rowkey_column_num_ + + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + deserialize_datum_cnt_ = merge_param.store_column_count_ - merge_param.rowkey_column_num_; + rowkey_column_num_ = merge_param.rowkey_column_num_; + store_column_count_ = merge_param.store_column_count_; + tablet_id_ = tablet_id; + table_data_desc_ = merge_param.table_data_desc_; + heap_table_array_ = heap_table_array; + pk_interval_ = pk_interval; + result_info_ = merge_param.result_info_; + is_inited_ = true; + } + } + return ret; +} + +int ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask::RowIterator::get_next_row( + const ObDatumRow *&result_row) +{ + int ret = OB_SUCCESS; + result_row = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask::RowIterator not init", + KR(ret), KP(this)); + } else { + if (pos_ == 0) { + const ObDatumRow *datum_row = nullptr; + if (OB_FAIL(origin_iter_->get_next_row(datum_row))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next row", KR(ret)); + } else { + // switch heap table + ret = OB_SUCCESS; + if (OB_FAIL(switch_next_heap_table())) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to switch next heap table", KR(ret)); + } + } + } + } else if (OB_UNLIKELY(datum_row->count_ != store_column_count_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected column count", KR(ret), K(store_column_count_), KPC(datum_row)); + } else { + // copy rowkey columns + for (int64_t i = 0; i < rowkey_column_num_; ++i) { + datum_row_.storage_datums_[i] = datum_row->storage_datums_[i]; + } + // copy normal columns + for (int64_t + i = rowkey_column_num_, + j = rowkey_column_num_ + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + i < datum_row->count_; ++i, ++j) { + datum_row_.storage_datums_[j] = datum_row->storage_datums_[i]; + } + result_row = &datum_row_; + } + } + while (OB_SUCC(ret) && result_row == nullptr) { + const ObDirectLoadMultipleExternalRow *external_row = nullptr; + uint64_t pk_seq = OB_INVALID_ID; + if (OB_FAIL(scanner_.get_next_row(external_row))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next row", KR(ret)); + } else { + // switch next heap table + ret = OB_SUCCESS; + if (OB_FAIL(switch_next_heap_table())) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to switch next heap table", KR(ret)); + } + } + } + } else if (OB_FAIL(external_row->to_datums(deserialize_datums_, deserialize_datum_cnt_))) { + LOG_WARN("fail to transfer datum row", KR(ret)); + } else if (OB_FAIL(pk_interval_.next_value(pk_seq))) { + LOG_WARN("fail to get next pk seq", KR(ret)); + } else { + // fill hide pk + datum_row_.storage_datums_[0].set_int(pk_seq); + result_row = &datum_row_; + ATOMIC_INC(&result_info_->rows_affected_); + } + } + } + return ret; +} + +int ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask::RowIterator::switch_next_heap_table() +{ + int ret = OB_SUCCESS; + if (pos_ >= heap_table_array_->count()) { + ret = OB_ITER_END; + } else { + ObDirectLoadMultipleHeapTable *heap_table = heap_table_array_->at(pos_); + // restructure scanner + scanner_.~ObDirectLoadMultipleHeapTableTabletWholeScanner(); + new (&scanner_) ObDirectLoadMultipleHeapTableTabletWholeScanner(); + if (OB_FAIL(scanner_.init(heap_table, tablet_id_, table_data_desc_))) { + LOG_WARN("fail to init scanner", KR(ret)); + } else { + ++pos_; + } + } + return ret; +} + +ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask:: + ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask() + : origin_table_(nullptr), heap_table_array_(nullptr) +{ +} + +ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask:: + ~ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask() +{ +} + +int ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask::init( + const ObDirectLoadMergeParam &merge_param, ObDirectLoadTabletMergeCtx *merge_ctx, + ObDirectLoadOriginTable *origin_table, + const ObIArray &heap_table_array, + const ObTabletCacheInterval &pk_interval) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObDirectLoadPartitionHeapTableMultipleMergeTask init twice", KR(ret), KP(this)); + } else if (OB_UNLIKELY(!merge_param.is_valid() || nullptr == merge_ctx || + nullptr == origin_table || heap_table_array.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), K(merge_param), KP(merge_ctx), KP(origin_table), + K(heap_table_array)); + } else { + merge_param_ = &merge_param; + merge_ctx_ = merge_ctx; + parallel_idx_ = 0; + origin_table_ = origin_table; + heap_table_array_ = &heap_table_array; + pk_interval_ = pk_interval; + is_inited_ = true; + } + return ret; +} + +int ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask::construct_row_iter( + ObIAllocator &allocator, ObIStoreRowIterator *&result_row_iter) +{ + int ret = OB_SUCCESS; + result_row_iter = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask not init", KR(ret), + KP(this)); + } else { + RowIterator *row_iter = nullptr; + if (OB_ISNULL(row_iter = OB_NEWx(RowIterator, (&allocator)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to new RowIterator", KR(ret)); + } else if (OB_FAIL(row_iter->init(*merge_param_, merge_ctx_->get_tablet_id(), origin_table_, + heap_table_array_, pk_interval_))) { + LOG_WARN("fail to init row iter", KR(ret)); + } else { + result_row_iter = row_iter; + } + if (OB_FAIL(ret)) { + if (nullptr != row_iter) { + row_iter->~RowIterator(); + allocator.free(row_iter); + row_iter = nullptr; + } + } + } + return ret; +} + } // namespace storage } // namespace oceanbase diff --git a/src/storage/direct_load/ob_direct_load_partition_merge_task.h b/src/storage/direct_load/ob_direct_load_partition_merge_task.h index 6fbdaa725..ec3c2d818 100644 --- a/src/storage/direct_load/ob_direct_load_partition_merge_task.h +++ b/src/storage/direct_load/ob_direct_load_partition_merge_task.h @@ -206,5 +206,56 @@ private: share::ObTabletCacheInterval pk_interval_; }; +class ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask + : public ObDirectLoadPartitionMergeTask +{ +public: + ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask(); + virtual ~ObDirectLoadPartitionHeapTableMultipleAggregateMergeTask(); + int init(const ObDirectLoadMergeParam &merge_param, ObDirectLoadTabletMergeCtx *merge_ctx, + ObDirectLoadOriginTable *origin_table, + const common::ObIArray &heap_table_array, + const share::ObTabletCacheInterval &pk_interval); +protected: + int construct_row_iter(common::ObIAllocator &allocator, ObIStoreRowIterator *&row_iter) override; +private: + class RowIterator : public ObIStoreRowIterator + { + public: + RowIterator(); + virtual ~RowIterator(); + int init(const ObDirectLoadMergeParam &merge_param, const common::ObTabletID &tablet_id, + ObDirectLoadOriginTable *origin_table, + const common::ObIArray *heap_table_array, + const share::ObTabletCacheInterval &pk_interval); + int get_next_row(const blocksstable::ObDatumRow *&datum_row) override; + private: + int switch_next_heap_table(); + private: + // for iter origin table + common::ObArenaAllocator allocator_; + blocksstable::ObDatumRange range_; + ObIStoreRowIterator *origin_iter_; + int64_t rowkey_column_num_; + int64_t store_column_count_; + // for iter multiple heap table + common::ObTabletID tablet_id_; + ObDirectLoadTableDataDesc table_data_desc_; + const common::ObIArray *heap_table_array_; + int64_t pos_; + ObDirectLoadMultipleHeapTableTabletWholeScanner scanner_; + blocksstable::ObDatumRow datum_row_; + blocksstable::ObStorageDatum *deserialize_datums_; + int64_t deserialize_datum_cnt_; + share::ObTabletCacheInterval pk_interval_; + table::ObTableLoadResultInfo *result_info_; + bool is_inited_; + }; +private: + ObDirectLoadOriginTable *origin_table_; + const common::ObIArray *heap_table_array_; + share::ObTabletCacheInterval pk_interval_; +}; + } // namespace storage } // namespace oceanbase diff --git a/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.h b/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.h index f9b8f54a8..c33490f1a 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.h +++ b/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.h @@ -237,9 +237,23 @@ public: void clear_pending_log_size() { ATOMIC_STORE(&pending_log_size_, 0); } int64_t get_pending_log_size() { return ATOMIC_LOAD(&pending_log_size_); } int64_t get_flushed_log_size() { return ATOMIC_LOAD(&flushed_log_size_); } - bool is_all_redo_submitted(ObITransCallback *generate_cursor) + bool is_all_redo_submitted() { - return (ObITransCallback *)callback_list_.get_tail() == generate_cursor; + bool all_redo_submitted = true; + if (OB_NOT_NULL(callback_lists_)) { + for (int64_t i = 0; i < MAX_CALLBACK_LIST_COUNT; ++i) { + if (!callback_lists_[i].empty()) { + all_redo_submitted = false; + break; + } + } + } + + if (all_redo_submitted) { + all_redo_submitted = !(((ObITransCallback *)callback_list_.get_tail())->need_submit_log()); + } + + return all_redo_submitted; } void merge_multi_callback_lists(); void reset_pdml_stat(); @@ -278,10 +292,6 @@ public: share::SCN get_checksum_scn() const { return callback_list_.get_checksum_scn(); } transaction::ObPartTransCtx *get_trans_ctx() const; private: - bool is_all_redo_submitted(ObMvccRowCallback *generate_cursor) - { - return (ObMvccRowCallback *)callback_list_.get_tail() == generate_cursor; - } void force_merge_multi_callback_lists(); private: ObITransCallback *get_guard_() { return callback_list_.get_guard(); } diff --git a/src/storage/memtable/ob_memtable_context.cpp b/src/storage/memtable/ob_memtable_context.cpp index 2c108862d..231f65aeb 100644 --- a/src/storage/memtable/ob_memtable_context.cpp +++ b/src/storage/memtable/ob_memtable_context.cpp @@ -223,10 +223,10 @@ void ObMemtableCtx::dec_ref() (void)ATOMIC_AAF(&ref_, -1); } -void ObMemtableCtx::set_replay() +void ObMemtableCtx::wait_pending_write() { - WRLockGuard guard(rwlock_); - is_master_ = false; + ATOMIC_STORE(&is_master_, false); + WRLockGuard wrguard(rwlock_); } SCN ObMemtableCtx::get_tx_end_scn() const @@ -907,10 +907,9 @@ int ObMemtableCtx::rollback(const int64_t to_seq_no, const int64_t from_seq_no) bool ObMemtableCtx::is_all_redo_submitted() { ObByteLockGuard guard(lock_); - return trans_mgr_.is_all_redo_submitted(log_gen_.get_generate_cursor()); + return trans_mgr_.is_all_redo_submitted(); } - int ObMemtableCtx::remove_callbacks_for_fast_commit() { int ret = OB_SUCCESS; diff --git a/src/storage/memtable/ob_memtable_context.h b/src/storage/memtable/ob_memtable_context.h index 7e52f3793..f5c5f0137 100644 --- a/src/storage/memtable/ob_memtable_context.h +++ b/src/storage/memtable/ob_memtable_context.h @@ -342,7 +342,7 @@ public: virtual void set_read_only(); virtual void inc_ref(); virtual void dec_ref(); - void set_replay(); + void wait_pending_write(); virtual int write_auth(const bool exclusive); virtual int write_done(); virtual int trans_begin(); diff --git a/src/storage/tx/ob_trans_define.h b/src/storage/tx/ob_trans_define.h index a8bc8c22e..3cdf10d71 100644 --- a/src/storage/tx/ob_trans_define.h +++ b/src/storage/tx/ob_trans_define.h @@ -1722,6 +1722,7 @@ enum class TxEndAction : int8_t { COMMIT_TX, ABORT_TX, + DELAY_ABORT_TX, KILL_TX_FORCEDLY }; diff --git a/src/storage/tx/ob_trans_part_ctx.cpp b/src/storage/tx/ob_trans_part_ctx.cpp index 5cb330d96..379335b3e 100644 --- a/src/storage/tx/ob_trans_part_ctx.cpp +++ b/src/storage/tx/ob_trans_part_ctx.cpp @@ -971,6 +971,16 @@ bool ObPartTransCtx::is_in_2pc_() const bool ObPartTransCtx::is_logging_() const { return !busy_cbs_.is_empty(); } +bool ObPartTransCtx::need_force_abort_() const +{ + return sub_state_.is_force_abort() && !sub_state_.is_state_log_submitted(); +} + +bool ObPartTransCtx::is_force_abort_logging_() const +{ + return sub_state_.is_force_abort() && sub_state_.is_state_log_submitting(); +} + bool ObPartTransCtx::has_persisted_log_() const { return exec_info_.max_applying_log_ts_.is_valid(); @@ -1244,6 +1254,9 @@ int ObPartTransCtx::check_rs_scheduler_is_alive_(bool &is_alive) if (OB_ISNULL(trans_service_)) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "trans service is NULL", KR(ret), K(*this)); + } else if (need_force_abort_() && !exec_info_.scheduler_.is_valid()) { + is_alive = false; + TRANS_LOG(WARN, "a aborting trans will be gc with invalid scheduler", K(ret), K(is_alive), KPC(this)); } else if (OB_ISNULL(server_tracer = trans_service_->get_server_tracer())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(WARN, "server tracer is NULL", KR(ret), K(*this)); @@ -1304,6 +1317,10 @@ int ObPartTransCtx::check_scheduler_status() } // 2. Ask for the status of scheduler ret = OB_SUCCESS; + int ctx_status = OB_SUCCESS; + if (sub_state_.is_force_abort()) { + ctx_status = OB_TRANS_KILLED; + } if (is_alive && need_check_scheduler) { ObTxKeepaliveMsg msg; msg.cluster_version_ = cluster_version_; @@ -1315,7 +1332,7 @@ int ObPartTransCtx::check_scheduler_status() msg.sender_ = ls_id_; msg.receiver_ = share::SCHEDULER_LS; // this just used to pass validation msg.epoch_ = epoch_; - msg.status_ = OB_SUCCESS; + msg.status_ = ctx_status; if (OB_FAIL(rpc_->post_msg(exec_info_.scheduler_, msg))) { TRANS_LOG(WARN, "post tx keepalive msg fail", K(ret), K(msg), KPC(this)); } @@ -1567,7 +1584,7 @@ int ObPartTransCtx::check_and_submit_redo_log_(bool &try_submit) bool is_tx_committing = ObTxState::INIT != get_downstream_state(); bool final_log_submitting = final_log_cb_.is_valid(); - if (!is_tx_committing && !final_log_submitting) { + if (!is_tx_committing && !final_log_submitting && !is_force_abort_logging_()) { (void)mt_ctx_.merge_multi_callback_lists_for_immediate_logging(); ret = submit_log_impl_(ObTxLogType::TX_REDO_LOG); try_submit = true; @@ -1636,7 +1653,9 @@ bool ObPartTransCtx::is_table_lock_killed() const int ObPartTransCtx::compensate_abort_log_() { int ret = OB_SUCCESS; - if (OB_FAIL(submit_log_impl_(ObTxLogType::TX_ABORT_LOG))) { + if (is_force_abort_logging_()) { + // do nothing + } else if (OB_FAIL(submit_log_impl_(ObTxLogType::TX_ABORT_LOG))) { TRANS_LOG(WARN, "submit abort log failed", KR(ret), K(*this)); } else { sub_state_.set_force_abort(); @@ -2045,7 +2064,7 @@ int ObPartTransCtx::try_submit_next_log_(const bool for_freeze) int ret = OB_SUCCESS; ObTxLogType log_type = ObTxLogType::UNKNOWN; if (ObPartTransAction::COMMIT == part_trans_action_ && !is_2pc_logging_() && !is_in_2pc_() - && !sub_state_.is_force_abort()) { + && !need_force_abort_()) { if (is_follower_()) { ret = OB_NOT_MASTER; } else { @@ -2306,6 +2325,43 @@ int ObPartTransCtx::fill_redo_log_(char *buf, int ret = OB_SUCCESS; const bool log_for_lock_node = true; // const bool log_for_lock_node = !(is_local_tx_() && (part_trans_action_ == ObPartTransAction::COMMIT)); + // // // // + // Possible problems caused: + // 1. block frozen : We wiil not add data_node_count if skip lock node in fill_redo. Then the next memtable + // will return -4112 and the prev memtable will wait for lock node clearing unsubmitted_cnt. + // 2. replay checksum error: + // | + // | part_trans_action != COMMIT + // v + // +-------------------------------------+ + // | start submit_commit_log | + // +-------------------------------------+ + // | + // | + // v + // +-------------------------------------+ + // | log_for_lock_node == false | + // | cal checksum with lock node | + // +-------------------------------------+ + // | + // | + // v + // +-------------------------------------+ + // | submit commit log failed with -4038 | + // | rewrite as OB_SUCCESS | + // +-------------------------------------+ + // | + // | part_trans_action = COMMIT + // v + // +-------------------------------------+ + // | retry submit commit log | + // +-------------------------------------+ + // | + // | + // v + // +-------------------------------------+ + // | replay checksum ERROR | + // +-------------------------------------+ if (OB_UNLIKELY(NULL == buf || buf_len < 0 || pos < 0 || buf_len < pos)) { ret = OB_INVALID_ARGUMENT; @@ -2446,7 +2502,7 @@ int ObPartTransCtx::submit_redo_log_() const int64_t replay_hint = static_cast(trans_id_.get_id()); ObRedoLogSubmitHelper helper; ObTxLogBlockHeader - log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); @@ -2495,7 +2551,7 @@ int ObPartTransCtx::submit_redo_commit_info_log_() const int64_t replay_hint = static_cast(trans_id_.get_id()); ObRedoLogSubmitHelper helper; ObTxLogBlockHeader - log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (sub_state_.is_info_log_submitted()) { // state log already submitted, do nothing @@ -2619,7 +2675,7 @@ int ObPartTransCtx::submit_redo_active_info_log_() const int64_t replay_hint = static_cast(trans_id_.get_id()); ObRedoLogSubmitHelper helper; ObTxLogBlockHeader - log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); @@ -2728,7 +2784,7 @@ int ObPartTransCtx::submit_prepare_log_() const int64_t replay_hint = static_cast(trans_id_.get_id()); ObRedoLogSubmitHelper helper; ObTxLogBlockHeader - log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); @@ -2849,7 +2905,8 @@ int ObPartTransCtx::submit_commit_log_() const int64_t replay_hint = static_cast(trans_id_.get_id()); ObRedoLogSubmitHelper helper; ObTxBufferNodeArray multi_source_data; - ObTxLogBlockHeader log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + ObTxLogBlockHeader + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); const bool local_tx = is_local_tx_(); if (OB_FAIL(gen_final_mds_array_(multi_source_data))) { @@ -2870,7 +2927,10 @@ int ObPartTransCtx::submit_commit_log_() } else if (use_local_block_buf) { // realloc log buf and retry submit log log_block.reset(); - ObTxLogBlockHeader tmp_log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + ObTxLogBlockHeader tmp_log_block_header(cluster_id_, + exec_info_.next_log_entry_no_, + trans_id_, + exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, tmp_log_block_header, false /*use_local_block_buf*/))) { TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); } else if (OB_FAIL(submit_redo_commit_info_log_(log_block, has_redo, helper))) { @@ -3049,7 +3109,7 @@ int ObPartTransCtx::submit_abort_log_() const int64_t replay_hint = static_cast(trans_id_.get_id()); ObTxLogBlockHeader - log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (OB_FAIL(gen_final_mds_array_(tmp_array, false))) { TRANS_LOG(WARN, "gen abort mds array failed", K(ret)); @@ -3108,7 +3168,8 @@ int ObPartTransCtx::submit_clear_log_() ObTxClearLog clear_log(exec_info_.incremental_participants_); ObTxLogCb *log_cb = NULL; const int64_t replay_hint = static_cast(trans_id_.get_id()); - ObTxLogBlockHeader log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + ObTxLogBlockHeader + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); @@ -3152,7 +3213,7 @@ int ObPartTransCtx::submit_record_log_() ObTxLogCb *log_cb = NULL; const int64_t replay_hint = static_cast(trans_id_.get_id()); ObTxLogBlockHeader - log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); @@ -3206,7 +3267,7 @@ int ObPartTransCtx::submit_big_segment_log_() while (OB_SUCC(ret)) { const char *submit_buf = nullptr; int64_t submit_buf_len = 0; - ObTxLogBlockHeader log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + ObTxLogBlockHeader log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); } else if (OB_FAIL(prepare_log_cb_(!NEED_FINAL_CB, log_cb))) { @@ -3551,7 +3612,7 @@ int ObPartTransCtx::after_submit_log_(ObTxLogBlock &log_block, exec_info_.next_log_entry_no_++; ObTxLogBlockHeader - block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); log_block.reuse(trans_id_, block_header); return ret; } @@ -4894,7 +4955,7 @@ int ObPartTransCtx::switch_to_leader(const SCN &start_working_ts) } else { TRANS_LOG(WARN, "txn data incomplete, will be aborted", K(contain_table_lock), KPC(this)); if (has_persisted_log_()) { - if (OB_FAIL(do_local_tx_end_(TxEndAction::ABORT_TX))) { + if (OB_FAIL(do_local_tx_end_(TxEndAction::DELAY_ABORT_TX))) { TRANS_LOG(WARN, "abort tx failed", KR(ret), K(*this)); } } else { @@ -5014,12 +5075,14 @@ int ObPartTransCtx::switch_to_follower_forcedly(ObIArray &cb TRANS_LOG(INFO, "switch to follower forcely, txn aborted without persisted log", KPC(this)); } else { // has persisted log, wait new leader to advance it - if (OB_FAIL(mt_ctx_.commit_to_replay())) { - TRANS_LOG(WARN, "commit to replay error", KR(ret), "context", *this); - } else if (OB_FAIL(mt_ctx_.clean_unlog_callbacks())) { + if (pending_write_ && OB_FALSE_IT(mt_ctx_.wait_pending_write())) { + // do nothing + } else if (OB_FALSE_IT(mt_ctx_.commit_to_replay())) { + // do nothing + } else if (OB_FALSE_IT(mt_ctx_.merge_multi_callback_lists_for_changing_leader())) { + // do nothing + } else if (!mt_ctx_.is_all_redo_submitted() && OB_FAIL(mt_ctx_.clean_unlog_callbacks())) { TRANS_LOG(WARN, "clear unlog callbacks", KR(ret), K(*this)); - } else { - TRANS_LOG(DEBUG, "commit to replay success", "context", *this); } // special handle commit triggered by local call: coordinator colocate with scheduler @@ -5071,7 +5134,7 @@ int ObPartTransCtx::switch_to_follower_gracefully(ObIArray & TRANS_LOG(ERROR, "tenant not match", K(ret), K(*this)); } else if (is_exiting_) { // do nothing - } else if (sub_state_.is_force_abort()) { + } else if (is_force_abort_logging_()) { // is aborting, skip } else if (is_follower_()) { TRANS_LOG(INFO, "current tx already follower", K(*this)); @@ -5080,7 +5143,7 @@ int ObPartTransCtx::switch_to_follower_gracefully(ObIArray & } else { if (pending_write_) { TRANS_LOG(INFO, "current tx is executing stmt", K(*this)); - mt_ctx_.set_replay(); + mt_ctx_.wait_pending_write(); need_submit_log = true; } else if (!is_committing_()) { need_submit_log = true; @@ -5109,7 +5172,7 @@ int ObPartTransCtx::switch_to_follower_gracefully(ObIArray & } } timeguard.click(); - if (OB_SUCC(ret) && need_submit_log) { + if (OB_SUCC(ret) && need_submit_log && !need_force_abort_()) { // We need merge all callbacklists before submitting active info (void)mt_ctx_.merge_multi_callback_lists_for_changing_leader(); if (ObTxLogType::TX_COMMIT_INFO_LOG == log_type) { @@ -5532,8 +5595,8 @@ int ObPartTransCtx::submit_multi_data_source_() int ret = OB_SUCCESS; ObTxLogBlock log_block; const int64_t replay_hint = static_cast(trans_id_.get_id()); - ObTxLogBlockHeader - log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + ObTxLogBlockHeader log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, + exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { TRANS_LOG(WARN, "init log block failed", KR(ret), K(*this)); } else { @@ -5693,6 +5756,7 @@ int ObPartTransCtx::register_multi_data_source(const ObTxDataSourceType data_sou ObString data; void *ptr = nullptr; ObTxBufferNodeArray tmp_array; + bool need_lock = true; if (try_lock) { @@ -5704,6 +5768,7 @@ int ObPartTransCtx::register_multi_data_source(const ObTxDataSourceType data_sou } else { // do nothing } + if (OB_SUCC(ret)) { CtxLockGuard guard(lock_, need_lock); @@ -5711,12 +5776,23 @@ int ObPartTransCtx::register_multi_data_source(const ObTxDataSourceType data_sou || data_source_type >= ObTxDataSourceType::MAX_TYPE)) { ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid argument", KR(ret), K(data_source_type), KP(buf), K(len)); + } else if (OB_UNLIKELY(is_committing_())) { + ret = OB_TRANS_HAS_DECIDED; + if (is_trans_expired_() && ObPartTransAction::ABORT == part_trans_action_) { + // rewrite error with TRANS_TIMEOUT to easy user + ret = OB_TRANS_TIMEOUT; + } else if (ObPartTransAction::ABORT == part_trans_action_ + || exec_info_.state_ == ObTxState::ABORT) { + ret = OB_TRANS_KILLED; + } + TRANS_LOG(WARN, "tx has decided", K(ret), KPC(this)); + } else if (OB_UNLIKELY(sub_state_.is_force_abort())) { + ret = OB_TRANS_KILLED; + TRANS_LOG(WARN, "tx force aborted due to data incomplete", K(ret), KPC(this)); } else if (is_follower_()) { ret = OB_NOT_MASTER; - TRANS_LOG(WARN, "can not register mds on a follower", K(ret), K(data_source_type), K(len), KPC(this)); - } else if (is_committing_()) { - ret = OB_TRANS_HAS_DECIDED; - TRANS_LOG(WARN, "can not register mds in committing part_ctx", K(ret), KPC(this)); + TRANS_LOG(WARN, "can not register mds on a follower", K(ret), K(data_source_type), K(len), + KPC(this)); } else if (OB_ISNULL(ptr = mtl_malloc(len, "MultiTxData"))) { ret = OB_ALLOCATE_MEMORY_FAILED; TRANS_LOG(WARN, "allocate memory failed", KR(ret), K(data_source_type), K(len)); @@ -5731,13 +5807,13 @@ int ObPartTransCtx::register_multi_data_source(const ObTxDataSourceType data_sou ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "too large mds buf node", K(ret), K(tmp_array.get_serialize_size())); } else if (OB_FAIL(mds_cache_.insert_mds_node(node))) { - TRANS_LOG(WARN, "register multi source data failed", KR(ret), K(data_source_type), K(*this)); + TRANS_LOG(WARN, "register multi source data failed", KR(ret), K(data_source_type), + K(*this)); } if (OB_FAIL(ret)) { mtl_free(ptr); - } else if (OB_FAIL(notify_data_source_(NotifyType::REGISTER_SUCC, SCN(), false, - tmp_array))) { + } else if (OB_FAIL(notify_data_source_(NotifyType::REGISTER_SUCC, SCN(), false, tmp_array))) { if (OB_SUCCESS != (tmp_ret = mds_cache_.rollback_last_mds_node())) { ret = OB_ERR_UNEXPECTED; TRANS_LOG(ERROR, "rollback last mds node failed", K(tmp_ret), K(ret)); @@ -5746,24 +5822,19 @@ int ObPartTransCtx::register_multi_data_source(const ObTxDataSourceType data_sou TRANS_LOG(WARN, "notify data source for register_succ failed", K(tmp_ret)); } else if (mds_cache_.get_unsubmitted_size() < ObTxMultiDataSourceLog::MAX_PENDING_BUF_SIZE) { // do nothing - } else if (OB_SUCCESS != (tmp_ret = submit_log_impl_(ObTxLogType::TX_MULTI_DATA_SOURCE_LOG))) { + } else if (OB_SUCCESS + != (tmp_ret = submit_log_impl_(ObTxLogType::TX_MULTI_DATA_SOURCE_LOG))) { TRANS_LOG(WARN, "submit mds log failed", K(tmp_ret)); } } } if (OB_FAIL(ret)) { - TRANS_LOG(WARN, - "register MDS redo in part_ctx failed", - K(ret), - K(trans_id_), - K(ls_id_), - K(data_source_type), - K(len), - K(mds_cache_), - K(exec_info_.multi_data_source_)); + TRANS_LOG(WARN, "register MDS redo in part_ctx failed", K(ret), K(trans_id_), K(ls_id_), + K(data_source_type), K(len), K(mds_cache_), K(exec_info_.multi_data_source_)); } - REC_TRANS_TRACE_EXT2(tlog_, register_multi_data_source, OB_ID(ret), ret, OB_ID(type), data_source_type); + REC_TRANS_TRACE_EXT2(tlog_, register_multi_data_source, OB_ID(ret), ret, OB_ID(type), + data_source_type); return ret; } @@ -6248,7 +6319,8 @@ int ObPartTransCtx::submit_rollback_to_log_(const int64_t from_scn, ObTxRollbackToLog log(from_scn, to_scn); ObTxLogCb *log_cb = NULL; - ObTxLogBlockHeader log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_); + ObTxLogBlockHeader + log_block_header(cluster_id_, exec_info_.next_log_entry_no_, trans_id_, exec_info_.scheduler_); if (OB_FAIL(log_block.init(replay_hint, log_block_header))) { TRANS_LOG(WARN, "init log block fail", K(ret), KPC(this)); @@ -6395,7 +6467,16 @@ int ObPartTransCtx::do_local_tx_end_(TxEndAction tx_end_action) switch (tx_end_action) { case TxEndAction::COMMIT_TX: { - ret = do_local_commit_tx_(); + if (sub_state_.is_force_abort()) { + if (OB_FAIL(compensate_abort_log_())) { + TRANS_LOG(WARN, "compensate abort log failed", K(ret), K(ls_id_), K(trans_id_), + K(tx_end_action), K(sub_state_)); + } else { + ret = OB_TRANS_KILLED; + } + } else { + ret = do_local_commit_tx_(); + } // part_trans_action_ will be set as commit in ObPartTransCtx::commit function break; } @@ -6410,6 +6491,10 @@ int ObPartTransCtx::do_local_tx_end_(TxEndAction tx_end_action) ret = do_force_kill_tx_(); break; } + case TxEndAction::DELAY_ABORT_TX: { + sub_state_.set_force_abort(); + break; + } default: { ret = OB_INVALID_ARGUMENT; TRANS_LOG(WARN, "invalid tx_end_action", K(ret), K(tx_end_action)); diff --git a/src/storage/tx/ob_trans_part_ctx.h b/src/storage/tx/ob_trans_part_ctx.h index 37ad229d5..d62d8ce63 100644 --- a/src/storage/tx/ob_trans_part_ctx.h +++ b/src/storage/tx/ob_trans_part_ctx.h @@ -253,6 +253,12 @@ private: int init_memtable_ctx_(const uint64_t tenant_id, const share::ObLSID &ls_id); bool is_in_2pc_() const; bool is_logging_() const; + + // force abort but not submit abort log + bool need_force_abort_() const; + // force abort but wait abort log_cb + bool is_force_abort_logging_() const; + bool need_record_log_() const; void reset_redo_lsns_(); void set_prev_record_lsn_(const LogOffSet &prev_record_lsn); diff --git a/src/storage/tx/ob_trans_service_v4.cpp b/src/storage/tx/ob_trans_service_v4.cpp index d62dedb82..a661e8101 100644 --- a/src/storage/tx/ob_trans_service_v4.cpp +++ b/src/storage/tx/ob_trans_service_v4.cpp @@ -1496,6 +1496,7 @@ int ObTransService::acquire_local_snapshot_(const share::ObLSID &ls_id, bool leader = false; SCN snapshot0; ObLSTxCtxMgr *ls_tx_ctx_mgr = NULL; + const bool can_elr = MTL_IS_PRIMARY_TENANT() ? true : false; if (OB_FAIL(tx_ctx_mgr_.get_ls_tx_ctx_mgr(ls_id, ls_tx_ctx_mgr))) { TRANS_LOG(WARN, "get ls_tx_ctx_mgr fail", K(ret), K(ls_id)); } else if (!ls_tx_ctx_mgr->in_leader_serving_state()) { @@ -1507,7 +1508,7 @@ int ObTransService::acquire_local_snapshot_(const share::ObLSID &ls_id, TRANS_LOG(WARN, "get replica role fail", K(ret), K(ls_id)); } else if (!leader) { ret = OB_NOT_MASTER; - } else if (FALSE_IT(snapshot0 = tx_version_mgr_.get_max_commit_ts(true))) { + } else if (FALSE_IT(snapshot0 = tx_version_mgr_.get_max_commit_ts(can_elr))) { } else if (!snapshot0.is_valid_and_not_min()) { ret = OB_EAGAIN; } else { diff --git a/src/storage/tx/ob_tx_2pc_ctx_impl.cpp b/src/storage/tx/ob_tx_2pc_ctx_impl.cpp index 2668d2e2e..f24f7b6c1 100644 --- a/src/storage/tx/ob_tx_2pc_ctx_impl.cpp +++ b/src/storage/tx/ob_tx_2pc_ctx_impl.cpp @@ -75,13 +75,26 @@ int ObPartTransCtx::do_prepare(bool &no_need_submit_log) int ret = OB_SUCCESS; no_need_submit_log = false; - if (exec_info_.is_dup_tx_ || OB_SUCC(search_unsubmitted_dup_table_redo_())) { - no_need_submit_log = true; - if (OB_FAIL(dup_table_tx_redo_sync_())) { - TRANS_LOG(WARN, "dup table tx redo sync failed", K(ret)); + if (OB_SUCC(ret)) { + if (sub_state_.is_force_abort()) { + if (OB_FAIL(compensate_abort_log_())) { + TRANS_LOG(WARN, "compensate abort log failed", K(ret), K(ls_id_), K(trans_id_), + K(get_downstream_state()), K(get_upstream_state()), K(sub_state_)); + } else { + ret = OB_TRANS_KILLED; + } + } + } + + if (OB_SUCC(ret)) { + if (exec_info_.is_dup_tx_ || OB_SUCC(search_unsubmitted_dup_table_redo_())) { + no_need_submit_log = true; + if (OB_FAIL(dup_table_tx_redo_sync_())) { + TRANS_LOG(WARN, "dup table tx redo sync failed", K(ret)); + } + } else if (OB_FAIL(generate_prepare_version_())) { + TRANS_LOG(WARN, "generate prepare version failed", K(ret), K(*this)); } - } else if (OB_FAIL(generate_prepare_version_())) { - TRANS_LOG(WARN, "generate prepare version failed", K(ret), K(*this)); } if (OB_SUCC(ret)) { diff --git a/src/storage/tx/ob_tx_2pc_msg_handler.cpp b/src/storage/tx/ob_tx_2pc_msg_handler.cpp index 7dc5e2a3c..7ec2eb62f 100644 --- a/src/storage/tx/ob_tx_2pc_msg_handler.cpp +++ b/src/storage/tx/ob_tx_2pc_msg_handler.cpp @@ -686,6 +686,13 @@ int ObPartTransCtx::handle_tx_2pc_prepare_redo_req(const Ob2pcPrepareRedoReqMsg msg_2pc_cache_ = &msg; if (OB_FAIL(set_2pc_request_id_(msg.request_id_))) { TRANS_LOG(WARN, "set request id failed", KR(ret), K(msg), K(*this)); + } else if (sub_state_.is_force_abort()) { + if (OB_FAIL(compensate_abort_log_())) { + TRANS_LOG(WARN, "compensate abort log failed", K(ret), K(ls_id_), K(trans_id_), + K(get_downstream_state()), K(get_upstream_state()), K(sub_state_)); + } else { + ret = OB_TRANS_KILLED; + } } else if (OB_FAIL(handle_2pc_req(msg_type))) { TRANS_LOG(WARN, "handle 2pc request failed", KR(ret), K(msg), K(*this)); } diff --git a/src/storage/tx/ob_tx_api.cpp b/src/storage/tx/ob_tx_api.cpp index a3d44e8b1..d018ec0c5 100644 --- a/src/storage/tx/ob_tx_api.cpp +++ b/src/storage/tx/ob_tx_api.cpp @@ -585,9 +585,7 @@ int ObTransService::get_read_snapshot(ObTxDesc &tx, snapshot.uncertain_bound_))) { TRANS_LOG(WARN, "acquire global snapshot fail", K(ret), K(tx)); } else { - if (tx.is_can_elr() && MTL_IS_PRIMARY_TENANT()) { - snapshot.core_.version_ = std::max(snapshot.core_.version_, tx_version_mgr_.get_max_commit_ts(true)); - } + // do nothing } if (OB_SUCC(ret)) { snapshot.source_ = ObTxReadSnapshot::SRC::GLOBAL; diff --git a/src/storage/tx/ob_tx_data_functor.cpp b/src/storage/tx/ob_tx_data_functor.cpp index ed7d83857..f93ef3c50 100644 --- a/src/storage/tx/ob_tx_data_functor.cpp +++ b/src/storage/tx/ob_tx_data_functor.cpp @@ -150,7 +150,7 @@ int GetTxStateWithSCNFunctor::operator()(const ObTxData &tx_data, ObTxCCCtx *tx_ // return the transaction state_ according to the merge log ts. // the detailed document is available as follows. - // https://yuque.antfin-inc.com/docs/share/a3160d5e-6e1a-4980-a12e-4af653c6cf57?# + // if (ObTxData::RUNNING == state || ObTxData::ELR_COMMIT == state) { // Case 1: data is during execution, so we return the running state with // INT64_MAX as version diff --git a/src/storage/tx/ob_tx_log.cpp b/src/storage/tx/ob_tx_log.cpp index 93d0c54fb..17d40ced4 100644 --- a/src/storage/tx/ob_tx_log.cpp +++ b/src/storage/tx/ob_tx_log.cpp @@ -974,7 +974,12 @@ int ObTxAbortLog::init_tx_data_backup(const share::SCN &start_scn) // ============================== Tx Log Blcok ============================= -OB_TX_SERIALIZE_MEMBER(ObTxLogBlockHeader, compat_bytes_, org_cluster_id_, log_entry_no_, tx_id_); +OB_TX_SERIALIZE_MEMBER(ObTxLogBlockHeader, + compat_bytes_, + org_cluster_id_, + log_entry_no_, + tx_id_, + scheduler_); int ObTxLogBlockHeader::before_serialize() { @@ -985,7 +990,7 @@ int ObTxLogBlockHeader::before_serialize() TRANS_LOG(WARN, "reset all compat_bytes_ valid failed", K(ret)); } } else { - if (OB_FAIL(compat_bytes_.init(3))) { + if (OB_FAIL(compat_bytes_.init(4))) { TRANS_LOG(WARN, "init compat_bytes_ failed", K(ret)); } } diff --git a/src/storage/tx/ob_tx_log.h b/src/storage/tx/ob_tx_log.h index 465d53c2d..669fd3872 100644 --- a/src/storage/tx/ob_tx_log.h +++ b/src/storage/tx/ob_tx_log.h @@ -901,6 +901,7 @@ public: org_cluster_id_ = 0; log_entry_no_ = 0; tx_id_ = 0; + scheduler_.reset(); } ObTxLogBlockHeader() { @@ -909,8 +910,10 @@ public: }; ObTxLogBlockHeader(const uint64_t org_cluster_id, const int64_t log_entry_no, - const ObTransID &tx_id) - : org_cluster_id_(org_cluster_id), log_entry_no_(log_entry_no), tx_id_(tx_id) + const ObTransID &tx_id, + const common::ObAddr &scheduler) + : org_cluster_id_(org_cluster_id), log_entry_no_(log_entry_no), tx_id_(tx_id), + scheduler_(scheduler) { before_serialize(); } @@ -918,10 +921,11 @@ public: uint64_t get_org_cluster_id() const { return org_cluster_id_; } int64_t get_log_entry_no() const { return log_entry_no_; } const ObTransID &get_tx_id() const { return tx_id_; } + const common::ObAddr &get_scheduler() const { return scheduler_; } bool is_valid() const { return org_cluster_id_ >= 0; } - TO_STRING_KV(K_(org_cluster_id), K_(log_entry_no), K_(tx_id)); + TO_STRING_KV(K_(org_cluster_id), K_(log_entry_no), K_(tx_id), K_(scheduler)); public: int before_serialize(); @@ -931,6 +935,7 @@ private: uint64_t org_cluster_id_; int64_t log_entry_no_; ObTransID tx_id_; + common::ObAddr scheduler_; }; class ObTxAdaptiveLogBuf diff --git a/src/storage/tx/ob_tx_ls_log_writer.cpp b/src/storage/tx/ob_tx_ls_log_writer.cpp index 6140dd0ff..b7451957f 100644 --- a/src/storage/tx/ob_tx_ls_log_writer.cpp +++ b/src/storage/tx/ob_tx_ls_log_writer.cpp @@ -59,7 +59,7 @@ void ObTxLSLogLimit::decide_log_buf_size() LOG_BUF_SIZE = 0; ObLogBaseHeader base_header; ObTxLogHeader tx_header; - ObTxLogBlockHeader block_header(UINT64_MAX, INT64_MAX, INT64_MAX); + ObTxLogBlockHeader block_header(UINT64_MAX, INT64_MAX, INT64_MAX, common::ObAddr()); ObTxStartWorkingLog sw_log(INT_MAX64); // block_header.before_serialize(); diff --git a/src/storage/tx/ob_tx_replay_executor.cpp b/src/storage/tx/ob_tx_replay_executor.cpp index 3b4ddef55..b55818ab4 100644 --- a/src/storage/tx/ob_tx_replay_executor.cpp +++ b/src/storage/tx/ob_tx_replay_executor.cpp @@ -247,11 +247,16 @@ int ObTxReplayExecutor::try_get_tx_ctx_(int64_t tx_id, int64_t tenant_id, const } else if (OB_TRANS_CTX_NOT_EXIST == ret) { ret = OB_SUCCESS; bool tx_ctx_existed = false; - common::ObAddr scheduler; - ObTxCreateArg arg(true, /* for_replay */ - tenant_id, tx_id, ls_id, log_block_header_.get_org_cluster_id(), - GET_MIN_CLUSTER_VERSION(), 0, /*session_id*/ - scheduler, INT64_MAX, /*trans_expired_time_*/ + common::ObAddr scheduler = log_block_header_.get_scheduler(); + ObTxCreateArg arg(true, /* for_replay */ + tenant_id, + tx_id, + ls_id, + log_block_header_.get_org_cluster_id(), + GET_MIN_CLUSTER_VERSION(), + 0, /*session_id*/ + scheduler, + INT64_MAX, /*trans_expired_time_*/ ls_tx_srv_->get_trans_service()); if (OB_FAIL(ls_tx_srv_->create_tx_ctx(arg, tx_ctx_existed, ctx_))) { TRANS_LOG(WARN, "get_tx_ctx error", K(ret), K(tx_id), KP(ctx_)); diff --git a/src/storage/tx_table/ob_tx_ctx_memtable.h b/src/storage/tx_table/ob_tx_ctx_memtable.h index 010aef988..fa6ad0c70 100644 --- a/src/storage/tx_table/ob_tx_ctx_memtable.h +++ b/src/storage/tx_table/ob_tx_ctx_memtable.h @@ -36,7 +36,7 @@ namespace storage // design prototype, the goal is a unified abstraction of the merge module. // // [1]: -// [2]: https://yuque.antfin.com/docs/share/1e78f01c-73fb-4c32-a002-c2c75ca844a8?# +// [2]: class ObTxCtxMemtable : public memtable::ObIMemtable, public checkpoint::ObCommonCheckpoint { public: diff --git a/src/storage/tx_table/ob_tx_data_table.h b/src/storage/tx_table/ob_tx_data_table.h index 995893ca2..baacc65bc 100644 --- a/src/storage/tx_table/ob_tx_data_table.h +++ b/src/storage/tx_table/ob_tx_data_table.h @@ -45,7 +45,7 @@ struct TxDataReadSchema // In Ob4.0, transaction state table is divided into tx data table and tx // context table. See details : -// https://yuque.antfin.com/docs/share/127d0836-8931-4c9e-8e68-64b900ba91f4?# +// // // All operatitons related to tx_data are implemented by ObTxDataTable. // See details :: diff --git a/tools/deploy/mysql_test/test_suite/expr/r/mysql/expr_export_set.result b/tools/deploy/mysql_test/test_suite/expr/r/mysql/expr_export_set.result index 12db327f9..78b1ae59d 100644 --- a/tools/deploy/mysql_test/test_suite/expr/r/mysql/expr_export_set.result +++ b/tools/deploy/mysql_test/test_suite/expr/r/mysql/expr_export_set.result @@ -38,15 +38,15 @@ select export_set(9,"Y","N","-",5); +-----------------------------+ select export_set(9,"左","右","-",5); +---------------------------------+ -| export_set(9,"左","右","-",5) | +| export_set(9,"左","右","-",5) | +---------------------------------+ -| 左-右-右-左-右 | +| 左-右-右-左-右 | +---------------------------------+ select export_set(9,"上","下","-",5); +---------------------------------+ -| export_set(9,"上","下","-",5) | +| export_set(9,"上","下","-",5) | +---------------------------------+ -| 上-下-下-上-下 | +| 上-下-下-上-下 | +---------------------------------+ select export_set(5,"Y","N",".",5); +-----------------------------+ diff --git a/tools/deploy/mysql_test/test_suite/expr/r/mysql/expr_instr.result b/tools/deploy/mysql_test/test_suite/expr/r/mysql/expr_instr.result index ca86f228e..b93e67497 100644 --- a/tools/deploy/mysql_test/test_suite/expr/r/mysql/expr_instr.result +++ b/tools/deploy/mysql_test/test_suite/expr/r/mysql/expr_instr.result @@ -62,25 +62,25 @@ select instr('abcbc', 'bc') from dual; +----------------------+ select instr('阿里巴巴', '阿里') from dual; +---------------------------------+ -| instr('阿里巴巴', '阿里') | +| instr('阿里巴巴', '阿里') | +---------------------------------+ | 1 | +---------------------------------+ select instr('阿里巴巴', '巴巴') from dual; +---------------------------------+ -| instr('阿里巴巴', '巴巴') | +| instr('阿里巴巴', '巴巴') | +---------------------------------+ | 3 | +---------------------------------+ select instr('阿里巴巴巴巴', '巴巴') from dual; +---------------------------------------+ -| instr('阿里巴巴巴巴', '巴巴') | +| instr('阿里巴巴巴巴', '巴巴') | +---------------------------------------+ | 3 | +---------------------------------------+ select instr('阿里巴巴', '阿里巴巴') from dual; +---------------------------------------+ -| instr('阿里巴巴', '阿里巴巴') | +| instr('阿里巴巴', '阿里巴巴') | +---------------------------------------+ | 1 | +---------------------------------------+ @@ -116,13 +116,13 @@ select instr('123.400000', null) from dual; +---------------------------+ select instr(null, '巴巴') from dual; +-----------------------+ -| instr(null, '巴巴') | +| instr(null, '巴巴') | +-----------------------+ | NULL | +-----------------------+ select instr('巴巴', null) from dual; +-----------------------+ -| instr('巴巴', null) | +| instr('巴巴', null) | +-----------------------+ | NULL | +-----------------------+ diff --git a/tools/deploy/mysql_test/test_suite/meta_info/r/mysql/meta_build_in_func_test.result b/tools/deploy/mysql_test/test_suite/meta_info/r/mysql/meta_build_in_func_test.result index 379de25fa..fb242c10c 100644 --- a/tools/deploy/mysql_test/test_suite/meta_info/r/mysql/meta_build_in_func_test.result +++ b/tools/deploy/mysql_test/test_suite/meta_info/r/mysql/meta_build_in_func_test.result @@ -1729,7 +1729,7 @@ def str_to_date('1970-02-03 10:56:56', NULL) 12 26 0 Y 128 6 63 +------------------------------------------+ select coalesce(length(lower(null)), length(lower(upper('yssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxddsd'))), length('dir')) from build_in_func_test_table; Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr -def coalesce(length(lower(null)), length(lower(upper('yssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss 8 20 3 Y 32768 0 63 +def coalesce(length(lower(null)), length(lower(upper('yssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss 8 20 3 Y 32768 0 63 +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | coalesce(length(lower(null)), length(lower(upper('yssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss | +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ diff --git a/tools/deploy/mysql_test/test_suite/pl/r/mysql/pl_basic_mysql.result b/tools/deploy/mysql_test/test_suite/pl/r/mysql/pl_basic_mysql.result index 844697285..789add5b7 100644 --- a/tools/deploy/mysql_test/test_suite/pl/r/mysql/pl_basic_mysql.result +++ b/tools/deploy/mysql_test/test_suite/pl/r/mysql/pl_basic_mysql.result @@ -2047,10 +2047,10 @@ SELECT * FROM result1// +------+--------------+--------------+ | id | res1 | res2 | +------+--------------+--------------+ -| 1 | 结果表: | 标签label1 | -| 2 | 结果表: | 标签label2 | -| 3 | 结果表: | 标签label1 | -| 4 | 结果表: | 标签label1 | +| 1 | 结果表: | 标签label1 | +| 2 | 结果表: | 标签label2 | +| 3 | 结果表: | 标签label1 | +| 4 | 结果表: | 标签label1 | +------+--------------+--------------+ DROP TABLE IF EXISTS result1// DROP PROCEDURE IF EXISTS `pro_1`// @@ -2213,9 +2213,9 @@ SELECT * FROM t2// +------+----------------------------------------+---------------------+---------------------+----------------------------+ | id | res1 | d1 | d2 | d3 | +------+----------------------------------------+---------------------+---------------------+----------------------------+ -| 1 | 插入DATETIME类型数据 | 1000-01-01 00:00:00 | 2000-01-01 00:00:00 | 9999-12-31 23:59:59.999999 | -| 2 | 变量形式插入DATETIME类型数据 | 1000-01-01 00:00:00 | 2021-07-03 00:00:00 | 9999-12-31 23:59:59.999999 | -| 3 | 直接插入DATETIME类型数据 | 3000-01-01 00:00:00 | 4000-01-01 00:00:00 | 9999-12-31 23:59:59.999999 | +| 1 | 插入DATETIME类型数据 | 1000-01-01 00:00:00 | 2000-01-01 00:00:00 | 9999-12-31 23:59:59.999999 | +| 2 | 变量形式插入DATETIME类型数据 | 1000-01-01 00:00:00 | 2021-07-03 00:00:00 | 9999-12-31 23:59:59.999999 | +| 3 | 直接插入DATETIME类型数据 | 3000-01-01 00:00:00 | 4000-01-01 00:00:00 | 9999-12-31 23:59:59.999999 | +------+----------------------------------------+---------------------+---------------------+----------------------------+ ### int @@ -2316,7 +2316,7 @@ select fun2()// +--------------+ | fun2() | +--------------+ -| 隐式提交 | +| 隐式提交 | +--------------+ select * from t1// diff --git a/tools/deploy/mysql_test/test_suite/skyline/t/skyline_basic_mysql.test b/tools/deploy/mysql_test/test_suite/skyline/t/skyline_basic_mysql.test index 3a18f033e..ac6c1d572 100644 --- a/tools/deploy/mysql_test/test_suite/skyline/t/skyline_basic_mysql.test +++ b/tools/deploy/mysql_test/test_suite/skyline/t/skyline_basic_mysql.test @@ -55,7 +55,7 @@ create table t6 (pk int primary key, a int, b int, c int, d int, e int, ## create table t7(a int, b int, c int, d int, e int, f int, key k1(a,c,b), key k2(a,b,c,d,e)); -## +##project/81079/issue/12046883?akProjectId=81079& create table t8(a int primary key, b int, c int, d int, e int, f int, index k1(b,c,e), index k2(c,d,e,f)); create table tmp (pk int primary key, c1 int, c2 int, c3 int, c4 int, c5 int, @@ -332,7 +332,7 @@ explain select c from t6 where b = 1 and a > 2 union select pk from tmp; ## explain select * from t7 where a >= 0 and a <= 5 and b = 1; -## +##project/81079/issue/12046883?akProjectId=81079& explain select * from t8 where e = 1 order by b; explain select * from t8 where e = 1 or f = 1 order by b; explain select * from t8 where d = 1 order by b; diff --git a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_concat.result b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_concat.result index fecc9994e..90e2db6a5 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_concat.result +++ b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_concat.result @@ -129,16 +129,16 @@ select group_concat(c1) from t111_var; set group_concat_max_len=29; select group_concat('中文' separator '分隔') from t111_var; +-------------------------------------------+ -| group_concat('中文' separator '分隔') | +| group_concat('中文' separator '分隔') | +-------------------------------------------+ -| 中文分隔中文分隔中 | +| 中文分隔中文分隔中 | +-------------------------------------------+ set group_concat_max_len=23; select group_concat('中文' separator '分隔') from t111_var; +-------------------------------------------+ -| group_concat('中文' separator '分隔') | +| group_concat('中文' separator '分隔') | +-------------------------------------------+ -| 中文分隔中文分 | +| 中文分隔中文分 | +-------------------------------------------+ set group_concat_max_len=1024; diff --git a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_location.result b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_location.result index 88553f358..769f8c61a 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_location.result +++ b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_location.result @@ -42,7 +42,7 @@ Warning 1292 Truncated incorrect INTEGER value: '0.1' Warning 1292 Truncated incorrect INTEGER value: '-1.1' select locate('中', 'a中测试', 1); +--------------------------------+ -| locate('中', 'a中测试', 1) | +| locate('中', 'a中测试', 1) | +--------------------------------+ | 2 | +--------------------------------+ @@ -85,16 +85,16 @@ select locate('a', 'a', 10000000000000000000000000000000000000000000000000000000 select instr('abc', 'a'), instr('aaaa','a'), instr('a中测试', '中'), instr(null, 'a'), instr('a', null); +-------------------+-------------------+----------------------------+------------------+------------------+ -| instr('abc', 'a') | instr('aaaa','a') | instr('a中测试', '中') | instr(null, 'a') | instr('a', null) | +| instr('abc', 'a') | instr('aaaa','a') | instr('a中测试', '中') | instr(null, 'a') | instr('a', null) | +-------------------+-------------------+----------------------------+------------------+------------------+ | 1 | 1 | 2 | NULL | NULL | +-------------------+-------------------+----------------------------+------------------+------------------+ select reverse(''), reverse(null), reverse('你好abc中文'), reverse(12345.123), reverse(null); +-------------+---------------+----------------------------+--------------------+---------------+ -| reverse('') | reverse(null) | reverse('你好abc中文') | reverse(12345.123) | reverse(null) | +| reverse('') | reverse(null) | reverse('你好abc中文') | reverse(12345.123) | reverse(null) | +-------------+---------------+----------------------------+--------------------+---------------+ -| | NULL | 文中cba好你 | 321.54321 | NULL | +| | NULL | 文中cba好你 | 321.54321 | NULL | +-------------+---------------+----------------------------+--------------------+---------------+ drop table if exists t1; diff --git a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_nullif_ifnull.result b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_nullif_ifnull.result index a43336319..10fef4608 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_nullif_ifnull.result +++ b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_nullif_ifnull.result @@ -7562,7 +7562,7 @@ insert into t1 values('10:10:10'); select nullif(z0_test0,'中文字符') from t1; +---------------------------------+ -| nullif(z0_test0,'中文字符') | +| nullif(z0_test0,'中文字符') | +---------------------------------+ | NULL | | 123456 | @@ -7685,7 +7685,7 @@ select d1, d2, nullif(d1, null), nullif(null, d1), nullif(d2, null), nullif(null +---------------------+---------------------+---------------------+------------------+---------------------+------------------+ | d1 | d2 | nullif(d1, null) | nullif(null, d1) | nullif(d2, null) | nullif(null, d2) | +---------------------+---------------------+---------------------+------------------+---------------------+------------------+ -| 中文字符 | 中文字符 | 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 中文字符 | 中文字符 | NULL | 中文字符 | NULL | | 123456 | 123456 | 123456 | NULL | 123456 | NULL | | ABCabc | ABCabc | ABCabc | NULL | ABCabc | NULL | | 2020 | 2020 | 2020 | NULL | 2020 | NULL | @@ -7701,9 +7701,9 @@ select d1, c1, nullif(d1, c1), nullif(c1, d1) from t1, t2 order by d1, c1; | NULL | NULL | NULL | NULL | | NULL | 1 | NULL | 1 | | NULL | 123456 | NULL | 123456 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 1 | NULL | NULL | -| 中文字符 | 123456 | 中文字符 | 123456 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 1 | NULL | NULL | +| 中文字符 | 123456 | 中文字符 | 123456 | | 123456 | NULL | 123456 | NULL | | 123456 | 1 | 123456 | 1 | | 123456 | 123456 | 123456 | 123456 | @@ -7730,9 +7730,9 @@ select d1, c2, nullif(d1, c2), nullif(c2, d1) from t1, t2 order by d1, c1; | NULL | NULL | NULL | NULL | | NULL | 2 | NULL | 2 | | NULL | 123456 | NULL | 123456 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 2 | 中文字符 | 2 | -| 中文字符 | 123456 | 中文字符 | 123456 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 2 | 中文字符 | 2 | +| 中文字符 | 123456 | 中文字符 | 123456 | | 123456 | NULL | 123456 | NULL | | 123456 | 2 | NULL | NULL | | 123456 | 123456 | 123456 | 123456 | @@ -7759,9 +7759,9 @@ select d1, c3, nullif(d1, c3), nullif(c3, d1) from t1, t2 order by d1, c1; | NULL | NULL | NULL | NULL | | NULL | 3 | NULL | 3 | | NULL | 123456 | NULL | 123456 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 3 | 中文字符 | 3 | -| 中文字符 | 123456 | 中文字符 | 123456 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 3 | 中文字符 | 3 | +| 中文字符 | 123456 | 中文字符 | 123456 | | 123456 | NULL | 123456 | NULL | | 123456 | 3 | 123456 | 3 | | 123456 | 123456 | 123456 | 123456 | @@ -7788,9 +7788,9 @@ select d1, c4, nullif(d1, c4), nullif(c4, d1) from t1, t2 order by d1, c1; | NULL | NULL | NULL | NULL | | NULL | 2020-10-10 | NULL | 2020-10-10 | | NULL | 2020-12-12 | NULL | 2020-12-12 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 2020-10-10 | 中文字符 | 2020-10-10 | -| 中文字符 | 2020-12-12 | 中文字符 | 2020-12-12 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 2020-10-10 | 中文字符 | 2020-10-10 | +| 中文字符 | 2020-12-12 | 中文字符 | 2020-12-12 | | 123456 | NULL | 123456 | NULL | | 123456 | 2020-10-10 | 123456 | 2020-10-10 | | 123456 | 2020-12-12 | 123456 | 2020-12-12 | @@ -7817,9 +7817,9 @@ select d1, c5, nullif(d1, c5), nullif(c5, d1) from t1, t2 order by d1, c1; | NULL | NULL | NULL | NULL | | NULL | 2020-10-10 10:10:10 | NULL | 2020-10-10 10:10:10 | | NULL | 2020-12-12 10:10:10 | NULL | 2020-12-12 10:10:10 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 2020-10-10 10:10:10 | 中文字符 | 2020-10-10 10:10:10 | -| 中文字符 | 2020-12-12 10:10:10 | 中文字符 | 2020-12-12 10:10:10 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 2020-10-10 10:10:10 | 中文字符 | 2020-10-10 10:10:10 | +| 中文字符 | 2020-12-12 10:10:10 | 中文字符 | 2020-12-12 10:10:10 | | 123456 | NULL | 123456 | NULL | | 123456 | 2020-10-10 10:10:10 | 123456 | 2020-10-10 10:10:10 | | 123456 | 2020-12-12 10:10:10 | 123456 | 2020-12-12 10:10:10 | @@ -7846,9 +7846,9 @@ select d1, c6, nullif(d1, c6), nullif(c6, d1) from t1, t2 order by d1, c1; | NULL | NULL | NULL | NULL | | NULL | 10:10:10 | NULL | 10:10:10 | | NULL | 12:12:12 | NULL | 12:12:12 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 10:10:10 | 中文字符 | 10:10:10 | -| 中文字符 | 12:12:12 | 中文字符 | 12:12:12 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 10:10:10 | 中文字符 | 10:10:10 | +| 中文字符 | 12:12:12 | 中文字符 | 12:12:12 | | 123456 | NULL | 123456 | NULL | | 123456 | 10:10:10 | 123456 | 10:10:10 | | 123456 | 12:12:12 | 123456 | 12:12:12 | @@ -7875,9 +7875,9 @@ select d1, c7, nullif(d1, c7), nullif(c7, d1) from t1, t2 order by d1, c1; | NULL | NULL | NULL | NULL | | NULL | 2020 | NULL | 2020 | | NULL | 2022 | NULL | 2022 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 2020 | 中文字符 | 2020 | -| 中文字符 | 2022 | 中文字符 | 2022 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 2020 | 中文字符 | 2020 | +| 中文字符 | 2022 | 中文字符 | 2022 | | 123456 | NULL | 123456 | NULL | | 123456 | 2020 | 123456 | 2020 | | 123456 | 2022 | 123456 | 2022 | @@ -7902,28 +7902,28 @@ select d1, c8, nullif(d1, c8), nullif(c8, d1) from t1, t2 order by d1, c1; | d1 | c8 | nullif(d1, c8) | nullif(c8, d1) | +---------------------+--------------+---------------------+----------------+ | NULL | NULL | NULL | NULL | -| NULL | 中文字符 | NULL | 中文字符 | +| NULL | 中文字符 | NULL | 中文字符 | | NULL | ABCabc | NULL | ABCabc | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 中文字符 | NULL | NULL | -| 中文字符 | ABCabc | 中文字符 | ABCabc | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 中文字符 | NULL | NULL | +| 中文字符 | ABCabc | 中文字符 | ABCabc | | 123456 | NULL | 123456 | NULL | -| 123456 | 中文字符 | 123456 | 中文字符 | +| 123456 | 中文字符 | 123456 | 中文字符 | | 123456 | ABCabc | 123456 | ABCabc | | ABCabc | NULL | ABCabc | NULL | -| ABCabc | 中文字符 | ABCabc | 中文字符 | +| ABCabc | 中文字符 | ABCabc | 中文字符 | | ABCabc | ABCabc | NULL | NULL | | 2020 | NULL | 2020 | NULL | -| 2020 | 中文字符 | 2020 | 中文字符 | +| 2020 | 中文字符 | 2020 | 中文字符 | | 2020 | ABCabc | 2020 | ABCabc | | 2020-10-10 | NULL | 2020-10-10 | NULL | -| 2020-10-10 | 中文字符 | 2020-10-10 | 中文字符 | +| 2020-10-10 | 中文字符 | 2020-10-10 | 中文字符 | | 2020-10-10 | ABCabc | 2020-10-10 | ABCabc | | 2020-10-10 10:10:10 | NULL | 2020-10-10 10:10:10 | NULL | -| 2020-10-10 10:10:10 | 中文字符 | 2020-10-10 10:10:10 | 中文字符 | +| 2020-10-10 10:10:10 | 中文字符 | 2020-10-10 10:10:10 | 中文字符 | | 2020-10-10 10:10:10 | ABCabc | 2020-10-10 10:10:10 | ABCabc | | 10:10:10 | NULL | 10:10:10 | NULL | -| 10:10:10 | 中文字符 | 10:10:10 | 中文字符 | +| 10:10:10 | 中文字符 | 10:10:10 | 中文字符 | | 10:10:10 | ABCabc | 10:10:10 | ABCabc | +---------------------+--------------+---------------------+----------------+ @@ -7934,9 +7934,9 @@ select d2, c1, nullif(d2, c1), nullif(c1, d2) from t1, t2 order by d2, c1; | NULL | NULL | NULL | NULL | | NULL | 1 | NULL | 1 | | NULL | 123456 | NULL | 123456 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 1 | NULL | NULL | -| 中文字符 | 123456 | 中文字符 | 123456 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 1 | NULL | NULL | +| 中文字符 | 123456 | 中文字符 | 123456 | | 123456 | NULL | 123456 | NULL | | 123456 | 1 | 123456 | 1 | | 123456 | 123456 | 123456 | 123456 | @@ -7963,9 +7963,9 @@ select d2, c2, nullif(d2, c2), nullif(c2, d2) from t1, t2 order by d2, c1; | NULL | NULL | NULL | NULL | | NULL | 2 | NULL | 2 | | NULL | 123456 | NULL | 123456 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 2 | 中文字符 | 2 | -| 中文字符 | 123456 | 中文字符 | 123456 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 2 | 中文字符 | 2 | +| 中文字符 | 123456 | 中文字符 | 123456 | | 123456 | NULL | 123456 | NULL | | 123456 | 2 | NULL | NULL | | 123456 | 123456 | 123456 | 123456 | @@ -7992,9 +7992,9 @@ select d2, c3, nullif(d2, c3), nullif(c3, d2) from t1, t2 order by d2, c1; | NULL | NULL | NULL | NULL | | NULL | 3 | NULL | 3 | | NULL | 123456 | NULL | 123456 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 3 | 中文字符 | 3 | -| 中文字符 | 123456 | 中文字符 | 123456 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 3 | 中文字符 | 3 | +| 中文字符 | 123456 | 中文字符 | 123456 | | 123456 | NULL | 123456 | NULL | | 123456 | 3 | 123456 | 3 | | 123456 | 123456 | 123456 | 123456 | @@ -8021,9 +8021,9 @@ select d2, c4, nullif(d2, c4), nullif(c4, d2) from t1, t2 order by d2, c1; | NULL | NULL | NULL | NULL | | NULL | 2020-10-10 | NULL | 2020-10-10 | | NULL | 2020-12-12 | NULL | 2020-12-12 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 2020-10-10 | 中文字符 | 2020-10-10 | -| 中文字符 | 2020-12-12 | 中文字符 | 2020-12-12 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 2020-10-10 | 中文字符 | 2020-10-10 | +| 中文字符 | 2020-12-12 | 中文字符 | 2020-12-12 | | 123456 | NULL | 123456 | NULL | | 123456 | 2020-10-10 | 123456 | 2020-10-10 | | 123456 | 2020-12-12 | 123456 | 2020-12-12 | @@ -8050,9 +8050,9 @@ select d2, c5, nullif(d2, c5), nullif(c5, d2) from t1, t2 order by d2, c1; | NULL | NULL | NULL | NULL | | NULL | 2020-10-10 10:10:10 | NULL | 2020-10-10 10:10:10 | | NULL | 2020-12-12 10:10:10 | NULL | 2020-12-12 10:10:10 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 2020-10-10 10:10:10 | 中文字符 | 2020-10-10 10:10:10 | -| 中文字符 | 2020-12-12 10:10:10 | 中文字符 | 2020-12-12 10:10:10 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 2020-10-10 10:10:10 | 中文字符 | 2020-10-10 10:10:10 | +| 中文字符 | 2020-12-12 10:10:10 | 中文字符 | 2020-12-12 10:10:10 | | 123456 | NULL | 123456 | NULL | | 123456 | 2020-10-10 10:10:10 | 123456 | 2020-10-10 10:10:10 | | 123456 | 2020-12-12 10:10:10 | 123456 | 2020-12-12 10:10:10 | @@ -8079,9 +8079,9 @@ select d2, c6, nullif(d2, c6), nullif(c6, d2) from t1, t2 order by d2, c1; | NULL | NULL | NULL | NULL | | NULL | 10:10:10 | NULL | 10:10:10 | | NULL | 12:12:12 | NULL | 12:12:12 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 10:10:10 | 中文字符 | 10:10:10 | -| 中文字符 | 12:12:12 | 中文字符 | 12:12:12 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 10:10:10 | 中文字符 | 10:10:10 | +| 中文字符 | 12:12:12 | 中文字符 | 12:12:12 | | 123456 | NULL | 123456 | NULL | | 123456 | 10:10:10 | 123456 | 10:10:10 | | 123456 | 12:12:12 | 123456 | 12:12:12 | @@ -8108,9 +8108,9 @@ select d2, c7, nullif(d2, c7), nullif(c7, d2) from t1, t2 order by d2, c1; | NULL | NULL | NULL | NULL | | NULL | 2020 | NULL | 2020 | | NULL | 2022 | NULL | 2022 | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 2020 | 中文字符 | 2020 | -| 中文字符 | 2022 | 中文字符 | 2022 | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 2020 | 中文字符 | 2020 | +| 中文字符 | 2022 | 中文字符 | 2022 | | 123456 | NULL | 123456 | NULL | | 123456 | 2020 | 123456 | 2020 | | 123456 | 2022 | 123456 | 2022 | @@ -8135,27 +8135,27 @@ select d2, c8, nullif(d2, c8), nullif(c8, d2) from t1, t2 order by d2, c1; | d2 | c8 | nullif(d2, c8) | nullif(c8, d2) | +---------------------+--------------+---------------------+----------------+ | NULL | NULL | NULL | NULL | -| NULL | 中文字符 | NULL | 中文字符 | +| NULL | 中文字符 | NULL | 中文字符 | | NULL | ABCabc | NULL | ABCabc | -| 中文字符 | NULL | 中文字符 | NULL | -| 中文字符 | 中文字符 | NULL | NULL | -| 中文字符 | ABCabc | 中文字符 | ABCabc | +| 中文字符 | NULL | 中文字符 | NULL | +| 中文字符 | 中文字符 | NULL | NULL | +| 中文字符 | ABCabc | 中文字符 | ABCabc | | 123456 | NULL | 123456 | NULL | -| 123456 | 中文字符 | 123456 | 中文字符 | +| 123456 | 中文字符 | 123456 | 中文字符 | | 123456 | ABCabc | 123456 | ABCabc | | ABCabc | NULL | ABCabc | NULL | -| ABCabc | 中文字符 | ABCabc | 中文字符 | +| ABCabc | 中文字符 | ABCabc | 中文字符 | | ABCabc | ABCabc | NULL | NULL | | 2020 | NULL | 2020 | NULL | -| 2020 | 中文字符 | 2020 | 中文字符 | +| 2020 | 中文字符 | 2020 | 中文字符 | | 2020 | ABCabc | 2020 | ABCabc | | 2020-10-10 | NULL | 2020-10-10 | NULL | -| 2020-10-10 | 中文字符 | 2020-10-10 | 中文字符 | +| 2020-10-10 | 中文字符 | 2020-10-10 | 中文字符 | | 2020-10-10 | ABCabc | 2020-10-10 | ABCabc | | 2020-10-10 10:10:10 | NULL | 2020-10-10 10:10:10 | NULL | -| 2020-10-10 10:10:10 | 中文字符 | 2020-10-10 10:10:10 | 中文字符 | +| 2020-10-10 10:10:10 | 中文字符 | 2020-10-10 10:10:10 | 中文字符 | | 2020-10-10 10:10:10 | ABCabc | 2020-10-10 10:10:10 | ABCabc | | 10:10:10 | NULL | 10:10:10 | NULL | -| 10:10:10 | 中文字符 | 10:10:10 | 中文字符 | +| 10:10:10 | 中文字符 | 10:10:10 | 中文字符 | | 10:10:10 | ABCabc | 10:10:10 | ABCabc | +---------------------+--------------+---------------------+----------------+ diff --git a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_pad.result b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_pad.result index 681d42385..2fba629f1 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_pad.result +++ b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_pad.result @@ -6173,113 +6173,113 @@ set character_set_server=utf8; set character_set_connection=binary; select hex(lpad('钡', 2, 'c')); +--------------------------+ -| hex(lpad('钡', 2, 'c')) | +| hex(lpad('钡', 2, 'c')) | +--------------------------+ | E992 | +--------------------------+ set character_set_connection=utf8; select hex(lpad('钡', 2, 'c')); +--------------------------+ -| hex(lpad('钡', 2, 'c')) | +| hex(lpad('钡', 2, 'c')) | +--------------------------+ | 63E992A1 | +--------------------------+ select lpad('a', 1, '阿斯'), length(lpad('a', 1, '阿斯')) from dual; +------------------------+--------------------------------+ -| lpad('a', 1, '阿斯') | length(lpad('a', 1, '阿斯')) | +| lpad('a', 1, '阿斯') | length(lpad('a', 1, '阿斯')) | +------------------------+--------------------------------+ | a | 1 | +------------------------+--------------------------------+ select lpad('a', 2, '阿斯'), length(lpad('a', 2, '阿斯')) from dual; +------------------------+--------------------------------+ -| lpad('a', 2, '阿斯') | length(lpad('a', 2, '阿斯')) | +| lpad('a', 2, '阿斯') | length(lpad('a', 2, '阿斯')) | +------------------------+--------------------------------+ -| 阿a | 4 | +| 阿a | 4 | +------------------------+--------------------------------+ select lpad('a', 3, '阿斯'), length(lpad('a', 3, '阿斯')) from dual; +------------------------+--------------------------------+ -| lpad('a', 3, '阿斯') | length(lpad('a', 3, '阿斯')) | +| lpad('a', 3, '阿斯') | length(lpad('a', 3, '阿斯')) | +------------------------+--------------------------------+ -| 阿斯a | 7 | +| 阿斯a | 7 | +------------------------+--------------------------------+ select lpad('a', 4, '阿斯'), length(lpad('a', 4, '阿斯')) from dual; +------------------------+--------------------------------+ -| lpad('a', 4, '阿斯') | length(lpad('a', 4, '阿斯')) | +| lpad('a', 4, '阿斯') | length(lpad('a', 4, '阿斯')) | +------------------------+--------------------------------+ -| 阿斯阿a | 10 | +| 阿斯阿a | 10 | +------------------------+--------------------------------+ select lpad('a', 5, '阿斯'), length(lpad('a', 5, '阿斯')) from dual; +------------------------+--------------------------------+ -| lpad('a', 5, '阿斯') | length(lpad('a', 5, '阿斯')) | +| lpad('a', 5, '阿斯') | length(lpad('a', 5, '阿斯')) | +------------------------+--------------------------------+ -| 阿斯阿斯a | 13 | +| 阿斯阿斯a | 13 | +------------------------+--------------------------------+ select lpad('a', 6, '阿斯'), length(lpad('a', 6, '阿斯')) from dual; +------------------------+--------------------------------+ -| lpad('a', 6, '阿斯') | length(lpad('a', 6, '阿斯')) | +| lpad('a', 6, '阿斯') | length(lpad('a', 6, '阿斯')) | +------------------------+--------------------------------+ -| 阿斯阿斯阿a | 16 | +| 阿斯阿斯阿a | 16 | +------------------------+--------------------------------+ select lpad('a', 7, '阿斯'), length(lpad('a', 7, '阿斯')) from dual; +------------------------+--------------------------------+ -| lpad('a', 7, '阿斯') | length(lpad('a', 7, '阿斯')) | +| lpad('a', 7, '阿斯') | length(lpad('a', 7, '阿斯')) | +------------------------+--------------------------------+ -| 阿斯阿斯阿斯a | 19 | +| 阿斯阿斯阿斯a | 19 | +------------------------+--------------------------------+ select lpad('a', 8, '阿斯'), length(lpad('a', 8, '阿斯')) from dual; +------------------------+--------------------------------+ -| lpad('a', 8, '阿斯') | length(lpad('a', 8, '阿斯')) | +| lpad('a', 8, '阿斯') | length(lpad('a', 8, '阿斯')) | +------------------------+--------------------------------+ -| 阿斯阿斯阿斯阿a | 22 | +| 阿斯阿斯阿斯阿a | 22 | +------------------------+--------------------------------+ select rpad('a', 1, '阿斯'), length(rpad('a', 1, '阿斯')) from dual; +------------------------+--------------------------------+ -| rpad('a', 1, '阿斯') | length(rpad('a', 1, '阿斯')) | +| rpad('a', 1, '阿斯') | length(rpad('a', 1, '阿斯')) | +------------------------+--------------------------------+ | a | 1 | +------------------------+--------------------------------+ select rpad('a', 2, '阿斯'), length(rpad('a', 2, '阿斯')) from dual; +------------------------+--------------------------------+ -| rpad('a', 2, '阿斯') | length(rpad('a', 2, '阿斯')) | +| rpad('a', 2, '阿斯') | length(rpad('a', 2, '阿斯')) | +------------------------+--------------------------------+ -| a阿 | 4 | +| a阿 | 4 | +------------------------+--------------------------------+ select rpad('a', 3, '阿斯'), length(rpad('a', 3, '阿斯')) from dual; +------------------------+--------------------------------+ -| rpad('a', 3, '阿斯') | length(rpad('a', 3, '阿斯')) | +| rpad('a', 3, '阿斯') | length(rpad('a', 3, '阿斯')) | +------------------------+--------------------------------+ -| a阿斯 | 7 | +| a阿斯 | 7 | +------------------------+--------------------------------+ select rpad('a', 4, '阿斯'), length(rpad('a', 4, '阿斯')) from dual; +------------------------+--------------------------------+ -| rpad('a', 4, '阿斯') | length(rpad('a', 4, '阿斯')) | +| rpad('a', 4, '阿斯') | length(rpad('a', 4, '阿斯')) | +------------------------+--------------------------------+ -| a阿斯阿 | 10 | +| a阿斯阿 | 10 | +------------------------+--------------------------------+ select rpad('a', 5, '阿斯'), length(rpad('a', 5, '阿斯')) from dual; +------------------------+--------------------------------+ -| rpad('a', 5, '阿斯') | length(rpad('a', 5, '阿斯')) | +| rpad('a', 5, '阿斯') | length(rpad('a', 5, '阿斯')) | +------------------------+--------------------------------+ -| a阿斯阿斯 | 13 | +| a阿斯阿斯 | 13 | +------------------------+--------------------------------+ select rpad('a', 6, '阿斯'), length(rpad('a', 6, '阿斯')) from dual; +------------------------+--------------------------------+ -| rpad('a', 6, '阿斯') | length(rpad('a', 6, '阿斯')) | +| rpad('a', 6, '阿斯') | length(rpad('a', 6, '阿斯')) | +------------------------+--------------------------------+ -| a阿斯阿斯阿 | 16 | +| a阿斯阿斯阿 | 16 | +------------------------+--------------------------------+ select rpad('a', 7, '阿斯'), length(rpad('a', 7, '阿斯')) from dual; +------------------------+--------------------------------+ -| rpad('a', 7, '阿斯') | length(rpad('a', 7, '阿斯')) | +| rpad('a', 7, '阿斯') | length(rpad('a', 7, '阿斯')) | +------------------------+--------------------------------+ -| a阿斯阿斯阿斯 | 19 | +| a阿斯阿斯阿斯 | 19 | +------------------------+--------------------------------+ select rpad('a', 8, '阿斯'), length(rpad('a', 8, '阿斯')) from dual; +------------------------+--------------------------------+ -| rpad('a', 8, '阿斯') | length(rpad('a', 8, '阿斯')) | +| rpad('a', 8, '阿斯') | length(rpad('a', 8, '阿斯')) | +------------------------+--------------------------------+ -| a阿斯阿斯阿斯阿 | 22 | +| a阿斯阿斯阿斯阿 | 22 | +------------------------+--------------------------------+ diff --git a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_regexp_func.result b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_regexp_func.result index 7cd558aae..312cfb7ae 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_regexp_func.result +++ b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_regexp_func.result @@ -44,7 +44,7 @@ select regexp_like(123, 123) from dual; +-----------------------+ select regexp_like('我是好人', '.是.*') from dual; +---------------------------------------+ -| regexp_like('我是好人', '.是.*') | +| regexp_like('我是好人', '.是.*') | +---------------------------------------+ | 1 | +---------------------------------------+ @@ -118,7 +118,7 @@ select regexp_instr(12341834, 1.3, '1', '2', 1) from dual; +------------------------------------------+ select regexp_instr('我是好人', '是.') from dual; +--------------------------------------+ -| regexp_instr('我是好人', '是.') | +| regexp_instr('我是好人', '是.') | +--------------------------------------+ | 2 | +--------------------------------------+ @@ -174,9 +174,9 @@ Warnings: Warning 1292 Truncated incorrect INTEGER value: '1.9' select regexp_replace('我是好人', '是.') from dual; +----------------------------------------+ -| regexp_replace('我是好人', '是.') | +| regexp_replace('我是好人', '是.') | +----------------------------------------+ -| 我人 | +| 我人 | +----------------------------------------+ select regexp_replace('abcadef', 'a.') from dual; @@ -270,8 +270,8 @@ select regexp_replace(12341834, 1.3, 99, '1', '2') from dual; +---------------------------------------------+ select regexp_replace('我是好人', '是.', '.....') from dual; +-------------------------------------------------+ -| regexp_replace('我是好人', '是.', '.....') | +| regexp_replace('我是好人', '是.', '.....') | +-------------------------------------------------+ -| 我.....人 | +| 我.....人 | +-------------------------------------------------+ diff --git a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_trim.result b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_trim.result index 9ebcae951..781d25195 100644 --- a/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_trim.result +++ b/tools/deploy/mysql_test/test_suite/static_engine/r/mysql/expr_trim.result @@ -170,13 +170,13 @@ drop table t1; select SUBSTRING( TRIM( BOTH CONVERT( 'a', BINARY( 0 ) ) FROM '+-Ã÷﹢﹣±/= â¥â' ) , 1 ,20) ; +-------------------------------------------------------------------------------------------------------+ -| SUBSTRING( TRIM( BOTH CONVERT( 'a', BINARY( 0 ) ) FROM '+-Ã÷﹢﹣±/= â¥â' ) , 1 ,20) | +| SUBSTRING( TRIM( BOTH CONVERT( 'a', BINARY( 0 ) ) FROM '+-Ã÷﹢﹣±/= â¥â' ) , 1 ,20) | +-------------------------------------------------------------------------------------------------------+ -| +-Ã÷﹢﹣±/= â¥â | +| +-Ã÷﹢﹣±/= â¥â | +-------------------------------------------------------------------------------------------------------+ select collation(TRIM( BOTH _binary'a' FROM '+-Ã÷﹢﹣±/= â¥â' )) ; +-----------------------------------------------------------------------------+ -| collation(TRIM( BOTH _binary'a' FROM '+-Ã÷﹢﹣±/= â¥â' )) | +| collation(TRIM( BOTH _binary'a' FROM '+-Ã÷﹢﹣±/= â¥â' )) | +-----------------------------------------------------------------------------+ | utf8mb4_general_ci | +-----------------------------------------------------------------------------+ diff --git a/unittest/libobcdc/log_generator.h b/unittest/libobcdc/log_generator.h index c30911e4f..20baafd18 100644 --- a/unittest/libobcdc/log_generator.h +++ b/unittest/libobcdc/log_generator.h @@ -199,7 +199,7 @@ private: int ObTxLogBlockBuilder::next_log_block() { int ret = OB_SUCCESS; - ObTxLogBlockHeader block_header(cluster_id_, log_entry_no_, tx_id_); + ObTxLogBlockHeader block_header(cluster_id_, log_entry_no_, tx_id_, common::ObAddr()); tx_log_block_.reset(); if (OB_FAIL(tx_log_block_.init(tx_id_, block_header))) { diff --git a/unittest/storage/tx/it/CMakeLists.txt b/unittest/storage/tx/it/CMakeLists.txt index fc8ce9e2b..eb67c5660 100644 --- a/unittest/storage/tx/it/CMakeLists.txt +++ b/unittest/storage/tx/it/CMakeLists.txt @@ -9,6 +9,7 @@ endfunction() tx_it_test(test_tx) tx_it_test(test_tx_free_route) +tx_it_test(test_tx_ctx) #tx_it_test(test_tx_perf) diff --git a/unittest/storage/tx/it/test_tx_ctx.cpp b/unittest/storage/tx/it/test_tx_ctx.cpp new file mode 100644 index 000000000..f30532071 --- /dev/null +++ b/unittest/storage/tx/it/test_tx_ctx.cpp @@ -0,0 +1,157 @@ +#include +#include +#define private public +#define protected public +#include "storage/tx/ob_trans_define.h" +#include "storage/tx/ob_trans_part_ctx.h" +#include "storage/tx/ob_trans_service.h" +#define USING_LOG_PREFIX TRANS +#include "../mock_utils/async_util.h" +#include "test_tx_dsl.h" +#include "tx_node.h" +namespace oceanbase +{ +using namespace ::testing; +using namespace transaction; +using namespace share; + +namespace concurrent_control +{ +int check_sequence_set_violation(const concurrent_control::ObWriteFlag, + const int64_t, + const ObTransID, + const blocksstable::ObDmlFlag, + const int64_t, + const ObTransID, + const blocksstable::ObDmlFlag, + const int64_t) +{ + return OB_SUCCESS; +} +} // namespace concurrent_control + +class ObTestTxCtx : public ::testing::Test +{ +public: + virtual void SetUp() override + { + ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(1001); + const uint64_t tv = ObTimeUtility::current_time(); + ObCurTraceId::set(&tv); + GCONF._ob_trans_rpc_timeout = 500; + ObClockGenerator::init(); + const testing::TestInfo *const test_info = + testing::UnitTest::GetInstance()->current_test_info(); + auto test_name = test_info->name(); + _TRANS_LOG(INFO, ">>>> starting test : %s", test_name); + } + virtual void TearDown() override + { + const testing::TestInfo *const test_info = + testing::UnitTest::GetInstance()->current_test_info(); + auto test_name = test_info->name(); + _TRANS_LOG(INFO, ">>>> tearDown test : %s", test_name); + ObClockGenerator::destroy(); + ObMallocAllocator::get_instance()->recycle_tenant_allocator(1001); + } + MsgBus bus_; +}; + +TEST_F(ObTestTxCtx, DelayAbort) +{ + ObTxPartList backup_parts; + START_ONE_TX_NODE(n1); + PREPARE_TX_PARAM(tx_param); + PREPARE_TX(n1, tx); + { // prepare snapshot for write + ObTxReadSnapshot snapshot; + ASSERT_EQ(OB_SUCCESS, + n1->get_read_snapshot(tx, tx_param.isolation_, n1->ts_after_ms(100), snapshot)); + CREATE_IMPLICIT_SAVEPOINT(n1, tx, tx_param, sp1); + ASSERT_EQ(OB_SUCCESS, n1->create_implicit_savepoint(tx, tx_param, sp1)); + ASSERT_EQ(OB_SUCCESS, n1->write(tx, snapshot, 100, 112)); + } + ASSERT_EQ(OB_SUCCESS, backup_parts.assign(tx.parts_)); + tx.parts_.reset(); + + ObLSTxCtxMgr *ls_tx_ctx_mgr = nullptr; + ObPartTransCtx *tx_ctx = nullptr; + ASSERT_EQ(OB_SUCCESS, n1->txs_.tx_ctx_mgr_.get_ls_tx_ctx_mgr(n1->ls_id_, ls_tx_ctx_mgr)); + + { + ASSERT_EQ(OB_SUCCESS, ls_tx_ctx_mgr->get_tx_ctx(tx.tx_id_, false /*for_replay*/, tx_ctx)); + GCONF._private_buffer_size = 1; + // ASSERT_EQ(OB_SUCCESS, tx_ctx->submit_log_impl_(ObTxLogType::TX_REDO_LOG)); + ASSERT_EQ(OB_SUCCESS, tx_ctx->submit_redo_log(false /*is_freeze*/)); + TRANS_LOG(INFO, "[TEST] after submit redo", K(tx_ctx->trans_id_), + K(tx_ctx->exec_info_.max_applied_log_ts_)); + n1->wait_all_redolog_applied(); + TRANS_LOG(INFO, "[TEST] after on_success redo", K(tx_ctx->trans_id_), + K(tx_ctx->exec_info_.max_applied_log_ts_)); + ASSERT_EQ(true, tx_ctx->exec_info_.redo_lsns_.count() > 0); + ASSERT_EQ(true, tx_ctx->exec_info_.max_applied_log_ts_.is_valid()); + ASSERT_EQ(ObTxState::INIT, tx_ctx->exec_info_.state_); + ASSERT_EQ(false, tx_ctx->is_follower_()); + ASSERT_EQ(OB_SUCCESS, ls_tx_ctx_mgr->revert_tx_ctx(tx_ctx)); + } + + ls_tx_ctx_mgr->switch_to_follower_forcedly(); + + { + ASSERT_EQ(OB_SUCCESS, ls_tx_ctx_mgr->get_tx_ctx(tx.tx_id_, true /*for_replay*/, tx_ctx)); + ASSERT_EQ(true, tx_ctx->exec_info_.redo_lsns_.count() > 0); + ASSERT_EQ(true, tx_ctx->exec_info_.max_applied_log_ts_.is_valid()); + ASSERT_EQ(ObTxState::INIT, tx_ctx->exec_info_.state_); + ASSERT_EQ(true, tx_ctx->is_follower_()); + ASSERT_EQ(OB_SUCCESS, ls_tx_ctx_mgr->revert_tx_ctx(tx_ctx)); + } + + ASSERT_EQ(OB_SUCCESS, ls_tx_ctx_mgr->switch_to_leader()); + n1->wait_all_redolog_applied(); + + { + ASSERT_EQ(OB_SUCCESS, ls_tx_ctx_mgr->get_tx_ctx(tx.tx_id_, false /*for_replay*/, tx_ctx)); + TRANS_LOG(INFO, "[TEST] after leader takeover", K(tx_ctx->trans_id_), + K(tx_ctx->exec_info_.state_), K(tx_ctx->exec_info_.max_applied_log_ts_)); + ASSERT_EQ(true, tx_ctx->exec_info_.redo_lsns_.count() > 0); + ASSERT_EQ(true, tx_ctx->exec_info_.max_applied_log_ts_.is_valid()); + ASSERT_EQ(true, tx_ctx->sub_state_.is_force_abort()); + ASSERT_EQ(false, tx_ctx->sub_state_.is_state_log_submitted()); + ASSERT_EQ(ObTxState::INIT, tx_ctx->exec_info_.state_); + ASSERT_EQ(false, tx_ctx->is_follower_()); + ASSERT_EQ(OB_SUCCESS, ls_tx_ctx_mgr->revert_tx_ctx(tx_ctx)); + } + + { // prepare snapshot for write + ObTxReadSnapshot snapshot; + ASSERT_EQ(OB_SUCCESS, + n1->get_read_snapshot(tx, tx_param.isolation_, n1->ts_after_ms(100), snapshot)); + CREATE_IMPLICIT_SAVEPOINT(n1, tx, tx_param, sp2); + ASSERT_EQ(OB_SUCCESS, n1->create_implicit_savepoint(tx, tx_param, sp2)); + ASSERT_EQ(OB_TRANS_KILLED, n1->write(tx, snapshot, 1110, 1120)); + } + + ASSERT_EQ(OB_SUCCESS, tx.parts_.assign(backup_parts)); + ASSERT_EQ(OB_TRANS_KILLED, n1->commit_tx(tx, n1->ts_after_ms(500))); + ASSERT_EQ(OB_SUCCESS, n1->release_tx(tx)); + + ASSERT_EQ(OB_SUCCESS, n1->wait_all_tx_ctx_is_destoryed()); + ASSERT_EQ(OB_SUCCESS, n1->txs_.tx_ctx_mgr_.revert_ls_tx_ctx_mgr(ls_tx_ctx_mgr)); +} +} // namespace oceanbase + +int main(int argc, char **argv) +{ + int64_t tx_id = 21533427; + uint64_t h = murmurhash(&tx_id, sizeof(tx_id), 0); + system("rm -rf test_tx_ctx*.log*"); + ObLogger &logger = ObLogger::get_logger(); + logger.set_file_name("test_tx_ctx.log", true, false, + "test_tx_ctx_rs.log", // rs + "test_tx_ctx_election.log", // election + "test_tx_ctx_audit.log"); // audit + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + ::testing::InitGoogleTest(&argc, argv); + TRANS_LOG(INFO, "mmhash:", K(h)); + return RUN_ALL_TESTS(); +} diff --git a/unittest/storage/tx/test_ob_tx_log.cpp b/unittest/storage/tx/test_ob_tx_log.cpp index 2752a0e21..d6a747129 100644 --- a/unittest/storage/tx/test_ob_tx_log.cpp +++ b/unittest/storage/tx/test_ob_tx_log.cpp @@ -112,7 +112,7 @@ TEST_F(TestObTxLog, tx_log_block_header) int64_t pos = 0; ObTxLogBlock fill_block, replay_block; - ObTxLogBlockHeader fill_block_header(TEST_ORG_CLUSTER_ID, TEST_LOG_ENTRY_NO, ObTransID(TEST_TX_ID)); + ObTxLogBlockHeader fill_block_header(TEST_ORG_CLUSTER_ID, TEST_LOG_ENTRY_NO, ObTransID(TEST_TX_ID), TEST_ADDR); ASSERT_EQ(OB_SUCCESS, fill_block.init(TEST_TX_ID, fill_block_header)); // check log_block_header @@ -205,7 +205,7 @@ TEST_F(TestObTxLog, tx_log_body_except_redo) ObTxAbortLog fill_abort(TEST_TX_BUFFER_NODE_ARRAY); ObTxRecordLog fill_record(TEST_LOG_OFFSET, TEST_LOG_OFFSET_ARRY); - ObTxLogBlockHeader header(TEST_ORG_CLUSTER_ID, TEST_LOG_ENTRY_NO, ObTransID(TEST_TX_ID)); + ObTxLogBlockHeader header(TEST_ORG_CLUSTER_ID, TEST_LOG_ENTRY_NO, ObTransID(TEST_TX_ID), TEST_ADDR); ASSERT_EQ(OB_SUCCESS, fill_block.init(TEST_TX_ID, header)); ASSERT_EQ(OB_SUCCESS, fill_block.add_new_log(fill_active_state)); ASSERT_EQ(OB_SUCCESS, fill_block.add_new_log(fill_commit_state)); @@ -320,7 +320,7 @@ TEST_F(TestObTxLog, tx_log_body_redo) TEST_LOG_OFFSET, TEST_INFO_ARRAY); - ObTxLogBlockHeader fill_block_header(TEST_ORG_CLUSTER_ID, TEST_LOG_ENTRY_NO, ObTransID(TEST_TX_ID)); + ObTxLogBlockHeader fill_block_header(TEST_ORG_CLUSTER_ID, TEST_LOG_ENTRY_NO, ObTransID(TEST_TX_ID), TEST_ADDR); ASSERT_EQ(OB_SUCCESS, fill_block.init(TEST_TX_ID, fill_block_header)); ObString TEST_MUTATOR_BUF("FFF"); @@ -506,6 +506,8 @@ TEST_F(TestObTxLog, test_default_log_deserialize) replay_member_cnt++; EXPECT_EQ(fill_block_header.get_tx_id().get_id(), replay_block_header.get_tx_id().get_id()); replay_member_cnt++; + EXPECT_EQ(fill_block_header.get_scheduler(), replay_block_header.get_scheduler()); + replay_member_cnt++; EXPECT_EQ(replay_member_cnt, fill_member_cnt); ObTxActiveInfoLogTempRef active_temp_ref; @@ -686,8 +688,8 @@ void test_big_commit_info_log(int64_t log_size) TEST_IS_DUP, TEST_CAN_ELR, TEST_TRACE_ID_STR, TEST_TRCE_INFO, TEST_LOG_OFFSET, TEST_BIG_REDO_LSN_ARRAY, TEST_LS_ARRAY, TEST_CLUSTER_VERSION, TEST_XID); - ObTxLogBlockHeader fill_block_header(TEST_ORG_CLUSTER_ID, TEST_LOG_ENTRY_NO, - ObTransID(TEST_TX_ID)); + ObTxLogBlockHeader + fill_block_header(TEST_ORG_CLUSTER_ID, TEST_LOG_ENTRY_NO, ObTransID(TEST_TX_ID), TEST_ADDR); ASSERT_EQ(OB_SUCCESS, fill_block.init(TEST_TX_ID, fill_block_header)); ASSERT_EQ(OB_LOG_TOO_LARGE, fill_block.add_new_log(fill_commit_state, &fill_big_segment));