diff --git a/src/rootserver/ob_split_partition_helper.cpp b/src/rootserver/ob_split_partition_helper.cpp index a07cb924a..1dfa093d7 100644 --- a/src/rootserver/ob_split_partition_helper.cpp +++ b/src/rootserver/ob_split_partition_helper.cpp @@ -452,7 +452,9 @@ int ObSplitPartitionHelper::prepare_dst_tablet_creator_( const int64_t split_cnt = dst_tablet_ids.at(0).count(); const int64_t table_cnt = inc_table_schemas.count(); bool is_oracle_mode = false; - if (OB_UNLIKELY(create_commit_versions.count() != table_cnt || dst_tablet_ids.count() != table_cnt)) { + if (OB_FAIL(check_mem_usage_for_split_(tenant_id, split_cnt))) { + LOG_WARN("failed to check memory usage", K(ret)); + } else if (OB_UNLIKELY(create_commit_versions.count() != table_cnt || dst_tablet_ids.count() != table_cnt)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arg", K(ret), K(table_cnt), K(create_commit_versions), K(dst_tablet_ids)); } else if (OB_FAIL(data_table_schema.check_if_oracle_compat_mode(is_oracle_mode))) { @@ -955,6 +957,62 @@ int ObSplitPartitionHelper::start_dst_( return ret; } +int ObSplitPartitionHelper::check_mem_usage_for_split_( + const uint64_t tenant_id, + const int64_t dst_tablets_number) +{ + int ret = OB_SUCCESS; + share::ObUnitTableOperator unit_op; + common::ObSEArray pools; + common::ObSEArray unit_config_ids; + common::ObSEArray unit_configs; + + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || dst_tablets_number < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(dst_tablets_number)); + } else if (dst_tablets_number > OB_MAX_SPLIT_PER_ROUND) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("the number of destined split tablets greater than 8192 is not supported", K(ret)); + LOG_USER_WARN(OB_NOT_SUPPORTED, "the number of destined split tablets greater than 8192 is"); + } else if (OB_FAIL(unit_op.init(*GCTX.sql_proxy_))) { + LOG_WARN("failed to init proxy", K(ret)); + } else if (OB_FAIL(unit_op.get_resource_pools(tenant_id, pools))) { + LOG_WARN("failed to get resource pool", K(ret), K(tenant_id)); + } else if (pools.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected empty pool", K(ret), K(pools), K(tenant_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < pools.count(); ++i) { + const share::ObResourcePool &pool = pools.at(i); + if OB_FAIL(unit_config_ids.push_back(pool.unit_config_id_)) { + LOG_WARN("failed to push back into unit_config_ids"); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(unit_op.get_unit_configs(unit_config_ids, unit_configs))) { + LOG_WARN("failed to get unit configs"); + } else if (unit_configs.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unit_configs should not be empty", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < unit_configs.count(); ++i) { + ObUnitConfig & u_config = unit_configs.at(i); + const double percent_mem_for_split = 0.2; + /* + tenant memory | maximum num of dst tablets + 2GB 51 + 4GB 102 + ...... + */ + if (u_config.memory_size() * percent_mem_for_split < (dst_tablets_number * MEMORY_USAGE_SPLIT_PER_DST)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("the memory usage of split greater than the memory limit for split", K(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "the memory usage of split greater than memory limit for split is"); + } + } + return ret; +} + int ObSplitPartitionHelper::clean_split_src_and_dst_tablet( const obrpc::ObCleanSplittedTabletArg &arg, const int64_t auto_part_size, diff --git a/src/rootserver/ob_split_partition_helper.h b/src/rootserver/ob_split_partition_helper.h index 8db5da901..12c2e9bd8 100644 --- a/src/rootserver/ob_split_partition_helper.h +++ b/src/rootserver/ob_split_partition_helper.h @@ -132,6 +132,9 @@ private: storage::ObTabletSplitMdsArg &start_dst_arg, ObTabletCreator *&tablet_creator, ObMySQLTransaction &trans); + static int check_mem_usage_for_split_( + const uint64_t tenant_id, + const int64_t dst_tablets_number); private: ObDDLSQLTransaction &trans_; @@ -142,6 +145,8 @@ private: share::ObDDLType split_type_; const static int64_t MYSQL_MAX_NUM_TABLETS_IN_TABLE = 8L * 1024L; const static int64_t ORACLE_MAX_NUM_TABLETS_IN_TABLE = 1024L * 1024L - 1L; + const static int64_t OB_MAX_SPLIT_PER_ROUND = 8L * 1024L; + const static int64_t MEMORY_USAGE_SPLIT_PER_DST = 8L * 1024L * 1024L; const common::ObIArray &new_table_schemas_; const common::ObIArray &upd_table_schemas_; const common::ObIArray &inc_table_schemas_;