Files
oceanbase/mittest/simple_server/rootservice/test_dup_table_partition_balance.cpp
2025-02-10 04:45:53 +00:00

122 lines
6.0 KiB
C++

/**
* Copyright (c) 2023 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#define USING_LOG_PREFIX SERVER
#define protected public
#define private public
#include "env/ob_simple_cluster_test_base.h"
#include "lib/ob_errno.h"
#include "lib/oblog/ob_log_module.h"
#include "rootserver/ob_partition_balance.h"
#include "share/ls/ob_ls_status_operator.h"
namespace oceanbase
{
using namespace unittest;
using namespace share;
using namespace share::schema;
using namespace common;
namespace rootserver
{
#define TEST_INFO(fmt, args...) FLOG_INFO("[TEST] " fmt, ##args)
#define EXE_SQL(...) \
ASSERT_EQ(OB_SUCCESS, sql.assign(__VA_ARGS__)); \
ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows));
class TestDupTablePartitionBalance : public ObSimpleClusterTestBase
{
public:
TestDupTablePartitionBalance() : ObSimpleClusterTestBase("test_dup_table_partition_balance") {}
};
TEST_F(TestDupTablePartitionBalance, create_tenant)
{
ASSERT_EQ(OB_SUCCESS, create_tenant());
ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2());
uint64_t tenant_id = OB_INVALID_TENANT_ID;
ASSERT_EQ(OB_SUCCESS, get_tenant_id(tenant_id));
TEST_INFO("create tenant finshed", K(tenant_id));
}
// prepare duplicate_scope changed table: 9 normal->dup, 9 dup->normal
TEST_F(TestDupTablePartitionBalance, prepare_dup_change_table)
{
ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2();
ObSqlString sql;
ObSqlString create_sql;
int64_t affected_rows = 0;
EXE_SQL("create table normal_1(c1 int, c2 int, c3 longtext, index(c1) local, index(c2) global)");
EXE_SQL("create table normal_2(c1 int, c2 int, c3 longtext, index(c1) local, index(c2) global) partition by hash(c1) partitions 2");
EXE_SQL("create table normal_3(c1 int, c2 int, c3 longtext, index(c1) local, index(c2) global) partition by range(c1) subpartition by hash(c1) subpartitions 2 (partition p1 values less than (100), partition p2 values less than MAXVALUE)");
EXE_SQL("alter table normal_1 duplicate_scope='cluster'"); // need transfer part: 1 normal_part (the global index of nonpart table is actually local index)
EXE_SQL("alter table normal_2 duplicate_scope='cluster'"); // need transfer part: 2 normal_part + 1 global_index
EXE_SQL("alter table normal_3 duplicate_scope='cluster'"); // need transfer part: 4 normal_part + 1 global_index
EXE_SQL("create table dup_1(c1 int, c2 int, c3 longtext, index(c1) local, index(c2) global) duplicate_scope = 'cluster'");
EXE_SQL("create table dup_2(c1 int, c2 int, c3 longtext, index(c1) local, index(c2) global) duplicate_scope = 'cluster' partition by hash(c1) partitions 2");
EXE_SQL("create table dup_3(c1 int, c2 int, c3 longtext, index(c1) local, index(c2) global) duplicate_scope = 'cluster' partition by range(c1) subpartition by hash(c1) subpartitions 2 (partition p1 values less than (100), partition p2 values less than MAXVALUE)");
EXE_SQL("alter table dup_1 duplicate_scope='none'"); // need transfer part: 1 normal_part (the global index of nonpart table is actually local_index)
EXE_SQL("alter table dup_2 duplicate_scope='none'"); // need transfer part: 2 normal_part + 1 global_index
EXE_SQL("create tablegroup tg1 sharding = 'NONE'");
EXE_SQL("alter table dup_3 duplicate_scope='none' tablegroup='tg1'"); // need transfer part: 4 normal_part + 1 global_index
TEST_INFO("prepare dup change table finished");
}
TEST_F(TestDupTablePartitionBalance, verify_need_transfer_part_map)
{
int ret = OB_SUCCESS;
uint64_t tenant_id = OB_INVALID_TENANT_ID;
ASSERT_EQ(OB_SUCCESS, get_tenant_id(tenant_id));
ObMySQLProxy &inner_proxy = get_curr_observer().get_mysql_proxy();
// get dup ls id
ObLSID dup_ls_id;
ObLSStatusOperator status_op;
ObLSStatusInfo dup_ls_status_info;
ASSERT_EQ(OB_SUCCESS, status_op.get_duplicate_ls_status_info(tenant_id, inner_proxy, dup_ls_status_info));
dup_ls_id = dup_ls_status_info.get_ls_id();
// do check
ObTenantSwitchGuard guard;
ASSERT_EQ(OB_SUCCESS, guard.switch_to(tenant_id));
ObPartitionBalance part_balance;
ASSERT_EQ(OB_SUCCESS, part_balance.init(tenant_id, GCTX.schema_service_, &inner_proxy, 1, 1, ObPartitionBalance::GEN_TRANSFER_TASK));
ASSERT_EQ(OB_SUCCESS, part_balance.process());
// verify dup change part_map: 9 normal->dup, 9 dup->normal
ASSERT_TRUE(1 == part_balance.job_generator_.normal_to_dup_part_map_.size() && 1 == part_balance.job_generator_.dup_to_normal_part_map_.size());
for (auto iter = part_balance.job_generator_.normal_to_dup_part_map_.begin(); iter != part_balance.job_generator_.normal_to_dup_part_map_.end(); iter++) {
ASSERT_TRUE(dup_ls_id != iter->first.get_src_ls_id() && dup_ls_id == iter->first.get_dest_ls_id());
ASSERT_TRUE(9 == iter->second.count());
TEST_INFO("normal_to_dup_part:", "task_key", iter->first, "part_cnt", iter->second.count(), "part_list", iter->second);
}
for (auto iter = part_balance.job_generator_.dup_to_normal_part_map_.begin(); iter != part_balance.job_generator_.dup_to_normal_part_map_.end(); iter++) {
ASSERT_TRUE(dup_ls_id == iter->first.get_src_ls_id() && dup_ls_id != iter->first.get_dest_ls_id());
ASSERT_TRUE(9 == iter->second.count());
TEST_INFO("dup_to_normal_part:", "task_key", iter->first, "part_cnt", iter->second.count(), "part_list", iter->second);
}
}
} // namespace share
} // namespace oceanbase
int main(int argc, char **argv)
{
oceanbase::unittest::init_log_and_gtest(argc, argv);
OB_LOGGER.set_log_level("INFO");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}