diff --git a/deps/oblib/src/lib/hash/ob_link_hashmap.h b/deps/oblib/src/lib/hash/ob_link_hashmap.h index 3b74891c01..783b04b341 100644 --- a/deps/oblib/src/lib/hash/ob_link_hashmap.h +++ b/deps/oblib/src/lib/hash/ob_link_hashmap.h @@ -386,6 +386,8 @@ public: return map(remove_if); } + const AllocHandle& get_alloc_handle() const { return alloc_handle_; } + private: DISALLOW_COPY_AND_ASSIGN(ObLinkHashMap); static int err_code_map(int err) diff --git a/deps/oblib/src/lib/mysqlclient/ob_mysql_result.h b/deps/oblib/src/lib/mysqlclient/ob_mysql_result.h index 8bba26a285..11a289fa36 100644 --- a/deps/oblib/src/lib/mysqlclient/ob_mysql_result.h +++ b/deps/oblib/src/lib/mysqlclient/ob_mysql_result.h @@ -1331,6 +1331,38 @@ }\ } +// timestamp -> int64_t + +#define EXTRACT_TIMESTAMP_FIELD_MYSQL(result, col_name, v) \ + if (OB_SUCC(ret)) \ + { \ + ObObj obj; \ + OZ ((result).get_obj(col_name, obj)); \ + if (OB_SUCC(ret)) { \ + if (obj.is_null()) { \ + ret = OB_ERR_NULL_VALUE; \ + } else { \ + OZ (obj.get_timestamp(v)); \ + } \ + } \ + } + +#define EXTRACT_TIMESTAMP_FIELD_MYSQL_SKIP_RET(result, col_name, v) \ + do { \ + ObObj obj; \ + OZ ((result).get_obj(col_name, obj)); \ + if (OB_SUCC(ret)) { \ + if (obj.is_null()) { \ + v = static_cast(0); \ + } else { \ + OZ (obj.get_timestamp(v)); \ + } \ + } else if (OB_ERR_COLUMN_NOT_FOUND == ret) { \ + ret = OB_SUCCESS; \ + v = static_cast(0); \ + } \ + } while (false) + namespace oceanbase { namespace common diff --git a/deps/oblib/src/lib/ob_define.h b/deps/oblib/src/lib/ob_define.h index 0ce3f51c9f..5ac907d75d 100644 --- a/deps/oblib/src/lib/ob_define.h +++ b/deps/oblib/src/lib/ob_define.h @@ -276,6 +276,8 @@ const int64_t OB_MAX_RESERVED_POINT_TYPE_LENGTH = 32; const int64_t OB_MAX_RESERVED_POINT_NAME_LENGTH = 128; const int64_t OB_MAX_EXTRA_ROWKEY_COLUMN_NUMBER = 2; //storage extra rowkey column number, it contains trans version column and sql sequence column const int64_t OB_INNER_MAX_ROWKEY_COLUMN_NUMBER = OB_MAX_ROWKEY_COLUMN_NUMBER + OB_MAX_EXTRA_ROWKEY_COLUMN_NUMBER; +const int64_t OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH = 64; +const int64_t OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE = 128; //for recybin diff --git a/deps/oblib/src/lib/ob_errno.h b/deps/oblib/src/lib/ob_errno.h index d04531743d..0afdeeaace 100644 --- a/deps/oblib/src/lib/ob_errno.h +++ b/deps/oblib/src/lib/ob_errno.h @@ -400,6 +400,13 @@ constexpr int OB_RESTORE_TENANT_FAILED = -9099; constexpr int OB_S3_ERROR = -9105; constexpr int OB_ERR_XML_PARSE = -9549; constexpr int OB_ERR_XSLT_PARSE = -9574; +constexpr int OB_TENANT_SNAPSHOT_NOT_EXIST = -12000; +constexpr int OB_TENANT_SNAPSHOT_EXIST = -12001; +constexpr int OB_TENANT_SNAPSHOT_TIMEOUT = -12002; +constexpr int OB_CLONE_TENANT_TIMEOUT = -12003; +constexpr int OB_ERR_CLONE_TENANT = -12004; +constexpr int OB_ERR_TENANT_SNAPSHOT = -12005; +constexpr int OB_TENANT_SNAPSHOT_LOCK_CONFLICT = -12006; constexpr int OB_MAX_RAISE_APPLICATION_ERROR = -20000; constexpr int OB_MIN_RAISE_APPLICATION_ERROR = -20999; diff --git a/deps/oblib/src/lib/wait_event/ob_wait_event.h b/deps/oblib/src/lib/wait_event/ob_wait_event.h index f75744fbb4..37850ab989 100644 --- a/deps/oblib/src/lib/wait_event/ob_wait_event.h +++ b/deps/oblib/src/lib/wait_event/ob_wait_event.h @@ -93,6 +93,7 @@ WAIT_EVENT_DEF(RESOURCE_SERVICE_LOCK_WAIT, 15263, "latch: resource_service lock WAIT_EVENT_DEF(RESOURCE_SERVICE_SWITCH_LOCK_WAIT, 15264, "latch:resource_service switch lock wait", "address", "number", "tries", CONCURRENCY, true, true) WAIT_EVENT_DEF(COLUMN_STORE_DDL_RESCAN_LOCK_WAIT, 15265, "latch: column store ddl rescan lock wait", "address", "number", "tries", CONCURRENCY, true, true) WAIT_EVENT_DEF(TABLET_DIRECT_LOAD_MGR_SCHEMA_WAIT, 15266, "latch: tablet direct load mgr schema wait", "address", "number", "tries", CONCURRENCY, true, true) +WAIT_EVENT_DEF(TENANT_SNAPSHOT_SERVICE_COND_WAIT, 15267, "tenant snapshot service condition wait", "address", "", "", CONCURRENCY, true, true) WAIT_EVENT_DEF(END_TRANS_WAIT, 16001, "wait end trans", "rollback", "trans_hash_value", "participant_count", COMMIT,false, false) WAIT_EVENT_DEF(START_STMT_WAIT, 16002, "wait start stmt", "trans_hash_value", "physic_plan_type", "participant_count", CLUSTER, false, false) WAIT_EVENT_DEF(END_STMT_WAIT, 16003, "wait end stmt", "rollback", "trans_hash_value", "physic_plan_type", CLUSTER, false, false) diff --git a/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h b/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h index 85770bd423..27f570b26a 100644 --- a/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h +++ b/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h @@ -1064,15 +1064,15 @@ PCODE_DEF(OB_DIRECT_LOAD_CONTROL, 0x1604) //PCODE_DEF(OB_REVOKE_ROUTINE, 0x1605) -// PCODE_DEF(OB_FLUSH_LS_ARCHIVE, 0x1606) +PCODE_DEF(OB_FLUSH_LS_ARCHIVE, 0x1606) // PCODE_DEF(OB_ACQUIRE_LS_TRANSFER_SCN, 0x1607) // create materialized view log // PCODE_DEF(OB_CREATE_MLOG, 0x1608) // 160A-160B for tenant clone -// PCODE_DEF(OB_CLONE_TENANT, 0x160A) -// PCODE_DEF(OB_CLONE_RESOURCE_POOL, 0x160B) +PCODE_DEF(OB_CLONE_TENANT, 0x160A) +PCODE_DEF(OB_CLONE_RESOURCE_POOL, 0x160B) //160Cfor transfer partition //PCODE_DEF(OB_TRABSFER_PARTITION, 0x160C) @@ -1095,9 +1095,9 @@ PCODE_DEF(OB_KILL_CLIENT_SESSION, 0x1614) PCODE_DEF(OB_CLIENT_SESSION_CONNECT_TIME, 0x1615) //tenant clone -//PCODE_DEF(OB_NOTIFY_CLONE_SCHEDULER, 0x1616) -//PCODE_DEF(OB_CLONE_KEY, 0x1617) -//PCODE_DEF(OB_TRIM_KEY_LIST, 0x1618) +PCODE_DEF(OB_NOTIFY_CLONE_SCHEDULER, 0x1616) +PCODE_DEF(OB_CLONE_KEY, 0x1617) +PCODE_DEF(OB_TRIM_KEY_LIST, 0x1618) //**** 注意:在此行之前增加新的RPC ID ****** // diff --git a/mittest/mtlenv/storage/CMakeLists.txt b/mittest/mtlenv/storage/CMakeLists.txt index 7c86b276c8..3b5cb61bda 100644 --- a/mittest/mtlenv/storage/CMakeLists.txt +++ b/mittest/mtlenv/storage/CMakeLists.txt @@ -24,6 +24,8 @@ storage_dml_unittest(test_tablet_mds_data test_tablet_mds_data.cpp) storage_dml_unittest(test_mds_data_read_write test_mds_data_read_write.cpp) storage_unittest(test_physical_copy_task test_physical_copy_task.cpp) storage_unittest(test_shared_block_reader_writer) +storage_dml_unittest(test_meta_snapshot test_meta_snapshot.cpp) +storage_dml_unittest(test_tablet_aggregated_info test_tablet_aggregated_info.cpp) # storage_dml_unittest(test_multi_version_merge_recycle) # storage_unittest(test_speed_limit test_speed_limit.cpp) storage_dml_unittest(test_tablet_block_id_list test_tablet_block_id_list.cpp) diff --git a/mittest/mtlenv/storage/test_ls_restore_task_mgr.cpp b/mittest/mtlenv/storage/test_ls_restore_task_mgr.cpp index 8256cbed52..95cd9c89f7 100644 --- a/mittest/mtlenv/storage/test_ls_restore_task_mgr.cpp +++ b/mittest/mtlenv/storage/test_ls_restore_task_mgr.cpp @@ -356,7 +356,7 @@ TEST_F(TestLSRestoreHandler, restore_start_1) EXPECT_EQ(ObLSRestoreStatus::Status::RESTORE_START, handler->state_handler_->ls_restore_status_); EXPECT_EQ(OB_SUCCESS, handler->state_handler_->do_restore()); EXPECT_EQ(OB_SUCCESS, ls->get_restore_status(status)); - EXPECT_EQ(ObLSRestoreStatus::Status::RESTORE_NONE, status); + EXPECT_EQ(ObLSRestoreStatus::Status::NONE, status); ls->set_restore_status(ObLSRestoreStatus(ObLSRestoreStatus::Status::RESTORE_START), rebuild_seq); ls->disable_replay(); LOG_INFO("TestLSRestoreHandler::restore_start_1 finish"); @@ -580,7 +580,7 @@ TEST_F(TestLSRestoreHandler, wait_state) EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->update_state_handle_()); EXPECT_EQ(ObLSRestoreStatus::Status::WAIT_RESTORE_MAJOR_DATA, ls->get_ls_restore_handler()->state_handler_->ls_restore_status_); EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->state_handler_->do_restore()); - EXPECT_EQ(ObLSRestoreStatus::Status::RESTORE_NONE, ls->ls_meta_.restore_status_); + EXPECT_EQ(ObLSRestoreStatus::Status::NONE, ls->ls_meta_.restore_status_); ob_role = ObRole::FOLLOWER; // follower in wait restore sys tablets @@ -650,13 +650,13 @@ TEST_F(TestLSRestoreHandler, wait_state) EXPECT_EQ(ObLSRestoreStatus::Status::QUICK_RESTORE_FINISH, ls->ls_meta_.restore_status_); // follower in wait restore major data - leader_status = ObLSRestoreStatus::Status::RESTORE_NONE; + leader_status = ObLSRestoreStatus::Status::NONE; ls->get_ls_restore_handler()->state_handler_ = nullptr; ls->ls_meta_.restore_status_ = ObLSRestoreStatus::Status::WAIT_RESTORE_MAJOR_DATA; EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->update_state_handle_()); EXPECT_EQ(ObLSRestoreStatus::Status::WAIT_RESTORE_MAJOR_DATA, ls->get_ls_restore_handler()->state_handler_->ls_restore_status_); EXPECT_EQ(OB_SUCCESS, ls->get_ls_restore_handler()->state_handler_->do_restore()); - EXPECT_EQ(ObLSRestoreStatus::Status::RESTORE_NONE, ls->ls_meta_.restore_status_); + EXPECT_EQ(ObLSRestoreStatus::Status::NONE, ls->ls_meta_.restore_status_); leader_status = ObLSRestoreStatus::Status::RESTORE_MAJOR_DATA; ls->ls_meta_.restore_status_ = ObLSRestoreStatus::Status::WAIT_RESTORE_MAJOR_DATA; diff --git a/mittest/mtlenv/storage/test_meta_snapshot.cpp b/mittest/mtlenv/storage/test_meta_snapshot.cpp new file mode 100644 index 0000000000..6dd424d330 --- /dev/null +++ b/mittest/mtlenv/storage/test_meta_snapshot.cpp @@ -0,0 +1,297 @@ +/** + * Copyright (c) 2021 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 +#include + +#define USING_LOG_PREFIX STORAGE + +#define protected public +#define private public +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h" +#include "storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h" +#include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" +#include "storage/tablet/ob_tablet_persister.h" + +namespace oceanbase +{ +namespace storage +{ +using namespace common; +using namespace blocksstable; + +class TestMetaSnapshot : public TestIndexBlockDataPrepare +{ +public: + TestMetaSnapshot(); + ~TestMetaSnapshot(); + virtual void TearDown(); + int persist_tablet(ObTabletHandle &new_tablet_handle); + int check_integrity( + const ObMetaDiskAddr &tablet_addr, + const ObTenantSnapshotID &snapshot_id, + const ObLSID &ls_id, + const ObTabletID &tablet_id); +}; + +TestMetaSnapshot::TestMetaSnapshot() + : TestIndexBlockDataPrepare( + "Test Meta Snapshot", + MINI_MERGE, + OB_DEFAULT_MACRO_BLOCK_SIZE, + 10000, + 65536) +{ +} + +TestMetaSnapshot::~TestMetaSnapshot() +{ +} + +void TestMetaSnapshot::TearDown() +{ + int ret = OB_SUCCESS; + ObSArray ids; + if (OB_FAIL(ObTenantMetaSnapshotHandler::get_all_tenant_snapshot(ids))) { + LOG_ERROR("fail to get tenant snapshot", K(ret)); + } else { + for (int i = 0; i < ids.count(); i++) { + if (OB_FAIL(ObTenantMetaSnapshotHandler::delete_tenant_snapshot(ids[i]))) { + LOG_ERROR("fail to delete tenant snapshot", K(ret), K(ids[i])); + } + } + } + TestIndexBlockDataPrepare::TearDown(); +} + +int TestMetaSnapshot::persist_tablet(ObTabletHandle &new_tablet_handle) +{ + int ret = OB_SUCCESS; + ObTabletID tablet_id(TestIndexBlockDataPrepare::tablet_id_); + ObLSID ls_id(ls_id_); + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ObMacroBlockHandle macro_handle; + + if (OB_FAIL(ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", K(ret), K(ls_id)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("fail to get tablet", K(ret), K(tablet_id)); + } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->get_shared_block_reader_writer().switch_block(macro_handle))) { + LOG_WARN("fail to switch shared meta block", K(ret)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*(tablet_handle.get_obj()), new_tablet_handle))) { + LOG_WARN("fail to persist and transform tablet", K(ret), K(tablet_handle)); + } else if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->compare_and_swap_tablet(ObTabletMapKey(ls_id, tablet_id), tablet_handle, new_tablet_handle))) { + LOG_WARN("fail to cas tablet", K(ret), K(ls_id), K(tablet_id), K(tablet_handle), K(new_tablet_handle)); + } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->get_shared_block_reader_writer().switch_block(macro_handle))) { + LOG_WARN("fail to switch shared meta block", K(ret)); + } + return ret; +} + +int TestMetaSnapshot::check_integrity( + const ObMetaDiskAddr &tablet_addr, + const ObTenantSnapshotID &snapshot_id, + const ObLSID &ls_id, + const ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + blocksstable::MacroBlockId tablet_meta_entry; + ObLinkedMacroBlockItemReader item_reader; + bool found = false; + + if (OB_FAIL(ObTenantMetaSnapshotHandler::get_ls_snapshot(snapshot_id, ls_id, tablet_meta_entry))) { + LOG_WARN("fail to get ls snapshot", K(ret), K(snapshot_id), K(ls_id)); + } else if (OB_FAIL(item_reader.init(tablet_meta_entry))) { + LOG_WARN("fail to init item reader", K(ret), K(tablet_meta_entry)); + } else { + ObUpdateTabletLog slog; + ObMetaDiskAddr addr; + while (OB_SUCC(ret)) { + char *item_buf = nullptr; + int64_t item_buf_len = 0; + int64_t pos = 0; + if (OB_FAIL(item_reader.get_next_item(item_buf, item_buf_len, addr))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to get next item", K(ret)); + } else { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("tablet snapshot doesn't exist", K(ret)); + } + } else if (OB_FAIL(slog.deserialize(item_buf, item_buf_len, pos))) { + LOG_WARN("fail to deserialize slog", K(ret)); + } else if (slog.tablet_id_ == tablet_id) { + if (slog.disk_addr_ != tablet_addr) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet disk doesn't match", K(ret), K(slog.disk_addr_), K(tablet_addr)); + } else { + found = true; + break; + } + } + } + } + + if (OB_SUCC(ret) && OB_UNLIKELY(!found)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("ls snapshot doesn't exist", K(ret)); + } + return ret; +} + +TEST_F(TestMetaSnapshot, test_create_delete) +{ + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + ObTenantSuperBlock super_block; + // test create snapshots + int64_t max_num = ObTenantSuperBlock::MAX_SNAPSHOT_NUM; + for (int i = 0; i < max_num - 1; i++) { + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_tenant_snapshot(ObTenantSnapshotID(i))); + } + ASSERT_NE(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_tenant_snapshot(ObTenantSnapshotID(1))); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_tenant_snapshot(ObTenantSnapshotID(max_num - 1))); + super_block = tenant->get_super_block(); + ASSERT_EQ(max_num, super_block.snapshot_cnt_); + ASSERT_NE(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_tenant_snapshot(ObTenantSnapshotID(34))); + + // test get all tenant snapshot + ObSArray ids; + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::get_all_tenant_snapshot(ids)); + ASSERT_EQ(max_num, ids.count()); + + // check snapshot + ObLSID single_ls_id(ls_id_); + ObTenantSnapshotMeta snapshot; + ObTenantSnapshotID snapshot_id(1); + share::SCN clog_max_scn; + ASSERT_EQ(OB_SUCCESS, super_block.get_snapshot(snapshot_id, snapshot)); + ASSERT_EQ(true, IS_EMPTY_BLOCK_LIST(snapshot.ls_meta_entry_)); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_single_ls_snapshot(snapshot_id, single_ls_id, clog_max_scn)); + super_block = tenant->get_super_block(); + ASSERT_EQ(OB_SUCCESS, super_block.get_snapshot(snapshot_id, snapshot)); + ASSERT_EQ(false, IS_EMPTY_BLOCK_LIST(snapshot.ls_meta_entry_)); + + // test find snapshot error + ObLSID ls_id(1); + MacroBlockId tablet_meta_entry; + ASSERT_NE(OB_SUCCESS, ObTenantMetaSnapshotHandler::get_ls_snapshot(ObTenantSnapshotID(34), ls_id, tablet_meta_entry)); + + // test delete snapshots + ASSERT_NE(OB_SUCCESS, ObTenantMetaSnapshotHandler::delete_tenant_snapshot(ObTenantSnapshotID(34))); + for (int i = 0; i < max_num; i++) { + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::delete_tenant_snapshot(ObTenantSnapshotID(i))); + super_block = tenant->get_super_block(); + ASSERT_EQ(max_num - i - 1, super_block.snapshot_cnt_); + } +} + +TEST_F(TestMetaSnapshot, test_ref_cnt) +{ + ObLSID ls_id(ls_id_); + + // persist tablet + int64_t ref_cnt = 0; + int64_t offset = 0; + int64_t size = 0; + ObBlockManager::BlockInfo block_info; + MacroBlockId table_store_id; + ObTabletHandle new_tablet_handle; + share::SCN clog_max_scn; + + ASSERT_EQ(OB_SUCCESS, persist_tablet(new_tablet_handle)); + ObTablet *new_tablet = new_tablet_handle.get_obj(); + ASSERT_EQ(OB_SUCCESS, new_tablet->table_store_addr_.addr_.get_block_addr(table_store_id, offset, size)); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, table_store_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(table_store_id, block_info)); + } + ref_cnt = block_info.ref_cnt_; + + // create snapshot and check ref cnt + ObTenantSnapshotID snapshot_id(1); + ASSERT_NE(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_single_ls_snapshot(snapshot_id, ls_id, clog_max_scn)); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_tenant_snapshot(snapshot_id)); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_single_ls_snapshot(snapshot_id, ls_id, clog_max_scn)); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, table_store_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(table_store_id, block_info)); + } + ASSERT_EQ(ref_cnt * 2, block_info.ref_cnt_); + + // delete snapshot and check ref cnt + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::delete_tenant_snapshot(snapshot_id)); + { + ObBucketHashWLockGuard lock_guard(OB_SERVER_BLOCK_MGR.bucket_lock_, table_store_id.hash()); + ASSERT_EQ(OB_SUCCESS, OB_SERVER_BLOCK_MGR.block_map_.get(table_store_id, block_info)); + } + ASSERT_EQ(ref_cnt, block_info.ref_cnt_); +} + +TEST_F(TestMetaSnapshot, test_create_integrity) +{ + int ret = OB_SUCCESS; + + // persist tablet + ObTabletHandle new_tablet_handle; + ObLSID ls_id(ls_id_); + ObTabletID tablet_id(TestIndexBlockDataPrepare::tablet_id_); + ASSERT_EQ(OB_SUCCESS, persist_tablet(new_tablet_handle)); + + // create snapshot and check integrity + blocksstable::MacroBlockId tablet_meta_entry; + ObTenantSnapshotID snapshot_id(1); + share::SCN clog_max_scn; + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_tenant_snapshot(snapshot_id)); + ASSERT_NE(OB_SUCCESS, check_integrity(new_tablet_handle.get_obj()->tablet_addr_, snapshot_id, ls_id, tablet_id)); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_single_ls_snapshot(snapshot_id, ls_id, clog_max_scn)); + ASSERT_EQ(OB_SUCCESS, check_integrity(new_tablet_handle.get_obj()->tablet_addr_, snapshot_id, ls_id, tablet_id)); +} + +TEST_F(TestMetaSnapshot, test_single_ls_snapshot) +{ + ObLSID ls_id(ls_id_); + ObTenantSnapshotID snapshot_id(1); + + // create tenant snapshot and delete ls snapshot + blocksstable::MacroBlockId tablet_meta_entry; + share::SCN clog_max_scn; + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_tenant_snapshot(snapshot_id)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTenantMetaSnapshotHandler::get_ls_snapshot(snapshot_id, ls_id, tablet_meta_entry)); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_single_ls_snapshot(snapshot_id, ls_id, clog_max_scn)); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::get_ls_snapshot(snapshot_id, ls_id, tablet_meta_entry)); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::delete_single_ls_snapshot(snapshot_id, ls_id)); + ASSERT_EQ(OB_ENTRY_NOT_EXIST, ObTenantMetaSnapshotHandler::get_ls_snapshot(snapshot_id, ls_id, tablet_meta_entry)); + + // create tablet and create single ls snapshot + ObTabletHandle new_tablet_handle; + ObTabletID tablet_id(TestIndexBlockDataPrepare::tablet_id_); + ASSERT_EQ(OB_SUCCESS, persist_tablet(new_tablet_handle)); + ASSERT_EQ(OB_SUCCESS, ObTenantMetaSnapshotHandler::create_single_ls_snapshot(snapshot_id, ls_id, clog_max_scn)); + + // check integrity + ASSERT_EQ(OB_SUCCESS, check_integrity(new_tablet_handle.get_obj()->tablet_addr_, snapshot_id, ls_id, tablet_id)); +} + +} +} + +int main(int argc, char **argv) +{ + system("rm -f test_meta_snapshot.log*"); + OB_LOGGER.set_file_name("test_meta_snapshot.log", true, true); + oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + oceanbase::common::ObClusterVersion::get_instance().init(CLUSTER_VERSION_4_2_0_0); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/mittest/mtlenv/storage/test_tablet_aggregated_info.cpp b/mittest/mtlenv/storage/test_tablet_aggregated_info.cpp new file mode 100644 index 0000000000..3322315cc0 --- /dev/null +++ b/mittest/mtlenv/storage/test_tablet_aggregated_info.cpp @@ -0,0 +1,97 @@ +/** + * Copyright (c) 2021 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 +#include + +#define USING_LOG_PREFIX STORAGE +#include + +#define protected public +#define private public + +#include "storage/tablet/ob_tablet.h" +#include "storage/ls/ob_ls.h" +#include "storage/ls/ob_ls_tablet_service.h" +#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" +#include "storage/tablet/ob_tablet_persister.h" +#include "mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h" +#include "storage/blocksstable/ob_block_manager.h" + +namespace oceanbase +{ +namespace storage +{ +using namespace common; +using namespace blocksstable; + +class TestTabletAggregatedInfo : public TestIndexBlockDataPrepare +{ +public: + TestTabletAggregatedInfo(); + ~TestTabletAggregatedInfo(); +}; + +TestTabletAggregatedInfo::TestTabletAggregatedInfo() + : TestIndexBlockDataPrepare( + "Test Tablet Aggregated Info", + MINI_MERGE, + OB_DEFAULT_MACRO_BLOCK_SIZE, + 10000, + 65536) +{ +} + +TestTabletAggregatedInfo::~TestTabletAggregatedInfo() +{ +} + +TEST_F(TestTabletAggregatedInfo, test_space_usage) +{ + ObTabletID tablet_id(TestIndexBlockDataPrepare::tablet_id_); + ObLSID ls_id(ls_id_); + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObLSService *ls_svr = MTL(ObLSService*); + ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); + ObTablet *tablet = tablet_handle.get_obj(); + + // check tablet's space_usage with empty major sstable + ObTabletHandle new_tablet_handle; + ASSERT_EQ(OB_SUCCESS, ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle)); + ObTabletSpaceUsage space_usage = new_tablet_handle.get_obj()->tablet_meta_.space_usage_; + ASSERT_EQ(0, space_usage.data_size_); + ASSERT_EQ(0, space_usage.shared_data_size_); + ASSERT_NE(0, space_usage.shared_meta_size_); + + // check tablet's space_usage without sstable + tablet->table_store_addr_.ptr_->major_tables_.reset(); + ASSERT_EQ(OB_SUCCESS, ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle)); + space_usage = new_tablet_handle.get_obj()->tablet_meta_.space_usage_; + ASSERT_EQ(0, space_usage.data_size_); + ASSERT_EQ(0, space_usage.shared_data_size_); + ASSERT_NE(0, space_usage.shared_meta_size_); +} + +} // storage +} // oceanbase + +int main(int argc, char **argv) +{ + system("rm -f test_tablet_aggregated_info.log*"); + OB_LOGGER.set_file_name("test_tablet_aggregated_info.log", true, true); + oceanbase::common::ObLogger::get_logger().set_log_level("INFO"); + oceanbase::common::ObClusterVersion::get_instance().init(CLUSTER_VERSION_4_2_0_0); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/mittest/mtlenv/storage/test_write_tablet_slog.cpp b/mittest/mtlenv/storage/test_write_tablet_slog.cpp index 537c0f51bc..a7af413dc4 100644 --- a/mittest/mtlenv/storage/test_write_tablet_slog.cpp +++ b/mittest/mtlenv/storage/test_write_tablet_slog.cpp @@ -27,7 +27,7 @@ #include "storage/init_basic_struct.h" #include "storage/test_tablet_helper.h" #include "storage/test_dml_common.h" -#include "observer/ob_server_startup_task_handler.h" +#include "storage/slog_ckpt/ob_tablet_replay_create_handler.h" #include "lib/oblog/ob_log.h" #include "share/ob_force_print_log.h" @@ -52,7 +52,9 @@ public: blocksstable::ObLogFileSpec log_file_spec_; share::ObLSID ls_id_; common::ObArenaAllocator allocator_; + static observer::ObStartupAccelTaskHandler startup_accel_handler_; }; +observer::ObStartupAccelTaskHandler TestWriteTabletSlog::startup_accel_handler_; TestWriteTabletSlog::TestWriteTabletSlog() : ls_id_(TEST_LS_ID) @@ -66,8 +68,8 @@ void TestWriteTabletSlog::SetUpTestCase() ASSERT_EQ(OB_SUCCESS, ret); ObServerCheckpointSlogHandler::get_instance().is_started_ = true; - ASSERT_EQ(OB_SUCCESS, SERVER_STARTUP_TASK_HANDLER.init()); - ASSERT_EQ(OB_SUCCESS, SERVER_STARTUP_TASK_HANDLER.start()); + ASSERT_EQ(OB_SUCCESS, startup_accel_handler_.init(observer::SERVER_ACCEL)); + ASSERT_EQ(OB_SUCCESS, startup_accel_handler_.start()); // create ls ObLSHandle ls_handle; @@ -81,7 +83,7 @@ void TestWriteTabletSlog::TearDownTestCase() ret = MTL(ObLSService*)->remove_ls(ObLSID(TEST_LS_ID), false); ASSERT_EQ(OB_SUCCESS, ret); - SERVER_STARTUP_TASK_HANDLER.destroy(); + startup_accel_handler_.destroy(); MockTenantModuleEnv::get_instance().destroy(); } @@ -156,7 +158,9 @@ TEST_F(TestWriteTabletSlog, basic) ASSERT_EQ(OB_SUCCESS, log_replayer.register_redo_module( ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, slog_handler)); ASSERT_EQ(OB_SUCCESS, log_replayer.replay(replay_start_cursor, replay_finish_cursor, OB_SERVER_TENANT_ID)); - ASSERT_EQ(OB_SUCCESS, slog_handler->concurrent_replay_load_tablets()); + ObTabletReplayCreateHandler handler; + ASSERT_EQ(OB_SUCCESS, handler.init(slog_handler->replay_tablet_disk_addr_map_, ObTabletRepalyOperationType::REPLAY_CREATE_TABLET)); + ASSERT_EQ(OB_SUCCESS, handler.concurrent_replay(&startup_accel_handler_)); // check the result of replay ObTabletHandle replay_tablet_handle; diff --git a/mittest/mtlenv/test_tx_data_table.cpp b/mittest/mtlenv/test_tx_data_table.cpp index 720f17b2fc..5174a29a9a 100644 --- a/mittest/mtlenv/test_tx_data_table.cpp +++ b/mittest/mtlenv/test_tx_data_table.cpp @@ -675,7 +675,7 @@ void TestTxDataTable::fake_ls_(ObLS &ls) ls.ls_meta_.ls_id_.id_ = 1001; ls.ls_meta_.gc_state_ = logservice::LSGCState::NORMAL; ls.ls_meta_.migration_status_ = ObMigrationStatus::OB_MIGRATION_STATUS_NONE; - ls.ls_meta_.restore_status_ = ObLSRestoreStatus::RESTORE_NONE; + ls.ls_meta_.restore_status_ = ObLSRestoreStatus::NONE; ls.ls_meta_.rebuild_seq_ = 0; } diff --git a/mittest/palf_cluster/logservice/log_service.cpp b/mittest/palf_cluster/logservice/log_service.cpp index 6dde8fb8e7..51d9b90fa6 100644 --- a/mittest/palf_cluster/logservice/log_service.cpp +++ b/mittest/palf_cluster/logservice/log_service.cpp @@ -280,6 +280,7 @@ palf::AccessMode LogService::get_palf_access_mode(const share::ObTenantRole &ten break; case share::ObTenantRole::STANDBY_TENANT: case share::ObTenantRole::RESTORE_TENANT: + case share::ObTenantRole::CLONE_TENANT: mode = palf::AccessMode::RAW_WRITE; break; default: diff --git a/mittest/simple_server/CMakeLists.txt b/mittest/simple_server/CMakeLists.txt index 9ee96c7195..e5b158e847 100644 --- a/mittest/simple_server/CMakeLists.txt +++ b/mittest/simple_server/CMakeLists.txt @@ -102,6 +102,7 @@ ob_unittest_observer(test_transfer_lock_info_operator storage_ha/test_transfer_l ob_unittest_observer(test_mds_recover test_mds_recover.cpp) ob_unittest_observer(test_keep_alive_min_start_scn test_keep_alive_min_start_scn.cpp) ob_unittest_observer(test_ls_replica test_ls_replica.cpp) +ob_unittest_observer(test_create_clone_tenant_resource_pool test_create_clone_tenant_resource_pool.cpp) ob_unittest_observer(test_tablet_autoinc_mgr test_tablet_autoinc_mgr.cpp) # TODO(muwei.ym): open later ob_ha_unittest_observer(test_transfer_handler storage_ha/test_transfer_handler.cpp) diff --git a/mittest/simple_server/test_create_clone_tenant_resource_pool.cpp b/mittest/simple_server/test_create_clone_tenant_resource_pool.cpp new file mode 100644 index 0000000000..ea7df0e026 --- /dev/null +++ b/mittest/simple_server/test_create_clone_tenant_resource_pool.cpp @@ -0,0 +1,106 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE + +#include +#include +#include "env/ob_simple_cluster_test_base.h" +#include "lib/ob_errno.h" + +namespace oceanbase +{ +using namespace unittest; +namespace share +{ +using ::testing::_; +using ::testing::Invoke; +using ::testing::Return; + +using namespace schema; +using namespace common; + +class TestCreateCloneTenantResourcePool : public unittest::ObSimpleClusterTestBase +{ +public: + TestCreateCloneTenantResourcePool() : unittest::ObSimpleClusterTestBase("test_create_clone_tenant_resource_pool") {} +}; + +TEST_F(TestCreateCloneTenantResourcePool, test_create_tenant_resource_pool) +{ + int ret = OB_SUCCESS; + // 0. prepare initial members + common::ObMySQLProxy &sql_proxy = get_curr_observer().get_mysql_proxy(); + rootserver::ObRootService *root_service = get_curr_observer().get_gctx().root_service_; + int64_t tmp_cnt = 0; + + // 1. create unit config + int64_t affected_rows = 0; + ObSqlString sql; + ASSERT_EQ(OB_SUCCESS, sql.assign("create resource unit clone_tenant_unit max_cpu 2, memory_size '2G', log_disk_size='2G';")); + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + + // 2. construct clone tenant arg + ObString pool_name = "resource_pool_for_clone_tenant_1001"; + ObString unit_config_name = "clone_tenant_unit"; + uint64_t source_tenant_id = 1; + uint64_t resource_pool_id = 2001; + ObCloneResourcePoolArg clone_tenant_arg; + ret = clone_tenant_arg.init(pool_name, unit_config_name, source_tenant_id, resource_pool_id); + ASSERT_EQ(OB_SUCCESS, ret); + + // 3. execute clone tenant + ret = root_service->clone_resource_pool(clone_tenant_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 4. check __all_resource_pool inserted new rows + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select count(*) as cnt " + "from __all_resource_pool " + "where name like '%%%.*s%%' " + "and unit_config_id = (select unit_config_id " + "from __all_unit_config " + "where name like '%%clone_tenant_unit%%');", + pool_name.length(), pool_name.ptr())); + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(res, sql.ptr())); + sqlclient::ObMySQLResult *result = res.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("cnt", tmp_cnt)); + ASSERT_EQ(1, tmp_cnt); + } + + // 5. check __all_unit inserted new rows + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt("select count(*) as cnt " + "from __all_unit " + "where unit_group_id = 0 " + "and resource_pool_id = %lu;", resource_pool_id)); + SMART_VAR(ObMySQLProxy::MySQLResult, res1) { + ASSERT_EQ(OB_SUCCESS, sql_proxy.read(res1, sql.ptr())); + sqlclient::ObMySQLResult *result = res1.get_result(); + ASSERT_NE(nullptr, result); + ASSERT_EQ(OB_SUCCESS, result->next()); + ASSERT_EQ(OB_SUCCESS, result->get_int("cnt", tmp_cnt)); + ASSERT_EQ(1, tmp_cnt); + } + +} +} // 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(); +} diff --git a/mittest/simple_server/test_ls_recover.cpp b/mittest/simple_server/test_ls_recover.cpp index 38dd033ce3..13fd5047f2 100644 --- a/mittest/simple_server/test_ls_recover.cpp +++ b/mittest/simple_server/test_ls_recover.cpp @@ -265,7 +265,7 @@ TEST_F(ObLSBeforeRestartTest, create_unfinished_ls_without_disk) LOG_INFO("create_ls", K(arg), K(id_100)); ASSERT_EQ(OB_SUCCESS, ls_svr->inner_create_ls_(arg.get_ls_id(), migration_status, - ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_NONE), + ObLSRestoreStatus(ObLSRestoreStatus::NONE), arg.get_create_scn(), ls)); ObLSLockGuard lock_ls(ls); @@ -293,7 +293,7 @@ TEST_F(ObLSBeforeRestartTest, create_unfinished_ls_with_disk) LOG_INFO("create_ls", K(arg), K(id_101)); ASSERT_EQ(OB_SUCCESS, ls_svr->inner_create_ls_(arg.get_ls_id(), migration_status, - ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_NONE), + ObLSRestoreStatus(ObLSRestoreStatus::NONE), arg.get_create_scn(), ls)); const bool unused_allow_log_sync = true; @@ -327,7 +327,7 @@ TEST_F(ObLSBeforeRestartTest, create_unfinished_ls_with_inner_tablet) LOG_INFO("create_ls", K(arg), K(id_102)); ASSERT_EQ(OB_SUCCESS, ls_svr->inner_create_ls_(arg.get_ls_id(), migration_status, - ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_NONE), + ObLSRestoreStatus(ObLSRestoreStatus::NONE), arg.get_create_scn(), ls)); const bool unused_allow_log_sync = true; @@ -364,7 +364,7 @@ TEST_F(ObLSBeforeRestartTest, create_unfinished_ls_with_commit_slog) LOG_INFO("create_ls", K(arg), K(id_103)); ASSERT_EQ(OB_SUCCESS, ls_svr->inner_create_ls_(arg.get_ls_id(), migration_status, - ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_NONE), + ObLSRestoreStatus(ObLSRestoreStatus::NONE), arg.get_create_scn(), ls)); const bool unused_allow_log_sync = true; @@ -447,7 +447,7 @@ TEST_F(ObLSBeforeRestartTest, create_rebuild_ls) LOG_INFO("create_ls", K(arg), K(id_105)); ASSERT_EQ(OB_SUCCESS, ls_svr->inner_create_ls_(arg.get_ls_id(), migration_status, - ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_NONE), + ObLSRestoreStatus(ObLSRestoreStatus::NONE), arg.get_create_scn(), ls)); const bool unused_allow_log_sync = true; diff --git a/src/logservice/archiveservice/ob_archive_service.cpp b/src/logservice/archiveservice/ob_archive_service.cpp index d05c600a39..d13831dcd1 100644 --- a/src/logservice/archiveservice/ob_archive_service.cpp +++ b/src/logservice/archiveservice/ob_archive_service.cpp @@ -201,6 +201,11 @@ void ObArchiveService::wakeup() cond_.signal(); } +void ObArchiveService::flush_all() +{ + ls_mgr_.flush_all(); +} + int ObArchiveService::iterate_ls(const std::function &func) { return ls_mgr_.iterate_ls(func); diff --git a/src/logservice/archiveservice/ob_archive_service.h b/src/logservice/archiveservice/ob_archive_service.h index 2d539618c4..98f8b801e2 100644 --- a/src/logservice/archiveservice/ob_archive_service.h +++ b/src/logservice/archiveservice/ob_archive_service.h @@ -107,6 +107,12 @@ public: ///////////// RPC process functions ///////////////// void wakeup(); + // Flush all logs to all archive destinations, in this interface a flush all flag is set and the flush action will be done in background. + // The flush flag is a temporary state on the ls, so only ls in archive progress in this server will be affected. + // + // New ls after the function call and ls migrated to other servers are immune. + void flush_all(); + int iterate_ls(const std::function &func); private: diff --git a/src/logservice/archiveservice/ob_ls_mgr.cpp b/src/logservice/archiveservice/ob_ls_mgr.cpp index aa8c02a769..51417f51db 100644 --- a/src/logservice/archiveservice/ob_ls_mgr.cpp +++ b/src/logservice/archiveservice/ob_ls_mgr.cpp @@ -13,6 +13,7 @@ #include "ob_ls_mgr.h" #include "lib/guard/ob_shared_guard.h" // ObShareGuard #include "lib/ob_define.h" +#include "lib/ob_errno.h" #include "lib/time/ob_time_utility.h" #include "share/backup/ob_backup_struct.h" // ObBackupPathString #include "share/ob_debug_sync.h" // DEBUG @@ -130,6 +131,52 @@ public: } }; +// get the end_lsn of palf, and set the end_lsn as the max no_limit lsn +// so all logs before the end_lsn will be archived as soon as possible +class ObArchiveLSMgr::FlushAllFunctor +{ +public: + FlushAllFunctor() : log_service_(NULL) {} + explicit FlushAllFunctor(logservice::ObLogService *log_service) : log_service_(log_service) {} + ~FlushAllFunctor() { log_service_ = NULL; } +public: + bool operator()(const ObLSID &id, ObLSArchiveTask *task) + { + int ret = OB_SUCCESS; + palf::LSN end_lsn; + palf::PalfHandleGuard palf_handle_guard; + if (NULL == log_service_) { + ret = OB_ERR_UNEXPECTED; + ARCHIVE_LOG(ERROR, "log_service_ is NULL", K(log_service_)); + } else if (OB_FAIL(log_service_->open_palf(id, palf_handle_guard))) { + ARCHIVE_LOG(WARN, "open_palf failed", K(id)); + } else if (OB_FAIL(palf_handle_guard.get_end_lsn(end_lsn))) { + ARCHIVE_LOG(WARN, "get end_lsn failed", K(id), K(end_lsn)); + } else if (OB_ISNULL(task)) { + ret = OB_ERR_UNEXPECTED; + ARCHIVE_LOG(ERROR, "archive task is NULL", K(id), K(task)); + } else if (OB_FAIL(task->update_no_limit_lsn(end_lsn))) { + ARCHIVE_LOG(WARN, "update no_limit lsn failed", K(id), K(end_lsn)); + } + // always return true + return true; + } +private: + logservice::ObLogService *log_service_; +}; + +void ObArchiveLSMgr::flush_all() +{ + int ret = OB_SUCCESS; + FlushAllFunctor functor(log_service_); + + if (OB_FAIL(ls_map_.for_each(functor))) { + ARCHIVE_LOG(WARN, "for_each failed"); + } else { + ARCHIVE_LOG(INFO, "flush_all succ"); + } +} + ObArchiveLSMgr::ObArchiveLSMgr() : inited_(false), tenant_id_(OB_INVALID_TENANT_ID), diff --git a/src/logservice/archiveservice/ob_ls_mgr.h b/src/logservice/archiveservice/ob_ls_mgr.h index d098a35a74..53a68f81ba 100644 --- a/src/logservice/archiveservice/ob_ls_mgr.h +++ b/src/logservice/archiveservice/ob_ls_mgr.h @@ -68,6 +68,7 @@ public: public: int iterate_ls(const std::function &func); template int foreach_ls(Fn &fn) { return ls_map_.for_each(fn); } + void flush_all(); public: int init(const uint64_t tenant_id, ObLogService *log_service, @@ -105,6 +106,7 @@ private: private: class CheckDeleteFunctor; class ClearArchiveTaskFunctor; + class FlushAllFunctor; private: bool inited_; uint64_t tenant_id_; diff --git a/src/logservice/archiveservice/ob_ls_task.cpp b/src/logservice/archiveservice/ob_ls_task.cpp index 962f7a5d71..faab7446d4 100644 --- a/src/logservice/archiveservice/ob_ls_task.cpp +++ b/src/logservice/archiveservice/ob_ls_task.cpp @@ -395,6 +395,18 @@ int ObLSArchiveTask::get_max_no_limit_lsn(const ArchiveWorkStation &station, LSN return ret; } +int ObLSArchiveTask::update_no_limit_lsn(const palf::LSN &lsn) +{ + int ret = OB_SUCCESS; + WLockGuard guard(rwlock_); + if (OB_UNLIKELY(!lsn.is_valid())) { + ARCHIVE_LOG(WARN, "lsn not valid", K(lsn)); + } else { + dest_.update_no_limit_lsn(lsn); + } + return ret; +} + int ObLSArchiveTask::print_self() { int ret = OB_SUCCESS; @@ -815,6 +827,16 @@ void ObLSArchiveTask::ArchiveDest::get_max_no_limit_lsn(LSN &lsn) lsn = max_no_limit_lsn_; } +void ObLSArchiveTask::ArchiveDest::update_no_limit_lsn(const palf::LSN &lsn) +{ + if (lsn > max_no_limit_lsn_) { + max_no_limit_lsn_ = lsn; + ARCHIVE_LOG(INFO, "update max no limit lsn succ", K(lsn)); + } else { + ARCHIVE_LOG(INFO, "lsn is smaller than max_no_limit_lsn_, just skip", K(lsn), K(max_no_limit_lsn_)); + } +} + void ObLSArchiveTask::ArchiveDest::mark_error() { has_encount_error_ = true; diff --git a/src/logservice/archiveservice/ob_ls_task.h b/src/logservice/archiveservice/ob_ls_task.h index bb19b0ae78..9b12c37934 100644 --- a/src/logservice/archiveservice/ob_ls_task.h +++ b/src/logservice/archiveservice/ob_ls_task.h @@ -128,6 +128,9 @@ public: int get_max_no_limit_lsn(const ArchiveWorkStation &station, LSN &lsn); + // support flush all logs to archvie dest + int update_no_limit_lsn(const palf::LSN &lsn); + int mark_error(const ArchiveKey &key); int print_self(); @@ -175,6 +178,7 @@ private: void get_send_task_count(int64_t &count); void get_archive_send_arg(ObArchiveSendDestArg &arg); void get_max_no_limit_lsn(LSN &lsn); + void update_no_limit_lsn(const palf::LSN &lsn); void mark_error(); void print_tasks_(); int64_t to_string(char *buf, const int64_t buf_len) const; diff --git a/src/logservice/ob_garbage_collector.cpp b/src/logservice/ob_garbage_collector.cpp index 94372925de..03c0df57fc 100644 --- a/src/logservice/ob_garbage_collector.cpp +++ b/src/logservice/ob_garbage_collector.cpp @@ -833,8 +833,11 @@ int ObGCHandler::try_check_and_set_wait_gc_when_log_archive_is_off_( ls_status = ObGarbageCollector::LSStatus::LS_NEED_DELETE_ENTRY; CLOG_LOG(INFO, "Tenant is dropped and the log stream can be removed, try_check_and_set_wait_gc_ success", K(tenant_id), K(ls_id), K(gc_state), K(offline_scn), K(readable_scn)); - } else if (offline_scn.is_valid() && MTL_GET_TENANT_ROLE_CACHE() == share::ObTenantRole::RESTORE_TENANT) { + } else if (offline_scn.is_valid() && + (MTL_GET_TENANT_ROLE_CACHE() == share::ObTenantRole::RESTORE_TENANT || + MTL_GET_TENANT_ROLE_CACHE() == share::ObTenantRole::CLONE_TENANT)) { // restore tenant, not need gc delay + // for clone tenant, we can ensure no ls's changes during clone procedure, so no need to deal with gc status if (OB_FAIL(ls_->set_gc_state(LSGCState::WAIT_GC))) { CLOG_LOG(WARN, "set_gc_state failed", K(ls_id), K(gc_state), K(ret)); } diff --git a/src/logservice/ob_log_base_type.h b/src/logservice/ob_log_base_type.h index 8c9e64735e..40ff1f154c 100644 --- a/src/logservice/ob_log_base_type.h +++ b/src/logservice/ob_log_base_type.h @@ -234,6 +234,10 @@ int log_base_type_to_string(const ObLogBaseType log_type, strncpy(str ,"WORKLOAD_REPOSITORY_SERVICE", str_len); } else if (log_type == TTL_LOG_BASE_TYPE) { strncpy(str ,"TTL_SERVICE", str_len); + } else if (log_type == SNAPSHOT_SCHEDULER_LOG_BASE_TYPE) { + strncpy(str ,"SNAPSHOT_SCHEDULER", str_len); + } else if (log_type == CLONE_SCHEDULER_LOG_BASE_TYPE) { + strncpy(str ,"CLONE_SCHEDULER", str_len); } else if (log_type == TABLE_LOAD_RESOURCE_SERVICE_LOG_BASE_TYPE) { strncpy(str ,"TABLE_LOAD_RESOURCE_SERVICE", str_len); } else if (log_type == MVIEW_MAINTENANCE_SERVICE_LOG_BASE_TYPE) { diff --git a/src/logservice/ob_log_service.cpp b/src/logservice/ob_log_service.cpp index aeb0e4d2c8..0d060f73a7 100644 --- a/src/logservice/ob_log_service.cpp +++ b/src/logservice/ob_log_service.cpp @@ -312,6 +312,7 @@ palf::AccessMode ObLogService::get_palf_access_mode(const share::ObTenantRole &t break; case share::ObTenantRole::STANDBY_TENANT: case share::ObTenantRole::RESTORE_TENANT: + case share::ObTenantRole::CLONE_TENANT: mode = palf::AccessMode::RAW_WRITE; break; default: diff --git a/src/logservice/restoreservice/ob_remote_error_reporter.cpp b/src/logservice/restoreservice/ob_remote_error_reporter.cpp index 44a0032024..cc3a257b25 100644 --- a/src/logservice/restoreservice/ob_remote_error_reporter.cpp +++ b/src/logservice/restoreservice/ob_remote_error_reporter.cpp @@ -124,7 +124,7 @@ int ObRemoteErrorReporter::do_report_(ObLS &ls) } else if (! error_exist) { } else if (OB_FAIL(ls.get_ls_meta().get_restore_status(restore_status))) { LOG_WARN("get restore status failed", K(ret), K(ls)); - } else if (restore_status.is_in_restore()) { + } else if (!restore_status.is_none()) { ret = report_restore_error_(ls, trace_id, ret_code); } else { ret = report_standby_error_(ls, trace_id, ret_code); diff --git a/src/observer/CMakeLists.txt b/src/observer/CMakeLists.txt index 960bfb282d..46e162bd14 100644 --- a/src/observer/CMakeLists.txt +++ b/src/observer/CMakeLists.txt @@ -36,7 +36,7 @@ ob_set_subtarget(ob_server common ob_srv_xlator_storage.cpp ob_tenant_duty_task.cpp ob_uniq_task_queue.cpp - ob_server_startup_task_handler.cpp + ob_startup_accel_task_handler.cpp ob_srv_rpc_handler.cpp ) @@ -245,7 +245,10 @@ ob_set_subtarget(ob_server virtual_table virtual_table/ob_all_virtual_load_data_stat.cpp virtual_table/ob_all_virtual_lock_wait_stat.cpp virtual_table/ob_all_virtual_long_ops_status.cpp + virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.cpp + virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.cpp virtual_table/ob_all_virtual_ls_info.cpp + virtual_table/ob_all_virtual_ls_snapshot.cpp virtual_table/ob_all_virtual_timestamp_service.cpp virtual_table/ob_all_virtual_transaction_freeze_checkpoint.cpp virtual_table/ob_all_virtual_transaction_checkpoint.cpp diff --git a/src/observer/ob_rpc_processor_simple.cpp b/src/observer/ob_rpc_processor_simple.cpp index 08cafccfbb..27242bb4b3 100644 --- a/src/observer/ob_rpc_processor_simple.cpp +++ b/src/observer/ob_rpc_processor_simple.cpp @@ -53,6 +53,7 @@ #include "share/sequence/ob_sequence_cache.h" #include "logservice/ob_log_service.h" #include "logservice/ob_log_handler.h" +#include "logservice/archiveservice/ob_archive_service.h" #include "share/scn.h" #include "storage/ob_common_id_utils.h" #include "storage/high_availability/ob_storage_ha_service.h" @@ -65,14 +66,18 @@ #include "rootserver/ob_tenant_transfer_service.h" // ObTenantTransferService #include "storage/high_availability/ob_transfer_service.h" // ObTransferService #include "sql/udr/ob_udr_mgr.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.h" +#include "rootserver/restore/ob_clone_scheduler.h" #ifdef OB_BUILD_SPM #include "sql/spm/ob_spm_controller.h" #endif #include "sql/plan_cache/ob_ps_cache.h" #include "rootserver/ob_primary_ls_service.h" // for ObPrimaryLSService +#include "rootserver/ob_root_utils.h" #include "sql/session/ob_sql_session_info.h" #include "sql/session/ob_sess_info_verify.h" #include "observer/table/ttl/ob_ttl_service.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_service.h" #include "storage/high_availability/ob_storage_ha_utils.h" namespace oceanbase @@ -1567,6 +1572,46 @@ int ObRpcCheckLSCanOfflineP::process() return ret; } +int ObRpcInnerCreateTenantSnapshotP::process() +{ + int ret = OB_SUCCESS; + if (MTL_ID() != arg_.get_tenant_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObRpcInnerCreateTenantSnapshotP::process tenant not match", KR(ret), K(arg_)); + } + if (OB_SUCC(ret)) { + ObTenantSnapshotService *service = nullptr; + service = MTL(ObTenantSnapshotService*); + if (OB_ISNULL(service)) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(ERROR, "mtl ObTenantSnapshotService should not be nullptr", KR(ret), K(arg_)); + } else if (OB_FAIL(service->create_tenant_snapshot(arg_))) { + COMMON_LOG(WARN, "fail to create tenant snapshot", KR(ret), K(arg_)); + } + } + return ret; +} + +int ObRpcInnerDropTenantSnapshotP::process() +{ + int ret = OB_SUCCESS; + if (MTL_ID() != arg_.get_tenant_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObRpcInnerDropTenantSnapshotP::process tenant not match", KR(ret), K(arg_)); + } + if (OB_SUCC(ret)) { + ObTenantSnapshotService *service = nullptr; + service = MTL(ObTenantSnapshotService*); + if (OB_ISNULL(service)) { + ret = OB_ERR_UNEXPECTED; + COMMON_LOG(ERROR, "mtl ObTenantSnapshotService should not be nullptr", KR(ret), K(arg_)); + } else if (OB_FAIL(service->drop_tenant_snapshot(arg_))) { + COMMON_LOG(WARN, "fail to drop tenant snapshot", KR(ret), K(arg_)); + } + } + return ret; +} + int ObRpcGetLSAccessModeP::process() { int ret = OB_SUCCESS; @@ -1659,7 +1704,7 @@ int ObRpcChangeLSAccessModeP::process() if (OB_UNLIKELY(!arg_.get_sys_ls_end_scn().is_valid_and_not_min())) { FLOG_WARN("invalid sys_ls_end_scn, no need to let user ls wait, " "the version might be smaller than V4.2.0", KR(ret), K(arg_.get_sys_ls_end_scn())); - } else if (OB_FAIL(ObRootUtils::wait_user_ls_sync_scn_locally( + } else if (OB_FAIL(rootserver::ObRootUtils::wait_user_ls_sync_scn_locally( arg_.get_sys_ls_end_scn(), log_ls_svr, *ls))) { @@ -2144,6 +2189,43 @@ int ObSetRootKeyP::process() } return ret; } + +int ObCloneKeyP::process() +{ + int ret = OB_SUCCESS; + const uint64_t source_tenant_id = arg_.get_source_tenant_id(); + ObCipherOpMode mode; + common::ObSEArray, 2> master_key_list; + if (OB_UNLIKELY(!arg_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(arg_)); + //get master key info from source tenant + } else if (OB_FAIL(ObMasterKeyGetter::get_table_key_algorithm(source_tenant_id, mode))) { + LOG_WARN("failed to get table key algorithm", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(ObMasterKeyGetter::instance().dump_tenant_keys(source_tenant_id, + master_key_list))) { + LOG_WARN("failed to dump tenant key", KR(ret), K(source_tenant_id)); + //set master key info for clone tenant + } else if (OB_FAIL(ObMasterKeyGetter::instance().load_tenant_keys(arg_.get_tenant_id(), + mode, + master_key_list))) { + LOG_WARN("failed to load tenant keys", KR(ret), K(arg_)); + } + return ret; +} + +int ObTrimKeyListP::process() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(arg_)); + } else if (OB_FAIL(ObMasterKeyGetter::instance().trim_master_key_map(arg_.get_tenant_id(), + arg_.get_latest_master_key_id()))) { + LOG_WARN("fail to trim master key map", KR(ret), K(arg_)); + } + return ret; +} #endif int ObHandlePartTransCtxP::process() @@ -2861,6 +2943,67 @@ int ObAdminUnlockMemberListP::process() return ret; } +int ObRpcNotifyTenantSnapshotSchedulerP::process() +{ + int ret = OB_SUCCESS; + if (!arg_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(arg_)); + } else { + MTL_SWITCH(gen_meta_tenant_id(arg_.get_tenant_id())) { + rootserver::ObTenantSnapshotScheduler* tenant_snapshot_scheduler = MTL(rootserver::ObTenantSnapshotScheduler*); + if (OB_ISNULL(tenant_snapshot_scheduler)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant snapshot scheduler is null", KR(ret), K(arg_)); + } else { + tenant_snapshot_scheduler->wakeup(); + } + } + } + (void)result_.init(ret); + return ret; +} + +int ObRpcFlushLSArchiveP::process() +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = MTL_ID(); + archive::ObArchiveService* archive_svr = MTL(archive::ObArchiveService*); + + if (!arg_.is_valid() || tenant_id != arg_.tenant_id_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(arg_), K(tenant_id)); + } else if (OB_ISNULL(archive_svr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("archive service is null", KR(ret), K(arg_)); + } else { + archive_svr->flush_all(); + } + result_ = ret; + return ret; +} + +int ObRpcNotifyCloneSchedulerP::process() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(arg_)); + } else { + MTL_SWITCH(arg_.get_tenant_id()) { + rootserver::ObCloneScheduler* clone_scheduler = MTL(rootserver::ObCloneScheduler*); + if (OB_ISNULL(clone_scheduler)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("clone scheduler is null", KR(ret), K(arg_)); + } else { + clone_scheduler->wakeup(); + } + } + } + (void)result_.init(ret); + return ret; +} + int ObKillClientSessionP::process() { int ret = OB_SUCCESS; diff --git a/src/observer/ob_rpc_processor_simple.h b/src/observer/ob_rpc_processor_simple.h index aa0b0085c4..e4f40cbe2a 100644 --- a/src/observer/ob_rpc_processor_simple.h +++ b/src/observer/ob_rpc_processor_simple.h @@ -209,6 +209,8 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_PRE_PROCESS_SERVER, ObPreProcessServerP); OB_DEFINE_PROCESSOR_S(Srv, OB_GET_MASTER_KEY, ObGetMasterKeyP); OB_DEFINE_PROCESSOR_S(Srv, OB_RESTORE_KEY, ObRestoreKeyP); OB_DEFINE_PROCESSOR_S(Srv, OB_SET_ROOT_KEY, ObSetRootKeyP); +OB_DEFINE_PROCESSOR_S(Srv, OB_CLONE_KEY, ObCloneKeyP); +OB_DEFINE_PROCESSOR_S(Srv, OB_TRIM_KEY_LIST, ObTrimKeyListP); #endif OB_DEFINE_PROCESSOR_S(Srv, OB_HANDLE_PART_TRANS_CTX, ObHandlePartTransCtxP); OB_DEFINE_PROCESSOR_S(Srv, OB_SERVER_FLUSH_OPT_STAT_MONITORING_INFO, ObFlushLocalOptStatMonitoringInfoP); @@ -255,6 +257,11 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_BROADCAST_CONSENSUS_VERSION, ObBroadcastConsensusV OB_DEFINE_PROCESSOR_S(Srv, OB_GET_LS_REPLAYED_SCN, ObRpcGetLSReplayedScnP); OB_DEFINE_PROCESSOR_S(Srv, OB_TABLE_TTL, ObTenantTTLP); OB_DEFINE_PROCESSOR_S(Srv, OB_HA_UNLOCK_MEMBER_LIST, ObAdminUnlockMemberListP); +OB_DEFINE_PROCESSOR_S(Srv, OB_NOTIFY_TENANT_SNAPSHOT_SCHEDULER, ObRpcNotifyTenantSnapshotSchedulerP); +OB_DEFINE_PROCESSOR_S(Srv, OB_INNER_CREATE_TENANT_SNAPSHOT, ObRpcInnerCreateTenantSnapshotP); +OB_DEFINE_PROCESSOR_S(Srv, OB_INNER_DROP_TENANT_SNAPSHOT, ObRpcInnerDropTenantSnapshotP); +OB_DEFINE_PROCESSOR_S(Srv, OB_FLUSH_LS_ARCHIVE, ObRpcFlushLSArchiveP); +OB_DEFINE_PROCESSOR_S(Srv, OB_NOTIFY_CLONE_SCHEDULER, ObRpcNotifyCloneSchedulerP); OB_DEFINE_PROCESSOR_S(Srv, OB_TABLET_MAJOR_FREEZE, ObRpcTabletMajorFreezeP); // OB_DEFINE_PROCESSOR_S(Srv, OB_KILL_CLIENT_SESSION, ObKillClientSessionP); // OB_DEFINE_PROCESSOR_S(Srv, OB_CLIENT_SESSION_CONNECT_TIME, ObClientSessionConnectTimeP); diff --git a/src/observer/ob_server.cpp b/src/observer/ob_server.cpp index 0d0bbe5ce1..898f30f1a6 100644 --- a/src/observer/ob_server.cpp +++ b/src/observer/ob_server.cpp @@ -106,7 +106,7 @@ #include "observer/ob_server_utils.h" #include "observer/table_load/ob_table_load_partition_calc.h" #include "observer/virtual_table/ob_mds_event_buffer.h" -#include "observer/ob_server_startup_task_handler.h" +#include "observer/ob_startup_accel_task_handler.h" #include "share/detect/ob_detect_manager.h" #include "observer/table/ttl/ob_table_ttl_task.h" #ifdef OB_BUILD_ARBITRATION @@ -412,7 +412,7 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg) LOG_ERROR("init ObStorageLoggerManager failed", KR(ret)); } else if (OB_FAIL(ObVirtualTenantManager::get_instance().init())) { LOG_ERROR("init tenant manager failed", KR(ret)); - } else if (OB_FAIL(SERVER_STARTUP_TASK_HANDLER.init())) { + } else if (OB_FAIL(startup_accel_handler_.init(SERVER_ACCEL))) { LOG_ERROR("init server startup task handler failed", KR(ret)); } else if (OB_FAIL(ObServerCheckpointSlogHandler::get_instance().init())) { LOG_ERROR("init server checkpoint slog handler failed", KR(ret)); @@ -742,7 +742,7 @@ void ObServer::destroy() FLOG_INFO("ob server block mgr destroyed"); FLOG_INFO("begin to destroy server startup task handler"); - SERVER_STARTUP_TASK_HANDLER.destroy(); + startup_accel_handler_.destroy(); FLOG_INFO("server startup task handler destroyed"); FLOG_INFO("begin to destroy backup index cache"); @@ -834,7 +834,7 @@ int ObServer::start() LOG_ERROR("fail to start signal worker", KR(ret)); } - if (FAILEDx(SERVER_STARTUP_TASK_HANDLER.start())) { + if (FAILEDx(startup_accel_handler_.start())) { LOG_ERROR("fail to start server startup task handler", KR(ret)); } else { FLOG_INFO("success to start server startup task handler"); @@ -998,7 +998,7 @@ int ObServer::start() has_stopped_ = false; } // this handler is only used to process tasks during startup. so it can be destroied here. - SERVER_STARTUP_TASK_HANDLER.destroy(); + startup_accel_handler_.destroy(); // refresh server configure // @@ -1359,7 +1359,7 @@ int ObServer::stop() FLOG_INFO("server checkpoint slog handler stopped"); FLOG_INFO("begin to stop server startup task handler"); - SERVER_STARTUP_TASK_HANDLER.stop(); + startup_accel_handler_.stop(); FLOG_INFO("server startup task handler stopped"); // It will wait for all requests done. @@ -1684,7 +1684,7 @@ int ObServer::wait() FLOG_INFO("wait server checkpoint slog handler success"); FLOG_INFO("begin to wait server startup task handler"); - SERVER_STARTUP_TASK_HANDLER.wait(); + startup_accel_handler_.wait(); FLOG_INFO("wait server startup task handler success"); FLOG_INFO("begin to wait global election report timer"); @@ -2552,6 +2552,7 @@ int ObServer::init_global_context() #endif (void)gctx_.set_upgrade_stage(obrpc::OB_UPGRADE_STAGE_INVALID); gctx_.wr_service_ = &wr_service_; + gctx_.startup_accel_handler_ = &startup_accel_handler_; gctx_.flashback_scn_ = opts_.flashback_scn_; gctx_.server_id_ = config_.observer_id; diff --git a/src/observer/ob_server.h b/src/observer/ob_server.h index a1b9df7b6f..09355b975b 100644 --- a/src/observer/ob_server.h +++ b/src/observer/ob_server.h @@ -61,6 +61,7 @@ #include "observer/table/ob_table_service.h" #include "observer/dbms_job/ob_dbms_job_rpc_proxy.h" #include "observer/ob_inner_sql_rpc_proxy.h" +#include "observer/ob_startup_accel_task_handler.h" #include "share/ls/ob_ls_table_operator.h" // for ObLSTableOperator #include "storage/ob_locality_manager.h" #include "storage/ob_partition_component_factory.h" @@ -454,6 +455,11 @@ private: arbserver::ObArbServerTimer arb_timer_; #endif share::ObWorkloadRepositoryService wr_service_; + + // This handler is used to process tasks during startup. it can speed up the startup process. + // If you have tasks that need to be processed in parallel, you can use this handler, + // but please note that this handler will be destroyed after observer startup. + ObStartupAccelTaskHandler startup_accel_handler_; }; // end of class ObServer inline ObServer &ObServer::get_instance() diff --git a/src/observer/ob_server_startup_task_handler.cpp b/src/observer/ob_server_startup_task_handler.cpp deleted file mode 100644 index a7188c9aa2..0000000000 --- a/src/observer/ob_server_startup_task_handler.cpp +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright (c) 2021 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. - */ - -#define USING_LOG_PREFIX SERVER -#include "observer/ob_server_startup_task_handler.h" -#include "share/ob_thread_mgr.h" - -namespace oceanbase -{ -namespace observer -{ -const int64_t ObServerStartupTaskHandler::MAX_QUEUED_TASK_NUM = 128; -const int64_t ObServerStartupTaskHandler::MAX_THREAD_NUM = 64; - -ObServerStartupTaskHandler::ObServerStartupTaskHandler() - : is_inited_(false), - tg_id_(-1), - task_allocator_() -{} - -ObServerStartupTaskHandler::~ObServerStartupTaskHandler() -{ - destroy(); -} - -int ObServerStartupTaskHandler::init() -{ - int ret = OB_SUCCESS; - if (is_inited_) { - ret = OB_INIT_TWICE; - LOG_WARN("ObServerStartupTaskHandler has already been inited", K(ret)); - } else if (OB_FAIL(task_allocator_.init(lib::ObMallocAllocator::get_instance(), - OB_MALLOC_NORMAL_BLOCK_SIZE, ObMemAttr(OB_SERVER_TENANT_ID, "StartupTask", ObCtxIds::DEFAULT_CTX_ID)))) { - LOG_WARN("fail to init tenant tiny allocator", K(ret)); - } else if (OB_FAIL(TG_CREATE(lib::TGDefIDs::SvrStartupHandler, tg_id_))) { - LOG_WARN("lib::TGDefIDs::SvrStartupHandler tg create", K(ret)); - } else { - is_inited_ = true; - } - return ret; -} - -int ObServerStartupTaskHandler::start() -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ObServerStartupTaskHandler not inited", K(ret)); - } else if (OB_FAIL(TG_SET_HANDLER_AND_START(tg_id_, *this))) { - LOG_WARN("fail to start ObServerStartupTaskHandler", K(ret)); - } - return ret; -} - -void ObServerStartupTaskHandler::stop() -{ - if (IS_INIT) { - TG_STOP(tg_id_); - } -} - -void ObServerStartupTaskHandler::wait() -{ - if (IS_INIT) { - TG_WAIT(tg_id_); - } -} - -void ObServerStartupTaskHandler::destroy() -{ - if (IS_INIT) { - TG_STOP(tg_id_); - TG_WAIT(tg_id_); - TG_DESTROY(tg_id_); - tg_id_ = -1; - task_allocator_.reset(); - is_inited_ = false; - } -} - -int ObServerStartupTaskHandler::push_task(ObServerStartupTask *task) -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("ObServerStartupTaskHandler not inited", K(ret)); - } else if (OB_FAIL(TG_PUSH_TASK(tg_id_, task))) { - LOG_WARN("fail to push server startup task", K(ret), KPC(task)); - } - return ret; -} - -void ObServerStartupTaskHandler::handle(void *task) -{ - int ret = OB_SUCCESS; - if (NULL == task) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("task is null", K(ret)); - } else { - ObServerStartupTask *startup_task = static_cast(task); - if (OB_FAIL(startup_task->execute())) { - LOG_WARN("fail to execute startup task", K(ret), KPC(startup_task)); - } - startup_task->~ObServerStartupTask(); - task_allocator_.free(startup_task); - } -} - -} // observer -} // oceanbase diff --git a/src/observer/ob_server_struct.h b/src/observer/ob_server_struct.h index e077ff36c7..7a27e767f9 100644 --- a/src/observer/ob_server_struct.h +++ b/src/observer/ob_server_struct.h @@ -124,6 +124,7 @@ class ObTableService; class ObSrvNetworkFrame; class ObIDiskReport; class ObResourceInnerSQLConnectionPool; +class ObStartupAccelTaskHandler; class ObServerOptions { @@ -288,6 +289,7 @@ struct ObGlobalContext storage::ObLocalityManager *locality_manager_; obrpc::ObExtenralTableRpcProxy *external_table_proxy_; share::ObWorkloadRepositoryService *wr_service_; + ObStartupAccelTaskHandler* startup_accel_handler_; ObGlobalContext() { MEMSET(this, 0, sizeof(*this)); init(); } ObGlobalContext &operator = (const ObGlobalContext &other); diff --git a/src/observer/ob_service.cpp b/src/observer/ob_service.cpp index d0c882f72a..eb90be5c5f 100644 --- a/src/observer/ob_service.cpp +++ b/src/observer/ob_service.cpp @@ -2755,11 +2755,11 @@ int ObService::get_leader_locations( // skip /* * This function may be blocked when dick is hang, - * we consider leader's status is always RESTORE_NONE + * we consider leader's restore status is always NONE * } else if (OB_FAIL(ls->get_restore_status(restore_status))) { * LOG_WARN("get restore status failed", KR(ret)); */ - } else if (FALSE_IT(restore_status = ObLSRestoreStatus::RESTORE_NONE)) { + } else if (FALSE_IT(restore_status = ObLSRestoreStatus::NONE)) { } else if (OB_FAIL(leader_location.init( GCTX.config_->cluster_id, /*cluster_id*/ tenant_id, /*tenant_id*/ diff --git a/src/observer/ob_srv_xlator_partition.cpp b/src/observer/ob_srv_xlator_partition.cpp index 738b1a2ffe..5b40a00d8e 100644 --- a/src/observer/ob_srv_xlator_partition.cpp +++ b/src/observer/ob_srv_xlator_partition.cpp @@ -101,6 +101,8 @@ void oceanbase::observer::init_srv_xlator_for_partition(ObSrvRpcXlator *xlator) RPC_PROCESSOR(ObGetMasterKeyP, gctx_); RPC_PROCESSOR(ObRestoreKeyP, gctx_); RPC_PROCESSOR(ObSetRootKeyP, gctx_); + RPC_PROCESSOR(ObCloneKeyP, gctx_); + RPC_PROCESSOR(ObTrimKeyListP, gctx_); #endif RPC_PROCESSOR(ObHandlePartTransCtxP, gctx_); #ifdef OB_BUILD_TDE_SECURITY diff --git a/src/observer/ob_srv_xlator_rootserver.cpp b/src/observer/ob_srv_xlator_rootserver.cpp index 557873ab05..1b5bfdb949 100644 --- a/src/observer/ob_srv_xlator_rootserver.cpp +++ b/src/observer/ob_srv_xlator_rootserver.cpp @@ -76,6 +76,7 @@ void oceanbase::observer::init_srv_xlator_for_rootserver(ObSrvRpcXlator *xlator) RPC_PROCESSOR(rootserver::ObRpcCreateResourceUnitP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObRpcAlterResourceUnitP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObRpcDropResourceUnitP, *gctx_.root_service_); + RPC_PROCESSOR(rootserver::ObRpcCloneResourcePoolP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObRpcCreateResourcePoolP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObRpcAlterResourcePoolP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObRpcDropResoucePoolP, *gctx_.root_service_); @@ -251,6 +252,7 @@ void oceanbase::observer::init_srv_xlator_for_rootserver(ObSrvRpcXlator *xlator) RPC_PROCESSOR(rootserver::ObBackupCleanP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObDeletePolicyP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObRecoverTableP, *gctx_.root_service_); + RPC_PROCESSOR(rootserver::ObRpcCloneTenantP, *gctx_.root_service_); // auto part ddl diff --git a/src/observer/ob_srv_xlator_storage.cpp b/src/observer/ob_srv_xlator_storage.cpp index 852a9eebe1..32b8b37cd3 100644 --- a/src/observer/ob_srv_xlator_storage.cpp +++ b/src/observer/ob_srv_xlator_storage.cpp @@ -120,6 +120,11 @@ void oceanbase::observer::init_srv_xlator_for_storage(ObSrvRpcXlator *xlator) { #endif RPC_PROCESSOR(ObRpcDDLCheckTabletMergeStatusP, gctx_); RPC_PROCESSOR(ObRpcCreateDuplicateLSP, gctx_); + RPC_PROCESSOR(ObRpcNotifyTenantSnapshotSchedulerP, gctx_); + RPC_PROCESSOR(ObRpcInnerCreateTenantSnapshotP, gctx_); + RPC_PROCESSOR(ObRpcInnerDropTenantSnapshotP, gctx_); + RPC_PROCESSOR(ObRpcFlushLSArchiveP, gctx_); + RPC_PROCESSOR(ObRpcNotifyCloneSchedulerP, gctx_); RPC_PROCESSOR(ObRpcTabletMajorFreezeP, gctx_); RPC_PROCESSOR(ObCancelGatherStatsP, gctx_); } diff --git a/src/observer/ob_startup_accel_task_handler.cpp b/src/observer/ob_startup_accel_task_handler.cpp new file mode 100644 index 0000000000..b1b462ae95 --- /dev/null +++ b/src/observer/ob_startup_accel_task_handler.cpp @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SERVER +#include "observer/ob_startup_accel_task_handler.h" +#include "share/ob_thread_mgr.h" +#include "share/rc/ob_tenant_base.h" + +namespace oceanbase +{ +namespace observer +{ +const int64_t ObStartupAccelTaskHandler::MAX_QUEUED_TASK_NUM = 128; +const int64_t ObStartupAccelTaskHandler::MAX_THREAD_NUM = 64; + +ObStartupAccelTaskHandler::ObStartupAccelTaskHandler() + : is_inited_(false), + tg_id_(-1), + task_allocator_() +{} + +ObStartupAccelTaskHandler::~ObStartupAccelTaskHandler() +{ + destroy(); +} + +int ObStartupAccelTaskHandler::init(ObStartupAccelType accel_type) +{ + int ret = OB_SUCCESS; + ObMemAttr mem_attr = ObMemAttr(SERVER_ACCEL == accel_type ? OB_SERVER_TENANT_ID : MTL_ID(), + "StartupTask", + ObCtxIds::DEFAULT_CTX_ID); + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("ObStartupAccelTaskHandler has already been inited", K(ret)); + } else if (OB_FAIL(task_allocator_.init(lib::ObMallocAllocator::get_instance(), + OB_MALLOC_NORMAL_BLOCK_SIZE, mem_attr))) { + LOG_WARN("fail to init tenant tiny allocator", K(ret)); + } else if (SERVER_ACCEL == accel_type && + OB_FAIL(TG_CREATE(lib::TGDefIDs::StartupAccelHandler, tg_id_))) { + LOG_WARN("lib::TGDefIDs::StartupAccelHandler tg create", K(ret)); + } else if (TENANT_ACCEL == accel_type && + OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::StartupAccelHandler, tg_id_))) { + LOG_WARN("lib::TGDefIDs::StartupAccelHandler tg create", K(ret)); + } else { + is_inited_ = true; + accel_type_ = accel_type; + } + return ret; +} + +int64_t ObStartupAccelTaskHandler::get_thread_cnt() +{ + int64_t thread_cnt = 1; + if (lib::is_mini_mode()) { + thread_cnt = 1; + } else { + if (SERVER_ACCEL == accel_type_) { + thread_cnt = common::get_cpu_count(); + } else { + thread_cnt = MTL_CPU_COUNT(); + } + } + + return std::min(MAX_THREAD_NUM, thread_cnt); +} + +int ObStartupAccelTaskHandler::start() +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObStartupAccelTaskHandler not inited", K(ret)); + } else if (OB_FAIL(TG_SET_HANDLER(tg_id_, *this))) { + LOG_WARN("tg set handler failed", K(ret), K(tg_id_)); + } else if (OB_FAIL(TG_SET_THREAD_CNT(tg_id_, get_thread_cnt()))) { + LOG_WARN("tg set thread cnt failed", K(ret), K(tg_id_), K(get_thread_cnt())); + } else if (OB_FAIL(TG_START(tg_id_))) { + LOG_WARN("fail to start ObStartupAccelTaskHandler", K(ret)); + } + return ret; +} + +void ObStartupAccelTaskHandler::stop() +{ + if (IS_INIT) { + TG_STOP(tg_id_); + } +} + +void ObStartupAccelTaskHandler::wait() +{ + if (IS_INIT) { + TG_WAIT(tg_id_); + } +} + +void ObStartupAccelTaskHandler::destroy() +{ + if (IS_INIT) { + TG_STOP(tg_id_); + TG_WAIT(tg_id_); + TG_DESTROY(tg_id_); + tg_id_ = -1; + task_allocator_.reset(); + is_inited_ = false; + } +} + +int ObStartupAccelTaskHandler::push_task(ObStartupAccelTask *task) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObStartupAccelTaskHandler not inited", K(ret)); + } else if (OB_FAIL(TG_PUSH_TASK(tg_id_, task))) { + LOG_WARN("fail to push startup accel task", K(ret), KPC(task)); + } + return ret; +} + +void ObStartupAccelTaskHandler::handle(void *task) +{ + int ret = OB_SUCCESS; + if (NULL == task) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("task is null", K(ret)); + } else { + ObStartupAccelTask *startup_task = static_cast(task); + if (OB_FAIL(startup_task->execute())) { + LOG_WARN("fail to execute startup task", K(ret), KPC(startup_task)); + } + startup_task->~ObStartupAccelTask(); + task_allocator_.free(startup_task); + } +} + +} // observer +} // oceanbase diff --git a/src/observer/ob_server_startup_task_handler.h b/src/observer/ob_startup_accel_task_handler.h similarity index 52% rename from src/observer/ob_server_startup_task_handler.h rename to src/observer/ob_startup_accel_task_handler.h index e249104795..d1fae640ba 100644 --- a/src/observer/ob_server_startup_task_handler.h +++ b/src/observer/ob_startup_accel_task_handler.h @@ -10,8 +10,8 @@ * See the Mulan PubL v2 for more details. */ -#ifndef OCEABASE_SERVER_OB_SERVER_STARTUP_TASK_HANDLER_H_ -#define OCEABASE_SERVER_OB_SERVER_STARTUP_TASK_HANDLER_H_ +#ifndef OCEABASE_SERVER_OB_STARTUP_ACCEL_TASK_HANDLER_H_ +#define OCEABASE_SERVER_OB_STARTUP_ACCEL_TASK_HANDLER_H_ #include "lib/ob_define.h" #include "lib/thread/thread_mgr.h" @@ -22,50 +22,46 @@ namespace oceanbase { namespace observer { -class ObServerStartupTask +class ObStartupAccelTask { public: - ObServerStartupTask() {} - virtual ~ObServerStartupTask() {} + ObStartupAccelTask() {} + virtual ~ObStartupAccelTask() {} virtual int execute() = 0; DECLARE_PURE_VIRTUAL_TO_STRING; }; -// This handler is only used to process tasks during startup. it can speed up the startup process. -// If you have tasks that need to be processed in parallel, you can use this handler, -// but please note that this handler will be destroyed after obsever startup. -class ObServerStartupTaskHandler : public lib::TGTaskHandler +enum ObStartupAccelType +{ + SERVER_ACCEL = 1, + TENANT_ACCEL = 2, +}; + +class ObStartupAccelTaskHandler : public lib::TGTaskHandler { public: static const int64_t MAX_QUEUED_TASK_NUM; static const int64_t MAX_THREAD_NUM; - ObServerStartupTaskHandler(); - ~ObServerStartupTaskHandler(); - int init(); + + ObStartupAccelTaskHandler(); + ~ObStartupAccelTaskHandler(); + int init(ObStartupAccelType accel_type); int start(); void stop(); void wait(); void destroy(); void handle(void *task) override; ObIAllocator &get_task_allocator() { return task_allocator_; } - int push_task(ObServerStartupTask *task); - static int64_t get_thread_num() { return std::min(MAX_THREAD_NUM, common::get_cpu_count()); } - static OB_INLINE ObServerStartupTaskHandler &get_instance(); + int push_task(ObStartupAccelTask *task); + int64_t get_thread_cnt(); private: bool is_inited_; + ObStartupAccelType accel_type_; int tg_id_; common::ObFIFOAllocator task_allocator_; }; -OB_INLINE ObServerStartupTaskHandler &ObServerStartupTaskHandler::get_instance() -{ - static ObServerStartupTaskHandler instance; - return instance; -} - -#define SERVER_STARTUP_TASK_HANDLER (::oceanbase::observer::ObServerStartupTaskHandler::get_instance()) - } // observer } // oceanbase diff --git a/src/observer/omt/ob_multi_tenant.cpp b/src/observer/omt/ob_multi_tenant.cpp index e271290e7b..bf762a9950 100644 --- a/src/observer/omt/ob_multi_tenant.cpp +++ b/src/observer/omt/ob_multi_tenant.cpp @@ -119,6 +119,8 @@ #include "logservice/leader_coordinator/ob_leader_coordinator.h" #include "storage/lob/ob_lob_manager.h" #include "share/deadlock/ob_deadlock_detector_mgr.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.h" +#include "rootserver/restore/ob_clone_scheduler.h" #ifdef OB_BUILD_SPM #include "sql/spm/ob_plan_baseline_mgr.h" #endif @@ -152,6 +154,7 @@ #include "observer/table/ob_htable_lock_mgr.h" #include "observer/table/ob_table_session_pool.h" #include "observer/ob_server_event_history_table_operator.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_service.h" #include "share/index_usage/ob_index_usage_info_mgr.h" using namespace oceanbase; @@ -492,6 +495,8 @@ int ObMultiTenant::init(ObAddr myaddr, MTL_BIND2(mtl_new_default, rootserver::ObArchiveSchedulerService::mtl_init, nullptr, rootserver::ObArchiveSchedulerService::mtl_stop, rootserver::ObArchiveSchedulerService::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObGlobalAutoIncService::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, share::detector::ObDeadLockDetectorMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObTenantSnapshotScheduler::mtl_init, nullptr, rootserver::ObTenantSnapshotScheduler::mtl_stop, rootserver::ObTenantSnapshotScheduler::mtl_wait, mtl_destroy_default); + MTL_BIND2(mtl_new_default, rootserver::ObCloneScheduler::mtl_init, nullptr, rootserver::ObCloneScheduler::mtl_stop, rootserver::ObCloneScheduler::mtl_wait, mtl_destroy_default); #ifdef OB_BUILD_ARBITRATION MTL_BIND2(mtl_new_default, ObPlanBaselineMgr::mtl_init, nullptr, ObPlanBaselineMgr::mtl_stop, ObPlanBaselineMgr::mtl_wait, mtl_destroy_default); #endif @@ -559,6 +564,7 @@ int ObMultiTenant::init(ObAddr myaddr, MTL_BIND2(mtl_new_default, ObOptStatMonitorManager::mtl_init, ObOptStatMonitorManager::mtl_start, ObOptStatMonitorManager::mtl_stop, ObOptStatMonitorManager::mtl_wait, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObTenantSrs::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, table::ObTableApiSessPoolMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, ObTenantSnapshotService::mtl_init, mtl_start_default, mtl_stop_default, nullptr, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObIndexUsageInfoMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, storage::ObTabletMemtableMgrPool::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); } diff --git a/src/observer/virtual_table/ob_all_virtual_ls_snapshot.cpp b/src/observer/virtual_table/ob_all_virtual_ls_snapshot.cpp new file mode 100644 index 0000000000..ee3024ae3a --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_ls_snapshot.cpp @@ -0,0 +1,287 @@ +/** + * Copyright (c) 2021 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 "observer/virtual_table/ob_all_virtual_ls_snapshot.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_service.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h" + +using namespace oceanbase::common; +using namespace oceanbase::storage; +namespace oceanbase +{ +namespace observer +{ + +ObAllVirtualLSSnapshot::ObAllVirtualLSSnapshot() + : ObVirtualTableScannerIterator(), + addr_(), + ls_meta_package_buf_(nullptr), + ls_snapshot_key_arr_(), + ls_snap_idx_(0) +{ +} + +ObAllVirtualLSSnapshot::~ObAllVirtualLSSnapshot() +{ + reset(); +} + +void ObAllVirtualLSSnapshot::reset() +{ + // Multi tenant resources should be released by ObMultiTenantOperator, call ObMultiTenantOperator::reset first + omt::ObMultiTenantOperator::reset(); + ObVirtualTableScannerIterator::reset(); + addr_.reset(); + ls_meta_package_buf_ = nullptr; + ls_snapshot_key_arr_.reset(); + ls_snap_idx_ = 0; +} + +int ObAllVirtualLSSnapshot::inner_open() +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(OB_ISNULL(allocator_))) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "allocator_ is null", KR(ret)); + } else if (OB_ISNULL(ls_meta_package_buf_ = static_cast(allocator_->alloc(LS_META_BUFFER_SIZE)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + SERVER_LOG(WARN, "fail to alloc memory for ls_meta_package_buf_", KR(ret), KP(allocator_)); + } + return ret; +} + +int ObAllVirtualLSSnapshot::inner_get_next_row(ObNewRow *&row) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(execute(row))) { + SERVER_LOG(WARN, "fail to execute inner_get_next_row", KR(ret)); + } + return ret; +} + +bool ObAllVirtualLSSnapshot::is_need_process(uint64_t tenant_id) +{ + return is_sys_tenant(effective_tenant_id_) || effective_tenant_id_ == tenant_id; +} + +void ObAllVirtualLSSnapshot::release_last_tenant() +{ + ls_snapshot_key_arr_.reset(); + ls_snap_idx_ = 0; +} + +int ObAllVirtualLSSnapshot::process_curr_tenant(ObNewRow *&row) +{ + int ret = OB_SUCCESS; + + ObTenantSnapshotService *tenant_snapshot_service = nullptr; + if (OB_UNLIKELY(OB_ISNULL(tenant_snapshot_service = MTL(ObTenantSnapshotService*)))) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "ObTenantSnapshotService is null", KR(ret)); + } else if (ls_snapshot_key_arr_.empty()) { + if (OB_FAIL(tenant_snapshot_service->get_all_ls_snapshot_keys(ls_snapshot_key_arr_))) { + SERVER_LOG(WARN, "fail to get_all_ls_snapshot_keys", KR(ret)); + } + } + + if (OB_SUCC(ret)) { + HEAP_VAR(ObLSSnapshotVTInfo, ls_snap_info){ + if (OB_FAIL(get_next_ls_snapshot_vt_info_(ls_snap_info))) { + SERVER_LOG(WARN, "fail to get ls_snapshot info", KR(ret)); + } else if (OB_FAIL(fill_row_(ls_snap_info))){ + SERVER_LOG(WARN, "fail to fill cur_row_", KR(ret), K(ls_snap_info)); + } + } + } + + if (OB_SUCC(ret)) { + row = &cur_row_; + } + return ret; +} + +int ObAllVirtualLSSnapshot::get_next_ls_snapshot_vt_info_(ObLSSnapshotVTInfo &ls_snap_info) +{ + int ret = OB_SUCCESS; + + bool try_next_loop = false; + do { + try_next_loop = false; + ObLSSnapshotMapKey ls_snap_map_key; + if (ls_snap_idx_ >= ls_snapshot_key_arr_.size()) { + ret = OB_ITER_END; + SERVER_LOG(INFO, "iterate current tenant reach end", + K(ls_snap_idx_), K(ls_snapshot_key_arr_.size())); + } else if (OB_UNLIKELY(ls_snap_idx_ < 0)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "ls_snap_idx_ out of bound", KR(ret), K(ls_snap_idx_), + K(ls_snapshot_key_arr_.size())); + } else { + ls_snap_map_key = ls_snapshot_key_arr_.at(ls_snap_idx_); + ObTenantSnapshotService *tenant_snapshot_service = MTL(ObTenantSnapshotService*); + if (OB_UNLIKELY(OB_ISNULL(tenant_snapshot_service))) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "ObTenantSnapshotService is unexpected nullptr", KR(ret)); + } else if (OB_FAIL(tenant_snapshot_service->get_ls_snapshot_vt_info(ls_snap_map_key, + ls_snap_info))) { + if (OB_ENTRY_NOT_EXIST != ret){ + SERVER_LOG(WARN, "fail to get ls_snapshot info", KR(ret), K(ls_snap_map_key)); + } else { + // ls snapshot may be removed by concurrent thread, skip it + SERVER_LOG(INFO, "ls snapshot entry not exist, try next", + KR(ret), K(ls_snap_map_key), K(ls_snap_idx_), K(ls_snapshot_key_arr_.size())); + ++ls_snap_idx_; + try_next_loop = true; + ret = OB_SUCCESS; + } + } else { + ++ls_snap_idx_; + try_next_loop = false; + } + } + } while (OB_SUCC(ret) && try_next_loop); + + return ret; +} + +int ObAllVirtualLSSnapshot::fill_row_(ObLSSnapshotVTInfo &ls_snap_info) +{ + int ret = OB_SUCCESS; + + ObLSSnapshotBuildCtxVTInfo &build_ctx_info = ls_snap_info.get_build_ctx_info(); + ObTenantSnapshotVTInfo &tsnap_info = ls_snap_info.get_tsnap_info(); + const int64_t col_count = output_column_ids_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < col_count; ++i) { + uint64_t col_id = output_column_ids_.at(i); + switch (col_id) { + case TENANT_ID: + cur_row_.cells_[i].set_int(MTL_ID()); + break; + case SNAPSHOT_ID: + cur_row_.cells_[i].set_int(ls_snap_info.get_tenant_snapshot_id().id()); + break; + case LS_ID: + cur_row_.cells_[i].set_int(ls_snap_info.get_ls_id().id()); + break; + case SVR_IP: + if (addr_.ip_to_string(ip_buf_, sizeof(ip_buf_))) { + cur_row_.cells_[i].set_varchar(ip_buf_); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation( + ObCharset::get_default_charset())); + } else { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "fail to execute ip_to_string", KR(ret), K(addr_)); + } + break; + case SVR_PORT: + cur_row_.cells_[i].set_int(addr_.get_port()); + break; + case META_EXISTED: + cur_row_.cells_[i].set_bool(ls_snap_info.get_meta_existed()); + break; + case BUILD_STATUS: + if (ls_snap_info.get_has_build_ctx()) { + cur_row_.cells_[i].set_varchar(build_ctx_info.get_build_status()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case REBUILD_SEQ_START: + if(ls_snap_info.get_has_build_ctx()) { + cur_row_.cells_[i].set_int(build_ctx_info.get_rebuild_seq_start()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case REBUILD_SEQ_END: + if (ls_snap_info.get_has_build_ctx()) { + cur_row_.cells_[i].set_int(build_ctx_info.get_rebuild_seq_end()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case END_INTERVAL_SCN: + if (ls_snap_info.get_has_build_ctx()) { + cur_row_.cells_[i].set_int(build_ctx_info.get_end_interval_scn().get_val_for_inner_table_field()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case LS_META_PACKAGE: + if (ls_snap_info.get_has_build_ctx()) { + int64_t length = 0; + if (OB_UNLIKELY(OB_ISNULL(ls_meta_package_buf_))) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "ls_meta_package_buf_ is null", KR(ret)); + } else if ((length = build_ctx_info.get_ls_meta_package().to_string(ls_meta_package_buf_, + LS_META_BUFFER_SIZE)) <= 0) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "fail to get ls_meta_package str", + KR(ret), K(ls_meta_package_buf_), K(build_ctx_info.get_ls_meta_package())); + } else { + cur_row_.cells_[i].set_lob_value(ObObjType::ObLongTextType, ls_meta_package_buf_, + static_cast(length)); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation( + ObCharset::get_default_charset())); + } + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case TSNAP_IS_RUNNING: + if (ls_snap_info.get_has_tsnap_info()){ + cur_row_.cells_[i].set_bool(tsnap_info.get_tsnap_is_running()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case TSNAP_HAS_UNFINISHED_CREATE_DAG: + if (ls_snap_info.get_has_tsnap_info()){ + cur_row_.cells_[i].set_bool(tsnap_info.get_tsnap_has_unfinished_create_dag()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case TSNAP_HAS_UNFINISHED_GC_DAG: + if (ls_snap_info.get_has_tsnap_info()){ + cur_row_.cells_[i].set_bool(tsnap_info.get_tsnap_has_unfinished_gc_dag()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case TSNAP_CLONE_REF: + if (ls_snap_info.get_has_tsnap_info()){ + cur_row_.cells_[i].set_int(tsnap_info.get_tsnap_clone_ref()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + case TSNAP_META_EXISTED: + if (ls_snap_info.get_has_tsnap_info()){ + cur_row_.cells_[i].set_bool(tsnap_info.get_tsnap_meta_existed()); + } else { // reset to display NULL + cur_row_.cells_[i].reset(); + } + break; + default: + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected col id", KR(ret), K(col_id), K(output_column_ids_)); + break; + } + } + return ret; +} + +} // observer +} // oceanbase diff --git a/src/observer/virtual_table/ob_all_virtual_ls_snapshot.h b/src/observer/virtual_table/ob_all_virtual_ls_snapshot.h new file mode 100644 index 0000000000..c3c74de764 --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_ls_snapshot.h @@ -0,0 +1,86 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OB_OBSERVER_OB_ALL_VIRTUAL_LS_SNAPSHOT_IN_STORAGE_NODE_H +#define OB_OBSERVER_OB_ALL_VIRTUAL_LS_SNAPSHOT_IN_STORAGE_NODE_H + +#include "observer/omt/ob_multi_tenant_operator.h" +#include "share/ob_virtual_table_scanner_iterator.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_mgr.h" + +namespace oceanbase +{ +namespace storage +{ +class ObLSSnapshotVTInfo; +}; + +namespace observer +{ + +class ObAllVirtualLSSnapshot : public common::ObVirtualTableScannerIterator, + public omt::ObMultiTenantOperator +{ +public: + ObAllVirtualLSSnapshot(); + virtual ~ObAllVirtualLSSnapshot(); + +public: + virtual int inner_open(); + virtual int inner_get_next_row(common::ObNewRow *&row); + virtual void reset(); + inline void set_addr(ObAddr &addr) { + addr_ = addr; + } + +private: + enum COLUMN_ID_LIST + { + TENANT_ID = common::OB_APP_MIN_COLUMN_ID, + SNAPSHOT_ID, + LS_ID, + SVR_IP, + SVR_PORT, + META_EXISTED, + BUILD_STATUS, + REBUILD_SEQ_START, + REBUILD_SEQ_END, + END_INTERVAL_SCN, + LS_META_PACKAGE, + TSNAP_IS_RUNNING, + TSNAP_HAS_UNFINISHED_CREATE_DAG, + TSNAP_HAS_UNFINISHED_GC_DAG, + TSNAP_CLONE_REF, + TSNAP_META_EXISTED + }; + virtual bool is_need_process(uint64_t tenant_id) override; + virtual int process_curr_tenant(common::ObNewRow *&row) override; + virtual void release_last_tenant() override; + int get_next_ls_snapshot_vt_info_(ObLSSnapshotVTInfo &ls_snapshot_vt_info); + int fill_row_(ObLSSnapshotVTInfo &ls_snap_info); + +private: + static constexpr int64_t LS_META_BUFFER_SIZE = 16384; + + common::ObAddr addr_; + char *ls_meta_package_buf_; + char ip_buf_[common::OB_IP_STR_BUFF]; + ObArray ls_snapshot_key_arr_; + int64_t ls_snap_idx_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObAllVirtualLSSnapshot); +}; + +} // namespace observer +} // namespace oceanbase +#endif // OB_OBSERVER_OB_ALL_VIRTUAL_LS_SNAPSHOT_IN_STORAGE_NODE_H diff --git a/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.cpp b/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.cpp new file mode 100644 index 0000000000..b1b387ad88 --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.cpp @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2021 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 "observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.h" +#include "lib/string/ob_hex_utils_base.h" + +using namespace oceanbase::common; +using namespace oceanbase::storage; + +namespace oceanbase +{ +namespace observer +{ + +ObAllVirtualTenantSnapshotLSReplica::ObAllVirtualTenantSnapshotLSReplica(): + common::ObVirtualTableScannerIterator(), + ls_meta_buf_(nullptr), + sql_res_(nullptr), + result_(nullptr) +{ +} + +ObAllVirtualTenantSnapshotLSReplica::~ObAllVirtualTenantSnapshotLSReplica() +{ + reset(); +} + +void ObAllVirtualTenantSnapshotLSReplica::reset() +{ + omt::ObMultiTenantOperator::reset(); + ObVirtualTableScannerIterator::reset(); + result_ = nullptr; + if (OB_NOT_NULL(sql_res_)) { + sql_res_->~ReadResult(); + if (OB_NOT_NULL(allocator_)) { + allocator_->free(sql_res_); + } + sql_res_ = nullptr; + } + if (OB_NOT_NULL(ls_meta_buf_)) { + if (OB_NOT_NULL(allocator_)) { + allocator_->free(ls_meta_buf_); + } + ls_meta_buf_ = nullptr; + } +} + +int ObAllVirtualTenantSnapshotLSReplica::inner_open() +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(allocator_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "allocator_ is null", KR(ret)); + } else if (OB_ISNULL(sql_res_ = OB_NEWx(ObMySQLProxy::MySQLResult, allocator_))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + SERVER_LOG(WARN, "fail to alloc memory for MySQLResult", KR(ret)); + } else if (OB_ISNULL(ls_meta_buf_ = static_cast(allocator_->alloc(LS_META_BUFFER_SIZE)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + SERVER_LOG(WARN, "fail to alloc memory for ls_meta_buf_", KR(ret), KP(allocator_)); + } + return ret; +} + +int ObAllVirtualTenantSnapshotLSReplica::inner_get_next_row(ObNewRow *&row) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(execute(row))) { + SERVER_LOG(WARN, "fail to execute inner_get_next_row", KR(ret)); + } + return ret; +} + +bool ObAllVirtualTenantSnapshotLSReplica::is_need_process(uint64_t tenant_id) +{ + return is_sys_tenant(effective_tenant_id_) || tenant_id == effective_tenant_id_; +} + +int ObAllVirtualTenantSnapshotLSReplica::process_curr_tenant(ObNewRow *&row) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(result_)) { + if (OB_FAIL(get_tenant_snapshot_ls_replica_entries_())) { + SERVER_LOG(WARN, "fail to get ls_replica result", KR(ret)); + } + } + + if (OB_FAIL(ret)) { + SERVER_LOG(DEBUG, "fail to get ls_replica result", KR(ret)); + } else if (OB_ISNULL(result_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "sql result is null", KR(ret)); + } else if (OB_SUCC(result_->next())) { + const ObNewRow *r = result_->get_row(); + if (OB_ISNULL(r) + || OB_ISNULL(r->cells_) + || r->get_count() < cur_row_.count_) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "row is null or column count mismatch", KR(ret), KP(r), K(cur_row_.count_)); + } else { + ObString ls_meta_package_str; + HEAP_VAR(ObLSMetaPackage, ls_meta_package) { + for (int64_t i = 0; OB_SUCC(ret) && i < cur_row_.count_; ++i) { + uint64_t col_id = output_column_ids_.at(i); + if (LS_META_PACKAGE == col_id) { // decode ls_meta_package column + int64_t length = 0; + EXTRACT_VARCHAR_FIELD_MYSQL(*result_, "ls_meta_package", ls_meta_package_str); + if (OB_ISNULL(ls_meta_buf_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "ls_meta_buf_ is null", KR(ret), KP(ls_meta_buf_), KP(allocator_)); + } else if (OB_FAIL(decode_hex_string_to_package_(ls_meta_package_str, *allocator_, ls_meta_package))){ + SERVER_LOG(WARN, "fail to decode hex string into ls_meta_package", KR(ret)); + } else if ((length = ls_meta_package.to_string(ls_meta_buf_, LS_META_BUFFER_SIZE)) <= 0) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "fail to get ls_meta_package string", KR(ret), K(length)); + } else { + cur_row_.cells_[i].set_lob_value(ObObjType::ObLongTextType, ls_meta_buf_, + static_cast(length)); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation( + ObCharset::get_default_charset())); + } + } else if (col_id - OB_APP_MIN_COLUMN_ID >= 0 && col_id - OB_APP_MIN_COLUMN_ID < r->count_) { + // direct copy other columns + cur_row_.cells_[i] = r->get_cell(col_id - OB_APP_MIN_COLUMN_ID); + } else { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected column id", KR(ret), K(col_id), K(output_column_ids_)); + } + } + } + } + } + + if (OB_SUCC(ret)) { + row = &cur_row_; + } + return ret; +} + +int ObAllVirtualTenantSnapshotLSReplica::decode_hex_string_to_package_(const ObString& hex_str, + ObIAllocator& allocator, + ObLSMetaPackage& ls_meta_package) +{ + int ret = OB_SUCCESS; + char *unhex_buf = nullptr; + int64_t unhex_buf_len = 0; + int64_t pos = 0; + ls_meta_package.reset(); + if (hex_str.empty()) { + ret = OB_INVALID_ARGUMENT; + SERVER_LOG(WARN, "invalid argument", KR(ret), K(hex_str)); + } else if (OB_FAIL(ObHexUtilsBase::unhex(hex_str, allocator, unhex_buf, unhex_buf_len))) { + SERVER_LOG(WARN, "fail to unhex", KR(ret), K(hex_str)); + } else if (OB_FAIL(ls_meta_package.deserialize(unhex_buf, unhex_buf_len, pos))) { + SERVER_LOG(WARN, "deserialize ls meta package failed", KR(ret), K(hex_str)); + } + return ret; +} + +int ObAllVirtualTenantSnapshotLSReplica::get_tenant_snapshot_ls_replica_entries_() +{ + int ret = OB_SUCCESS; + + ObSqlString sql; + int64_t user_tenant_id = MTL_ID(); + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(ERROR, "sql_proxy is null", KR(ret)); + } else if (OB_FAIL(sql.assign_fmt("SELECT tenant_id, snapshot_id, ls_id, svr_ip, svr_port, " + "gmt_create, gmt_modified, status, zone, unit_id, " + "begin_interval_scn, end_interval_scn, ls_meta_package " + "FROM %s " + "WHERE tenant_id = %lu", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id))) { + SERVER_LOG(WARN, "fail to assign sql", KR(ret), K(sql)); + } else if (OB_ISNULL(sql_res_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "sql_res_ is null", KR(ret)); + } else if (OB_FAIL(GCTX.sql_proxy_->read(*sql_res_, gen_meta_tenant_id(user_tenant_id), sql.ptr()))) { + SERVER_LOG(WARN, "fail to execute sql", KR(ret), K(sql)); + } else if (OB_ISNULL(result_ = sql_res_->get_result())) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "sql result is null", KR(ret)); + } + return ret; +} + +void ObAllVirtualTenantSnapshotLSReplica::release_last_tenant() +{ + if (OB_NOT_NULL(sql_res_)) { + sql_res_->reset(); + } + result_ = nullptr; +} + +} //observer +} //oceanbase diff --git a/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.h b/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.h new file mode 100644 index 0000000000..b13d47ce5a --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OB_OBSERVER_OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_H +#define OB_OBSERVER_OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_H + +#include "observer/omt/ob_multi_tenant_operator.h" +#include "share/ob_virtual_table_scanner_iterator.h" +#include "storage/ls/ob_ls_meta_package.h" + +namespace oceanbase { +namespace observer { + +class ObAllVirtualTenantSnapshotLSReplica : public common::ObVirtualTableScannerIterator, + public omt::ObMultiTenantOperator +{ +public: + ObAllVirtualTenantSnapshotLSReplica(); + virtual ~ObAllVirtualTenantSnapshotLSReplica(); + + virtual int inner_get_next_row(common::ObNewRow *&row); + virtual void reset(); + virtual int inner_open(); + +private: + enum COLUMN_ID_LIST + { + TENANT_ID = common::OB_APP_MIN_COLUMN_ID, + SNAPSHOT_ID, + LS_ID, + SVR_IP, + SVR_PORT, + GMT_CREATE, + GMT_MODIFIED, + STATUS, + ZONE, + UNIT_ID, + BEGIN_INTERVAL_SCN, + END_INTERVAL_SCN, + LS_META_PACKAGE + }; + virtual bool is_need_process(uint64_t tenant_id) override; + virtual int process_curr_tenant(common::ObNewRow *&row) override; + virtual void release_last_tenant() override; + int decode_hex_string_to_package_(const ObString& hex_str, + ObIAllocator& allocator, + ObLSMetaPackage& ls_meta_package); + int get_tenant_snapshot_ls_replica_entries_(); + +private: + static const int64_t LS_META_BUFFER_SIZE = 16 * 1024; + char *ls_meta_buf_; + common::ObMySQLProxy::MySQLResult *sql_res_; + common::sqlclient::ObMySQLResult *result_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObAllVirtualTenantSnapshotLSReplica); +}; + +} // namespace observer +} // namespace oceanbase +#endif // OB_OBSERVER_OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_H diff --git a/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.cpp b/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.cpp new file mode 100644 index 0000000000..196643f321 --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.cpp @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2021 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 "observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.h" +#include "lib/string/ob_hex_utils_base.h" + +using namespace oceanbase::common; +using namespace oceanbase::storage; + +namespace oceanbase +{ +namespace observer +{ + +ObAllVirtualTenantSnapshotLSReplicaHistory::ObAllVirtualTenantSnapshotLSReplicaHistory(): + common::ObVirtualTableScannerIterator(), + ls_meta_buf_(nullptr), + sql_res_(nullptr), + result_(nullptr) +{ +} + +ObAllVirtualTenantSnapshotLSReplicaHistory::~ObAllVirtualTenantSnapshotLSReplicaHistory() +{ + reset(); +} + +void ObAllVirtualTenantSnapshotLSReplicaHistory::reset() +{ + omt::ObMultiTenantOperator::reset(); + ObVirtualTableScannerIterator::reset(); + result_ = nullptr; + if (OB_NOT_NULL(sql_res_)) { + sql_res_->~ReadResult(); + if (OB_NOT_NULL(allocator_)) { + allocator_->free(sql_res_); + } + sql_res_ = nullptr; + } + if (OB_NOT_NULL(ls_meta_buf_)) { + if (OB_NOT_NULL(allocator_)) { + allocator_->free(ls_meta_buf_); + } + ls_meta_buf_ = nullptr; + } +} + +int ObAllVirtualTenantSnapshotLSReplicaHistory::inner_open() +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(allocator_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "allocator_ is null", KR(ret)); + } else if (OB_ISNULL(sql_res_ = OB_NEWx(ObMySQLProxy::MySQLResult, allocator_))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + SERVER_LOG(WARN, "fail to alloc memory for MySQLResult", KR(ret)); + } else if (OB_ISNULL(ls_meta_buf_ = static_cast(allocator_->alloc(LS_META_BUFFER_SIZE)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + SERVER_LOG(WARN, "fail to alloc memory for ls_meta_buf_", KR(ret), KP(allocator_)); + } + return ret; +} + +int ObAllVirtualTenantSnapshotLSReplicaHistory::inner_get_next_row(ObNewRow *&row) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(execute(row))) { + SERVER_LOG(WARN, "fail to execute inner_get_next_row", KR(ret)); + } + return ret; +} + +bool ObAllVirtualTenantSnapshotLSReplicaHistory::is_need_process(uint64_t tenant_id) +{ + return is_sys_tenant(effective_tenant_id_) || tenant_id == effective_tenant_id_; +} + +int ObAllVirtualTenantSnapshotLSReplicaHistory::process_curr_tenant(ObNewRow *&row) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(result_)) { + if (OB_FAIL(get_tenant_snapshot_ls_replica_entries_())) { + SERVER_LOG(WARN, "fail to get ls_replica result", KR(ret)); + } + } + + if (OB_FAIL(ret)) { + SERVER_LOG(DEBUG, "fail to get ls_replica result", KR(ret)); + } else if (OB_ISNULL(result_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "sql result is null", KR(ret)); + } else if (OB_SUCC(result_->next())) { + const ObNewRow *r = result_->get_row(); + if (OB_ISNULL(r) + || OB_ISNULL(r->cells_) + || r->get_count() < cur_row_.count_) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "row is null or column count mismatch", KR(ret), KP(r), K(cur_row_.count_)); + } else { + ObString ls_meta_package_str; + HEAP_VAR(ObLSMetaPackage, ls_meta_package) { + for (int64_t i = 0; OB_SUCC(ret) && i < cur_row_.count_; ++i) { + uint64_t col_id = output_column_ids_.at(i); + if (LS_META_PACKAGE == col_id) { // decode ls_meta_package column + int64_t length = 0; + EXTRACT_VARCHAR_FIELD_MYSQL(*result_, "ls_meta_package", ls_meta_package_str); + if (OB_ISNULL(ls_meta_buf_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "ls_meta_buf_ is null", KR(ret), KP(ls_meta_buf_), KP(allocator_)); + } else if (OB_FAIL(decode_hex_string_to_package_(ls_meta_package_str, *allocator_, ls_meta_package))){ + SERVER_LOG(WARN, "fail to decode hex string into ls_meta_package", KR(ret)); + } else if ((length = ls_meta_package.to_string(ls_meta_buf_, LS_META_BUFFER_SIZE)) <= 0) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "fail to get ls_meta_package string", KR(ret), K(length)); + } else { + cur_row_.cells_[i].set_lob_value(ObObjType::ObLongTextType, ls_meta_buf_, + static_cast(length)); + cur_row_.cells_[i].set_collation_type(ObCharset::get_default_collation( + ObCharset::get_default_charset())); + } + } else if (col_id - OB_APP_MIN_COLUMN_ID >= 0 && col_id - OB_APP_MIN_COLUMN_ID < r->count_) { + // direct copy other columns + cur_row_.cells_[i] = r->get_cell(col_id - OB_APP_MIN_COLUMN_ID); + } else { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "unexpected column id", KR(ret), K(col_id), K(output_column_ids_)); + } + } + } + } + } + + if (OB_SUCC(ret)) { + row = &cur_row_; + } + return ret; +} + +int ObAllVirtualTenantSnapshotLSReplicaHistory::decode_hex_string_to_package_(const ObString& hex_str, + ObIAllocator& allocator, + ObLSMetaPackage& ls_meta_package) +{ + int ret = OB_SUCCESS; + char *unhex_buf = nullptr; + int64_t unhex_buf_len = 0; + int64_t pos = 0; + ls_meta_package.reset(); + if (hex_str.empty()) { + ret = OB_INVALID_ARGUMENT; + SERVER_LOG(WARN, "invalid argument", KR(ret), K(hex_str)); + } else if (OB_FAIL(ObHexUtilsBase::unhex(hex_str, allocator, unhex_buf, unhex_buf_len))) { + SERVER_LOG(WARN, "fail to unhex", KR(ret), K(hex_str)); + } else if (OB_FAIL(ls_meta_package.deserialize(unhex_buf, unhex_buf_len, pos))) { + SERVER_LOG(WARN, "deserialize ls meta package failed", KR(ret), K(hex_str)); + } + return ret; +} + +int ObAllVirtualTenantSnapshotLSReplicaHistory::get_tenant_snapshot_ls_replica_entries_() +{ + int ret = OB_SUCCESS; + + ObSqlString sql; + int64_t user_tenant_id = MTL_ID(); + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(ERROR, "sql_proxy is null", KR(ret)); + } else if (OB_FAIL(sql.assign_fmt("SELECT tenant_id, snapshot_id, ls_id, svr_ip, svr_port, " + "gmt_create, gmt_modified, status, zone, unit_id, " + "begin_interval_scn, end_interval_scn, ls_meta_package " + "FROM %s " + "WHERE tenant_id = %lu", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME, + user_tenant_id))) { + SERVER_LOG(WARN, "fail to assign sql", KR(ret), K(sql)); + } else if (OB_ISNULL(sql_res_)) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "sql_res_ is null", KR(ret)); + } else if (OB_FAIL(GCTX.sql_proxy_->read(*sql_res_, gen_meta_tenant_id(user_tenant_id), sql.ptr()))) { + SERVER_LOG(WARN, "fail to execute sql", KR(ret), K(sql)); + } else if (OB_ISNULL(result_ = sql_res_->get_result())) { + ret = OB_ERR_UNEXPECTED; + SERVER_LOG(WARN, "sql result is null", KR(ret)); + } + return ret; +} + +void ObAllVirtualTenantSnapshotLSReplicaHistory::release_last_tenant() +{ + if (OB_NOT_NULL(sql_res_)) { + sql_res_->reset(); + } + result_ = nullptr; +} + +} //observer +} //oceanbase diff --git a/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.h b/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.h new file mode 100644 index 0000000000..1098db2027 --- /dev/null +++ b/src/observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.h @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OB_OBSERVER_OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_H +#define OB_OBSERVER_OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_H + +#include "observer/omt/ob_multi_tenant_operator.h" +#include "share/ob_virtual_table_scanner_iterator.h" +#include "storage/ls/ob_ls_meta_package.h" + +namespace oceanbase { +namespace observer { + +class ObAllVirtualTenantSnapshotLSReplicaHistory : public common::ObVirtualTableScannerIterator, + public omt::ObMultiTenantOperator +{ +public: + ObAllVirtualTenantSnapshotLSReplicaHistory(); + virtual ~ObAllVirtualTenantSnapshotLSReplicaHistory(); + + virtual int inner_get_next_row(common::ObNewRow *&row); + virtual void reset(); + virtual int inner_open(); + +private: + enum COLUMN_ID_LIST + { + TENANT_ID = common::OB_APP_MIN_COLUMN_ID, + SNAPSHOT_ID, + LS_ID, + SVR_IP, + SVR_PORT, + GMT_CREATE, + GMT_MODIFIED, + STATUS, + ZONE, + UNIT_ID, + BEGIN_INTERVAL_SCN, + END_INTERVAL_SCN, + LS_META_PACKAGE + }; + virtual bool is_need_process(uint64_t tenant_id) override; + virtual int process_curr_tenant(common::ObNewRow *&row) override; + virtual void release_last_tenant() override; + int decode_hex_string_to_package_(const ObString& hex_str, + ObIAllocator& allocator, + ObLSMetaPackage& ls_meta_package); + int get_tenant_snapshot_ls_replica_entries_(); + +private: + static const int64_t LS_META_BUFFER_SIZE = 16 * 1024; + char *ls_meta_buf_; + common::ObMySQLProxy::MySQLResult *sql_res_; + common::sqlclient::ObMySQLResult *result_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObAllVirtualTenantSnapshotLSReplicaHistory); +}; + +} // namespace observer +} // namespace oceanbase +#endif // OB_OBSERVER_OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_H diff --git a/src/observer/virtual_table/ob_virtual_show_trace.cpp b/src/observer/virtual_table/ob_virtual_show_trace.cpp index 80ceead5f8..5f0f273667 100644 --- a/src/observer/virtual_table/ob_virtual_show_trace.cpp +++ b/src/observer/virtual_table/ob_virtual_show_trace.cpp @@ -122,7 +122,7 @@ int ObVirtualShowTrace::retrive_all_span_info() { // make sure %res destructed before execute other sql in the same transaction SMART_VAR(ObMySQLProxy::MySQLResult, res) { - ObMySQLResult *result = NULL; + common::sqlclient::ObMySQLResult *result = NULL; ObISQLClient *sql_client = &trans; uint64_t table_id = OB_ALL_VIRTUAL_TRACE_SPAN_INFO_TID; ObSQLClientRetryWeak sql_client_retry_weak(sql_client, diff --git a/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp b/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp index 3f96cf6d44..a3eabfc339 100644 --- a/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp +++ b/src/observer/virtual_table/ob_virtual_table_iterator_factory.cpp @@ -80,6 +80,7 @@ #include "observer/virtual_table/ob_all_virtual_engine_table.h" #include "observer/virtual_table/ob_all_virtual_files_table.h" #include "observer/virtual_table/ob_all_virtual_ls_info.h" +#include "observer/virtual_table/ob_all_virtual_ls_snapshot.h" #include "observer/virtual_table/ob_all_plan_cache_stat.h" #include "observer/virtual_table/ob_plan_cache_plan_explain.h" #include "observer/virtual_table/ob_all_virtual_ps_stat.h" @@ -212,7 +213,8 @@ #include "observer/virtual_table/ob_all_virtual_ls_log_restore_status.h" #include "observer/virtual_table/ob_all_virtual_tablet_buffer_info.h" #include "observer/virtual_table/ob_virtual_flt_config.h" - +#include "observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica.h" +#include "observer/virtual_table/ob_all_virtual_tenant_snapshot_ls_replica_history.h" #include "observer/virtual_table/ob_all_virtual_kv_connection.h" #include "observer/virtual_table/ob_tenant_show_restore_preview.h" @@ -733,6 +735,26 @@ int ObVTIterCreator::create_vt_iter(ObVTableScanParam ¶ms, } break; } + case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TID: { + ObAllVirtualTenantSnapshotLSReplica *all_vtsnap_ls_replica = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllVirtualTenantSnapshotLSReplica, all_vtsnap_ls_replica))) { + SERVER_LOG(ERROR, "ObAllVirtualTenantSnapshotLSReplica construct failed", K(ret)); + } else { + all_vtsnap_ls_replica->set_allocator(&allocator); + vt_iter = static_cast(all_vtsnap_ls_replica); + } + break; + } + case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID: { + ObAllVirtualTenantSnapshotLSReplicaHistory *vtsnap_ls_replica_history = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllVirtualTenantSnapshotLSReplicaHistory, vtsnap_ls_replica_history))) { + SERVER_LOG(ERROR, "ObAllVirtualTenantSnapshotLSReplica construct failed", K(ret)); + } else { + vtsnap_ls_replica_history->set_allocator(&allocator); + vt_iter = static_cast(vtsnap_ls_replica_history); + } + break; + } case OB_ALL_VIRTUAL_LS_INFO_TID: { ObAllVirtualLSInfo *all_virtual_ls_info = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllVirtualLSInfo, all_virtual_ls_info))) { @@ -743,6 +765,17 @@ int ObVTIterCreator::create_vt_iter(ObVTableScanParam ¶ms, } break; } + case OB_ALL_VIRTUAL_LS_SNAPSHOT_TID: { + ObAllVirtualLSSnapshot *all_virtual_ls_snap = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllVirtualLSSnapshot, all_virtual_ls_snap))) { + SERVER_LOG(ERROR, "ObAllVirtualLSSnapshot construct failed", K(ret)); + } else { + all_virtual_ls_snap->set_addr(addr_); + all_virtual_ls_snap->set_allocator(&allocator); + vt_iter = static_cast(all_virtual_ls_snap); + } + break; + } case OB_ALL_VIRTUAL_OBJ_LOCK_TID: { ObAllVirtualObjLock *all_virtual_obj_lock = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObAllVirtualObjLock, all_virtual_obj_lock))) { diff --git a/src/rootserver/CMakeLists.txt b/src/rootserver/CMakeLists.txt index fd193040da..1dbeb24239 100644 --- a/src/rootserver/CMakeLists.txt +++ b/src/rootserver/CMakeLists.txt @@ -158,6 +158,9 @@ ob_set_subtarget(ob_rootserver restore restore/ob_restore_service.cpp restore/ob_restore_scheduler.cpp restore/ob_restore_util.cpp + restore/ob_tenant_clone_util.cpp + restore/ob_clone_scheduler.cpp + restore/ob_restore_common_util.cpp ) ob_set_subtarget(ob_rootserver virtual_table @@ -167,4 +170,9 @@ ob_set_subtarget(ob_rootserver virtual_table virtual_table/ob_all_virtual_ls_replica_task_plan.cpp ) +ob_set_subtarget(ob_rootserver tenant_snapshot + tenant_snapshot/ob_tenant_snapshot_scheduler.cpp + tenant_snapshot/ob_tenant_snapshot_util.cpp +) + ob_server_add_target(ob_rootserver) diff --git a/src/rootserver/backup/ob_backup_schedule_task.cpp b/src/rootserver/backup/ob_backup_schedule_task.cpp index 113453e2a5..95cdb5f897 100644 --- a/src/rootserver/backup/ob_backup_schedule_task.cpp +++ b/src/rootserver/backup/ob_backup_schedule_task.cpp @@ -422,7 +422,8 @@ int ObBackupDataBaseTask::set_optional_servers_(const ObIArray & const ObLSInfo::ReplicaArray &replica_array = ls_info.get_replicas(); for (int i = 0; OB_SUCC(ret) && i < replica_array.count(); ++i) { const ObLSReplica &replica = replica_array.at(i); - if (replica.is_in_service() && !replica.is_strong_leader() && replica.is_valid() && !replica.is_in_restore() + if (replica.is_in_service() && !replica.is_strong_leader() && replica.is_valid() + && replica.get_restore_status().is_none() && ObReplicaTypeCheck::is_full_replica(replica.get_replica_type()) // TODO(zeyong) 4.3 allow R replica backup later && !check_replica_in_black_server_(replica, black_servers)) { ObBackupServer server; @@ -434,7 +435,8 @@ int ObBackupDataBaseTask::set_optional_servers_(const ObIArray & } for (int i = 0; OB_SUCC(ret) && i < replica_array.count(); ++i) { const ObLSReplica &replica = replica_array.at(i); - if (replica.is_in_service() && replica.is_strong_leader() && replica.is_valid() && !replica.is_in_restore() + if (replica.is_in_service() && replica.is_strong_leader() && replica.is_valid() + && replica.get_restore_status().is_none() && (replica_array.count() == 1 || !check_replica_in_black_server_(replica, black_servers))) { // if only has one replica. no use black server. ObBackupServer server; diff --git a/src/rootserver/backup/ob_tenant_archive_scheduler.cpp b/src/rootserver/backup/ob_tenant_archive_scheduler.cpp index e99cc5070c..ec85f28f8e 100644 --- a/src/rootserver/backup/ob_tenant_archive_scheduler.cpp +++ b/src/rootserver/backup/ob_tenant_archive_scheduler.cpp @@ -27,6 +27,7 @@ #include "share/ls/ob_ls_operator.h" #include "share/scn.h" #include "share/ob_debug_sync.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" using namespace oceanbase; using namespace rootserver; @@ -458,6 +459,7 @@ int ObArchiveHandler::close_archive_mode() { int ret = OB_SUCCESS; ObArchiveMode archive_mode; + bool has_tenant_snapshot = false; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("tenant archive scheduler not init", K(ret)); @@ -470,6 +472,13 @@ int ObArchiveHandler::close_archive_mode() ret = OB_ALREADY_IN_NOARCHIVE_MODE; LOG_USER_ERROR(OB_ALREADY_IN_NOARCHIVE_MODE); LOG_WARN("already in noarchive mode", K(ret), K_(tenant_id)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_has_snapshot(*sql_proxy_, + tenant_id_, has_tenant_snapshot))) { + LOG_WARN("failed to check whether tenant has snapshot", K(ret)); + } else if (has_tenant_snapshot) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("can not close log archive while tenant snapshots exist", KR(ret)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant snapshots exist, close log archive"); } else if (OB_FAIL(archive_table_op_.close_archive_mode(*sql_proxy_))) { LOG_WARN("failed to close archive mode", K(ret), K_(tenant_id)); } else { @@ -589,10 +598,18 @@ int ObArchiveHandler::disable_archive(const int64_t dest_no) int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; ObTenantArchiveRoundAttr new_round_attr; + bool has_tenant_snapshot = false; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("tenant archive scheduler not init", K(ret)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_has_snapshot(*sql_proxy_, + tenant_id_, has_tenant_snapshot))) { + LOG_WARN("failed to check whether tenant has snapshot", K(ret)); + } else if (has_tenant_snapshot) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("can not disable archive while tenant snapshots exist", KR(ret)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant snapshots exist, disable log archive"); } else if (OB_FAIL(round_handler_.disable_archive(dest_no, new_round_attr))) { LOG_WARN("failed to disable archive", K(ret), K_(tenant_id), K(dest_no)); } else { diff --git a/src/rootserver/ob_balance_group_ls_stat_operator.cpp b/src/rootserver/ob_balance_group_ls_stat_operator.cpp index eea76b6864..5169db1f81 100755 --- a/src/rootserver/ob_balance_group_ls_stat_operator.cpp +++ b/src/rootserver/ob_balance_group_ls_stat_operator.cpp @@ -1683,6 +1683,10 @@ int ObNewTableTabletAllocator::alloc_ls_for_duplicate_table_( LOG_WARN("failed to init arg", KR(ret), K(tenant_id)); } else if (OB_TMP_FAIL(GCTX.srv_rpc_proxy_->to(leader).timeout(timeout).notify_create_duplicate_ls(arg, result))) { LOG_WARN("failed to create tenant duplicate ls", KR(tmp_ret), K(tenant_id), K(leader), K(arg), K(timeout)); + if (OB_CONFLICT_WITH_CLONE == tmp_ret) { + ret = tmp_ret; + LOG_WARN("tenant is in clone procedure, can not create new log stream for now", KR(ret), K(tenant_id), K(arg)); + } } } else { LOG_WARN("fail to get duplicate log stream from table", KR(tmp_ret), K(tenant_id)); diff --git a/src/rootserver/ob_bootstrap.cpp b/src/rootserver/ob_bootstrap.cpp index 3630e11d87..8ecb9fa194 100644 --- a/src/rootserver/ob_bootstrap.cpp +++ b/src/rootserver/ob_bootstrap.cpp @@ -1523,7 +1523,7 @@ int ObBootstrap::create_sys_resource_pool() } else if (OB_FAIL(unit_mgr_.grant_pools( trans, new_ug_id_array, lib::Worker::CompatMode::MYSQL, pool_names, - OB_SYS_TENANT_ID, is_bootstrap))) { + OB_SYS_TENANT_ID, is_bootstrap, OB_INVALID_TENANT_ID/*source_tenant_id*/))) { LOG_WARN("grant_pools_to_tenant failed", K(pool_names), "tenant_id", static_cast(OB_SYS_TENANT_ID), K(ret)); } else { diff --git a/src/rootserver/ob_common_ls_service.cpp b/src/rootserver/ob_common_ls_service.cpp index 81227edd39..2e1177d84f 100755 --- a/src/rootserver/ob_common_ls_service.cpp +++ b/src/rootserver/ob_common_ls_service.cpp @@ -146,7 +146,7 @@ int ObCommonLSService::try_create_ls_(const share::schema::ObTenantSchema &tenan K(status_info)); } else if (OB_FAIL(do_create_user_ls(tenant_schema, status_info, recovery_stat.get_create_scn(), - false, palf_base_info))) { + false, palf_base_info, OB_INVALID_TENANT_ID/*source_tenant_id*/))) { LOG_WARN("failed to create new ls", KR(ret), K(status_info), K(recovery_stat)); } @@ -208,7 +208,8 @@ int ObCommonLSService::try_modify_ls_unit_group_( int ObCommonLSService::do_create_user_ls( const share::schema::ObTenantSchema &tenant_schema, const share::ObLSStatusInfo &info, const SCN &create_scn, - bool create_with_palf, const palf::PalfBaseInfo &palf_base_info) + bool create_with_palf, const palf::PalfBaseInfo &palf_base_info, + const uint64_t source_tenant_id) { int ret = OB_SUCCESS; LOG_INFO("[COMMON_LS_SERVICE] start to create ls", K(info), K(create_scn)); @@ -234,9 +235,10 @@ int ObCommonLSService::do_create_user_ls( locality_array, create_scn, tenant_schema.get_compatibility_mode(), create_with_palf, - palf_base_info))) { + palf_base_info, + source_tenant_id))) { LOG_WARN("failed to create user ls", KR(ret), K(info), K(locality_array), K(create_scn), - K(palf_base_info), K(create_with_palf)); + K(palf_base_info), K(create_with_palf), K(source_tenant_id)); } } } diff --git a/src/rootserver/ob_common_ls_service.h b/src/rootserver/ob_common_ls_service.h index ac9e5e13fb..4a08b3cba3 100644 --- a/src/rootserver/ob_common_ls_service.h +++ b/src/rootserver/ob_common_ls_service.h @@ -95,7 +95,8 @@ public: const share::ObLSStatusInfo &info, const SCN &create_scn, bool create_with_palf, - const palf::PalfBaseInfo &palf_base_info); + const palf::PalfBaseInfo &palf_base_info, + const uint64_t source_tenant_id); static int update_tenant_info(const uint64_t tenant_id, const share::ObTenantSwitchoverStatus &staus, ObMySQLProxy *proxy); diff --git a/src/rootserver/ob_ddl_service.cpp b/src/rootserver/ob_ddl_service.cpp index 8557ff2e74..4fe223ec77 100755 --- a/src/rootserver/ob_ddl_service.cpp +++ b/src/rootserver/ob_ddl_service.cpp @@ -116,6 +116,7 @@ #include "storage/tx_storage/ob_ls_map.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/tablelock/ob_lock_inner_connection_util.h" +#include "rootserver/restore/ob_tenant_clone_util.h" namespace oceanbase @@ -22429,9 +22430,20 @@ int ObDDLService::create_tenant( bool tenant_exist = false; if (OB_NOT_NULL(schema_guard.get_tenant_info(tenant_name))) { tenant_exist = true; - } else if (!arg.is_restore_) { - if (OB_FAIL(ObRestoreUtil::check_has_physical_restore_job(*sql_proxy_, tenant_name, tenant_exist))) { - LOG_WARN("failed to check has physical restore job", KR(ret), K(tenant_name)); + } else { + if (!arg.is_restore_tenant()) { + if (OB_FAIL(ObRestoreUtil::check_has_physical_restore_job(*sql_proxy_, tenant_name, tenant_exist))) { + LOG_WARN("failed to check has physical restore job", KR(ret), K(tenant_name)); + } + } + if (OB_FAIL(ret)) { + } else if (tenant_exist) { + // do nothing + } else if (!arg.is_clone_tenant()) { + // check whether has clone job, if has clone job then tenant_exist should be true + if (OB_FAIL(ObTenantCloneUtil::check_clone_tenant_exist(*sql_proxy_, tenant_name, tenant_exist))) { + LOG_WARN("failed to check clone tenant exist", KR(ret), K(tenant_name)); + } } } if (OB_FAIL(ret)) { @@ -22445,7 +22457,7 @@ int ObDDLService::create_tenant( LOG_USER_ERROR(OB_TENANT_EXIST, to_cstring(tenant_name)); LOG_WARN("tenant already exists", KR(ret), K(tenant_name)); } - } else if (OB_FAIL(create_tenant(arg, schema_guard, tenant_id))) { + } else if (OB_FAIL(inner_create_tenant_(arg, schema_guard, tenant_id))) { LOG_WARN("fail to create tenant", KR(ret), K(arg)); } } @@ -22491,7 +22503,7 @@ int ObDDLService::generate_tenant_schema( user_tenant_schema.set_tenant_id(user_tenant_id); if (!tenant_role.is_primary()) { //standby cluster and restore tenant no need init user tenant system variables - if (tenant_role.is_restore()) { + if (tenant_role.is_restore() || tenant_role.is_clone()) { user_tenant_schema.set_status(TENANT_STATUS_RESTORE); } else if (arg.is_creating_standby_) { user_tenant_schema.set_status(TENANT_STATUS_CREATING_STANDBY); @@ -22543,7 +22555,9 @@ int ObDDLService::generate_tenant_schema( * standby tenant so that it can be upgraded from 0 to ensure that the compatible_version matches * the internal table. and it also prevent loss of the upgrade action. */ - uint64_t compatible_version = arg.is_restore_ ? arg.compatible_version_ : DATA_CURRENT_VERSION; + uint64_t compatible_version = (arg.is_restore_tenant() || arg.is_clone_tenant()) + ? arg.compatible_version_ + : DATA_CURRENT_VERSION; if (OB_FAIL(gen_tenant_init_config(user_tenant_id, compatible_version, config))) { LOG_WARN("fail to gen tenant init config", KR(ret), K(user_tenant_id), K(compatible_version)); } else if (OB_FAIL(init_configs.push_back(config))) { @@ -22619,7 +22633,7 @@ int ObDDLService::init_schema_status( return ret; } -int ObDDLService::create_tenant( +int ObDDLService::inner_create_tenant_( const ObCreateTenantArg &arg, share::schema::ObSchemaGetterGuard &schema_guard, UInt64 &tenant_id) @@ -22641,12 +22655,12 @@ int ObDDLService::create_tenant( (ObSysVariableSchema, meta_sys_variable)) { if (OB_FAIL(check_inner_stat())) { LOG_WARN("fail to check inner stat", KR(ret)); - } else if (arg.is_restore_) { - tenant_role = share::RESTORE_TENANT_ROLE; + } else if (arg.is_restore_tenant() || arg.is_clone_tenant()) { + tenant_role = arg.is_restore_tenant() ? share::RESTORE_TENANT_ROLE : share::CLONE_TENANT_ROLE; recovery_until_scn = arg.recovery_until_scn_; user_palf_base_info = arg.palf_base_info_; create_ls_with_palf = true; - } else if (arg.is_creating_standby_) { + } else if (arg.is_standby_tenant()) { tenant_role = share::STANDBY_TENANT_ROLE; } else { tenant_role = share::PRIMARY_TENANT_ROLE; @@ -22678,22 +22692,23 @@ int ObDDLService::create_tenant( } else { DEBUG_SYNC(BEFORE_CREATE_META_TENANT); // create ls/tablet/schema in tenant space + // TODO@jingyu.cr: need to support create clone tenant from lower version, mark compatible version for unit ObArray pools; if (OB_FAIL(get_pools(arg.pool_list_, pools))) { LOG_WARN("get_pools failed", KR(ret), K(arg)); } else if (OB_FAIL(create_normal_tenant(meta_tenant_id, pools, meta_tenant_schema, tenant_role, recovery_until_scn, meta_sys_variable, false/*create_ls_with_palf*/, meta_palf_base_info, init_configs, - arg.is_creating_standby_, arg.log_restore_source_))) { + arg.is_standby_tenant(), arg.log_restore_source_, arg.source_tenant_id_))) { LOG_WARN("fail to create meta tenant", KR(ret), K(meta_tenant_id), K(pools), K(meta_sys_variable), - K(tenant_role), K(recovery_until_scn), K(meta_palf_base_info), K(init_configs)); + K(tenant_role), K(recovery_until_scn), K(meta_palf_base_info), K(init_configs), K(arg)); } else { ObString empty_str; DEBUG_SYNC(BEFORE_CREATE_USER_TENANT); if (OB_FAIL(create_normal_tenant(user_tenant_id, pools, user_tenant_schema, tenant_role, recovery_until_scn, user_sys_variable, create_ls_with_palf, user_palf_base_info, init_configs, - false /* is_creating_standby */, empty_str))) { + false /* is_creating_standby */, empty_str, arg.source_tenant_id_))) { LOG_WARN("fail to create user tenant", KR(ret), K(user_tenant_id), K(pools), K(user_sys_variable), - K(tenant_role), K(recovery_until_scn), K(user_palf_base_info)); + K(tenant_role), K(recovery_until_scn), K(user_palf_base_info), K(arg)); } } // drop tenant if create tenant failed. @@ -22856,8 +22871,9 @@ int ObDDLService::create_tenant_schema( trans, new_ug_id_array, compat_mode, pools, user_tenant_id, - false/*is_bootstrap*/))) { - LOG_WARN("grant_pools_to_tenant failed", KR(ret), K(pools), K(user_tenant_id)); + false/*is_bootstrap*/, + arg.source_tenant_id_))) { + LOG_WARN("grant_pools_to_tenant failed", KR(ret), K(arg), K(pools), K(user_tenant_id)); } LOG_INFO("[CREATE_TENANT] STEP 1.2. finish grant pools", KR(ret), K(user_tenant_id), "cost", ObTimeUtility::fast_current_time() - tmp_start_time); @@ -23010,7 +23026,7 @@ int ObDDLService::check_need_create_root_key(const ObCreateTenantArg &arg, bool need_create = false; if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_0_0) { need_create = false; - } else if (arg.is_restore_) { + } else if (arg.is_restore_tenant() || arg.is_clone_tenant()) { need_create = false; } else { need_create = true; @@ -23275,10 +23291,11 @@ int ObDDLService::create_normal_tenant( const palf::PalfBaseInfo &palf_base_info, const common::ObIArray &init_configs, bool is_creating_standby, - const common::ObString &log_restore_source) + const common::ObString &log_restore_source, + const uint64_t source_tenant_id) { const int64_t start_time = ObTimeUtility::fast_current_time(); - LOG_INFO("[CREATE_TENANT] STEP 2. start create tenant", K(tenant_id), K(tenant_schema)); + LOG_INFO("[CREATE_TENANT] STEP 2. start create tenant", K(tenant_id), K(tenant_schema), K(source_tenant_id)); int ret = OB_SUCCESS; ObSArray tables; if (OB_FAIL(check_inner_stat())) { @@ -23289,10 +23306,10 @@ int ObDDLService::create_normal_tenant( } else if (is_sys_tenant(tenant_id)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("tenant_id is invalid", KR(ret), K(tenant_id)); - } else if (OB_FAIL(insert_restore_tenant_job(tenant_id, tenant_schema.get_tenant_name(), tenant_role))) { - LOG_WARN("failed to insert restore tenant job", KR(ret), K(tenant_id), K(tenant_role), K(tenant_schema)); - } else if (OB_FAIL(create_tenant_sys_ls(tenant_schema, pool_list, create_ls_with_palf, palf_base_info))) { - LOG_WARN("fail to create tenant sys log stream", KR(ret), K(tenant_schema), K(pool_list), K(palf_base_info)); + } else if (OB_FAIL(insert_restore_or_clone_tenant_job_(tenant_id, tenant_schema.get_tenant_name(), tenant_role, source_tenant_id))) { + LOG_WARN("failed to insert restore or clone tenant job", KR(ret), K(tenant_id), K(tenant_role), K(tenant_schema), K(source_tenant_id)); + } else if (OB_FAIL(create_tenant_sys_ls(tenant_schema, pool_list, create_ls_with_palf, palf_base_info, source_tenant_id))) { + LOG_WARN("fail to create tenant sys log stream", KR(ret), K(tenant_schema), K(pool_list), K(palf_base_info), K(source_tenant_id)); } else if (is_user_tenant(tenant_id) && !tenant_role.is_primary()) { //standby cluster no need create sys tablet and init tenant schema } else if (OB_FAIL(ObSchemaUtils::construct_inner_table_schemas(tenant_id, tables))) { @@ -23311,15 +23328,16 @@ int ObDDLService::create_normal_tenant( //create user ls LOG_WARN("failed to create tenant user ls", KR(ret), K(tenant_id)); } - LOG_INFO("[CREATE_TENANT] STEP 2. finish create tenant", KR(ret), K(tenant_id), + LOG_INFO("[CREATE_TENANT] STEP 2. finish create tenant", KR(ret), K(tenant_id), K(source_tenant_id), "cost", ObTimeUtility::fast_current_time() - start_time); return ret; } -int ObDDLService::insert_restore_tenant_job( +int ObDDLService::insert_restore_or_clone_tenant_job_( const uint64_t tenant_id, const ObString &tenant_name, - const share::ObTenantRole &tenant_role) + const share::ObTenantRole &tenant_role, + const uint64_t source_tenant_id) { int ret = OB_SUCCESS; if (OB_FAIL(check_inner_stat())) { @@ -23330,8 +23348,16 @@ int ObDDLService::insert_restore_tenant_job( } else if (OB_ISNULL(sql_proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ptr is null", KR(ret), KP_(sql_proxy)); - } else if (is_meta_tenant(tenant_id) || !tenant_role.is_restore()) { - //no need to insert retore job; + } else if (is_meta_tenant(tenant_id)) { + // no need to insert job for meta tenant + } else if (!tenant_role.is_restore() && !tenant_role.is_clone()) { + // no need to insert restore/clone job + } else if (tenant_role.is_clone()) { + // insert clone job + if (OB_FAIL(ObTenantCloneUtil::insert_user_tenant_clone_job(*sql_proxy_, tenant_name, + tenant_id))) { + LOG_WARN("failed to insert user tenant clone job", KR(ret), K(tenant_name), K(tenant_id)); + } } else if (OB_FAIL(ObRestoreUtil::insert_user_tenant_restore_job(*sql_proxy_, tenant_name, tenant_id))) { LOG_WARN("failed to insert user tenant restore job", KR(ret), K(tenant_id), K(tenant_name)); @@ -23386,12 +23412,15 @@ int ObDDLService::create_tenant_sys_ls( const ObTenantSchema &tenant_schema, const ObIArray &pool_list, const bool create_ls_with_palf, - const palf::PalfBaseInfo &palf_base_info) + const palf::PalfBaseInfo &palf_base_info, + const uint64_t source_tenant_id) { const int64_t start_time = ObTimeUtility::fast_current_time(); - LOG_INFO("[CREATE_TENANT] STEP 2.1. start create sys log stream", K(tenant_schema)); + LOG_INFO("[CREATE_TENANT] STEP 2.1. start create sys log stream", K(tenant_schema), K(source_tenant_id)); int ret = OB_SUCCESS; const uint64_t tenant_id = tenant_schema.get_tenant_id(); + // meta tenant do not have to reference source tenant id + const uint64_t source_tenant_id_to_use = is_user_tenant(tenant_id) ? source_tenant_id : OB_INVALID_TENANT_ID; int64_t wait_leader = 0; if (OB_FAIL(check_inner_stat())) { LOG_WARN("variable is not init", KR(ret)); @@ -23425,9 +23454,9 @@ int ObDDLService::create_tenant_sys_ls( } else if (OB_FAIL(ls_creator.create_tenant_sys_ls( primary_zone_list.at(0), locality, pool_list, paxos_replica_num, tenant_schema.get_compatibility_mode(), zone_priority.string(), - create_ls_with_palf, palf_base_info))) { + create_ls_with_palf, palf_base_info, source_tenant_id_to_use))) { LOG_WARN("fail to create tenant sys ls", KR(ret), K(pool_list), K(palf_base_info), - K(locality), K(paxos_replica_num), K(tenant_schema), K(zone_priority)); + K(locality), K(paxos_replica_num), K(tenant_schema), K(zone_priority), K(source_tenant_id_to_use)); } else { share::ObLSLeaderElectionWaiter ls_leader_waiter(*lst_operator_, stopped_); int64_t timeout = GCONF.rpc_timeout; @@ -24828,7 +24857,8 @@ int ObDDLService::modify_and_cal_resource_pool_diff( ret = OB_NOT_SUPPORTED; LOG_WARN("fail to grant pool", K(ret), K(diff_pools)); } else if (OB_FAIL(unit_mgr_->grant_pools( - trans, new_ug_id_array, compat_mode, diff_pools, tenant_id))) { + trans, new_ug_id_array, compat_mode, diff_pools, tenant_id, + OB_INVALID_TENANT_ID/*source_tenant_id*/))) { LOG_WARN("fail to grant pools", K(ret)); } } else if (new_pool_name_list.count() + 1 == old_pool_name_list.count()) { diff --git a/src/rootserver/ob_ddl_service.h b/src/rootserver/ob_ddl_service.h index 61b72888ed..9b655475fc 100644 --- a/src/rootserver/ob_ddl_service.h +++ b/src/rootserver/ob_ddl_service.h @@ -2052,7 +2052,7 @@ private: const obrpc::ObCreateTenantArg &arg, share::schema::ObTenantSchema &tenant_schema, share::schema::ObSysVariableSchema &sys_variable_schema); - int create_tenant( + int inner_create_tenant_( const obrpc::ObCreateTenantArg &arg, share::schema::ObSchemaGetterGuard &schema_guard, obrpc::UInt64 &tenant_id); @@ -2073,13 +2073,15 @@ private: const palf::PalfBaseInfo &palf_base_info, const common::ObIArray &init_configs, bool is_creating_standby, - const common::ObString &log_restore_source); + const common::ObString &log_restore_source, + const uint64_t source_tenant_id); int set_sys_ls_status(const uint64_t tenant_id); int create_tenant_sys_ls( const share::schema::ObTenantSchema &tenant_schema, const common::ObIArray &pool_list, const bool create_ls_with_palf, - const palf::PalfBaseInfo &palf_base_info); + const palf::PalfBaseInfo &palf_base_info, + const uint64_t source_tenant_id); int create_tenant_user_ls(const uint64_t tenant_id); int broadcast_sys_table_schemas( const uint64_t tenant_id, @@ -2101,10 +2103,11 @@ private: const uint64_t tenant_id, const common::ObString &log_restore_source, common::ObMySQLTransaction &trans); - int insert_restore_tenant_job( + int insert_restore_or_clone_tenant_job_( const uint64_t tenant_id, const ObString &tenant_name, - const share::ObTenantRole &tenant_role); + const share::ObTenantRole &tenant_role, + const uint64_t source_tenant_id); int create_sys_table_schemas( ObDDLOperator &ddl_operator, ObMySQLTransaction &trans, diff --git a/src/rootserver/ob_disaster_recovery_task.cpp b/src/rootserver/ob_disaster_recovery_task.cpp index a84a0a9fb8..e9e0f054c5 100644 --- a/src/rootserver/ob_disaster_recovery_task.cpp +++ b/src/rootserver/ob_disaster_recovery_task.cpp @@ -103,6 +103,7 @@ static const char* disaster_recovery_task_ret_comment_strs[] = { "[rs] task can not execute because fail to check paxos replica number", "[rs] task can not execute because replica is not in service", "[rs] task can not execute because server is permanent offline", + "[rs] task can not persist because conflict with clone operation", ""/*default max*/ }; diff --git a/src/rootserver/ob_disaster_recovery_task.h b/src/rootserver/ob_disaster_recovery_task.h index 5472532eb6..53ab6d9718 100644 --- a/src/rootserver/ob_disaster_recovery_task.h +++ b/src/rootserver/ob_disaster_recovery_task.h @@ -69,6 +69,7 @@ enum ObDRTaskRetComment CANNOT_EXECUTE_DUE_TO_PAXOS_REPLICA_NUMBER = 7, CANNOT_EXECUTE_DUE_TO_REPLICA_NOT_INSERVICE = 8, CANNOT_EXECUTE_DUE_TO_SERVER_PERMANENT_OFFLINE = 9, + CANNOT_PERSIST_TASK_DUE_TO_CLONE_CONFLICT = 10, MAX }; diff --git a/src/rootserver/ob_disaster_recovery_task_mgr.cpp b/src/rootserver/ob_disaster_recovery_task_mgr.cpp index 2691136f4e..df86289884 100644 --- a/src/rootserver/ob_disaster_recovery_task_mgr.cpp +++ b/src/rootserver/ob_disaster_recovery_task_mgr.cpp @@ -31,14 +31,20 @@ #include "share/ob_share_util.h" // for ObShareUtil #include "lib/lock/ob_tc_rwlock.h" // for common::RWLock #include "rootserver/ob_disaster_recovery_task.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" // for ObTenantSnapshotUtil #include "share/inner_table/ob_inner_table_schema_constants.h" #include "share/ob_all_server_tracer.h" +#include "storage/tablelock/ob_lock_inner_connection_util.h" // for ObInnerConnectionLockUtil +#include "observer/ob_inner_sql_connection.h" namespace oceanbase { using namespace common; using namespace lib; using namespace obrpc; +using namespace transaction::tablelock; +using namespace share; + namespace rootserver { ObDRTaskQueue::ObDRTaskQueue() : inited_(false), @@ -1196,27 +1202,54 @@ int ObDRTaskMgr::load_task_info_( } int ObDRTaskMgr::persist_task_info_( - const ObDRTask &task) + const ObDRTask &task, + ObDRTaskRetComment &ret_comment) { int ret = OB_SUCCESS; + ret_comment = ObDRTaskRetComment::MAX; share::ObDMLSqlSplicer dml; ObSqlString sql; int64_t affected_rows = 0; const uint64_t sql_tenant_id = gen_meta_tenant_id(task.get_tenant_id()); + ObMySQLTransaction trans; + const int64_t timeout = GCONF.internal_sql_execute_timeout; + observer::ObInnerSQLConnection *conn = NULL; + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::MODIFY_REPLICA); + if (OB_FAIL(check_inner_stat_())) { LOG_WARN("fail to check inner stat", KR(ret), K_(inited), K_(stopped), K_(loaded)); } else if (OB_ISNULL(sql_proxy_)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(sql_proxy_, sql_tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(sql_tenant_id)); } else if (OB_FAIL(task.fill_dml_splicer(dml))) { LOG_WARN("fill dml splicer failed", KR(ret)); } else if (OB_FAIL(dml.splice_insert_sql(share::OB_ALL_LS_REPLICA_TASK_TNAME, sql))) { LOG_WARN("fail to splice batch insert update sql", KR(ret), K(sql)); - } else if (OB_FAIL(sql_proxy_->write(sql_tenant_id, sql.ptr(), affected_rows))) { + } else if (OB_ISNULL(conn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("conn_ is NULL", KR(ret)); + } else if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(sql_tenant_id, + OB_ALL_LS_REPLICA_TASK_TID, + EXCLUSIVE, + timeout, + conn))) { + LOG_WARN("lock dest table failed", KR(ret), K(sql_tenant_id)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(task.get_tenant_id(), case_to_check))) { + LOG_WARN("fail to check whether tenant is in cloning procedure", KR(ret)); + ret_comment = CANNOT_PERSIST_TASK_DUE_TO_CLONE_CONFLICT; + } else if (OB_FAIL(trans.write(sql_tenant_id, sql.ptr(), affected_rows))) { LOG_WARN("execute sql failed", KR(ret), "tenant_id",task.get_tenant_id(), K(sql_tenant_id), K(sql)); - } else { - FLOG_INFO("[DRTASK_NOTICE] persist task into inner table succeed", K(task)); } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + FLOG_INFO("[DRTASK_NOTICE] finish persist task into inner table", KR(ret), K(task)); return ret; } @@ -1425,7 +1458,7 @@ int ObDRTaskMgr::execute_task( ObDRTaskRetComment ret_comment = ObDRTaskRetComment::MAX; if (OB_FAIL(check_inner_stat_())) { LOG_WARN("fail to check inner stat", KR(ret), K_(inited), K_(stopped), K_(loaded)); - } else if (OB_FAIL(persist_task_info_(task))) { + } else if (OB_FAIL(persist_task_info_(task, ret_comment))) { LOG_WARN("fail to persist task info into table", KR(ret)); } else if (OB_FAIL(task_executor_->execute(task, dummy_ret, ret_comment))) { LOG_WARN("fail to execute disaster recovery task", KR(ret)); diff --git a/src/rootserver/ob_disaster_recovery_task_mgr.h b/src/rootserver/ob_disaster_recovery_task_mgr.h index 92d3ce67a6..33b57ce959 100644 --- a/src/rootserver/ob_disaster_recovery_task_mgr.h +++ b/src/rootserver/ob_disaster_recovery_task_mgr.h @@ -362,7 +362,8 @@ private: // write task info into inner table // @param [in] task, which task info to write int persist_task_info_( - const ObDRTask &task); + const ObDRTask &task, + ObDRTaskRetComment &ret_comment); // try to log inmemory task infos according to balancer_log_interval // @param [in] last_dump_ts, last time do logging diff --git a/src/rootserver/ob_disaster_recovery_worker.cpp b/src/rootserver/ob_disaster_recovery_worker.cpp index 5f39a836f8..58fb44cecb 100755 --- a/src/rootserver/ob_disaster_recovery_worker.cpp +++ b/src/rootserver/ob_disaster_recovery_worker.cpp @@ -1969,6 +1969,38 @@ int ObDRWorker::try_disaster_recovery() return ret; } +int ObDRWorker::check_whether_the_tenant_role_can_exec_dr_(const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else { + if (is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) { + ret = OB_SUCCESS; + } else { + ObAllTenantInfo tenant_info; + if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, + GCTX.sql_proxy_, + false, + tenant_info))) { + LOG_WARN("fail to load tenant info", KR(ret), K(tenant_id)); + } else if (tenant_info.is_clone()) { + ret = OB_STATE_NOT_MATCH; + LOG_INFO("the tenant is currently in the clone processing and disaster recovery will" + " not be executed for the time being", KR(ret), K(tenant_id)); + } else { + ret = OB_SUCCESS; + } + } + } + return ret; +} + int ObDRWorker::try_tenant_disaster_recovery( const uint64_t tenant_id, const bool only_for_display, @@ -1986,6 +2018,8 @@ int ObDRWorker::try_tenant_disaster_recovery( ret = OB_ERR_UNEXPECTED; LOG_WARN("lst operator ptr or sql proxy is null", KR(ret), KP(lst_operator_), KP(sql_proxy_)); + } else if (OB_FAIL(check_whether_the_tenant_role_can_exec_dr_(tenant_id))) { + LOG_INFO("fail to check_whether_the_tenant_role_can_exec_dr_", KR(ret), K(tenant_id)); } else { LOG_INFO("start try tenant disaster recovery", K(tenant_id), K(only_for_display)); share::ObLSStatusOperator ls_status_operator; @@ -3939,7 +3973,7 @@ int ObDRWorker::find_valid_readonly_replica_( } else if (replica->is_in_service() && server_stat_info->is_alive() && !server_stat_info->is_stopped() - && !replica->get_restore_status().is_restore_failed() + && !replica->get_restore_status().is_failed() && unit_stat_info->get_server_stat()->is_alive() && !unit_stat_info->get_server_stat()->is_block()) { if (OB_FAIL(target_replica.assign(*replica))) { @@ -4844,7 +4878,7 @@ int ObDRWorker::choose_disaster_recovery_data_source( && !server_stat_info->is_stopped() && type_checker.is_candidate(ls_replica->get_replica_type()) && ls_replica->get_server() == src_member.get_server() - && !ls_replica->get_restore_status().is_restore_failed()) { + && !ls_replica->get_restore_status().is_failed()) { src_replica = ls_replica; break; } @@ -4876,7 +4910,7 @@ int ObDRWorker::choose_disaster_recovery_data_source( && type_checker.is_candidate(ls_replica->get_replica_type()) && ls_replica->get_zone() == dst_zone && ls_replica->get_server() != dst_member.get_server() - && !ls_replica->get_restore_status().is_restore_failed()) { + && !ls_replica->get_restore_status().is_failed()) { src_replica = ls_replica; break; } @@ -4912,7 +4946,7 @@ int ObDRWorker::choose_disaster_recovery_data_source( && type_checker.is_candidate(ls_replica->get_replica_type()) && ls_region == dst_region && ls_replica->get_server() != dst_member.get_server() - && !ls_replica->get_restore_status().is_restore_failed()) { + && !ls_replica->get_restore_status().is_failed()) { src_replica = ls_replica; break; } @@ -4943,7 +4977,7 @@ int ObDRWorker::choose_disaster_recovery_data_source( && !server_stat_info->is_stopped() && type_checker.is_candidate(ls_replica->get_replica_type()) && ls_replica->get_server() != dst_member.get_server() - && !ls_replica->get_restore_status().is_restore_failed()) { + && !ls_replica->get_restore_status().is_failed()) { src_replica = ls_replica; break; } diff --git a/src/rootserver/ob_disaster_recovery_worker.h b/src/rootserver/ob_disaster_recovery_worker.h index e3a90b33fe..4ead779e59 100755 --- a/src/rootserver/ob_disaster_recovery_worker.h +++ b/src/rootserver/ob_disaster_recovery_worker.h @@ -694,6 +694,8 @@ private: const int64_t &priority, bool &task_exist); + int check_whether_the_tenant_role_can_exec_dr_(const uint64_t tenant_id); + int try_remove_permanent_offline_replicas( const bool only_for_display, DRLSInfo &dr_ls_info, diff --git a/src/rootserver/ob_ls_service_helper.cpp b/src/rootserver/ob_ls_service_helper.cpp index 1ab73e8466..f70c0d21dd 100755 --- a/src/rootserver/ob_ls_service_helper.cpp +++ b/src/rootserver/ob_ls_service_helper.cpp @@ -683,7 +683,8 @@ int ObLSServiceHelper::revision_to_equal_status_(const ObLSStatusMachineParamete ls_info.get_ls_group_id(), ls_info.get_create_scn(), working_sw_status, - tenant_ls_info, trans, ls_info.get_ls_flag()))) { + tenant_ls_info, trans, ls_info.get_ls_flag(), + OB_INVALID_TENANT_ID/*source_tenant_id*/))) { LOG_WARN("failed to create new ls in trans", KR(ret), K(ls_info), K(tenant_ls_info), K(working_sw_status)); } END_TRANSACTION(trans); @@ -821,7 +822,8 @@ int ObLSServiceHelper::create_new_ls_in_trans( const share::ObTenantSwitchoverStatus &working_sw_status, ObTenantLSInfo& tenant_ls_info, ObMySQLTransaction &trans, - const share::ObLSFlag &ls_flag) + const share::ObLSFlag &ls_flag, + const uint64_t source_tenant_id) { int ret = OB_SUCCESS; int64_t info_index = OB_INVALID_INDEX_INT64; @@ -845,6 +847,144 @@ int ObLSServiceHelper::create_new_ls_in_trans( ObLSLifeAgentManager ls_life_agent(*GCTX.sql_proxy_); ObSqlString zone_priority; uint64_t unit_group_id = 0; + if (OB_INVALID_TENANT_ID == source_tenant_id) { + if (OB_FAIL(construct_unit_group_id_and_primary_zone_( + ls_id, + ls_group_id, + ls_flag, + tenant_ls_info, + unit_group_id, + primary_zone))) { + LOG_WARN("fail to construct unit group id and primary zone", KR(ret), K(ls_id), K(ls_group_id), K(ls_flag), K(tenant_ls_info)); + } + } else { + // for clone tenant + if (OB_FAIL(construct_unit_group_id_and_primary_zone_for_clone_tenant_(ls_id, source_tenant_id, tenant_id, unit_group_id, primary_zone))) { + LOG_WARN("fail to construct unit group id and primary zone for clone tenant", KR(ret), K(ls_id), K(source_tenant_id), K(tenant_id)); + } + } + + if (FAILEDx(new_info.init(tenant_id, ls_id, + ls_group_id, + share::OB_LS_CREATING, + unit_group_id, + primary_zone, ls_flag))) { + LOG_WARN("failed to init new info", KR(ret), K(tenant_id), K(unit_group_id), + K(ls_id), K(ls_group_id), K(group_info), K(primary_zone), K(ls_flag)); + } else if (OB_FAIL(ObTenantThreadHelper::get_zone_priority(primary_zone, + *tenant_ls_info.get_tenant_schema(), zone_priority))) { + LOG_WARN("failed to get normalize primary zone", KR(ret), K(primary_zone), K(zone_priority)); + } else if (OB_FAIL(ls_life_agent.create_new_ls_in_trans(new_info, create_scn, + zone_priority.string(), working_sw_status, trans))) { + LOG_WARN("failed to insert ls info", KR(ret), K(new_info), K(create_scn), K(zone_priority)); + } + } + return ret; +} + +int ObLSServiceHelper::construct_unit_group_id_and_primary_zone_for_clone_tenant_( + const share::ObLSID &ls_id, + const uint64_t source_tenant_id, + const uint64_t tenant_id, + uint64_t &unit_group_id, + ObZone &primary_zone) +{ + int ret = OB_SUCCESS; + uint64_t source_unit_group_id = OB_INVALID_ID; + unit_group_id = OB_INVALID_ID; + primary_zone.reset(); + if (OB_UNLIKELY(!ls_id.is_valid()) + || OB_UNLIKELY(OB_INVALID_TENANT_ID == source_tenant_id) + || OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id) + || OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is invalid", KR(ret), K(ls_id), K(source_tenant_id), K(tenant_id), KP(GCTX.sql_proxy_)); + } else { + // construct primary zone + share::ObLSStatusInfo ls_status_info; + MTL_SWITCH(OB_SYS_TENANT_ID) { + share::ObLSStatusOperator ls_status_operator; + if (OB_FAIL(ls_status_operator.get_ls_status_info(source_tenant_id, ls_id, ls_status_info, *GCTX.sql_proxy_))) { + LOG_WARN("fail to get all ls status", KR(ret), K(source_tenant_id), K(ls_id), K(ls_status_info)); + } else if (OB_UNLIKELY(!ls_status_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("source ls status info is invalid", KR(ret), K(ls_status_info)); + } else if (OB_FAIL(primary_zone.assign(ls_status_info.primary_zone_))) { + LOG_WARN("fail to assign primary zone", KR(ret), K(ls_status_info)); + } else { + source_unit_group_id = ls_status_info.unit_group_id_; + } + } + // construct sql to fetch unit group id + ObSqlString sql; + const uint64_t exec_tenant_id = OB_SYS_TENANT_ID; + if (OB_FAIL(ret)) { + } else if (0 == source_unit_group_id) { + unit_group_id = 0; + } else if (OB_FAIL(sql.assign_fmt("SELECT DISTINCT b.unit_group_id FROM " + "(SELECT svr_ip, svr_port FROM %s WHERE tenant_id = %ld AND unit_group_id = %ld) as a " + "INNER JOIN " + "(SELECT * FROM %s WHERE tenant_id = %ld) as b " + "ON a.svr_ip = b.svr_ip AND a.svr_port = b.svr_port", + OB_DBA_OB_UNITS_TNAME, source_tenant_id, source_unit_group_id, + OB_DBA_OB_UNITS_TNAME, tenant_id))) { + LOG_WARN("fail to construct sql to fetch unit group id for new log stream", KR(ret), + K(source_tenant_id), K(tenant_id), K(source_unit_group_id)); + } else { + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(GCTX.sql_proxy_->read(res, exec_tenant_id, sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(exec_tenant_id), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret), K(sql)); + } else { + ret = result->next(); + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("unit group id not found", KR(ret), K(sql)); + } else if (OB_FAIL(ret)) { + LOG_WARN("failed to get unit group id", KR(ret), K(sql)); + } else { + EXTRACT_INT_FIELD_MYSQL(*result, "unit_group_id", unit_group_id, uint64_t); + if (OB_FAIL(ret)) { + LOG_WARN("fail to get unit group id from result", KR(ret)); + } else if (OB_UNLIKELY(OB_INVALID_ID == unit_group_id)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("unexpected unit group id", KR(ret), K(sql), K(unit_group_id)); + } + } + if (OB_SUCC(ret)) { + if (OB_ITER_END != result->next()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expect only one row", KR(ret), K(sql)); + } + } + } + } + } + } + return ret; +} + +int ObLSServiceHelper::construct_unit_group_id_and_primary_zone_( + const share::ObLSID &ls_id, + const uint64_t ls_group_id, + const share::ObLSFlag &ls_flag, + ObTenantLSInfo &tenant_ls_info, + uint64_t &unit_group_id, + ObZone &primary_zone) +{ + int ret = OB_SUCCESS; + unit_group_id = 0; + primary_zone.reset(); + if (OB_UNLIKELY(!ls_id.is_valid() + || OB_INVALID_ID == ls_group_id + || !ls_flag.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is invalid", KR(ret), K(ls_id), K(ls_group_id), K(ls_flag)); + } else { + ObLSGroupInfo group_info; if (0 == ls_group_id) { unit_group_id = 0; if (!ls_flag.is_duplicate_ls()) { @@ -880,21 +1020,6 @@ int ObLSServiceHelper::create_new_ls_in_trans( } else { LOG_WARN("failed to get ls group info", KR(ret), K(ls_group_id), K(tenant_ls_info)); } - - if (FAILEDx(new_info.init(tenant_id, ls_id, - ls_group_id, - share::OB_LS_CREATING, - unit_group_id, - primary_zone, ls_flag))) { - LOG_WARN("failed to init new info", KR(ret), K(tenant_id), K(unit_group_id), - K(ls_id), K(ls_group_id), K(group_info), K(primary_zone), K(ls_flag)); - } else if (OB_FAIL(ObTenantThreadHelper::get_zone_priority(primary_zone, - *tenant_ls_info.get_tenant_schema(), zone_priority))) { - LOG_WARN("failed to get normalize primary zone", KR(ret), K(primary_zone), K(zone_priority)); - } else if (OB_FAIL(ls_life_agent.create_new_ls_in_trans(new_info, create_scn, - zone_priority.string(), working_sw_status, trans))) { - LOG_WARN("failed to insert ls info", KR(ret), K(new_info), K(create_scn), K(zone_priority)); - } } return ret; } diff --git a/src/rootserver/ob_ls_service_helper.h b/src/rootserver/ob_ls_service_helper.h index 2f89d32087..098a99129a 100644 --- a/src/rootserver/ob_ls_service_helper.h +++ b/src/rootserver/ob_ls_service_helper.h @@ -229,7 +229,8 @@ public: const share::ObTenantSwitchoverStatus &working_sw_status, ObTenantLSInfo& tenant_ls_info, common::ObMySQLTransaction &trans, - const share::ObLSFlag &ls_flag); + const share::ObLSFlag &ls_flag, + const uint64_t source_tenant_id); static int balance_ls_group( const bool need_execute_balance, ObTenantLSInfo& tenant_ls_info, @@ -273,6 +274,20 @@ private: const uint64_t ls_group_id, ObUnitGroupInfo &src_info, ObUnitGroupInfo &dest_info); + static int construct_unit_group_id_and_primary_zone_for_clone_tenant_( + const share::ObLSID &ls_id, + const uint64_t source_tenant_id, + const uint64_t tenant_id, + uint64_t &unit_group_id, + ObZone &primary_zone); + + static int construct_unit_group_id_and_primary_zone_( + const share::ObLSID &ls_id, + const uint64_t ls_group_id, + const share::ObLSFlag &ls_flag, + ObTenantLSInfo &tenant_ls_info, + uint64_t &unit_group_id, + ObZone &primary_zone); static int get_ls_all_replica_readable_scn_(const uint64_t tenant_id, const share::ObLSID &src_ls, share::SCN &readable_scn); diff --git a/src/rootserver/ob_recovery_ls_service.cpp b/src/rootserver/ob_recovery_ls_service.cpp index 43a8fe4a38..b2b271254f 100755 --- a/src/rootserver/ob_recovery_ls_service.cpp +++ b/src/rootserver/ob_recovery_ls_service.cpp @@ -932,7 +932,7 @@ int ObRecoveryLSService::create_new_ls_(const share::ObLSAttr &ls_attr, ObLSFlag ls_flag = ls_attr.get_ls_flag(); if (OB_FAIL(ObLSServiceHelper::create_new_ls_in_trans(ls_attr.get_ls_id(), ls_attr.get_ls_group_id(), ls_attr.get_create_scn(), - switchover_status, tenant_stat, trans, ls_flag))) { + switchover_status, tenant_stat, trans, ls_flag, OB_INVALID_TENANT_ID/*source_tenant_id*/))) { LOG_WARN("failed to add new ls status info", KR(ret), K(ls_attr), K(sync_scn), K(tenant_stat), K(switchover_status)); } diff --git a/src/rootserver/ob_root_service.cpp b/src/rootserver/ob_root_service.cpp index 090d66d1ff..a80953f808 100755 --- a/src/rootserver/ob_root_service.cpp +++ b/src/rootserver/ob_root_service.cpp @@ -110,6 +110,10 @@ #include "logservice/ob_log_service.h" #include "rootserver/restore/ob_recover_table_initiator.h" #include "rootserver/ob_heartbeat_service.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "share/restore/ob_tenant_clone_table_operator.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" +#include "rootserver/restore/ob_tenant_clone_util.h" #include "parallel_ddl/ob_create_table_helper.h" // ObCreateTableHelper #include "parallel_ddl/ob_create_view_helper.h" // ObCreateViewHelper @@ -2457,6 +2461,43 @@ int ObRootService::drop_resource_unit(const obrpc::ObDropResourceUnitArg &arg) return ret; } +int ObRootService::clone_resource_pool(const obrpc::ObCloneResourcePoolArg &arg) +{ + int ret = OB_SUCCESS; + bool is_compatible = false; + LOG_INFO("receive clone_resource_pool request", K(arg)); + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("rootservice not init", KR(ret), K_(inited)); + } else if (!arg.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument to clone resource pool", KR(ret), K(arg)); + } else if (OB_FAIL(ObShareUtil::check_compat_version_for_clone_tenant( + arg.get_source_tenant_id(), + is_compatible))) { + LOG_WARN("fail to check compat version", KR(ret), K(arg)); + } else if (!is_compatible) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("clone tenant or sys tenant data version is below 4.3", KR(ret), K(arg), K(is_compatible)); + } else { + share::ObResourcePool pool_to_clone; + pool_to_clone.name_ = arg.get_pool_name(); + pool_to_clone.resource_pool_id_ = arg.get_resource_pool_id(); + if (OB_FAIL(unit_manager_.clone_resource_pool(pool_to_clone, arg.get_unit_config_name(), arg.get_source_tenant_id()))) { + LOG_WARN("clone_resource_pool failed", KR(ret), K(pool_to_clone), K(arg)); + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = submit_reload_unit_manager_task())) { + if (OB_CANCELED != tmp_ret) { + LOG_ERROR("fail to reload unit_manager, please try 'alter system reload unit'", K(tmp_ret)); + } + } + } + } + LOG_INFO("finish clone_resource_pool", KR(ret), K(arg)); + ROOTSERVICE_EVENT_ADD("root_service", "clone_resource_pool", KR(ret), K(arg)); + return ret; +} + int ObRootService::create_resource_pool(const obrpc::ObCreateResourcePoolArg &arg) { int ret = OB_SUCCESS; @@ -2675,8 +2716,17 @@ int ObRootService::drop_resource_pool(const obrpc::ObDropResourcePoolArg &arg) LOG_WARN("missing arg to drop resource pool", K(arg), K(ret)); } else { LOG_INFO("receive drop_resource_pool request", K(arg)); - if (OB_FAIL(unit_manager_.drop_resource_pool(arg.pool_name_, if_exist))) { - LOG_WARN("drop_resource_pool failed", "pool", arg.pool_name_, K(if_exist), K(ret)); + if (OB_INVALID_ID != arg.pool_id_) { + if (OB_FAIL(unit_manager_.drop_resource_pool(arg.pool_id_, if_exist))) { + LOG_WARN("drop_resource_pool failed", "pool", arg.pool_id_, K(if_exist), KR(ret)); + } + } else { + if (OB_FAIL(unit_manager_.drop_resource_pool(arg.pool_name_, if_exist))) { + LOG_WARN("drop_resource_pool failed", "pool", arg.pool_name_, K(if_exist), KR(ret)); + } + } + + if (OB_FAIL(ret)) { int mysql_error = -common::ob_mysql_errno(ret); if (OB_TIMEOUT == ret || OB_TIMEOUT == mysql_error) { int tmp_ret = OB_SUCCESS; @@ -2715,6 +2765,7 @@ int ObRootService::create_tenant(const ObCreateTenantArg &arg, UInt64 &tenant_id LOG_INFO("receive create tenant arg", K(arg), "timeout_ts", THIS_WORKER.get_timeout_ts()); int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; + bool compatible_with_clone_tenant = false; const ObString &tenant_name = arg.tenant_schema_.get_tenant_name_str(); // when recovering table, it needs to create tmp tenant const bool tmp_tenant = arg.is_tmp_tenant_for_recover_; @@ -2723,6 +2774,16 @@ int ObRootService::create_tenant(const ObCreateTenantArg &arg, UInt64 &tenant_id LOG_WARN("not init", KR(ret)); } else if (!tmp_tenant && OB_FAIL(ObResolverUtils::check_not_supported_tenant_name(tenant_name))) { LOG_WARN("unsupported tenant name", KR(ret), K(tenant_name)); + } else if (arg.is_clone_tenant() + && OB_FAIL(ObShareUtil::check_compat_version_for_clone_tenant( + arg.source_tenant_id_, + compatible_with_clone_tenant))) { + LOG_WARN("fail to check compatible version with clone tenant", KR(ret), K(arg)); + } else if (arg.is_clone_tenant() && !compatible_with_clone_tenant) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("create clone tenant with data version below 4.3 not allowed", + KR(ret), K(arg), K(compatible_with_clone_tenant)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "create clone tenant with data version below 4.3"); } else if (OB_FAIL(ddl_service_.create_tenant(arg, tenant_id))) { LOG_WARN("fail to create tenant", KR(ret), K(arg)); if (OB_TMP_FAIL(submit_reload_unit_manager_task())) { @@ -2730,7 +2791,7 @@ int ObRootService::create_tenant(const ObCreateTenantArg &arg, UInt64 &tenant_id LOG_ERROR("fail to reload unit_mgr, please try 'alter system reload unit'", KR(ret), KR(tmp_ret)); } } - } else {} + } LOG_INFO("finish create tenant", KR(ret), K(tenant_id), K(arg), "timeout_ts", THIS_WORKER.get_timeout_ts()); return ret; } @@ -5037,6 +5098,148 @@ int ObRootService::update_index_status(const obrpc::ObUpdateIndexStatusArg &arg) return ret; } +int ObRootService::clone_tenant(const obrpc::ObCloneTenantArg &arg, + obrpc::ObCloneTenantRes &res) +{ + int ret = OB_SUCCESS; + res.reset(); + int64_t refreshed_schema_version = OB_INVALID_VERSION; + const ObString &clone_tenant_name = arg.get_new_tenant_name(); + const ObString &source_tenant_name = arg.get_source_tenant_name(); + const ObString &tenant_snapshot_name = arg.get_tenant_snapshot_name(); + const bool is_fork_tenant = tenant_snapshot_name.empty(); + uint64_t source_tenant_id = OB_INVALID_TENANT_ID; + int64_t job_id = OB_INVALID_ID; + ObTenantSnapItem tenant_snapshot_item; + bool is_unit_config_exist = false; + bool is_resource_pool_exist = false; + + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (!arg.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", KR(ret), K(arg)); + } else if (OB_ISNULL(schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected schema_service_", KR(ret), KP(schema_service_)); + } else if (GCTX.is_standby_cluster() || GCONF.in_upgrade_mode()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("clone tenant while in standby cluster or in upgrade mode is not allowed", KR(ret)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "clone tenant while in standby cluster or in upgrade mode"); + } else if (OB_FAIL(ObResolverUtils::check_not_supported_tenant_name(clone_tenant_name))) { + LOG_WARN("unsupported clone tenant name", KR(ret), K(clone_tenant_name)); + } else { + ObSchemaGetterGuard schema_guard; + const ObTenantSchema *clone_tenant_schema = NULL; + const ObTenantSchema *source_tenant_schema = NULL; + if (OB_FAIL(ddl_service_.get_tenant_schema_guard_with_version_in_inner_table( + OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get sys tenant's schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_schema_version(OB_SYS_TENANT_ID, refreshed_schema_version))) { + LOG_WARN("fail to get sys schema version", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(clone_tenant_name, clone_tenant_schema))) { + LOG_WARN("fail to get clone tenant schema", KR(ret), K(clone_tenant_name)); + } else if (OB_NOT_NULL(clone_tenant_schema)) { + ret = OB_TENANT_EXIST; + LOG_WARN("clone tenant already exists", KR(ret), K(clone_tenant_name)); + LOG_USER_ERROR(OB_TENANT_EXIST, to_cstring(clone_tenant_name)); + } else if (OB_FAIL(schema_guard.get_tenant_info(source_tenant_name, source_tenant_schema))) { + LOG_WARN("fail to get source tenant info", KR(ret), K(source_tenant_name)); + } else if (OB_ISNULL(source_tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("source tenant not exists", KR(ret), K(source_tenant_name)); + LOG_USER_ERROR(OB_TENANT_NOT_EXIST, source_tenant_name.length(), source_tenant_name.ptr()); + } else { + source_tenant_id = source_tenant_schema->get_tenant_id(); + } + } + + if (FAILEDx(ObTenantSnapshotUtil::check_source_tenant_info(source_tenant_id, + ObTenantSnapshotUtil::RESTORE_OP))) { + LOG_WARN("source tenant can not do cloning", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(unit_manager_.check_unit_config_exist(arg.get_unit_config_name(), is_unit_config_exist))) { + LOG_WARN("fail to check unit config exist", KR(ret), K(arg)); + } else if (!is_unit_config_exist) { + ret = OB_RESOURCE_UNIT_NOT_EXIST; + LOG_USER_ERROR(OB_RESOURCE_UNIT_NOT_EXIST, to_cstring(arg.get_unit_config_name())); + LOG_WARN("config not exist", KR(ret), K(arg)); + } else if (OB_FAIL(unit_manager_.check_resource_pool_exist(arg.get_resource_pool_name(), is_resource_pool_exist))) { + LOG_WARN("fail to check resource pool exist", KR(ret), K(arg)); + } else if (is_resource_pool_exist) { + ret = OB_RESOURCE_POOL_EXIST; + LOG_USER_ERROR(OB_RESOURCE_POOL_EXIST, to_cstring(arg.get_resource_pool_name())); + LOG_WARN("resource_pool already exist", "name", arg.get_resource_pool_name(), K(ret)); + } else if (is_fork_tenant) { // fork tenant (clone tenant without snapshot) + // precheck + if (OB_FAIL(ObTenantSnapshotUtil::check_log_archive_ready(source_tenant_id, source_tenant_name))) { + LOG_WARN("check log archive ready failed", KR(ret), K(source_tenant_id), K(source_tenant_name)); + } + } else { // !is_fork_tenant (clone tenant with snapshot) + if (OB_FAIL(ObTenantSnapshotUtil::get_tenant_snapshot_info(sql_proxy_, source_tenant_id, + tenant_snapshot_name, tenant_snapshot_item))) { + LOG_WARN("get tenant snapshot info failed", KR(ret), K(source_tenant_id), K(tenant_snapshot_name)); + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + ret = OB_OP_NOT_ALLOW; + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant snapshot not exist in source tenant, clone tenant"); + } + } + } + + if (OB_SUCC(ret)) { + ObCloneJob clone_job; + bool has_job = false; + SCN gts_scn; + ObDDLSQLTransaction trans(schema_service_, false /*end_signal*/); + if (OB_FAIL(trans.start(&sql_proxy_, OB_SYS_TENANT_ID, refreshed_schema_version))) { + LOG_WARN("failed to start trans", KR(ret)); + } else if (OB_FAIL(OB_TS_MGR.get_ts_sync(OB_SYS_TENANT_ID, GCONF.rpc_timeout, gts_scn))) { + LOG_WARN("fail to get ts sync", KR(ret)); + } else if (FALSE_IT(job_id = gts_scn.get_val_for_tx())) { + } else if (OB_FAIL(ObTenantCloneUtil::fill_clone_job(job_id, arg, source_tenant_id, source_tenant_name, + tenant_snapshot_item, clone_job))) { + LOG_WARN("fail to fill clone job", KR(ret), K(job_id), K(arg), K(source_tenant_id), K(tenant_snapshot_item)); + } else if (OB_FAIL(ObTenantCloneUtil::record_clone_job(trans, clone_job))) { + LOG_WARN("fail to record clone job", KR(ret), K(clone_job)); + } else { + res.set_job_id(job_id); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, KR(tmp_ret), KR(ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + } + + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(ObTenantCloneUtil::notify_clone_scheduler(OB_SYS_TENANT_ID))) { + LOG_WARN("notify clone scheduler failed", KR(tmp_ret)); + } + } + + LOG_INFO("[RESTORE] clone tenant start", KR(ret), K(arg)); + ROOTSERVICE_EVENT_ADD("clone", "clone_start", + "job_id", job_id, + K(ret), + "clone_tenant_name", clone_tenant_name, + "source_tenant_name", source_tenant_name); + + if (OB_SUCC(ret)) { + const char *status_str = ObTenantCloneStatus::get_clone_status_str( + ObTenantCloneStatus::Status::CLONE_SYS_LOCK); + ROOTSERVICE_EVENT_ADD("clone", "change_clone_status", + "job_id", job_id, + K(ret), + "prev_clone_status", "NULL", + "cur_clone_status", status_str); + } + return ret; +} + int ObRootService::init_debug_database() { const schema_create_func *creator_ptr_array[] = { diff --git a/src/rootserver/ob_root_service.h b/src/rootserver/ob_root_service.h index cefcb7bffd..7dac36f904 100644 --- a/src/rootserver/ob_root_service.h +++ b/src/rootserver/ob_root_service.h @@ -458,6 +458,7 @@ public: int create_resource_unit(const obrpc::ObCreateResourceUnitArg &arg); int alter_resource_unit(const obrpc::ObAlterResourceUnitArg &arg); int drop_resource_unit(const obrpc::ObDropResourceUnitArg &arg); + int clone_resource_pool(const obrpc::ObCloneResourcePoolArg &arg); int create_resource_pool(const obrpc::ObCreateResourcePoolArg &arg); int alter_resource_pool(const obrpc::ObAlterResourcePoolArg &arg); int drop_resource_pool(const obrpc::ObDropResourcePoolArg &arg); @@ -508,6 +509,7 @@ public: int drop_tablegroup(const obrpc::ObDropTablegroupArg &arg); int drop_index(const obrpc::ObDropIndexArg &arg, obrpc::ObDropIndexRes &res); int rebuild_index(const obrpc::ObRebuildIndexArg &arg, obrpc::ObAlterTableRes &res); + int clone_tenant(const obrpc::ObCloneTenantArg &arg, obrpc::ObCloneTenantRes &res); //the interface only for switchover: execute skip check enable_ddl int flashback_index(const obrpc::ObFlashBackIndexArg &arg); int purge_index(const obrpc::ObPurgeIndexArg &arg); diff --git a/src/rootserver/ob_rs_async_rpc_proxy.h b/src/rootserver/ob_rs_async_rpc_proxy.h index d3144f9ff3..d1cc961e42 100644 --- a/src/rootserver/ob_rs_async_rpc_proxy.h +++ b/src/rootserver/ob_rs_async_rpc_proxy.h @@ -82,7 +82,12 @@ RPC_F(obrpc::OB_KILL_CLIENT_SESSION, obrpc::ObKillClientSessionArg, obrpc::ObKil #ifdef OB_BUILD_TDE_SECURITY RPC_F(obrpc::OB_RESTORE_KEY, obrpc::ObRestoreKeyArg, obrpc::ObRestoreKeyResult, ObRestoreKeyProxy); RPC_F(obrpc::OB_SET_ROOT_KEY, obrpc::ObRootKeyArg, obrpc::ObRootKeyResult, ObSetRootKeyProxy); +RPC_F(obrpc::OB_CLONE_KEY, obrpc::ObCloneKeyArg, obrpc::ObCloneKeyResult, ObCloneKeyProxy); +RPC_F(obrpc::OB_TRIM_KEY_LIST, obrpc::ObTrimKeyListArg, obrpc::ObTrimKeyListResult, ObTrimKeyListProxy); #endif +RPC_F(obrpc::OB_INNER_CREATE_TENANT_SNAPSHOT, obrpc::ObInnerCreateTenantSnapshotArg, obrpc::ObInnerCreateTenantSnapshotResult, ObTenantSnapshotCreatorProxy); +RPC_F(obrpc::OB_INNER_DROP_TENANT_SNAPSHOT, obrpc::ObInnerDropTenantSnapshotArg, obrpc::ObInnerDropTenantSnapshotResult, ObTenantSnapshotDropperProxy); +RPC_F(obrpc::OB_FLUSH_LS_ARCHIVE, obrpc::ObFlushLSArchiveArg, obrpc::Int64, ObFlushLSArchiveProxy); }//end namespace rootserver }//end namespace oceanbase diff --git a/src/rootserver/ob_rs_rpc_processor.h b/src/rootserver/ob_rs_rpc_processor.h index c2d3e09ade..ca781880cf 100644 --- a/src/rootserver/ob_rs_rpc_processor.h +++ b/src/rootserver/ob_rs_rpc_processor.h @@ -389,6 +389,7 @@ DEFINE_RS_RPC_PROCESSOR(obrpc::OB_ROOT_MINOR_FREEZE, ObRpcRootMinorFreezeP, root DEFINE_RS_RPC_PROCESSOR(obrpc::OB_CREATE_RESOURCE_UNIT, ObRpcCreateResourceUnitP, create_resource_unit(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_ALTER_RESOURCE_UNIT, ObRpcAlterResourceUnitP, alter_resource_unit(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_DROP_RESOURCE_UNIT, ObRpcDropResourceUnitP, drop_resource_unit(arg_)); +DEFINE_RS_RPC_PROCESSOR(obrpc::OB_CLONE_RESOURCE_POOL, ObRpcCloneResourcePoolP, clone_resource_pool(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_CREATE_RESOURCE_POOL, ObRpcCreateResourcePoolP, create_resource_pool(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_ALTER_RESOURCE_POOL, ObRpcAlterResourcePoolP, alter_resource_pool(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_DROP_RESOURCE_POOL, ObRpcDropResoucePoolP, drop_resource_pool(arg_)); @@ -527,6 +528,7 @@ DEFINE_RS_RPC_PROCESSOR(obrpc::OB_BACKUP_CLEAN, ObBackupCleanP, handle_backup_de DEFINE_RS_RPC_PROCESSOR(obrpc::OB_DELETE_POLICY, ObDeletePolicyP, handle_delete_policy(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_PHYSICAL_RESTORE_RES, ObRpcPhysicalRestoreResultP, send_physical_restore_result(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_RECOVER_TABLE, ObRecoverTableP, handle_recover_table(arg_)); +DEFINE_RS_RPC_PROCESSOR(obrpc::OB_CLONE_TENANT, ObRpcCloneTenantP, clone_tenant(arg_, result_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_RS_FLUSH_OPT_STAT_MONITORING_INFO, ObRpcFlushOptStatMonitoringInfoP, flush_opt_stat_monitoring_info(arg_)); diff --git a/src/rootserver/ob_tenant_balance_service.cpp b/src/rootserver/ob_tenant_balance_service.cpp index 2af297a71e..e6af38ffdf 100755 --- a/src/rootserver/ob_tenant_balance_service.cpp +++ b/src/rootserver/ob_tenant_balance_service.cpp @@ -25,6 +25,7 @@ #include "rootserver/ob_balance_ls_primary_zone.h"//ObBalanceLSPrimaryZone #include "observer/ob_server_struct.h"//GCTX #include "rootserver/ob_partition_balance.h" // partition balance +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" //ObTenantSnapshotUtil #include "storage/tablelock/ob_lock_utils.h" // ObInnerTableLockUtil #include "share/ob_cluster_version.h" #include "share/ob_share_util.h" // ObShareUtil @@ -635,6 +636,7 @@ int ObTenantBalanceService::persist_job_and_task_(const share::ObBalanceJob &job ObArray &tasks) { int ret = OB_SUCCESS; + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::TRANSFER); if (OB_UNLIKELY(!inited_ || ! ATOMIC_LOAD(&loaded_))) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(inited_), K(loaded_)); @@ -654,6 +656,8 @@ int ObTenantBalanceService::persist_job_and_task_(const share::ObBalanceJob &job LOG_WARN("lock and check balance job failed", KR(ret), K_(tenant_id)); } else if (OB_FAIL(ObBalanceJobTableOperator::insert_new_job(job, trans))) { LOG_WARN("failed to insert new job", KR(ret), K(job)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(tenant_id_, case_to_check))) { + LOG_WARN("fail to check whether tenant is cloning", KR(ret), K_(tenant_id), K(case_to_check)); } for (int64_t i = 0; OB_SUCC(ret) && i < tasks.count(); ++i) { if (OB_FAIL(ObBalanceTaskTableOperator::insert_new_task(tasks.at(i), diff --git a/src/rootserver/ob_tenant_thread_helper.cpp b/src/rootserver/ob_tenant_thread_helper.cpp index b1fb2a7136..5fbe6382e3 100755 --- a/src/rootserver/ob_tenant_thread_helper.cpp +++ b/src/rootserver/ob_tenant_thread_helper.cpp @@ -21,6 +21,7 @@ #include "share/ob_share_util.h"//ObShareUtil #include "share/ob_tenant_info_proxy.h"//ObAllTenantInfo #include "share/restore/ob_physical_restore_table_operator.h"//restore_job +#include "share/restore/ob_tenant_clone_table_operator.h" // clone_job #include "share/restore/ob_physical_restore_info.h"//restore_info #include "share/ob_primary_zone_util.h"//get_ls_primary_zone_priority #include "observer/ob_server_struct.h"//GCTX @@ -324,6 +325,29 @@ int ObTenantThreadHelper::check_can_do_recovery_(const uint64_t tenant_id) ret = OB_NEED_WAIT; LOG_WARN("restore tenant not valid to recovery", KR(ret), K(job_info)); } + } else if (is_clone_tenant(tenant_role)) { + //need to check success to create init ls + share::ObTenantCloneTableOperator clone_table_operator; + ObArray job_arr; + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql can't null", KR(ret), K(GCTX.sql_proxy_)); + } else if (OB_FAIL(clone_table_operator.init(tenant_id, GCTX.sql_proxy_))) { + LOG_WARN("fail to init clone table operator", KR(ret), K(tenant_id)); + } else if (OB_FAIL(clone_table_operator.get_all_clone_jobs(job_arr))) { + LOG_WARN("fail to get clone job", KR(ret), K(tenant_id)); + } else if (job_arr.empty()) { + ret = OB_NEED_WAIT; + LOG_WARN("clone job is empty", KR(ret), K(tenant_id)); + } else if (job_arr.count()!=1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("clone job's count is unexpected", KR(ret), K(job_arr)); + } else if (job_arr.at(0).is_valid_status_allows_user_tenant_to_do_ls_recovery()) { + //can do recovery + } else { + ret = OB_NEED_WAIT; + LOG_WARN("clone tenant not valid to recovery", KR(ret), K(job_arr)); + } } else if (is_invalid_tenant(tenant_role)) { ret = OB_NEED_WAIT; LOG_WARN("tenant role not ready, need wait", KR(ret), K(tenant_role)); diff --git a/src/rootserver/ob_unit_manager.cpp b/src/rootserver/ob_unit_manager.cpp index b8a2883174..ff34006f85 100644 --- a/src/rootserver/ob_unit_manager.cpp +++ b/src/rootserver/ob_unit_manager.cpp @@ -110,10 +110,15 @@ double ObUnitManager::ObUnitLoad::get_demand(ObResourceType resource_type) const const char *ObUnitManager::end_migrate_op_type_to_str(const ObUnitManager::EndMigrateOp &t) { const char* str = "UNKNOWN"; - if (EndMigrateOp::COMMIT == t) { str = "COMMIT"; } - else if (EndMigrateOp::ABORT == t) { str = "ABORT"; } - else if (EndMigrateOp::REVERSE == t) { str = "REVERSE"; } - else { str = "NONE"; } + if (EndMigrateOp::COMMIT == t) { + str = "COMMIT"; + } else if (EndMigrateOp::ABORT == t) { + str = "ABORT"; + } else if (EndMigrateOp::REVERSE == t) { + str = "REVERSE"; + } else { + str = "NONE"; + } return str; } //////////////////////////////////////////////////////////////// @@ -563,6 +568,37 @@ int ObUnitManager::alter_unit_config(const ObUnitConfig &unit_config) return ret; } +int ObUnitManager::check_unit_config_exist(const share::ObUnitConfigName &unit_config_name, + bool &is_exist) +{ + int ret = OB_SUCCESS; + SpinRLockGuard guard(lock_); + ObUnitConfig *config = NULL; + is_exist = false; + + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(inited_), K(loaded_)); + } else if (unit_config_name.is_empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(unit_config_name)); + } else if (OB_FAIL(get_unit_config_by_name(unit_config_name, config))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("get_unit_config_by_name failed", KR(ret), K(unit_config_name)); + } else { + ret = OB_SUCCESS; + // is_exist = false + } + } else if (OB_ISNULL(config)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), KP(config), K(unit_config_name)); + } else { + is_exist = true; + } + + return ret; +} + int ObUnitManager::drop_unit_config(const ObUnitConfigName &name, const bool if_exist) { int ret = OB_SUCCESS; @@ -721,6 +757,112 @@ int ObUnitManager::inner_check_pool_in_shrinking_( return ret; } +int ObUnitManager::construct_resource_pool_to_clone_( + const uint64_t source_tenant_id, + share::ObResourcePool &pool_to_clone) +{ + int ret = OB_SUCCESS; + int64_t unit_num = 0; + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTenantSchema *tenant_schema = NULL; + common::ObSEArray zone_list; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == source_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(construct_source_tenant_unit_num_(source_tenant_id, unit_num))) { + LOG_WARN("fail to construct source tenant unit_num", KR(ret), K(source_tenant_id), K(unit_num)); + } else if (OB_ISNULL(schema_service_)) { + ret = OB_NOT_INIT; + LOG_WARN("schema service is null", K(schema_service_), KR(ret)); + } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get tenant schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(source_tenant_id, tenant_schema))) { + LOG_WARN("fail to get tenant info", KR(ret), K(source_tenant_id)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant schema is null", KR(ret), KP(tenant_schema)); + // just get units in locality is ok + } else if (OB_FAIL(tenant_schema->get_zone_list(zone_list))) { + LOG_WARN("fail to get zone list", KR(ret)); + } else if (0 >= zone_list.count()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("source tenant zone list should have at least zone zone", KR(ret), K(source_tenant_id), K(zone_list)); + } else if (OB_FAIL(pool_to_clone.zone_list_.assign(zone_list))) { + LOG_WARN("fail to assign zone_list", KR(ret), K(source_tenant_id), K(pool_to_clone), K(zone_list)); + } else { + // pool_to_clone.name_ is already setted before + pool_to_clone.unit_count_ = unit_num; + pool_to_clone.replica_type_ = REPLICA_TYPE_FULL; + // parameters below will be setted later: + // pool_to_clone.resource_pool_id_ will be setted when inner_create_resource_pool + // pool_to_clone.unit_config_id_ will be setted when inner_create_resource_pool + // pool_to_clone.tenant_id_ will be setted when granted this pool to tenant + } + return ret; +} + +int ObUnitManager::construct_source_tenant_unit_num_( + const uint64_t source_tenant_id, + int64_t &unit_num) +{ + int ret = OB_SUCCESS; + unit_num = 0; + ObArray pool_ids; + share::ObResourcePool *pool; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == source_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(inner_get_pool_ids_of_tenant(source_tenant_id, pool_ids))) { + LOG_WARN("fail to get resource pool ids of source tenant", KR(ret), K(source_tenant_id)); + } else if (OB_UNLIKELY(0 >= pool_ids.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("source tenant should have at least one pool", KR(ret), K(pool_ids)); + } else if (OB_FAIL(get_resource_pool_by_id(pool_ids.at(0), pool))) { + LOG_WARN("fail to get first resource pool", KR(ret), K(pool_ids)); + } else if (OB_ISNULL(pool)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool is null", KR(ret), KP(pool)); + } else if (OB_UNLIKELY(0 >= pool->unit_count_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("source tenant should have at least one unit", KR(ret), K(source_tenant_id), KPC(pool)); + } else { + // tenant's resource pools should have same unit_num + // so it is ok for us to pick unit_num of first pool + unit_num = pool->unit_count_; + } + return ret; +} + +int ObUnitManager::clone_resource_pool( + share::ObResourcePool &resource_pool, + const share::ObUnitConfigName &unit_config_name, + const uint64_t source_tenant_id) +{ + int ret = OB_SUCCESS; + LOG_INFO("start clone_resource_pool", K(resource_pool), K(unit_config_name), K(source_tenant_id)); + SpinWLockGuard guard(lock_); + bool if_not_exist = false; + common::ObArray source_units; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == source_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(resource_pool), K(unit_config_name), K(source_tenant_id)); + } else if (OB_FAIL(construct_resource_pool_to_clone_(source_tenant_id, resource_pool))) { + LOG_WARN("fail to construct resource pool to clone", KR(ret), K(source_tenant_id), K(resource_pool)); + } else if (OB_FAIL(inner_get_all_unit_infos_by_tenant_(source_tenant_id, source_units))) { + LOG_WARN("fail to get units by source tenant", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(inner_create_resource_pool( + resource_pool, + unit_config_name, + if_not_exist, + source_tenant_id, + source_units))) { + LOG_WARN("fail to inner create resource pool for clone tenant", KR(ret), K(resource_pool), + K(unit_config_name), K(if_not_exist), K(source_tenant_id), K(source_units)); + } + LOG_INFO("finish clone_resource_pool", KR(ret), K(resource_pool), K(unit_config_name), K(source_tenant_id)); + return ret; +} + int ObUnitManager::create_resource_pool( share::ObResourcePool &resource_pool, const ObUnitConfigName &config_name, @@ -728,8 +870,9 @@ int ObUnitManager::create_resource_pool( { int ret = OB_SUCCESS; SpinWLockGuard guard(lock_); - if (OB_FAIL(inner_create_resource_pool(resource_pool, config_name, if_not_exist))) { - LOG_WARN("fail to inner create resource pool", K(ret)); + common::ObArray source_units; // not used + if (OB_FAIL(inner_create_resource_pool(resource_pool, config_name, if_not_exist, OB_INVALID_TENANT_ID/*source_tenant_id*/, source_units))) { + LOG_WARN("fail to inner create resource pool", KR(ret), K(resource_pool), K(config_name), K(if_not_exist)); } return ret; } @@ -737,21 +880,30 @@ int ObUnitManager::create_resource_pool( int ObUnitManager::inner_create_resource_pool( share::ObResourcePool &resource_pool, const ObUnitConfigName &config_name, - const bool if_not_exist) + const bool if_not_exist, + const uint64_t source_tenant_id, + const common::ObIArray &source_units) { int ret = OB_SUCCESS; - LOG_INFO("start create resource pool", K(resource_pool), K(config_name)); + LOG_INFO("start inner create resource pool", K(resource_pool), K(config_name), + K(if_not_exist), K(source_tenant_id), K(source_units)); ObUnitConfig *config = NULL; share::ObResourcePool *pool = NULL; - const char *module = "CREATE_RESOURCE_POOL"; bool is_bootstrap_pool = (ObUnitConfig::SYS_UNIT_CONFIG_ID == resource_pool.unit_config_id_); + // source_tenant_id is used to recognize whether this resource pool is for clone tenant + // if OB_INVALID_TENANT_ID == source_tenant_id means this is clone resource pool for clone tenant + // if OB_INVALID_TENANT_ID != source_tenant_id means this is create resource pool for normal/restore tenant + // so please DO NOT check whether source_tenant_id is valid or not + bool is_clone_tenant = OB_INVALID_TENANT_ID != source_tenant_id; + const char *module = is_clone_tenant ? "CLONE_RESOURCE_POOL" : "CREATE_RESOURCE_POOL"; + if (!check_inner_stat()) { ret = OB_INNER_STAT_ERROR; LOG_WARN("check_inner_stat failed", K(inited_), K(loaded_), K(ret)); } else if (is_bootstrap_pool && OB_FAIL(check_bootstrap_pool(resource_pool))) { LOG_WARN("check bootstrap pool failed", K(resource_pool), K(ret)); - } else if (!is_bootstrap_pool && OB_FAIL(check_resource_pool(resource_pool))) { - LOG_WARN("check_resource_pool failed", K(resource_pool), K(ret)); + } else if (!is_bootstrap_pool && OB_FAIL(check_resource_pool(resource_pool, is_clone_tenant))) { + LOG_WARN("check_resource_pool failed", K(resource_pool), K(is_clone_tenant), K(ret)); } else if (config_name.is_empty()) { ret = OB_INVALID_ARGUMENT; LOG_USER_ERROR(OB_INVALID_ARGUMENT, "resource unit name"); @@ -812,14 +964,19 @@ int ObUnitManager::inner_create_resource_pool( } } if (OB_FAIL(ret)) { - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, *new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, *new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("update_resource_pool failed", "resource_pool", *new_pool, K(ret)); } else if (OB_FAIL(update_pool_map(new_pool))) { LOG_WARN("update pool map failed", "resource_pool", *new_pool, K(ret)); } if (OB_SUCCESS == ret && !is_bootstrap_resource_pool(new_pool->resource_pool_id_)) { - if (OB_FAIL(allocate_new_pool_units_(trans, *new_pool, module))) { + if (is_clone_tenant) { + if (OB_FAIL(check_new_pool_units_for_clone_tenant_(trans, *new_pool, source_units))) { + LOG_WARN("fail to check new pool units for clone tenant", KR(ret), + K(source_tenant_id), K(source_units), "resource_pool", *new_pool); + } + } else if (OB_FAIL(allocate_new_pool_units_(trans, *new_pool, module))) { LOG_WARN("arrange pool units failed", K(module), KR(ret), "resource_pool", *new_pool); } } @@ -890,15 +1047,214 @@ int ObUnitManager::inner_create_resource_pool( } else if (OB_FAIL(insert_config_pool(config->unit_config_id(), new_pool))) { LOG_WARN("insert config pool failed", "config id", config->unit_config_id(), K(ret)); } else { - ROOTSERVICE_EVENT_ADD("unit", "create_resource_pool", + ROOTSERVICE_EVENT_ADD("unit", is_clone_tenant ? "clone_resource_pool" : "create_resource_pool", "name", new_pool->name_, "unit", config_name, - "zone_list", new_pool->zone_list_); + "zone_list", new_pool->zone_list_, + "source_tenant_id", source_tenant_id); } } } } - LOG_INFO("finish create resource pool", K(resource_pool), K(config_name), K(ret)); + LOG_INFO("finish inner create resource pool", K(resource_pool), K(config_name), + K(source_tenant_id), K(source_units), K(ret)); + return ret; +} + +int ObUnitManager::check_new_pool_units_for_clone_tenant_( + ObISQLClient &client, + const share::ObResourcePool &pool, + const common::ObIArray &source_units) +{ + int ret = OB_SUCCESS; + ObUnitConfig *config = NULL; + ObArray servers_info_of_source_units; + ObArray server_resources; + std::string resource_not_enough_reason; + + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(inited_), K(loaded_)); + } else if (OB_UNLIKELY(!pool.is_valid()) + || OB_UNLIKELY(pool.zone_list_.count() <= 0) + || OB_UNLIKELY(source_units.count() <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid pool", KR(ret), K(pool), K(source_units)); + } else if (OB_ISNULL(srv_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("srv_rpc_proxy_ is null", KR(ret), KP(srv_rpc_proxy_)); + } else if (OB_FAIL(get_unit_config_by_id(pool.unit_config_id_, config))) { + LOG_WARN("get_unit_config_by_id failed", KR(ret), "unit_config_id", pool.unit_config_id_); + } else if (OB_ISNULL(config)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("config is null", KR(ret), KP(config)); + } else { + ObNotifyTenantServerResourceProxy notify_proxy( + *srv_rpc_proxy_, + &obrpc::ObSrvRpcProxy::notify_tenant_server_unit_resource); + for (int64_t i = 0; OB_SUCC(ret) && i < pool.zone_list_.count(); i++) { + // for each zone, check servers have enough resources + // ATTENTION: + // The locations of clone tenant's units are certain according to source tenant's units + // So there is no need to allocate servers for these units, but we have to check whether + // these servers have enough resources. + // We regard server inactive as a common case, let check success but log WARN in log file. + // We can ignore server inactive because majority of snapshot restored successfully is enough, + // it is ok currently to let it passed, just let log stream creation to handle this situation. + const ObZone &zone = pool.zone_list_.at(i); + servers_info_of_source_units.reuse(); + server_resources.reuse(); + + if (OB_FAIL(construct_server_resources_info_( + zone, + source_units, + servers_info_of_source_units, + server_resources))) { + LOG_WARN("fail to construct server resource infos", KR(ret), K(zone), K(source_units)); + } else if (OB_FAIL(check_server_resources_and_persist_unit_info_( + client, + notify_proxy, + zone, + pool, + servers_info_of_source_units, + server_resources, + config->unit_resource()))) { + LOG_WARN("fail to check and persist unit info", KR(ret), K(zone), K(pool), + K(servers_info_of_source_units), K(server_resources), KPC(config)); + } + } + } + return ret; +} + +int ObUnitManager::construct_server_resources_info_( + const ObZone &zone, + const ObIArray &source_units, + ObIArray &server_infos, + ObIArray &server_resources) +{ + int ret = OB_SUCCESS; + server_infos.reset(); + server_resources.reset(); + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(inited_), K(loaded_)); + } else if (OB_UNLIKELY(zone.is_empty()) + || OB_UNLIKELY(0 >= source_units.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(zone), K(source_units)); + } else { + ObArray active_servers_resource_info_result; + for (int64_t i = 0; OB_SUCC(ret) && i < source_units.count(); i++) { + const share::ObUnit &unit = source_units.at(i).unit_; + if (zone == unit.zone_) { + const common::ObAddr &source_unit_server = unit.server_; + bool server_is_active = false; + if (OB_FAIL(SVR_TRACER.check_server_active(source_unit_server, server_is_active))) { + LOG_WARN("fail to check server active", KR(ret), K(zone), K(unit), + K(source_unit_server), K(server_is_active)); + } else if (server_is_active) { + ObServerInfoInTable server_info; + if (OB_FAIL(SVR_TRACER.get_server_info(source_unit_server, server_info))) { + LOG_WARN("fail to get server info", KR(ret), K(source_unit_server), K(server_info)); + } else if (OB_FAIL(server_infos.push_back(server_info))) { + LOG_WARN("fail to add active server info into array", KR(ret), K(server_info)); + } + } else { + // TODO@jingyu.cr: + // If server not alive, we can not get correct cpu/mem/log_disk capacity, so just ignore them + // Later, we can handle this case by ignoring zone with inactive server or find another valid + // server to put unit on, just let other majority replicas successfully restored is ok. + LOG_WARN("[CLONE_TENANT_UNIT] server is inactive, create clone tenant resource pool may failed", + K(zone), K(source_unit_server), K(server_is_active)); + } + } + } + if (OB_FAIL(ret)) { + } else if (0 >= server_infos.count()) { + // just ignore, let snapshot creation decide whether to raise error + LOG_INFO("[CLONE_TENANT_UNIT] zone may have no valid servers to hold unit", K(zone), K(source_units)); + } else if (OB_FAIL(get_servers_resource_info_via_rpc(server_infos, active_servers_resource_info_result))) { + LOG_WARN("fail to get server resource info via rpc", KR(ret), K(server_infos)); + } else if (OB_FAIL(build_server_resources_(active_servers_resource_info_result, server_resources))) { + LOG_WARN("fail to build server resources", KR(ret), K(active_servers_resource_info_result)); + } + } + return ret; +} + +int ObUnitManager::check_server_resources_and_persist_unit_info_( + ObISQLClient &client, + ObNotifyTenantServerResourceProxy ¬ify_proxy, + const ObZone &zone, + const share::ObResourcePool &pool, + const ObIArray &server_infos, + const ObIArray &server_resources, + const share::ObUnitResource &config) +{ + int ret = OB_SUCCESS; + bool is_server_valid = false; + bool is_resource_enough = false; + uint64_t new_unit_id = OB_INVALID_ID; + ObArray new_servers; // not used + ObArray units; + const char* module = "clone_resource_pool"; + bool for_clone_tenant = true; + int64_t not_excluded_server_count = 0; + std::string resource_not_enough_reason; + ObArray excluded_servers; // not used + ObArray valid_server_resources; + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(inited_), K(loaded_)); + } else if (server_infos.count() != server_resources.count()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid servers_info and server_resources array", KR(ret), K(server_infos), K(server_resources)); + } else if (OB_FAIL(construct_valid_servers_resource_( + zone, + config, + excluded_servers, + server_infos, + server_resources, + module, + for_clone_tenant, + not_excluded_server_count, + resource_not_enough_reason, + valid_server_resources))) { + LOG_WARN("fail to construct valid servers resource", KR(ret), K(zone), K(config), + K(excluded_servers), K(server_infos), K(module), K(for_clone_tenant)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < valid_server_resources.count(); i++) { + const ObUnitPlacementStrategy::ObServerResource &server_resource = valid_server_resources.at(i); + if (OB_FAIL(try_persist_unit_info_( + notify_proxy, + client, + zone, + pool, + lib::Worker::CompatMode::INVALID/*compat_mode*/, + 0/*unit_group_id*/, + server_resource.addr_, + new_servers, + units))) { + LOG_WARN("[CLONE_TENANT_UNIT] fail to persist unit info", KR(ret), K(zone), K(pool), K(server_resource)); + } + } + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(notify_proxy.wait())) { + LOG_WARN("fail to wait notify resource", KR(ret), K(tmp_ret)); + ret = (OB_SUCCESS == ret) ? tmp_ret : ret; + } + if (OB_FAIL(ret)) { + LOG_WARN("start to rollback unit persistence", KR(ret), K(units), K(pool)); + if(OB_TMP_FAIL(rollback_persistent_units_( + units, + pool, + notify_proxy))) { + LOG_WARN("[CLONE_TENANT_UNIT] fail to rollback unit persistence", + KR(ret), KR(tmp_ret), K(units), K(pool)); + } + } + } return ret; } @@ -1104,7 +1460,7 @@ int ObUnitManager::do_split_pool_persistent_info( } else if (new_pool->zone_list_.count() != 1) { ret = OB_ERR_UNEXPECTED; LOG_WARN("zone list count unexpected", K(ret), "zone_list", new_pool->zone_list_); - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, *new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, *new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update resource pool", K(ret)); } else if (OB_FAIL(split_pool_unit_persistent_info( trans, new_pool->zone_list_.at(0), new_pool, pool))) { @@ -1369,7 +1725,7 @@ int ObUnitManager::split_pool_unit_persistent_info( } else { share::ObUnit new_unit = *unit; new_unit.resource_pool_id_ = new_pool->resource_pool_id_; - if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { + if (OB_FAIL(ut_operator_.update_unit(trans, new_unit, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update unit", K(ret), K(new_unit)); } else { ROOTSERVICE_EVENT_ADD("unit", "split_pool", @@ -1860,7 +2216,7 @@ int ObUnitManager::expand_tenant_pools_unit_num_( LOG_WARN("fail to assign new pool", KR(ret)); } else if (FALSE_IT(new_pool.unit_count_ = new_unit_num)) { // false it, shall never be here - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool, true/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update resource pool", KR(ret), K(tenant_id)); } } @@ -2070,7 +2426,7 @@ int ObUnitManager::shrink_tenant_pools_unit_num( LOG_WARN("fail to assign new pool", KR(ret), K(tenant_id), KPC(pool)); } else if (FALSE_IT(new_pool.unit_count_ = new_unit_num)) { // shall never be here - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool, true/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update resource pool", KR(ret), K(tenant_id), K(new_pool)); } else if (OB_FAIL(get_units_by_pool(pool->resource_pool_id_, units))) { LOG_WARN("fail to get units by pool", KR(ret), KPC(pool), K(tenant_id)); @@ -2091,7 +2447,7 @@ int ObUnitManager::shrink_tenant_pools_unit_num( // shall never be here } else if (FALSE_IT(new_unit.status_ = ObUnit::UNIT_STATUS_DELETING)) { // shall never be here - } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { + } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit, true/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update unit", KR(ret), K(new_unit)); } } @@ -2169,7 +2525,7 @@ int ObUnitManager::rollback_tenant_shrink_pools_unit_num( LOG_WARN("fail to assign new pool", KR(ret), KPC(pool)); } else if (FALSE_IT(new_pool.unit_count_ = new_unit_num)) { // shall never be here - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update resource pool", KR(ret), K(new_pool)); } else if (OB_FAIL(get_units_by_pool(pool->resource_pool_id_, units))) { LOG_WARN("fail to get units by pool", KR(ret), "pool_id", pool->resource_pool_id_); @@ -2187,7 +2543,7 @@ int ObUnitManager::rollback_tenant_shrink_pools_unit_num( } else if (ObUnit::UNIT_STATUS_DELETING == this_unit->status_) { ObUnit new_unit = *this_unit; new_unit.status_ = ObUnit::UNIT_STATUS_ACTIVE; - if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { + if (OB_FAIL(ut_operator_.update_unit(trans, new_unit, true/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update unit", K(ret), K(new_unit), "cur_unit", *this_unit); } } else { @@ -2587,7 +2943,7 @@ int ObUnitManager::do_merge_pool_persistent_info( merge_zone_list, old_pool))) { // The specifications of the pools to be merged are the same, so select the first pool here LOG_WARN("fail to fill merging pool basic info", K(ret)); - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, *allocate_pool_ptr))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, *allocate_pool_ptr, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update resource pool", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < old_pool.count(); ++i) { @@ -2700,7 +3056,7 @@ int ObUnitManager::merge_pool_unit_persistent_info( } else { share::ObUnit new_unit = *unit; new_unit.resource_pool_id_ = new_pool->resource_pool_id_; - if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { + if (OB_FAIL(ut_operator_.update_unit(trans, new_unit, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update unit", K(ret), K(new_unit)); } ROOTSERVICE_EVENT_ADD("unit", "merge_pool", @@ -2945,6 +3301,39 @@ int ObUnitManager::alter_resource_pool(const share::ObResourcePool &alter_pool, return ret; } +int ObUnitManager::drop_resource_pool(const uint64_t pool_id, const bool if_exist) +{ + int ret = OB_SUCCESS; + LOG_INFO("start drop resource pool", K(pool_id)); + SpinWLockGuard guard(lock_); + share::ObResourcePool *pool = NULL; + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", K(inited_), K(loaded_), K(ret)); + } else if (OB_INVALID_ID == pool_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(pool_id), K(ret)); + } else if (OB_FAIL(get_resource_pool_by_id(pool_id, pool))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("get resource pool by id failed", K(pool_id), K(ret)); + } else { + if (if_exist) { + ret = OB_SUCCESS; + LOG_USER_NOTE(OB_RESOURCE_POOL_NOT_EXIST, to_cstring(pool_id)); + LOG_INFO("resource_pool not exist, but no need drop it", K(pool_id)); + } else { + ret = OB_RESOURCE_POOL_NOT_EXIST; + LOG_USER_ERROR(OB_RESOURCE_POOL_NOT_EXIST, to_cstring(pool_id)); + LOG_WARN("resource_pool not exist", K(pool_id), K(ret)); + } + } + } else if (OB_FAIL(inner_drop_resource_pool(pool))) { + LOG_WARN("fail to inner drop resource pool", KR(ret), K(pool_id)); + } + LOG_INFO("finish drop resource pool", K(pool_id), K(ret)); + return ret; +} + int ObUnitManager::drop_resource_pool(const ObResourcePoolName &name, const bool if_exist) { int ret = OB_SUCCESS; @@ -2972,39 +3361,13 @@ int ObUnitManager::drop_resource_pool(const ObResourcePoolName &name, const bool LOG_WARN("resource_pool not exist", K(name), K(ret)); } } - } else if (NULL == pool) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("pool is null", KP(pool), K(ret)); - } else if (pool->is_granted_to_tenant()) { - ret = OB_RESOURCE_POOL_ALREADY_GRANTED; - LOG_USER_ERROR(OB_RESOURCE_POOL_ALREADY_GRANTED, to_cstring(name)); - LOG_WARN("resource pool is granted to tenant, can't not delete it", - "tenant_id", pool->tenant_id_, K(ret)); - } else { - common::ObMySQLTransaction trans; - if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) { - LOG_WARN("start transaction failed", K(ret)); - } else if (OB_FAIL(remove_resource_pool_unit_in_trans(pool->resource_pool_id_, - trans))) { - LOG_WARN("failed to remove reource pool and unit", K(ret), K(pool)); - } - if (trans.is_started()) { - const bool commit = (OB_SUCC(ret)); - int temp_ret = OB_SUCCESS; - if (OB_SUCCESS != (temp_ret = trans.end(commit))) { - LOG_WARN("trans end failed", K(commit), K(temp_ret)); - ret = (OB_SUCCESS == ret) ? temp_ret : ret; - } - } - - if (OB_FAIL(ret)) { - } else if (OB_FAIL(delete_resource_pool_unit(pool))) { - LOG_WARN("failed to delete resource pool or unit", K(ret), K(pool)); - } + } else if (OB_FAIL(inner_drop_resource_pool(pool))) { + LOG_WARN("fail to inner drop resource pool", KR(ret), K(name)); } LOG_INFO("finish drop resource pool", K(name), K(ret)); return ret; } + int ObUnitManager::remove_resource_pool_unit_in_trans(const int64_t resource_pool_id, ObMySQLTransaction &trans) { @@ -3618,7 +3981,8 @@ int ObUnitManager::grant_pools(common::ObMySQLTransaction &trans, const lib::Worker::CompatMode compat_mode, const ObIArray &pool_names, const uint64_t tenant_id, - const bool is_bootstrap + const bool is_bootstrap, + const uint64_t source_tenant_id /*arg "const bool skip_offline_server" is no longer supported*/) { int ret = OB_SUCCESS; @@ -3670,9 +4034,9 @@ int ObUnitManager::grant_pools(common::ObMySQLTransaction &trans, LOG_WARN("fail to generate new unit group id", KR(ret), K(tenant_id), K(legal_unit_num)); } else if (OB_FAIL(do_grant_pools_( trans, new_unit_group_id_array, compat_mode, - pool_names, tenant_id, is_bootstrap))) { + pool_names, tenant_id, is_bootstrap, source_tenant_id))) { LOG_WARN("do grant pools failed", KR(ret), K(grant), K(pool_names), K(tenant_id), - K(compat_mode), K(is_bootstrap)); + K(compat_mode), K(is_bootstrap), K(source_tenant_id)); } LOG_INFO("grant resource pools to tenant", KR(ret), K(pool_names), K(tenant_id), K(is_bootstrap)); return ret; @@ -4278,6 +4642,20 @@ int ObUnitManager::inner_get_zone_alive_unit_infos_by_tenant( int ObUnitManager::get_all_unit_infos_by_tenant(const uint64_t tenant_id, ObIArray &unit_infos) +{ + int ret = OB_SUCCESS; + SpinRLockGuard guard(lock_); + unit_infos.reset(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_FAIL(inner_get_all_unit_infos_by_tenant_(tenant_id, unit_infos))) { + LOG_WARN("fail to inner get unit infos of tenant", KR(ret), K(tenant_id)); + } + return ret; +} + +int ObUnitManager::inner_get_all_unit_infos_by_tenant_(const uint64_t tenant_id, + ObIArray &unit_infos) { int ret = OB_SUCCESS; share::schema::ObSchemaGetterGuard schema_guard; @@ -4302,7 +4680,7 @@ int ObUnitManager::get_all_unit_infos_by_tenant(const uint64_t tenant_id, LOG_WARN("tenant schema is null", K(ret), KP(tenant_schema)); } else if (OB_FAIL(tenant_schema->get_zone_list(tenant_zone_list))) { LOG_WARN("fail to get zone list", K(ret)); - } else if (OB_FAIL(get_pool_ids_of_tenant(tenant_id, rs_pool))) { + } else if (OB_FAIL(inner_get_pool_ids_of_tenant(tenant_id, rs_pool))) { LOG_WARN("fail to get pool ids of tenant", K(ret), K(tenant_id)); } else { FOREACH_X(pool, rs_pool, OB_SUCCESS == ret) { @@ -4313,7 +4691,10 @@ int ObUnitManager::get_all_unit_infos_by_tenant(const uint64_t tenant_id, } else if (OB_UNLIKELY(NULL == pool)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("pool is null", K(ret)); - } else if (OB_FAIL(get_unit_infos_of_pool(*pool, unit_array))) { + } else if (OB_UNLIKELY(OB_INVALID_ID == *pool)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(inner_get_unit_infos_of_pool_(*pool, unit_array))) { LOG_WARN("fail to get unit infos of pool", K(ret)); } else if (unit_array.count() > 0) { FOREACH_X(u, unit_array, OB_SUCCESS == ret) { @@ -4688,7 +5069,9 @@ int ObUnitManager::calc_sum_load(const ObArray *unit_loads, return ret; } -int ObUnitManager::check_resource_pool(share::ObResourcePool &resource_pool) const +int ObUnitManager::check_resource_pool( + share::ObResourcePool &resource_pool, + const bool is_clone_tenant) const { int ret = OB_SUCCESS; if (!check_inner_stat()) { @@ -4703,6 +5086,7 @@ int ObUnitManager::check_resource_pool(share::ObResourcePool &resource_pool) con LOG_USER_ERROR(OB_INVALID_ARGUMENT, "unit num"); LOG_WARN("invalid resource unit num", "unit num", resource_pool.unit_count_, K(ret)); } else { + // check zones in zone_list not intersected for (int64_t i = 0; OB_SUCC(ret) && i < resource_pool.zone_list_.count(); ++i) { for (int64_t j = i + 1; OB_SUCC(ret) && j < resource_pool.zone_list_.count(); ++j) { if (resource_pool.zone_list_[i] == resource_pool.zone_list_[j]) { @@ -4713,6 +5097,7 @@ int ObUnitManager::check_resource_pool(share::ObResourcePool &resource_pool) con } } } + // check zones in zone_list all existed if (OB_SUCC(ret)) { FOREACH_CNT_X(zone, resource_pool.zone_list_, OB_SUCCESS == ret) { bool zone_exist = false; @@ -4725,6 +5110,7 @@ int ObUnitManager::check_resource_pool(share::ObResourcePool &resource_pool) con } } } + // construct all zone as zone_list if zone_list is null if (OB_SUCCESS == ret && 0 == resource_pool.zone_list_.count()) { ObArray zone_infos; if (OB_FAIL(zone_mgr_.get_zone(zone_infos))) { @@ -4741,14 +5127,22 @@ int ObUnitManager::check_resource_pool(share::ObResourcePool &resource_pool) con } } } - FOREACH_CNT_X(zone, resource_pool.zone_list_, OB_SUCCESS == ret) { - int64_t alive_server_count = 0; - if (OB_FAIL(SVR_TRACER.get_alive_servers_count(*zone, alive_server_count))) { - LOG_WARN("get_alive_servers failed", KR(ret), KPC(zone)); - } else if (alive_server_count < resource_pool.unit_count_) { - ret = OB_UNIT_NUM_OVER_SERVER_COUNT; - LOG_WARN("resource pool unit num over zone server count", "unit_count", - resource_pool.unit_count_, K(alive_server_count), K(ret), "zone", *zone); + // check zones in zone_list has enough alive servers to support unit_num + // ATTENTION: + // There is a limit that we have to persist all unit config successfully before create tenant. + // For clone tenant, the locations of units to create is certain. + // If majority of servers is down, clone tenant will fail, and this case can be detected before persist unit. + // So for clone tenant, just skip this check, just make sure majority of teannt snapshot can restored is ok. + if (!is_clone_tenant) { + FOREACH_CNT_X(zone, resource_pool.zone_list_, OB_SUCCESS == ret) { + int64_t alive_server_count = 0; + if (OB_FAIL(SVR_TRACER.get_alive_servers_count(*zone, alive_server_count))) { + LOG_WARN("get_alive_servers failed", KR(ret), KPC(zone)); + } else if (alive_server_count < resource_pool.unit_count_) { + ret = OB_UNIT_NUM_OVER_SERVER_COUNT; + LOG_WARN("resource pool unit num over zone server count", "unit_count", + resource_pool.unit_count_, K(alive_server_count), K(ret), "zone", *zone); + } } } } @@ -5113,32 +5507,17 @@ int ObUnitManager::allocate_pool_units_( } } else if (OB_FAIL(excluded_servers.push_back(server))) { LOG_WARN("push_back failed", K(ret)); - } else if (OB_FAIL(fetch_new_unit_id(unit_id))) { - LOG_WARN("fetch_new_unit_id failed", K(ret)); - } else { - const bool is_delete = false; // is_delete is false when allocate new unit - ObUnit unit; - unit.reset(); - unit.unit_id_ = unit_id; - unit.resource_pool_id_ = pool.resource_pool_id_; - unit.unit_group_id_ = (nullptr == unit_group_id_array) ? 0 : unit_group_id_array->at(j); - unit.server_ = server; - unit.status_ = ObUnit::UNIT_STATUS_ACTIVE; - unit.replica_type_ = pool.replica_type_; - if (OB_FAIL(unit.zone_.assign(zone))) { - LOG_WARN("fail to assign zone", KR(ret), K(zone)); - } else if (OB_FAIL(try_notify_tenant_server_unit_resource_( - pool.tenant_id_, is_delete, notify_proxy, - pool.unit_config_id_, compat_mode, unit, false/*if not grant*/, - false/*skip offline server*/))) { - LOG_WARN("fail to try notify server unit resource", K(ret)); - } else if (OB_FAIL(add_unit(client, unit))) { - LOG_WARN("add_unit failed", K(unit), K(ret)); - } else if (OB_FAIL(new_servers.push_back(server))) { - LOG_WARN("push_back failed", K(ret)); - } else if (OB_FAIL(units.push_back(unit))) { - LOG_WARN("fail to push an element into units", KR(ret), K(unit)); - } + } else if (OB_FAIL(try_persist_unit_info_( + notify_proxy, + client, + zone, + pool, + compat_mode, + (nullptr == unit_group_id_array) ? 0 : unit_group_id_array->at(j), + server, + new_servers, + units))) { + LOG_WARN("fail to persist unit info", KR(ret), K(zone), K(pool), K(compat_mode), K(server)); } } } @@ -5163,6 +5542,55 @@ int ObUnitManager::allocate_pool_units_( return ret; } +int ObUnitManager::try_persist_unit_info_( + ObNotifyTenantServerResourceProxy ¬ify_proxy, + ObISQLClient &client, + const ObZone &zone, + const share::ObResourcePool &pool, + const lib::Worker::CompatMode &compat_mode, + const uint64_t unit_group_id, + const ObAddr &server, + ObIArray &new_servers, + ObIArray &units) +{ + int ret = OB_SUCCESS; + ObUnit unit; + uint64_t new_unit_id = OB_INVALID_ID; + const bool is_delete = false; // is_delete is false when allocate new unit + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(inited_), K(loaded_)); + } else if (OB_UNLIKELY(zone.is_empty()) + || OB_UNLIKELY(!server.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(zone), K(server)); + } else if (OB_FAIL(fetch_new_unit_id(new_unit_id))) { + LOG_WARN("fetch_new_unit_id failed", KR(ret)); + } else { + unit.unit_id_ = new_unit_id; + unit.resource_pool_id_ = pool.resource_pool_id_; + unit.unit_group_id_ = unit_group_id; + unit.server_ = server; + unit.status_ = ObUnit::UNIT_STATUS_ACTIVE; + unit.replica_type_ = pool.replica_type_; + if (OB_FAIL(unit.zone_.assign(zone))) { + LOG_WARN("fail to assign zone", KR(ret), K(zone)); + } else if (OB_FAIL(try_notify_tenant_server_unit_resource_( + pool.tenant_id_, is_delete, notify_proxy, + pool.unit_config_id_, compat_mode, unit, false/*if not grant*/, + false/*skip offline server*/))) { + LOG_WARN("fail to try notify server unit resource", KR(ret), K(pool), K(is_delete), K(unit)); + } else if (OB_FAIL(add_unit(client, unit))) { + LOG_WARN("add_unit failed", KR(ret), K(unit), K(unit)); + } else if (OB_FAIL(new_servers.push_back(server))) { + LOG_WARN("push_back failed", KR(ret), K(server)); + } else if (OB_FAIL(units.push_back(unit))) { + LOG_WARN("fail to push an element into units", KR(ret), K(unit)); + } + } + return ret; +} + int ObUnitManager::get_excluded_servers( const ObUnit &unit, const ObUnitStat &unit_stat, @@ -5433,6 +5861,145 @@ int ObUnitManager::choose_server_for_unit( return ret; } +int ObUnitManager::check_server_status_valid_and_construct_log_( + const share::ObServerInfoInTable &server_info, + const bool for_clone_tenant, + bool &is_server_valid, + std::string ¬_valid_reason) const +{ + int ret = OB_SUCCESS; + is_server_valid = false; + const ObAddr &server = server_info.get_server(); + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(inited_), K(loaded_)); + } else if (OB_UNLIKELY(!server_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(server_info)); + } else if (!for_clone_tenant && !server_info.is_active()) { + // server is inactive + is_server_valid = false; + not_valid_reason = not_valid_reason + "server '" + to_cstring(server) + "' is not active\n"; + } else if (server_info.is_migrate_in_blocked()) { + // server is block-migrate-in + is_server_valid = false; + not_valid_reason = not_valid_reason + "server '" + to_cstring(server) + "' is blocked migrate-in\n"; + } else { + is_server_valid = true; + } + return ret; +} + +int ObUnitManager::check_server_resource_enough_and_construct_log_( + const ObUnitPlacementStrategy::ObServerResource &server_resource, + const share::ObUnitResource &config, + bool &is_resource_enough, + std::string &resource_not_enough_reason) const +{ + int ret = OB_SUCCESS; + is_resource_enough = false; + double hard_limit = 1.0; + const ObAddr &server = server_resource.get_server(); + ObResourceType not_enough_resource = RES_MAX; + AlterResourceErr not_enough_resource_config = ALT_ERR; + + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(inited_), K(loaded_)); + } else if (OB_FAIL(get_hard_limit(hard_limit))) { + LOG_WARN("get_hard_limit failed", KR(ret)); + } else if (FALSE_IT(is_resource_enough = check_resource_enough_for_unit_( + server_resource, config, hard_limit, + not_enough_resource, not_enough_resource_config))) { + // shall never be here + } else if (!is_resource_enough) { + resource_not_enough_reason = + resource_not_enough_reason + "server '" + to_cstring(server) + "' " + + resource_type_to_str(not_enough_resource) + " resource not enough\n"; + } + return ret; +} + +int ObUnitManager::construct_valid_servers_resource_( + const ObZone &zone, + const share::ObUnitResource &config, + const ObIArray &excluded_servers, + const ObIArray &servers_info, + const ObIArray &server_resources, + const char *module, + const bool for_clone_tenant, + int64_t ¬_excluded_server_count, + std::string &resource_not_enough_reason, + ObIArray &valid_server_resources) const +{ + int ret = OB_SUCCESS; + not_excluded_server_count = 0; + valid_server_resources.reset(); + if (OB_UNLIKELY(servers_info.count() != server_resources.count()) + || OB_UNLIKELY(zone.is_empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(servers_info), K(server_resources), K(zone)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < servers_info.count(); ++i) { // for each active servers + ObResourceType not_enough_resource = RES_MAX; + AlterResourceErr not_enough_resource_config = ALT_ERR; + const ObServerInfoInTable &server_info = servers_info.at(i); + const ObAddr &server = server_info.get_server(); + const ObUnitPlacementStrategy::ObServerResource &server_resource = server_resources.at(i); + bool is_server_valid = false; + bool is_resource_enough = false; + + if (has_exist_in_array(excluded_servers, server)) { + // excluded servers are expected, need not show in reason + continue; + } else { + not_excluded_server_count++; + if (OB_FAIL(check_server_status_valid_and_construct_log_( + server_info, + for_clone_tenant, + is_server_valid, + resource_not_enough_reason))) { + LOG_WARN("fail to check server status", KR(ret), K(server_info), K(for_clone_tenant)); + } else if (!is_server_valid) { + if (for_clone_tenant) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("[CLONE_TENANT_UNIT] server with invalid status, can not create clone tenant resource pool", + KR(ret), K(server_info), K(is_server_valid)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "server is block migrate in, create clone tenant resource pool"); + } else { + LOG_WARN("[CHOOSE_SERVER_FOR_UNIT] server can not migrate in", K(module), K(i), K(server_info)); + continue; + } + } else if (OB_FAIL(check_server_resource_enough_and_construct_log_( + server_resource, + config, + is_resource_enough, + resource_not_enough_reason))) { + LOG_WARN("fail to check server resource", KR(ret), K(server_resource), K(config)); + } else if (is_resource_enough) { + LOG_INFO("[CHOOSE_SERVER_FOR_UNIT] find available server", K(module), K(i), + K(server_resource), "request_unit_config", config); + if (OB_FAIL(valid_server_resources.push_back(server_resource))) { + LOG_WARN("failed to push into array", KR(ret), K(server_resource)); + } + } else { + if (for_clone_tenant) { + ret = OB_ZONE_RESOURCE_NOT_ENOUGH; + LOG_WARN("resource not enough", KR(ret), K(server_resource), K(config)); + LOG_USER_ERROR(OB_ZONE_RESOURCE_NOT_ENOUGH, + to_cstring(zone), servers_info.count(), resource_not_enough_reason.c_str()); + } else { + LOG_INFO("[CHOOSE_SERVER_FOR_UNIT] server resource not enough", K(module), K(i), + "not_enough_resource", resource_type_to_str(not_enough_resource), + "not_enough_resource_config", alter_resource_err_to_str(not_enough_resource_config), + K(server_resource), "request_unit_config", config); + } + } + } + } + } + return ret; +} int ObUnitManager::do_choose_server_for_unit_(const ObUnitResource &config, const ObZone &zone, @@ -5448,6 +6015,7 @@ int ObUnitManager::do_choose_server_for_unit_(const ObUnitResource &config, int ret = OB_SUCCESS; double hard_limit = 1.0; ObArray valid_server_resources; + bool for_clone_tenant = false; choosed_server.reset(); @@ -5462,56 +6030,20 @@ int ObUnitManager::do_choose_server_for_unit_(const ObUnitResource &config, } else { int64_t not_excluded_server_count = 0; // 1. construct valid servers resource - for (int64_t i = 0; OB_SUCC(ret) && i < servers_info.count(); ++i) { // for each active servers - ObResourceType not_enough_resource = RES_MAX; - AlterResourceErr not_enough_resource_config = ALT_ERR; - const ObServerInfoInTable &server_info = servers_info.at(i); - const ObAddr &server = server_info.get_server(); - const ObUnitPlacementStrategy::ObServerResource &server_resource = server_resources.at(i); - - if (has_exist_in_array(excluded_servers, server)) { - // excluded servers are expected, need not show in reason - continue; - } else { - not_excluded_server_count++; - - if (!server_info.can_migrate_in()) { - if (!server_info.is_active()) { - resource_not_enough_reason = - resource_not_enough_reason + "server '" + to_cstring(server) + "' is not active\n"; - } else { - // server is block-migrate-in - resource_not_enough_reason = - resource_not_enough_reason + "server '" + to_cstring(server) + "' is blocked migrate-in\n"; - } - LOG_WARN("[CHOOSE_SERVER_FOR_UNIT] server can not migrate in", K(module), K(i), "server", server_info); - continue; - } else { - bool is_resource_enough = - check_resource_enough_for_unit_(server_resource, config, hard_limit, - not_enough_resource, not_enough_resource_config); - - if (is_resource_enough) { - LOG_INFO("[CHOOSE_SERVER_FOR_UNIT] find available server", K(module), K(i), - K(server_resource), "request_unit_config", config); - - if (OB_FAIL(valid_server_resources.push_back(server_resource))) { - LOG_WARN("failed to push into array", KR(ret), K(server_resource)); - } - } else { - LOG_INFO("[CHOOSE_SERVER_FOR_UNIT] server resource not enough", K(module), K(i), - "not_enough_resource", resource_type_to_str(not_enough_resource), - "not_enough_resource_config", alter_resource_err_to_str(not_enough_resource_config), - K(server_resource), "request_unit_config", config); - resource_not_enough_reason = - resource_not_enough_reason + "server '" + to_cstring(server) + "' " - + resource_type_to_str(not_enough_resource) + " resource not enough\n"; - } - } - } - } // end for - - if (OB_SUCCESS == ret) { + if (OB_FAIL(construct_valid_servers_resource_( + zone, + config, + excluded_servers, + servers_info, + server_resources, + module, + for_clone_tenant, + not_excluded_server_count, + resource_not_enough_reason, + valid_server_resources))) { + LOG_WARN("fail to construct valid servers resource", KR(ret), K(zone), K(config), K(excluded_servers), + K(servers_info), K(server_resources), K(module), K(for_clone_tenant)); + } else { if (0 == not_excluded_server_count) { ret = OB_ZONE_SERVER_NOT_ENOUGH; LOG_WARN("zone server not enough to hold all units", K(module), KR(ret), K(zone), K(excluded_servers), @@ -6043,7 +6575,7 @@ int ObUnitManager::add_unit(ObISQLClient &client, const ObUnit &unit) ret = OB_ALLOCATE_MEMORY_FAILED; LOG_ERROR("alloc unit failed", K(ret)); } else { - if (OB_FAIL(ut_operator_.update_unit(client, unit))) { + if (OB_FAIL(ut_operator_.update_unit(client, unit, false/*need_check_conflict_with_clone*/))) { LOG_WARN("update_unit failed", K(unit), K(ret)); } else { *new_unit = unit; @@ -6393,7 +6925,7 @@ int ObUnitManager::shrink_not_granted_pool( new_pool.unit_count_ = alter_unit_num; } if (OB_FAIL(ret)) { - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update resource pool", K(ret)); } else if (OB_FAIL(check_shrink_unit_num_zone_condition(pool, alter_unit_num, delete_unit_id_array))) { LOG_WARN("fail to check shrink unit num zone condition", K(ret)); @@ -6837,7 +7369,7 @@ int ObUnitManager::expand_pool_unit_num_( LOG_WARN("failed to assign new_poll", K(ret)); } else { new_pool.unit_count_ = alter_unit_num; - if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("update_resource_pool failed", K(new_pool), K(ret)); } } @@ -7414,7 +7946,7 @@ int ObUnitManager::do_add_pool_zone_list( "pool id", pool->resource_pool_id_, K(to_be_add_zones)); } else if (OB_FAIL(pool->zone_list_.assign(new_zone_list))) { LOG_WARN("fail to update pool zone list in memory", K(ret)); - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update resource pool", K(ret)); } else {} //no more to do if (trans.is_started()) { @@ -7494,7 +8026,7 @@ int ObUnitManager::do_remove_pool_zone_list( trans, pool->resource_pool_id_, to_be_removed_zones))) { LOG_WARN("fail to remove units in zones", K(ret), "pool id", pool->resource_pool_id_, K(to_be_removed_zones)); - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update resource pool", K(ret)); } else {} // no more to do if (trans.is_started()) { @@ -7821,7 +8353,7 @@ int ObUnitManager::change_pool_config(share::ObResourcePool *pool, ObUnitConfig } if (OB_SUCC(ret)) { new_pool.unit_config_id_ = new_config->unit_config_id(); - if (OB_FAIL(ut_operator_.update_resource_pool(*proxy_, new_pool))) { + if (OB_FAIL(ut_operator_.update_resource_pool(*proxy_, new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("ut_operator_ update_resource_pool failed", K(new_pool), K(ret)); } else if (OB_FAIL(dec_config_ref_count(config->unit_config_id()))) { LOG_WARN("dec_config_ref_count failed", "unit_config_id", @@ -7956,13 +8488,206 @@ int ObUnitManager::check_pool_ownership_(const uint64_t tenant_id, return ret; } +int ObUnitManager::construct_pool_units_to_grant_( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const share::ObResourcePool &new_pool, + const common::ObIArray &zone_sorted_unit_array, + const common::ObIArray &new_ug_ids, + const lib::Worker::CompatMode &compat_mode, + ObNotifyTenantServerResourceProxy ¬ify_proxy, + const uint64_t source_tenant_id, + ObIArray &pool_units) +{ + int ret = OB_SUCCESS; + pool_units.reset(); + common::ObArray source_units; + common::ObArray source_ug_ids; + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K_(inited), K_(loaded)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id)) + || OB_UNLIKELY(0 >= zone_sorted_unit_array.count()) + || OB_UNLIKELY(0 >= new_ug_ids.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(zone_sorted_unit_array), + K(new_ug_ids)); + } else { + if (OB_INVALID_TENANT_ID != source_tenant_id) { + if (OB_FAIL(inner_get_all_unit_infos_by_tenant_(source_tenant_id, source_units))) { + LOG_WARN("fail to get source units of source tenant", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(construct_source_unit_group_ids_(source_units, source_ug_ids))) { + LOG_WARN("fail to construct source unit group ids", KR(ret), K(source_units)); + } + } + ObUnit new_unit; + for (int64_t j = 0; OB_SUCC(ret) && j < zone_sorted_unit_array.count(); ++j) { + ObUnit *unit = zone_sorted_unit_array.at(j); + uint64_t unit_group_id_to_set = 0; + new_unit.reset(); + if (OB_ISNULL(unit)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unit ptr is null", KR(ret)); + } else if (OB_FAIL(try_notify_tenant_server_unit_resource_( + tenant_id, false /*is_delete*/, notify_proxy, + new_pool.unit_config_id_, compat_mode, *unit, + false/*if_not_grant*/, false/*skip_offline_server*/))) { + LOG_WARN("fail to try notify server unit resource", KR(ret), + K(tenant_id), K(compat_mode), KPC(unit)); + } else if (FALSE_IT(new_unit = *unit)) { + // shall never be here + } else if (OB_FAIL(construct_unit_group_id_for_unit_( + source_tenant_id, + source_units, + source_ug_ids, + *unit, + j/*unit_index*/, + new_pool.unit_count_, + new_ug_ids, + unit_group_id_to_set))) { + LOG_WARN("fail to construct unit group id for unit", KR(ret), K(source_tenant_id), + K(source_units), K(source_ug_ids), KPC(unit), K(j), K(new_pool), K(new_ug_ids)); + } else if (FALSE_IT(new_unit.unit_group_id_ = unit_group_id_to_set)) { + // shall never be here + } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit, false/*need_check_conflict_with_clone*/))) { + LOG_WARN("fail to update unit", KR(ret), K(new_unit)); + } else if (OB_FAIL(pool_units.push_back(*unit))) { + LOG_WARN("fail to push an element into pool_units", KR(ret), KPC(unit)); + } + } + } + return ret; +} + +int ObUnitManager::construct_source_unit_group_ids_( + const common::ObIArray &source_units, + common::ObIArray &source_unit_group_ids) +{ + int ret = OB_SUCCESS; + source_unit_group_ids.reset(); + if (OB_UNLIKELY(0 == source_units.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid source units", KR(ret), K(source_units)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < source_units.count(); ++i) { + uint64_t source_unit_group_id = 0; + if (!source_units.at(i).unit_.is_active_status()) { + // we can ensure all unit belongs to source tenant is active status, so it is unexpected to find an inactive unit + ret = OB_STATE_NOT_MATCH; + LOG_WARN("unit status is not expected", KR(ret), K(source_units), K(i)); + } else { + source_unit_group_id = source_units.at(i).unit_.unit_group_id_; + if (!has_exist_in_array(source_unit_group_ids, source_unit_group_id)) { + if (OB_FAIL(source_unit_group_ids.push_back(source_unit_group_id))) { + LOG_WARN("fail to add source unit group id into array", KR(ret), K(source_unit_group_id)); + } + } + } + } + } + return ret; +} + +int ObUnitManager::construct_unit_group_id_for_unit_( + const uint64_t source_tenant_id, + const common::ObIArray &source_units, + const common::ObIArray &source_unit_group_ids, + const ObUnit &target_unit, + const int64_t unit_index, + const int64_t unit_num, + const common::ObIArray &new_ug_ids, + uint64_t &unit_group_id) +{ + int ret = OB_SUCCESS; + unit_group_id = OB_INVALID_ID; + common::ObArray sorted_new_ug_ids; + common::ObArray sorted_source_ug_ids; + + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K_(inited), K_(loaded)); + } else if (OB_UNLIKELY(0 >= unit_num) + || OB_UNLIKELY(0 > unit_index) + || OB_UNLIKELY(new_ug_ids.count() != unit_num) + || OB_UNLIKELY(0 >= new_ug_ids.count()) + || OB_UNLIKELY((source_unit_group_ids.count() != new_ug_ids.count() && 0!= source_unit_group_ids.count()))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(unit_index), K(source_units), K(source_unit_group_ids), + K(unit_num), K(new_ug_ids)); + } else if (OB_INVALID_TENANT_ID == source_tenant_id) { + // for tenant not clone, just allocate new unit group ids by order + unit_group_id = new_ug_ids.at(unit_index % (unit_num)); + } else { + // for clone tenant, we have to choose new unit group id for this unit + if (OB_FAIL(sorted_new_ug_ids.assign(new_ug_ids))) { + LOG_WARN("fail to assign unit group ids", KR(ret), K(new_ug_ids)); + } else if (OB_FAIL(sorted_source_ug_ids.assign(source_unit_group_ids))) { + LOG_WARN("fail to assign source unit group ids", KR(ret), K(source_unit_group_ids)); + } else { + // construct sorted unit group ids first + std::sort(sorted_new_ug_ids.begin(), sorted_new_ug_ids.end()); + std::sort(sorted_source_ug_ids.begin(), sorted_source_ug_ids.end()); + // for clone tenant, we have to construct unit_group_id for its units + // the rule to allocate unit_group_id + // + // resume source tenant has source_units like below: + // ======================================================== + // | server_addr | source_unit_id | source_unit_group_id | + // ======================================================== + // | server A | 1001 | ug1 | + // |------------------------------------------------------| + // | server B | 1002 | ug2 | + // |------------------------------------------------------| + // | server C | 1003 | ug3 | + // ======================================================== + // + // And we have 3 new unit group ids belongs to clone tenant, mark them as new_ug4, new_ug5, new_ug6. + // And assume unit id for clone tenant is 1004(server B), 1005(server A), 1006(server C). + // And assume ug1 > ug3 > ug2 + // And assume new_ug5 > new_ug6 > new_ug4 + // + // The logic to construct unit_group_id for unit(1004) is firstly to get the unit with same server(B), which is unit 1002. + // Then caculate the order of source_unit_group_id(which is ug2) belongs to unit 1002 during all source_group_ids.(The smallest one) + // Then get the smallest new unit_group_id which is new_ug4. + // After all, the unit group id constructed for unit 1004 is new_ug4. + // + // ATTENTION: + // The main logic here is to gurantee a mapping relationship between source_ug_ids and new_ug_ids by comparing the order. + const common::ObAddr target_server = target_unit.server_; + uint64_t source_unit_group_id = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < source_units.count(); ++i) { + if (target_server == source_units.at(i).unit_.server_) { + source_unit_group_id = source_units.at(i).unit_.unit_group_id_; + int64_t index = OB_INVALID_INDEX_INT64; + if (has_exist_in_array(sorted_source_ug_ids, source_unit_group_id, &index)) { + unit_group_id = sorted_new_ug_ids.at(index); + break; + } else { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("can not find unit group id from source ug ids", KR(ret), + K(sorted_source_ug_ids), K(source_unit_group_id)); + } + } + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(OB_INVALID_ID == unit_group_id)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("can not find a valid unit group id", KR(ret), K(source_tenant_id), K(unit_group_id), + K(source_units), K(target_unit), K(sorted_source_ug_ids), K(sorted_new_ug_ids)); + } + return ret; +} + int ObUnitManager::do_grant_pools_( ObMySQLTransaction &trans, const common::ObIArray &new_ug_ids, const lib::Worker::CompatMode compat_mode, const ObIArray &pool_names, const uint64_t tenant_id, - const bool is_bootstrap) + const bool is_bootstrap, + const uint64_t source_tenant_id) { int ret = OB_SUCCESS; if (!check_inner_stat()) { @@ -7999,40 +8724,28 @@ int ObUnitManager::do_grant_pools_( LOG_WARN("failed to assign new_pool", KR(ret)); } else if (FALSE_IT(new_pool.tenant_id_ = tenant_id)) { // shall never be here - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool,false/*need_check_conflict_with_clone*/))) { LOG_WARN("update_resource_pool failed", K(new_pool), KR(ret)); } else if (is_bootstrap) { //no need to notify unit and modify unit group id } else if (OB_FAIL(build_zone_sorted_unit_array_(pool, zone_sorted_unit_array))) { LOG_WARN("failed to generate zone_sorted_unit_array", KR(ret), KPC(pool)); - } else { - ObUnit new_unit; - for (int64_t j = 0; OB_SUCC(ret) && j < zone_sorted_unit_array.count(); ++j) { - ObUnit *unit = zone_sorted_unit_array.at(j); - new_unit.reset(); - if (OB_ISNULL(unit)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unit ptr is null", KR(ret)); - } else if (OB_FAIL(try_notify_tenant_server_unit_resource_( - tenant_id, false /*is_delete*/, notify_proxy, - new_pool.unit_config_id_, compat_mode, *unit, - false/*if_not_grant*/, false/*skip_offline_server*/))) { - LOG_WARN("fail to try notify server unit resource", KR(ret)); - } else if (FALSE_IT(new_unit = *unit)) { - // shall never be here - } else if (FALSE_IT(new_unit.unit_group_id_ = new_ug_ids.at(j % (pool->unit_count_)))) { - // shall never be here - } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { - LOG_WARN("fail to update unit", KR(ret)); - } else if (OB_FAIL(pool_units.push_back(*unit))) { - LOG_WARN("fail to push an element into pool_units", KR(ret)); - } - } - } - if (FAILEDx(all_pool_units.push_back(pool_units))) { - LOG_WARN("fail to push an element into all_pool_units", KR(ret)); + } else if (OB_FAIL(construct_pool_units_to_grant_( + trans, + tenant_id, + new_pool, + zone_sorted_unit_array, + new_ug_ids, + compat_mode, + notify_proxy, + source_tenant_id, + pool_units))) { + LOG_WARN("fail to construct pool units to grant", KR(ret), K(tenant_id), K(new_pool), + K(zone_sorted_unit_array), K(new_ug_ids), K(compat_mode), K(source_tenant_id)); + } else if (OB_FAIL(all_pool_units.push_back(pool_units))) { + LOG_WARN("fail to push an element into all_pool_units", KR(ret), K(pool_units)); } else if (OB_FAIL(pools.push_back(new_pool))) { - LOG_WARN("fail to push an element into pools", KR(ret)); + LOG_WARN("fail to push an element into pools", KR(ret), K(new_pool)); } } int tmp_ret = OB_SUCCESS; @@ -8101,7 +8814,7 @@ int ObUnitManager::do_revoke_pools_( LOG_WARN("failed to assign new_pool", KR(ret)); } else if (FALSE_IT(new_pool.tenant_id_ = OB_INVALID_ID)) { // shall never be here - } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool))) { + } else if (OB_FAIL(ut_operator_.update_resource_pool(trans, new_pool, false/*need_check_conflict_with_clone*/))) { LOG_WARN("update_resource_pool failed", K(new_pool), KR(ret)); } else if (OB_FAIL(build_zone_sorted_unit_array_(pool, zone_sorted_unit_array))) { LOG_WARN("failed to generate zone_sorted_unit_array", KR(ret), KPC(pool)); @@ -8122,7 +8835,7 @@ int ObUnitManager::do_revoke_pools_( // shall never be here } else if (FALSE_IT(new_unit.unit_group_id_ = new_ug_ids.at(j % (pool->unit_count_)))) { // shall never be here - } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { + } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit, false/*need_check_conflict_with_clone*/))) { LOG_WARN("fail to update unit", KR(ret)); } } @@ -8792,7 +9505,7 @@ int ObUnitManager::do_migrate_unit_in_trans_(const share::ObResourcePool &pool, } // Update unit info if (OB_FAIL(ret)) { - } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { + } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit, true/*need_check_conflict_with_clone*/))) { LOG_WARN("update_unit failed", K(new_unit), K(ret)); } // End this transaction @@ -8968,7 +9681,7 @@ int ObUnitManager::end_migrate_unit(const uint64_t unit_id, const EndMigrateOp e if (OB_FAIL(ret)) { } else if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) { LOG_WARN("failed to start transaction ", K(ret)); - } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit))) { + } else if (OB_FAIL(ut_operator_.update_unit(trans, new_unit, true/*need_check_conflict_with_clone*/))) { LOG_WARN("ut_operator update unit failed", K(new_unit), K(ret)); } else { if (ABORT == end_migrate_op) { @@ -10144,6 +10857,44 @@ int ObUnitManager::delete_migrate_unit(const ObAddr &src_server, return ret; } +int ObUnitManager::inner_drop_resource_pool(share::ObResourcePool *pool) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(pool)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pool is null", KP(pool), K(ret)); + } else if (pool->is_granted_to_tenant()) { + ret = OB_RESOURCE_POOL_ALREADY_GRANTED; + LOG_USER_ERROR(OB_RESOURCE_POOL_ALREADY_GRANTED, to_cstring(pool->name_)); + LOG_WARN("resource pool is granted to tenant, can't not delete it", + "tenant_id", pool->tenant_id_, K(ret)); + } else { + common::ObMySQLTransaction trans; + if (OB_FAIL(trans.start(proxy_, OB_SYS_TENANT_ID))) { + LOG_WARN("start transaction failed", K(ret)); + } else if (OB_FAIL(remove_resource_pool_unit_in_trans(pool->resource_pool_id_, + trans))) { + LOG_WARN("failed to remove resource pool and unit", K(ret), K(pool)); + } + if (trans.is_started()) { + const bool commit = (OB_SUCC(ret)); + int temp_ret = OB_SUCCESS; + if (OB_SUCCESS != (temp_ret = trans.end(commit))) { + LOG_WARN("trans end failed", K(commit), K(temp_ret)); + ret = (OB_SUCCESS == ret) ? temp_ret : ret; + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(delete_resource_pool_unit(pool))) { + LOG_WARN("failed to delete resource pool or unit", K(ret), K(pool)); + } + } + + return ret; +} + #undef DELETE_ITEM_FROM_MAP #define GET_ITEM_FROM_MAP(map, key, value) \ @@ -10284,6 +11035,37 @@ int ObUnitManager::get_server_ref_count(common::hash::ObHashMap return ret; } +int ObUnitManager::check_resource_pool_exist(const share::ObResourcePoolName &resource_pool_name, + bool &is_exist) +{ + int ret = OB_SUCCESS; + SpinRLockGuard guard(lock_); + share::ObResourcePool *pool = NULL; + is_exist = false; + + if (!check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat failed", KR(ret), K(inited_), K(loaded_)); + } else if (resource_pool_name.is_empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(resource_pool_name)); + } else if (OB_FAIL(inner_get_resource_pool_by_name(resource_pool_name, pool))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("inner_get_resource_pool_by_name failed", KR(ret), K(resource_pool_name)); + } else { + ret = OB_SUCCESS; + // is_exist = false + } + } else if (OB_ISNULL(pool)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), KP(pool), K(resource_pool_name)); + } else { + is_exist = true; + } + + return ret; +} + int ObUnitManager::inner_get_resource_pool_by_name( const ObResourcePoolName &name, share::ObResourcePool *&pool) const diff --git a/src/rootserver/ob_unit_manager.h b/src/rootserver/ob_unit_manager.h index 2cf7601742..05e42acafa 100644 --- a/src/rootserver/ob_unit_manager.h +++ b/src/rootserver/ob_unit_manager.h @@ -140,10 +140,17 @@ public: const bool if_not_exist); virtual int drop_unit_config(const share::ObUnitConfigName &name, const bool if_exist); virtual int alter_unit_config(const share::ObUnitConfig &unit_config); + virtual int check_unit_config_exist(const share::ObUnitConfigName &unit_config_name, + bool &is_exist); // resource pool related virtual int check_tenant_pools_in_shrinking(const uint64_t tenant_id, bool &is_shrinking); virtual int check_pool_in_shrinking(const uint64_t pool_id, bool &is_shrinking); + virtual int check_resource_pool_exist(const share::ObResourcePoolName &resource_pool_name, + bool &is_exist); + virtual int clone_resource_pool(share::ObResourcePool &resource_pool, + const share::ObUnitConfigName &unit_config_name, + const uint64_t source_tenant_id); virtual int create_resource_pool(share::ObResourcePool &resource_pool, const share::ObUnitConfigName &config_name, const bool if_not_exist); @@ -157,6 +164,9 @@ public: const share::ObResourcePool &alter_pool, const share::ObUnitConfigName &config_name, const common::ObIArray &delete_unit_id_array); + virtual int drop_resource_pool( + const uint64_t pool_id, + const bool if_exist); virtual int drop_resource_pool( const share::ObResourcePoolName &name, const bool if_exist); @@ -188,7 +198,8 @@ public: const lib::Worker::CompatMode compat_mode, const common::ObIArray &pool_names, const uint64_t tenant_id, - const bool is_bootstrap = false); + const bool is_bootstrap = false, + const uint64_t source_tenant_id = OB_INVALID_TENANT_ID); virtual int revoke_pools( common::ObMySQLTransaction &trans, common::ObIArray &new_ug_id_array, @@ -436,6 +447,8 @@ private: bool &is_enough, AlterResourceErr &err_index) const; virtual int migrate_unit_(const uint64_t unit_id, const common::ObAddr &dst, const bool is_manual = false); + int inner_get_all_unit_infos_by_tenant_(const uint64_t tenant_id, + ObIArray &unit_infos); int do_migrate_unit_notify_resource_(const share::ObResourcePool &pool, const share::ObUnit &new_unit, const bool is_manual, @@ -467,7 +480,7 @@ private: int inner_get_pool_ids_of_tenant(const uint64_t tenant_id, ObIArray &pool_ids) const; - int check_resource_pool(share::ObResourcePool &resource_pool) const; + int check_resource_pool(share::ObResourcePool &resource_pool, const bool is_clone_tenant) const; int allocate_pool_units_(common::ObISQLClient &client, const share::ObResourcePool &pool, const common::ObIArray &zones, @@ -716,12 +729,42 @@ private: int check_pool_ownership_(const uint64_t tenant_id, const common::ObIArray &pool_names, const bool grant); + + int construct_pool_units_to_grant_( + ObMySQLTransaction &trans, + const uint64_t tenant_id, + const share::ObResourcePool &new_pool, + const common::ObIArray &zone_sorted_unit_array, + const common::ObIArray &new_ug_ids, + const lib::Worker::CompatMode &compat_mode, + ObNotifyTenantServerResourceProxy ¬ify_proxy, + const uint64_t source_tenant_id, + ObIArray &pool_units); + + int construct_unit_group_id_for_unit_( + const uint64_t source_tenant_id, + const common::ObIArray &source_units, + const common::ObIArray &source_unit_group_ids, + const share::ObUnit &target_unit, + const int64_t unit_index, + const int64_t unit_num, + const common::ObIArray &new_ug_ids, + uint64_t &unit_group_id); + + // construct source unit group ids from source units + // @params[in] source_units, unit belongs to source tenant + // @params[out] source_unit_group_ids, the result + int construct_source_unit_group_ids_( + const common::ObIArray &source_units, + common::ObIArray &source_unit_group_ids); + int do_grant_pools_(common::ObMySQLTransaction &trans, const common::ObIArray &new_unit_group_id_array, const lib::Worker::CompatMode compat_mode, const common::ObIArray &pool_names, const uint64_t tenant_id, - const bool is_bootstrap); + const bool is_bootstrap, + const uint64_t source_tenant_id); int do_revoke_pools_(common::ObMySQLTransaction &trans, const common::ObIArray &new_unit_group_id_array, @@ -770,6 +813,7 @@ private: int delete_tenant_pool(const uint64_t tenant_id, share::ObResourcePool *pool); int delete_config_pool(const uint64_t config_id, share::ObResourcePool *pool); int delete_migrate_unit(const common::ObAddr &src_server, const uint64_t unit_id); + int inner_drop_resource_pool(share::ObResourcePool *pool); int get_unit_config_by_name(const share::ObUnitConfigName &name, share::ObUnitConfig *&config) const; @@ -919,7 +963,9 @@ private: int inner_create_resource_pool( share::ObResourcePool &resource_pool, const share::ObUnitConfigName &config_name, - const bool if_not_exist); + const bool if_not_exist, + const uint64_t source_tenant_id, + const common::ObIArray &source_units); int inner_try_delete_migrate_unit_resource( const uint64_t unit_id, const common::ObAddr &migrate_from_server); @@ -960,6 +1006,63 @@ private: int get_pool_unit_group_id_( const share::ObResourcePool &pool, common::ObIArray &new_unit_group_id_array); + // clone tenant resource pool related + int construct_resource_pool_to_clone_( + const uint64_t source_tenant_id, + share::ObResourcePool &pool_to_clone); + int construct_source_tenant_unit_num_( + const uint64_t source_tenant_id, + int64_t &unit_num); + int check_new_pool_units_for_clone_tenant_( + ObISQLClient &client, + const share::ObResourcePool &pool, + const common::ObIArray &source_units); + int construct_server_resources_info_( + const ObZone &zone, + const ObIArray &source_units, + ObIArray &server_infos, + ObIArray &server_resources); + int check_server_resources_and_persist_unit_info_( + ObISQLClient &client, + ObNotifyTenantServerResourceProxy ¬ify_proxy, + const ObZone &zone, + const share::ObResourcePool &pool, + const ObIArray &server_infos, + const ObIArray &server_resources, + const share::ObUnitResource &config); + + int try_persist_unit_info_( + ObNotifyTenantServerResourceProxy ¬ify_proxy, + ObISQLClient &client, + const ObZone &zone, + const share::ObResourcePool &pool, + const lib::Worker::CompatMode &compat_mode, + const uint64_t unit_group_id, + const ObAddr &server, + ObIArray &new_servers, + ObIArray &units); + int check_server_status_valid_and_construct_log_( + const share::ObServerInfoInTable &server_info, + const bool for_clone_tenant, + bool &is_server_valid, + std::string ¬_valid_reason) const; + int check_server_resource_enough_and_construct_log_( + const ObUnitPlacementStrategy::ObServerResource &server_resource, + const share::ObUnitResource &config, + bool &is_resource_enough, + std::string &resource_not_enough_reason) const; + int construct_valid_servers_resource_( + const ObZone &zone, + const share::ObUnitResource &config, + const ObIArray &excluded_servers, + const ObIArray &servers_info, + const ObIArray &server_resources, + const char* module, + const bool for_clone_tenant, + int64_t ¬_excluded_server_count, + std::string &resource_not_enough_reason, + ObIArray &valid_server_resources) const; + // arrange unit related int allocate_new_pool_units_( common::ObISQLClient &client, diff --git a/src/rootserver/ob_upgrade_executor.cpp b/src/rootserver/ob_upgrade_executor.cpp index d5126f8ddd..f37788ea76 100644 --- a/src/rootserver/ob_upgrade_executor.cpp +++ b/src/rootserver/ob_upgrade_executor.cpp @@ -14,6 +14,7 @@ #include "rootserver/ob_upgrade_executor.h" #include "rootserver/ob_ls_service_helper.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" //ObTenantSnapshotUtil #include "observer/ob_server_struct.h" #include "share/ob_global_stat_proxy.h" #include "share/ob_cluster_event_history_table_operator.h"//CLUSTER_EVENT_INSTANCE @@ -597,6 +598,7 @@ int ObUpgradeExecutor::run_upgrade_begin_action_( int ret = OB_SUCCESS; ObMySQLTransaction trans; share::SCN sys_ls_target_scn = SCN::invalid_scn(); + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::UPGRADE); if (OB_FAIL(check_inner_stat_())) { LOG_WARN("fail to check inner stat", KR(ret)); } else if (OB_FAIL(check_stop())) { @@ -632,6 +634,11 @@ int ObUpgradeExecutor::run_upgrade_begin_action_( LOG_WARN("fail to get target data version", KR(ret), K(tenant_id)); } } + // check tenant not in cloning procedure in trans + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(tenant_id, case_to_check))) { + LOG_WARN("fail to check whether tenant is in cloning produre", KR(ret), K(tenant_id)); + } // try update target_data_version if (OB_FAIL(ret)) { } else if (target_data_version >= DATA_CURRENT_VERSION) { diff --git a/src/rootserver/restore/ob_clone_scheduler.cpp b/src/rootserver/restore/ob_clone_scheduler.cpp new file mode 100644 index 0000000000..b74003934b --- /dev/null +++ b/src/rootserver/restore/ob_clone_scheduler.cpp @@ -0,0 +1,2011 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS_RESTORE + +#include "ob_clone_scheduler.h" +#include "share/ls/ob_ls_operator.h" +#include "share/ob_max_id_fetcher.h" +#include "rootserver/ob_common_ls_service.h" +#include "rootserver/restore/ob_restore_common_util.h" +#include "share/restore/ob_log_restore_source_mgr.h" +#include "share/backup/ob_archive_persist_helper.h" +#include "rootserver/restore/ob_tenant_clone_util.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "rootserver/ob_ddl_service.h" +#include "storage/tablelock/ob_lock_inner_connection_util.h" +#include "observer/ob_inner_sql_connection.h" +#ifdef OB_BUILD_TDE_SECURITY +#include "share/ob_master_key_getter.h" +#endif + +namespace oceanbase +{ +namespace rootserver +{ +using namespace common; +using namespace share; +using namespace transaction::tablelock; + +ObCloneScheduler::ObCloneScheduler() + : is_inited_(false), + schema_service_(NULL), + sql_proxy_(NULL), + rpc_proxy_(NULL), + srv_rpc_proxy_(NULL), + idle_time_us_(1), + work_immediately_(false) +{ +} + +ObCloneScheduler::~ObCloneScheduler() +{ + if (!has_set_stop()) { + stop(); + wait(); + } +} + +void ObCloneScheduler::destroy() +{ + ObTenantThreadHelper::destroy(); + is_inited_ = false; +} + +int ObCloneScheduler::init() +{ + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret)); + } else if (OB_ISNULL(GCTX.schema_service_) + || OB_ISNULL(GCTX.sql_proxy_) + || OB_ISNULL(GCTX.rs_rpc_proxy_) + || OB_ISNULL(GCTX.srv_rpc_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(GCTX.schema_service_), + KP(GCTX.sql_proxy_), KP(GCTX.rs_rpc_proxy_), KP(GCTX.srv_rpc_proxy_)); + //TODO: SimpleLSService + } else if (OB_FAIL(ObTenantThreadHelper::create("CloneSche", lib::TGDefIDs::SimpleLSService, *this))) { + LOG_WARN("failed to create thread", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::start())) { + LOG_WARN("fail to start thread", KR(ret)); + } else { + schema_service_ = GCTX.schema_service_; + sql_proxy_ = GCTX.sql_proxy_; + rpc_proxy_ = GCTX.rs_rpc_proxy_; + srv_rpc_proxy_ = GCTX.srv_rpc_proxy_; + is_inited_ = true; + } + return ret; +} + +int ObCloneScheduler::idle() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (work_immediately_) { + work_immediately_ = false; + } else { + ObTenantThreadHelper::idle(idle_time_us_); + idle_time_us_ = is_sys_tenant(tenant_id)? DEFAULT_IDLE_TIME : PROCESS_IDLE_TIME; + } + return ret; +} + +void ObCloneScheduler::wakeup() +{ + ObTenantThreadHelper::wakeup(); +} + +void ObCloneScheduler::do_work() +{ + LOG_INFO("[RESTORE] clone scheduler start"); + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else { + const uint64_t tenant_id = MTL_ID(); + idle_time_us_ = is_sys_tenant(tenant_id)? DEFAULT_IDLE_TIME : PROCESS_IDLE_TIME; + ob_setup_default_tsi_warning_buffer(); + while (!has_set_stop()) { + ObCurTraceId::init(GCTX.self_addr()); + ob_reset_tsi_warning_buffer(); + ObArray clone_jobs; + ObTenantCloneTableOperator clone_op; + if (!is_sys_tenant(tenant_id) && !is_meta_tenant(tenant_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected tenant id", KR(ret), K(tenant_id)); + } else if (is_sys_tenant(tenant_id) && OB_FAIL(check_sys_tenant_(tenant_id))) { + LOG_WARN("sys tenant can not do cloning operation", KR(ret), K(tenant_id)); + } else if (is_meta_tenant(tenant_id) && OB_FAIL(check_meta_tenant_(tenant_id))) { + LOG_WARN("meta tenant can not do cloning operation", KR(ret), K(tenant_id)); + } else if (OB_FAIL(clone_op.init(gen_user_tenant_id(tenant_id), sql_proxy_))) { + LOG_WARN("fail to init", KR(ret), K(tenant_id)); + } else if (OB_FAIL(clone_op.get_all_clone_jobs(clone_jobs))) { + LOG_WARN("fail to get clone jobs", KR(ret), K(tenant_id)); + } else { + FOREACH_CNT_X(clone_job, clone_jobs, !has_set_stop()) { // ignore ret + if (OB_ISNULL(clone_job)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("clone job is null", KR(ret)); + } else if (!clone_job->is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("clone job is not valid", KR(ret), KPC(clone_job)); + } else if (is_sys_tenant(tenant_id)) { + if (OB_FAIL(process_sys_clone_job(*clone_job))) { + LOG_WARN("fail to process sys clone job", KR(ret), KPC(clone_job)); + } + } else if (OB_FAIL(process_user_clone_job(*clone_job))) { + LOG_WARN("fail to process user clone job", KR(ret), KPC(clone_job)); + } + idle_time_us_ = PROCESS_IDLE_TIME; + } + } + ret = OB_SUCCESS; + idle(); + } + } + LOG_INFO("[RESTORE] clone scheduler quit"); +} + +int ObCloneScheduler::process_sys_clone_job(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (OB_UNLIKELY(!is_sys_tenant(tenant_id) + || tenant_id != job.get_tenant_id())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tenant id", KR(ret), K(tenant_id), K(job)); + } else { + ObTraceIdGuard trace_guard(job.get_trace_id()); + switch (job.get_status()) { + case ObTenantCloneStatus::Status::CLONE_SYS_LOCK: + ret = clone_lock(job); + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL: + ret = clone_create_resource_pool(job); + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT: + ret = clone_create_snapshot_for_fork_tenant(job); + break; + case ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT: + ret = clone_wait_create_snapshot_for_fork_tenant(job); + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT: + ret = clone_create_tenant(job); + break; + case ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH: + ret = clone_wait_tenant_restore_finish(job); + break; + case ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE: + ret = clone_release_resource(job); + break; + case ObTenantCloneStatus::Status::CLONE_SYS_SUCCESS: + ret = clone_sys_finish(job); + break; + case ObTenantCloneStatus::Status::CLONE_SYS_LOCK_FAIL: + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL_FAIL: + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT_FAIL: + case ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT_FAIL: + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT_FAIL: + case ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH_FAIL: + case ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE_FAIL: + case ObTenantCloneStatus::Status::CLONE_SYS_CANCELED: + ret = clone_recycle_failed_job(job); + break; + default: + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected status", KR(ret), K(job)); + break; + } + } + return ret; +} + +int ObCloneScheduler::process_user_clone_job(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (OB_UNLIKELY(!is_meta_tenant(tenant_id) + || gen_user_tenant_id(tenant_id) != job.get_tenant_id())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tenant id", KR(ret), K(tenant_id), K(job)); + } else { + ObTraceIdGuard trace_guard(job.get_trace_id()); + switch (job.get_status()) { + case ObTenantCloneStatus::Status::CLONE_USER_PREPARE: + ret = clone_prepare(job); + break; + case ObTenantCloneStatus::Status::CLONE_USER_CREATE_INIT_LS: + ret = clone_init_ls(job); + break; + case ObTenantCloneStatus::Status::CLONE_USER_WAIT_LS: + ret = clone_wait_ls_finish(job); + break; + case ObTenantCloneStatus::Status::CLONE_USER_POST_CHECK: + ret = clone_post_check(job); + break; + case ObTenantCloneStatus::Status::CLONE_USER_SUCCESS: + ret = clone_user_finish(job); + break; + case ObTenantCloneStatus::Status::CLONE_USER_FAIL: + ret = clone_user_finish(job); + break; + default: + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected status", KR(ret), K(job)); + break; + } + } + return ret; +} + +int ObCloneScheduler::clone_lock(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const int64_t job_id = job.get_job_id(); + const ObTenantSnapshotID &snapshot_id = job.get_tenant_snapshot_id(); + ObTenantCloneJobType job_type = job.get_job_type(); + int32_t loop_cnt = 0; + const ObTenantSnapshotUtil::TenantSnapshotOp op = ObTenantCloneJobType::RESTORE == job_type ? + ObTenantSnapshotUtil::RESTORE_OP : + ObTenantSnapshotUtil::FORK_OP; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (!is_sys_tenant(tenant_id) || !is_user_tenant(source_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(source_tenant_id), K(snapshot_id)); + } else if (!snapshot_id.is_valid() && ObTenantCloneJobType::RESTORE == job_type) { + // if the job_type is FORK, the according snapshot has not been created; + // if the job_type is RESTORE, the according snapshot must already be created + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(source_tenant_id), K(snapshot_id)); + } else if (ObTenantCloneJobType::RESTORE != job_type && ObTenantCloneJobType::FORK != job_type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_type)); + } else { + while (OB_SUCC(ret)) { + ObMySQLTransaction trans; + ObTenantSnapStatus original_global_state_status = ObTenantSnapStatus::MAX; + bool need_wait = false; + if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(source_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(ObTenantSnapshotUtil::trylock_tenant_snapshot_simulated_mutex(trans, + source_tenant_id, op, job_id, + original_global_state_status))) { + if (OB_TENANT_SNAPSHOT_LOCK_CONFLICT != ret) { + LOG_WARN("trylock tenant snapshot simulated mutex failed", KR(ret), K(source_tenant_id)); + } else { + if (ObTenantSnapStatus::CREATING == original_global_state_status) { + ret = OB_SUCCESS; + need_wait = true; + LOG_INFO("need wait for current tenant restore operation", KR(ret), K(source_tenant_id)); + } else { + LOG_WARN("GLOBAL_STATE snapshot lock conflict", KR(ret), K(source_tenant_id), + K(original_global_state_status)); + } + } + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_has_no_conflict_tasks(source_tenant_id))) { + LOG_WARN("fail to check tenant has conflict tasks", KR(ret), K(source_tenant_id)); + } else if (ObTenantCloneJobType::RESTORE == job_type && + OB_FAIL(ObTenantSnapshotUtil::add_restore_tenant_task(trans, source_tenant_id, + snapshot_id))) { + // if job_type is FORK, the snapshot will be updated as RESTORE when it is created successful + LOG_WARN("failed to add restore tenant snapshot task", KR(ret), K(source_tenant_id), K(snapshot_id)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", (OB_SUCCESS == ret), KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + if (OB_SUCC(ret)) { + if (need_wait) { + if ((++loop_cnt) >= MAX_RETRY_CNT) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("not allow to lock", KR(ret), K(job)); + } else { + ob_usleep(2 * 1000 * 1000L); + } + } else { + break; + } + } + } + } + + // if (FAILEDx(wait_source_relative_task_finished_(source_tenant_id))) { + // LOG_WARN("wait source relative task finished failed", KR(ret), KR(source_tenant_id)); + // } + + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + LOG_INFO("[RESTORE] clone lock", KR(ret), K(job)); + return ret; +} + +int ObCloneScheduler::clone_create_resource_pool(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + obrpc::ObCloneResourcePoolArg arg; + int64_t timeout = GCONF._ob_ddl_timeout; + uint64_t resource_pool_id = job.get_resource_pool_id(); + const int64_t job_id = job.get_job_id(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_ISNULL(GCTX.rs_mgr_) || OB_ISNULL(rpc_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job), KP(rpc_proxy_)); + } else if (OB_INVALID_ID == resource_pool_id) { + ObMaxIdFetcher id_fetcher(*sql_proxy_); + if (OB_FAIL(id_fetcher.fetch_new_max_id(OB_SYS_TENANT_ID, + ObMaxIdType::OB_MAX_USED_RESOURCE_POOL_ID_TYPE, + resource_pool_id))) { + LOG_WARN("fetch resource pool id failed", KR(ret), K(job)); + } else if (OB_INVALID_ID == resource_pool_id) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid resource pool id", KR(ret), K(job)); + } else if (OB_FAIL(ObTenantCloneUtil::update_resource_pool_id_of_clone_job(*sql_proxy_, + job_id, + resource_pool_id))) { + LOG_WARN("fail to update resource pool id of clone job", KR(ret), K(job), K(arg)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(fill_clone_resource_pool_arg_(job, resource_pool_id, arg))) { + LOG_WARN("fail to fill clone resource pool arg", KR(ret), K(job), K(arg)); + } else if (OB_FAIL(rpc_proxy_->to_rs(*GCTX.rs_mgr_).timeout(timeout).clone_resource_pool(arg))) { + LOG_WARN("fail to clone resource pool", KR(ret), K(arg), K(timeout)); + } + + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + LOG_INFO("[RESTORE] clone create resource pool", KR(ret), K(arg), K(job)); + return ret; +} + +int ObCloneScheduler::clone_create_snapshot_for_fork_tenant(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + const uint64_t tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const ObString &source_tenant_name = job.get_source_tenant_name(); + const ObTenantCloneJobType type = job.get_job_type(); + const int64_t job_id = job.get_job_id(); + ObTenantSnapItem item; + ObMySQLTransaction trans; + ObSqlString snapshot_name; + ObTenantSnapshotID tenant_snapshot_id; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (!is_sys_tenant(tenant_id) || !is_user_tenant(source_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_UNLIKELY(source_tenant_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("empty source tenant name", KR(ret), K(job)); + } else if (ObTenantCloneJobType::FORK != type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid job type", KR(ret), K(job)); + } else if (!job.get_tenant_snapshot_id().is_valid()) { + if (OB_FAIL(rootserver::ObTenantSnapshotUtil::generate_tenant_snapshot_name( + source_tenant_id, snapshot_name, true))) { + LOG_WARN("failed to generate new tenant snapshot name", KR(ret), K(source_tenant_id)); + } else if (snapshot_name.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid job", KR(ret), K(job)); + } else if (OB_FAIL(rootserver::ObTenantSnapshotUtil::generate_tenant_snapshot_id( + source_tenant_id, tenant_snapshot_id))) { + LOG_WARN("failed to generate snapshot id", KR(ret), K(source_tenant_id)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid job", KR(ret), K(job)); + } else if (OB_FAIL(ObTenantCloneUtil::update_snapshot_info_for_fork_job(*sql_proxy_, + job_id, + tenant_snapshot_id, + snapshot_name.string()))) { + LOG_WARN("fail to update snapshot info", KR(ret), K(job), K(tenant_snapshot_id), K(snapshot_name)); + } + } else { // job.tenant_snapshot_id_.is_valid() == true + if (job.get_tenant_snapshot_name().empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid job", KR(ret), K(job)); + } else if (OB_FAIL(snapshot_name.assign(job.get_tenant_snapshot_name()))) { + LOG_WARN("fail to assign", KR(ret), K(job)); + } else { + tenant_snapshot_id = job.get_tenant_snapshot_id(); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(source_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(rootserver::ObTenantSnapshotUtil::get_tenant_snapshot_info(trans, + source_tenant_id, + tenant_snapshot_id, + item))) { + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + ret = OB_SUCCESS; + if (OB_FAIL(rootserver::ObTenantSnapshotUtil::create_fork_tenant_snapshot(trans, + source_tenant_id, + source_tenant_name, + snapshot_name.string(), + tenant_snapshot_id))) { + LOG_WARN("create tenant snapshot failed", KR(ret), K(job), K(tenant_snapshot_id), K(snapshot_name)); + } + } else { + LOG_WARN("get tenant snapshot failed", KR(ret), K(source_tenant_id), K(snapshot_name)); + } + } else { + // do nothing, tenant snapshot has been created + } + + if (trans.is_started()) { + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", (OB_SUCCESS == ret), K(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + LOG_INFO("[RESTORE] create fork tenant snapshot", KR(ret), K(job)); + return ret; +} + +int ObCloneScheduler::clone_wait_create_snapshot_for_fork_tenant(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const ObTenantCloneJobType type = job.get_job_type(); + const ObTenantSnapshotID tenant_snapshot_id = job.get_tenant_snapshot_id(); + const int64_t job_id = job.get_job_id(); + ObTenantSnapItem item; + ObMySQLTransaction trans; + bool need_wait = false; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (!is_sys_tenant(tenant_id) + || !is_user_tenant(source_tenant_id) + || !tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(source_tenant_id), K(tenant_snapshot_id)); + } else if (ObTenantCloneJobType::FORK != type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(source_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(rootserver::ObTenantSnapshotUtil::get_tenant_snapshot_info(*sql_proxy_, + source_tenant_id, + tenant_snapshot_id, + item))) { + LOG_WARN("get tenant snapshot failed", KR(ret), K(source_tenant_id), K(tenant_snapshot_id)); + } else if (ObTenantSnapStatus::CREATING == item.get_status() || + ObTenantSnapStatus::DECIDED == item.get_status()) { + need_wait = true; + } else if (ObTenantSnapStatus::RESTORING == item.get_status()) { + // no need to update snapshot status + } else if (ObTenantSnapStatus::NORMAL != item.get_status()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid status for fork tenant snapshot", KR(ret), K(source_tenant_id), + K(tenant_snapshot_id), K(item)); + } else if (OB_FAIL(rootserver::ObTenantSnapshotUtil::add_restore_tenant_task(trans, item))) { + LOG_WARN("fail to update fork tenant snapshot to restoring", KR(ret), K(item)); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", (OB_SUCCESS == ret), K(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + if (!need_wait) { + const bool need_update_clone_job_scn = !job.get_restore_scn().is_valid(); + if (OB_FAIL(ret)) { + } else if (need_update_clone_job_scn && + OB_FAIL(ObTenantCloneUtil::update_restore_scn_for_fork_job(*sql_proxy_, + job_id, + item.get_snapshot_scn()))) { + LOG_WARN("fail to update snapshot scn", KR(ret), K(job), K(item)); + } + + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + } + + LOG_INFO("[RESTORE] wait create fork tenant snapshot", KR(ret), K(need_wait), K(job)); + return ret; +} + +int ObCloneScheduler::clone_create_tenant(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + obrpc::ObCreateTenantArg arg; + uint64_t clone_tenant_id = job.get_clone_tenant_id(); + const uint64_t tenant_id = job.get_tenant_id(); + const int64_t job_id = job.get_job_id(); + obrpc::UInt64 unused_res; + const int64_t timeout = GCONF._ob_ddl_timeout; + ObTenantCloneTableOperator clone_op; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_INVALID_TENANT_ID == clone_tenant_id) { + ObMaxIdFetcher id_fetcher(*sql_proxy_); + uint64_t max_id = OB_INVALID_ID; + if (OB_FAIL(id_fetcher.fetch_new_max_id(OB_SYS_TENANT_ID, OB_MAX_USED_TENANT_ID_TYPE, max_id))) { + LOG_WARN("get new schema id failed", KR(ret)); + } else if (OB_INVALID_ID == max_id || OB_INVALID_TENANT_ID == max_id) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid id", KR(ret), K(max_id), K(job)); + } else if (OB_FAIL(clone_op.init(tenant_id, sql_proxy_))) { + LOG_WARN("fail to init", KR(ret), K(tenant_id)); + } else if (OB_FAIL(clone_op.update_job_clone_tenant_id(job_id, max_id))) { + LOG_WARN("fail to update clone tenant id", KR(ret), K(max_id), K(job)); + } else { + clone_tenant_id = max_id; + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(fill_create_tenant_arg_(job, clone_tenant_id, arg))) { + LOG_WARN("fail to fill create tenant arg", KR(ret), K(job)); + } else if (OB_FAIL(rpc_proxy_->timeout(timeout).create_tenant(arg, unused_res))) { + LOG_WARN("fail to create tenant", KR(ret), K(arg)); + } + + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + LOG_INFO("[RESTORE] clone create tenant", KR(ret), K(arg), K(job)); + return ret; +} + +int ObCloneScheduler::clone_wait_tenant_restore_finish(const ObCloneJob &job) +{ + int ret = OB_SUCCESS; + ObTenantCloneTableOperator clone_op; + ObCloneJob user_job_history; + const uint64_t clone_tenant_id = job.get_clone_tenant_id(); + bool need_wait = false; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_FAIL(clone_op.init(clone_tenant_id, sql_proxy_))) { + LOG_WARN("fail to init clone op", KR(ret), K(clone_tenant_id)); + } else if (OB_FAIL(clone_op.get_user_clone_job_history(user_job_history))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to get clone job history", KR(ret), K(clone_tenant_id)); + } else { + need_wait = true; + LOG_INFO("need wait user tenant restore finish", KR(ret), K(clone_tenant_id)); + } + } else if (user_job_history.get_status().is_user_success_status()) { + ObTenantSchema tenant_schema; + if (OB_FAIL(ObTenantThreadHelper::get_tenant_schema(clone_tenant_id, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(clone_tenant_id)); + } else if (tenant_schema.is_restore_tenant_status() || tenant_schema.is_normal()) { + if (tenant_schema.is_restore_tenant_status()) { + const int64_t timeout = GCONF.internal_sql_execute_timeout; + // try finish restore status + obrpc::ObCreateTenantEndArg arg; + arg.tenant_id_ = clone_tenant_id; + arg.exec_tenant_id_ = OB_SYS_TENANT_ID; + if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_FAIL(rpc_proxy_->timeout(timeout).create_tenant_end(arg))) { + need_wait = true; + LOG_WARN("fail to create tenant end", KR(ret), K(arg), K(timeout)); + } + } + } else { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("tenant status not match", KR(ret), K(tenant_schema)); + } + } else { + int user_ret_code = user_job_history.get_ret_code(); + ret = OB_SUCCESS == user_ret_code ? OB_ERR_CLONE_TENANT : user_ret_code; + LOG_WARN("user_job_history status is not SUCCESS", KR(ret), K(user_job_history)); + } + + if (!need_wait) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + LOG_INFO("[RESTORE] clone wait tenant restore finish", KR(ret), K(job)); + } + return ret; +} + +int ObCloneScheduler::clone_release_resource(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const ObTenantSnapshotID snapshot_id = job.get_tenant_snapshot_id(); + const ObTenantCloneJobType job_type = job.get_job_type(); + int tmp_ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (!is_sys_tenant(tenant_id) + || !is_user_tenant(source_tenant_id) + || !snapshot_id.is_valid() + || OB_ISNULL(sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(source_tenant_id), K(snapshot_id), KP(sql_proxy_)); + } else if (ObTenantCloneJobType::RESTORE != job_type && ObTenantCloneJobType::FORK != job_type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_FAIL(ObTenantCloneUtil::release_source_tenant_resource_of_clone_job(*sql_proxy_, job))) { + LOG_WARN("failed to release source tenant resource", KR(ret), K(job)); + } + + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + LOG_INFO("[RESTORE] clone_release_resource", KR(ret), K(job)); + return ret; +} + +int ObCloneScheduler::clone_sys_finish(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + bool clone_tenant_exist = true; + const uint64_t tenant_id = job.get_tenant_id(); //sys tenant id + const uint64_t clone_tenant_id = job.get_clone_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const ObTenantSnapshotID &snapshot_id = job.get_tenant_snapshot_id(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_FAIL(ObRestoreCommonUtil::check_tenant_is_existed(schema_service_, + clone_tenant_id, clone_tenant_exist))) { + LOG_WARN("fail to check whether tenant is existed", KR(ret), K(clone_tenant_id), K(job)); + } else if (!clone_tenant_exist) { + LOG_WARN("clone tenant is not exist", KR(ret), K(clone_tenant_id)); + } + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); + } else if (OB_FAIL(ObTenantCloneUtil::recycle_clone_job(*sql_proxy_, job))) { + LOG_WARN("recycle clone job failed", KR(ret), K(job)); + } + + LOG_INFO("[RESTORE] clone sys finish", KR(ret), K(job)); + const char *status_str = ObTenantCloneStatus::get_clone_status_str(job.get_status()); + ROOTSERVICE_EVENT_ADD("clone", "clone_sys_finish", + "job_id", job.get_job_id(), + K(ret), + "cur_clone_status", status_str); + return ret; +} + +int ObCloneScheduler::clone_prepare(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t user_tenant_id = job.get_tenant_id(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_FAIL(clone_root_key_(job))) { + LOG_WARN("fail to clone root key", KR(ret), K(job)); + } else if (OB_FAIL(clone_keystore_(job))) { + LOG_WARN("fail to clone keystore", KR(ret), K(job)); + } else { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + } + LOG_INFO("[RESTORE] clone prepare", KR(ret), K(job)); + return ret; +} + +//Note: the role of cloning tenant is CLONING_TENANT, +// and the status of cloning tenant is TENANT_STATUS_RESTORE. +int ObCloneScheduler::clone_init_ls(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + const uint64_t user_tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + schema::ObTenantSchema tenant_schema; + ObAllTenantInfo all_tenant_info; + ObSArray ls_attr_array; + bool need_wait = false; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); + } else if (OB_FAIL(ObTenantThreadHelper::get_tenant_schema(user_tenant_id, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(user_tenant_id)); + } else if (!tenant_schema.is_restore_tenant_status()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant is not in restore status", KR(ret), K(tenant_schema)); + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(user_tenant_id, sql_proxy_, + false/*for_update*/, all_tenant_info))) { + LOG_WARN("failed to load tenant info", KR(ret), K(user_tenant_id)); + } else if (!all_tenant_info.is_clone()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant is not in clone role", KR(ret), K(all_tenant_info)); + } else if (OB_FAIL(get_ls_attrs_from_source_(job, ls_attr_array))) { + LOG_WARN("fail to get ls attrs from source", KR(ret), K(job)); + } else { + const SCN &sync_scn = job.get_restore_scn(); + ObLSRecoveryStatOperator ls_recovery; + const uint64_t exec_tenant_id = get_private_table_exec_tenant_id(user_tenant_id); + START_TRANSACTION(sql_proxy_, exec_tenant_id) + LOG_INFO("start to create ls and set sync scn", K(sync_scn), K(ls_attr_array), K(source_tenant_id)); + if (OB_FAIL(ls_recovery.update_sys_ls_sync_scn(user_tenant_id, trans, sync_scn))) { + LOG_WARN("failed to update sync ls sync scn", KR(ret), K(sync_scn)); + } + END_TRANSACTION(trans) + } + + if (OB_SUCC(ret)) { + share::ObBackupPathString log_path; + ObLogRestoreSourceMgr restore_source_mgr; + + if (OB_FAIL(create_all_ls_(user_tenant_id, tenant_schema, ls_attr_array, source_tenant_id))) { + LOG_WARN("failed to create all ls", KR(ret), K(user_tenant_id), K(tenant_schema), + K(ls_attr_array), K(source_tenant_id)); + } else if (OB_FAIL(wait_all_ls_created_(tenant_schema, job))) { + LOG_WARN("failed to wait all ls created", KR(ret), K(tenant_schema), K(job)); + } else if (OB_FAIL(finish_create_ls_(tenant_schema, ls_attr_array))) { + LOG_WARN("failed to finish create ls", KR(ret), K(tenant_schema), K(ls_attr_array)); + } else if (OB_FAIL(get_source_tenant_archive_log_path_(source_tenant_id, log_path))) { + LOG_WARN("failed to get source tenant archive log path", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(restore_source_mgr.init(user_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init restore_source_mgr", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(restore_source_mgr.add_location_source(job.get_restore_scn(), log_path.str()))) { + LOG_WARN("failed to add log restore source", KR(ret), K(job), K(log_path)); + } + } + if (OB_FAIL(ret)) { + need_wait = true; + } + + if (!need_wait) { + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + } + + LOG_INFO("[RESTORE] clone init ls", KR(ret), KR(tmp_ret), K(job), K(need_wait)); + return ret; +} + +int ObCloneScheduler::get_tenant_snap_ls_replica_simple_items_( + const share::ObCloneJob &job, + ObArray& ls_snapshot_array) +{ + int ret = OB_SUCCESS; + ls_snapshot_array.reset(); + + ObTenantSnapshotTableOperator snap_op; + if (!is_user_tenant(job.get_source_tenant_id()) || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("source tenant is not user_tenant or sql proxy is null", + KR(ret), K(job.get_source_tenant_id()), KP(sql_proxy_)); + } else { + MTL_SWITCH(OB_SYS_TENANT_ID) { + if (OB_FAIL(snap_op.init(job.get_source_tenant_id(), sql_proxy_))) { + LOG_WARN("fail to init snap op", KR(ret), K(job)); + } else if (OB_FAIL(snap_op.get_tenant_snap_ls_replica_simple_items( + job.get_tenant_snapshot_id(), + ls_snapshot_array))) { + LOG_WARN("fail to get_tenant_snap_ls_replica_simple_items", KR(ret), K(job)); + } + } + } + return ret; +} + +int ObCloneScheduler::check_one_ls_replica_restore_finish_( + const share::ObCloneJob& job, + const ObLSInfo& ls_info, + const ObLSStatusInfoArray& ls_array, + const ObArray& ls_snapshot_array, + TenantRestoreStatus &tenant_restore_status) /*a valid value in the outer func, do not reset it*/ +{ + int ret = OB_SUCCESS; + + bool found_in_ls_status = false; + for (int64_t i = 0; i < ls_array.count(); ++i) { + if (ls_array.at(i).get_ls_id() == ls_info.get_ls_id()) { + found_in_ls_status = true; + break; + } + } + + if (!found_in_ls_status) { + LOG_INFO("ls in __all_ls_meta_table does not appear in __all_ls_status", K(ls_info), K(ls_array)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && !tenant_restore_status.is_failed() && i < ls_info.get_replicas().count(); ++i) { + const ObLSReplica &replica = ls_info.get_replicas().at(i); + + bool found_in_ls_snapshot = false; + share::ObLSRestoreStatus ls_restore_status; + for (int64_t j = 0; OB_SUCC(ret) && j < ls_snapshot_array.count(); ++j) { + if (replica.get_server() == ls_snapshot_array.at(j).get_addr()) { + if (ls_snapshot_array.at(j).get_status() != ObLSSnapStatus::NORMAL) { + LOG_INFO("ls in __all_ls_meta_table does not be normal status in ls snapshot table", + K(replica), K(ls_snapshot_array.at(j))); + } else { + if (OB_FAIL(ls_restore_status.set_status(replica.get_restore_status()))) { + LOG_WARN("fail to set ls restore status", KR(ret), K(replica)); + } + found_in_ls_snapshot = true; + } + break; + } + } + + if (OB_FAIL(ret)) { + } else if (!found_in_ls_snapshot) { + LOG_INFO("ls in __all_ls_meta_table does not be found in ls snapshot table or not be normal status", + K(replica), K(ls_snapshot_array)); + } else if (!ls_restore_status.is_in_clone_or_none() || ls_restore_status.is_failed()) { + tenant_restore_status = TenantRestoreStatus::FAILED; + ROOTSERVICE_EVENT_ADD("clone", "clone_ls_replica_failed", + "job_id", job.get_job_id(), + "ls_restore_status", share::ObLSRestoreStatus::get_restore_status_str(ls_restore_status), + "ls_id", replica.get_ls_id().id(), + "server", replica.get_server()); + LOG_WARN("ls is restore failed or unexpected status", + K(replica), K(ls_restore_status), K(tenant_restore_status)); + } else if (!ls_restore_status.is_none() && tenant_restore_status.is_success()) { + tenant_restore_status = TenantRestoreStatus::IN_PROGRESS; + } + } + } + return ret; +} + +int ObCloneScheduler::check_all_ls_restore_finish_(const share::ObCloneJob &job, + TenantRestoreStatus &tenant_restore_status) +{ + int ret = OB_SUCCESS; + const uint64_t user_tenant_id = job.get_tenant_id(); + + ObArray ls_info_array; + ObLSStatusInfoArray ls_array; + ObArray ls_snapshot_array; + + ObLSStatusOperator status_op; + tenant_restore_status = TenantRestoreStatus::SUCCESS; + if (!is_user_tenant(user_tenant_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the target tenant of clone job is not user tenant", KR(ret), K(job)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql_proxy_ is unexpected nullptr", KR(ret), K(job)); + } else if (OB_ISNULL(GCTX.lst_operator_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("GCTX.lst_operator_ is unexpected nullptr", KR(ret), K(job)); + } else if (OB_FAIL(GCTX.lst_operator_->get_by_tenant(user_tenant_id, false, ls_info_array))) { + LOG_WARN("fail to execute get_by_tenant", KR(ret), K(job)); + } else if (OB_FAIL(status_op.get_all_ls_status_by_order(user_tenant_id, ls_array, *sql_proxy_))) { + LOG_WARN("failed to get all ls status", KR(ret), K(job)); + } else if (OB_FAIL(get_tenant_snap_ls_replica_simple_items_(job, ls_snapshot_array))) { + LOG_WARN("fail to get_tenant_snap_ls_replica_simple_items_", KR(ret), K(job)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && !tenant_restore_status.is_failed() && i < ls_info_array.count(); ++i) { + const ObLSInfo& ls_info = ls_info_array.at(i); + if (OB_FAIL(check_one_ls_replica_restore_finish_(job, + ls_info, + ls_array, + ls_snapshot_array, + tenant_restore_status))) { + LOG_WARN("fail to check_one_ls_replica_restore_finish_", + KR(ret), K(ls_info), K(ls_array), K(ls_snapshot_array), K(tenant_restore_status), K(job)); + } + } + if (!tenant_restore_status.is_success()) { + LOG_INFO("check all ls restore not finish, just wait", + KR(ret), K(tenant_restore_status), K(job)); + } + } + + return ret; +} + +int ObCloneScheduler::clone_wait_ls_finish(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t user_tenant_id = job.get_tenant_id(); + TenantRestoreStatus tenant_restore_status; + ObTenantSchema tenant_schema; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (!is_user_tenant(user_tenant_id) || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not user tenant or sql proxy is null", KR(ret), K(user_tenant_id), KP(sql_proxy_)); + } else if (OB_FAIL(ObTenantThreadHelper::get_tenant_schema(user_tenant_id, tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(user_tenant_id)); + } else if (!tenant_schema.is_restore_tenant_status()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant is not in restore status", KR(ret), K(tenant_schema)); + } else if (OB_FAIL(check_all_ls_restore_finish_(job, tenant_restore_status))) { + LOG_WARN("failed to check all ls restore finish", KR(ret), K(job)); + } else if (tenant_restore_status.is_finish()) { + int tmp_ret = OB_SUCCESS; + int tenant_restore_result = OB_LS_RESTORE_FAILED; + if (tenant_restore_status.is_success()) { + tenant_restore_result = OB_SUCCESS; + } + if (OB_TMP_FAIL(try_update_job_status_(tenant_restore_result, job))) { + LOG_WARN("fail to update job status", KR(tmp_ret), KR(tenant_restore_result), K(job)); + } + LOG_INFO("[RESTORE] clone wait all ls finish", KR(ret), KR(tenant_restore_result), K(job)); + } + return ret; +} + +int ObCloneScheduler::clone_post_check(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t user_tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + bool sync_satisfied = true; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (!is_user_tenant(user_tenant_id) || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not user tenant or sql proxy is null", KR(ret), K(user_tenant_id), KP(sql_proxy_)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_FAIL(ObRestoreCommonUtil::try_update_tenant_role(sql_proxy_, user_tenant_id, + job.get_restore_scn(), true /*is_clone*/, sync_satisfied))) { + LOG_WARN("failed to try update tenant role", KR(ret), K(user_tenant_id), K(job)); + } else if (!sync_satisfied) { + ret = OB_NEED_WAIT; + LOG_WARN("tenant sync scn not equal to restore scn, need wait", KR(ret), K(job)); + } + + if (FAILEDx(ObRestoreCommonUtil::process_schema(sql_proxy_, user_tenant_id))) { + LOG_WARN("failed to process schema", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(convert_parameters_(user_tenant_id, source_tenant_id))) { + LOG_WARN("failed to convert parameters", KR(ret), K(user_tenant_id), K(source_tenant_id)); + } + + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_update_job_status_(ret, job))) { + LOG_WARN("fail to update job status", KR(ret), KR(tmp_ret), K(job)); + } + } + LOG_INFO("[RESTORE] clone post check", KR(ret), K(job)); + return ret; +} + +int ObCloneScheduler::clone_user_finish(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + uint64_t user_tenant_id = job.get_tenant_id(); + bool sync_satisfied = true; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_UNLIKELY(!is_user_tenant(user_tenant_id) + || OB_ISNULL(sql_proxy_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not user tenant or sql proxy is null", KR(ret), K(user_tenant_id), KP(sql_proxy_)); + } else if (OB_FAIL(ObTenantCloneUtil::recycle_clone_job(*sql_proxy_, job))) { + LOG_WARN("fail to recycle clone job", KR(ret), K(user_tenant_id)); + } + + LOG_INFO("[RESTORE] clone user finish", KR(ret), K(job)); + const char *status_str = ObTenantCloneStatus::get_clone_status_str(job.get_status()); + ROOTSERVICE_EVENT_ADD("clone", "clone_user_finish", + "job_id", job.get_job_id(), + K(ret), + "cur_clone_status", status_str); + return ret; +} + +// 1. for clone_tenant, gc the resource of resource_pool and clone_tenant +// 2. for source_tenant, release global_lock and tenant snapshot +// 3. for sys_tenant, finish the clone job +int ObCloneScheduler::clone_recycle_failed_job(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const ObTenantCloneStatus job_status = job.get_status(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (!is_sys_tenant(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_UNLIKELY(!job.is_valid()) + || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid clone job", KR(ret), K(job), KP(sql_proxy_)); + } else if (!job_status.is_sys_failed_status()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("try to recycle a processing or successful job", KR(ret), K(job)); + } else if (ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE_FAIL != job_status && + OB_FAIL(ObTenantCloneUtil::release_clone_tenant_resource_of_clone_job(job))) { + // CLONE_SYS_RELEASE_RESOURCE means the clone_tenant has been created and restored successful. + // thus, if the clone_job is failed in this status, we just need to release the according snapshot. + LOG_WARN("fail to release resource of clone tenant", KR(ret), K(job)); + } else if (OB_FAIL(ObTenantCloneUtil::release_source_tenant_resource_of_clone_job(*sql_proxy_, job))) { + LOG_WARN("fail to release resource of source tenant", KR(ret), K(job)); + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(ObTenantCloneUtil::recycle_clone_job(*sql_proxy_, job))) { + LOG_WARN("fail to recycle clone job", KR(ret), K(job)); + } + const char *status_str = ObTenantCloneStatus::get_clone_status_str(job.get_status()); + ROOTSERVICE_EVENT_ADD("clone", "clone_recycle_failed_job_finish", + "job_id", job.get_job_id(), + K(ret), + "cur_clone_status", status_str); + } + return ret; +} + +int ObCloneScheduler::try_update_job_status_( + const int return_ret, + const ObCloneJob &job) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObTenantCloneTableOperator clone_op; + const uint64_t tenant_id = job.get_tenant_id(); + const ObTenantCloneStatus cur_status = job.get_status(); + ObTenantCloneStatus next_status; + ObMySQLTransaction trans; + ObString err_msg; + ObArenaAllocator str_alloc; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_FAIL(deep_copy_ob_string(str_alloc, common::ob_get_tsi_err_msg(return_ret), err_msg))) { + LOG_WARN("fail to deep copy", KR(ret)); + } else if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(tenant_id)))) { + LOG_WARN("failed to start trans in meta tenant", KR(ret), K(gen_meta_tenant_id(tenant_id))); + } else if (OB_FAIL(clone_op.init(gen_user_tenant_id(tenant_id), &trans))) { + LOG_WARN("fail to init clone_op", KR(ret), K(tenant_id)); + } else { + if (is_sys_tenant(tenant_id)) { + next_status = get_sys_next_status_(return_ret, cur_status, job.get_job_type()); + } else { + next_status = get_user_next_status_(return_ret, cur_status); + } + if (!next_status.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected status", KR(ret), K(next_status)); + } else if (OB_FAIL(clone_op.update_job_status(job.get_job_id(), job.get_status(), next_status))) { + LOG_WARN("fail to update job status", KR(ret), K(job), K(next_status)); + } else if (OB_UNLIKELY(OB_SUCCESS != return_ret)) { + if (OB_FAIL(clone_op.update_job_failed_info(job.get_job_id(), return_ret, err_msg))) { + LOG_WARN("fail to update job failed info", KR(ret), K(job), K(return_ret), K(err_msg)); + } + } + } + + if (trans.is_started()) { + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", (OB_SUCCESS == ret), KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + if (OB_SUCC(ret)) { + work_immediately_ = true; + LOG_INFO("[RESTORE] switch job status", KR(ret), K(job), K(next_status)); + (void)record_rs_event_(job, cur_status, next_status, return_ret); + } + return ret; +} + +ObTenantCloneStatus ObCloneScheduler::get_sys_next_status_(int return_ret, + const share::ObTenantCloneStatus current_status, + const share::ObTenantCloneJobType job_type) +{ + ObTenantCloneStatus next_status = OB_SUCCESS == return_ret ? + get_sys_next_status_in_normal_(current_status, job_type) : + get_sys_next_status_in_failed_(current_status); + + return next_status; +} + +share::ObTenantCloneStatus ObCloneScheduler::get_sys_next_status_in_normal_(const share::ObTenantCloneStatus current_status, + const share::ObTenantCloneJobType job_type) +{ + ObTenantCloneStatus next_status; + + switch (current_status) { + case ObTenantCloneStatus::Status::CLONE_SYS_LOCK: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL: + next_status = share::ObTenantCloneJobType::RESTORE == job_type ? + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT : + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_SUCCESS; + break; + default : + //do nothing + break; + } + return next_status; +} + +share::ObTenantCloneStatus ObCloneScheduler::get_sys_next_status_in_failed_(const share::ObTenantCloneStatus current_status) +{ + ObTenantCloneStatus next_status; + + switch (current_status) { + case ObTenantCloneStatus::Status::CLONE_SYS_LOCK: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_LOCK_FAIL; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL_FAIL; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT_FAIL; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT_FAIL; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT_FAIL; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH_FAIL; + break; + case ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE: + next_status = ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE_FAIL; + break; + default : + //do nothing + break; + } + return next_status; +} + +ObTenantCloneStatus ObCloneScheduler::get_user_next_status_( + const int return_ret, + const ObTenantCloneStatus current_status) +{ + ObTenantCloneStatus next_status; + if (OB_SUCCESS != return_ret) { + next_status = ObTenantCloneStatus::Status::CLONE_USER_FAIL; + } else { + switch (current_status) { + case ObTenantCloneStatus::Status::CLONE_USER_PREPARE: + next_status = ObTenantCloneStatus::Status::CLONE_USER_CREATE_INIT_LS; + break; + case ObTenantCloneStatus::Status::CLONE_USER_CREATE_INIT_LS: + next_status = ObTenantCloneStatus::Status::CLONE_USER_WAIT_LS; + break; + case ObTenantCloneStatus::Status::CLONE_USER_WAIT_LS: + next_status = ObTenantCloneStatus::Status::CLONE_USER_POST_CHECK; + break; + case ObTenantCloneStatus::Status::CLONE_USER_POST_CHECK: + next_status = ObTenantCloneStatus::Status::CLONE_USER_SUCCESS; + break; + default : + //do nothing + break; + } + } + return next_status; +} + +void ObCloneScheduler::record_rs_event_( + const share::ObCloneJob &job, + const share::ObTenantCloneStatus prev_status, + const share::ObTenantCloneStatus cur_status, + const int ret) +{ + const char *prev_status_str = ObTenantCloneStatus::get_clone_status_str(prev_status); + const char *cur_status_str = ObTenantCloneStatus::get_clone_status_str(cur_status); + ROOTSERVICE_EVENT_ADD("clone", "change_clone_status", + "job_id", job.get_job_id(), + K(ret), + "prev_clone_status", prev_status_str, + "cur_clone_status", cur_status_str); +} + +int ObCloneScheduler::check_sys_tenant_(const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObSimpleTenantSchema *tenant_schema = NULL; + uint64_t data_version = 0; + + if (!is_sys_tenant(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("unexpected tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null schema service", KR(ret), KP(GCTX.schema_service_)); + } else if (GCTX.is_standby_cluster() || GCONF.in_upgrade_mode()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("clone tenant while in standby cluster or in upgrade mode is not allowed", KR(ret)); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( + OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) { + LOG_WARN("failed to get tenant info", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(tenant_id)); + } else if (!tenant_schema->is_normal()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("sys tenant is not normal", KR(ret), K(tenant_id)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(OB_SYS_TENANT_ID, data_version))) { + LOG_WARN("fail to get sys tenant data version", KR(ret)); + } else if (DATA_VERSION_4_3_0_0 > data_version) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("sys tenant data version is below 4.3", KR(ret), K(tenant_id)); + } + + return ret; +} + +//non-cloning tenant need stop this thread to save resources +int ObCloneScheduler::check_meta_tenant_(const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + bool compatibility_satisfied = false; + uint64_t user_tenant_id = gen_user_tenant_id(tenant_id); + bool is_clone_tenant = true; + ObAllTenantInfo all_tenant_info; + + if (!is_meta_tenant(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("unexpected tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null schema service", KR(ret), KP(GCTX.schema_service_)); + } else if (GCTX.is_standby_cluster() || GCONF.in_upgrade_mode()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("clone tenant while in standby cluster or in upgrade mode is not allowed", KR(ret)); + } else if (OB_FAIL(ObShareUtil::check_compat_version_for_clone_tenant(tenant_id, compatibility_satisfied))) { + LOG_WARN("check tenant compatibility failed", KR(ret), K(tenant_id)); + } else if (!compatibility_satisfied) { + ret = OB_OP_NOT_ALLOW; + LOG_INFO("tenant data version is below 4.3", KR(ret), K(tenant_id), K(compatibility_satisfied)); + } else { + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObSimpleTenantSchema *meta_tenant_schema = NULL; + const share::schema::ObTenantSchema *user_tenant_schema = NULL; + if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( + OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, meta_tenant_schema))) { + LOG_WARN("failed to get tenant info", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(meta_tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(tenant_id)); + } else if (!meta_tenant_schema->is_normal()) { + ret = OB_OP_NOT_ALLOW; + LOG_INFO("meta tenant is not normal", KR(ret), K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_tenant_info(user_tenant_id, user_tenant_schema))) { + LOG_WARN("failed to get tenant info", KR(ret), K(user_tenant_id)); + } else if (OB_ISNULL(user_tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(user_tenant_id)); + } else if (!user_tenant_schema->is_restore_tenant_status()) { + //we only stop this thread in clone tenant when the status of the tenant is normal + is_clone_tenant = false; + LOG_INFO("tenant is not in restore status", KR(ret), KPC(user_tenant_schema)); + } else { /*restore_tenant_status*/ + if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(user_tenant_id, GCTX.sql_proxy_, + false/*for_update*/, all_tenant_info))) { + LOG_WARN("failed to load tenant info", KR(ret), K(user_tenant_id)); + } else if (all_tenant_info.is_restore()) { + is_clone_tenant = false; + LOG_INFO("tenant is in restore role", KR(ret), K(all_tenant_info)); + } + } + } + + if (OB_SUCC(ret) && !is_clone_tenant) { + stop(); + } + + return ret; +} + +int ObCloneScheduler::wait_source_relative_task_finished_( + const uint64_t source_tenant_id) +{ + int ret = OB_SUCCESS; + ObMySQLTransaction trans; + const int64_t timeout = DEFAULT_TIMEOUT; + observer::ObInnerSQLConnection *conn = NULL; + + if (!is_user_tenant(source_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(trans.start(sql_proxy_, source_tenant_id))) { + LOG_WARN("failed to start trans in user tenant", KR(ret), K(source_tenant_id)); + } else if (OB_ISNULL(conn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("conn_ is NULL", KR(ret)); + //TODO: __all_unit is not in white list + } else if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(source_tenant_id, + OB_ALL_UNIT_TID, + EXCLUSIVE, + timeout, + conn))) { + LOG_WARN("lock dest table failed", KR(ret), K(source_tenant_id)); + } + + /*If we successfully lock, we can assure that there are currently + no related tasks being executed, so we can roll back the lock. + Afterwards, new related tasks will not be allowed to be executed + because we previously locked the record GLOBAL_STATE (snapshot_id = 0) + in the internal table __all_tenant_snapshot */ + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + //rollback + if (OB_TMP_FAIL(trans.end(false))) { + LOG_WARN("trans abort failed", KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + return ret; +} + +int ObCloneScheduler::fill_clone_resource_pool_arg_( + const share::ObCloneJob &job, + const uint64_t resource_pool_id, + obrpc::ObCloneResourcePoolArg &arg) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_FAIL(arg.init(job.get_resource_pool_name(), + job.get_unit_config_name(), + job.get_source_tenant_id(), + resource_pool_id))) { + LOG_WARN("fail to init arg", KR(ret), K(job)); + } else { + arg.exec_tenant_id_ = OB_SYS_TENANT_ID; + } + return ret; +} + +int ObCloneScheduler::fill_create_tenant_arg_( + const share::ObCloneJob &job, + const uint64_t clone_tenant_id, + obrpc::ObCreateTenantArg &arg) +{ + int ret = OB_SUCCESS; + arg.reset(); + ObTenantSnapshotTableOperator snap_op; + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const ObTenantSnapshotID &snapshot_id = job.get_tenant_snapshot_id(); + ObTenantSnapItem snap_item; + ObTenantSchema source_tenant_schema; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_UNLIKELY(!job.is_valid() + || !snapshot_id.is_valid() + || !job.get_restore_scn().is_valid() + || OB_INVALID_TENANT_ID == clone_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job), K(clone_tenant_id)); + } else if (OB_ISNULL(schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null schema service", KR(ret), KP(schema_service_)); + } else if (OB_FAIL(ObTenantThreadHelper::get_tenant_schema(source_tenant_id, source_tenant_schema))) { + LOG_WARN("failed to get tenant schema", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(snap_op.init(source_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init table op", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(snap_op.get_tenant_snap_item(job.get_tenant_snapshot_id(), false, snap_item))) { + LOG_WARN("failed to get snap item", KR(ret), K(source_tenant_id), K(job.get_tenant_snapshot_id())); + } else if (OB_FAIL(arg.pool_list_.push_back(job.get_resource_pool_name()))) { + LOG_WARN("failed to push back", KR(ret), K(job.get_resource_pool_name())); + } else if (OB_FAIL(arg.tenant_schema_.set_tenant_name(job.get_clone_tenant_name()))) { + LOG_WARN("fail to set tenant name", KR(ret), K(job.get_clone_tenant_name())); + } else if (OB_FAIL(arg.tenant_schema_.set_primary_zone(source_tenant_schema.get_primary_zone()))) { + LOG_WARN("fail to set primary zone", KR(ret), K(source_tenant_schema.get_primary_zone())); + } else if (OB_FAIL(arg.tenant_schema_.set_locality(source_tenant_schema.get_locality()))) { + LOG_WARN("fail to set locality", KR(ret), K(source_tenant_schema.get_locality())); + } else { + HEAP_VAR(ObLSMetaPackage, sys_ls_meta_package) { + if (OB_FAIL(snap_op.get_proper_ls_meta_package(snapshot_id, SYS_LS, sys_ls_meta_package))) { + LOG_WARN("failed to get sys ls meta package", KR(ret), K(source_tenant_id), K(snapshot_id)); + } else { + arg.tenant_schema_.set_compatibility_mode(source_tenant_schema.get_compatibility_mode()); + arg.exec_tenant_id_ = OB_SYS_TENANT_ID; + arg.tenant_schema_.set_tenant_id(clone_tenant_id); + arg.if_not_exist_ = true; + arg.palf_base_info_ = sys_ls_meta_package.palf_meta_; + arg.recovery_until_scn_ = job.get_restore_scn(); + arg.compatible_version_ = snap_item.get_data_version(); + arg.source_tenant_id_ = source_tenant_id; + } + } + } + + return ret; +} + +int ObCloneScheduler::clone_root_key_(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; +#ifdef OB_BUILD_TDE_SECURITY + const uint64_t user_tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + ObRootKey root_key; + + if (OB_UNLIKELY(!is_user_tenant(user_tenant_id) + || !is_user_tenant(source_tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(user_tenant_id), K(source_tenant_id)); + } else if (OB_FAIL(ObMasterKeyGetter::instance().get_root_key(source_tenant_id, root_key, true))) { + LOG_WARN("failed to get root key from source tenant", KR(ret), K(source_tenant_id)); + } else if (obrpc::RootKeyType::INVALID == root_key.key_type_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid root key", KR(ret)); + } else if (OB_FAIL(ObMasterKeyGetter::instance().set_root_key(user_tenant_id, root_key.key_type_, + root_key.key_, true))) { + LOG_WARN("failed to set root key for clone tenant", KR(ret)); + } else if (OB_FAIL(ObRestoreCommonUtil::notify_root_key(srv_rpc_proxy_, sql_proxy_, + user_tenant_id, root_key))) { + LOG_WARN("failed to notify root key", KR(ret), K(user_tenant_id)); + } +#endif + return ret; +} + +int ObCloneScheduler::clone_keystore_(const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; +#ifdef OB_BUILD_TDE_SECURITY + const int64_t timeout = max(GCONF.rpc_timeout, DEFAULT_TIMEOUT); + ObString tde_method; + const uint64_t user_tenant_id = job.get_tenant_id(); + const uint64_t source_tenant_id = job.get_source_tenant_id(); + ObUnitTableOperator unit_operator; + common::ObArray units; + ObArray return_code_array; + obrpc::ObCloneKeyArg arg; + if (OB_FAIL(ObEncryptionUtil::get_tde_method(source_tenant_id, tde_method))) { + LOG_WARN("failed to get tde_method", KR(ret), K(source_tenant_id)); + } else if (OB_UNLIKELY(tde_method.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tde_method is empty", KR(ret)); + } else if (!ObTdeMethodUtil::is_valid(tde_method)) { + //source tenant does not enable encryption. + //do nothing + } else if (OB_ISNULL(srv_rpc_proxy_) || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null svr rpc proxy or sql proxy", KR(ret)); + } else if (OB_FAIL(unit_operator.init(*sql_proxy_))) { + LOG_WARN("failed to init unit operator", KR(ret)); + } else if (OB_FAIL(unit_operator.get_units_by_tenant(user_tenant_id, units))) { + LOG_WARN("failed to get tenant unit", KR(ret), K(user_tenant_id)); + } else { + ObCloneKeyProxy proxy(*srv_rpc_proxy_, &obrpc::ObSrvRpcProxy::clone_key); + arg.set_tenant_id(user_tenant_id); + arg.set_source_tenant_id(source_tenant_id); + for (int64_t i = 0; OB_SUCC(ret) && i < units.count(); i++) { + const ObUnit &unit = units.at(i); + if (OB_FAIL(proxy.call(unit.server_, timeout, arg))) { + LOG_WARN("failed to send rpc", KR(ret), K(unit.server_), K(arg)); + } + } + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(proxy.wait_all(return_code_array))) { + LOG_WARN("wait batch result failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + if (OB_SUCC(ret)) { + if (return_code_array.count() != proxy.get_dests().count() + || return_code_array.count() != proxy.get_args().count() + || return_code_array.count() != proxy.get_results().count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("count not match", KR(ret), K(return_code_array.count()), K(proxy.get_dests().count()), + K(proxy.get_args().count()), K(proxy.get_results().count())); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < return_code_array.count(); i++) { + int res_ret = return_code_array.at(i); + const ObAddr &addr = proxy.get_dests().at(i); + if (OB_SUCCESS != res_ret) { + ret = res_ret; + LOG_WARN("rpc execute failed", KR(ret), K(addr)); + } + } + } + } + } +#endif + return ret; +} + +int ObCloneScheduler::get_ls_attrs_from_source_( + const share::ObCloneJob &job, + ObSArray &ls_attr_array) +{ + int ret = OB_SUCCESS; + ls_attr_array.reset(); + ObTenantSnapshotTableOperator table_op; + ObArray snap_ls_items; + + if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else { + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const ObTenantSnapshotID &snapshot_id = job.get_tenant_snapshot_id(); + MTL_SWITCH(OB_SYS_TENANT_ID) { + if (OB_FAIL(table_op.init(source_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init table op", KR(ret)); + } else if (OB_FAIL(table_op.get_tenant_snap_ls_items(snapshot_id, snap_ls_items))) { + LOG_WARN("failed to get tenant snapshot ls items", KR(ret), K(source_tenant_id), K(snapshot_id)); + } + } + } + if (OB_SUCC(ret)) { + ARRAY_FOREACH_N(snap_ls_items, i, cnt) { + const ObTenantSnapLSItem &snap_ls_item = snap_ls_items.at(i); + if (OB_FAIL(ls_attr_array.push_back(snap_ls_item.get_ls_attr()))) { + LOG_WARN("failed to push back ls attr", KR(ret), K(snap_ls_item)); + } + } + } + return ret; +} + +int ObCloneScheduler::create_all_ls_( + const uint64_t user_tenant_id, + const share::schema::ObTenantSchema &tenant_schema, + const common::ObIArray &ls_attr_array, + const uint64_t source_tenant_id) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); + } else if (OB_FAIL(ObRestoreCommonUtil::create_all_ls(sql_proxy_, user_tenant_id, + tenant_schema, ls_attr_array, source_tenant_id))) { + LOG_WARN("failed to create all ls", KR(ret), K(user_tenant_id), K(tenant_schema), + K(ls_attr_array), K(source_tenant_id)); + } + return ret; +} + +int ObCloneScheduler::wait_all_ls_created_( + const share::schema::ObTenantSchema &tenant_schema, + const share::ObCloneJob &job) +{ + int ret = OB_SUCCESS; + const uint64_t source_tenant_id = job.get_source_tenant_id(); + const ObTenantSnapshotID &tenant_snapshot_id = job.get_tenant_snapshot_id(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_UNLIKELY(!tenant_schema.is_valid() + || !job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_schema), K(job)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); + } else { + const uint64_t tenant_id = tenant_schema.get_tenant_id(); + ObLSStatusOperator status_op; + ObLSStatusInfoArray ls_array; + ObLSRecoveryStat recovery_stat; + ObLSRecoveryStatOperator ls_recovery_operator; + + if (OB_FAIL(status_op.get_all_ls_status_by_order(tenant_id, ls_array, + *sql_proxy_))) { + LOG_WARN("failed to get all ls status", KR(ret), K(tenant_id)); + } else { + HEAP_VAR(ObLSMetaPackage, ls_meta_package) { + for (int64_t i = 0; OB_SUCC(ret) && i < ls_array.count(); ++i) { + const ObLSStatusInfo &info = ls_array.at(i); + if (info.ls_is_creating()) { + recovery_stat.reset(); + ls_meta_package.reset(); + if (OB_FAIL(ls_recovery_operator.get_ls_recovery_stat(tenant_id, info.ls_id_, + false/*for_update*/, recovery_stat, *sql_proxy_))) { + LOG_WARN("failed to get ls recovery stat", KR(ret), K(tenant_id), K(info)); + } else { + MTL_SWITCH(OB_SYS_TENANT_ID) { + ObTenantSnapshotTableOperator snap_op; + if (OB_FAIL(snap_op.init(source_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init snap op", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(snap_op.get_proper_ls_meta_package(tenant_snapshot_id, info.ls_id_, ls_meta_package))) { + LOG_WARN("failed to get ls meta package", KR(ret), K(tenant_snapshot_id), K(info.ls_id_)); + } + } + } + if (FAILEDx(ObCommonLSService::do_create_user_ls( + tenant_schema, info, recovery_stat.get_create_scn(), + true, /*create with palf*/ + ls_meta_package.palf_meta_, source_tenant_id))) { + LOG_WARN("failed to create ls with palf", KR(ret), K(info), K(tenant_schema), + K(recovery_stat.get_create_scn()), K(ls_meta_package.palf_meta_), K(source_tenant_id)); + } + } + } + } + } + LOG_INFO("[RESTORE] wait ls created", KR(ret), K(tenant_id), K(ls_array)); + } + return ret; +} + +int ObCloneScheduler::finish_create_ls_( + const share::schema::ObTenantSchema &tenant_schema, + const common::ObIArray &ls_attr_array) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_UNLIKELY(!tenant_schema.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_schema)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); + } else if (OB_FAIL(ObRestoreCommonUtil::finish_create_ls(sql_proxy_, tenant_schema, ls_attr_array))) { + LOG_WARN("failed to finish create ls", KR(ret), K(tenant_schema)); + } + return ret; +} + +int ObCloneScheduler::get_source_tenant_archive_log_path_( + const uint64_t source_tenant_id, + share::ObBackupPathString& path) +{ + int ret = OB_SUCCESS; + ObArchivePersistHelper op; + common::ObArray> dest_arr; + + if (OB_UNLIKELY(!is_user_tenant(source_tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(source_tenant_id)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); + } else { + MTL_SWITCH(OB_SYS_TENANT_ID) { + if (OB_FAIL(op.init(source_tenant_id))) { + LOG_WARN("fail to init ObArchivePersistHelper", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(op.get_valid_dest_pairs(*sql_proxy_, dest_arr))) { + LOG_WARN("fail to get_valid_dest_pairs", KR(ret), K(source_tenant_id)); + } else if (dest_arr.empty()) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("dest arr is empty", KR(ret), K(source_tenant_id)); + } else { + path = dest_arr.at(0).second; + LOG_INFO("get source tenant archive log dest path succ", K(path), K(source_tenant_id)); + } + } + } + return ret; +} + +int ObCloneScheduler::convert_parameters_( + const uint64_t user_tenant_id, + const uint64_t source_tenant_id) +{ + int ret = OB_SUCCESS; +#ifdef OB_BUILD_TDE_SECURITY + ObString tde_method; + ObString kms_info; + ObSqlString sql; + int64_t affected_row = 0; + uint64_t latest_master_key_id = 0; + bool source_has_encrypt_info = true; + bool clone_has_encrypt_info = true; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else if (has_set_stop()) { + ret = OB_CANCELED; + LOG_WARN("clone scheduler stopped", KR(ret)); + } else if (OB_UNLIKELY(!is_user_tenant(user_tenant_id) + || !is_user_tenant(source_tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(user_tenant_id), K(source_tenant_id)); + } else if (OB_FAIL(ObEncryptionUtil::get_tde_method(source_tenant_id, tde_method))) { + LOG_WARN("failed to get tde_method", KR(ret), K(source_tenant_id)); + } else if (OB_UNLIKELY(tde_method.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tde_method is empty", KR(ret)); + } else if (!ObTdeMethodUtil::is_valid(tde_method)) { + source_has_encrypt_info = false; + } else if (OB_FAIL(get_latest_key_id_(user_tenant_id, latest_master_key_id))) { + if (OB_ENTRY_NOT_EXIST == ret) { + clone_has_encrypt_info = false; + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get latest key id", KR(ret), K(user_tenant_id)); + } + } + + /* If the source tenant has encrypt_info, + (under current regulations) + its tde_method cannot be changed, and encryption cannot be turned off. + So if false == source_has_encrypt_info, + we can assure clone tenant does not enable encryption. */ + if (OB_SUCC(ret) && source_has_encrypt_info) { + if (OB_FAIL(trim_master_key_map_(user_tenant_id, latest_master_key_id))) { + LOG_WARN("fail to trim master key map", KR(ret), K(user_tenant_id), K(latest_master_key_id)); + } else if (!clone_has_encrypt_info) { + //do nothing + } else if (OB_FAIL(sql.assign_fmt("ALTER SYSTEM SET tde_method = '%.*s'", + tde_method.length(), tde_method.ptr()))) { + LOG_WARN("failed to assign fmt", KR(ret), K(tde_method)); + } else if (OB_FAIL(sql_proxy_->write(user_tenant_id, sql.ptr(), affected_row))) { + LOG_WARN("failed to execute", KR(ret), K(user_tenant_id), K(sql)); + } else if (ObTdeMethodUtil::is_internal(tde_method)) { + // do nothing + } else if (OB_FAIL(ObEncryptionUtil::get_tde_kms_info(source_tenant_id, kms_info))) { + LOG_WARN("failed to get tde kms info", KR(ret), K(source_tenant_id)); + //TODO: TDE method can change | kms_info may change + } else if (OB_UNLIKELY(kms_info.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("kms_info should not be empty", KR(ret)); + } else if (FALSE_IT(sql.reset())) { + } else if (OB_FAIL(sql.assign_fmt("ALTER SYSTEM SET external_kms_info= '%.*s'", + kms_info.length(), kms_info.ptr()))) { + LOG_WARN("failed to assign fmt", KR(ret)); + } else if (OB_FAIL(sql_proxy_->write(user_tenant_id, sql.ptr(), affected_row))) { + LOG_WARN("failed to execute", KR(ret), K(user_tenant_id)); + } + } +#endif + return ret; +} + +int ObCloneScheduler::trim_master_key_map_( + const uint64_t user_tenant_id, + const uint64_t latest_key_id) +{ + int ret = OB_SUCCESS; +#ifdef OB_BUILD_TDE_SECURITY + const int64_t timeout = max(GCONF.rpc_timeout, DEFAULT_TIMEOUT); + ObUnitTableOperator unit_operator; + common::ObArray units; + ObArray return_code_array; + obrpc::ObTrimKeyListArg arg; + if (OB_UNLIKELY(!is_user_tenant(user_tenant_id) + || OB_INVALID_ID == latest_key_id + || OB_ISNULL(sql_proxy_) + || OB_ISNULL(srv_rpc_proxy_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(user_tenant_id), K(latest_key_id), + KP(sql_proxy_), KP(srv_rpc_proxy_)); + } else if (OB_FAIL(unit_operator.init(*sql_proxy_))) { + LOG_WARN("failed to init unit operator", KR(ret)); + } else if (OB_FAIL(unit_operator.get_units_by_tenant(user_tenant_id, units))) { + LOG_WARN("failed to get tenant unit", KR(ret), K(user_tenant_id)); + } else { + ObTrimKeyListProxy proxy(*srv_rpc_proxy_, &obrpc::ObSrvRpcProxy::trim_key_list); + arg.set_tenant_id(user_tenant_id); + arg.set_latest_master_key_id(latest_key_id); + ARRAY_FOREACH_N(units, i, cnt) { + const ObUnit &unit = units.at(i); + if (OB_FAIL(proxy.call(unit.server_, timeout, arg))) { + LOG_WARN("failed to send rpc", KR(ret)); + } + } + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(proxy.wait_all(return_code_array))) { + LOG_WARN("wait batch result failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + if (OB_SUCC(ret)) { + if (return_code_array.count() != proxy.get_dests().count() + || return_code_array.count() != proxy.get_args().count() + || return_code_array.count() != proxy.get_results().count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("count not match", KR(ret), K(return_code_array.count()), K(proxy.get_dests().count()), + K(proxy.get_args().count()), K(proxy.get_results().count())); + } else { + ARRAY_FOREACH_N(return_code_array, i, cnt) { + int res_ret = return_code_array.at(i); + const ObAddr &addr = proxy.get_dests().at(i); + if (OB_SUCCESS != res_ret) { + ret = res_ret; + LOG_WARN("rpc execute failed", KR(ret), K(addr)); + } + } + } + } + } +#endif + return ret; +} + +int ObCloneScheduler::get_latest_key_id_( + const uint64_t user_tenant_id, + uint64_t &latest_key_id) +{ + int ret = OB_SUCCESS; +#ifdef OB_BUILD_TDE_SECURITY + ObSqlString sql; + if (OB_UNLIKELY(!is_user_tenant(user_tenant_id) + || OB_ISNULL(sql_proxy_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(user_tenant_id), KP(sql_proxy_)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT master_key_id FROM %s ORDER BY MASTER_KEY_ID DESC LIMIT 1", + OB_ALL_TENANT_KEYSTORE_HISTORY_TNAME))) { + LOG_WARN("assign sql failed", KR(ret)); + //TODO: exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id) + } else if (OB_FAIL(sql_proxy_->read(res, user_tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(sql)); + } else if (OB_UNLIKELY(NULL == (result = res.get_result()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } else { + LOG_WARN("next failed", KR(ret)); + } + } else { + EXTRACT_INT_FIELD_MYSQL(*result, "master_key_id", latest_key_id, uint64_t); + } + } + } +#endif + return ret; +} + +} +} diff --git a/src/rootserver/restore/ob_clone_scheduler.h b/src/rootserver/restore/ob_clone_scheduler.h new file mode 100644 index 0000000000..cfcd4cc3e8 --- /dev/null +++ b/src/rootserver/restore/ob_clone_scheduler.h @@ -0,0 +1,153 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_ROOTSERVER_OB_CLONE_SCHEDULER_H_ +#define OCEANBASE_ROOTSERVER_OB_CLONE_SCHEDULER_H_ + +#include "share/restore/ob_tenant_clone_table_operator.h" +#include "share/ob_rpc_struct.h" +#include "rootserver/ob_tenant_thread_helper.h"//ObTenantThreadHelper +#include "share/ls/ob_ls_status_operator.h" + +namespace oceanbase +{ +namespace share +{ +class ObLSAttr; +class ObTenantSnapLSReplicaSimpleItem; +} + +namespace rootserver +{ + +class TenantRestoreStatus; + +class ObCloneScheduler : public ObTenantThreadHelper, + public logservice::ObICheckpointSubHandler, + public logservice::ObIReplaySubHandler +{ +public: + ObCloneScheduler(); + virtual ~ObCloneScheduler(); + int init(); + virtual void do_work() override; + void destroy(); + void wakeup(); + int idle(); + DEFINE_MTL_FUNC(ObCloneScheduler); + +public: + virtual share::SCN get_rec_scn() override { return share::SCN::max_scn(); } + virtual int flush(share::SCN &scn) override { return OB_SUCCESS; } + int replay(const void *buffer, const int64_t nbytes, const palf::LSN &lsn, const share::SCN &scn) override + { + UNUSED(buffer); + UNUSED(nbytes); + UNUSED(lsn); + UNUSED(scn); + return OB_SUCCESS; + } +public: + int process_sys_clone_job(const share::ObCloneJob &job); + int process_user_clone_job(const share::ObCloneJob &job); + int clone_lock(const share::ObCloneJob &job); + int clone_create_resource_pool(const share::ObCloneJob &job); + int clone_create_snapshot_for_fork_tenant(const share::ObCloneJob &job); + int clone_wait_create_snapshot_for_fork_tenant(const share::ObCloneJob &job); + int clone_create_tenant(const share::ObCloneJob &job); + int clone_wait_tenant_restore_finish(const share::ObCloneJob &job); + int clone_release_resource(const share::ObCloneJob &job); + int clone_sys_finish(const share::ObCloneJob &job); + int clone_prepare(const share::ObCloneJob &job); + int clone_init_ls(const share::ObCloneJob &job); + int clone_wait_ls_finish(const share::ObCloneJob &job); + int clone_post_check(const share::ObCloneJob &job); + int clone_user_finish(const share::ObCloneJob &job); + int clone_recycle_failed_job(const share::ObCloneJob &job); + +private: + int try_update_job_status_(const int return_ret, + const share::ObCloneJob &job); + share::ObTenantCloneStatus get_sys_next_status_(const int return_ret, + const share::ObTenantCloneStatus current_status, + const share::ObTenantCloneJobType job_type); + share::ObTenantCloneStatus get_sys_next_status_in_normal_(const share::ObTenantCloneStatus current_status, + const share::ObTenantCloneJobType job_type); + share::ObTenantCloneStatus get_sys_next_status_in_failed_(const share::ObTenantCloneStatus current_status); + share::ObTenantCloneStatus get_user_next_status_(const int return_ret, + const share::ObTenantCloneStatus current_status); + void record_rs_event_(const share::ObCloneJob &job, + const share::ObTenantCloneStatus prev_status, + const share::ObTenantCloneStatus cur_status, + const int return_ret); + int check_sys_tenant_(const uint64_t tenant_id); + int check_meta_tenant_(const uint64_t tenant_id); + + int wait_source_relative_task_finished_(const uint64_t user_tenant_id); + int fill_clone_resource_pool_arg_(const share::ObCloneJob &job, + const uint64_t resource_pool_id, + obrpc::ObCloneResourcePoolArg &arg); + int fill_create_tenant_arg_(const share::ObCloneJob &job, + const uint64_t clone_tenant_id, + obrpc::ObCreateTenantArg &arg); + int clone_root_key_(const share::ObCloneJob &job); + int clone_keystore_(const share::ObCloneJob &job); + int get_ls_attrs_from_source_(const share::ObCloneJob &job, + ObSArray &ls_attr_array); + int create_all_ls_(const uint64_t user_tenant_id, + const share::schema::ObTenantSchema &tenant_schema, + const common::ObIArray &ls_attr_array, + const uint64_t source_tenant_id); + int wait_all_ls_created_(const share::schema::ObTenantSchema &tenant_schema, + const share::ObCloneJob &job); + int finish_create_ls_(const share::schema::ObTenantSchema &tenant_schema, + const common::ObIArray &ls_attr_array); + int get_source_tenant_archive_log_path_(const uint64_t source_tenant_id, + share::ObBackupPathString& path); + int convert_parameters_(const uint64_t user_tenant_id, + const uint64_t source_tenant_id); + int trim_master_key_map_(const uint64_t user_tenant_id, + const uint64_t latest_key_id); + int get_latest_key_id_(const uint64_t user_tenant_id, + uint64_t &latest_key_id); + + int get_tenant_snap_ls_replica_simple_items_( + const share::ObCloneJob &job, + ObArray& ls_snapshot_array); + + int check_all_ls_restore_finish_(const share::ObCloneJob &job, + TenantRestoreStatus &tenant_restore_status); + int check_one_ls_replica_restore_finish_(const share::ObCloneJob& job, + const share::ObLSInfo& ls_info, + const share::ObLSStatusInfoArray& ls_array, + const ObArray& ls_snapshot_array, + TenantRestoreStatus &tenant_restore_status); +private: + static const int32_t MAX_RETRY_CNT = 5; + static const int64_t DEFAULT_TIMEOUT = 10 * 1000 * 1000L; + static const int64_t DEFAULT_IDLE_TIME = 60 * 1000 * 1000L; + static const int64_t PROCESS_IDLE_TIME = 1 * 1000 * 1000L; +private: + bool is_inited_; + share::schema::ObMultiVersionSchemaService *schema_service_; + common::ObMySQLProxy *sql_proxy_; + obrpc::ObCommonRpcProxy *rpc_proxy_; + obrpc::ObSrvRpcProxy *srv_rpc_proxy_; + int64_t idle_time_us_; + bool work_immediately_; + DISALLOW_COPY_AND_ASSIGN(ObCloneScheduler); +}; + +} +} + +#endif // OCEANBASE_ROOTSERVER_OB_CLONE_SCHEDULER_H_ diff --git a/src/rootserver/restore/ob_restore_common_util.cpp b/src/rootserver/restore/ob_restore_common_util.cpp new file mode 100644 index 0000000000..dd49a8fc67 --- /dev/null +++ b/src/rootserver/restore/ob_restore_common_util.cpp @@ -0,0 +1,324 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS_RESTORE + +#include "ob_restore_common_util.h" +#include "share/ls/ob_ls_status_operator.h" //ObLSStatusOperator +#include "share/ls/ob_ls_operator.h"//ObLSAttr +#include "rootserver/ob_ls_service_helper.h" +#include "rootserver/ob_tenant_role_transition_service.h" +#include "src/share/ob_schema_status_proxy.h" +#include "src/share/ob_rpc_struct.h" +#include "rootserver/ob_ddl_service.h" +#ifdef OB_BUILD_TDE_SECURITY +#include "share/ob_master_key_getter.h" +#endif + +using namespace oceanbase::share::schema; +using namespace oceanbase::rootserver; +using namespace oceanbase::share; +using namespace oceanbase::common; + +int ObRestoreCommonUtil::notify_root_key( + obrpc::ObSrvRpcProxy *srv_rpc_proxy_, + common::ObMySQLProxy *sql_proxy_, + const uint64_t tenant_id, + const share::ObRootKey &root_key) +{ + int ret = OB_SUCCESS; +#ifdef OB_BUILD_TDE_SECURITY + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); + } else if (OB_UNLIKELY(obrpc::RootKeyType::INVALID == root_key.key_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid root_key", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(srv_rpc_proxy_) || OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null svr rpc proxy or sql proxy", KR(ret), + KP(srv_rpc_proxy_), KP(sql_proxy_)); + } else { + obrpc::ObRootKeyArg arg; + obrpc::ObRootKeyResult result; + ObUnitTableOperator unit_operator; + ObArray units; + ObArray addrs; + arg.tenant_id_ = tenant_id; + arg.is_set_ = true; + arg.key_type_ = root_key.key_type_; + arg.root_key_ = root_key.key_; + if (OB_FAIL(unit_operator.init(*sql_proxy_))) { + LOG_WARN("failed to init unit operator", KR(ret)); + } else if (OB_FAIL(unit_operator.get_units_by_tenant(tenant_id, units))) { + LOG_WARN("failed to get tenant unit", KR(ret), K(tenant_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < units.count(); i++) { + const ObUnit &unit = units.at(i); + if (OB_FAIL(addrs.push_back(unit.server_))) { + LOG_WARN("failed to push back addr", KR(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObDDLService::notify_root_key(*srv_rpc_proxy_, arg, addrs, result))) { + LOG_WARN("failed to notify root key", KR(ret)); + } + } +#endif + return ret; +} + +int ObRestoreCommonUtil::create_all_ls( + common::ObMySQLProxy *sql_proxy, + const uint64_t tenant_id, + const share::schema::ObTenantSchema &tenant_schema, + const common::ObIArray &ls_attr_array, + const uint64_t source_tenant_id) +{ + int ret = OB_SUCCESS; + ObLSStatusOperator status_op; + ObLSStatusInfo status_info; + if (OB_UNLIKELY(!is_user_tenant(tenant_id) + || !tenant_schema.is_valid() + || ls_attr_array.empty() + || OB_ISNULL(sql_proxy))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_schema), + K(ls_attr_array), KP(sql_proxy)); + } else { + common::ObMySQLTransaction trans; + const int64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id); + + if (OB_FAIL(trans.start(sql_proxy, exec_tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id)); + } else { + //must be in trans + //Multiple LS groups will be created here. + //In order to ensure that each LS group can be evenly distributed in the unit group, + //it is necessary to read the distribution of LS groups within the transaction. + ObTenantLSInfo tenant_stat(sql_proxy, &tenant_schema, tenant_id, &trans); + for (int64_t i = 0; OB_SUCC(ret) && i < ls_attr_array.count(); ++i) { + const ObLSAttr &ls_info = ls_attr_array.at(i); + ObLSFlag ls_flag = ls_info.get_ls_flag(); + if (ls_info.get_ls_id().is_sys_ls()) { + } else if (OB_SUCC(status_op.get_ls_status_info(tenant_id, ls_info.get_ls_id(), + status_info, trans))) { + LOG_INFO("[RESTORE] ls already exist", K(ls_info), K(tenant_id)); + } else if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get ls status info", KR(ret), K(tenant_id), K(ls_info)); + } else if (OB_FAIL(ObLSServiceHelper::create_new_ls_in_trans( + ls_info.get_ls_id(), ls_info.get_ls_group_id(), ls_info.get_create_scn(), + share::NORMAL_SWITCHOVER_STATUS, tenant_stat, trans, ls_flag, source_tenant_id))) { + LOG_WARN("failed to add new ls status info", KR(ret), K(ls_info), K(source_tenant_id)); + } + LOG_INFO("create init ls", KR(ret), K(ls_info), K(source_tenant_id)); + } + } + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + ret = OB_SUCC(ret) ? tmp_ret : ret; + LOG_WARN("failed to end trans", KR(ret), KR(tmp_ret)); + } + } + return ret; +} + +int ObRestoreCommonUtil::finish_create_ls( + common::ObMySQLProxy *sql_proxy, + const share::schema::ObTenantSchema &tenant_schema, + const common::ObIArray &ls_attr_array) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!tenant_schema.is_valid() + || OB_ISNULL(sql_proxy))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_schema), KP(sql_proxy)); + } else { + const uint64_t tenant_id = tenant_schema.get_tenant_id(); + const int64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id); + common::ObMySQLTransaction trans; + ObLSStatusOperator status_op; + ObLSStatusInfoArray ls_array; + ObLSStatus ls_info = share::OB_LS_EMPTY;//ls status in __all_ls + if (OB_FAIL(status_op.get_all_ls_status_by_order(tenant_id, ls_array, + *sql_proxy))) { + LOG_WARN("failed to get all ls status", KR(ret), K(tenant_id)); + } else if (OB_FAIL(trans.start(sql_proxy, exec_tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < ls_array.count(); ++i) { + const ObLSStatusInfo &status_info = ls_array.at(i); + if (OB_UNLIKELY(status_info.ls_is_creating())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should be created", KR(ret), K(status_info)); + } else { + ret = OB_ENTRY_NOT_EXIST; + for (int64_t j = 0; OB_ENTRY_NOT_EXIST == ret && j < ls_attr_array.count(); ++j) { + if (ls_attr_array.at(i).get_ls_id() == status_info.ls_id_) { + ret = OB_SUCCESS; + ls_info = ls_attr_array.at(i).get_ls_status(); + } + } + if (OB_FAIL(ret)) { + LOG_WARN("failed to find ls in attr", KR(ret), K(status_info), K(ls_attr_array)); + } else if (share::OB_LS_CREATING == ls_info) { + //no need to update + } else if (ls_info == status_info.status_) { + //no need update + } else if (OB_FAIL(status_op.update_ls_status_in_trans( + tenant_id, status_info.ls_id_, status_info.status_, + ls_info, share::NORMAL_SWITCHOVER_STATUS, trans))) { + LOG_WARN("failed to update status", KR(ret), K(tenant_id), K(status_info), K(ls_info)); + } else { + LOG_INFO("[RESTORE] update ls status", K(tenant_id), K(status_info), K(ls_info)); + } + } + } + } + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { + ret = OB_SUCC(ret) ? tmp_ret : ret; + LOG_WARN("failed to end trans", KR(ret), KR(tmp_ret)); + } + } + return ret; +} + +int ObRestoreCommonUtil::try_update_tenant_role(common::ObMySQLProxy *sql_proxy, + const uint64_t tenant_id, + const share::SCN &restore_scn, + const bool is_clone, + bool &sync_satisfied) +{ + int ret = OB_SUCCESS; + sync_satisfied = true; + ObAllTenantInfo all_tenant_info; + int64_t new_switch_ts = 0; + bool need_update = false; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) + || OB_ISNULL(sql_proxy) + || OB_ISNULL(GCTX.srv_rpc_proxy_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not user tenant or proxy is null", KR(ret), K(tenant_id), + KP(sql_proxy), KP(GCTX.srv_rpc_proxy_)); + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, sql_proxy, + false/*for_update*/, all_tenant_info))) { + LOG_WARN("failed to load tenant info", KR(ret), K(tenant_id)); + } else if (!is_clone && all_tenant_info.is_restore()) { + need_update = true; + } else if (is_clone && all_tenant_info.is_clone()) { + need_update = true; + } + + if (OB_SUCC(ret) && need_update) { + //update tenant role to standby tenant + if (all_tenant_info.get_sync_scn() != restore_scn) { + sync_satisfied = false; + LOG_WARN("tenant sync scn not equal to restore scn", KR(ret), + K(all_tenant_info), K(restore_scn)); + } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_role( + tenant_id, sql_proxy, all_tenant_info.get_switchover_epoch(), + share::STANDBY_TENANT_ROLE, all_tenant_info.get_switchover_status(), + share::NORMAL_SWITCHOVER_STATUS, new_switch_ts))) { + LOG_WARN("failed to update tenant role", KR(ret), K(tenant_id), K(all_tenant_info)); + } else { + ObTenantRoleTransitionService role_transition_service(tenant_id, sql_proxy, + GCTX.srv_rpc_proxy_, obrpc::ObSwitchTenantArg::OpType::INVALID); + (void)role_transition_service.broadcast_tenant_info( + ObTenantRoleTransitionConstants::RESTORE_TO_STANDBY_LOG_MOD_STR); + } + } + return ret; +} + +int ObRestoreCommonUtil::process_schema(common::ObMySQLProxy *sql_proxy, + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(sql_proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy)); + } else { + //reset schema status + ObSchemaStatusProxy proxy(*sql_proxy); + ObRefreshSchemaStatus schema_status(tenant_id, OB_INVALID_TIMESTAMP, OB_INVALID_VERSION); + if (OB_FAIL(proxy.init())) { + LOG_WARN("failed to init schema proxy", KR(ret)); + } else if (OB_FAIL(proxy.set_tenant_schema_status(schema_status))) { + LOG_WARN("failed to update schema status", KR(ret), K(schema_status)); + } + } + + if (OB_SUCC(ret)) { + obrpc::ObBroadcastSchemaArg arg; + arg.tenant_id_ = tenant_id; + if (OB_ISNULL(GCTX.rs_rpc_proxy_) || OB_ISNULL(GCTX.rs_mgr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rs_rpc_proxy_ or rs_mgr_is null", KR(ret), KP(GCTX.rs_rpc_proxy_), KP(GCTX.rs_mgr_)); + } else if (OB_FAIL(GCTX.rs_rpc_proxy_->to_rs(*GCTX.rs_mgr_).broadcast_schema(arg))) { + LOG_WARN("failed to broadcast schema", KR(ret), K(arg)); + } + } + + return ret; +} + +int ObRestoreCommonUtil::check_tenant_is_existed(ObMultiVersionSchemaService *schema_service, + const uint64_t tenant_id, + bool &is_existed) +{ + int ret = OB_SUCCESS; + is_existed = true; + ObSchemaGetterGuard schema_guard; + bool tenant_dropped = false; + + if (OB_INVALID_TENANT_ID == tenant_id) { + //maybe failed to create tenant + is_existed = false; + LOG_INFO("tenant maybe failed to create", KR(ret)); + } else if (OB_ISNULL(schema_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema service is null", KR(ret), KP(schema_service)); + } else if (OB_FAIL(schema_service->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get tenant schema guard", KR(ret)); + } else if (OB_SUCCESS != schema_guard.check_formal_guard()) { + ret = OB_SCHEMA_ERROR; + LOG_WARN("failed to check formal gurad", KR(ret)); + } else if (OB_FAIL(schema_guard.check_if_tenant_has_been_dropped(tenant_id, tenant_dropped))) { + LOG_WARN("failed to check tenant is beed dropped", KR(ret), K(tenant_id)); + } else if (tenant_dropped) { + is_existed = false; + LOG_INFO("restore tenant has been dropped", KR(ret), K(tenant_id)); + } else { + //check restore tenant's meta tenant is valid to read + const share::schema::ObTenantSchema *tenant_schema = NULL; + const uint64_t meta_tenant_id = gen_meta_tenant_id(tenant_id); + if (OB_FAIL(schema_guard.get_tenant_info(meta_tenant_id, tenant_schema))) { + LOG_WARN("failed to get tenant info", KR(ret), K(meta_tenant_id)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(meta_tenant_id)); + } else if (tenant_schema->is_normal()) { + is_existed = true; + } else { + //other status cannot get result from meta + is_existed = false; + LOG_WARN("meta tenant of restore tenant not normal", KR(ret), KPC(tenant_schema)); + } + } + return ret; +} diff --git a/src/rootserver/restore/ob_restore_common_util.h b/src/rootserver/restore/ob_restore_common_util.h new file mode 100644 index 0000000000..e304da12ce --- /dev/null +++ b/src/rootserver/restore/ob_restore_common_util.h @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef __OB_RS_RESTORE_COMMON_UTIL_H__ +#define __OB_RS_RESTORE_COMMON_UTIL_H__ + +#include "share/ob_rpc_struct.h" +#include "share/ob_common_rpc_proxy.h" +#include "share/scn.h" + +namespace oceanbase +{ +namespace share +{ +class ObRootKey; +struct ObLSAttr; +} +namespace rootserver +{ + +class TenantRestoreStatus +{ +public: + enum Status : int8_t + { + INVALID = -1, + IN_PROGRESS = 0, + SUCCESS = 1, + FAILED = 2, + }; + +public: + TenantRestoreStatus() : status_(INVALID) {} + TenantRestoreStatus(int8_t status) : status_(status) {} + + bool is_finish() { return SUCCESS == status_ || FAILED == status_; } + bool is_success() { return SUCCESS == status_; } + bool is_failed() { return FAILED == status_; } + + TenantRestoreStatus operator=(const TenantRestoreStatus &other) { status_ = other.status_; return *this; } + bool operator == (const TenantRestoreStatus &other) const { return status_ == other.status_; } + bool operator != (const TenantRestoreStatus &other) const { return status_ != other.status_; } + + TO_STRING_KV(K_(status)); +private: + int8_t status_; +}; + +class ObRestoreCommonUtil +{ +public: + static int notify_root_key(obrpc::ObSrvRpcProxy *srv_rpc_proxy_, + common::ObMySQLProxy *sql_proxy_, + const uint64_t tenant_id, + const share::ObRootKey &root_key); + static int create_all_ls(common::ObMySQLProxy *sql_proxy, + const uint64_t tenant_id, + const share::schema::ObTenantSchema &tenant_schema, + const common::ObIArray &ls_attr_array, + const uint64_t source_tenant_id = OB_INVALID_TENANT_ID); + static int finish_create_ls(common::ObMySQLProxy *sql_proxy, + const share::schema::ObTenantSchema &tenant_schema, + const common::ObIArray &ls_attr_array); + static int try_update_tenant_role(common::ObMySQLProxy *sql_proxy, + const uint64_t tenant_id, + const share::SCN &restore_scn, + const bool is_clone, + bool &sync_satisfied); + static int process_schema(common::ObMySQLProxy *sql_proxy, + const uint64_t tenant_id); + static int check_tenant_is_existed(ObMultiVersionSchemaService *schema_service, + const uint64_t tenant_id, + bool &is_existed); + +private: + DISALLOW_COPY_AND_ASSIGN(ObRestoreCommonUtil); +}; +} +} + +#endif /* __OB_RS_RESTORE_COMMON_UTIL_H__ */ diff --git a/src/rootserver/restore/ob_restore_scheduler.cpp b/src/rootserver/restore/ob_restore_scheduler.cpp index 63bef09921..7643ed1752 100644 --- a/src/rootserver/restore/ob_restore_scheduler.cpp +++ b/src/rootserver/restore/ob_restore_scheduler.cpp @@ -543,31 +543,8 @@ int ObRestoreScheduler::restore_root_key(const share::ObPhysicalRestoreJob &job_ LOG_WARN("fail to get root key", K(ret)); } else if (obrpc::RootKeyType::INVALID == root_key.key_type_) { // do nothing - } else { - obrpc::ObRootKeyArg arg; - obrpc::ObRootKeyResult result; - ObUnitTableOperator unit_operator; - ObArray units; - ObArray addrs; - arg.tenant_id_ = tenant_id_; - arg.is_set_ = true; - arg.key_type_ = root_key.key_type_; - arg.root_key_ = root_key.key_; - if (OB_FAIL(unit_operator.init(*sql_proxy_))) { - LOG_WARN("failed to init unit operator", KR(ret)); - } else if (OB_FAIL(unit_operator.get_units_by_tenant(tenant_id_, units))) { - LOG_WARN("failed to get tenant unit", KR(ret), K_(tenant_id)); - } - for (int64_t i = 0; OB_SUCC(ret) && i < units.count(); i++) { - const ObUnit &unit = units.at(i); - if (OB_FAIL(addrs.push_back(unit.server_))) { - LOG_WARN("failed to push back addr", KR(ret)); - } - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(ObDDLService::notify_root_key(*srv_rpc_proxy_, arg, addrs, result))) { - LOG_WARN("failed to notify root key", K(ret)); - } + } else if (OB_FAIL(ObRestoreCommonUtil::notify_root_key(srv_rpc_proxy_, sql_proxy_, tenant_id_, root_key))) { + LOG_WARN("failed to notify root key", KR(ret), K(tenant_id_)); } } #endif @@ -628,10 +605,8 @@ int ObRestoreScheduler::restore_keystore(const share::ObPhysicalRestoreJob &job_ int ObRestoreScheduler::post_check(const ObPhysicalRestoreJob &job_info) { int ret = OB_SUCCESS; - ObSchemaGetterGuard schema_guard; DEBUG_SYNC(BEFORE_PHYSICAL_RESTORE_POST_CHECK); - ObAllTenantInfo all_tenant_info; - const uint64_t exec_tenant_id = gen_meta_tenant_id(tenant_id_); + bool sync_satisfied = true; if (!inited_) { ret = OB_NOT_INIT; @@ -642,41 +617,16 @@ int ObRestoreScheduler::post_check(const ObPhysicalRestoreJob &job_info) LOG_WARN("invalid tenant id", K(ret), K(tenant_id_)); } else if (OB_FAIL(restore_service_->check_stop())) { LOG_WARN("restore scheduler stopped", K(ret)); - } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id_, sql_proxy_, - false, /*for_update*/all_tenant_info))) { - LOG_WARN("failed to load tenant info", KR(ret), K(tenant_id_)); - } else if (all_tenant_info.is_restore()) { - //update tenant role to standby tenant - int64_t new_switch_ts = 0; - if (all_tenant_info.get_sync_scn() != job_info.get_restore_scn()) { - ret = OB_NEED_WAIT; - LOG_WARN("tenant sync scn not equal to restore scn, need wait", KR(ret), K(all_tenant_info), K(job_info)); - } else if (OB_FAIL(ObAllTenantInfoProxy::update_tenant_role( - tenant_id_, sql_proxy_, all_tenant_info.get_switchover_epoch(), - share::STANDBY_TENANT_ROLE, all_tenant_info.get_switchover_status(), - share::NORMAL_SWITCHOVER_STATUS, new_switch_ts))) { - LOG_WARN("failed to update tenant role", KR(ret), K(tenant_id_), K(all_tenant_info)); - } else { - ObTenantRoleTransitionService role_transition_service(tenant_id_, sql_proxy_, - GCTX.srv_rpc_proxy_, ObSwitchTenantArg::OpType::INVALID); - (void)role_transition_service.broadcast_tenant_info( - ObTenantRoleTransitionConstants::RESTORE_TO_STANDBY_LOG_MOD_STR); - } + } else if (OB_FAIL(ObRestoreCommonUtil::try_update_tenant_role(sql_proxy_, tenant_id_, + job_info.get_restore_scn(), false /*is_clone*/, sync_satisfied))) { + LOG_WARN("failed to try update tenant role", KR(ret), K(tenant_id_), K(job_info)); + } else if (!sync_satisfied) { + ret = OB_NEED_WAIT; + LOG_WARN("tenant sync scn not equal to restore scn, need wait", KR(ret), K(job_info)); } - if (FAILEDx(reset_schema_status(tenant_id_, sql_proxy_))) { - LOG_WARN("failed to reset schema status", KR(ret)); - } - - if (OB_SUCC(ret)) { - ObBroadcastSchemaArg arg; - arg.tenant_id_ = tenant_id_; - if (OB_ISNULL(GCTX.rs_rpc_proxy_) || OB_ISNULL(GCTX.rs_mgr_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("common rpc proxy is null", KR(ret), KP(GCTX.rs_mgr_), KP(GCTX.rs_rpc_proxy_)); - } else if (OB_FAIL(GCTX.rs_rpc_proxy_->to_rs(*GCTX.rs_mgr_).broadcast_schema(arg))) { - LOG_WARN("failed to broadcast schema", KR(ret), K(arg)); - } + if (FAILEDx(ObRestoreCommonUtil::process_schema(sql_proxy_, tenant_id_))) { + LOG_WARN("failed to process schema", KR(ret)); } if (FAILEDx(convert_parameters(job_info))) { @@ -771,8 +721,6 @@ int ObRestoreScheduler::try_get_tenant_restore_history_( { int ret = OB_SUCCESS; restore_tenant_exist = true; - ObSchemaGetterGuard schema_guard; - bool tenant_dropped = false; ObHisRestoreJobPersistInfo user_history_info; const uint64_t restore_tenant_id = job_info.get_tenant_id(); if (!inited_) { @@ -780,39 +728,9 @@ int ObRestoreScheduler::try_get_tenant_restore_history_( LOG_WARN("not inited", KR(ret)); } else if (OB_FAIL(restore_service_->check_stop())) { LOG_WARN("restore scheduler stopped", KR(ret)); - } else if (OB_INVALID_TENANT_ID == restore_tenant_id) { - //maybe failed to create tenant - restore_tenant_exist = false; - LOG_INFO("tenant maybe failed to create", KR(ret), K(job_info)); - } else if (OB_ISNULL(schema_service_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("schema service is null", KR(ret)); - } else if (OB_FAIL(schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { - LOG_WARN("fail to get tenant schema guard", KR(ret)); - } else if (OB_SUCCESS != schema_guard.check_formal_guard()) { - ret = OB_SCHEMA_ERROR; - LOG_WARN("failed to check formal gurad", KR(ret), K(job_info)); - } else if (OB_FAIL(schema_guard.check_if_tenant_has_been_dropped(restore_tenant_id, tenant_dropped))) { - LOG_WARN("failed to check tenant is beed dropped", KR(ret), K(restore_tenant_id)); - } else if (tenant_dropped) { - restore_tenant_exist = false; - LOG_INFO("restore tenant has been dropped", KR(ret), K(job_info)); - } else { - //check restore tenant's meta tenant is valid to read - const share::schema::ObTenantSchema *tenant_schema = NULL; - const uint64_t meta_tenant_id = gen_meta_tenant_id(restore_tenant_id); - if (OB_FAIL(schema_guard.get_tenant_info(meta_tenant_id, tenant_schema))) { - LOG_WARN("failed to get tenant ids", KR(ret), K(meta_tenant_id)); - } else if (OB_ISNULL(tenant_schema)) { - ret = OB_TENANT_NOT_EXIST; - LOG_WARN("tenant not exist", KR(ret), K(meta_tenant_id)); - } else if (tenant_schema->is_normal()) { - restore_tenant_exist = true; - } else { - //other status cannot get result from meta - restore_tenant_exist = false; - LOG_INFO("meta tenant of restore tenant not normal", KR(ret), KPC(tenant_schema)); - } + } else if (OB_FAIL(ObRestoreCommonUtil::check_tenant_is_existed(schema_service_, + restore_tenant_id, restore_tenant_exist))) { + LOG_WARN("fail to check tenant_is_existed", KR(ret), K(restore_tenant_id), K(job_info)); } if (OB_FAIL(ret)) { } else if (!restore_tenant_exist) { @@ -1059,7 +977,7 @@ int ObRestoreScheduler::restore_init_ls(const share::ObPhysicalRestoreJob &job_i if (FAILEDx(ls_recovery.update_sys_ls_sync_scn(tenant_id_, trans, sync_scn))) { LOG_WARN("failed to update sync ls sync scn", KR(ret), K(sync_scn)); } - END_TRANSACTION(trans) + END_TRANSACTION(trans) } if (FAILEDx(create_all_ls_(*tenant_schema, backup_ls_attr.ls_attr_array_))) { LOG_WARN("failed to create all ls", KR(ret), K(backup_ls_attr), KPC(tenant_schema)); @@ -1087,7 +1005,7 @@ int ObRestoreScheduler::restore_init_ls(const share::ObPhysicalRestoreJob &job_i } } - if (OB_SUCC(ret) || is_tenant_restore_failed(tenant_restore_status)) { + if (OB_SUCC(ret) || tenant_restore_status.is_failed()) { int tmp_ret = OB_SUCCESS; if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { tmp_ret = OB_SUCC(ret) ? tmp_ret : ret; @@ -1139,8 +1057,6 @@ int ObRestoreScheduler::create_all_ls_( const common::ObIArray &ls_attr_array) { int ret = OB_SUCCESS; - ObLSStatusOperator status_op; - ObLSStatusInfo status_info; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", KR(ret)); @@ -1149,44 +1065,8 @@ int ObRestoreScheduler::create_all_ls_( } else if (OB_ISNULL(sql_proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); - } else if (OB_UNLIKELY(!tenant_schema.is_valid() - || 0 >= ls_attr_array.count())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(tenant_schema), K(ls_attr_array)); - } else { - common::ObMySQLTransaction trans; - const int64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id_); - - if (OB_FAIL(trans.start(sql_proxy_, exec_tenant_id))) { - LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id)); - } else { - //must be in trans - //Multiple LS groups will be created here. - //In order to ensure that each LS group can be evenly distributed in the unit group, - //it is necessary to read the distribution of LS groups within the transaction. - ObTenantLSInfo tenant_stat(sql_proxy_, &tenant_schema, tenant_id_, &trans); - for (int64_t i = 0; OB_SUCC(ret) && i < ls_attr_array.count(); ++i) { - const ObLSAttr &ls_info = ls_attr_array.at(i); - ObLSFlag ls_flag = ls_info.get_ls_flag(); - if (ls_info.get_ls_id().is_sys_ls()) { - } else if (OB_SUCC(status_op.get_ls_status_info(tenant_id_, ls_info.get_ls_id(), - status_info, trans))) { - LOG_INFO("[RESTORE] ls already exist", K(ls_info), K(tenant_id_)); - } else if (OB_ENTRY_NOT_EXIST != ret) { - LOG_WARN("failed to get ls status info", KR(ret), K(tenant_id_), K(ls_info)); - } else if (OB_FAIL(ObLSServiceHelper::create_new_ls_in_trans( - ls_info.get_ls_id(), ls_info.get_ls_group_id(), ls_info.get_create_scn(), - share::NORMAL_SWITCHOVER_STATUS, tenant_stat, trans, ls_flag))) { - LOG_WARN("failed to add new ls status info", KR(ret), K(ls_info)); - } - LOG_INFO("create init ls", KR(ret), K(ls_info)); - } - } - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to end trans", KR(ret), KR(tmp_ret)); - } + } else if (OB_FAIL(ObRestoreCommonUtil::create_all_ls(sql_proxy_, tenant_id_, tenant_schema, ls_attr_array))) { + LOG_WARN("fail to create all ls", KR(ret), K(tenant_id_), K(tenant_schema), K(ls_attr_array)); } return ret; } @@ -1232,7 +1112,7 @@ int ObRestoreScheduler::wait_all_ls_created_(const share::schema::ObTenantSchema } else if (OB_FAIL(ObCommonLSService::do_create_user_ls( tenant_schema, info, recovery_stat.get_create_scn(), true, /*create with palf*/ - palf_base_info))) { + palf_base_info, OB_INVALID_TENANT_ID/*source_tenant_id*/))) { LOG_WARN("failed to create ls with palf", KR(ret), K(info), K(tenant_schema), K(palf_base_info)); } @@ -1259,53 +1139,8 @@ int ObRestoreScheduler::finish_create_ls_( } else if (OB_ISNULL(sql_proxy_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("sql proxy is null", KR(ret), KP(sql_proxy_)); - } else { - const uint64_t tenant_id = tenant_schema.get_tenant_id(); - const int64_t exec_tenant_id = ObLSLifeIAgent::get_exec_tenant_id(tenant_id); - common::ObMySQLTransaction trans; - ObLSStatusOperator status_op; - ObLSStatusInfoArray ls_array; - ObLSStatus ls_info = share::OB_LS_EMPTY;//ls status in __all_ls - if (OB_FAIL(status_op.get_all_ls_status_by_order(tenant_id, ls_array, - *sql_proxy_))) { - LOG_WARN("failed to get all ls status", KR(ret), K(tenant_id)); - } else if (OB_FAIL(trans.start(sql_proxy_, exec_tenant_id))) { - LOG_WARN("failed to start trans", KR(ret), K(exec_tenant_id)); - } else { - for (int64_t i = 0; OB_SUCC(ret) && i < ls_array.count(); ++i) { - const ObLSStatusInfo &status_info = ls_array.at(i); - if (OB_UNLIKELY(status_info.ls_is_creating())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls should be created", KR(ret), K(status_info)); - } else { - ret = OB_ENTRY_NOT_EXIST; - for (int64_t j = 0; OB_ENTRY_NOT_EXIST == ret && j < ls_attr_array.count(); ++j) { - if (ls_attr_array.at(i).get_ls_id() == status_info.ls_id_) { - ret = OB_SUCCESS; - ls_info = ls_attr_array.at(i).get_ls_status(); - } - } - if (OB_FAIL(ret)) { - LOG_WARN("failed to find ls in attr", KR(ret), K(status_info), K(ls_attr_array)); - } else if (share::OB_LS_CREATING == ls_info) { - //no need to update - } else if (ls_info == status_info.status_) { - //no need update - } else if (OB_FAIL(status_op.update_ls_status_in_trans( - tenant_id, status_info.ls_id_, status_info.status_, - ls_info, share::NORMAL_SWITCHOVER_STATUS, trans))) { - LOG_WARN("failed to update status", KR(ret), K(tenant_id), K(status_info), K(ls_info)); - } else { - LOG_INFO("[RESTORE] update ls status", K(tenant_id), K(status_info), K(ls_info)); - } - } - } - } - int tmp_ret = OB_SUCCESS; - if (OB_SUCCESS != (tmp_ret = trans.end(OB_SUCC(ret)))) { - ret = OB_SUCC(ret) ? tmp_ret : ret; - LOG_WARN("failed to end trans", KR(ret), KR(tmp_ret)); - } + } else if (OB_FAIL(ObRestoreCommonUtil::finish_create_ls(sql_proxy_, tenant_schema, ls_attr_array))) { + LOG_WARN("fail to finish create ls", KR(ret), K(tenant_schema), K(ls_attr_array)); } return ret; } @@ -1338,12 +1173,12 @@ int ObRestoreScheduler::restore_wait_to_consistent_scn(const share::ObPhysicalRe KPC(tenant_schema)); } else if (OB_FAIL(check_all_ls_restore_to_consistent_scn_finish_(tenant_id, tenant_restore_status))) { LOG_WARN("fail to check all ls restore finish", KR(ret), K(job_info)); - } else if (is_tenant_restore_finish(tenant_restore_status)) { + } else if (tenant_restore_status.is_finish()) { LOG_INFO("[RESTORE] restore wait all ls restore to consistent scn done", K(tenant_id), K(tenant_restore_status)); int tmp_ret = OB_SUCCESS; ObMySQLTransaction trans; const uint64_t exec_tenant_id = gen_meta_tenant_id(job_info.get_tenant_id()); - if (is_tenant_restore_failed(tenant_restore_status)) { + if (tenant_restore_status.is_failed()) { ret = OB_LS_RESTORE_FAILED; LOG_INFO("[RESTORE]restore wait all ls restore to consistent scn failed", K(ret)); if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, ret, job_info))) { @@ -1416,11 +1251,11 @@ int ObRestoreScheduler::restore_wait_ls_finish(const share::ObPhysicalRestoreJob KPC(tenant_schema)); } else if (OB_FAIL(check_all_ls_restore_finish_(tenant_id, tenant_restore_status))) { LOG_WARN("failed to check all ls restore finish", KR(ret), K(job_info)); - } else if (is_tenant_restore_finish(tenant_restore_status)) { + } else if (tenant_restore_status.is_finish()) { LOG_INFO("[RESTORE] restore wait all ls finish done", K(tenant_id), K(tenant_restore_status)); int tmp_ret = OB_SUCCESS; int tenant_restore_result = OB_LS_RESTORE_FAILED; - if (is_tenant_restore_success(tenant_restore_status)) { + if (tenant_restore_status.is_success()) { tenant_restore_result = OB_SUCCESS; } if (OB_SUCCESS != (tmp_ret = try_update_job_status(*sql_proxy_, tenant_restore_result, job_info))) { @@ -1463,25 +1298,25 @@ int ObRestoreScheduler::check_all_ls_restore_finish_( //if one of ls restore failed, make tenant restore failed // while (OB_SUCC(ret) && OB_SUCC(result->next()) - && !is_tenant_restore_failed(tenant_restore_status)) { + && !tenant_restore_status.is_failed()) { EXTRACT_INT_FIELD_MYSQL(*result, "ls_id", ls_id, int64_t); EXTRACT_INT_FIELD_MYSQL(*result, "restore_status", restore_status, int32_t); if (OB_FAIL(ret)) { } else if (OB_FAIL(ls_restore_status.set_status(restore_status))) { LOG_WARN("failed to set status", KR(ret), K(restore_status)); - } else if (ls_restore_status.is_restore_failed()) { + } else if (!ls_restore_status.is_in_restore_or_none() || ls_restore_status.is_failed()) { //restore failed tenant_restore_status = TenantRestoreStatus::FAILED; - } else if (!ls_restore_status.is_restore_none() - && is_tenant_restore_success(tenant_restore_status)) { + } else if (!ls_restore_status.is_none() + && tenant_restore_status.is_success()) { tenant_restore_status = TenantRestoreStatus::IN_PROGRESS; } } // while if (OB_ITER_END == ret) { ret = OB_SUCCESS; } - if (TenantRestoreStatus::SUCCESS != tenant_restore_status) { + if (!tenant_restore_status.is_success()) { LOG_INFO("check all ls restore not finish, just wait", KR(ret), K(tenant_id), K(ls_id), K(tenant_restore_status)); } @@ -1512,7 +1347,7 @@ int ObRestoreScheduler::check_all_ls_restore_to_consistent_scn_finish_( } if (OB_FAIL(ret)) { - } else if (TenantRestoreStatus::SUCCESS != tenant_restore_status) { + } else if (!tenant_restore_status.is_success()) { LOG_INFO("check all ls restore to consistent_scn not finish, just wait", KR(ret), K(tenant_id), K(tenant_restore_status)); } diff --git a/src/rootserver/restore/ob_restore_scheduler.h b/src/rootserver/restore/ob_restore_scheduler.h index f22ee84365..d623cd3459 100644 --- a/src/rootserver/restore/ob_restore_scheduler.h +++ b/src/rootserver/restore/ob_restore_scheduler.h @@ -17,6 +17,7 @@ #include "share/backup/ob_backup_struct.h" #include "share/ob_rpc_struct.h" #include "share/ob_upgrade_utils.h" +#include "ob_restore_common_util.h" namespace oceanbase { @@ -43,25 +44,6 @@ public: void do_work(); void destroy(); public: - enum TenantRestoreStatus - { - IN_PROGRESS = 0, - SUCCESS, - FAILED - }; - bool is_tenant_restore_finish(const TenantRestoreStatus tenant_restore_status) const - { - return SUCCESS == tenant_restore_status || FAILED == tenant_restore_status; - } - bool is_tenant_restore_success(const TenantRestoreStatus tenant_restore_status) const - { - return SUCCESS == tenant_restore_status; - } - bool is_tenant_restore_failed(const TenantRestoreStatus tenant_restore_status) const - { - return FAILED == tenant_restore_status; - } - static int reset_schema_status(const uint64_t tenant_id, common::ObMySQLProxy *sql_proxy); public: diff --git a/src/rootserver/restore/ob_restore_util.cpp b/src/rootserver/restore/ob_restore_util.cpp index 1fc53477a1..b81c932e88 100644 --- a/src/rootserver/restore/ob_restore_util.cpp +++ b/src/rootserver/restore/ob_restore_util.cpp @@ -855,7 +855,7 @@ int ObRestoreUtil::recycle_restore_job(const uint64_t tenant_id, int64_t pos = 0; ARRAY_FOREACH_X(ls_restore_progress_infos, i, cnt, OB_SUCC(ret)) { const ObLSRestoreProgressPersistInfo &ls_restore_info = ls_restore_progress_infos.at(i); - if (ls_restore_info.status_.is_restore_failed()) { + if (ls_restore_info.status_.is_failed()) { if (OB_FAIL(databuff_printf(history_info.comment_.ptr(), history_info.comment_.capacity(), pos, "%s;", ls_restore_info.comment_.ptr()))) { if (OB_SIZE_OVERFLOW == ret) { diff --git a/src/rootserver/restore/ob_tenant_clone_util.cpp b/src/rootserver/restore/ob_tenant_clone_util.cpp new file mode 100644 index 0000000000..d907615ca2 --- /dev/null +++ b/src/rootserver/restore/ob_tenant_clone_util.cpp @@ -0,0 +1,588 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS_RESTORE + +#include "ob_tenant_clone_util.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "share/restore/ob_tenant_clone_table_operator.h" +#include "share/location_cache/ob_location_service.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" + +using namespace oceanbase::rootserver; +using namespace oceanbase::share; + +//a source tenant only has one clone_job at the same time +int ObTenantCloneUtil::check_source_tenant_has_clone_job( + common::ObISQLClient &sql_client, + const uint64_t source_tenant_id, + bool &has_job) +{ + int ret = OB_SUCCESS; + has_job = false; + ObTenantCloneTableOperator clone_op; + ObCloneJob clone_job; + + if (OB_FAIL(clone_op.init(OB_SYS_TENANT_ID, &sql_client))) { + LOG_WARN("fail to init clone op", KR(ret)); + } else if (OB_FAIL(clone_op.get_clone_job_by_source_tenant_id( + source_tenant_id, clone_job))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get job", KR(ret), K(source_tenant_id)); + } + } else { + has_job = true; + } + + return ret; +} + +int ObTenantCloneUtil::check_clone_tenant_exist(common::ObISQLClient &sql_client, + const ObString &clone_tenant_name, + bool &is_exist) +{ + int ret = OB_SUCCESS; + is_exist = false; + ObTenantCloneTableOperator clone_op; + ObCloneJob clone_job; + + if (OB_FAIL(clone_op.init(OB_SYS_TENANT_ID, &sql_client))) { + LOG_WARN("fail to init clone op", KR(ret)); + } else if (OB_FAIL(clone_op.get_clone_job_by_clone_tenant_name( + clone_tenant_name, false/*need lock*/, clone_job))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get job", KR(ret), K(clone_tenant_name)); + } + } else { + is_exist = true; + LOG_INFO("clone job exist", KR(ret), K(clone_tenant_name)); + } + + return ret; +} + +int ObTenantCloneUtil::fill_clone_job(const int64_t job_id, + const obrpc::ObCloneTenantArg &arg, + const uint64_t source_tenant_id, + const ObString &source_tenant_name, + const ObTenantSnapItem &snapshot_item, + ObCloneJob &clone_job) +{ + int ret = OB_SUCCESS; + clone_job.reset(); + ObTenantCloneJobType job_type = ObTenantCloneJobType::CLONE_JOB_MAX_TYPE; + common::ObCurTraceId::TraceId trace_id; + + if (OB_UNLIKELY(job_id < 0 + || !arg.is_valid() + || !is_user_tenant(source_tenant_id) + || source_tenant_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id), K(arg), K(source_tenant_id), + K(source_tenant_name), K(snapshot_item)); + } else if (FALSE_IT(job_type = snapshot_item.is_valid() ? + ObTenantCloneJobType::RESTORE : + ObTenantCloneJobType::FORK)) { + } else { + ObCurTraceId::TraceId *cur_trace_id = ObCurTraceId::get_trace_id(); + if (nullptr != cur_trace_id) { + trace_id = *cur_trace_id; + } else { + trace_id.init(GCONF.self_addr_); + } + const ObCloneJob::ObCloneJobInitArg init_arg = { + .trace_id_ = trace_id, + .tenant_id_ = OB_SYS_TENANT_ID, + .job_id_ = job_id, + .source_tenant_id_ = source_tenant_id, + .source_tenant_name_ = source_tenant_name, + .clone_tenant_id_ = OB_INVALID_TENANT_ID, + .clone_tenant_name_ = arg.get_new_tenant_name(), + .tenant_snapshot_id_ = snapshot_item.get_tenant_snapshot_id(), + .tenant_snapshot_name_ = snapshot_item.get_snapshot_name(), + .resource_pool_id_ = OB_INVALID_ID, + .resource_pool_name_ = arg.get_resource_pool_name(), + .unit_config_name_ = arg.get_unit_config_name(), + .restore_scn_ = snapshot_item.get_snapshot_scn(), + .status_ = ObTenantCloneStatus(ObTenantCloneStatus::Status::CLONE_SYS_LOCK), + .job_type_ = job_type, + .ret_code_ = OB_SUCCESS, + }; + if (OB_FAIL(clone_job.init(init_arg))) { + LOG_WARN("fail to init clone job", KR(ret), K(init_arg)); + } + } + + return ret; +} + +int ObTenantCloneUtil::record_clone_job(common::ObISQLClient &sql_client, + const share::ObCloneJob &clone_job) +{ + int ret = OB_SUCCESS; + ObTenantCloneTableOperator clone_op; + uint64_t source_tenant_id = clone_job.get_source_tenant_id(); + ObString clone_tenant_name = clone_job.get_clone_tenant_name(); + bool has_job = false; + bool tenant_exist_in_clone_job = false; + + if (OB_UNLIKELY(!clone_job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(clone_job)); + } else if (OB_FAIL(check_source_tenant_has_clone_job(sql_client, source_tenant_id, has_job))) { + LOG_WARN("fail to check source tenant has clone job", KR(ret), K(source_tenant_id)); + } else if (has_job) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("source tenant already has clone job", KR(ret), K(source_tenant_id)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "source tenant has a running clone job, clone tenant now"); + } else if (OB_FAIL(ObTenantCloneUtil::check_clone_tenant_exist(sql_client, + clone_tenant_name, tenant_exist_in_clone_job))) { + LOG_WARN("failed to check clone tenant exist in clone job", KR(ret), K(clone_tenant_name)); + } else if (tenant_exist_in_clone_job) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("duplicate clone tenant name in clone job", KR(ret), K(clone_tenant_name)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "clone tenant name exists in a running clone job, clone tenant now"); + } else if (OB_FAIL(clone_op.init(OB_SYS_TENANT_ID, &sql_client))) { + LOG_WARN("fail to init clone op", KR(ret)); + } else if (OB_FAIL(clone_op.insert_clone_job(clone_job))) { + LOG_WARN("fail to insert clone job", KR(ret), K(clone_job)); + } + + return ret; +} + +int ObTenantCloneUtil::update_resource_pool_id_of_clone_job(common::ObISQLClient &sql_client, + const int64_t job_id, + const uint64_t resource_pool_id) +{ + int ret = OB_SUCCESS; + ObTenantCloneTableOperator clone_op; + + if (OB_UNLIKELY(job_id < 0 || OB_INVALID_ID == resource_pool_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id), K(resource_pool_id)); + } else if (OB_FAIL(clone_op.init(OB_SYS_TENANT_ID, &sql_client))) { + LOG_WARN("fail to init clone op", KR(ret)); + } else if (OB_FAIL(clone_op.update_job_resource_pool_id(job_id, resource_pool_id))) { + LOG_WARN("fail to update clone job resource pool id", KR(ret), K(job_id), K(resource_pool_id)); + } + + return ret; +} + +int ObTenantCloneUtil::update_snapshot_info_for_fork_job(common::ObISQLClient &sql_client, + const int64_t job_id, + const ObTenantSnapshotID tenant_snapshot_id, + const ObString &tenant_snapshot_name) +{ + int ret = OB_SUCCESS; + ObTenantCloneTableOperator clone_op; + + if (OB_UNLIKELY(job_id < 0 || !tenant_snapshot_id.is_valid() || + tenant_snapshot_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id), K(tenant_snapshot_id), K(tenant_snapshot_name)); + } else if (OB_FAIL(clone_op.init(OB_SYS_TENANT_ID, &sql_client))) { + LOG_WARN("fail to init clone op", KR(ret)); + } else if (OB_FAIL(clone_op.update_job_snapshot_info(job_id, + tenant_snapshot_id, + tenant_snapshot_name))) { + LOG_WARN("fail to update clone job id and name", KR(ret), K(job_id), K(tenant_snapshot_id), K(tenant_snapshot_name)); + } + + return ret; +} + +int ObTenantCloneUtil::update_restore_scn_for_fork_job(common::ObISQLClient &sql_client, + const int64_t job_id, + const SCN &restore_scn) +{ + int ret = OB_SUCCESS; + ObTenantCloneTableOperator clone_op; + + if (OB_UNLIKELY(OB_INVALID_ID == job_id || !restore_scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id), K(restore_scn)); + } else if (OB_FAIL(clone_op.init(OB_SYS_TENANT_ID, &sql_client))) { + LOG_WARN("fail to init clone op", KR(ret)); + } else if (OB_FAIL(clone_op.update_job_snapshot_scn(job_id, + restore_scn))) { + LOG_WARN("fail to update clone job snapshot scn", KR(ret), K(job_id), K(restore_scn)); + } + + return ret; +} + +int ObTenantCloneUtil::insert_user_tenant_clone_job(common::ObISQLClient &sql_client, + const ObString &clone_tenant_name, + const uint64_t user_tenant_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(clone_tenant_name.empty() || !is_user_tenant(user_tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(clone_tenant_name), K(user_tenant_id)); + } else { + ObTenantCloneTableOperator clone_op; + ObCloneJob clone_job; + ObCloneJob user_clone_job; + if (OB_FAIL(clone_op.init(OB_SYS_TENANT_ID, &sql_client))) { + LOG_WARN("fail init clone op", KR(ret)); + } else if (OB_FAIL(clone_op.get_clone_job_by_clone_tenant_name( + clone_tenant_name, false/*need_lock*/, clone_job))) { + LOG_WARN("fail to get clone job", KR(ret), K(clone_tenant_name)); + } else if (OB_FAIL(user_clone_job.assign(clone_job))) { + LOG_WARN("fail to assign clone job", KR(ret), K(clone_job)); + } else { + user_clone_job.set_tenant_id(user_tenant_id); + user_clone_job.set_clone_tenant_id(user_tenant_id); + user_clone_job.set_status(ObTenantCloneStatus::Status::CLONE_USER_PREPARE); + ObTenantCloneTableOperator user_clone_op; + if (OB_FAIL(user_clone_op.init(user_tenant_id, &sql_client))) { + LOG_WARN("fail init clone op", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(user_clone_op.insert_clone_job(user_clone_job))) { + LOG_WARN("fail to insert clone job", KR(ret), K(user_clone_job)); + } + } + } + return ret; +} + +int ObTenantCloneUtil::recycle_clone_job(common::ObISQLClient &sql_client, + const ObCloneJob &job) +{ + int ret = OB_SUCCESS; + ObTenantCloneTableOperator clone_op; + ObMySQLTransaction trans; + const uint64_t tenant_id = job.get_tenant_id(); + + if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_FAIL(trans.start(&sql_client, gen_meta_tenant_id(tenant_id)))) { + LOG_WARN("fail to start trans", KR(ret), K(gen_meta_tenant_id(tenant_id))); + } else if (OB_FAIL(clone_op.init(tenant_id, &trans))) { + LOG_WARN("fail to init", KR(ret), K(tenant_id)); + } else if (OB_FAIL(clone_op.insert_clone_job_history(job))) { + LOG_WARN("fail to insert clone job history", KR(ret), K(job)); + } else if (OB_FAIL(clone_op.remove_clone_job(job))) { + LOG_WARN("fail to remove clone job", KR(ret), K(job)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, KR(tmp_ret), KR(ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + return ret; +} + +int ObTenantCloneUtil::notify_clone_scheduler(const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + common::ObAddr leader_addr; + obrpc::ObNotifyCloneSchedulerArg arg; + arg.set_tenant_id(tenant_id); + obrpc::ObNotifyCloneSchedulerResult res; + + if (OB_UNLIKELY(!is_sys_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pointer is null", KR(ret), KP(GCTX.srv_rpc_proxy_), KP(GCTX.location_service_)); + } else if (OB_FAIL(GCTX.location_service_->get_leader_with_retry_until_timeout( + GCONF.cluster_id, tenant_id, ObLSID(ObLSID::SYS_LS_ID), leader_addr))) { + LOG_WARN("failed to get leader address", KR(ret), K(tenant_id)); + } else if (OB_FAIL(GCTX.srv_rpc_proxy_->to(leader_addr).by(tenant_id).notify_clone_scheduler(arg, res))) { + LOG_WARN("failed to notify clone scheduler", KR(ret), K(leader_addr), K(arg)); + } else { + int res_ret = res.get_result(); + if (OB_SUCCESS != res_ret) { + ret = res_ret; + LOG_WARN("the result of notify clone scheduler failed", KR(res_ret), K(leader_addr), K(arg)); + } + } + return ret; +} + +int ObTenantCloneUtil::release_clone_tenant_resource_of_clone_job(const ObCloneJob &clone_job) +{ + int ret = OB_SUCCESS; + const int64_t timeout = GCONF._ob_ddl_timeout; + const uint64_t resource_pool_id = clone_job.get_resource_pool_id(); + const uint64_t clone_tenant_id = clone_job.get_clone_tenant_id(); + const ObString &clone_tenant_name = clone_job.get_clone_tenant_name(); + + if (!clone_job.get_status().is_sys_failed_status()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("try to release resource of a processing or success job", KR(ret), K(clone_job)); + } else if (OB_ISNULL(GCTX.rs_rpc_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret)); + } else if (OB_INVALID_ID == resource_pool_id) { + // clone tenant and resource pool have not been created + // it's no need to release resource + } else { + if (OB_INVALID_TENANT_ID != clone_tenant_id) { + obrpc::ObDropTenantArg arg; + ObArenaAllocator allocator; + arg.exec_tenant_id_ = clone_job.get_tenant_id(); + arg.if_exist_ = false; + arg.delay_to_drop_ = false; + arg.force_drop_ = true; + arg.drop_only_in_restore_ = true; + arg.tenant_id_ = clone_tenant_id; + + if (OB_FAIL(deep_copy_ob_string(allocator, clone_tenant_name, arg.tenant_name_))) { + LOG_WARN("fail to assign", KR(ret), K(clone_job)); + } else if (OB_FAIL(GCTX.rs_rpc_proxy_->timeout(timeout).drop_tenant(arg))) { + if (ret == OB_TENANT_NOT_EXIST) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to drop tenant", KR(ret), K(clone_job), K(arg)); + } + } + LOG_INFO("recycle clone tenant", KR(ret), K(clone_job)); + } + if (OB_SUCC(ret)) { + obrpc::ObDropResourcePoolArg arg; + arg.exec_tenant_id_ = clone_job.get_tenant_id(); + arg.pool_id_ = resource_pool_id; + arg.if_exist_ = true; + if (OB_FAIL(GCTX.rs_rpc_proxy_->timeout(timeout).drop_resource_pool(arg))) { + LOG_WARN("drop_resource_pool failed", KR(ret), K(clone_job)); + } + LOG_INFO("recycle clone resource pool", KR(ret), K(clone_job)); + } + } + + return ret; +} + +int ObTenantCloneUtil::release_source_tenant_resource_of_clone_job(common::ObISQLClient &sql_client, + const ObCloneJob &clone_job) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObMySQLTransaction trans; + ObTenantSnapshotTableOperator table_op; + const int64_t job_id = clone_job.get_job_id(); + const uint64_t source_tenant_id = clone_job.get_source_tenant_id(); + const ObTenantSnapshotID tenant_snapshot_id = clone_job.get_tenant_snapshot_id(); + const ObTenantCloneJobType job_type = clone_job.get_job_type(); + const ObTenantCloneStatus status = clone_job.get_status(); + bool is_already_unlocked = false; + bool is_source_tenant_exist = true; + bool need_notify_tenant_snapshot_scheduler = false; + + share::schema::ObSchemaGetterGuard schema_guard; + + if (!clone_job.get_status().is_sys_release_resource_status()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("try to release resource of a processing or success job", KR(ret), K(clone_job)); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(schema_guard.check_tenant_exist(source_tenant_id, is_source_tenant_exist))) { + LOG_WARN("get tenant ids failed", K(ret)); + } else if (OB_UNLIKELY(!is_source_tenant_exist)) { + LOG_INFO("source tenant doesn't exist while release source tenant resource", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(schema_guard.reset())) { + LOG_WARN("fail to reset schema guard", KR(ret)); + } else if (OB_FAIL(trans.start(&sql_client, gen_meta_tenant_id(source_tenant_id)))) { + LOG_WARN("trans start failed", KR(ret), K(clone_job)); + } else if (OB_FAIL(table_op.init(source_tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(clone_job)); + } else { // is_source_tenant_exist == true + // release global lock + ObTenantSnapItem global_lock; + if (OB_FAIL(table_op.get_tenant_snap_item( + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), + true /*for update*/, + global_lock))) { + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("global lock has not been created", KR(ret), K(clone_job)); + is_already_unlocked = true; + } else { + LOG_WARN("fail to get global_lock", KR(ret), K(clone_job)); + } + } else if (ObTenantSnapStatus::RESTORING != global_lock.get_status()) { + is_already_unlocked = true; + LOG_INFO("global lock has been released", KR(ret), K(clone_job)); + } else if (OB_FAIL(ObTenantSnapshotUtil::unlock_tenant_snapshot_simulated_mutex_from_clone_release_task( + trans, + source_tenant_id, + job_id, + ObTenantSnapStatus::RESTORING, + is_already_unlocked))) { + LOG_WARN("fail to unlock", KR(ret), K(clone_job), K(global_lock)); + } + + // release snapshot + // "is_already_unlocked == true" means the release trans of this clone job has been committed, + // or clone job is failed at the first status (CLONE_SYS_LOCK) + // thus, no need to handle with the snapshot + if (OB_SUCC(ret) && !is_already_unlocked) { + ObTenantSnapItem tenant_snapshot_item; + ObTenantSnapStatus next_snap_status = ObTenantCloneJobType::RESTORE == job_type ? + ObTenantSnapStatus::NORMAL : + ObTenantSnapStatus::DELETING; + if (!tenant_snapshot_id.is_valid()) { + if (ObTenantCloneJobType::FORK == job_type && + !status.is_sys_valid_snapshot_status_for_fork()) { + LOG_INFO("fork tenant snapshot has not been created", K(clone_job)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant snapshot is invalid", KR(ret), K(clone_job)); + } + } else if (OB_FAIL(ObTenantSnapshotUtil::get_tenant_snapshot_info(trans, + source_tenant_id, + tenant_snapshot_id, + tenant_snapshot_item))) { + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret && ObTenantCloneJobType::FORK == job_type) { + // fork clone job will generate tenant_snapshot_id at first, and then create snapshot. + // thus, it is possible that job has valid tenant_snapshot_id, but the snapshot doesn't exist + ret = OB_SUCCESS; + LOG_INFO("tenant snapshot has not been created", K(clone_job)); + } else { + LOG_WARN("fail to get tenant snapshot", KR(ret), K(clone_job)); + } + } else if (tenant_snapshot_item.get_status() == next_snap_status) { + LOG_INFO("tenant snapshot item already in next status", + K(clone_job), K(tenant_snapshot_item), K(next_snap_status)); + } else if (OB_FAIL(table_op.update_tenant_snap_item(tenant_snapshot_id, + tenant_snapshot_item.get_status(), + next_snap_status))) { + LOG_WARN("failed to update snapshot status", KR(ret), K(clone_job)); + } else if (ObTenantSnapStatus::DELETING == next_snap_status) { + ObTenantSnapJobItem job_item(source_tenant_id, + tenant_snapshot_id, + ObTenantSnapOperation::DELETE, + clone_job.get_trace_id()); + if (OB_FAIL(table_op.insert_tenant_snap_job_item(job_item))) { + LOG_WARN("fail to insert tenant snapshot job", KR(ret), K(job_item)); + } else if (OB_FAIL(ObTenantSnapshotUtil::recycle_tenant_snapshot_ls_replicas(trans, source_tenant_id, + clone_job.get_tenant_snapshot_name()))) { + LOG_WARN("fail to recycle tenant snapshot ls replicas", KR(ret), K(clone_job)); + } else { + need_notify_tenant_snapshot_scheduler = true; + } + } + } + } + + if (trans.is_started()) { + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, K(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + if (OB_SUCC(ret) && need_notify_tenant_snapshot_scheduler) { + if (OB_TMP_FAIL(ObTenantSnapshotUtil::notify_scheduler(source_tenant_id))) { + LOG_WARN("notify tenant snapshot scheduler failed", KR(tmp_ret), K(clone_job)); + } + } + + return ret; +} + +int ObTenantCloneUtil::get_clone_job_failed_message(common::ObISQLClient &sql_client, + const int64_t job_id, + const uint64_t tenant_id, + ObIAllocator &allocator, + ObString &err_msg) +{ + int ret = OB_SUCCESS; + ObTenantCloneTableOperator clone_op; + + if (OB_UNLIKELY(job_id < 0 || !is_sys_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id), K(tenant_id)); + } else if (OB_FAIL(clone_op.init(tenant_id, &sql_client))) { + LOG_WARN("fail to init", KR(ret), K(tenant_id)); + } else if (OB_FAIL(clone_op.get_job_failed_message(job_id, allocator, err_msg))) { + LOG_WARN("fail to get clone job failed message", KR(ret), K(job_id), K(tenant_id)); + } + return ret; +} + +//This function is called by the user executing "cancel clone" sql. +int ObTenantCloneUtil::cancel_clone_job(common::ObISQLClient &sql_client, + const ObString &clone_tenant_name, + bool &clone_already_finish) +{ + int ret = OB_SUCCESS; + clone_already_finish = false; + ObTenantCloneTableOperator clone_op; + ObCloneJob clone_job; + ObMySQLTransaction trans; + static const char *err_msg = "clone job has been canceled"; + const ObTenantCloneStatus next_status(ObTenantCloneStatus::Status::CLONE_SYS_CANCELED); + + if (OB_UNLIKELY(clone_tenant_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(clone_tenant_name)); + } else if (OB_FAIL(trans.start(&sql_client, OB_SYS_TENANT_ID))) { + LOG_WARN("failed to start trans", KR(ret)); + } else if (OB_FAIL(clone_op.init(OB_SYS_TENANT_ID, &trans))) { + LOG_WARN("fail init clone op", KR(ret)); + } else if (OB_FAIL(clone_op.get_clone_job_by_clone_tenant_name( + clone_tenant_name, true/*need_lock*/, clone_job))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to get clone job", KR(ret), K(clone_tenant_name)); + } else { + ret = OB_SUCCESS; + clone_already_finish = true; + } + } else if (clone_job.get_status().is_user_status()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected sys clone job status", KR(ret), K(clone_job)); + } else if (ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE == clone_job.get_status() + || !clone_job.get_status().is_sys_processing_status()) { + clone_already_finish = true; + } else if (OB_FAIL(clone_op.update_job_status(clone_job.get_job_id(), + clone_job.get_status(), /*old_status*/ + next_status))) { + LOG_WARN("fail to update job status", KR(ret), K(clone_tenant_name), K(clone_job)); + } else if (OB_FAIL(clone_op.update_job_failed_info(clone_job.get_job_id(), OB_CANCELED, err_msg))) { + LOG_WARN("fail to update job failed info", KR(ret), K(clone_job)); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", (OB_SUCCESS == ret), KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + if (OB_SUCC(ret)) { + LOG_INFO("[RESTORE] switch job status", KR(ret), K(clone_job), K(next_status)); + + const char *prev_status_str = ObTenantCloneStatus::get_clone_status_str(clone_job.get_status()); + const char *cur_status_str = ObTenantCloneStatus::get_clone_status_str(next_status); + + ROOTSERVICE_EVENT_ADD("clone", "change_clone_status", + "job_id", clone_job.get_job_id(), + K(ret), + "prev_clone_status", prev_status_str, + "cur_clone_status", cur_status_str); + } + return ret; +} diff --git a/src/rootserver/restore/ob_tenant_clone_util.h b/src/rootserver/restore/ob_tenant_clone_util.h new file mode 100644 index 0000000000..cd6b73ae5f --- /dev/null +++ b/src/rootserver/restore/ob_tenant_clone_util.h @@ -0,0 +1,85 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef __OB_RS_TENANT_CLONE_UTIL_H__ +#define __OB_RS_TENANT_CLONE_UTIL_H__ + +#include "lib/mysqlclient/ob_mysql_transaction.h" + +namespace oceanbase +{ +namespace share +{ +class ObTenantSnapshotID; +class ObTenantSnapItem; +class ObCloneJob; +class SCN; +} +namespace obrpc +{ +class ObCloneTenantArg; +} +namespace rootserver +{ +class ObTenantCloneUtil +{ +public: + static int check_source_tenant_has_clone_job(common::ObISQLClient &sql_client, + const uint64_t source_tenant_id, + bool &has_job); + static int check_clone_tenant_exist(common::ObISQLClient &sql_client, + const ObString &clone_tenant_name, + bool &is_exist); + static int fill_clone_job(const int64_t job_id, + const obrpc::ObCloneTenantArg &arg, + const uint64_t source_tenant_id, + const ObString &source_tenant_name, + const share::ObTenantSnapItem &snapshot_item, + share::ObCloneJob &clone_job); + static int record_clone_job(common::ObISQLClient &sql_client, + const share::ObCloneJob &clone_job); + static int update_resource_pool_id_of_clone_job(common::ObISQLClient &sql_client, + const int64_t job_id, + const uint64_t resource_pool_id); + static int update_snapshot_info_for_fork_job(common::ObISQLClient &sql_client, + const int64_t job_id, + const share::ObTenantSnapshotID tenant_snapshot_id, + const ObString &tenant_snapshot_name); + static int update_restore_scn_for_fork_job(common::ObISQLClient &sql_client, + const int64_t job_id, + const share::SCN &restore_scn); + static int insert_user_tenant_clone_job(common::ObISQLClient &sql_client, + const ObString &clone_tenant_name, + const uint64_t user_tenant_id); + static int recycle_clone_job(common::ObISQLClient &sql_client, + const share::ObCloneJob &job); + static int notify_clone_scheduler(const uint64_t tenant_id); + static int release_clone_tenant_resource_of_clone_job(const share::ObCloneJob &clone_job); + static int release_source_tenant_resource_of_clone_job(common::ObISQLClient &sql_client, + const share::ObCloneJob &clone_job); + static int get_clone_job_failed_message(common::ObISQLClient &sql_client, + const int64_t job_id, + const uint64_t tenant_id, + ObIAllocator &allocator, + ObString &err_msg); + //attention: This function is called by the user executing "cancel clone" sql. + static int cancel_clone_job(common::ObISQLClient &sql_client, + const ObString &clone_tenant_name, + bool &clone_already_finish); +}; + + +} +} + + +#endif /* __OB_RS_TENANT_CLONE_UTIL_H__ */ diff --git a/src/rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.cpp b/src/rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.cpp new file mode 100644 index 0000000000..8d2cf813d4 --- /dev/null +++ b/src/rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.cpp @@ -0,0 +1,1268 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS + +#include "ob_tenant_snapshot_scheduler.h" +#include "lib/utility/ob_tracepoint.h" // ERRSIM_POINT_DEF +#include "src/rootserver/ob_rs_async_rpc_proxy.h" +#include "src/rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" +#include "src/rootserver/restore/ob_tenant_clone_util.h" +#include "share/backup/ob_tenant_archive_mgr.h" +#include "storage/tablelock/ob_lock_inner_connection_util.h" +#include "observer/ob_inner_sql_connection.h" +#include "share/ls/ob_ls_table_operator.h" +#include "storage/tx/ob_ts_mgr.h" + +namespace oceanbase +{ +using namespace transaction::tablelock; + +namespace rootserver +{ +using namespace oceanbase::share; + +ObTenantSnapshotScheduler::ObTenantSnapshotScheduler() + : inited_(false), + sql_proxy_(NULL), + idle_time_us_(1) +{ +} + +ObTenantSnapshotScheduler::~ObTenantSnapshotScheduler() +{ + if (!has_set_stop()) { + stop(); + wait(); + } +} + +void ObTenantSnapshotScheduler::destroy() +{ + ObTenantThreadHelper::destroy(); + inited_ = false; +} + +int ObTenantSnapshotScheduler::init() +{ + int ret = OB_SUCCESS; + if (inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", KR(ret)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(GCTX.sql_proxy_)); + //TODO: SimpleLSService + } else if (OB_FAIL(ObTenantThreadHelper::create("SnapSche", lib::TGDefIDs::SimpleLSService, *this))) { + LOG_WARN("failed to create thread", KR(ret)); + } else if (OB_FAIL(ObTenantThreadHelper::start())) { + LOG_WARN("fail to start thread", KR(ret)); + } else { + sql_proxy_ = GCTX.sql_proxy_; + inited_ = true; + } + return ret; +} + +//TODO: wakeup and idle need to be improved +void ObTenantSnapshotScheduler::wakeup() +{ + ObTenantThreadHelper::wakeup(); +} + +int ObTenantSnapshotScheduler::idle() +{ + int ret = OB_SUCCESS; + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else { + ObTenantThreadHelper::idle(idle_time_us_); + idle_time_us_ = DEFAULT_IDLE_TIME; + } + return ret; +} + +//TODO: Synchronous deletion of snapshots to avoid delayed resource release. +//TODO: Standby tenant stop this thread +void ObTenantSnapshotScheduler::do_work() +{ + LOG_INFO("[SNAPSHOT] tenant snapshot scheduler start"); + int ret = OB_SUCCESS; + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret)); + } else { + idle_time_us_ = DEFAULT_IDLE_TIME; + bool compatibility_satisfied = false; + bool status_satisfied = false; + ObAllTenantInfo all_tenant_info; + const uint64_t meta_tenant_id = MTL_ID(); + const uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + while (!has_set_stop()) { + ObCurTraceId::init(GCTX.self_addr()); + if (!is_meta_tenant(meta_tenant_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected tenant id", KR(ret), K(meta_tenant_id)); + } else if (OB_FAIL(ObShareUtil::check_compat_version_for_clone_tenant(user_tenant_id, compatibility_satisfied))) { + LOG_WARN("check tenant compatibility failed", KR(ret), K(user_tenant_id)); + } else if (!compatibility_satisfied) { + ret = OB_OP_NOT_ALLOW; + LOG_INFO("tenant data version is below 4.3", KR(ret), K(user_tenant_id), K(compatibility_satisfied)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_status(user_tenant_id, status_satisfied))) { + LOG_WARN("check_tenant_status failed", KR(ret), K(user_tenant_id)); + } else if (!status_satisfied) { + LOG_INFO("tenant status is not valid", K(user_tenant_id), K(status_satisfied)); + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(user_tenant_id, GCTX.sql_proxy_, + false/*for_update*/, all_tenant_info))) { + LOG_WARN("failed to load tenant info", KR(ret), K(user_tenant_id)); + } else if (!all_tenant_info.is_primary()) { + LOG_INFO("tenant is not primary tenant", K(user_tenant_id)); + } else { + //********************************************************************* + //First, check whether creation or deletion jobs exist. + //Note: only one creation job can exist at a time, num > 1 is illegal. + // the num of deletion jobs is not limited. + //********************************************************************* + //Then, If the creation job has not yet been processed, we process it. + // if it has been processed, we only need to check the result. + //Note: if the result does not pass, the rpc will be resend to observers. + //********************************************************************* + //Then, We continue with the deletion jobs + //Note: we don't care about the actual results of deletion jobs + // in this thread. + //********************************************************************* + ObArray create_jobs; + ObArray delete_jobs; + if (OB_FAIL(get_tenant_snapshot_jobs_(create_jobs, delete_jobs))) { + LOG_WARN("get tenant snapshot jobs failed", KR(ret), K(user_tenant_id)); + } else { + if (create_jobs.count() > 0) { + if (create_jobs.count() > 1) { + //only one creation job can exist at a time, num > 1 is illegal! + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected creation job count", KR(ret), K(create_jobs)); + } else { + ObCreateSnapshotJob &create_job = create_jobs.at(0); + ObTraceIdGuard trace_guard(create_job.get_trace_id()); + if (OB_FAIL(prepare_for_create_tenant_snapshot_(create_job))) { + LOG_WARN("prepare for snapshot failed", KR(ret), K(create_job)); + } else if (OB_FAIL(process_create_tenant_snapshot_(create_job))) { + LOG_WARN("process create snapshot failed", KR(ret), K(create_job)); + } + idle_time_us_ = PROCESS_IDLE_TIME; + } + } + //Then, we just process the deletion jobs (Do not let creation job block deletion jobs) + ret = OB_SUCCESS; + if (delete_jobs.count() > 0) { + if (OB_FAIL(process_delete_tenant_snapshots_(delete_jobs))) { + LOG_WARN("process delete snapshots failed", KR(ret), K(delete_jobs)); + } + idle_time_us_ = PROCESS_IDLE_TIME; + } + } + } + ret = OB_SUCCESS; + idle(); + } + } +} + +int ObTenantSnapshotScheduler::get_tenant_snapshot_jobs_( + ObArray &create_jobs, + ObArray &delete_jobs) +{ + int ret = OB_SUCCESS; + create_jobs.reset(); + delete_jobs.reset(); + ObTenantSnapshotTableOperator table_op; + ObArray items; + uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + ObArbitrationServiceStatus arbitration_service_status; + int64_t paxos_replica_num = OB_INVALID_COUNT; + int64_t restore_job_num = 0; + + if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KP(GCTX.schema_service_)); + } else { + share::schema::ObSchemaGetterGuard schema_guard; + const ObTenantSchema *tenant_schema = NULL; + if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(schema_guard.get_tenant_info(user_tenant_id, tenant_schema))) { + LOG_WARN("fail to get tenant schema", KR(ret), K(user_tenant_id)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant schema is null", KR(ret)); + } else if (FALSE_IT(arbitration_service_status = tenant_schema->get_arbitration_service_status())) { + } else if (OB_FAIL(tenant_schema->get_paxos_replica_num(schema_guard, paxos_replica_num))) { + LOG_WARN("failed to get paxos replica num", KR(ret), KPC(tenant_schema)); + } else if (OB_INVALID_COUNT == paxos_replica_num) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected paxos_replica_num", KR(ret), K(paxos_replica_num)); + } + } + + if (FAILEDx(table_op.init(user_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init table op", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(table_op.get_all_user_tenant_snap_items(items))) { + LOG_WARN("failed to get snapshot items", KR(ret)); + } else { + int64_t tenant_snapshot_creation_timeout = max(SNAPSHOT_CREATION_TIMEOUT, GCONF._ob_ddl_timeout); + ARRAY_FOREACH_N(items, i, cnt) { + const ObTenantSnapItem& item = items.at(i); + if (ObTenantSnapStatus::CREATING == items.at(i).get_status() + || ObTenantSnapStatus::DECIDED == items.at(i).get_status()) { + ObCreateSnapshotJob create_job; + if (OB_FAIL(build_tenant_snapshot_create_job_(item, arbitration_service_status, + paxos_replica_num, + tenant_snapshot_creation_timeout, + create_job))){ + LOG_WARN("fail to build snapshot create job", KR(ret), K(item), + K(arbitration_service_status), + K(paxos_replica_num)); + } else if (OB_FAIL(create_jobs.push_back(create_job))) { + LOG_WARN("push back failed", KR(ret), K(create_job)); + } + } else if (ObTenantSnapStatus::DELETING == items.at(i).get_status()) { + ObDeleteSnapshotJob delete_job; + if (OB_FAIL(build_tenant_snapshot_delete_job_(item, delete_job))) { + LOG_WARN("fail to build snapshot delete job", KR(ret), K(item)); + } else if (OB_FAIL(delete_jobs.push_back(delete_job))) { + LOG_WARN("push back failed", KR(ret), K(item), K(delete_job)); + } + } else if (ObTenantSnapStatus::RESTORING == items.at(i).get_status()) { + restore_job_num++; + } else if (ObTenantSnapStatus::FAILED == items.at(i).get_status()) { + // when a tenant snapshot is created failed, + // for the normal tenant snapshot, it will be setted as DELETING and be deleted directly; + // for the fork tenant snapshot, due to it is created in a step of clone job, it will be + // setted as FAILED and be deleted while the clone job has been recycled + } else if (ObTenantSnapStatus::NORMAL == items.at(i).get_status()) { + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tenant snapshot status", KR(ret), K(items)); + } + } + } + + if (OB_FAIL(ret)) { + } else if ((create_jobs.count() > 1) + || (create_jobs.count() + restore_job_num > 1)) { + //only one creation job/restoration job can exist at a time, num > 1 is illegal! + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected tenant snapshot count", KR(ret), K(create_jobs), K(restore_job_num)); + } + + return ret; +} + +int ObTenantSnapshotScheduler::build_tenant_snapshot_create_job_( + const ObTenantSnapItem &item, + const ObArbitrationServiceStatus &arbitration_service_status, + const int64_t paxos_replica_num, + const int64_t timeout, + ObCreateSnapshotJob &job) +{ + int ret = OB_SUCCESS; + job.reset(); + uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + ObTenantSnapJobItem job_item; + ObTenantSnapshotTableOperator table_op; + + if (OB_UNLIKELY(!item.is_valid() || !arbitration_service_status.is_valid() || + paxos_replica_num <= 0 || timeout < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(item), K(arbitration_service_status), + K(paxos_replica_num), K(timeout)); + } else if (OB_FAIL(table_op.init(user_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init table op", KR(ret)); + } else if (OB_FAIL(table_op.get_tenant_snap_job_item(item.get_tenant_snapshot_id(), + ObTenantSnapOperation::CREATE, + job_item))) { + LOG_WARN("fail to get tenant snapshot job item", KR(ret), K(item)); + } else if (OB_UNLIKELY(!job_item.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid job item", KR(ret), K(item), K(job_item)); + } else if (OB_FAIL(job.init(item.get_create_time(), + item.get_create_time() + timeout, + paxos_replica_num, arbitration_service_status, + job_item))) { + LOG_WARN("fail to init create snapshot job", KR(ret), K(item), K(paxos_replica_num), + K(arbitration_service_status), + K(job_item)); + } + + return ret; +} + +int ObTenantSnapshotScheduler::build_tenant_snapshot_delete_job_(const ObTenantSnapItem &item, + ObDeleteSnapshotJob &job) +{ + int ret = OB_SUCCESS; + job.reset(); + uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + ObTenantSnapJobItem job_item; + ObTenantSnapshotTableOperator table_op; + + if (OB_UNLIKELY(!item.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(item)); + } else if (OB_FAIL(table_op.init(user_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init table op", KR(ret)); + } else if (OB_FAIL(table_op.get_tenant_snap_job_item(item.get_tenant_snapshot_id(), + ObTenantSnapOperation::DELETE, + job_item))) { + LOG_WARN("fail to get tenant snapshot job item", KR(ret), K(item)); + } else if (OB_UNLIKELY(!job_item.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid job item", KR(ret), K(item), K(job_item)); + } else if (OB_FAIL(job.init(job_item))) { + LOG_WARN("fail to init delete snapshot job", KR(ret), K(item), K(job_item)); + } + + return ret; +} + +//************************************************************************* +//First, close ls Add/Remove tasks and transfer tasks +//************************************************************************* +//Then, generate snapshot ls items (extract ls info from other inner table) +//************************************************************************* +//Then, check whether transfer scn of each ls is consistent +//************************************************************************* +//Then, generate ls replica base info (extract from inner table) +//************************************************************************* +//Last, insert data into inner table:__all_tenant_snapshot_ls +//************************************************************************* +//Last, insert data into inner table:__all_tenant_snapshot_ls_replica +//************************************************************************* +int ObTenantSnapshotScheduler::prepare_for_create_tenant_snapshot_( + const ObCreateSnapshotJob &create_job) +{ + int ret = OB_SUCCESS; + uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + const ObTenantSnapshotID &tenant_snapshot_id = create_job.get_tenant_snapshot_id(); + const int64_t paxos_replica_num = create_job.get_paxos_replica_num(); + ObTenantSnapshotTableOperator first_table_op; + ObTenantSnapLSItem snap_ls_item; + ObArray snap_ls_items; + ObArray ls_replica_items; + + if (OB_UNLIKELY(!create_job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(create_job)); + } else if (OB_FAIL(first_table_op.init(user_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init table op", KR(ret), K(user_tenant_id)); + } else if (OB_SUCC(first_table_op.get_tenant_snap_ls_item(tenant_snapshot_id, SYS_LS, snap_ls_item))) { + //do nothing + } else if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("failed to get snapshot sys ls item", KR(ret), K(tenant_snapshot_id)); + } else { + ret = OB_SUCCESS; + if (OB_FAIL(generate_snap_ls_items_(tenant_snapshot_id, user_tenant_id, snap_ls_items))) { + LOG_WARN("generate snap ls items failed", KR(ret), K(tenant_snapshot_id), K(user_tenant_id)); + } else if (OB_FAIL(generate_snap_ls_replica_base_info_(tenant_snapshot_id, user_tenant_id, + snap_ls_items, paxos_replica_num, ls_replica_items))) { + LOG_WARN("generate snap ls replica base items failed", KR(ret), K(tenant_snapshot_id), K(user_tenant_id), + K(snap_ls_items), K(paxos_replica_num)); + } else { + ObTenantSnapshotTableOperator second_table_op; + ObMySQLTransaction trans; + if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(user_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(second_table_op.init(user_tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(second_table_op.insert_tenant_snap_ls_items(snap_ls_items))) { + LOG_WARN("failed to insert snapshot ls items", KR(ret), K(snap_ls_items)); + } else if (OB_FAIL(second_table_op.insert_tenant_snap_ls_replica_simple_items(ls_replica_items))) { + LOG_WARN("failed to insert snapshot ls replica simple items", KR(ret), K(ls_replica_items)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + } + } + + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + // if create_job is not valid, we should not delete the tenant snapshot + // because we don't know whether the tenant_snapshot_id the create_job contains is valid + if (!create_job.is_valid()) { + tmp_ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(tmp_ret), K(create_job)); + } else if (OB_TMP_FAIL(create_tenant_snapshot_fail_(create_job))) { + LOG_WARN("failed to execute create_tenant_snapshot_fail_", KR(tmp_ret), + K(tenant_snapshot_id), K(user_tenant_id)); + } + } + + return ret; +} + +//TODO: whether "create_abort" ls need to be added. +int ObTenantSnapshotScheduler::generate_snap_ls_items_( + const ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + ObArray &snap_ls_items) +{ + int ret = OB_SUCCESS; + snap_ls_items.reset(); + ObLSAttrArray ls_attr_array; + + if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() || !is_user_tenant(user_tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(user_tenant_id)); + } else { + share::ObLSAttrOperator ls_attr_operator(user_tenant_id, sql_proxy_); + if (OB_FAIL(ls_attr_operator.get_all_ls_by_order(ls_attr_array))) { + LOG_WARN("fail to get all ls", KR(ret), K(user_tenant_id)); + } else { + ARRAY_FOREACH_N(ls_attr_array, i, cnt) { + const ObLSAttr &ls_attr = ls_attr_array.at(i); + ObTenantSnapLSItem snap_ls_item; + if (OB_FAIL(snap_ls_item.init(user_tenant_id, tenant_snapshot_id, ls_attr))) { + LOG_WARN("failed to init snap_ls_item", KR(ret), K(user_tenant_id), + K(tenant_snapshot_id), K(ls_attr)); + } else if (OB_FAIL(snap_ls_items.push_back(snap_ls_item))) { + LOG_WARN("failed to push back", KR(ret), K(snap_ls_item)); + } + } + } + } + return ret; +} + +int ObTenantSnapshotScheduler::generate_snap_ls_replica_base_info_( + const ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + const ObArray &snap_ls_items, + const int64_t paxos_replica_num, + ObArray &ls_replica_items) +{ + int ret = OB_SUCCESS; + ls_replica_items.reset(); + ObArray tenant_ls_infos; + + if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !is_user_tenant(user_tenant_id) + || snap_ls_items.empty()) + || OB_INVALID_COUNT == paxos_replica_num + || OB_ISNULL(GCTX.lst_operator_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(user_tenant_id), + K(snap_ls_items), K(paxos_replica_num), KP(GCTX.lst_operator_)); + } else if (OB_FAIL(GCTX.lst_operator_->get_by_tenant(user_tenant_id, false, tenant_ls_infos))) { + LOG_WARN("fail to execute get_by_tenant", KR(ret), K(user_tenant_id)); + } else { + ObTenantSnapLSReplicaSimpleItem item; + ObArray valid_replicas; + ARRAY_FOREACH_N(snap_ls_items, i, cnt) { + const ObLSID &ls_id = snap_ls_items.at(i).get_ls_attr().get_ls_id(); + if (OB_FAIL(get_ls_valid_replicas_(ls_id, tenant_ls_infos, valid_replicas))) { + LOG_WARN("fail to get ls valid replicas", KR(ret), K(ls_id), K(tenant_ls_infos)); + } else if (rootserver::majority(paxos_replica_num) > valid_replicas.count()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("ls valid replica num is not satisfied", KR(ret), K(paxos_replica_num), K(valid_replicas), + K(ls_id), K(tenant_ls_infos)); + } else { + ARRAY_FOREACH_N(valid_replicas, j, cnt) { + item.reset(); + const ObLSReplica *replica = valid_replicas.at(j); + if (OB_ISNULL(replica)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected replica ptr", KR(ret), KP(replica)); + } else if (OB_UNLIKELY(!replica->is_valid() + || !replica->get_server().is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("replica is not valid", KR(ret), KPC(replica)); + } else if (OB_FAIL(item.init(user_tenant_id, tenant_snapshot_id, ls_id, + replica->get_server(), + ObLSSnapStatus::CREATING /*status*/, + replica->get_zone(), + replica->get_unit_id(), + SCN::invalid_scn() /*begin_interval_scn*/, + SCN::invalid_scn() /*end_interval_scn*/))) { + LOG_WARN("fail to init item", KR(ret), K(user_tenant_id), K(tenant_snapshot_id), + K(ls_id), KPC(replica)); + } else if (OB_FAIL(ls_replica_items.push_back(item))) { + LOG_WARN("fail to push back", KR(ret), K(item)); + } + } + } + } + } + return ret; +} + +int ObTenantSnapshotScheduler::get_ls_valid_replicas_( + const ObLSID &ls_id, + const ObArray &tenant_ls_infos, + ObArray &valid_replicas) +{ + int ret = OB_SUCCESS; + valid_replicas.reset(); + bool find_ls = false; + + if (OB_UNLIKELY(!ls_id.is_valid() + || tenant_ls_infos.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_id), K(tenant_ls_infos)); + } else { + ARRAY_FOREACH_N(tenant_ls_infos, i, cnt) { + const ObLSInfo &ls_info = tenant_ls_infos.at(i); + if (ls_id == ls_info.get_ls_id()) { + find_ls = true; + const ObIArray &replicas = ls_info.get_replicas(); + ARRAY_FOREACH_N(replicas, j, cnt) { + const ObLSReplica &replica = replicas.at(j); + if (replica.get_replica_type() == REPLICA_TYPE_FULL + && replica.get_replica_status() == REPLICA_STATUS_NORMAL) { + if (OB_FAIL(valid_replicas.push_back(&replica))) { + LOG_WARN("fail to push back", KR(ret), K(replica), KP(&replica)); + } + } + } + break; + } + } + if (OB_SUCC(ret)) { + if (!find_ls) { + ret = OB_LS_NOT_EXIST; + LOG_WARN("fail to find ls in tenant_ls_infos", KR(ret), K(ls_id), K(tenant_ls_infos)); + } + } + } + + return ret; +} + +int ObTenantSnapshotScheduler::process_create_tenant_snapshot_( + const ObCreateSnapshotJob &create_job) +{ + int ret = OB_SUCCESS; + ObUnitTableOperator unit_operator; + common::ObArray units; + ObArray addr_array; + uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + const ObTenantSnapshotID &tenant_snapshot_id = create_job.get_tenant_snapshot_id(); + int64_t cur_time = ObTimeUtility::current_time(); + + if (OB_UNLIKELY(!create_job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(create_job)); + } else if (cur_time > create_job.get_create_expire_ts()) { + ret = OB_TIMEOUT; + LOG_WARN("create tenant snapshot timeout", KR(ret), K(create_job), K(cur_time)); + } else if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null sql proxy", KR(ret)); + } else if (OB_FAIL(unit_operator.init(*sql_proxy_))) { + LOG_WARN("failed to init unit operator", KR(ret)); + } else if (OB_FAIL(unit_operator.get_units_by_tenant(user_tenant_id, units))) { + LOG_WARN("failed to get tenant unit", KR(ret), K(user_tenant_id)); + } else { + ARRAY_FOREACH_N(units, i, cnt) { + const ObUnit &unit = units.at(i); + if (OB_FAIL(addr_array.push_back(unit.server_))) { + LOG_WARN("failed to push back addr", KR(ret), K(unit.server_)); + } + } + } + + if (OB_SUCC(ret)) { + SCN clog_start_scn = SCN::invalid_scn(); + SCN snapshot_scn = SCN::invalid_scn(); + bool need_wait_archive_finish = false; + bool need_wait_minority = false; + + if (OB_FAIL(send_create_tenant_snapshot_rpc_(tenant_snapshot_id, user_tenant_id, addr_array))) { + LOG_WARN("failed to send create snapshot rpc", KR(ret), K(tenant_snapshot_id), + K(user_tenant_id), K(addr_array)); + } else if (OB_FAIL(check_create_tenant_snapshot_result_(create_job, clog_start_scn, snapshot_scn, + need_wait_minority))) { + LOG_WARN("the result does not meet the requirements or other errors", KR(ret), K(create_job)); + } else if (need_wait_minority) { + LOG_INFO("wait for minority to create snapshot", K(create_job)); + } else if (OB_FAIL(send_flush_ls_archive_rpc_(user_tenant_id, addr_array))) { + LOG_WARN("fail to send ls flush rpc", KR(ret), K(user_tenant_id), K(addr_array)); + } else if (OB_FAIL(check_log_archive_finish_(user_tenant_id, snapshot_scn, need_wait_archive_finish))) { + LOG_WARN("failed to execute check_log_archive_finish", KR(ret), K(user_tenant_id), K(snapshot_scn)); + } else if (need_wait_archive_finish) { + } else if (OB_FAIL(finish_create_tenant_snapshot_(tenant_snapshot_id, user_tenant_id, + clog_start_scn, snapshot_scn))) { + LOG_WARN("failed to execute finish_create_tenant_snapshot", KR(ret), K(tenant_snapshot_id), + K(user_tenant_id), K(clog_start_scn), + K(snapshot_scn)); + } + } + + if (OB_FAIL(ret) && OB_REPLICA_NUM_NOT_ENOUGH != ret) { + int tmp_ret = OB_SUCCESS; + // if create_job is not valid, we should not delete the tenant snapshot + // because we don't know whether the tenant_snapshot_id it contains is valid + if (OB_UNLIKELY(!create_job.is_valid())) { + tmp_ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(tmp_ret), K(create_job)); + } else if (OB_TMP_FAIL(create_tenant_snapshot_fail_(create_job))) { + LOG_WARN("failed to execute create_tenant_snapshot_fail_", KR(tmp_ret), + K(tenant_snapshot_id), K(user_tenant_id)); + } + } + + return ret; +} + +int ObTenantSnapshotScheduler::send_create_tenant_snapshot_rpc_( + const ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + const ObArray &addr_array) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + + ObArray return_code_array; + obrpc::ObInnerCreateTenantSnapshotArg arg; + int64_t timeout = max(GCONF.rpc_timeout, DEFAULT_TIMEOUT); + + if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !is_user_tenant(user_tenant_id) + || addr_array.empty()) + || OB_ISNULL(GCTX.srv_rpc_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(user_tenant_id), + K(addr_array), KP(GCTX.srv_rpc_proxy_)); + } else { + arg.set_tenant_snapshot_id(tenant_snapshot_id); + arg.set_tenant_id(user_tenant_id); + rootserver::ObTenantSnapshotCreatorProxy create_snapshot_proxy(*GCTX.srv_rpc_proxy_, + &obrpc::ObSrvRpcProxy::inner_create_tenant_snapshot); + //traverse addr_array to send RPC + ARRAY_FOREACH_N(addr_array, i, cnt) { + const ObAddr &addr = addr_array.at(i); + if (OB_TMP_FAIL(create_snapshot_proxy.call(addr, timeout, + GCONF.cluster_id, user_tenant_id, arg))) { + LOG_WARN("failed to call async rpc", KR(tmp_ret), K(addr), K(user_tenant_id), K(arg)); + } + } + + if (OB_TMP_FAIL(create_snapshot_proxy.wait_all(return_code_array))) { + LOG_WARN("wait batch result failed", KR(tmp_ret), KR(ret)); + } else { + //if (return_code_array.count() != create_snapshot_proxy.get_dests().count() + // || return_code_array.count() != create_snapshot_proxy.get_args().count() + // || return_code_array.count() != create_snapshot_proxy.get_results().count()) { + // ret = OB_ERR_UNEXPECTED; + // LOG_WARN("count not match", KR(ret), K(return_code_array), K(create_snapshot_proxy.get_dests()), + // K(create_snapshot_proxy.get_args()), K(create_snapshot_proxy.get_results())); + //} else { + // ARRAY_FOREACH_N(return_code_array, i, cnt) { + // int res_ret = return_code_array.at(i); + // const ObAddr &addr = create_snapshot_proxy.get_dests().at(i); + // if (OB_SUCCESS != res_ret) { + // LOG_WARN("rpc execute failed", KR(res_ret), K(addr)); + // } + // } + //} + } + } + return ret; +} + +// Check whether the num of created snapshots (for each ls) meets the majority. +// TODO This function needs to be split into multiple functions +int ObTenantSnapshotScheduler::check_create_tenant_snapshot_result_( + const ObCreateSnapshotJob &create_job, + SCN &clog_start_scn, + SCN &snapshot_scn, + bool &need_wait_minority) +{ + int ret = OB_SUCCESS; + clog_start_scn.reset(); + snapshot_scn.reset(); + need_wait_minority = false; + uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + ObTenantSnapshotTableOperator table_op; + ObArray snap_ls_items; + // FIXME: create_job's member functions should not be called before make sure the create_job is valid; + const ObTenantSnapshotID &tenant_snapshot_id = create_job.get_tenant_snapshot_id(); + int64_t paxos_replica_num = create_job.get_paxos_replica_num(); + const ObArbitrationServiceStatus &arbitration_service_status = create_job.get_arbitration_service_status(); + SCN tmp_clog_start_scn = SCN::max_scn(); + SCN tmp_snapshot_scn = SCN::min_scn(); + ObArray failed_addrs; + ObArray processing_addrs; + ObTenantArchiveRoundAttr round_attr; + const int64_t fake_incarnation = 1; + ObTenantSnapItem tenant_snap_item; + ObMySQLTransaction trans; + + if (OB_UNLIKELY(!create_job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(create_job)); + } else if (paxos_replica_num <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected paxos_replica_num", KR(ret), K(paxos_replica_num)); + // TODO: Whether to use arbitration service is pending. + } else if (arbitration_service_status.is_enable_like()) { + if (paxos_replica_num != 2 && paxos_replica_num != 4) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("locality must be 2F or 4F", KR(ret), K(paxos_replica_num)); + } else { + paxos_replica_num++; + } + } + + if (FAILEDx(trans.start(sql_proxy_, gen_meta_tenant_id(user_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(gen_meta_tenant_id(user_tenant_id))); + } else if (OB_FAIL(table_op.init(user_tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(user_tenant_id)); + // We need to decide snapshot_scn and clog_start_scn while locking tenant_snapshot_item; + // because after locking tenant_snapshot_item, the storage node can no longer report it; + // therefore, the snapshot scn we finally determined will be correct; + } else if (OB_FAIL(table_op.get_tenant_snap_item(tenant_snapshot_id, true /*lock*/, tenant_snap_item))) { + LOG_WARN("fail to get_tenant_snap_item", KR(ret), K(tenant_snapshot_id)); + } else if (ObTenantSnapStatus::DECIDED == tenant_snap_item.get_status()) { + clog_start_scn = tenant_snap_item.get_clog_start_scn(); + snapshot_scn = tenant_snap_item.get_snapshot_scn(); + need_wait_minority = false; + } else if (OB_FAIL(table_op.get_tenant_snap_ls_items(tenant_snapshot_id, snap_ls_items))) { + LOG_WARN("failed to get tenant snapshot ls items", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(ObTenantArchiveMgr::get_tenant_current_round(user_tenant_id, fake_incarnation, round_attr))) { + LOG_WARN("failed to get cur log archive round", KR(ret), K(user_tenant_id)); + } else { + ARRAY_FOREACH_N(snap_ls_items, i, cnt) { + int32_t succ_member = 0; + failed_addrs.reset(); + processing_addrs.reset(); + const ObLSID &ls_id = snap_ls_items.at(i).get_ls_attr().get_ls_id(); + ObArray simple_items; + if (OB_FAIL(table_op.get_tenant_snap_ls_replica_simple_items(tenant_snapshot_id, ls_id, simple_items))) { + LOG_WARN("failed to get snapshot ls replica items by ls", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else { + ARRAY_FOREACH_N(simple_items, j, cnt) { + //for each ls, check whether status of each replica is "normal" + //Note: "normal" means snapshot has been created successfully + const ObTenantSnapLSReplicaSimpleItem &item = simple_items.at(j); + if (ObLSSnapStatus::NORMAL == item.get_status()) { + if (!item.get_begin_interval_scn().is_valid() || !item.get_end_interval_scn().is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("scn is not valid", KR(ret), K(item)); + } else if (item.get_begin_interval_scn() < round_attr.start_scn_) { + LOG_INFO("checkpoint scn of the ls replica is smaller than archive scn", K(item), K(round_attr)); + ObTenantSnapLSReplicaSimpleItem new_item; + + if (OB_FAIL(new_item.assign(item))) { + LOG_WARN("fail to assign", KR(ret), K(item)); + } else if (FALSE_IT(new_item.set_status(ObLSSnapStatus::FAILED))) { + } else if (OB_FAIL(table_op.update_tenant_snap_ls_replica_item(new_item, nullptr))) { + LOG_WARN("fail to update tenant snapshot ls replica item", KR(ret), K(new_item)); + } else if (OB_FAIL(failed_addrs.push_back(item.get_addr()))) { + LOG_WARN("push back failed", KR(ret), K(item.get_addr())); + } + } else { // item.get_begin_interval_scn() >= round_attr.start_scn_ + //clog_start_scn is the minimum value among all the begin_interval_scn + if (item.get_begin_interval_scn() < tmp_clog_start_scn) { + tmp_clog_start_scn = item.get_begin_interval_scn(); + } + //snapshot_scn is the maximum value among all the end_interval_scn + if (item.get_end_interval_scn() > tmp_snapshot_scn) { + tmp_snapshot_scn = item.get_end_interval_scn(); + } + succ_member++; + } + } else if (ObLSSnapStatus::FAILED == item.get_status()) { + if (OB_FAIL(failed_addrs.push_back(item.get_addr()))) { + LOG_WARN("push back failed", KR(ret), K(item.get_addr())); + } + } else if (ObLSSnapStatus::CREATING == item.get_status()) { + if (OB_FAIL(processing_addrs.push_back(item.get_addr()))) { + LOG_WARN("push back failed", KR(ret), K(item.get_addr())); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tenant snapshot status", KR(ret), K(item)); + } + } + } + if (OB_SUCC(ret)) { + int32_t failed_member = failed_addrs.count(); + int32_t creating_member = processing_addrs.count(); + if (arbitration_service_status.is_enable_like()) { + succ_member++; + } + // attention: + // in normal case, creating_member + succ_member + failed_member == paxos_replica_num + // in transfer case, it might happened that creating_member + succ_member + failed_member > paxos_replica_num + if (rootserver::majority(paxos_replica_num) > creating_member + succ_member) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("no possible to reach the majority", KR(ret), K(ls_id), + K(paxos_replica_num), K(succ_member), + K(creating_member), K(failed_member), + K(processing_addrs), K(failed_addrs)); + } else if (rootserver::majority(paxos_replica_num) > succ_member) { + ret = OB_REPLICA_NUM_NOT_ENOUGH; + LOG_WARN("success count less than majority, creating is in progress", KR(ret), + K(paxos_replica_num), K(succ_member), K(ls_id), K(processing_addrs), K(failed_addrs)); + } else if (paxos_replica_num > succ_member && creating_member > 0) { + need_wait_minority = true; + LOG_INFO("the tenant snapshot has reached majority " + "but some replicas are still creating snapshot", K(ls_id), + K(paxos_replica_num), K(succ_member), + K(creating_member), K(failed_member), + K(processing_addrs), K(failed_addrs)); + } + } + } // end for + } + + bool whether_to_commit_trans = false; + if (OB_SUCC(ret) && ObTenantSnapStatus::CREATING == tenant_snap_item.get_status()) { // majority snapshot has created successful + if (need_wait_minority) { + // considering the performance of tenant cloning is affected by the missing of snapshots, + // we will wait a small interval as long as possible to make all ls replicas create snapshots successful. + check_need_wait_minority_create_snapshot_(create_job, need_wait_minority); + } + if (!need_wait_minority) { + clog_start_scn = tmp_clog_start_scn; + snapshot_scn = tmp_snapshot_scn; + + SCN gts_scn; + // TODO: Currently, how to get the maximum scn in ObLSMetaPackage has not yet been solved; + // The end_interval_scn reported by the storage node may be smaller than the actual + // required; We rely on gts when local snapshots are created to determine snapshot scn; + if (OB_FAIL(OB_TS_MGR.get_ts_sync(user_tenant_id, GCONF.rpc_timeout, gts_scn))) { + LOG_WARN("fail to get gts sync", KR(ret), K(user_tenant_id)); + } else if (FALSE_IT(snapshot_scn = MAX(snapshot_scn, gts_scn))) { + } else if (OB_FAIL(table_op.update_tenant_snap_item(tenant_snapshot_id, + ObTenantSnapStatus::CREATING, + ObTenantSnapStatus::DECIDED, + snapshot_scn, + clog_start_scn))) { + LOG_WARN("fail to update snapshot status and interval scn", + KR(ret), K(user_tenant_id), K(tenant_snapshot_id), K(clog_start_scn), K(snapshot_scn)); + } else { + whether_to_commit_trans = true; + } + } + LOG_INFO("results meet the requirement", + KR(ret), K(create_job), K(clog_start_scn), K(snapshot_scn), + K(need_wait_minority), K(whether_to_commit_trans)); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(whether_to_commit_trans))) { + LOG_WARN("trans end failed", "is_commit", whether_to_commit_trans, KR(ret), KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + return ret; +} + +void ObTenantSnapshotScheduler::check_need_wait_minority_create_snapshot_( + const ObCreateSnapshotJob &create_job, + bool &need_wait_minority) +{ + int ret = OB_SUCCESS; + uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + SCN gts; + const int64_t current_time = ObTimeUtility::current_time(); + need_wait_minority = false; + + if (OB_UNLIKELY(!create_job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid create job", KR(ret), K(create_job)); + } else if (create_job.get_majority_succ_time() == OB_INVALID_TIMESTAMP) { + ObTenantSnapshotTableOperator table_op; + if (OB_FAIL(table_op.init(user_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init table op", KR(ret)); + } else if (OB_FAIL(table_op.update_tenant_snap_job_majority_succ_time( + create_job.get_tenant_snapshot_id(), + current_time))) { + LOG_WARN("fail to update snapshot majority succ time", KR(ret), K(create_job), K(current_time)); + } else { + need_wait_minority = true; + } + } else { // create_job.get_majority_succ_time() != OB_INVALID_TIMESTAMP + if (OB_UNLIKELY(current_time < create_job.get_majority_succ_time())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid majority succ time", KR(ret), K(create_job)); + } else if (current_time - create_job.get_majority_succ_time() < WAIT_MINORITY_CREATE_SNAPSHOT_TIME) { + need_wait_minority = true; + } + } +} + +int ObTenantSnapshotScheduler::send_flush_ls_archive_rpc_(const uint64_t user_tenant_id, + const ObArray &addr_array) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObArray return_code_array; + obrpc::ObFlushLSArchiveArg arg; + arg.tenant_id_ = user_tenant_id; + int64_t timeout = max(GCONF.rpc_timeout, DEFAULT_TIMEOUT); + rootserver::ObFlushLSArchiveProxy flush_ls_archive(*GCTX.srv_rpc_proxy_, + &obrpc::ObSrvRpcProxy::flush_ls_archive); + return_code_array.reset(); + + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == user_tenant_id || addr_array.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(user_tenant_id), K(addr_array)); + } else { + // traverse addr_array to send RPC + ARRAY_FOREACH_N(addr_array, i, cnt) { + const ObAddr &addr = addr_array.at(i); + if (OB_TMP_FAIL(flush_ls_archive.call(addr, timeout, + GCONF.cluster_id, user_tenant_id, arg))) { + LOG_WARN("failed to call async rpc", KR(tmp_ret), K(addr), K(arg), K(user_tenant_id)); + } + } + + //wait + if (OB_TMP_FAIL(flush_ls_archive.wait_all(return_code_array))) { + LOG_WARN("wait batch result failed", KR(tmp_ret), KR(ret)); + } + + // if (OB_SUCC(ret)) { + // if (return_code_array.count() != flush_ls_archive.get_dests().count()) { + // ret = OB_ERR_UNEXPECTED; + // LOG_WARN("count not match", KR(ret), K(return_code_array), K(flush_ls_archive.get_dests())); + // } else { + // ARRAY_FOREACH_N(return_code_array, i, cnt) { + // int res_ret = return_code_array.at(i); + // const ObAddr &addr = flush_ls_archive.get_dests().at(i); + // if (OB_SUCCESS != res_ret) { + // ret = res_ret; + // LOG_WARN("rpc execute failed", KR(ret), K(addr)); + // } + // } + // } + // } + } + + return ret; +} + +int ObTenantSnapshotScheduler::check_log_archive_finish_( + const uint64_t user_tenant_id, + const SCN &snapshot_scn, + bool &need_wait) +{ + int ret = OB_SUCCESS; + need_wait = false; + ObTenantArchiveRoundAttr round_attr; + int64_t fake_incarnation = 1; + if (OB_UNLIKELY(!is_user_tenant(user_tenant_id) || !snapshot_scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(user_tenant_id), K(snapshot_scn)); + } else if (OB_FAIL(ObTenantArchiveMgr::get_tenant_current_round(user_tenant_id, fake_incarnation, round_attr))) { + LOG_WARN("failed to get cur log archive round", KR(ret), K(user_tenant_id)); + } else if (round_attr.checkpoint_scn_ < snapshot_scn) { + need_wait = true; + LOG_WARN("need wait log archive checkpoint_scn exceed snapshot_scn", KR(ret), + K(round_attr.checkpoint_scn_), K(snapshot_scn)); + } else { + LOG_INFO("log archive finish", KR(ret), K(round_attr.checkpoint_scn_), K(snapshot_scn)); + } + return ret; +} + +int ObTenantSnapshotScheduler::finish_create_tenant_snapshot_( + const share::ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + const SCN &clog_start_scn, + const SCN &snapshot_scn) +{ + int ret = OB_SUCCESS; + ObMySQLTransaction trans; + ObTenantSnapshotTableOperator table_op; + ObTenantSnapItem item; + uint64_t data_version = 0; + ObTenantSnapItem global_lock; + + if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !is_user_tenant(user_tenant_id) + || !clog_start_scn.is_valid() + || !snapshot_scn.is_valid() + || OB_ISNULL(sql_proxy_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(user_tenant_id), + K(clog_start_scn), K(snapshot_scn), KP(sql_proxy_)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_and_get_data_version(user_tenant_id, data_version))) { + LOG_WARN("fail to check and get data version or tenant is in upgrading procedure", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(user_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(table_op.init(user_tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item(tenant_snapshot_id, false, item))) { + LOG_WARN("failed to get item", KR(ret), K(tenant_snapshot_id)); + } else if (item.get_data_version() != data_version) { + ret = OB_VERSION_NOT_MATCH; + LOG_WARN("data version are not match", KR(ret), K(item), K(data_version)); + } else if (OB_FAIL(table_op.update_tenant_snap_item(tenant_snapshot_id, + ObTenantSnapStatus::DECIDED, + ObTenantSnapStatus::NORMAL))) { + LOG_WARN("failed to update snapshot status", KR(ret), K(user_tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.delete_tenant_snap_job_item(tenant_snapshot_id))) { + LOG_WARN("failed to delete snapshot job item", KR(ret), K(user_tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item( + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), + true /*for update*/, + global_lock))) { + LOG_WARN("failed to get special tenant snapshot item", KR(ret), K(user_tenant_id)); + } else if (ObTenantSnapStatus::RESTORING == global_lock.get_status()) { + // For fork tenant (a job type of tenant cloning), the status of global_lock is set as RESTORING at beginning. + // in this case, the global_lock should be unlocked after cloning tenant is finished + } else if (OB_FAIL(ObTenantSnapshotUtil::unlock_tenant_snapshot_simulated_mutex_from_snapshot_task( + trans, + user_tenant_id, + ObTenantSnapStatus::CREATING, + snapshot_scn))) { + LOG_WARN("failed to unlock tenant snapshot simulated mutex", KR(ret), K(user_tenant_id), K(snapshot_scn)); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + if (OB_SUCC(ret)) { + LOG_INFO("create tenant snapshot finished", K(tenant_snapshot_id)); + } + return ret; +} + +int ObTenantSnapshotScheduler::create_tenant_snapshot_fail_(const ObCreateSnapshotJob& create_job) +{ + int ret = OB_SUCCESS; + ObMySQLTransaction trans; + ObTenantSnapshotTableOperator table_op; + ObTenantSnapItem global_lock; + + if (OB_UNLIKELY(!create_job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(create_job)); + } else { + const ObTenantSnapshotID &tenant_snapshot_id = create_job.get_tenant_snapshot_id(); + const uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + + if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(user_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(table_op.init(user_tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item( + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), + true /*for update*/, + global_lock))) { + LOG_WARN("failed to get special tenant snapshot item", KR(ret), K(user_tenant_id)); + } else { + if (ObTenantSnapStatus::RESTORING == global_lock.get_status()) { + // For fork tenant (a job type of tenant cloning), the status of global_lock is set as RESTORING at beginning. + // in this case, when creating snapshot failed, + // the snapshot and global_lock should only be released by clone job + if (OB_FAIL(table_op.update_tenant_snap_item(tenant_snapshot_id, + ObTenantSnapStatus::CREATING, + ObTenantSnapStatus::DECIDED, + ObTenantSnapStatus::FAILED))) { + LOG_WARN("failed to update snapshot status", KR(ret), K(user_tenant_id), K(tenant_snapshot_id)); + } + } else { + if (OB_FAIL(table_op.update_tenant_snap_item(tenant_snapshot_id, + ObTenantSnapStatus::CREATING, + ObTenantSnapStatus::DECIDED, + ObTenantSnapStatus::DELETING))) { + LOG_WARN("failed to update snapshot status", KR(ret), K(user_tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(ObTenantSnapshotUtil::recycle_tenant_snapshot_ls_replicas(trans, user_tenant_id, + tenant_snapshot_id))) { + LOG_WARN("fail to recycle tenant snapshot ls replicas", KR(ret), K(user_tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.delete_tenant_snap_job_item(tenant_snapshot_id))) { + LOG_WARN("failed to delete snapshot job item", KR(ret), K(user_tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.insert_tenant_snap_job_item( + ObTenantSnapJobItem(user_tenant_id, + tenant_snapshot_id, + ObTenantSnapOperation::DELETE, + create_job.get_trace_id())))) { + LOG_WARN("fail to insert tenant snapshot job item", KR(ret), K(create_job)); + } else if (OB_FAIL(ObTenantSnapshotUtil::unlock_tenant_snapshot_simulated_mutex_from_snapshot_task( + trans, user_tenant_id, ObTenantSnapStatus::CREATING, SCN::invalid_scn()))) { + LOG_WARN("failed to unlock tenant snapshot simulated mutex", KR(ret), K(user_tenant_id)); + } + } + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + } + + return ret; +} + +int ObTenantSnapshotScheduler::process_delete_tenant_snapshots_( + const ObArray &delete_jobs) +{ + int ret = OB_SUCCESS; + uint64_t user_tenant_id = gen_user_tenant_id(MTL_ID()); + ObTenantSnapshotTableOperator table_op; + ObArray addr_array; + + if (OB_UNLIKELY(delete_jobs.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(delete_jobs)); + } else if (OB_FAIL(table_op.init(user_tenant_id, sql_proxy_))) { + LOG_WARN("failed to init table op", KR(ret), K(user_tenant_id)); + } else { + ARRAY_FOREACH_N(delete_jobs, i, cnt) { + //process each tenant_snapshot + const ObDeleteSnapshotJob& delete_job = delete_jobs.at(i); + ObTraceIdGuard trace_guard(delete_job.get_trace_id()); + addr_array.reset(); + const ObTenantSnapshotID &tenant_snapshot_id = delete_job.get_tenant_snapshot_id(); + if (OB_FAIL(table_op.get_tenant_snap_related_addrs(tenant_snapshot_id, addr_array))) { + LOG_WARN("failed to get snapshot related addrs", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(send_delete_tenant_snapshot_rpc_(tenant_snapshot_id, user_tenant_id, addr_array))) { + LOG_WARN("failed to send delete snapshot rpc", KR(ret), K(tenant_snapshot_id), + K(user_tenant_id), K(addr_array)); + } + + int64_t cur_time = ObTimeUtility::current_time(); + if (cur_time > delete_job.get_job_start_time() + SNAPSHOT_DELETION_TIMEOUT) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(finish_delete_tenant_snapshot_(tenant_snapshot_id, user_tenant_id))) { + LOG_WARN("failed to execute finish_delete_tenant_snapshot_", KR(tmp_ret), + K(tenant_snapshot_id), K(user_tenant_id)); + } + } + } + } + + return ret; +} + +int ObTenantSnapshotScheduler::send_delete_tenant_snapshot_rpc_( + const ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + const ObArray &addr_array) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + + ObArray return_code_array; + obrpc::ObInnerDropTenantSnapshotArg arg; + int64_t timeout = max(GCONF.rpc_timeout, DEFAULT_TIMEOUT); + + if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !is_user_tenant(user_tenant_id) + || addr_array.empty()) + || OB_ISNULL(GCTX.srv_rpc_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(user_tenant_id), + K(addr_array), KP(GCTX.srv_rpc_proxy_)); + } else { + arg.set_tenant_snapshot_id(tenant_snapshot_id); + arg.set_tenant_id(user_tenant_id); + rootserver::ObTenantSnapshotDropperProxy delete_snapshot_proxy(*GCTX.srv_rpc_proxy_, + &obrpc::ObSrvRpcProxy::inner_drop_tenant_snapshot); + //traverse addr_array to send RPC + ARRAY_FOREACH_N(addr_array, i, cnt) { + const ObAddr &addr = addr_array.at(i); + if (OB_TMP_FAIL(delete_snapshot_proxy.call(addr, timeout, + GCONF.cluster_id, user_tenant_id, arg))) { + LOG_WARN("failed to call async rpc", KR(tmp_ret), K(addr), K(user_tenant_id), K(arg)); + } + } + + //wait + if (OB_TMP_FAIL(delete_snapshot_proxy.wait_all(return_code_array))) { + LOG_WARN("wait batch result failed", KR(tmp_ret), KR(ret)); + } else { + //if (return_code_array.count() != delete_snapshot_proxy.get_dests().count() + // || return_code_array.count() != delete_snapshot_proxy.get_args().count() + // || return_code_array.count() != delete_snapshot_proxy.get_results().count()) { + // ret = OB_ERR_UNEXPECTED; + // LOG_WARN("count not match", KR(ret), K(return_code_array), K(delete_snapshot_proxy.get_dests()), + // K(delete_snapshot_proxy.get_args()), K(delete_snapshot_proxy.get_results())); + //} else { + // ARRAY_FOREACH_N(return_code_array, i, cnt) { + // int res_ret = return_code_array.at(i); + // const ObAddr &addr = delete_snapshot_proxy.get_dests().at(i); + // if (OB_SUCCESS != res_ret) { + // LOG_WARN("rpc execute failed", KR(res_ret), K(addr)); + // } + // } + //} + } + } + + return ret; +} + +int ObTenantSnapshotScheduler::finish_delete_tenant_snapshot_( + const ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotTableOperator table_op; + ObMySQLTransaction trans; + + if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !is_user_tenant(user_tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(user_tenant_id)); + } else if (OB_FAIL(trans.start(sql_proxy_, gen_meta_tenant_id(user_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(table_op.init(user_tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(user_tenant_id)); + } else if (OB_FAIL(table_op.delete_tenant_snap_job_item(tenant_snapshot_id))) { + LOG_WARN("failed to delete snapshot job item", + KR(ret), K(user_tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.delete_tenant_snap_item(tenant_snapshot_id))) { + LOG_WARN("failed to delete snapshot item", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.delete_tenant_snap_ls_items(tenant_snapshot_id))) { + LOG_WARN("failed to delete snapshot ls item", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.delete_tenant_snap_ls_replica_items(tenant_snapshot_id))) { + LOG_WARN("failed to delete snapshot ls replica item", KR(ret), K(tenant_snapshot_id)); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + + if (OB_SUCC(ret)) { + LOG_INFO("delete tenant snapshot finished", K(tenant_snapshot_id)); + } + + return ret; +} + +} +} diff --git a/src/rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.h b/src/rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.h new file mode 100644 index 0000000000..f7006ff4e4 --- /dev/null +++ b/src/rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.h @@ -0,0 +1,121 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_ROOTSERVER_OB_TENANT_SNAPSHOT_SCHEDULER_H_ +#define OCEANBASE_ROOTSERVER_OB_TENANT_SNAPSHOT_SCHEDULER_H_ + +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "rootserver/ob_tenant_thread_helper.h" + +namespace oceanbase +{ +namespace rootserver +{ + +// scheduler tenant snapshot job, this include: +// 1: process snapshot creation job (send RPC to each related obs to process) +// 2: process snapshot deletion job (send RPC to each related obs to process) +// 3: check snapshot creation result of each related obs. +//Note: this thread does not care about deletion result of each related obs. +class ObTenantSnapshotScheduler : public ObTenantThreadHelper, + public logservice::ObICheckpointSubHandler, + public logservice::ObIReplaySubHandler +{ +public: + ObTenantSnapshotScheduler(); + virtual ~ObTenantSnapshotScheduler(); + int init(); + virtual void do_work() override; + void destroy(); + void wakeup(); + int idle(); + DEFINE_MTL_FUNC(ObTenantSnapshotScheduler) + +public: + virtual share::SCN get_rec_scn() override { return share::SCN::max_scn(); } + virtual int flush(share::SCN &scn) override { return OB_SUCCESS; } + int replay(const void *buffer, const int64_t nbytes, const palf::LSN &lsn, const share::SCN &scn) override + { + UNUSED(buffer); + UNUSED(nbytes); + UNUSED(lsn); + UNUSED(scn); + return OB_SUCCESS; + } + +private: + int get_tenant_snapshot_jobs_(ObArray &create_jobs, + ObArray &delete_jobs); + int build_tenant_snapshot_create_job_(const ObTenantSnapItem &item, + const ObArbitrationServiceStatus &arbitration_service_status, + const int64_t paxos_replica_num, + const int64_t timeout, + ObCreateSnapshotJob &job); + int build_tenant_snapshot_delete_job_(const ObTenantSnapItem &item, + ObDeleteSnapshotJob &job); + int prepare_for_create_tenant_snapshot_(const ObCreateSnapshotJob &create_job); + int wait_related_task_finished_(const uint64_t user_tenant_id); + int generate_snap_ls_items_(const ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + ObArray &snap_ls_items); + int generate_snap_ls_replica_base_info_(const ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + const ObArray &snap_ls_items, + const int64_t paxos_replica_num, + ObArray &ls_replica_items); + int get_ls_valid_replicas_(const ObLSID &ls_id, + const ObArray &tenant_ls_infos, + ObArray &valid_replicas); + int process_create_tenant_snapshot_(const ObCreateSnapshotJob &create_job); + int send_create_tenant_snapshot_rpc_(const share::ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + const ObArray &addr_array); + int check_create_tenant_snapshot_result_(const ObCreateSnapshotJob &create_job, + SCN &clog_start_scn, + SCN &snapshot_scn, + bool &need_wait_minority); + void check_need_wait_minority_create_snapshot_(const ObCreateSnapshotJob &create_job, + bool &need_wait_minority); + int send_flush_ls_archive_rpc_(const uint64_t user_tenant_id, + const ObArray &addr_array); + int check_log_archive_finish_(const uint64_t user_tenant_id, + const SCN &snapshot_scn, + bool &need_wait); + int finish_create_tenant_snapshot_(const share::ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + const SCN &clog_start_scn, + const SCN &snapshot_scn); + int create_tenant_snapshot_fail_(const ObCreateSnapshotJob& create_job); + int process_delete_tenant_snapshots_(const ObArray &delete_jobs); + int send_delete_tenant_snapshot_rpc_(const share::ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id, + const ObArray &addr_array); + int finish_delete_tenant_snapshot_(const share::ObTenantSnapshotID &tenant_snapshot_id, + const uint64_t user_tenant_id); +private: + static const int64_t DEFAULT_TIMEOUT = 10 * 1000 * 1000L; + static const int64_t DEFAULT_IDLE_TIME = 60 * 1000 * 1000L; + static const int64_t SNAPSHOT_CREATION_TIMEOUT = 300 * 1000 * 1000L; + static const int64_t SNAPSHOT_DELETION_TIMEOUT = 5 * 1000 * 1000L; + static const int64_t PROCESS_IDLE_TIME = 1 * 1000 * 1000L; + static const int64_t WAIT_MINORITY_CREATE_SNAPSHOT_TIME = 20 * 1000 * 1000; +private: + bool inited_; + common::ObMySQLProxy *sql_proxy_; + int64_t idle_time_us_; + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapshotScheduler); +}; +} +} + + +#endif // OCEANBASE_ROOTSERVER_OB_TENANT_SNAPSHOT_SCHEDULER_H_ diff --git a/src/rootserver/tenant_snapshot/ob_tenant_snapshot_util.cpp b/src/rootserver/tenant_snapshot/ob_tenant_snapshot_util.cpp new file mode 100644 index 0000000000..fedd750241 --- /dev/null +++ b/src/rootserver/tenant_snapshot/ob_tenant_snapshot_util.cpp @@ -0,0 +1,1804 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX RS + +#include "ob_tenant_snapshot_util.h" +#include "rootserver/ob_ls_service_helper.h" //ObTenantLSInfo +#include "share/backup/ob_tenant_archive_mgr.h" +#include "share/balance/ob_balance_job_table_operator.h" //ObBalanceJob +#include "share/location_cache/ob_location_service.h" +#include "share/ls/ob_ls_operator.h" //ObLSAttrOperator +#include "share/ob_global_stat_proxy.h" //ObGlobalStatProxy +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "storage/tx/ob_ts_mgr.h" +#include "storage/tablelock/ob_lock_utils.h" //ObInnerTableLockUtil +#include "storage/tablelock/ob_lock_inner_connection_util.h" // for ObInnerConnectionLockUtil +#include "observer/ob_inner_sql_connection.h" + +using namespace oceanbase::rootserver; +using namespace oceanbase::share; +using namespace oceanbase::transaction::tablelock; + +static const char* conflict_case_with_clone_strs[] = { + "UPGRADE", + "TRANSFER", + "MODIFY_RESOURCE_POOL", + "MODIFY_UNIT", + "MODIFY_LS", + "MODIFY_REPLICA", + "SWITCHOVER" +}; + +const char* ObConflictCaseWithClone::get_case_name_str() const +{ + STATIC_ASSERT(ARRAYSIZEOF(conflict_case_with_clone_strs) == (int64_t)MAX_CASE_NAME, + "conflict_case_with_clone_strs string array size mismatch enum ConflictCaseWithClone count"); + const char *str = NULL; + if (case_name_ > INVALID_CASE_NAME && case_name_ < MAX_CASE_NAME) { + str = conflict_case_with_clone_strs[static_cast(case_name_)]; + } else { + LOG_WARN_RET(OB_ERR_UNEXPECTED, "invalid ConflictCaseWithClone", K_(case_name)); + } + return str; +} + +int64_t ObConflictCaseWithClone::to_string(char *buf, const int64_t buf_len) const +{ + int64_t pos = 0; + J_OBJ_START(); + J_KV(K_(case_name)); + J_OBJ_END(); + return pos; +} + +const char* ObTenantSnapshotUtil::TENANT_SNAP_OP_PRINT_ARRAY[] = +{ + "create tenant snapshot", + "drop tenant snapshot", + "clone tenant", + "fork tenant", +}; + +const char* ObTenantSnapshotUtil::get_op_print_str(const TenantSnapshotOp &op) +{ + STATIC_ASSERT(ARRAYSIZEOF(TENANT_SNAP_OP_PRINT_ARRAY) == static_cast(TenantSnapshotOp::MAX), + "type string array size mismatch with enum tenant snapshot operation count"); + const char* str = ""; + if (op >= TenantSnapshotOp::CREATE_OP && op < TenantSnapshotOp::MAX) { + str = TENANT_SNAP_OP_PRINT_ARRAY[static_cast(op)]; + } else { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid tenant snapshot op", K(op)); + } + return str; +} + +int ObTenantSnapshotUtil::create_tenant_snapshot(const ObString &tenant_name, + const ObString &tenant_snapshot_name, + uint64_t &tenant_id, + ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + LOG_INFO("receive create tenant snapshot request", K(tenant_name), K(tenant_snapshot_name)); + tenant_id = OB_INVALID_TENANT_ID; + tenant_snapshot_id.reset(); + uint64_t source_tenant_id = OB_INVALID_TENANT_ID; + ObTenantSnapshotID tmp_tenant_snapshot_id; + ObSqlString new_snapshot_name; + + if (OB_UNLIKELY(tenant_name.empty() + || tenant_snapshot_name.length() > OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", KR(ret), K(tenant_name), K(tenant_snapshot_name)); + } else if (OB_FAIL(get_tenant_id(tenant_name, source_tenant_id))) { + LOG_WARN("get tenant id failed", KR(ret), K(tenant_name)); + } else if (!is_user_tenant(source_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("non-user tenant", KR(ret), K(source_tenant_id)); + LOG_USER_ERROR(OB_INVALID_ARGUMENT, "non-user tenant id"); + } else if (OB_FAIL(check_source_tenant_info(source_tenant_id, CREATE_OP))) { + LOG_WARN("check source tenant info failed", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(check_log_archive_ready(source_tenant_id, tenant_name))) { + LOG_WARN("check log archive ready failed", KR(ret), K(source_tenant_id)); + } else if (tenant_snapshot_name.empty() && + OB_FAIL(rootserver::ObTenantSnapshotUtil::generate_tenant_snapshot_name( + source_tenant_id, new_snapshot_name, false))) { + LOG_WARN("failed to generate new tenant snapshot name", KR(ret), K(source_tenant_id)); + } else if (!tenant_snapshot_name.empty() && + OB_FAIL(new_snapshot_name.assign(tenant_snapshot_name.ptr(), + tenant_snapshot_name.length()))) { + LOG_WARN("failed to assign", KR(ret), K(tenant_snapshot_name)); + } else if (OB_UNLIKELY(new_snapshot_name.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid snapshot name", KR(ret), K(new_snapshot_name)); + } else if (OB_FAIL(rootserver::ObTenantSnapshotUtil::generate_tenant_snapshot_id( + source_tenant_id, tmp_tenant_snapshot_id))) { + LOG_WARN("failed to generate snapshot id", KR(ret), K(source_tenant_id)); + } else if (!tmp_tenant_snapshot_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid snapshot id", KR(ret), K(tmp_tenant_snapshot_id)); + } else { + ObMySQLTransaction trans; + ObTenantSnapStatus original_global_state_status = ObTenantSnapStatus::MAX; + if (OB_FAIL(trans.start(GCTX.sql_proxy_, gen_meta_tenant_id(source_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(trylock_tenant_snapshot_simulated_mutex(trans, source_tenant_id, + TenantSnapshotOp::CREATE_OP, OB_INVALID_ID /*owner_job_id*/, + original_global_state_status))) { + if (OB_TENANT_SNAPSHOT_LOCK_CONFLICT != ret) { + LOG_WARN("trylock tenant snapshot simulated mutex failed", KR(ret), K(source_tenant_id)); + } else { + LOG_WARN("GLOBAL_STATE snapshot lock conflict", KR(ret), K(source_tenant_id), + K(original_global_state_status)); + LOG_USER_ERROR(OB_TENANT_SNAPSHOT_LOCK_CONFLICT, "there may be other tenant snapshot operation in progress"); + } + } else if (OB_FAIL(check_tenant_has_no_conflict_tasks(source_tenant_id))) { + LOG_WARN("fail to check tenant has conflict tasks", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(add_create_tenant_snapshot_task(trans, source_tenant_id, + new_snapshot_name.string(), + tmp_tenant_snapshot_id))) { + LOG_WARN("add create tenant snapshot task failed", KR(ret), K(source_tenant_id), + K(new_snapshot_name), + K(tmp_tenant_snapshot_id)); + } else { + tenant_id = source_tenant_id; + tenant_snapshot_id = tmp_tenant_snapshot_id; + } + + DEBUG_SYNC(AFTER_LOCK_SNAPSHOT_MUTEX); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", (OB_SUCCESS == ret), KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + } + + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(notify_scheduler(source_tenant_id))) { + LOG_WARN("notify tenant snapshot scheduler failed", KR(tmp_ret), K(source_tenant_id)); + } + } + return ret; +} + +// create tenant without global lock +int ObTenantSnapshotUtil::create_fork_tenant_snapshot(ObMySQLTransaction &trans, + const uint64_t target_tenant_id, + const ObString &target_tenant_name, + const ObString &tenant_snapshot_name, + const ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + LOG_INFO("receive create fork tenant snapshot request", K(target_tenant_id), K(tenant_snapshot_id), + K(tenant_snapshot_name)); + + if (!is_user_tenant(target_tenant_id) || target_tenant_name.empty() || + tenant_snapshot_name.empty() || !tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(target_tenant_id), K(target_tenant_name), + K(tenant_snapshot_name), K(tenant_snapshot_id)); + } else if (OB_FAIL(check_source_tenant_info(target_tenant_id, CREATE_OP))) { + LOG_WARN("check source tenant info failed", KR(ret), K(target_tenant_id)); + } else if (OB_FAIL(check_log_archive_ready(target_tenant_id, target_tenant_name))) { + LOG_WARN("check log archive ready failed", KR(ret), K(target_tenant_id), K(target_tenant_name)); + } else if (OB_FAIL(add_create_tenant_snapshot_task(trans, target_tenant_id, + tenant_snapshot_name, + tenant_snapshot_id))) { + LOG_WARN("add create tenant snapshot task failed", KR(ret), K(target_tenant_id), + K(tenant_snapshot_id), + K(tenant_snapshot_name)); + } + + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(notify_scheduler(target_tenant_id))) { + LOG_WARN("notify tenant snapshot scheduler failed", KR(tmp_ret), K(target_tenant_id)); + } + } + return ret; +} + +int ObTenantSnapshotUtil::drop_tenant_snapshot(const ObString &tenant_name, + const ObString &tenant_snapshot_name) +{ + int ret = OB_SUCCESS; + LOG_INFO("receive drop tenant snapshot request", K(tenant_name), K(tenant_snapshot_name)); + uint64_t target_tenant_id = OB_INVALID_TENANT_ID; + + if (OB_UNLIKELY(tenant_name.empty() || tenant_snapshot_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", KR(ret), K(tenant_name), K(tenant_snapshot_name)); + } else if (OB_FAIL(get_tenant_id(tenant_name, target_tenant_id))) { + LOG_WARN("get tenant id failed", KR(ret), K(tenant_name)); + } else if (!is_user_tenant(target_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("non-user tenant", KR(ret), K(target_tenant_id)); + LOG_USER_ERROR(OB_INVALID_ARGUMENT, "non-user tenant id"); + } else if (OB_FAIL(check_source_tenant_info(target_tenant_id, DROP_OP))) { + LOG_WARN("check source tenant info failed", KR(ret), K(target_tenant_id)); + } else { + ObMySQLTransaction trans; + if (OB_FAIL(trans.start(GCTX.sql_proxy_, gen_meta_tenant_id(target_tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(target_tenant_id)); + } else if (OB_FAIL(add_drop_tenant_snapshot_task(trans, target_tenant_id, tenant_snapshot_name))) { + LOG_WARN("add drop tenant snapshot task failed", KR(ret), K(target_tenant_id), K(tenant_snapshot_name)); + } else if (OB_FAIL(recycle_tenant_snapshot_ls_replicas(trans, target_tenant_id, tenant_snapshot_name))) { + LOG_WARN("fail to recycle tenant snapshot ls replicas", KR(ret), K(tenant_name), + K(target_tenant_id), + K(tenant_snapshot_name)); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", (OB_SUCCESS == ret), KR(tmp_ret)); + ret = (OB_SUCC(ret)) ? tmp_ret : ret; + } + } + } + + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(notify_scheduler(target_tenant_id))) { + LOG_WARN("notify tenant snapshot scheduler failed", KR(tmp_ret), K(target_tenant_id)); + } + } + + return ret; +} + +int ObTenantSnapshotUtil::get_tenant_id(const ObString &tenant_name, + uint64_t &tenant_id) +{ + int ret = OB_SUCCESS; + tenant_id = OB_INVALID_TENANT_ID; + share::schema::ObSchemaGetterGuard schema_guard; + const ObTenantSchema *tenant_schema = NULL; + + if (OB_UNLIKELY(tenant_name.empty())) { + ret = OB_INVALID_TENANT_NAME; + LOG_WARN("invalid tenant name", KR(ret), K(tenant_name)); + } else if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema service is null", KR(ret)); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( + OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_name, tenant_schema))) { + LOG_WARN("failed to get tenant info", KR(ret), K(tenant_name)); + } else if (NULL == tenant_schema) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret), K(tenant_name)); + } else { + tenant_id = tenant_schema->get_tenant_id(); + } + return ret; +} + +int ObTenantSnapshotUtil::check_source_tenant_info(const uint64_t tenant_id, + const TenantSnapshotOp op) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + bool status_satisfied = false; + bool compatibility_satisfied = false; + bool role_satisfied = false; + ObAllTenantInfo all_tenant_info; + ObSqlString print_str; + + if (OB_UNLIKELY(TenantSnapshotOp::MAX == op)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(op)); + } else if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("tenant snapshot operation for non-user-tenant is not allowed", KR(ret), K(tenant_id)); + if (TenantSnapshotOp::RESTORE_OP == op || TenantSnapshotOp::FORK_OP == op) { + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "clone non-user-tenant is"); + } else { + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "tenant snapshot operation for non-user-tenant is"); + } + } else if (OB_FAIL(check_tenant_status(tenant_id, status_satisfied))) { + LOG_WARN("check tenant status failed", KR(ret), K(tenant_id)); + } else if (!status_satisfied) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("tenant status is not valid", KR(ret), K(tenant_id), K(status_satisfied)); + if (OB_TMP_FAIL(print_str.assign_fmt("source tenant status is not valid, %s", get_op_print_str(op)))) { + LOG_WARN("assign failed", KR(tmp_ret), K(get_op_print_str(op))); + } else { + LOG_USER_ERROR(OB_OP_NOT_ALLOW, print_str.ptr()); + } + } else if (OB_FAIL(ObShareUtil::check_compat_version_for_clone_tenant(tenant_id, compatibility_satisfied))) { + LOG_WARN("check tenant compatibility failed", KR(ret), K(tenant_id)); + } else if (!compatibility_satisfied) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("tenant data version is below 4.3", KR(ret), K(tenant_id), K(compatibility_satisfied)); + if (OB_TMP_FAIL(print_str.assign_fmt("source tenant data version is below 4.3, %s", get_op_print_str(op)))) { + LOG_WARN("assign failed", KR(tmp_ret), K(get_op_print_str(op))); + } else { + LOG_USER_ERROR(OB_OP_NOT_ALLOW, print_str.ptr()); + } + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, GCTX.sql_proxy_, + false/*for_update*/, all_tenant_info))) { + LOG_WARN("failed to load tenant info", KR(ret), K(tenant_id)); + } else if (!all_tenant_info.is_primary()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("tenant is not primary tenant", KR(ret), K(tenant_id)); + if (OB_TMP_FAIL(print_str.assign_fmt("source tenant is not primary tenant, %s", get_op_print_str(op)))) { + LOG_WARN("assign failed", KR(tmp_ret), K(get_op_print_str(op))); + } else { + LOG_USER_ERROR(OB_OP_NOT_ALLOW, print_str.ptr()); + } + } + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_status(const uint64_t tenant_id, + bool &is_satisfied) +{ + int ret = OB_SUCCESS; + is_satisfied = false; + share::schema::ObSchemaGetterGuard schema_guard; + const ObSimpleTenantSchema *tenant_schema = NULL; + const ObSimpleTenantSchema *meta_tenant_schema = NULL; + uint64_t meta_tenant_id = OB_INVALID_TENANT_ID; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || OB_ISNULL(GCTX.schema_service_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), KP(GCTX.schema_service_)); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret), K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) { + LOG_WARN("fail to get tenant info", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant schema is null", KR(ret), K(tenant_id)); + } else if (!tenant_schema->is_normal()) { + } else if (tenant_schema->is_in_recyclebin()) { + } else if (FALSE_IT(meta_tenant_id = gen_meta_tenant_id(tenant_id))) { + } else if (OB_FAIL(schema_guard.get_tenant_info(meta_tenant_id, meta_tenant_schema))) { + LOG_WARN("fail to get tenant info", KR(ret), K(meta_tenant_id)); + } else if (OB_ISNULL(meta_tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("meta tenant schema is null", KR(ret), K(meta_tenant_id)); + } else if (!meta_tenant_schema->is_normal()) { + } else { + is_satisfied = true; + } + + return ret; +} + +int ObTenantSnapshotUtil::check_log_archive_ready(const uint64_t tenant_id, const ObString &tenant_name) +{ + int ret = OB_SUCCESS; + ObTenantArchiveRoundAttr round_attr; + int64_t fake_incarnation = 1; + + if (OB_INVALID_TENANT_ID == tenant_id || tenant_name.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_name)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret)); + } else if (OB_FAIL(ObTenantArchiveMgr::get_tenant_current_round(tenant_id, fake_incarnation, round_attr))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_OP_NOT_ALLOW; + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "log archive is not ready, create tenant snapshot"); + } else { + LOG_WARN("failed to get cur log archive round", KR(ret), K(tenant_id)); + } + } else if (ObArchiveRoundState::Status::DOING != round_attr.state_.status_) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("log archive is not ready", KR(ret), K(tenant_id)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "log archive is not ready, create tenant snapshot"); + } else { + SCN min_ls_ckpt_scn; + ObSqlString sql; + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = nullptr; + uint64_t min_ls_checkpoint_scn = 0; + if (OB_FAIL(sql.assign_fmt("SELECT MIN(checkpoint_scn) as min_ckpt_scn FROM %s " + "WHERE tenant_id = %ld", + OB_ALL_VIRTUAL_LS_INFO_TNAME, tenant_id))) { + LOG_WARN("assign sql failed", KR(ret)); + } else if (OB_FAIL(GCTX.sql_proxy_->read(res, tenant_id, sql.ptr()))) { + LOG_WARN("failed to execute sql", KR(ret), K(sql), K(tenant_id)); + } else if (nullptr == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret), K(sql)); + } else if (OB_FAIL(result->next())) { + LOG_WARN("fail to get next row", KR(ret), K(sql)); + } else { + EXTRACT_UINT_FIELD_MYSQL(*result, "min_ckpt_scn", min_ls_checkpoint_scn, uint64_t); + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(min_ls_ckpt_scn.convert_for_inner_table_field(min_ls_checkpoint_scn))) { + LOG_WARN("fail to convert scn", KR(ret), K(min_ls_checkpoint_scn)); + } + } + } + + if (OB_SUCC(ret) && min_ls_ckpt_scn < round_attr.start_scn_) { + ret = OB_ERR_TENANT_SNAPSHOT; + LOG_WARN("ls checkpoint scn is smaller than archive start scn", KR(ret), + K(round_attr.start_scn_), + K(min_ls_ckpt_scn)); + ObSqlString str; + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(str.assign_fmt("Current checkpoint scn is smaller than the start_scn of " + "archive log, creating tenant snapshot is not allowed. " + "You could execute 'ALTER SYSTEM MINOR FREEZE TENANT = %.*s' " + "to trigger a minor compaction for advancing the checkpoint " + "and then wait for a minute before executing again.", + tenant_name.length(), tenant_name.ptr()))) { + LOG_WARN("fail to append format", KR(tmp_ret), K(tenant_id)); + } else { + LOG_USER_ERROR(OB_ERR_TENANT_SNAPSHOT, str.string().length(), str.ptr()); + } + } + } + + return ret; +} + +//********************************************************************* +//We use the record (GLOBAL_STATE) in the inner table __all_tenant_snapshots +// to simulate a mutex for tenant snapshot. +//Note: drop tenant snapshot operation no need to trylock. +// special_item is the memory structure of GLOBAL_STATE. +//********************************************************************* +int ObTenantSnapshotUtil::trylock_tenant_snapshot_simulated_mutex(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const TenantSnapshotOp op, + const int64_t owner_job_id, + ObTenantSnapStatus &original_global_state_status) +{ + int ret = OB_SUCCESS; + original_global_state_status = ObTenantSnapStatus::MAX; + ObTenantSnapItem special_item; + bool lock_conflict = true; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) + || (CREATE_OP != op && RESTORE_OP != op && FORK_OP != op))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(op)); + } else if (OB_FAIL(check_tenant_snapshot_simulated_mutex_(trans, tenant_id, + special_item, lock_conflict))) { + LOG_WARN("check simulated mutex failed", KR(ret), K(tenant_id)); + } else if (FALSE_IT(original_global_state_status = special_item.get_status())) { + } else if (lock_conflict) { + if (0 < owner_job_id && special_item.get_owner_job_id() == owner_job_id) { + // has been locked by clone job + lock_conflict = false; + LOG_INFO("has been locked by one's own clone job before", KR(ret), K(tenant_id), + K(owner_job_id), K(special_item)); + } else { + ret = OB_TENANT_SNAPSHOT_LOCK_CONFLICT; + LOG_WARN("GLOBAL_STATE snapshot lock conflict", KR(ret), K(tenant_id)); + } + } else if (FALSE_IT(special_item.set_owner_job_id(owner_job_id))) { + } else if (OB_FAIL(lock_(trans, tenant_id, op, special_item))) { + LOG_WARN("lock_ failed", KR(ret), K(tenant_id), K(op), K(special_item)); + } + + return ret; +} + +int ObTenantSnapshotUtil::unlock_tenant_snapshot_simulated_mutex_from_clone_release_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const int64_t owner_job_id, + const ObTenantSnapStatus &old_status, + bool &is_already_unlocked) +{ + int ret = OB_SUCCESS; + const SCN snapshot_scn = SCN::invalid_scn(); + is_already_unlocked = false; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id)) || + OB_INVALID_ID == owner_job_id || + ObTenantSnapStatus::MAX == old_status) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(owner_job_id), K(tenant_id), K(old_status)); + } else if (OB_FAIL(unlock_(trans, tenant_id, owner_job_id, old_status, snapshot_scn, is_already_unlocked))) { + LOG_WARN("fail to unlock", KR(ret), K(tenant_id), K(owner_job_id), K(old_status), K(snapshot_scn)); + } else if (is_already_unlocked) { + // curent owner_job_id of global_lock is different from given id, + // which means the global_lock of current releasing job has been already unlocked. + // ret = OB_SUCCESS; + } + + return ret; +} + +int ObTenantSnapshotUtil::unlock_tenant_snapshot_simulated_mutex_from_snapshot_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObTenantSnapStatus &old_status, + const SCN &snapshot_scn) +{ + int ret = OB_SUCCESS; + const int64_t owner_job_id = OB_INVALID_ID; + bool is_conflicted_owner_job_id = true; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || ObTenantSnapStatus::MAX == old_status || + !snapshot_scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(old_status), K(snapshot_scn)); + } else if (OB_FAIL(unlock_(trans, tenant_id, owner_job_id, old_status, snapshot_scn, is_conflicted_owner_job_id))) { + LOG_WARN("fail to unlock", KR(ret), K(tenant_id), K(owner_job_id), K(old_status), K(snapshot_scn)); + } else if (is_conflicted_owner_job_id) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("job_id is different from owner_job_id of global lock", KR(ret), K(owner_job_id)); + } + + return ret; +} + +//********************************************************************* +//if the status of the record (GLOBAL_STATE) is "NORMAL", it means +// the simulated mutex is not locked, +// and we can lock it (change the status) later to prevent other tenant snapshot operations. +//or else, it means the simulated mutex is locked, +// and we can not do tenant snapshot operation. +//Note: At the beginning, if the record (GLOBAL_STATE) is not exist, We have to insert it. +//********************************************************************* +int ObTenantSnapshotUtil::check_tenant_snapshot_simulated_mutex_(ObMySQLTransaction &trans, + const uint64_t tenant_id, + ObTenantSnapItem &special_item, + bool &is_conflict) +{ + int ret = OB_SUCCESS; + special_item.reset(); + is_conflict = true; + ObTenantSnapshotTableOperator table_op; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + //get special item(GLOBAL_STATE) + } else if (OB_FAIL(table_op.init(tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item( + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), + true /*for update*/, + special_item))) { + if (OB_TENANT_SNAPSHOT_NOT_EXIST != ret) { + LOG_WARN("failed to get special tenant snapshot item", KR(ret), K(tenant_id)); + } else { + ret = OB_SUCCESS; + special_item.reset(); + ObTenantSnapItem tmp_special_item; + //insert special item(GLOBAL_STATE) + if (OB_FAIL(tmp_special_item.init(tenant_id, /*tenant_id*/ + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), /*snapshot_id*/ + ObTenantSnapshotTableOperator::GLOBAL_STATE_NAME, /*snapshot_name*/ + ObTenantSnapStatus::NORMAL, /*status*/ + SCN::invalid_scn(), /*snapshot_scn*/ + SCN::invalid_scn(), /*clog_start_scn*/ + ObTenantSnapType::AUTO, /*type*/ + OB_INVALID_TIMESTAMP, /*create_time*/ + 0, /*data_version*/ + OB_INVALID_ID /*owner_job_id*/))) { + LOG_WARN("failed to init special item", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_op.insert_tenant_snap_item(tmp_special_item))) { + LOG_WARN("failed to insert special snapshot item", KR(ret), K(tmp_special_item)); + if (OB_TENANT_SNAPSHOT_EXIST == ret) { + ret = OB_TENANT_SNAPSHOT_LOCK_CONFLICT; + } + //get special item(GLOBAL_STATE) + } else if (OB_FAIL(table_op.get_tenant_snap_item( + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), + true /*for update*/, + special_item))) { + LOG_WARN("failed to get special tenant snapshot item", KR(ret), K(tenant_id)); + } + } + } + + if (OB_SUCC(ret)) { + if (ObTenantSnapStatus::NORMAL == special_item.get_status()) { + is_conflict = false; + } + } + + return ret; +} + +int ObTenantSnapshotUtil::unlock_(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const int64_t owner_job_id, + const ObTenantSnapStatus &old_status, + const SCN &snapshot_scn, + bool &is_conflicted_owner_job_id) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotTableOperator table_op; + ObTenantSnapItem global_lock; + is_conflicted_owner_job_id = false; + + if (OB_FAIL(table_op.init(tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item( + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), + true /*for update*/, + global_lock))) { + LOG_WARN("fail to get global_lock", KR(ret), K(tenant_id)); + } else if (owner_job_id != global_lock.get_owner_job_id()) { + is_conflicted_owner_job_id = true; + LOG_INFO("job_id is different from owner_job_id of global lock", K(owner_job_id), K(global_lock)); + } else if (OB_FAIL(table_op.update_special_tenant_snap_item( + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), + old_status, /*old status*/ + ObTenantSnapStatus::NORMAL, /*new status*/ + OB_INVALID_ID, /*owner job id*/ + snapshot_scn))) { + LOG_WARN("update special tenant snapshot item failed", KR(ret)); + } + + return ret; +} + +//we can lock (change the status of GLOBAL_STATE) to prevent other tenant snapshot operations. +int ObTenantSnapshotUtil::lock_(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const TenantSnapshotOp op, + const ObTenantSnapItem &special_item) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotTableOperator table_op; + ObTenantSnapStatus new_status = ObTenantSnapStatus::MAX; + share::SCN gts_scn = SCN::invalid_scn(); + int64_t new_create_time = OB_INVALID_TIMESTAMP; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || !special_item.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(special_item)); + } else { + if (CREATE_OP == op || FORK_OP == op) { + new_create_time = ObTimeUtility::current_time(); + if (CREATE_OP == op) { + new_status = ObTenantSnapStatus::CREATING; + } else { // FORK_OP == op + new_status = ObTenantSnapStatus::RESTORING; + } + } else if (RESTORE_OP == op) { + new_status = ObTenantSnapStatus::RESTORING; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tenant snapshot operation", KR(ret), K(tenant_id), K(op)); + } + } + + if (FAILEDx(table_op.init(tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_op.update_special_tenant_snap_item( + special_item.get_tenant_snapshot_id(), + ObTenantSnapStatus::NORMAL, /*old status*/ + new_status, /*new status*/ + special_item.get_owner_job_id(), /*owner job id*/ + gts_scn, /*new snapshot scn*/ + new_create_time /*new create time*/ + ))) { + LOG_WARN("update special tenant snapshot item failed", KR(ret), + K(special_item), K(new_status)); + } + + return ret; +} + +int ObTenantSnapshotUtil::add_create_tenant_snapshot_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObString &snapshot_name, + const ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + uint64_t data_version = 0; + SCN gts_scn = SCN::invalid_scn(); + int64_t create_time = OB_INVALID_TIMESTAMP; + ObTenantSnapshotTableOperator table_op; + ObTenantSnapItem item; + common::ObCurTraceId::TraceId trace_id; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || snapshot_name.empty() + || snapshot_name.length() > OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH + || !tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(snapshot_name), K(tenant_snapshot_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(GCTX.sql_proxy_)); + } else if (OB_FAIL(check_and_get_data_version(tenant_id, data_version))) { + LOG_WARN("fail to check and get data version or tenant is in upgrading procedure", KR(ret), K(tenant_id)); + } else if (FALSE_IT(create_time = ObTimeUtility::current_time())) { + } else if (OB_FAIL(item.init(tenant_id, /*tenant_id*/ + tenant_snapshot_id, /*snapshot_id*/ + snapshot_name, /*snapshot_name*/ + ObTenantSnapStatus::CREATING, /*status*/ + SCN::invalid_scn(), /*snapshot_scn*/ + SCN::invalid_scn(), /*clog_start_scn*/ + ObTenantSnapType::MANUAL, /*type*/ + create_time, /*create_time*/ + data_version, /*data_version*/ + OB_INVALID_ID /*owner_job_id*/))) { + LOG_WARN("failed to init item", KR(ret), K(tenant_id), K(tenant_snapshot_id), + K(snapshot_name), K(create_time), K(data_version)); + } else if (OB_FAIL(table_op.init(tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_op.insert_tenant_snap_item(item))) { + LOG_WARN("failed to insert snapshot item", KR(ret), K(item)); + } else { + ObCurTraceId::TraceId *cur_trace_id = ObCurTraceId::get_trace_id(); + if (nullptr != cur_trace_id) { + trace_id = *cur_trace_id; + } else { + trace_id.init(GCONF.self_addr_); + } + ObTenantSnapJobItem job_item(tenant_id, + tenant_snapshot_id, + ObTenantSnapOperation::CREATE, + trace_id); + if (OB_FAIL(table_op.insert_tenant_snap_job_item(job_item))) { + LOG_WARN("fail to insert tenant snapshot job", KR(ret), K(job_item)); + } + } + + return ret; +} + +int ObTenantSnapshotUtil::add_drop_tenant_snapshot_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObString &snapshot_name) +{ + int ret = OB_SUCCESS; + ObTenantSnapItem item; + ObTenantSnapshotTableOperator table_op; + common::ObCurTraceId::TraceId trace_id; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || snapshot_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(snapshot_name)); + } else if (OB_FAIL(table_op.init(tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item(snapshot_name, true, item))) { + LOG_WARN("failed to get tenant snap item", KR(ret), K(tenant_id), K(snapshot_name)); + } else if (ObTenantSnapStatus::NORMAL != item.get_status()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("not allowed for current snapshot operation", KR(ret), K(tenant_id), K(item.get_status())); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "there may be other operation on the same tenant snapshot, drop tenant snapshot"); + } else if (OB_FAIL(table_op.update_tenant_snap_item(snapshot_name, + ObTenantSnapStatus::NORMAL, + ObTenantSnapStatus::DELETING))) { + LOG_WARN("update tenant snapshot status failed", KR(ret), K(tenant_id), K(snapshot_name)); + } else { + ObCurTraceId::TraceId *cur_trace_id = ObCurTraceId::get_trace_id(); + if (nullptr != cur_trace_id) { + trace_id = *cur_trace_id; + } else { + trace_id.init(GCONF.self_addr_); + } + ObTenantSnapJobItem job_item(tenant_id, + item.get_tenant_snapshot_id(), + ObTenantSnapOperation::DELETE, + trace_id); + if (OB_FAIL(table_op.insert_tenant_snap_job_item(job_item))) { + LOG_WARN("fail to insert tenant snapshot job", KR(ret), K(job_item)); + } + } + + return ret; +} + +int ObTenantSnapshotUtil::get_tenant_snapshot_info(common::ObISQLClient &sql_client, + const uint64_t source_tenant_id, + const ObString &snapshot_name, + share::ObTenantSnapItem &item) +{ + int ret = OB_SUCCESS; + item.reset(); + ObTenantSnapshotTableOperator table_op; + if (OB_UNLIKELY(!is_user_tenant(source_tenant_id) || snapshot_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(source_tenant_id), K(snapshot_name)); + } else if (OB_FAIL(table_op.init(source_tenant_id, &sql_client))) { + LOG_WARN("failed to init table op", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item(snapshot_name, false, item))) { + LOG_WARN("failed to get snapshot item", KR(ret), K(snapshot_name)); + } + return ret; +} + +int ObTenantSnapshotUtil::get_tenant_snapshot_info(common::ObISQLClient &sql_client, + const uint64_t source_tenant_id, + const ObTenantSnapshotID &snapshot_id, + share::ObTenantSnapItem &item) +{ + int ret = OB_SUCCESS; + item.reset(); + ObTenantSnapshotTableOperator table_op; + if (OB_UNLIKELY(!is_user_tenant(source_tenant_id) || !snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(source_tenant_id), K(snapshot_id)); + } else if (OB_FAIL(table_op.init(source_tenant_id, &sql_client))) { + LOG_WARN("failed to init table op", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item(snapshot_id, false, item))) { + LOG_WARN("failed to get snapshot item", KR(ret), K(snapshot_id)); + } + return ret; +} + +int ObTenantSnapshotUtil::add_restore_tenant_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const share::ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotTableOperator table_op; + ObTenantSnapItem snap_item; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || !tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.init(tenant_id, &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item(tenant_snapshot_id, true, snap_item))) { + LOG_WARN("failed to get snapshot item", KR(ret), K(tenant_snapshot_id)); + } else if (ObTenantSnapStatus::NORMAL != snap_item.get_status()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("not allowed for current snapshot operation", KR(ret), K(tenant_id), K(snap_item.get_status())); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "there may be other operation on the same tenant snapshot, restore tenant"); + } else if (OB_FAIL(table_op.update_tenant_snap_item(tenant_snapshot_id, + ObTenantSnapStatus::NORMAL, /*old_status*/ + ObTenantSnapStatus::RESTORING /*new_status*/))) { + LOG_WARN("update tenant snapshot status failed", KR(ret), K(tenant_id), K(tenant_snapshot_id)); + } + + return ret; +} + +int ObTenantSnapshotUtil::add_restore_tenant_task(ObMySQLTransaction &trans, + const ObTenantSnapItem &snap_item) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotTableOperator table_op; + + if (!snap_item.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(snap_item)); + } else if (ObTenantSnapStatus::NORMAL != snap_item.get_status()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("not allowed for current snapshot operation", KR(ret), K(snap_item)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "there may be other operation on the same tenant snapshot, restore tenant"); + } else if (OB_FAIL(table_op.init(snap_item.get_tenant_id(), &trans))) { + LOG_WARN("failed to init table op", KR(ret), K(snap_item)); + } else if (OB_FAIL(table_op.update_tenant_snap_item(snap_item.get_tenant_snapshot_id(), + ObTenantSnapStatus::NORMAL, /*old_status*/ + ObTenantSnapStatus::RESTORING /*new_status*/))) { + LOG_WARN("update tenant snapshot status failed", KR(ret), K(snap_item)); + } + + return ret; +} + +int ObTenantSnapshotUtil::generate_tenant_snapshot_name(const uint64_t tenant_id, + ObSqlString &tenant_snapshot_name, + bool is_inner) +{ + int ret = OB_SUCCESS; + tenant_snapshot_name.reset(); + share::SCN gts_scn = SCN::invalid_scn(); + + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_FAIL(OB_TS_MGR.get_ts_sync(tenant_id, GCONF.rpc_timeout, gts_scn))) { + LOG_WARN("fail to get gts sync", KR(ret), K(tenant_id)); + } else if (!gts_scn.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected gts_scn", KR(ret), K(tenant_id), K(gts_scn)); + } else if (OB_FAIL(tenant_snapshot_name.assign_fmt(is_inner ? "_inner_snapshot$%lu" : + "snapshot$%lu", + gts_scn.get_val_for_gts() + ))) { + LOG_WARN("failed to assign_fmt", KR(ret), K(gts_scn)); + } + + return ret; +} + +int ObTenantSnapshotUtil::generate_tenant_snapshot_id(const uint64_t tenant_id, + ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + tenant_snapshot_id.reset(); + share::SCN gts_scn = SCN::invalid_scn(); + + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret)); + } else if (OB_FAIL(OB_TS_MGR.get_ts_sync(tenant_id, GCONF.rpc_timeout, gts_scn))) { + LOG_WARN("fail to get gts sync", KR(ret), K(tenant_id)); + } else if (!gts_scn.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected gts_scn", KR(ret), K(tenant_id), K(gts_scn)); + } else { + tenant_snapshot_id = gts_scn.get_val_for_tx(); + } + + return ret; +} + +int ObTenantSnapshotUtil::check_and_get_data_version(const uint64_t tenant_id, + uint64_t &data_version) +{ + int ret = OB_SUCCESS; + data_version = 0; + uint64_t current_data_version = 0; + uint64_t target_data_version = 0; + uint64_t compatible_version = 0; + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::UPGRADE); + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy is null", KR(ret), KP(GCTX.sql_proxy_), K(tenant_id)); + } else if (OB_FAIL(ObShareUtil::fetch_current_data_version(*GCTX.sql_proxy_, tenant_id, current_data_version))) { + LOG_WARN("fail to get current data version", KR(ret), K(tenant_id)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compatible_version))) { + LOG_WARN("fail to get min data version", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_tenant_is_in_upgrading_procedure_(tenant_id, target_data_version))) { + LOG_WARN("fail to check or tenant is in upgrading procedure", KR(ret), K(tenant_id)); + } else if (current_data_version != compatible_version + || current_data_version != target_data_version) { + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("source tenant is in upgrading procedure, can not do clone", KR(ret), K(tenant_id), + K(current_data_version), K(target_data_version), K(compatible_version)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, case_to_check.get_case_name_str(), CLONE_PROCEDURE_STR); + } else { + data_version = current_data_version; + } + return ret; +} + +int ObTenantSnapshotUtil::get_sys_ls_info(common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const ObTenantSnapshotID &tenant_snapshot_id, + ObArray &simple_items) +{ + int ret = OB_SUCCESS; + simple_items.reset(); + ObTenantSnapshotTableOperator snap_op; + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || !tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(snap_op.init(tenant_id, &sql_client))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(snap_op.get_tenant_snap_ls_replica_simple_items(tenant_snapshot_id, SYS_LS, simple_items))) { + LOG_WARN("failed to get sys ls replica simple items", KR(ret), K(tenant_snapshot_id)); + } + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_has_snapshot(common::ObISQLClient &sql_client, + const uint64_t tenant_id, + bool &has_snapshot) +{ + int ret = OB_SUCCESS; + has_snapshot = false; + ObTenantSnapshotTableOperator snap_op; + ObArray items; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_FAIL(snap_op.init(tenant_id, &sql_client))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(snap_op.get_all_user_tenant_snap_items(items))) { + LOG_WARN("failed to get all user snapshot items", KR(ret), K(tenant_id)); + } else if (!items.empty()) { + has_snapshot = true; + } + return ret; +} + +int ObTenantSnapshotUtil::notify_scheduler(const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + common::ObAddr leader_addr; + obrpc::ObNotifyTenantSnapshotSchedulerArg arg; + arg.set_tenant_id(tenant_id); + obrpc::ObNotifyTenantSnapshotSchedulerResult res; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.srv_rpc_proxy_) || OB_ISNULL(GCTX.location_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pointer is null", KR(ret), KP(GCTX.srv_rpc_proxy_), KP(GCTX.location_service_)); + } else if (OB_FAIL(GCTX.location_service_->get_leader_with_retry_until_timeout( + GCONF.cluster_id, gen_meta_tenant_id(tenant_id), ObLSID(ObLSID::SYS_LS_ID), leader_addr))) { + LOG_WARN("failed to get leader address", KR(ret), K(tenant_id)); + } else if (OB_FAIL(GCTX.srv_rpc_proxy_->to(leader_addr).by(tenant_id).notify_tenant_snapshot_scheduler(arg, res))) { + LOG_WARN("failed to notify tenant snapshot scheduler", KR(ret), K(leader_addr), K(arg)); + } else { + int res_ret = res.get_result(); + if (OB_SUCCESS != res_ret) { + ret = res_ret; + LOG_WARN("the result of notify scheduler failed", KR(res_ret), K(leader_addr), K(arg)); + } + } + + return ret; +} + +int ObTenantSnapshotUtil::recycle_tenant_snapshot_ls_replicas(common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const ObString &tenant_snapshot_name) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotTableOperator snap_op; + ObTenantSnapItem item; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || tenant_snapshot_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_snapshot_name)); + } else if (OB_FAIL(snap_op.init(tenant_id, &sql_client))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(snap_op.get_tenant_snap_item(tenant_snapshot_name, false /*need_lock*/, item))) { + LOG_WARN("fail to get tenant snap item", KR(ret), K(tenant_id), K(tenant_snapshot_name)); + } else if (OB_UNLIKELY(!item.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tenant snapshot item", KR(ret), K(item)); + } else if (OB_FAIL(snap_op.archive_tenant_snap_ls_replica_history(item.get_tenant_snapshot_id()))) { + LOG_WARN("fail to archive tenant snap ls replica", KR(ret), K(item)); + } else if (OB_FAIL(snap_op.eliminate_tenant_snap_ls_replica_history())) { + LOG_WARN("fail to eliminate tenant snap ls replica history", KR(ret)); + } + + return ret; +} + +int ObTenantSnapshotUtil::recycle_tenant_snapshot_ls_replicas(common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const share::ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotTableOperator snap_op; + ObTenantSnapItem item; + + if (OB_UNLIKELY(!is_user_tenant(tenant_id) || !tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(snap_op.init(tenant_id, &sql_client))) { + LOG_WARN("failed to init table op", KR(ret), K(tenant_id)); + } else if (OB_FAIL(snap_op.archive_tenant_snap_ls_replica_history(tenant_snapshot_id))) { + LOG_WARN("fail to archive tenant snap ls replica", KR(ret), K(item)); + } else if (OB_FAIL(snap_op.eliminate_tenant_snap_ls_replica_history())) { + LOG_WARN("fail to eliminate tenant snap ls replica history", KR(ret)); + } + + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_in_cloning_procedure_in_trans_( + const uint64_t tenant_id, + bool &is_tenant_in_cloning) +{ + int ret = OB_SUCCESS; + is_tenant_in_cloning = true; + common::ObMySQLTransaction trans; + int64_t user_tenant_id = OB_INVALID_TENANT_ID; + int64_t meta_tenant_id = OB_INVALID_TENANT_ID; + ObTenantSnapshotTableOperator tenant_snapshot_table_operator; + ObTenantSnapItem tenant_snapshot_item; + bool lock_line = true; + bool tenant_snapshot_table_exist = false; + + // is_tenant_in_cloning = false if one of conditions below is satisfied + // (1) tenant is not up to version 4.3, __all_tenant_snapshot not exists, clone is not supported + // (2) line with snapshot_id = 0 in __all_tenant_snapshot not exists + // (3) line with snapshot_id = 0 in __all_tenant_snapshot exists but is NORMAL status + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) { + is_tenant_in_cloning = false; + LOG_TRACE("sys and meta tenant can not in cloning procedure", K(tenant_id)); + } else if (OB_FAIL(check_snapshot_table_exists_(tenant_id, tenant_snapshot_table_exist))) { + LOG_WARN("fail to check __all_tenant_snapshot table exists", KR(ret), K(tenant_id)); + } else if (!tenant_snapshot_table_exist) { + is_tenant_in_cloning = false; + LOG_INFO("tenant snapshot table not exists, tenant is not cloning", K(tenant_id)); + } else { + user_tenant_id = gen_user_tenant_id(tenant_id); + meta_tenant_id = gen_meta_tenant_id(tenant_id); + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, meta_tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id), K(meta_tenant_id)); + } else if (OB_FAIL(tenant_snapshot_table_operator.init(user_tenant_id, &trans))) { + LOG_WARN("fail to init tenant snapshot table operator", KR(ret), K(tenant_id), K(user_tenant_id)); + // 1. lock __all_tenant_snapshot where snapshot_id = 0 + } else if (OB_FAIL(tenant_snapshot_table_operator.get_tenant_snap_item( + ObTenantSnapshotID(ObTenantSnapshotTableOperator::GLOBAL_STATE_ID), + lock_line, + tenant_snapshot_item))) { + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + // good, there is no snapshot need creating for this tenant + ret = OB_SUCCESS; + is_tenant_in_cloning = false; + LOG_TRACE("snapshot with GLOBAL_STATE_ID not exists, tenant is not cloning", K(tenant_id)); + } else { + LOG_WARN("fail to get snapshot item from __all_tenant_snapshot", KR(ret), K(tenant_id)); + } + } else if (ObTenantSnapStatus::NORMAL != tenant_snapshot_item.get_status()) { + is_tenant_in_cloning = true; + LOG_INFO("snapshot with GLOBAL_STATE_ID is not in NORMAL status, tenant is in cloning procedure", + K(tenant_id), K(tenant_snapshot_item)); + } else { + // good, there is no ls snapshot exists for this tenant + is_tenant_in_cloning = false; + LOG_TRACE("snapshot with GLOBAL_STATE_ID is in NORMAL status," + " tenant is not in cloning procedure", K(tenant_id), K(user_tenant_id), K(meta_tenant_id), + K(tenant_snapshot_item)); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + } + return ret; +} + +int ObTenantSnapshotUtil::check_snapshot_table_exists_( + const uint64_t user_tenant_id, + bool &tenant_snapshot_table_exist) +{ + // we check whether __all_tenant_snapshot table exists + // STEP 1: check data version + // if data_version already up to 4.3, table must exist + // STEP 2: check schema + // if data_version below 4.3, we check schema next + // if table exists in schema, table must exist + // STEP 3: check __all_table + // if schema not refreshed, check __all_table + int ret = OB_SUCCESS; + bool is_compatible_with_clone = false; + tenant_snapshot_table_exist = false; + if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(user_tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(user_tenant_id)); + // STEP 1: check data version first + } else if (OB_FAIL(ObShareUtil::check_compat_version_for_clone_tenant(user_tenant_id, is_compatible_with_clone))) { + LOG_WARN("fail to check compat version for clone tenant", KR(ret), K(user_tenant_id)); + } else if (is_compatible_with_clone) { + // good, data version up to 4.3 + tenant_snapshot_table_exist = true; + } else { + // STEP 2: check schema + ObSchemaGetterGuard meta_schema_guard; + const ObSimpleTableSchemaV2 *snapshot_table_schema = NULL; + uint64_t meta_tenant_id = gen_meta_tenant_id(user_tenant_id); + if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema service is null"); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(meta_tenant_id, meta_schema_guard))) { + LOG_WARN("get schema guard failed", KR(ret)); + } else if (OB_FAIL(meta_schema_guard.get_simple_table_schema(meta_tenant_id, OB_ALL_TENANT_SNAPSHOT_TID, snapshot_table_schema))) { + LOG_WARN("fail to get snapshot table schema", KR(ret), K(user_tenant_id), K(meta_tenant_id)); + } else if (OB_ISNULL(snapshot_table_schema)) { + tenant_snapshot_table_exist = false; + } else { + // good, table exists + tenant_snapshot_table_exist = true; + } + } + + if (OB_FAIL(ret)) { + } else if (tenant_snapshot_table_exist) { + // good, table exists + } else { + // STEP 3: check __all_table + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + ObSqlString sql("CloneTable"); + uint64_t exec_tenant_id = gen_meta_tenant_id(user_tenant_id); + int64_t row_count = 0; + if (OB_FAIL(sql.assign_fmt("SELECT count(*) as COUNT FROM %s " + "WHERE tenant_id = 0 AND table_id = %ld", + OB_ALL_TABLE_TNAME, OB_ALL_TENANT_SNAPSHOT_TID))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(GCTX.sql_proxy_->read(res, GCONF.cluster_id, exec_tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(sql), K(user_tenant_id), K(exec_tenant_id)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret)); + } else if (OB_FAIL(result->next())) { + LOG_WARN("empty result set", KR(ret)); + } else { + EXTRACT_INT_FIELD_MYSQL(*result, "COUNT", row_count, int64_t); + if (OB_FAIL(ret)) { + LOG_WARN("fail to get int from result", KR(ret)); + } else if (row_count == 0) { + tenant_snapshot_table_exist = false; + } else { + tenant_snapshot_table_exist = true; + } + } + } + } + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure( + const uint64_t tenant_id, + const ObConflictCaseWithClone &case_to_check) +{ + int ret = OB_SUCCESS; + LOG_TRACE("start to check whether tenant is in cloning procedure", K(tenant_id), K(case_to_check)); + bool tenant_is_in_cloning_procedure = true; + int64_t check_begin_time = ObTimeUtility::current_time(); + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id)) + || OB_UNLIKELY(!case_to_check.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(case_to_check)); + } else if (OB_FAIL(check_tenant_in_cloning_procedure_in_trans_( + tenant_id, + tenant_is_in_cloning_procedure))) { + LOG_WARN("fail to check tenant in cloning procedure in trans", KR(ret), K(tenant_id)); + } else if (tenant_is_in_cloning_procedure) { + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("tenant is in cloning procedure, some operations is not allowed for now", KR(ret), + K(tenant_id), K(tenant_is_in_cloning_procedure)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, CLONE_PROCEDURE_STR, case_to_check.get_case_name_str()); + } else { + // good, tenant not in cloning procedure + } + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_TRACE("finish check whether tenant is in cloning procedure", KR(ret), K(tenant_id), + K(case_to_check), K(tenant_is_in_cloning_procedure), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_has_no_conflict_tasks( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + int64_t check_begin_time = ObTimeUtility::current_time(); + uint64_t data_version = 0; + LOG_INFO("begin to check whether tenant has conflict tasks", K(tenant_id)); + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("sys or meta tenant can not in clone procedure, clone not allowed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_tenant_is_in_upgrading_procedure_(tenant_id, data_version))) { + LOG_WARN("fail to check tenant in upgrading procedure", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_tenant_is_in_transfer_procedure_(tenant_id))) { + LOG_WARN("fail to check tenant in transfer procedure", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_tenant_is_in_modify_resource_pool_procedure_(tenant_id))) { + LOG_WARN("fail to check tenant in modify resource pool procedure", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_tenant_is_in_modify_unit_procedure_(tenant_id))) { + LOG_WARN("fail to check tenant in modify unit procedure", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_tenant_is_in_modify_ls_procedure_(tenant_id))) { + LOG_WARN("fail to check tenant in modify ls procedure", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_tenant_is_in_modify_replica_procedure_(tenant_id))) { + LOG_WARN("fail to check tenant in modify replica procedure", KR(ret), K(tenant_id)); + } else if (OB_FAIL(check_tenant_is_in_switchover_procedure_(tenant_id))) { + LOG_WARN("fail to check tenant in switchover procedure", KR(ret), K(tenant_id)); + } + //TODO@jingyu.cr: need to consider these cases: + // (1) conflict check for arbitration service status + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_INFO("finish check whether tenant has conflict tasks", KR(ret), + K(tenant_id), K(check_begin_time), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_is_in_upgrading_procedure_( + const uint64_t tenant_id, + uint64_t &data_version) +{ + int ret = OB_SUCCESS; + data_version = 0; + int check_begin_time = ObTimeUtility::current_time(); + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::UPGRADE); + LOG_INFO("begin to check whether tenant is upgrading", K(tenant_id)); + common::ObMySQLTransaction trans; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id)); + } else { + ObGlobalStatProxy proxy(trans, tenant_id); + uint64_t target_data_version = 0; + uint64_t current_data_version = 0; + if (OB_FAIL(proxy.get_target_data_version(true/*for_update*/, target_data_version))) { + LOG_WARN("fail to get target data version", KR(ret), K(tenant_id)); + } else if (OB_FAIL(proxy.get_current_data_version(current_data_version))) { + LOG_WARN("fail to get current data version", KR(ret), K(tenant_id)); + } else if (current_data_version != target_data_version) { + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("source tenant is in upgrading procedure, can not do clone", KR(ret), K(tenant_id), + K(current_data_version), K(target_data_version)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, case_to_check.get_case_name_str(), CLONE_PROCEDURE_STR); + } else { + data_version = target_data_version; + } + } + // TODO@jingyu.cr: need to solve problems below + // 1. after current_data_version==target_data_version in upgrade procedure, make sure whether check conflict in steps remained + // 2. clone tenant need target_tenant initialize data_version + // source tenant baseline + memdump's data_version need same + // make sure whether to double check tenant's data_version is same + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_INFO("finish check whether tenant is upgrading", KR(ret), K(tenant_id), K(check_begin_time), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_is_in_transfer_procedure_( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + int check_begin_time = ObTimeUtility::current_time(); + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::TRANSFER); + LOG_INFO("begin to check whether tenant is transfer", K(tenant_id)); + common::ObMySQLTransaction trans; + ObBalanceJob job; + int64_t start_time = OB_INVALID_TIMESTAMP; // not used + int64_t finish_time = OB_INVALID_TIMESTAMP; // not used + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ObInnerTableLockUtil::lock_inner_table_in_trans( + trans, + tenant_id, + OB_ALL_BALANCE_JOB_TID, + EXCLUSIVE))) { + LOG_WARN("lock inner table failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ObBalanceJobTableOperator::get_balance_job( + tenant_id, + false/*for_update*/, + trans, + job, + start_time, + finish_time))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + // good, no balance job exists + } else { + LOG_WARN("failed to get balance job", KR(ret), K(tenant_id)); + } + } else { + // job exists, tenant is doing transfer, clone tenant related operations not allowed + // TODO@jingyu.cr: we can control more precisely by checking __all_balance_task, + // some operations like ls alter is allowed + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("source tenant is in balance procedure, can not do clone", KR(ret), K(tenant_id), K(job)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, case_to_check.get_case_name_str(), CLONE_PROCEDURE_STR); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_INFO("finish check whether tenant is transfer", KR(ret), K(tenant_id), K(check_begin_time), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_is_in_modify_resource_pool_procedure_( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + int check_begin_time = ObTimeUtility::current_time(); + LOG_INFO("begin to check whether tenant is transfer", K(tenant_id)); + ObSqlString sql("FetchPool"); + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(sql.append_fmt("SELECT * FROM %s WHERE tenant_id = %lu FOR UPDATE", + OB_ALL_RESOURCE_POOL_TNAME, tenant_id))) { + LOG_WARN("append_fmt failed", KR(ret), K(tenant_id)); + } else { + SMART_VAR(ObISQLClient::ReadResult, result) { + common::sqlclient::ObMySQLResult *res = NULL; + if (OB_FAIL(GCTX.sql_proxy_->read(result, GCONF.cluster_id, OB_SYS_TENANT_ID, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), "sql", sql.ptr()); + } else if (OB_ISNULL(res = result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed", KR(ret)); + } else if (OB_FAIL(res->next())) { + if (OB_ITER_END == ret) { + // rewrite error code + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expect at least one row in __all_resource_pool", KR(ret), K(sql)); + } else { + LOG_WARN("iterate next result fail", KR(ret), K(sql)); + } + } else { + // good, we can acquire lock on __all_resource_pool + // can continue clone related procedure + } + } + } + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_INFO("finish check whether tenant is modify resource pool", KR(ret), K(tenant_id), K(check_begin_time), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_is_in_modify_ls_procedure_( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + common::ObMySQLTransaction trans; + int check_begin_time = ObTimeUtility::current_time(); + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::MODIFY_LS); + LOG_INFO("begin to check whether tenant is modifing ls", K(tenant_id)); + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, tenant_id))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id)); + } else { + ObLSAttrOperator ls_table_operator(tenant_id, GCTX.sql_proxy_); + ObLSAttr sys_ls_attr; + ObArray ls_array; + // 1. lock sys ls in __all_ls under user tenant + if (OB_FAIL(ls_table_operator.get_ls_attr(SYS_LS, true/*for_update*/, trans, sys_ls_attr))) { + LOG_WARN("failed to load sys ls status", KR(ret)); + } else if (OB_FAIL(ls_table_operator.get_all_ls_by_order(ls_array))) { + LOG_WARN("failed to get all_ls by order", KR(ret)); + } else if (ls_array.count() <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls_array has no member", KR(ret), K(ls_array)); + } else { + // TODO@jingyu.cr: make sure whether change ls status from creating to create_abort + // 2. let ls info is consistent in__all_ls and __all_ls_status + // 3. adjust ls status in __all_ls_status + for (int64_t i = 0; OB_SUCC(ret) && i < ls_array.count(); ++i) { + const share::ObLSAttr &ls_info = ls_array.at(i); + if (!ls_info.ls_is_normal()) { + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("source tenant has ls not in normal status, can not do clone", KR(ret), K(tenant_id), K(ls_info)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, case_to_check.get_case_name_str(), CLONE_PROCEDURE_STR); + } + } + } + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_INFO("finish check whether tenant is modify ls", KR(ret), K(tenant_id), K(check_begin_time), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_is_in_modify_replica_procedure_( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + common::ObMySQLTransaction trans; + const int64_t timeout = GCONF.internal_sql_execute_timeout; + observer::ObInnerSQLConnection *conn = NULL; + ObSqlString sql("FetchDRTask"); + int64_t task_cnt = 0; + int check_begin_time = ObTimeUtility::current_time(); + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::MODIFY_REPLICA); + LOG_INFO("begin to check whether tenant is modifing ls", K(tenant_id)); + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, gen_meta_tenant_id(tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(conn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("conn_ is NULL", KR(ret)); + } else if (OB_FAIL(ObInnerConnectionLockUtil::lock_table(gen_meta_tenant_id(tenant_id), + OB_ALL_LS_REPLICA_TASK_TID, + EXCLUSIVE, + timeout, + conn))) { + LOG_WARN("lock dest table failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(sql.append_fmt("SELECT count(*) as task_count FROM %s", + OB_ALL_LS_REPLICA_TASK_TNAME))) { + LOG_WARN("append_fmt failed", KR(ret), K(tenant_id)); + } else { + SMART_VAR(ObISQLClient::ReadResult, res) { + sqlclient::ObMySQLResult *result = NULL; + if (OB_FAIL(trans.read(res, GCONF.cluster_id, gen_meta_tenant_id(tenant_id), sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), "sql", sql.ptr()); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get sql result", K(ret), KP(result)); + } else if (OB_FAIL(result->next())) { + LOG_WARN("result next failed", K(ret), K(tenant_id)); + } else { + EXTRACT_INT_FIELD_MYSQL(*result, "task_count", task_cnt, int64_t); + if (OB_FAIL(ret)) { + LOG_WARN("fail to extract int from result", KR(ret)); + } else if (0 < task_cnt) { + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("replica task is running now, can not create snapshot or clone tenant", KR(ret), K(tenant_id)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, case_to_check.get_case_name_str(), CLONE_PROCEDURE_STR); + } + } + } + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_INFO("finish check whether tenant is modify replica", KR(ret), K(tenant_id), K(check_begin_time), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_is_in_switchover_procedure_( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + common::ObMySQLTransaction trans; + ObAllTenantInfo tenant_info; + int check_begin_time = ObTimeUtility::current_time(); + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::SWITCHOVER); + LOG_INFO("begin to check whether tenant is switchover", K(tenant_id)); + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, gen_meta_tenant_id(tenant_id)))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info( + tenant_id, + &trans, + true/*for_update*/, + tenant_info))) { + LOG_WARN("failed to load tenant info", KR(ret), K(tenant_id)); + } else if (!tenant_info.is_primary() || !tenant_info.is_normal_status()) { + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("tenant is not PRIMARY or NORMAL, create snapshot or clone tenant not allowed", + KR(ret), K(tenant_id), K(tenant_info)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, case_to_check.get_case_name_str(), CLONE_PROCEDURE_STR); + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_INFO("finish check whether tenant is switchover", KR(ret), K(tenant_id), K(check_begin_time), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_tenant_is_in_modify_unit_procedure_( + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + common::ObMySQLTransaction trans; + ObSqlString sql("FetchUnit"); + int check_begin_time = ObTimeUtility::current_time(); + LOG_INFO("begin to check whether tenant is modifing unit", K(tenant_id)); + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, OB_SYS_TENANT_ID))) { + LOG_WARN("failed to start trans", KR(ret), K(tenant_id)); + } else if (OB_FAIL(sql.append_fmt("SELECT * FROM %s WHERE resource_pool_id in " + "(SELECT resource_pool_id FROM %s WHERE tenant_id = %lu) FOR UPDATE", + OB_ALL_UNIT_TNAME, OB_ALL_RESOURCE_POOL_TNAME, tenant_id))) { + LOG_WARN("append_fmt failed", KR(ret), K(tenant_id)); + } else { + SMART_VAR(ObISQLClient::ReadResult, result) { + if (OB_FAIL(trans.read(result, GCONF.cluster_id, OB_SYS_TENANT_ID, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), "sql", sql.ptr()); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get mysql result failed"); + } else if (OB_FAIL(check_unit_infos_(*result.get_result(), tenant_id))) { + LOG_WARN("construct log stream info failed", KR(ret), K(tenant_id)); + } + } + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + int64_t cost = ObTimeUtility::current_time() - check_begin_time; + LOG_INFO("finish check whether tenant is modifing unit", KR(ret), K(tenant_id), K(check_begin_time), K(cost)); + return ret; +} + +int ObTenantSnapshotUtil::check_unit_infos_( + common::sqlclient::ObMySQLResult &res, + const uint64_t tenant_id) +{ + int ret = OB_SUCCESS; + ObUnit unit_info; + int64_t unit_count = 0; + ObConflictCaseWithClone case_to_check(rootserver::ObConflictCaseWithClone::MODIFY_UNIT); + if (!is_valid_tenant_id(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else { + while (OB_SUCC(ret)) { + if (OB_FAIL(res.next())) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("get next result failed", KR(ret)); + } + break; + } + unit_info.reset(); + if (OB_FAIL(ObUnitTableOperator::read_unit(res, unit_info))) { + LOG_WARN("fail to construct unit info", KR(ret)); + } else if (!unit_info.is_active_status()) { + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("unit is not active, can not do clone tenant related operations", KR(ret), K(unit_info)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, case_to_check.get_case_name_str(), CLONE_PROCEDURE_STR); + } else if (unit_info.migrate_from_server_.is_valid()) { + ret = OB_CONFLICT_WITH_CLONE; + LOG_WARN("unit is migrating, can not do clone tenant related operations", KR(ret), K(unit_info)); + LOG_USER_ERROR(OB_CONFLICT_WITH_CLONE, tenant_id, case_to_check.get_case_name_str(), CLONE_PROCEDURE_STR); + } else { + unit_count++; + } + } + + if (OB_FAIL(ret)) { + } else if (0 >= unit_count) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("no valid unit exists", KR(ret)); + } + } + return ret; +} + +int ObTenantSnapshotUtil::lock_unit_for_tenant( + common::ObISQLClient &client, + const ObUnit &unit, + uint64_t &tenant_id_to_lock) +{ + int ret = OB_SUCCESS; + tenant_id_to_lock = OB_INVALID_TENANT_ID; + ObMySQLTransaction trans; + + if (OB_UNLIKELY(!unit.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(unit)); + } else if (OB_ISNULL(GCTX.sql_proxy_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, OB_SYS_TENANT_ID))) { + LOG_WARN("fail to start trans", KR(ret)); + } else { + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + const uint64_t exec_tenant_id = OB_SYS_TENANT_ID; + ObSqlString lock_sql("UnitTableLoc"); + if (OB_FAIL(lock_sql.assign_fmt("SELECT * FROM %s WHERE unit_id = %lu FOR UPDATE", + OB_ALL_UNIT_TNAME, unit.unit_id_))) { + LOG_WARN("fail to construct lock sql", KR(ret), K(unit)); + } else if (OB_FAIL(trans.read(res, exec_tenant_id, lock_sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(exec_tenant_id), K(lock_sql)); + } else { + ObUnitTableOperator unit_table_operator; + ObArray input_pool_ids; + ObArray input_pools; + if (OB_FAIL(unit_table_operator.init(*GCTX.sql_proxy_))) { + LOG_WARN("failed to init unit operator", KR(ret)); + } else if (OB_FAIL(input_pool_ids.push_back(unit.resource_pool_id_))) { + LOG_WARN("fail to add resource pool id into array", KR(ret), K(unit)); + } else if (OB_FAIL(unit_table_operator.get_resource_pools(input_pool_ids, input_pools))) { + LOG_WARN("fail to get resource pool by input pool id", KR(ret), K(input_pool_ids)); + } else if (OB_UNLIKELY(1 < input_pools.count())) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("expect single resource pool", KR(ret), K(unit), K(input_pool_ids), K(input_pools)); + } else { + tenant_id_to_lock = input_pools.at(0).tenant_id_; + } + } + } + } + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", KR(tmp_ret), KR(ret)); + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + return ret; +} + +int ObTenantSnapshotUtil::lock_resource_pool_for_tenant( + common::ObISQLClient &client, + const share::ObResourcePool &resource_pool) +{ + int ret = OB_SUCCESS; + ObSqlString lock_sql("PoolLock"); + if (OB_UNLIKELY(!resource_pool.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(resource_pool)); + } else if (OB_UNLIKELY(!is_valid_tenant_id(resource_pool.tenant_id_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("resource pool tenant id is invalid", KR(ret), K(resource_pool)); + } else if (is_sys_tenant(resource_pool.tenant_id_) || is_meta_tenant(resource_pool.tenant_id_)) { + // do nothing + } else if (OB_FAIL(lock_sql.assign_fmt("SELECT * FROM %s WHERE resource_pool_id = %lu FOR UPDATE", + OB_ALL_RESOURCE_POOL_TNAME, resource_pool.resource_pool_id_))) { + LOG_WARN("fail to construct lock sql", KR(ret), K(resource_pool)); + } else { + HEAP_VAR(ObMySQLProxy::MySQLResult, res) { + common::sqlclient::ObMySQLResult *result = NULL; + const uint64_t exec_tenant_id = OB_SYS_TENANT_ID; + if (OB_FAIL(client.read(res, exec_tenant_id, lock_sql.ptr()))) { + LOG_WARN("failed to read", KR(ret), K(exec_tenant_id), K(lock_sql)); + } + } + } + return ret; +} diff --git a/src/rootserver/tenant_snapshot/ob_tenant_snapshot_util.h b/src/rootserver/tenant_snapshot/ob_tenant_snapshot_util.h new file mode 100644 index 0000000000..095ce2a32a --- /dev/null +++ b/src/rootserver/tenant_snapshot/ob_tenant_snapshot_util.h @@ -0,0 +1,225 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef __OB_RS_TENANT_SNAPSHOT_UTIL_H__ +#define __OB_RS_TENANT_SNAPSHOT_UTIL_H__ + +#include "lib/mysqlclient/ob_mysql_transaction.h" +#include "share/scn.h" + +namespace oceanbase +{ +namespace share +{ +class ObTenantSnapshotID; +enum class ObTenantSnapStatus : int64_t; +class ObTenantSnapItem; +class ObTenantSnapLSReplicaSimpleItem; +class ObUnit; +class ObResourcePool; +} +namespace rootserver +{ +const char *const CLONE_PROCEDURE_STR = "create snapshot or clone tenant"; + +class ObConflictCaseWithClone +{ + OB_UNIS_VERSION(1); +public: + enum ConflictCaseWithClone + { + INVALID_CASE_NAME = -1, + UPGRADE = 0, + TRANSFER = 1, + MODIFY_RESOURCE_POOL = 2, + MODIFY_UNIT = 3, + MODIFY_LS = 4, + MODIFY_REPLICA = 5, + SWITCHOVER = 6, + MAX_CASE_NAME + }; +public: + ObConflictCaseWithClone() : case_name_(INVALID_CASE_NAME) {} + explicit ObConflictCaseWithClone(ConflictCaseWithClone case_name) : case_name_(case_name) {} + + ObConflictCaseWithClone &operator=(const ConflictCaseWithClone case_name) { case_name_ = case_name; return *this; } + ObConflictCaseWithClone &operator=(const ObConflictCaseWithClone &other) { case_name_ = other.case_name_; return *this; } + void reset() { case_name_ = INVALID_CASE_NAME; } + int64_t to_string(char *buf, const int64_t buf_len) const; + void assign(const ObConflictCaseWithClone &other) { case_name_ = other.case_name_; } + bool operator==(const ObConflictCaseWithClone &other) const { return other.case_name_ == case_name_; } + bool operator!=(const ObConflictCaseWithClone &other) const { return other.case_name_ != case_name_; } + bool is_valid() const { return INVALID_CASE_NAME < case_name_ && MAX_CASE_NAME > case_name_; } + bool is_upgrade() const { return UPGRADE == case_name_; } + bool is_transfer() const { return TRANSFER == case_name_; } + bool is_modify_resource_pool() const { return MODIFY_RESOURCE_POOL == case_name_; } + bool is_modify_unit() const { return MODIFY_UNIT == case_name_; } + bool is_modify_ls() const { return MODIFY_LS == case_name_; } + bool is_modify_replica() const { return MODIFY_REPLICA == case_name_; } + bool is_switchover() const { return SWITCHOVER == case_name_; } + const ConflictCaseWithClone &get_case_name() const { return case_name_; } + const char* get_case_name_str() const; +private: + ConflictCaseWithClone case_name_; +}; + +class ObTenantSnapshotUtil +{ +public: + /*snapshot operation*/ + enum TenantSnapshotOp : int8_t + { + CREATE_OP = 0, + DROP_OP = 1, + RESTORE_OP = 2, + FORK_OP = 3, + MAX, + }; +public: + static const char* get_op_print_str(const TenantSnapshotOp &op); + +public: + static int create_tenant_snapshot(const ObString &tenant_name, + const ObString &tenant_snapshot_name, + uint64_t &tenant_id, + share::ObTenantSnapshotID &tenant_snapshot_id); + static int create_fork_tenant_snapshot(ObMySQLTransaction &trans, + const uint64_t target_tenant_id, + const ObString &target_tenant_name, + const ObString &tenant_snapshot_name, + const share::ObTenantSnapshotID &tenant_snapshot_id); + static int drop_tenant_snapshot(const ObString &tenant_name, + const ObString &tenant_snapshot_name); + static int get_tenant_id(const ObString &tenant_name, + uint64_t &tenant_id); + static int check_source_tenant_info(const uint64_t tenant_id, + const TenantSnapshotOp op); + static int check_tenant_status(const uint64_t tenant_id, + bool &is_satisfied); + static int check_log_archive_ready(const uint64_t tenant_id, const ObString &tenant_name); + static int trylock_tenant_snapshot_simulated_mutex(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const TenantSnapshotOp op, + const int64_t owner_job_id, + share::ObTenantSnapStatus &original_global_state_status); + static int unlock_tenant_snapshot_simulated_mutex_from_clone_release_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const int64_t owner_job_id, + const share::ObTenantSnapStatus &old_status, + bool &is_already_unlocked); + static int unlock_tenant_snapshot_simulated_mutex_from_snapshot_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const share::ObTenantSnapStatus &old_status, + const share::SCN &snapshot_scn); + static int add_create_tenant_snapshot_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObString &snapshot_name, + const share::ObTenantSnapshotID &tenant_snapshot_id); + static int add_drop_tenant_snapshot_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const ObString &snapshot_name); + static int get_tenant_snapshot_info(common::ObISQLClient &sql_client, + const uint64_t source_tenant_id, + const ObString &snapshot_name, + share::ObTenantSnapItem &item); + static int get_tenant_snapshot_info(common::ObISQLClient &sql_client, + const uint64_t source_tenant_id, + const share::ObTenantSnapshotID &snapshot_id, + share::ObTenantSnapItem &item); + static int add_restore_tenant_task(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const share::ObTenantSnapshotID &tenant_snapshot_id); + static int add_restore_tenant_task(ObMySQLTransaction &trans, + const share::ObTenantSnapItem &snap_item); + static int generate_tenant_snapshot_name(const uint64_t tenant_id, + ObSqlString &tenant_snapshot_name, + bool is_inner = false); + static int generate_tenant_snapshot_id(const uint64_t tenant_id, + share::ObTenantSnapshotID &tenant_snapshot_id); + static int check_and_get_data_version(const uint64_t tenant_id, + uint64_t &data_version); + static int get_sys_ls_info(common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const share::ObTenantSnapshotID &tenant_snapshot_id, + ObArray &simple_items); + static int check_tenant_has_snapshot(common::ObISQLClient &sql_client, + const uint64_t tenant_id, + bool &has_snapshot); + static int notify_scheduler(const uint64_t tenant_id); + static int recycle_tenant_snapshot_ls_replicas(common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const ObString &tenant_snapshot_name); + static int recycle_tenant_snapshot_ls_replicas(common::ObISQLClient &sql_client, + const uint64_t tenant_id, + const share::ObTenantSnapshotID &tenant_snapshot_id); + // functions to check conflict conditions between clone and other operations + static int check_tenant_not_in_cloning_procedure( + const uint64_t tenant_id, + const ObConflictCaseWithClone &case_to_check); + static int check_tenant_has_no_conflict_tasks(const uint64_t tenant_id); + static int lock_unit_for_tenant( + common::ObISQLClient &client, + const share::ObUnit &unit, + uint64_t &tenant_id_to_lock); + static int lock_resource_pool_for_tenant( + common::ObISQLClient &client, + const share::ObResourcePool &resource_pool); +private: + static int check_tenant_snapshot_simulated_mutex_(ObMySQLTransaction &trans, + const uint64_t tenant_id, + share::ObTenantSnapItem &special_item, + bool &is_conflict); + static int unlock_(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const int64_t owner_job_id, + const share::ObTenantSnapStatus &old_status, + const share::SCN &snapshot_scn, + bool &is_conflicted_owner_job_id); + static int lock_(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const TenantSnapshotOp op, + const share::ObTenantSnapItem &special_item); + // check whether tenant is in cloning procedure in trans + // @params[in] user_tenant_id, the tenant to check + // @params[out] is_tenant_in_cloning, the output + // + // is_tenant_in_cloning = false if one of conditions below is satisfied + // (1) tenant is not up to version 4.3, clone is not supported + // (2) line with snapshot_id = 0 in __all_tenant_snapshot not exists + // (3) line with snapshot_id = 0 in __all_tenant_snapshot exists but is NORMAL status + // and no snapshot item exists in __all_tenant_snapshot_ls for this tenant + static int check_tenant_in_cloning_procedure_in_trans_( + const uint64_t user_tenant_id, + bool &is_tenant_in_cloning); + // check whether tenant is upgrading + // @params[in] tenant_id, tenant to check + static int check_tenant_is_in_upgrading_procedure_(const uint64_t tenant_id, + uint64_t &data_version); + static int check_tenant_is_in_transfer_procedure_(const uint64_t tenant_id); + static int check_tenant_is_in_modify_resource_pool_procedure_(const uint64_t tenant_id); + static int check_tenant_is_in_modify_unit_procedure_(const uint64_t tenant_id); + static int check_tenant_is_in_modify_ls_procedure_(const uint64_t tenant_id); + static int check_tenant_is_in_modify_replica_procedure_(const uint64_t tenant_id); + static int check_tenant_is_in_switchover_procedure_(const uint64_t tenant_id); + static int check_unit_infos_(common::sqlclient::ObMySQLResult &res, const uint64_t tenant_id); + static int check_snapshot_table_exists_(const uint64_t user_tenant_id, bool &tenant_snapshot_table_exist); +private: + static const char* TENANT_SNAP_OP_PRINT_ARRAY[]; +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapshotUtil); +}; + +} +} + + +#endif /* __OB_RS_TENANT_SNAPSHOT_UTIL_H__ */ diff --git a/src/share/CMakeLists.txt b/src/share/CMakeLists.txt index e2bf0abc9a..bf46c21d18 100644 --- a/src/share/CMakeLists.txt +++ b/src/share/CMakeLists.txt @@ -270,8 +270,11 @@ ob_set_subtarget(ob_share common_mixed detect/ob_detect_rpc_processor.cpp detect/ob_detect_manager_utils.cpp table/ob_table_load_sql_statistics.cpp + tenant_snapshot/ob_tenant_snapshot_id.cpp + tenant_snapshot/ob_tenant_snapshot_table_operator.cpp table/ob_ttl_util.cpp table/ob_table_config_util.cpp + restore/ob_tenant_clone_table_operator.cpp index_usage/ob_index_usage_info_mgr.cpp index_usage/ob_index_usage_report_task.cpp ) diff --git a/src/share/inner_table/ob_inner_table_schema.12401_12450.cpp b/src/share/inner_table/ob_inner_table_schema.12401_12450.cpp index ed54fa3715..38adfc591a 100644 --- a/src/share/inner_table/ob_inner_table_schema.12401_12450.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12401_12450.cpp @@ -500,6 +500,655 @@ int ObInnerTableSchema::all_virtual_tenant_parameter_schema(ObTableSchema &table return ret; } +int ObInnerTableSchema::all_virtual_tenant_snapshot_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("clog_start_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("create_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_version", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("owner_job_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_tenant_snapshot_ls_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(3); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_group_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 100, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("flag", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_LS_FLAG_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("create_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_tenant_snapshot_ls_replica_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(5); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 4, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 5, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("zone", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_ZONE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("begin_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("end_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_meta_package", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_tablet_buffer_info_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -6092,6 +6741,748 @@ int ObInnerTableSchema::all_virtual_import_table_task_history_schema(ObTableSche return ret; } +int ObInnerTableSchema::all_virtual_clone_job_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_CLONE_JOB_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_CLONE_JOB_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source_tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source_tenant_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj clone_tenant_id_default; + clone_tenant_id_default.set_int(OB_INVALID_TENANT_ID); + ADD_COLUMN_SCHEMA_T("clone_tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + clone_tenant_id_default, + clone_tenant_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("clone_tenant_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_snapshot_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_snapshot_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_RESOURCE_POOL_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_config_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_UNIT_CONFIG_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj restore_scn_default; + restore_scn_default.set_uint64(0); + ADD_COLUMN_SCHEMA_T("restore_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + restore_scn_default, + restore_scn_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 64, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("clone_start_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("clone_finished_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ret_code", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("error_msg", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_ERROR_MSG_LEN, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_clone_job_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_CLONE_JOB_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_CLONE_JOB_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source_tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source_tenant_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj clone_tenant_id_default; + clone_tenant_id_default.set_int(OB_INVALID_TENANT_ID); + ADD_COLUMN_SCHEMA_T("clone_tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + clone_tenant_id_default, + clone_tenant_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("clone_tenant_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_snapshot_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_snapshot_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_RESOURCE_POOL_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_config_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_UNIT_CONFIG_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj restore_scn_default; + restore_scn_default.set_uint64(0); + ADD_COLUMN_SCHEMA_T("restore_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + restore_scn_default, + restore_scn_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 64, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("clone_start_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("clone_finished_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ret_code", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("error_msg", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_ERROR_MSG_LEN, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_aux_stat_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.12451_12500.cpp b/src/share/inner_table/ob_inner_table_schema.12451_12500.cpp index fa98d7ca29..c19a152cc2 100644 --- a/src/share/inner_table/ob_inner_table_schema.12451_12500.cpp +++ b/src/share/inner_table/ob_inner_table_schema.12451_12500.cpp @@ -25,6 +25,468 @@ using namespace common; namespace share { +int ObInnerTableSchema::all_virtual_tenant_snapshot_job_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_JOB_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(3); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_JOB_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("operation", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("job_start_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("majority_succ_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_virtual_ls_snapshot_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_LS_SNAPSHOT_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_LS_SNAPSHOT_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 1, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 2, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("meta_existed", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("build_status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("rebuild_seq_start", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("rebuild_seq_end", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("end_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_meta_package", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tsnap_is_running", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tsnap_has_unfinished_create_dag", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tsnap_has_unfinished_gc_dag", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tsnap_clone_ref", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tsnap_meta_existed", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTinyIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + 1, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { + table_schema.get_part_option().set_part_num(1); + table_schema.set_part_level(PARTITION_LEVEL_ONE); + table_schema.get_part_option().set_part_func_type(PARTITION_FUNC_TYPE_LIST_COLUMNS); + if (OB_FAIL(table_schema.get_part_option().set_part_expr("svr_ip, svr_port"))) { + LOG_WARN("set_part_expr failed", K(ret)); + } else if (OB_FAIL(table_schema.mock_list_partition_array())) { + LOG_WARN("mock list partition array failed", K(ret)); + } + } + table_schema.set_index_using_type(USING_HASH); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_index_usage_info_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -388,6 +850,247 @@ int ObInnerTableSchema::all_virtual_index_usage_info_schema(ObTableSchema &table return ret; } +int ObInnerTableSchema::all_virtual_tenant_snapshot_ls_replica_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(5); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 4, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 5, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("zone", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_ZONE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("begin_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("end_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_meta_package", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.15401_15450.cpp b/src/share/inner_table/ob_inner_table_schema.15401_15450.cpp index 5388412ec0..5dcf735996 100644 --- a/src/share/inner_table/ob_inner_table_schema.15401_15450.cpp +++ b/src/share/inner_table/ob_inner_table_schema.15401_15450.cpp @@ -4823,6 +4823,300 @@ int ObInnerTableSchema::all_virtual_aux_stat_real_agent_ora_schema(ObTableSchema return ret; } +int ObInnerTableSchema::all_virtual_ls_snapshot_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(VIRTUAL_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCollationType::CS_TYPE_UTF8MB4_BIN); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TENANT_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SNAPSHOT_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("LS_ID", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SVR_IP", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 1, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + 2, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("SVR_PORT", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 2, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("META_EXISTED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("BUILD_STATUS", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_UTF8MB4_BIN, //column_collation_type + 32, //column_length + 2, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("REBUILD_SEQ_START", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("REBUILD_SEQ_END", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("END_INTERVAL_SCN", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("LS_META_PACKAGE", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TSNAP_IS_RUNNING", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TSNAP_HAS_UNFINISHED_CREATE_DAG", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TSNAP_HAS_UNFINISHED_GC_DAG", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TSNAP_CLONE_REF", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("TSNAP_META_EXISTED", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObNumberType, //column_type + CS_TYPE_INVALID, //column_collation_type + 38, //column_length + 38, //column_precision + 0, //column_scale + true, //is_nullable + false); //is_autoincrement + } + if (OB_SUCC(ret)) { + table_schema.get_part_option().set_part_num(1); + table_schema.set_part_level(PARTITION_LEVEL_ONE); + table_schema.get_part_option().set_part_func_type(PARTITION_FUNC_TYPE_LIST); + if (OB_FAIL(table_schema.get_part_option().set_part_expr("SVR_IP, SVR_PORT"))) { + LOG_WARN("set_part_expr failed", K(ret)); + } else if (OB_FAIL(table_schema.mock_list_partition_array())) { + LOG_WARN("mock list partition array failed", K(ret)); + } + } + table_schema.set_index_using_type(USING_HASH); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_index_usage_info_real_agent_ora_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.21501_21550.cpp b/src/share/inner_table/ob_inner_table_schema.21501_21550.cpp index 37c4b88d5c..4ca1f6ef0e 100644 --- a/src/share/inner_table/ob_inner_table_schema.21501_21550.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21501_21550.cpp @@ -75,6 +75,56 @@ int ObInnerTableSchema::dba_ob_trusted_root_certificate_schema(ObTableSchema &ta return ret; } +int ObInnerTableSchema::dba_ob_clone_progress_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_CLONE_PROGRESS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_CLONE_PROGRESS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT job_id AS CLONE_JOB_ID, trace_id AS TRACE_ID, source_tenant_id AS SOURCE_TENANT_ID, source_tenant_name AS SOURCE_TENANT_NAME, clone_tenant_id AS CLONE_TENANT_ID, clone_tenant_name AS CLONE_TENANT_NAME, tenant_snapshot_id AS TENANT_SNAPSHOT_ID, tenant_snapshot_name AS TENANT_SNAPSHOT_NAME, resource_pool_id AS RESOURCE_POOL_ID, resource_pool_name AS RESOURCE_POOL_NAME, unit_config_name AS UNIT_CONFIG_NAME, restore_scn AS RESTORE_SCN, status AS STATUS, job_type AS CLONE_JOB_TYPE, clone_start_time AS CLONE_START_TIME, clone_finished_time AS CLONE_FINISHED_TIME, ret_code AS RET_CODE, error_msg AS ERROR_MESSAGE FROM oceanbase.__all_clone_job ORDER BY CLONE_START_TIME )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::cdb_index_usage_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -125,6 +175,156 @@ int ObInnerTableSchema::cdb_index_usage_schema(ObTableSchema &table_schema) return ret; } +int ObInnerTableSchema::gv_ob_ls_snapshots_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_GV_OB_LS_SNAPSHOTS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_GV_OB_LS_SNAPSHOTS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT tenant_id AS TENANT_ID, snapshot_id AS SNAPSHOT_ID, ls_id AS LS_ID, svr_ip AS SVR_IP, svr_port AS SVR_PORT, (CASE WHEN meta_existed = 1 THEN 'YES' ELSE 'NO' END) AS META_EXISTED, (CASE WHEN build_status = 0 THEN 'BUILDING' WHEN build_status = 1 THEN 'FAILED' WHEN build_status = 2 THEN 'SUCCESSFUL' ELSE 'UNKNOWN' END) AS BUILD_STATUS, rebuild_seq_start AS REBUILD_SEQ_START, rebuild_seq_end AS REBUILD_SEQ_END, end_interval_scn AS END_INTERVAL_SCN, ls_meta_package AS LS_META_PACKAGE, (CASE WHEN tsnap_is_running = 1 THEN 'YES' ELSE 'NO' END) AS TSNAP_IS_RUNNING, (CASE WHEN tsnap_has_unfinished_create_dag = 1 THEN 'YES' ELSE 'NO' END) AS TSNAP_HAS_UNFINISHED_CREATE_DAG, (CASE WHEN tsnap_has_unfinished_gc_dag = 1 THEN 'YES' ELSE 'NO' END) AS TSNAP_HAS_UNFINISHED_GC_DAG, tsnap_clone_ref AS TSNAP_CLONE_REF, (CASE WHEN tsnap_meta_existed = 1 THEN 'YES' ELSE 'NO' END) AS TSNAP_META_EXISTED FROM oceanbase.__all_virtual_ls_snapshot )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::v_ob_ls_snapshots_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_V_OB_LS_SNAPSHOTS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_V_OB_LS_SNAPSHOTS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT * FROM oceanbase.GV$OB_LS_SNAPSHOTS WHERE SVR_IP = HOST_IP() AND SVR_PORT = RPC_PORT() )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::dba_ob_clone_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_DBA_OB_CLONE_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_DBA_OB_CLONE_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT job_id AS CLONE_JOB_ID, trace_id AS TRACE_ID, source_tenant_id AS SOURCE_TENANT_ID, source_tenant_name AS SOURCE_TENANT_NAME, clone_tenant_id AS CLONE_TENANT_ID, clone_tenant_name AS CLONE_TENANT_NAME, tenant_snapshot_id AS TENANT_SNAPSHOT_ID, tenant_snapshot_name AS TENANT_SNAPSHOT_NAME, resource_pool_id AS RESOURCE_POOL_ID, resource_pool_name AS RESOURCE_POOL_NAME, unit_config_name AS UNIT_CONFIG_NAME, restore_scn AS RESTORE_SCN, status AS STATUS, job_type AS CLONE_JOB_TYPE, clone_start_time AS CLONE_START_TIME, clone_finished_time AS CLONE_FINISHED_TIME, ret_code AS RET_CODE, error_msg AS ERROR_MESSAGE FROM oceanbase.__all_clone_job_history ORDER BY CLONE_START_TIME )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.28201_28250.cpp b/src/share/inner_table/ob_inner_table_schema.28201_28250.cpp index 617990a3e9..09b5ce7649 100644 --- a/src/share/inner_table/ob_inner_table_schema.28201_28250.cpp +++ b/src/share/inner_table/ob_inner_table_schema.28201_28250.cpp @@ -125,6 +125,106 @@ int ObInnerTableSchema::dba_index_usage_ora_schema(ObTableSchema &table_schema) return ret; } +int ObInnerTableSchema::gv_ob_ls_snapshots_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_GV_OB_LS_SNAPSHOTS_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_GV_OB_LS_SNAPSHOTS_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT tenant_id AS TENANT_ID, snapshot_id AS SNAPSHOT_ID, ls_id AS LS_ID, svr_ip AS SVR_IP, svr_port AS SVR_PORT, (CASE WHEN meta_existed = 1 THEN 'YES' ELSE 'NO' END) AS META_EXISTED, (CASE WHEN build_status = 0 THEN 'BUILDING' WHEN build_status = 1 THEN 'FAILED' WHEN build_status = 2 THEN 'SUCCESSFUL' ELSE 'UNKNOWN' END) AS BUILD_STATUS, rebuild_seq_start AS REBUILD_SEQ_START, rebuild_seq_end AS REBUILD_SEQ_END, end_interval_scn AS END_INTERVAL_SCN, ls_meta_package AS LS_META_PACKAGE, (CASE WHEN tsnap_is_running = 1 THEN 'YES' ELSE 'NO' END) AS TSNAP_IS_RUNNING, (CASE WHEN tsnap_has_unfinished_create_dag = 1 THEN 'YES' ELSE 'NO' END) AS TSNAP_HAS_UNFINISHED_CREATE_DAG, (CASE WHEN tsnap_has_unfinished_gc_dag = 1 THEN 'YES' ELSE 'NO' END) AS TSNAP_HAS_UNFINISHED_GC_DAG, tsnap_clone_ref AS TSNAP_CLONE_REF, (CASE WHEN tsnap_meta_existed = 1 THEN 'YES' ELSE 'NO' END) AS TSNAP_META_EXISTED FROM SYS.ALL_VIRTUAL_LS_SNAPSHOT )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::v_ob_ls_snapshots_ora_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); + table_schema.set_database_id(OB_ORA_SYS_DATABASE_ID); + table_schema.set_table_id(OB_V_OB_LS_SNAPSHOTS_ORA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(0); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_VIEW); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_V_OB_LS_SNAPSHOTS_ORA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT * FROM SYS.GV$OB_LS_SNAPSHOTS WHERE SVR_IP = HOST_IP() AND SVR_PORT = RPC_PORT() )__"))) { + LOG_ERROR("fail to set view_definition", K(ret)); + } + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(0); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_table_idx_data_table_id_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -10584,6 +10684,140 @@ int ObInnerTableSchema::all_rls_context_history_idx_rls_context_his_table_id_sch return ret; } +int ObInnerTableSchema::all_tenant_snapshot_idx_tenant_snapshot_name_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(USER_INDEX); + table_schema.set_index_type(INDEX_TYPE_UNIQUE_LOCAL); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ++column_id; // for gmt_create + } + + if (OB_SUCC(ret)) { + ++column_id; // for gmt_modified + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TID); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_name", //column_name + column_id + 3, //column_id + 1, //rowkey_id + 1, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false,//is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_WITH_COLUMN_FLAGS("shadow_pk_0", //column_name + column_id + 32768, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true,//is_nullable + false,//is_autoincrement + true,//is_hidden + false);//is_storing_column + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_WITH_COLUMN_FLAGS("shadow_pk_1", //column_name + column_id + 32769, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true,//is_nullable + false,//is_autoincrement + true,//is_hidden + false);//is_storing_column + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + column_id + 1, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false,//is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + column_id + 2, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false,//is_nullable + false); //is_autoincrement + } + table_schema.set_index_status(INDEX_STATUS_AVAILABLE); + table_schema.set_index_type(INDEX_TYPE_UNIQUE_LOCAL); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_TID); + + table_schema.set_max_used_column_id(column_id + 32769); + return ret; +} + int ObInnerTableSchema::all_dbms_lock_allocated_idx_dbms_lock_allocated_lockhandle_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.451_500.cpp b/src/share/inner_table/ob_inner_table_schema.451_500.cpp index ba86f1f3d0..9928e1e6c3 100644 --- a/src/share/inner_table/ob_inner_table_schema.451_500.cpp +++ b/src/share/inner_table/ob_inner_table_schema.451_500.cpp @@ -1788,6 +1788,703 @@ int ObInnerTableSchema::all_balance_task_helper_schema(ObTableSchema &table_sche return ret; } +int ObInnerTableSchema::all_tenant_snapshot_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("clog_start_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("create_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_version", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("owner_job_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_tenant_snapshot_ls_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(3); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_group_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 100, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("flag", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_LS_FLAG_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("create_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_tenant_snapshot_ls_replica_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(5); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 4, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 5, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("zone", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_ZONE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("begin_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("end_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_meta_package", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_dbms_lock_allocated_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -6946,6 +7643,780 @@ int ObInnerTableSchema::all_import_table_task_history_schema(ObTableSchema &tabl return ret; } +int ObInnerTableSchema::all_clone_job_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_CLONE_JOB_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_CLONE_JOB_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source_tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source_tenant_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj clone_tenant_id_default; + clone_tenant_id_default.set_int(OB_INVALID_TENANT_ID); + ADD_COLUMN_SCHEMA_T("clone_tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + clone_tenant_id_default, + clone_tenant_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("clone_tenant_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_snapshot_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_snapshot_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_RESOURCE_POOL_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_config_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_UNIT_CONFIG_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj restore_scn_default; + restore_scn_default.set_uint64(0); + ADD_COLUMN_SCHEMA_T("restore_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + restore_scn_default, + restore_scn_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 64, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("clone_start_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("clone_finished_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ret_code", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("error_msg", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_ERROR_MSG_LEN, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_CLONE_JOB_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_CLONE_JOB_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_clone_job_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_CLONE_JOB_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_CLONE_JOB_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source_tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("source_tenant_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj clone_tenant_id_default; + clone_tenant_id_default.set_int(OB_INVALID_TENANT_ID); + ADD_COLUMN_SCHEMA_T("clone_tenant_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + clone_tenant_id_default, + clone_tenant_id_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("clone_tenant_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_snapshot_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_snapshot_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("resource_pool_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_RESOURCE_POOL_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_config_name", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_UNIT_CONFIG_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ObObj restore_scn_default; + restore_scn_default.set_uint64(0); + ADD_COLUMN_SCHEMA_T("restore_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + restore_scn_default, + restore_scn_default); //default_value + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 64, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("job_type", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("clone_start_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("clone_finished_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ret_code", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("error_msg", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_ERROR_MSG_LEN, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_CLONE_JOB_HISTORY_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_aux_stat_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.501_550.cpp b/src/share/inner_table/ob_inner_table_schema.501_550.cpp index 5697c1142a..c0a71eae5a 100644 --- a/src/share/inner_table/ob_inner_table_schema.501_550.cpp +++ b/src/share/inner_table/ob_inner_table_schema.501_550.cpp @@ -25,6 +25,190 @@ using namespace common; namespace share { +int ObInnerTableSchema::all_tenant_snapshot_job_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_JOB_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(3); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_JOB_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("operation", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("job_start_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("trace_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_MAX_TRACE_ID_BUFFER_SIZE, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA_TS("majority_succ_time", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(ObPreciseDateTime), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false, //is_autoincrement + false); //is_on_update_for_timestamp + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_JOB_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_trusted_root_certificate_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -162,6 +346,263 @@ int ObInnerTableSchema::all_trusted_root_certificate_schema(ObTableSchema &table return ret; } +int ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(5); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(SYSTEM_TABLE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ObObj gmt_create_default; + ObObj gmt_create_default_null; + + gmt_create_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_create_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_create", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + false, //is_on_update_for_timestamp + gmt_create_default_null, + gmt_create_default) + } + + if (OB_SUCC(ret)) { + ObObj gmt_modified_default; + ObObj gmt_modified_default_null; + + gmt_modified_default.set_ext(ObActionFlag::OP_DEFAULT_NOW_FLAG); + gmt_modified_default_null.set_null(); + ADD_COLUMN_SCHEMA_TS_T("gmt_modified", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObTimestampType, //column_type + CS_TYPE_BINARY,//collation_type + 0, //column length + -1, //column_precision + 6, //column_scale + true,//is nullable + false, //is_autoincrement + true, //is_on_update_for_timestamp + gmt_modified_default_null, + gmt_modified_default) + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("snapshot_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_id", //column_name + ++column_id, //column_id + 3, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_ip", //column_name + ++column_id, //column_id + 4, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_IP_ADDR_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("svr_port", //column_name + ++column_id, //column_id + 5, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("status", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + OB_DEFAULT_STATUS_LENTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("zone", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_INVALID, //column_collation_type + MAX_ZONE_LENGTH, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("unit_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObIntType, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(int64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("begin_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("end_interval_scn", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("ls_meta_package", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObLongTextType, //column_type + CS_TYPE_INVALID, //column_collation_type + 0, //column_length + -1, //column_precision + -1, //column_scale + true, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID); + table_schema.set_aux_lob_meta_tid(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.50451_50500.cpp b/src/share/inner_table/ob_inner_table_schema.50451_50500.cpp index 29daa8d22f..e056824150 100644 --- a/src/share/inner_table/ob_inner_table_schema.50451_50500.cpp +++ b/src/share/inner_table/ob_inner_table_schema.50451_50500.cpp @@ -1105,6 +1105,411 @@ int ObInnerTableSchema::all_balance_task_helper_aux_lob_meta_schema(ObTableSchem return ret; } +int ObInnerTableSchema::all_tenant_snapshot_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_tenant_snapshot_ls_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_LS_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_tenant_snapshot_ls_replica_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_dbms_lock_allocated_aux_lob_meta_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -2455,6 +2860,276 @@ int ObInnerTableSchema::all_import_table_task_history_aux_lob_meta_schema(ObTabl return ret; } +int ObInnerTableSchema::all_clone_job_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_CLONE_JOB_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_CLONE_JOB_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_CLONE_JOB_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_CLONE_JOB_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_clone_job_history_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_CLONE_JOB_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_aux_stat_aux_lob_meta_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.50501_50550.cpp b/src/share/inner_table/ob_inner_table_schema.50501_50550.cpp index 4b23150771..4d98636c04 100644 --- a/src/share/inner_table/ob_inner_table_schema.50501_50550.cpp +++ b/src/share/inner_table/ob_inner_table_schema.50501_50550.cpp @@ -25,6 +25,141 @@ using namespace common; namespace share { +int ObInnerTableSchema::all_tenant_snapshot_job_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_JOB_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_trusted_root_certificate_aux_lob_meta_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -160,6 +295,141 @@ int ObInnerTableSchema::all_trusted_root_certificate_aux_lob_meta_schema(ObTable return ret; } +int ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_aux_lob_meta_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(2); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_META); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 16, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("seq_id", //column_name + ++column_id, //column_id + 2, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 8192, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("binary_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("char_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 262144, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.60451_60500.cpp b/src/share/inner_table/ob_inner_table_schema.60451_60500.cpp index c941546147..3bd7cbf2c5 100644 --- a/src/share/inner_table/ob_inner_table_schema.60451_60500.cpp +++ b/src/share/inner_table/ob_inner_table_schema.60451_60500.cpp @@ -745,6 +745,276 @@ int ObInnerTableSchema::all_balance_task_helper_aux_lob_piece_schema(ObTableSche return ret; } +int ObInnerTableSchema::all_tenant_snapshot_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_tenant_snapshot_ls_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_LS_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_tenant_snapshot_ls_replica_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_dbms_lock_allocated_aux_lob_piece_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -1645,6 +1915,186 @@ int ObInnerTableSchema::all_import_table_task_history_aux_lob_piece_schema(ObTab return ret; } +int ObInnerTableSchema::all_clone_job_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_CLONE_JOB_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + +int ObInnerTableSchema::all_clone_job_history_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_CLONE_JOB_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_aux_stat_aux_lob_piece_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.60501_60550.cpp b/src/share/inner_table/ob_inner_table_schema.60501_60550.cpp index ff0df783d4..c46228a63a 100644 --- a/src/share/inner_table/ob_inner_table_schema.60501_60550.cpp +++ b/src/share/inner_table/ob_inner_table_schema.60501_60550.cpp @@ -25,6 +25,96 @@ using namespace common; namespace share { +int ObInnerTableSchema::all_tenant_snapshot_job_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_JOB_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_trusted_root_certificate_aux_lob_piece_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -115,6 +205,96 @@ int ObInnerTableSchema::all_trusted_root_certificate_aux_lob_piece_schema(ObTabl return ret; } +int ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_aux_lob_piece_schema(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + uint64_t column_id = OB_APP_MIN_COLUMN_ID - 1; + + //generated fields: + table_schema.set_tenant_id(OB_SYS_TENANT_ID); + table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_database_id(OB_SYS_DATABASE_ID); + table_schema.set_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_rowkey_split_pos(0); + table_schema.set_is_use_bloomfilter(false); + table_schema.set_progressive_merge_num(0); + table_schema.set_rowkey_column_num(1); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(AUX_LOB_PIECE); + table_schema.set_index_type(INDEX_TYPE_IS_NOT); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TNAME))) { + LOG_ERROR("fail to set table_name", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_compress_func_name(OB_DEFAULT_COMPRESS_FUNC_NAME))) { + LOG_ERROR("fail to set compress_func_name", K(ret)); + } + } + table_schema.set_part_level(PARTITION_LEVEL_ZERO); + table_schema.set_charset_type(ObCharset::get_default_charset()); + table_schema.set_collation_type(ObCharset::get_default_collation(ObCharset::get_default_charset())); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("piece_id", //column_name + ++column_id, //column_id + 1, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt64Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint64_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("data_len", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObUInt32Type, //column_type + CS_TYPE_INVALID, //column_collation_type + sizeof(uint32_t), //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("lob_data", //column_name + ++column_id, //column_id + 0, //rowkey_id + 0, //index_id + 0, //part_key_pos + ObVarcharType, //column_type + CS_TYPE_BINARY, //column_collation_type + 32, //column_length + -1, //column_precision + -1, //column_scale + false, //is_nullable + false); //is_autoincrement + } + table_schema.set_index_using_type(USING_BTREE); + table_schema.set_row_store_type(ENCODING_ROW_STORE); + table_schema.set_store_format(OB_STORE_FORMAT_DYNAMIC_MYSQL); + table_schema.set_progressive_merge_round(1); + table_schema.set_storage_format_version(3); + table_schema.set_tablet_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_data_table_id(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.h b/src/share/inner_table/ob_inner_table_schema.h index 0b38551667..a4c1660a38 100644 --- a/src/share/inner_table/ob_inner_table_schema.h +++ b/src/share/inner_table/ob_inner_table_schema.h @@ -546,6 +546,9 @@ public: static int wr_statname_schema(share::schema::ObTableSchema &table_schema); static int wr_sysstat_schema(share::schema::ObTableSchema &table_schema); static int all_balance_task_helper_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_replica_schema(share::schema::ObTableSchema &table_schema); static int all_dbms_lock_allocated_schema(share::schema::ObTableSchema &table_schema); static int wr_control_schema(share::schema::ObTableSchema &table_schema); static int all_tenant_event_history_schema(share::schema::ObTableSchema &table_schema); @@ -556,9 +559,13 @@ public: static int all_import_table_job_history_schema(share::schema::ObTableSchema &table_schema); static int all_import_table_task_schema(share::schema::ObTableSchema &table_schema); static int all_import_table_task_history_schema(share::schema::ObTableSchema &table_schema); + static int all_clone_job_schema(share::schema::ObTableSchema &table_schema); + static int all_clone_job_history_schema(share::schema::ObTableSchema &table_schema); static int all_aux_stat_schema(share::schema::ObTableSchema &table_schema); static int all_index_usage_info_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_job_schema(share::schema::ObTableSchema &table_schema); static int all_trusted_root_certificate_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_replica_history_schema(share::schema::ObTableSchema &table_schema); static int tenant_virtual_all_table_schema(share::schema::ObTableSchema &table_schema); static int tenant_virtual_table_column_schema(share::schema::ObTableSchema &table_schema); static int tenant_virtual_table_index_schema(share::schema::ObTableSchema &table_schema); @@ -949,6 +956,9 @@ public: static int all_virtual_storage_leak_info_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_ls_log_restore_status_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_tenant_parameter_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tenant_snapshot_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tenant_snapshot_ls_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tenant_snapshot_ls_replica_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_tablet_buffer_info_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_wr_control_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_tenant_event_history_schema(share::schema::ObTableSchema &table_schema); @@ -962,8 +972,13 @@ public: static int all_virtual_import_table_job_history_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_import_table_task_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_import_table_task_history_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_clone_job_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_clone_job_history_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_aux_stat_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tenant_snapshot_job_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_ls_snapshot_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_index_usage_info_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tenant_snapshot_ls_replica_history_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_sql_audit_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_plan_stat_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_plan_cache_plan_explain_ora_schema(share::schema::ObTableSchema &table_schema); @@ -1213,6 +1228,7 @@ public: static int all_virtual_import_table_task_history_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_ls_info_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_aux_stat_real_agent_ora_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_ls_snapshot_ora_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_index_usage_info_real_agent_ora_schema(share::schema::ObTableSchema &table_schema); static int gv_ob_plan_cache_stat_schema(share::schema::ObTableSchema &table_schema); static int gv_ob_plan_cache_plan_stat_schema(share::schema::ObTableSchema &table_schema); @@ -1585,7 +1601,11 @@ public: static int cdb_ob_aux_statistics_schema(share::schema::ObTableSchema &table_schema); static int dba_index_usage_schema(share::schema::ObTableSchema &table_schema); static int dba_ob_trusted_root_certificate_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_clone_progress_schema(share::schema::ObTableSchema &table_schema); static int cdb_index_usage_schema(share::schema::ObTableSchema &table_schema); + static int gv_ob_ls_snapshots_schema(share::schema::ObTableSchema &table_schema); + static int v_ob_ls_snapshots_schema(share::schema::ObTableSchema &table_schema); + static int dba_ob_clone_history_schema(share::schema::ObTableSchema &table_schema); static int dba_synonyms_schema(share::schema::ObTableSchema &table_schema); static int dba_objects_ora_schema(share::schema::ObTableSchema &table_schema); static int all_objects_schema(share::schema::ObTableSchema &table_schema); @@ -2010,6 +2030,8 @@ public: static int gv_ob_flt_trace_config_ora_schema(share::schema::ObTableSchema &table_schema); static int dba_ob_aux_statistics_ora_schema(share::schema::ObTableSchema &table_schema); static int dba_index_usage_ora_schema(share::schema::ObTableSchema &table_schema); + static int gv_ob_ls_snapshots_ora_schema(share::schema::ObTableSchema &table_schema); + static int v_ob_ls_snapshots_ora_schema(share::schema::ObTableSchema &table_schema); static int all_table_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_column_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_ddl_operation_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); @@ -2264,6 +2286,9 @@ public: static int wr_statname_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int wr_sysstat_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_balance_task_helper_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_replica_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_dbms_lock_allocated_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int wr_control_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_tenant_event_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); @@ -2274,9 +2299,13 @@ public: static int all_import_table_job_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_import_table_task_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_import_table_task_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_clone_job_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_clone_job_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_aux_stat_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_index_usage_info_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_job_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_trusted_root_certificate_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_replica_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_table_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_column_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_ddl_operation_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); @@ -2531,6 +2560,9 @@ public: static int wr_statname_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int wr_sysstat_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_balance_task_helper_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_replica_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_dbms_lock_allocated_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int wr_control_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_tenant_event_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); @@ -2541,9 +2573,13 @@ public: static int all_import_table_job_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_import_table_task_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_import_table_task_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_clone_job_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_clone_job_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_aux_stat_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_index_usage_info_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_job_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_trusted_root_certificate_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_ls_replica_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_ash_all_virtual_ash_i1_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_sql_plan_monitor_all_virtual_sql_plan_monitor_i1_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_sql_audit_all_virtual_sql_audit_i1_schema(share::schema::ObTableSchema &table_schema); @@ -2729,6 +2765,7 @@ public: static int all_rls_group_history_idx_rls_group_his_table_id_schema(share::schema::ObTableSchema &table_schema); static int all_rls_context_idx_rls_context_table_id_schema(share::schema::ObTableSchema &table_schema); static int all_rls_context_history_idx_rls_context_his_table_id_schema(share::schema::ObTableSchema &table_schema); + static int all_tenant_snapshot_idx_tenant_snapshot_name_schema(share::schema::ObTableSchema &table_schema); static int all_dbms_lock_allocated_idx_dbms_lock_allocated_lockhandle_schema(share::schema::ObTableSchema &table_schema); static int all_dbms_lock_allocated_idx_dbms_lock_allocated_expiration_schema(share::schema::ObTableSchema &table_schema); static int all_kv_ttl_task_idx_kv_ttl_task_table_id_schema(share::schema::ObTableSchema &table_schema); @@ -3002,6 +3039,9 @@ const schema_create_func sys_table_schema_creators [] = { ObInnerTableSchema::wr_statname_schema, ObInnerTableSchema::wr_sysstat_schema, ObInnerTableSchema::all_balance_task_helper_schema, + ObInnerTableSchema::all_tenant_snapshot_schema, + ObInnerTableSchema::all_tenant_snapshot_ls_schema, + ObInnerTableSchema::all_tenant_snapshot_ls_replica_schema, ObInnerTableSchema::all_dbms_lock_allocated_schema, ObInnerTableSchema::wr_control_schema, ObInnerTableSchema::all_tenant_event_history_schema, @@ -3012,9 +3052,13 @@ const schema_create_func sys_table_schema_creators [] = { ObInnerTableSchema::all_import_table_job_history_schema, ObInnerTableSchema::all_import_table_task_schema, ObInnerTableSchema::all_import_table_task_history_schema, + ObInnerTableSchema::all_clone_job_schema, + ObInnerTableSchema::all_clone_job_history_schema, ObInnerTableSchema::all_aux_stat_schema, ObInnerTableSchema::all_index_usage_info_schema, + ObInnerTableSchema::all_tenant_snapshot_job_schema, ObInnerTableSchema::all_trusted_root_certificate_schema, + ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_schema, NULL,}; const schema_create_func virtual_table_schema_creators [] = { @@ -3408,6 +3452,9 @@ const schema_create_func virtual_table_schema_creators [] = { ObInnerTableSchema::all_virtual_storage_leak_info_schema, ObInnerTableSchema::all_virtual_ls_log_restore_status_schema, ObInnerTableSchema::all_virtual_tenant_parameter_schema, + ObInnerTableSchema::all_virtual_tenant_snapshot_schema, + ObInnerTableSchema::all_virtual_tenant_snapshot_ls_schema, + ObInnerTableSchema::all_virtual_tenant_snapshot_ls_replica_schema, ObInnerTableSchema::all_virtual_tablet_buffer_info_schema, ObInnerTableSchema::all_virtual_wr_control_schema, ObInnerTableSchema::all_virtual_tenant_event_history_schema, @@ -3421,8 +3468,13 @@ const schema_create_func virtual_table_schema_creators [] = { ObInnerTableSchema::all_virtual_import_table_job_history_schema, ObInnerTableSchema::all_virtual_import_table_task_schema, ObInnerTableSchema::all_virtual_import_table_task_history_schema, + ObInnerTableSchema::all_virtual_clone_job_schema, + ObInnerTableSchema::all_virtual_clone_job_history_schema, ObInnerTableSchema::all_virtual_aux_stat_schema, + ObInnerTableSchema::all_virtual_tenant_snapshot_job_schema, + ObInnerTableSchema::all_virtual_ls_snapshot_schema, ObInnerTableSchema::all_virtual_index_usage_info_schema, + ObInnerTableSchema::all_virtual_tenant_snapshot_ls_replica_history_schema, ObInnerTableSchema::all_virtual_ash_all_virtual_ash_i1_schema, ObInnerTableSchema::all_virtual_sql_plan_monitor_all_virtual_sql_plan_monitor_i1_schema, ObInnerTableSchema::all_virtual_sql_audit_all_virtual_sql_audit_i1_schema, @@ -3682,6 +3734,7 @@ const schema_create_func virtual_table_schema_creators [] = { ObInnerTableSchema::all_virtual_import_table_task_history_ora_schema, ObInnerTableSchema::all_virtual_ls_info_ora_schema, ObInnerTableSchema::all_virtual_aux_stat_real_agent_ora_schema, + ObInnerTableSchema::all_virtual_ls_snapshot_ora_schema, ObInnerTableSchema::all_virtual_index_usage_info_real_agent_ora_schema, ObInnerTableSchema::all_virtual_table_real_agent_ora_idx_data_table_id_real_agent_schema, ObInnerTableSchema::all_virtual_table_real_agent_ora_idx_db_tb_name_real_agent_schema, @@ -4138,7 +4191,11 @@ const schema_create_func sys_view_schema_creators [] = { ObInnerTableSchema::cdb_ob_aux_statistics_schema, ObInnerTableSchema::dba_index_usage_schema, ObInnerTableSchema::dba_ob_trusted_root_certificate_schema, + ObInnerTableSchema::dba_ob_clone_progress_schema, ObInnerTableSchema::cdb_index_usage_schema, + ObInnerTableSchema::gv_ob_ls_snapshots_schema, + ObInnerTableSchema::v_ob_ls_snapshots_schema, + ObInnerTableSchema::dba_ob_clone_history_schema, ObInnerTableSchema::dba_synonyms_schema, ObInnerTableSchema::dba_objects_ora_schema, ObInnerTableSchema::all_objects_schema, @@ -4563,6 +4620,8 @@ const schema_create_func sys_view_schema_creators [] = { ObInnerTableSchema::gv_ob_flt_trace_config_ora_schema, ObInnerTableSchema::dba_ob_aux_statistics_ora_schema, ObInnerTableSchema::dba_index_usage_ora_schema, + ObInnerTableSchema::gv_ob_ls_snapshots_ora_schema, + ObInnerTableSchema::v_ob_ls_snapshots_ora_schema, NULL,}; const schema_create_func core_index_table_schema_creators [] = { @@ -4663,6 +4722,7 @@ const schema_create_func sys_index_table_schema_creators [] = { ObInnerTableSchema::all_rls_group_history_idx_rls_group_his_table_id_schema, ObInnerTableSchema::all_rls_context_idx_rls_context_table_id_schema, ObInnerTableSchema::all_rls_context_history_idx_rls_context_his_table_id_schema, + ObInnerTableSchema::all_tenant_snapshot_idx_tenant_snapshot_name_schema, ObInnerTableSchema::all_dbms_lock_allocated_idx_dbms_lock_allocated_lockhandle_schema, ObInnerTableSchema::all_dbms_lock_allocated_idx_dbms_lock_allocated_expiration_schema, ObInnerTableSchema::all_kv_ttl_task_idx_kv_ttl_task_table_id_schema, @@ -4910,6 +4970,9 @@ const uint64_t tenant_space_tables [] = { OB_WR_STATNAME_TID, OB_WR_SYSSTAT_TID, OB_ALL_BALANCE_TASK_HELPER_TID, + OB_ALL_TENANT_SNAPSHOT_TID, + OB_ALL_TENANT_SNAPSHOT_LS_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID, OB_ALL_DBMS_LOCK_ALLOCATED_TID, OB_WR_CONTROL_TID, OB_ALL_TENANT_EVENT_HISTORY_TID, @@ -4920,8 +4983,12 @@ const uint64_t tenant_space_tables [] = { OB_ALL_IMPORT_TABLE_JOB_HISTORY_TID, OB_ALL_IMPORT_TABLE_TASK_TID, OB_ALL_IMPORT_TABLE_TASK_HISTORY_TID, + OB_ALL_CLONE_JOB_TID, + OB_ALL_CLONE_JOB_HISTORY_TID, OB_ALL_AUX_STAT_TID, OB_ALL_INDEX_USAGE_INFO_TID, + OB_ALL_TENANT_SNAPSHOT_JOB_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID, OB_TENANT_VIRTUAL_ALL_TABLE_TID, OB_TENANT_VIRTUAL_TABLE_COLUMN_TID, OB_TENANT_VIRTUAL_TABLE_INDEX_TID, @@ -5111,6 +5178,9 @@ const uint64_t tenant_space_tables [] = { OB_ALL_VIRTUAL_PX_P2P_DATAHUB_TID, OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TID, OB_ALL_VIRTUAL_TENANT_PARAMETER_TID, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_TID, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_TID, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TID, OB_ALL_VIRTUAL_WR_CONTROL_TID, OB_ALL_VIRTUAL_TENANT_EVENT_HISTORY_TID, OB_ALL_VIRTUAL_FLT_CONFIG_TID, @@ -5120,6 +5190,11 @@ const uint64_t tenant_space_tables [] = { OB_ALL_VIRTUAL_IMPORT_TABLE_JOB_HISTORY_TID, OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_TID, OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_TID, + OB_ALL_VIRTUAL_CLONE_JOB_TID, + OB_ALL_VIRTUAL_CLONE_JOB_HISTORY_TID, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_JOB_TID, + OB_ALL_VIRTUAL_LS_SNAPSHOT_TID, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TID, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_ALL_VIRTUAL_SQL_AUDIT_I1_TID, OB_ALL_VIRTUAL_PLAN_STAT_ORA_TID, @@ -5378,6 +5453,7 @@ const uint64_t tenant_space_tables [] = { OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_ORA_TID, OB_ALL_VIRTUAL_LS_INFO_ORA_TID, OB_ALL_VIRTUAL_AUX_STAT_REAL_AGENT_ORA_TID, + OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TID, OB_ALL_VIRTUAL_INDEX_USAGE_INFO_REAL_AGENT_ORA_TID, OB_GV_OB_PLAN_CACHE_STAT_TID, OB_GV_OB_PLAN_CACHE_PLAN_STAT_TID, @@ -5644,6 +5720,8 @@ const uint64_t tenant_space_tables [] = { OB_DBA_OB_IMPORT_TABLE_TASK_HISTORY_TID, OB_DBA_OB_AUX_STATISTICS_TID, OB_DBA_INDEX_USAGE_TID, + OB_GV_OB_LS_SNAPSHOTS_TID, + OB_V_OB_LS_SNAPSHOTS_TID, OB_DBA_SYNONYMS_TID, OB_DBA_OBJECTS_ORA_TID, OB_ALL_OBJECTS_TID, @@ -6068,6 +6146,8 @@ const uint64_t tenant_space_tables [] = { OB_GV_OB_FLT_TRACE_CONFIG_ORA_TID, OB_DBA_OB_AUX_STATISTICS_ORA_TID, OB_DBA_INDEX_USAGE_ORA_TID, + OB_GV_OB_LS_SNAPSHOTS_ORA_TID, + OB_V_OB_LS_SNAPSHOTS_ORA_TID, OB_ALL_TABLE_IDX_DATA_TABLE_ID_TID, OB_ALL_TABLE_IDX_DB_TB_NAME_TID, OB_ALL_TABLE_IDX_TB_NAME_TID, @@ -6156,6 +6236,7 @@ const uint64_t tenant_space_tables [] = { OB_ALL_RLS_GROUP_HISTORY_IDX_RLS_GROUP_HIS_TABLE_ID_TID, OB_ALL_RLS_CONTEXT_IDX_RLS_CONTEXT_TABLE_ID_TID, OB_ALL_RLS_CONTEXT_HISTORY_IDX_RLS_CONTEXT_HIS_TABLE_ID_TID, + OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TID, OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_LOCKHANDLE_TID, OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_EXPIRATION_TID, OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TID, @@ -6465,6 +6546,9 @@ const uint64_t tenant_space_tables [] = { OB_WR_STATNAME_AUX_LOB_META_TID, OB_WR_SYSSTAT_AUX_LOB_META_TID, OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TID, OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_META_TID, OB_WR_CONTROL_AUX_LOB_META_TID, OB_ALL_TENANT_EVENT_HISTORY_AUX_LOB_META_TID, @@ -6475,8 +6559,12 @@ const uint64_t tenant_space_tables [] = { OB_ALL_IMPORT_TABLE_JOB_HISTORY_AUX_LOB_META_TID, OB_ALL_IMPORT_TABLE_TASK_AUX_LOB_META_TID, OB_ALL_IMPORT_TABLE_TASK_HISTORY_AUX_LOB_META_TID, + OB_ALL_CLONE_JOB_AUX_LOB_META_TID, + OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TID, OB_ALL_AUX_STAT_AUX_LOB_META_TID, OB_ALL_INDEX_USAGE_INFO_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID, OB_ALL_TABLE_AUX_LOB_PIECE_TID, OB_ALL_COLUMN_AUX_LOB_PIECE_TID, OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TID, @@ -6710,6 +6798,9 @@ const uint64_t tenant_space_tables [] = { OB_WR_STATNAME_AUX_LOB_PIECE_TID, OB_WR_SYSSTAT_AUX_LOB_PIECE_TID, OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID, + OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TID, + OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TID, OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_PIECE_TID, OB_WR_CONTROL_AUX_LOB_PIECE_TID, OB_ALL_TENANT_EVENT_HISTORY_AUX_LOB_PIECE_TID, @@ -6720,8 +6811,12 @@ const uint64_t tenant_space_tables [] = { OB_ALL_IMPORT_TABLE_JOB_HISTORY_AUX_LOB_PIECE_TID, OB_ALL_IMPORT_TABLE_TASK_AUX_LOB_PIECE_TID, OB_ALL_IMPORT_TABLE_TASK_HISTORY_AUX_LOB_PIECE_TID, + OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID, + OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TID, OB_ALL_AUX_STAT_AUX_LOB_PIECE_TID, - OB_ALL_INDEX_USAGE_INFO_AUX_LOB_PIECE_TID, }; + OB_ALL_INDEX_USAGE_INFO_AUX_LOB_PIECE_TID, + OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID, }; const uint64_t all_ora_mapping_virtual_table_org_tables [] = { OB_ALL_VIRTUAL_SQL_AUDIT_TID, @@ -6860,7 +6955,8 @@ const uint64_t all_ora_mapping_virtual_table_org_tables [] = { OB_ALL_VIRTUAL_IMPORT_TABLE_JOB_HISTORY_TID, OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_TID, OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_TID, - OB_ALL_VIRTUAL_LS_INFO_TID, }; + OB_ALL_VIRTUAL_LS_INFO_TID, + OB_ALL_VIRTUAL_LS_SNAPSHOT_TID, }; const uint64_t all_ora_mapping_virtual_tables [] = { OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TID , OB_ALL_VIRTUAL_PLAN_STAT_ORA_TID @@ -6999,6 +7095,7 @@ const uint64_t all_ora_mapping_virtual_tables [] = { OB_ALL_VIRTUAL_SQL_AUDIT_O , OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_ORA_TID , OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_ORA_TID , OB_ALL_VIRTUAL_LS_INFO_ORA_TID +, OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TID , }; /* start/end_pos is start/end postition for column with tenant id */ @@ -7247,6 +7344,9 @@ const char* const tenant_space_table_names [] = { OB_WR_STATNAME_TNAME, OB_WR_SYSSTAT_TNAME, OB_ALL_BALANCE_TASK_HELPER_TNAME, + OB_ALL_TENANT_SNAPSHOT_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, OB_ALL_DBMS_LOCK_ALLOCATED_TNAME, OB_WR_CONTROL_TNAME, OB_ALL_TENANT_EVENT_HISTORY_TNAME, @@ -7257,8 +7357,12 @@ const char* const tenant_space_table_names [] = { OB_ALL_IMPORT_TABLE_JOB_HISTORY_TNAME, OB_ALL_IMPORT_TABLE_TASK_TNAME, OB_ALL_IMPORT_TABLE_TASK_HISTORY_TNAME, + OB_ALL_CLONE_JOB_TNAME, + OB_ALL_CLONE_JOB_HISTORY_TNAME, OB_ALL_AUX_STAT_TNAME, OB_ALL_INDEX_USAGE_INFO_TNAME, + OB_ALL_TENANT_SNAPSHOT_JOB_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME, OB_TENANT_VIRTUAL_ALL_TABLE_TNAME, OB_TENANT_VIRTUAL_TABLE_COLUMN_TNAME, OB_TENANT_VIRTUAL_TABLE_INDEX_TNAME, @@ -7448,6 +7552,9 @@ const char* const tenant_space_table_names [] = { OB_ALL_VIRTUAL_PX_P2P_DATAHUB_TNAME, OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TNAME, OB_ALL_VIRTUAL_TENANT_PARAMETER_TNAME, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_TNAME, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_TNAME, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, OB_ALL_VIRTUAL_WR_CONTROL_TNAME, OB_ALL_VIRTUAL_TENANT_EVENT_HISTORY_TNAME, OB_ALL_VIRTUAL_FLT_CONFIG_TNAME, @@ -7457,6 +7564,11 @@ const char* const tenant_space_table_names [] = { OB_ALL_VIRTUAL_IMPORT_TABLE_JOB_HISTORY_TNAME, OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_TNAME, OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_TNAME, + OB_ALL_VIRTUAL_CLONE_JOB_TNAME, + OB_ALL_VIRTUAL_CLONE_JOB_HISTORY_TNAME, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_JOB_TNAME, + OB_ALL_VIRTUAL_LS_SNAPSHOT_TNAME, + OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TNAME, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_ALL_VIRTUAL_SQL_AUDIT_I1_TNAME, OB_ALL_VIRTUAL_PLAN_STAT_ORA_TNAME, @@ -7715,6 +7827,7 @@ const char* const tenant_space_table_names [] = { OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_ORA_TNAME, OB_ALL_VIRTUAL_LS_INFO_ORA_TNAME, OB_ALL_VIRTUAL_AUX_STAT_REAL_AGENT_ORA_TNAME, + OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TNAME, OB_ALL_VIRTUAL_INDEX_USAGE_INFO_REAL_AGENT_ORA_TNAME, OB_GV_OB_PLAN_CACHE_STAT_TNAME, OB_GV_OB_PLAN_CACHE_PLAN_STAT_TNAME, @@ -7981,6 +8094,8 @@ const char* const tenant_space_table_names [] = { OB_DBA_OB_IMPORT_TABLE_TASK_HISTORY_TNAME, OB_DBA_OB_AUX_STATISTICS_TNAME, OB_DBA_INDEX_USAGE_TNAME, + OB_GV_OB_LS_SNAPSHOTS_TNAME, + OB_V_OB_LS_SNAPSHOTS_TNAME, OB_DBA_SYNONYMS_TNAME, OB_DBA_OBJECTS_ORA_TNAME, OB_ALL_OBJECTS_TNAME, @@ -8405,6 +8520,8 @@ const char* const tenant_space_table_names [] = { OB_GV_OB_FLT_TRACE_CONFIG_ORA_TNAME, OB_DBA_OB_AUX_STATISTICS_ORA_TNAME, OB_DBA_INDEX_USAGE_ORA_TNAME, + OB_GV_OB_LS_SNAPSHOTS_ORA_TNAME, + OB_V_OB_LS_SNAPSHOTS_ORA_TNAME, OB_ALL_TABLE_IDX_DATA_TABLE_ID_TNAME, OB_ALL_TABLE_IDX_DB_TB_NAME_TNAME, OB_ALL_TABLE_IDX_TB_NAME_TNAME, @@ -8493,6 +8610,7 @@ const char* const tenant_space_table_names [] = { OB_ALL_RLS_GROUP_HISTORY_IDX_RLS_GROUP_HIS_TABLE_ID_TNAME, OB_ALL_RLS_CONTEXT_IDX_RLS_CONTEXT_TABLE_ID_TNAME, OB_ALL_RLS_CONTEXT_HISTORY_IDX_RLS_CONTEXT_HIS_TABLE_ID_TNAME, + OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TNAME, OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_LOCKHANDLE_TNAME, OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_EXPIRATION_TNAME, OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TNAME, @@ -8802,6 +8920,9 @@ const char* const tenant_space_table_names [] = { OB_WR_STATNAME_AUX_LOB_META_TNAME, OB_WR_SYSSTAT_AUX_LOB_META_TNAME, OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TNAME, + OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TNAME, OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_META_TNAME, OB_WR_CONTROL_AUX_LOB_META_TNAME, OB_ALL_TENANT_EVENT_HISTORY_AUX_LOB_META_TNAME, @@ -8812,8 +8933,12 @@ const char* const tenant_space_table_names [] = { OB_ALL_IMPORT_TABLE_JOB_HISTORY_AUX_LOB_META_TNAME, OB_ALL_IMPORT_TABLE_TASK_AUX_LOB_META_TNAME, OB_ALL_IMPORT_TABLE_TASK_HISTORY_AUX_LOB_META_TNAME, + OB_ALL_CLONE_JOB_AUX_LOB_META_TNAME, + OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TNAME, OB_ALL_AUX_STAT_AUX_LOB_META_TNAME, OB_ALL_INDEX_USAGE_INFO_AUX_LOB_META_TNAME, + OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TNAME, OB_ALL_TABLE_AUX_LOB_PIECE_TNAME, OB_ALL_COLUMN_AUX_LOB_PIECE_TNAME, OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TNAME, @@ -9047,6 +9172,9 @@ const char* const tenant_space_table_names [] = { OB_WR_STATNAME_AUX_LOB_PIECE_TNAME, OB_WR_SYSSTAT_AUX_LOB_PIECE_TNAME, OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TNAME, + OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TNAME, OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_PIECE_TNAME, OB_WR_CONTROL_AUX_LOB_PIECE_TNAME, OB_ALL_TENANT_EVENT_HISTORY_AUX_LOB_PIECE_TNAME, @@ -9057,8 +9185,12 @@ const char* const tenant_space_table_names [] = { OB_ALL_IMPORT_TABLE_JOB_HISTORY_AUX_LOB_PIECE_TNAME, OB_ALL_IMPORT_TABLE_TASK_AUX_LOB_PIECE_TNAME, OB_ALL_IMPORT_TABLE_TASK_HISTORY_AUX_LOB_PIECE_TNAME, + OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TNAME, + OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TNAME, OB_ALL_AUX_STAT_AUX_LOB_PIECE_TNAME, - OB_ALL_INDEX_USAGE_INFO_AUX_LOB_PIECE_TNAME, }; + OB_ALL_INDEX_USAGE_INFO_AUX_LOB_PIECE_TNAME, + OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TNAME, }; const uint64_t only_rs_vtables [] = { OB_ALL_VIRTUAL_CORE_META_TABLE_TID, @@ -9204,6 +9336,7 @@ const uint64_t tenant_distributed_vtables [] = { OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_TID, OB_ALL_VIRTUAL_PX_P2P_DATAHUB_TID, OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TID, + OB_ALL_VIRTUAL_LS_SNAPSHOT_TID, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TID, OB_ALL_VIRTUAL_SQL_AUDIT_ORA_ALL_VIRTUAL_SQL_AUDIT_I1_TID, OB_ALL_VIRTUAL_PLAN_STAT_ORA_TID, @@ -9270,7 +9403,8 @@ const uint64_t tenant_distributed_vtables [] = { OB_ALL_VIRTUAL_PX_P2P_DATAHUB_ORA_TID, OB_ALL_VIRTUAL_TIMESTAMP_SERVICE_ORA_TID, OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_ORA_TID, - OB_ALL_VIRTUAL_LS_INFO_ORA_TID, }; + OB_ALL_VIRTUAL_LS_INFO_ORA_TID, + OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TID, }; const uint64_t restrict_access_virtual_tables[] = { OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TID, @@ -9389,6 +9523,7 @@ const uint64_t restrict_access_virtual_tables[] = { OB_ALL_VIRTUAL_IMPORT_TABLE_JOB_HISTORY_ORA_TID, OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_ORA_TID, OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_ORA_TID, + OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TID, OB_ALL_VIRTUAL_INDEX_USAGE_INFO_REAL_AGENT_ORA_TID }; @@ -11568,6 +11703,30 @@ LOBMapping const lob_aux_table_mappings [] = { ObInnerTableSchema::all_balance_task_helper_aux_lob_piece_schema }, + { + OB_ALL_TENANT_SNAPSHOT_TID, + OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_tenant_snapshot_aux_lob_meta_schema, + ObInnerTableSchema::all_tenant_snapshot_aux_lob_piece_schema + }, + + { + OB_ALL_TENANT_SNAPSHOT_LS_TID, + OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_tenant_snapshot_ls_aux_lob_meta_schema, + ObInnerTableSchema::all_tenant_snapshot_ls_aux_lob_piece_schema + }, + + { + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_tenant_snapshot_ls_replica_aux_lob_meta_schema, + ObInnerTableSchema::all_tenant_snapshot_ls_replica_aux_lob_piece_schema + }, + { OB_ALL_DBMS_LOCK_ALLOCATED_TID, OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_META_TID, @@ -11648,6 +11807,22 @@ LOBMapping const lob_aux_table_mappings [] = { ObInnerTableSchema::all_import_table_task_history_aux_lob_piece_schema }, + { + OB_ALL_CLONE_JOB_TID, + OB_ALL_CLONE_JOB_AUX_LOB_META_TID, + OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_clone_job_aux_lob_meta_schema, + ObInnerTableSchema::all_clone_job_aux_lob_piece_schema + }, + + { + OB_ALL_CLONE_JOB_HISTORY_TID, + OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TID, + OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_clone_job_history_aux_lob_meta_schema, + ObInnerTableSchema::all_clone_job_history_aux_lob_piece_schema + }, + { OB_ALL_AUX_STAT_TID, OB_ALL_AUX_STAT_AUX_LOB_META_TID, @@ -11664,6 +11839,14 @@ LOBMapping const lob_aux_table_mappings [] = { ObInnerTableSchema::all_index_usage_info_aux_lob_piece_schema }, + { + OB_ALL_TENANT_SNAPSHOT_JOB_TID, + OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_tenant_snapshot_job_aux_lob_meta_schema, + ObInnerTableSchema::all_tenant_snapshot_job_aux_lob_piece_schema + }, + { OB_ALL_TRUSTED_ROOT_CERTIFICATE_TID, OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_META_TID, @@ -11672,6 +11855,14 @@ LOBMapping const lob_aux_table_mappings [] = { ObInnerTableSchema::all_trusted_root_certificate_aux_lob_piece_schema }, + { + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_aux_lob_meta_schema, + ObInnerTableSchema::all_tenant_snapshot_ls_replica_history_aux_lob_piece_schema + }, + }; static inline bool get_sys_table_lob_aux_table_id(const uint64_t tid, uint64_t& meta_tid, uint64_t& piece_tid) @@ -11709,12 +11900,12 @@ static inline int get_sys_table_lob_aux_schema(const uint64_t tid, } const int64_t OB_CORE_TABLE_COUNT = 4; -const int64_t OB_SYS_TABLE_COUNT = 264; -const int64_t OB_VIRTUAL_TABLE_COUNT = 746; -const int64_t OB_SYS_VIEW_COUNT = 796; -const int64_t OB_SYS_TENANT_TABLE_COUNT = 1811; +const int64_t OB_SYS_TABLE_COUNT = 271; +const int64_t OB_VIRTUAL_TABLE_COUNT = 755; +const int64_t OB_SYS_VIEW_COUNT = 802; +const int64_t OB_SYS_TENANT_TABLE_COUNT = 1833; const int64_t OB_CORE_SCHEMA_VERSION = 1; -const int64_t OB_BOOTSTRAP_SCHEMA_VERSION = 1814; +const int64_t OB_BOOTSTRAP_SCHEMA_VERSION = 1836; } // end namespace share } // end namespace oceanbase diff --git a/src/share/inner_table/ob_inner_table_schema.lob.cpp b/src/share/inner_table/ob_inner_table_schema.lob.cpp index fd8fd089cd..6994ea20f4 100644 --- a/src/share/inner_table/ob_inner_table_schema.lob.cpp +++ b/src/share/inner_table/ob_inner_table_schema.lob.cpp @@ -21,7 +21,7 @@ inner_lob_map_t inner_lob_map; bool lob_mapping_init() { int ret = OB_SUCCESS; - if (OB_FAIL(inner_lob_map.create(267, ObModIds::OB_INNER_LOB_HASH_SET))) { + if (OB_FAIL(inner_lob_map.create(274, ObModIds::OB_INNER_LOB_HASH_SET))) { SERVER_LOG(WARN, "fail to create inner lob map", K(ret)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < ARRAYSIZEOF(lob_aux_table_mappings); ++i) { diff --git a/src/share/inner_table/ob_inner_table_schema_constants.h b/src/share/inner_table/ob_inner_table_schema_constants.h index 54fa70a6c3..098d206e6b 100644 --- a/src/share/inner_table/ob_inner_table_schema_constants.h +++ b/src/share/inner_table/ob_inner_table_schema_constants.h @@ -282,6 +282,9 @@ const uint64_t OB_WR_SNAPSHOT_TID = 456; // "__wr_snapshot" const uint64_t OB_WR_STATNAME_TID = 457; // "__wr_statname" const uint64_t OB_WR_SYSSTAT_TID = 458; // "__wr_sysstat" const uint64_t OB_ALL_BALANCE_TASK_HELPER_TID = 459; // "__all_balance_task_helper" +const uint64_t OB_ALL_TENANT_SNAPSHOT_TID = 460; // "__all_tenant_snapshot" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_TID = 461; // "__all_tenant_snapshot_ls" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID = 462; // "__all_tenant_snapshot_ls_replica" const uint64_t OB_ALL_DBMS_LOCK_ALLOCATED_TID = 471; // "__all_dbms_lock_allocated" const uint64_t OB_WR_CONTROL_TID = 472; // "__wr_control" const uint64_t OB_ALL_TENANT_EVENT_HISTORY_TID = 473; // "__all_tenant_event_history" @@ -292,9 +295,13 @@ const uint64_t OB_ALL_IMPORT_TABLE_JOB_TID = 477; // "__all_import_table_job" const uint64_t OB_ALL_IMPORT_TABLE_JOB_HISTORY_TID = 478; // "__all_import_table_job_history" const uint64_t OB_ALL_IMPORT_TABLE_TASK_TID = 479; // "__all_import_table_task" const uint64_t OB_ALL_IMPORT_TABLE_TASK_HISTORY_TID = 480; // "__all_import_table_task_history" +const uint64_t OB_ALL_CLONE_JOB_TID = 485; // "__all_clone_job" +const uint64_t OB_ALL_CLONE_JOB_HISTORY_TID = 486; // "__all_clone_job_history" const uint64_t OB_ALL_AUX_STAT_TID = 494; // "__all_aux_stat" const uint64_t OB_ALL_INDEX_USAGE_INFO_TID = 495; // "__all_index_usage_info" +const uint64_t OB_ALL_TENANT_SNAPSHOT_JOB_TID = 500; // "__all_tenant_snapshot_job" const uint64_t OB_ALL_TRUSTED_ROOT_CERTIFICATE_TID = 502; // "__all_trusted_root_certificate" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID = 507; // "__all_tenant_snapshot_ls_replica_history" const uint64_t OB_TENANT_VIRTUAL_ALL_TABLE_TID = 10001; // "__tenant_virtual_all_table" const uint64_t OB_TENANT_VIRTUAL_TABLE_COLUMN_TID = 10002; // "__tenant_virtual_table_column" const uint64_t OB_TENANT_VIRTUAL_TABLE_INDEX_TID = 10003; // "__tenant_virtual_table_index" @@ -685,6 +692,9 @@ const uint64_t OB_ALL_VIRTUAL_COLUMN_GROUP_TID = 12398; // "__all_virtual_column const uint64_t OB_ALL_VIRTUAL_STORAGE_LEAK_INFO_TID = 12399; // "__all_virtual_storage_leak_info" const uint64_t OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TID = 12400; // "__all_virtual_ls_log_restore_status" const uint64_t OB_ALL_VIRTUAL_TENANT_PARAMETER_TID = 12401; // "__all_virtual_tenant_parameter" +const uint64_t OB_ALL_VIRTUAL_TENANT_SNAPSHOT_TID = 12402; // "__all_virtual_tenant_snapshot" +const uint64_t OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_TID = 12403; // "__all_virtual_tenant_snapshot_ls" +const uint64_t OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TID = 12404; // "__all_virtual_tenant_snapshot_ls_replica" const uint64_t OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_TID = 12405; // "__all_virtual_tablet_buffer_info" const uint64_t OB_ALL_VIRTUAL_WR_CONTROL_TID = 12414; // "__all_virtual_wr_control" const uint64_t OB_ALL_VIRTUAL_TENANT_EVENT_HISTORY_TID = 12415; // "__all_virtual_tenant_event_history" @@ -698,8 +708,13 @@ const uint64_t OB_ALL_VIRTUAL_IMPORT_TABLE_JOB_TID = 12424; // "__all_virtual_im const uint64_t OB_ALL_VIRTUAL_IMPORT_TABLE_JOB_HISTORY_TID = 12425; // "__all_virtual_import_table_job_history" const uint64_t OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_TID = 12426; // "__all_virtual_import_table_task" const uint64_t OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_TID = 12427; // "__all_virtual_import_table_task_history" +const uint64_t OB_ALL_VIRTUAL_CLONE_JOB_TID = 12435; // "__all_virtual_clone_job" +const uint64_t OB_ALL_VIRTUAL_CLONE_JOB_HISTORY_TID = 12436; // "__all_virtual_clone_job_history" const uint64_t OB_ALL_VIRTUAL_AUX_STAT_TID = 12447; // "__all_virtual_aux_stat" +const uint64_t OB_ALL_VIRTUAL_TENANT_SNAPSHOT_JOB_TID = 12453; // "__all_virtual_tenant_snapshot_job" +const uint64_t OB_ALL_VIRTUAL_LS_SNAPSHOT_TID = 12458; // "__all_virtual_ls_snapshot" const uint64_t OB_ALL_VIRTUAL_INDEX_USAGE_INFO_TID = 12459; // "__all_virtual_index_usage_info" +const uint64_t OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID = 12464; // "__all_virtual_tenant_snapshot_ls_replica_history" const uint64_t OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TID = 15009; // "ALL_VIRTUAL_SQL_AUDIT_ORA" const uint64_t OB_ALL_VIRTUAL_PLAN_STAT_ORA_TID = 15010; // "ALL_VIRTUAL_PLAN_STAT_ORA" const uint64_t OB_ALL_VIRTUAL_PLAN_CACHE_PLAN_EXPLAIN_ORA_TID = 15012; // "ALL_VIRTUAL_PLAN_CACHE_PLAN_EXPLAIN_ORA" @@ -949,6 +964,7 @@ const uint64_t OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_ORA_TID = 15411; // "ALL_VIRTUAL const uint64_t OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_ORA_TID = 15412; // "ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_ORA" const uint64_t OB_ALL_VIRTUAL_LS_INFO_ORA_TID = 15414; // "ALL_VIRTUAL_LS_INFO_ORA" const uint64_t OB_ALL_VIRTUAL_AUX_STAT_REAL_AGENT_ORA_TID = 15427; // "ALL_VIRTUAL_AUX_STAT_REAL_AGENT_ORA" +const uint64_t OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TID = 15439; // "ALL_VIRTUAL_LS_SNAPSHOT_ORA" const uint64_t OB_ALL_VIRTUAL_INDEX_USAGE_INFO_REAL_AGENT_ORA_TID = 15440; // "ALL_VIRTUAL_INDEX_USAGE_INFO_REAL_AGENT_ORA" const uint64_t OB_GV_OB_PLAN_CACHE_STAT_TID = 20001; // "GV$OB_PLAN_CACHE_STAT" const uint64_t OB_GV_OB_PLAN_CACHE_PLAN_STAT_TID = 20002; // "GV$OB_PLAN_CACHE_PLAN_STAT" @@ -1321,7 +1337,11 @@ const uint64_t OB_DBA_OB_AUX_STATISTICS_TID = 21497; // "DBA_OB_AUX_STATISTICS" const uint64_t OB_CDB_OB_AUX_STATISTICS_TID = 21498; // "CDB_OB_AUX_STATISTICS" const uint64_t OB_DBA_INDEX_USAGE_TID = 21499; // "DBA_INDEX_USAGE" const uint64_t OB_DBA_OB_TRUSTED_ROOT_CERTIFICATE_TID = 21509; // "DBA_OB_TRUSTED_ROOT_CERTIFICATE" +const uint64_t OB_DBA_OB_CLONE_PROGRESS_TID = 21510; // "DBA_OB_CLONE_PROGRESS" const uint64_t OB_CDB_INDEX_USAGE_TID = 21513; // "CDB_INDEX_USAGE" +const uint64_t OB_GV_OB_LS_SNAPSHOTS_TID = 21517; // "GV$OB_LS_SNAPSHOTS" +const uint64_t OB_V_OB_LS_SNAPSHOTS_TID = 21518; // "V$OB_LS_SNAPSHOTS" +const uint64_t OB_DBA_OB_CLONE_HISTORY_TID = 21519; // "DBA_OB_CLONE_HISTORY" const uint64_t OB_DBA_SYNONYMS_TID = 25001; // "DBA_SYNONYMS" const uint64_t OB_DBA_OBJECTS_ORA_TID = 25002; // "DBA_OBJECTS_ORA" const uint64_t OB_ALL_OBJECTS_TID = 25003; // "ALL_OBJECTS" @@ -1746,6 +1766,8 @@ const uint64_t OB_V_OB_LS_LOG_RESTORE_STATUS_ORA_TID = 28194; // "V$OB_LS_LOG_RE const uint64_t OB_GV_OB_FLT_TRACE_CONFIG_ORA_TID = 28195; // "GV$OB_FLT_TRACE_CONFIG_ORA" const uint64_t OB_DBA_OB_AUX_STATISTICS_ORA_TID = 28210; // "DBA_OB_AUX_STATISTICS_ORA" const uint64_t OB_DBA_INDEX_USAGE_ORA_TID = 28214; // "DBA_INDEX_USAGE_ORA" +const uint64_t OB_GV_OB_LS_SNAPSHOTS_ORA_TID = 28215; // "GV$OB_LS_SNAPSHOTS_ORA" +const uint64_t OB_V_OB_LS_SNAPSHOTS_ORA_TID = 28216; // "V$OB_LS_SNAPSHOTS_ORA" const uint64_t OB_ALL_TABLE_AUX_LOB_META_TID = 50003; // "__all_table_aux_lob_meta" const uint64_t OB_ALL_COLUMN_AUX_LOB_META_TID = 50004; // "__all_column_aux_lob_meta" const uint64_t OB_ALL_DDL_OPERATION_AUX_LOB_META_TID = 50005; // "__all_ddl_operation_aux_lob_meta" @@ -2000,6 +2022,9 @@ const uint64_t OB_WR_SNAPSHOT_AUX_LOB_META_TID = 50456; // "__wr_snapshot_aux_lo const uint64_t OB_WR_STATNAME_AUX_LOB_META_TID = 50457; // "__wr_statname_aux_lob_meta" const uint64_t OB_WR_SYSSTAT_AUX_LOB_META_TID = 50458; // "__wr_sysstat_aux_lob_meta" const uint64_t OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID = 50459; // "__all_balance_task_helper_aux_lob_meta" +const uint64_t OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TID = 50460; // "__all_tenant_snapshot_aux_lob_meta" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TID = 50461; // "__all_tenant_snapshot_ls_aux_lob_meta" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TID = 50462; // "__all_tenant_snapshot_ls_replica_aux_lob_meta" const uint64_t OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_META_TID = 50471; // "__all_dbms_lock_allocated_aux_lob_meta" const uint64_t OB_WR_CONTROL_AUX_LOB_META_TID = 50472; // "__wr_control_aux_lob_meta" const uint64_t OB_ALL_TENANT_EVENT_HISTORY_AUX_LOB_META_TID = 50473; // "__all_tenant_event_history_aux_lob_meta" @@ -2010,9 +2035,13 @@ const uint64_t OB_ALL_IMPORT_TABLE_JOB_AUX_LOB_META_TID = 50477; // "__all_impor const uint64_t OB_ALL_IMPORT_TABLE_JOB_HISTORY_AUX_LOB_META_TID = 50478; // "__all_import_table_job_history_aux_lob_meta" const uint64_t OB_ALL_IMPORT_TABLE_TASK_AUX_LOB_META_TID = 50479; // "__all_import_table_task_aux_lob_meta" const uint64_t OB_ALL_IMPORT_TABLE_TASK_HISTORY_AUX_LOB_META_TID = 50480; // "__all_import_table_task_history_aux_lob_meta" +const uint64_t OB_ALL_CLONE_JOB_AUX_LOB_META_TID = 50485; // "__all_clone_job_aux_lob_meta" +const uint64_t OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TID = 50486; // "__all_clone_job_history_aux_lob_meta" const uint64_t OB_ALL_AUX_STAT_AUX_LOB_META_TID = 50494; // "__all_aux_stat_aux_lob_meta" const uint64_t OB_ALL_INDEX_USAGE_INFO_AUX_LOB_META_TID = 50495; // "__all_index_usage_info_aux_lob_meta" +const uint64_t OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TID = 50500; // "__all_tenant_snapshot_job_aux_lob_meta" const uint64_t OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_META_TID = 50502; // "__all_trusted_root_certificate_aux_lob_meta" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID = 50507; // "__all_tenant_snapshot_ls_replica_history_aux_lob_meta" const uint64_t OB_ALL_TABLE_AUX_LOB_PIECE_TID = 60003; // "__all_table_aux_lob_piece" const uint64_t OB_ALL_COLUMN_AUX_LOB_PIECE_TID = 60004; // "__all_column_aux_lob_piece" const uint64_t OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TID = 60005; // "__all_ddl_operation_aux_lob_piece" @@ -2267,6 +2296,9 @@ const uint64_t OB_WR_SNAPSHOT_AUX_LOB_PIECE_TID = 60456; // "__wr_snapshot_aux_l const uint64_t OB_WR_STATNAME_AUX_LOB_PIECE_TID = 60457; // "__wr_statname_aux_lob_piece" const uint64_t OB_WR_SYSSTAT_AUX_LOB_PIECE_TID = 60458; // "__wr_sysstat_aux_lob_piece" const uint64_t OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID = 60459; // "__all_balance_task_helper_aux_lob_piece" +const uint64_t OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TID = 60460; // "__all_tenant_snapshot_aux_lob_piece" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TID = 60461; // "__all_tenant_snapshot_ls_aux_lob_piece" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TID = 60462; // "__all_tenant_snapshot_ls_replica_aux_lob_piece" const uint64_t OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_PIECE_TID = 60471; // "__all_dbms_lock_allocated_aux_lob_piece" const uint64_t OB_WR_CONTROL_AUX_LOB_PIECE_TID = 60472; // "__wr_control_aux_lob_piece" const uint64_t OB_ALL_TENANT_EVENT_HISTORY_AUX_LOB_PIECE_TID = 60473; // "__all_tenant_event_history_aux_lob_piece" @@ -2277,9 +2309,13 @@ const uint64_t OB_ALL_IMPORT_TABLE_JOB_AUX_LOB_PIECE_TID = 60477; // "__all_impo const uint64_t OB_ALL_IMPORT_TABLE_JOB_HISTORY_AUX_LOB_PIECE_TID = 60478; // "__all_import_table_job_history_aux_lob_piece" const uint64_t OB_ALL_IMPORT_TABLE_TASK_AUX_LOB_PIECE_TID = 60479; // "__all_import_table_task_aux_lob_piece" const uint64_t OB_ALL_IMPORT_TABLE_TASK_HISTORY_AUX_LOB_PIECE_TID = 60480; // "__all_import_table_task_history_aux_lob_piece" +const uint64_t OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID = 60485; // "__all_clone_job_aux_lob_piece" +const uint64_t OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TID = 60486; // "__all_clone_job_history_aux_lob_piece" const uint64_t OB_ALL_AUX_STAT_AUX_LOB_PIECE_TID = 60494; // "__all_aux_stat_aux_lob_piece" const uint64_t OB_ALL_INDEX_USAGE_INFO_AUX_LOB_PIECE_TID = 60495; // "__all_index_usage_info_aux_lob_piece" +const uint64_t OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TID = 60500; // "__all_tenant_snapshot_job_aux_lob_piece" const uint64_t OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_PIECE_TID = 60502; // "__all_trusted_root_certificate_aux_lob_piece" +const uint64_t OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID = 60507; // "__all_tenant_snapshot_ls_replica_history_aux_lob_piece" const uint64_t OB_ALL_VIRTUAL_PLAN_CACHE_STAT_ALL_VIRTUAL_PLAN_CACHE_STAT_I1_TID = 14999; // "__all_virtual_plan_cache_stat" const uint64_t OB_ALL_VIRTUAL_SESSION_EVENT_ALL_VIRTUAL_SESSION_EVENT_I1_TID = 14998; // "__all_virtual_session_event" const uint64_t OB_ALL_VIRTUAL_SESSION_WAIT_ALL_VIRTUAL_SESSION_WAIT_I1_TID = 14997; // "__all_virtual_session_wait" @@ -2393,6 +2429,7 @@ const uint64_t OB_ALL_RLS_GROUP_IDX_RLS_GROUP_TABLE_ID_TID = 101085; // "__all_r const uint64_t OB_ALL_RLS_GROUP_HISTORY_IDX_RLS_GROUP_HIS_TABLE_ID_TID = 101086; // "__all_rls_group_history" const uint64_t OB_ALL_RLS_CONTEXT_IDX_RLS_CONTEXT_TABLE_ID_TID = 101087; // "__all_rls_context" const uint64_t OB_ALL_RLS_CONTEXT_HISTORY_IDX_RLS_CONTEXT_HIS_TABLE_ID_TID = 101088; // "__all_rls_context_history" +const uint64_t OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TID = 101089; // "__all_tenant_snapshot" const uint64_t OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_LOCKHANDLE_TID = 101090; // "__all_dbms_lock_allocated" const uint64_t OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_EXPIRATION_TID = 101091; // "__all_dbms_lock_allocated" const uint64_t OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TID = 101093; // "__all_kv_ttl_task" @@ -2725,6 +2762,9 @@ const char *const OB_WR_SNAPSHOT_TNAME = "__wr_snapshot"; const char *const OB_WR_STATNAME_TNAME = "__wr_statname"; const char *const OB_WR_SYSSTAT_TNAME = "__wr_sysstat"; const char *const OB_ALL_BALANCE_TASK_HELPER_TNAME = "__all_balance_task_helper"; +const char *const OB_ALL_TENANT_SNAPSHOT_TNAME = "__all_tenant_snapshot"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_TNAME = "__all_tenant_snapshot_ls"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME = "__all_tenant_snapshot_ls_replica"; const char *const OB_ALL_DBMS_LOCK_ALLOCATED_TNAME = "__all_dbms_lock_allocated"; const char *const OB_WR_CONTROL_TNAME = "__wr_control"; const char *const OB_ALL_TENANT_EVENT_HISTORY_TNAME = "__all_tenant_event_history"; @@ -2735,9 +2775,13 @@ const char *const OB_ALL_IMPORT_TABLE_JOB_TNAME = "__all_import_table_job"; const char *const OB_ALL_IMPORT_TABLE_JOB_HISTORY_TNAME = "__all_import_table_job_history"; const char *const OB_ALL_IMPORT_TABLE_TASK_TNAME = "__all_import_table_task"; const char *const OB_ALL_IMPORT_TABLE_TASK_HISTORY_TNAME = "__all_import_table_task_history"; +const char *const OB_ALL_CLONE_JOB_TNAME = "__all_clone_job"; +const char *const OB_ALL_CLONE_JOB_HISTORY_TNAME = "__all_clone_job_history"; const char *const OB_ALL_AUX_STAT_TNAME = "__all_aux_stat"; const char *const OB_ALL_INDEX_USAGE_INFO_TNAME = "__all_index_usage_info"; +const char *const OB_ALL_TENANT_SNAPSHOT_JOB_TNAME = "__all_tenant_snapshot_job"; const char *const OB_ALL_TRUSTED_ROOT_CERTIFICATE_TNAME = "__all_trusted_root_certificate"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME = "__all_tenant_snapshot_ls_replica_history"; const char *const OB_TENANT_VIRTUAL_ALL_TABLE_TNAME = "__tenant_virtual_all_table"; const char *const OB_TENANT_VIRTUAL_TABLE_COLUMN_TNAME = "__tenant_virtual_table_column"; const char *const OB_TENANT_VIRTUAL_TABLE_INDEX_TNAME = "__tenant_virtual_table_index"; @@ -3128,6 +3172,9 @@ const char *const OB_ALL_VIRTUAL_COLUMN_GROUP_TNAME = "__all_virtual_column_grou const char *const OB_ALL_VIRTUAL_STORAGE_LEAK_INFO_TNAME = "__all_virtual_storage_leak_info"; const char *const OB_ALL_VIRTUAL_LS_LOG_RESTORE_STATUS_TNAME = "__all_virtual_ls_log_restore_status"; const char *const OB_ALL_VIRTUAL_TENANT_PARAMETER_TNAME = "__all_virtual_tenant_parameter"; +const char *const OB_ALL_VIRTUAL_TENANT_SNAPSHOT_TNAME = "__all_virtual_tenant_snapshot"; +const char *const OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_TNAME = "__all_virtual_tenant_snapshot_ls"; +const char *const OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TNAME = "__all_virtual_tenant_snapshot_ls_replica"; const char *const OB_ALL_VIRTUAL_TABLET_BUFFER_INFO_TNAME = "__all_virtual_tablet_buffer_info"; const char *const OB_ALL_VIRTUAL_WR_CONTROL_TNAME = "__all_virtual_wr_control"; const char *const OB_ALL_VIRTUAL_TENANT_EVENT_HISTORY_TNAME = "__all_virtual_tenant_event_history"; @@ -3141,8 +3188,13 @@ const char *const OB_ALL_VIRTUAL_IMPORT_TABLE_JOB_TNAME = "__all_virtual_import_ const char *const OB_ALL_VIRTUAL_IMPORT_TABLE_JOB_HISTORY_TNAME = "__all_virtual_import_table_job_history"; const char *const OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_TNAME = "__all_virtual_import_table_task"; const char *const OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_TNAME = "__all_virtual_import_table_task_history"; +const char *const OB_ALL_VIRTUAL_CLONE_JOB_TNAME = "__all_virtual_clone_job"; +const char *const OB_ALL_VIRTUAL_CLONE_JOB_HISTORY_TNAME = "__all_virtual_clone_job_history"; const char *const OB_ALL_VIRTUAL_AUX_STAT_TNAME = "__all_virtual_aux_stat"; +const char *const OB_ALL_VIRTUAL_TENANT_SNAPSHOT_JOB_TNAME = "__all_virtual_tenant_snapshot_job"; +const char *const OB_ALL_VIRTUAL_LS_SNAPSHOT_TNAME = "__all_virtual_ls_snapshot"; const char *const OB_ALL_VIRTUAL_INDEX_USAGE_INFO_TNAME = "__all_virtual_index_usage_info"; +const char *const OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME = "__all_virtual_tenant_snapshot_ls_replica_history"; const char *const OB_ALL_VIRTUAL_SQL_AUDIT_ORA_TNAME = "ALL_VIRTUAL_SQL_AUDIT"; const char *const OB_ALL_VIRTUAL_PLAN_STAT_ORA_TNAME = "ALL_VIRTUAL_PLAN_STAT"; const char *const OB_ALL_VIRTUAL_PLAN_CACHE_PLAN_EXPLAIN_ORA_TNAME = "ALL_VIRTUAL_PLAN_CACHE_PLAN_EXPLAIN"; @@ -3392,6 +3444,7 @@ const char *const OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_ORA_TNAME = "ALL_VIRTUAL_IMPO const char *const OB_ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY_ORA_TNAME = "ALL_VIRTUAL_IMPORT_TABLE_TASK_HISTORY"; const char *const OB_ALL_VIRTUAL_LS_INFO_ORA_TNAME = "ALL_VIRTUAL_LS_INFO"; const char *const OB_ALL_VIRTUAL_AUX_STAT_REAL_AGENT_ORA_TNAME = "ALL_VIRTUAL_AUX_STAT_REAL_AGENT"; +const char *const OB_ALL_VIRTUAL_LS_SNAPSHOT_ORA_TNAME = "ALL_VIRTUAL_LS_SNAPSHOT"; const char *const OB_ALL_VIRTUAL_INDEX_USAGE_INFO_REAL_AGENT_ORA_TNAME = "ALL_VIRTUAL_INDEX_USAGE_INFO_REAL_AGENT"; const char *const OB_GV_OB_PLAN_CACHE_STAT_TNAME = "GV$OB_PLAN_CACHE_STAT"; const char *const OB_GV_OB_PLAN_CACHE_PLAN_STAT_TNAME = "GV$OB_PLAN_CACHE_PLAN_STAT"; @@ -3764,7 +3817,11 @@ const char *const OB_DBA_OB_AUX_STATISTICS_TNAME = "DBA_OB_AUX_STATISTICS"; const char *const OB_CDB_OB_AUX_STATISTICS_TNAME = "CDB_OB_AUX_STATISTICS"; const char *const OB_DBA_INDEX_USAGE_TNAME = "DBA_INDEX_USAGE"; const char *const OB_DBA_OB_TRUSTED_ROOT_CERTIFICATE_TNAME = "DBA_OB_TRUSTED_ROOT_CERTIFICATE"; +const char *const OB_DBA_OB_CLONE_PROGRESS_TNAME = "DBA_OB_CLONE_PROGRESS"; const char *const OB_CDB_INDEX_USAGE_TNAME = "CDB_INDEX_USAGE"; +const char *const OB_GV_OB_LS_SNAPSHOTS_TNAME = "GV$OB_LS_SNAPSHOTS"; +const char *const OB_V_OB_LS_SNAPSHOTS_TNAME = "V$OB_LS_SNAPSHOTS"; +const char *const OB_DBA_OB_CLONE_HISTORY_TNAME = "DBA_OB_CLONE_HISTORY"; const char *const OB_DBA_SYNONYMS_TNAME = "DBA_SYNONYMS"; const char *const OB_DBA_OBJECTS_ORA_TNAME = "DBA_OBJECTS"; const char *const OB_ALL_OBJECTS_TNAME = "ALL_OBJECTS"; @@ -4189,6 +4246,8 @@ const char *const OB_V_OB_LS_LOG_RESTORE_STATUS_ORA_TNAME = "V$OB_LS_LOG_RESTORE const char *const OB_GV_OB_FLT_TRACE_CONFIG_ORA_TNAME = "GV$OB_FLT_TRACE_CONFIG"; const char *const OB_DBA_OB_AUX_STATISTICS_ORA_TNAME = "DBA_OB_AUX_STATISTICS"; const char *const OB_DBA_INDEX_USAGE_ORA_TNAME = "DBA_INDEX_USAGE"; +const char *const OB_GV_OB_LS_SNAPSHOTS_ORA_TNAME = "GV$OB_LS_SNAPSHOTS"; +const char *const OB_V_OB_LS_SNAPSHOTS_ORA_TNAME = "V$OB_LS_SNAPSHOTS"; const char *const OB_ALL_TABLE_AUX_LOB_META_TNAME = "__all_table_aux_lob_meta"; const char *const OB_ALL_COLUMN_AUX_LOB_META_TNAME = "__all_column_aux_lob_meta"; const char *const OB_ALL_DDL_OPERATION_AUX_LOB_META_TNAME = "__all_ddl_operation_aux_lob_meta"; @@ -4443,6 +4502,9 @@ const char *const OB_WR_SNAPSHOT_AUX_LOB_META_TNAME = "__wr_snapshot_aux_lob_met const char *const OB_WR_STATNAME_AUX_LOB_META_TNAME = "__wr_statname_aux_lob_meta"; const char *const OB_WR_SYSSTAT_AUX_LOB_META_TNAME = "__wr_sysstat_aux_lob_meta"; const char *const OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TNAME = "__all_balance_task_helper_aux_lob_meta"; +const char *const OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TNAME = "__all_tenant_snapshot_aux_lob_meta"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TNAME = "__all_tenant_snapshot_ls_aux_lob_meta"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TNAME = "__all_tenant_snapshot_ls_replica_aux_lob_meta"; const char *const OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_META_TNAME = "__all_dbms_lock_allocated_aux_lob_meta"; const char *const OB_WR_CONTROL_AUX_LOB_META_TNAME = "__wr_control_aux_lob_meta"; const char *const OB_ALL_TENANT_EVENT_HISTORY_AUX_LOB_META_TNAME = "__all_tenant_event_history_aux_lob_meta"; @@ -4453,9 +4515,13 @@ const char *const OB_ALL_IMPORT_TABLE_JOB_AUX_LOB_META_TNAME = "__all_import_tab const char *const OB_ALL_IMPORT_TABLE_JOB_HISTORY_AUX_LOB_META_TNAME = "__all_import_table_job_history_aux_lob_meta"; const char *const OB_ALL_IMPORT_TABLE_TASK_AUX_LOB_META_TNAME = "__all_import_table_task_aux_lob_meta"; const char *const OB_ALL_IMPORT_TABLE_TASK_HISTORY_AUX_LOB_META_TNAME = "__all_import_table_task_history_aux_lob_meta"; +const char *const OB_ALL_CLONE_JOB_AUX_LOB_META_TNAME = "__all_clone_job_aux_lob_meta"; +const char *const OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TNAME = "__all_clone_job_history_aux_lob_meta"; const char *const OB_ALL_AUX_STAT_AUX_LOB_META_TNAME = "__all_aux_stat_aux_lob_meta"; const char *const OB_ALL_INDEX_USAGE_INFO_AUX_LOB_META_TNAME = "__all_index_usage_info_aux_lob_meta"; +const char *const OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TNAME = "__all_tenant_snapshot_job_aux_lob_meta"; const char *const OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_META_TNAME = "__all_trusted_root_certificate_aux_lob_meta"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TNAME = "__all_tenant_snapshot_ls_replica_history_aux_lob_meta"; const char *const OB_ALL_TABLE_AUX_LOB_PIECE_TNAME = "__all_table_aux_lob_piece"; const char *const OB_ALL_COLUMN_AUX_LOB_PIECE_TNAME = "__all_column_aux_lob_piece"; const char *const OB_ALL_DDL_OPERATION_AUX_LOB_PIECE_TNAME = "__all_ddl_operation_aux_lob_piece"; @@ -4710,6 +4776,9 @@ const char *const OB_WR_SNAPSHOT_AUX_LOB_PIECE_TNAME = "__wr_snapshot_aux_lob_pi const char *const OB_WR_STATNAME_AUX_LOB_PIECE_TNAME = "__wr_statname_aux_lob_piece"; const char *const OB_WR_SYSSTAT_AUX_LOB_PIECE_TNAME = "__wr_sysstat_aux_lob_piece"; const char *const OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TNAME = "__all_balance_task_helper_aux_lob_piece"; +const char *const OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TNAME = "__all_tenant_snapshot_aux_lob_piece"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TNAME = "__all_tenant_snapshot_ls_aux_lob_piece"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TNAME = "__all_tenant_snapshot_ls_replica_aux_lob_piece"; const char *const OB_ALL_DBMS_LOCK_ALLOCATED_AUX_LOB_PIECE_TNAME = "__all_dbms_lock_allocated_aux_lob_piece"; const char *const OB_WR_CONTROL_AUX_LOB_PIECE_TNAME = "__wr_control_aux_lob_piece"; const char *const OB_ALL_TENANT_EVENT_HISTORY_AUX_LOB_PIECE_TNAME = "__all_tenant_event_history_aux_lob_piece"; @@ -4720,9 +4789,13 @@ const char *const OB_ALL_IMPORT_TABLE_JOB_AUX_LOB_PIECE_TNAME = "__all_import_ta const char *const OB_ALL_IMPORT_TABLE_JOB_HISTORY_AUX_LOB_PIECE_TNAME = "__all_import_table_job_history_aux_lob_piece"; const char *const OB_ALL_IMPORT_TABLE_TASK_AUX_LOB_PIECE_TNAME = "__all_import_table_task_aux_lob_piece"; const char *const OB_ALL_IMPORT_TABLE_TASK_HISTORY_AUX_LOB_PIECE_TNAME = "__all_import_table_task_history_aux_lob_piece"; +const char *const OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TNAME = "__all_clone_job_aux_lob_piece"; +const char *const OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TNAME = "__all_clone_job_history_aux_lob_piece"; const char *const OB_ALL_AUX_STAT_AUX_LOB_PIECE_TNAME = "__all_aux_stat_aux_lob_piece"; const char *const OB_ALL_INDEX_USAGE_INFO_AUX_LOB_PIECE_TNAME = "__all_index_usage_info_aux_lob_piece"; +const char *const OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TNAME = "__all_tenant_snapshot_job_aux_lob_piece"; const char *const OB_ALL_TRUSTED_ROOT_CERTIFICATE_AUX_LOB_PIECE_TNAME = "__all_trusted_root_certificate_aux_lob_piece"; +const char *const OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TNAME = "__all_tenant_snapshot_ls_replica_history_aux_lob_piece"; const char *const OB_ALL_VIRTUAL_PLAN_CACHE_STAT_ALL_VIRTUAL_PLAN_CACHE_STAT_I1_TNAME = "__idx_11003_all_virtual_plan_cache_stat_i1"; const char *const OB_ALL_VIRTUAL_SESSION_EVENT_ALL_VIRTUAL_SESSION_EVENT_I1_TNAME = "__idx_11013_all_virtual_session_event_i1"; const char *const OB_ALL_VIRTUAL_SESSION_WAIT_ALL_VIRTUAL_SESSION_WAIT_I1_TNAME = "__idx_11014_all_virtual_session_wait_i1"; @@ -4836,6 +4909,7 @@ const char *const OB_ALL_RLS_GROUP_IDX_RLS_GROUP_TABLE_ID_TNAME = "__idx_437_idx const char *const OB_ALL_RLS_GROUP_HISTORY_IDX_RLS_GROUP_HIS_TABLE_ID_TNAME = "__idx_438_idx_rls_group_his_table_id"; const char *const OB_ALL_RLS_CONTEXT_IDX_RLS_CONTEXT_TABLE_ID_TNAME = "__idx_439_idx_rls_context_table_id"; const char *const OB_ALL_RLS_CONTEXT_HISTORY_IDX_RLS_CONTEXT_HIS_TABLE_ID_TNAME = "__idx_440_idx_rls_context_his_table_id"; +const char *const OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TNAME = "__idx_460_idx_tenant_snapshot_name"; const char *const OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_LOCKHANDLE_TNAME = "__idx_471_idx_dbms_lock_allocated_lockhandle"; const char *const OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_EXPIRATION_TNAME = "__idx_471_idx_dbms_lock_allocated_expiration"; const char *const OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TNAME = "__idx_410_idx_kv_ttl_task_table_id"; 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 54c380b54e..77454a01b7 100644 --- a/src/share/inner_table/ob_inner_table_schema_def.py +++ b/src/share/inner_table/ob_inner_table_schema_def.py @@ -5927,9 +5927,79 @@ def_table_schema( ('ls_group_id', 'int', 'false'), ], ) -# 460 : __all_tenant_snapshot -# 461 : __all_tenant_snapshot_ls -# 462 : __all_virtual_tenant_snapshot_ls_replica + +def_table_schema( + owner = 'chensen.cs', + table_name = '__all_tenant_snapshot', + table_id = '460', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('tenant_id', 'int'), + ('snapshot_id', 'int', 'false'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + normal_columns = [ + ('snapshot_name', 'varchar:OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE', 'false'), + ('status', 'varchar:32', 'false'), + ('snapshot_scn', 'uint', 'false'), + ('clog_start_scn', 'uint', 'false'), + ('type', 'varchar:16', 'false'), + ('create_time', 'timestamp', 'false'), + ('data_version', 'uint', 'false'), + ('owner_job_id', 'int', 'false') + ], +) + +def_table_schema( + owner = 'chensen.cs', + table_name = '__all_tenant_snapshot_ls', + table_id = '461', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('tenant_id', 'int'), + ('snapshot_id', 'int', 'false'), + ('ls_id', 'int', 'false'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + normal_columns = [ + ('ls_group_id', 'int', 'false'), + ('status', 'varchar:100', 'false'), + ('flag', 'varchar:OB_MAX_LS_FLAG_LENGTH', 'false'), + ('create_scn', 'uint', 'false'), + ], +) + +def_table_schema( + owner = 'chensen.cs', + table_name = '__all_tenant_snapshot_ls_replica', + table_id = '462', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('tenant_id', 'int'), + ('snapshot_id', 'int', 'false'), + ('ls_id', 'int', 'false'), + ('svr_ip', 'varchar:MAX_IP_ADDR_LENGTH', 'false'), + ('svr_port', 'int', 'false'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + normal_columns = [ + ('status', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false'), + ('zone', 'varchar:MAX_ZONE_LENGTH', 'false'), + ('unit_id', 'int', 'false'), + ('begin_interval_scn', 'uint', 'false'), + ('end_interval_scn', 'uint', 'false'), + ('ls_meta_package', 'longtext', 'true') + ], +) # 463 : __all_mlogs # 464 : __all_mviews @@ -6361,8 +6431,75 @@ def_table_schema( # 483 : __all_storage_ha_error_diagnose # 484 : __all_storage_ha_perf_diagnose -# 485 : __all_clone_job -# 486 : __all_clone_job_history +def_table_schema( + owner = 'chensen.cs', + table_name = '__all_clone_job', + table_id = '485', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('tenant_id', 'int'), + ('job_id', 'int'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + normal_columns = [ + ('trace_id', 'varchar:OB_MAX_TRACE_ID_BUFFER_SIZE', 'false'), + ('source_tenant_id', 'int', 'false'), + ('source_tenant_name', 'varchar:OB_MAX_TENANT_NAME_LENGTH_STORE', 'false'), + ('clone_tenant_id', 'int', 'false', 'OB_INVALID_TENANT_ID'), + ('clone_tenant_name', 'varchar:OB_MAX_TENANT_NAME_LENGTH_STORE', 'false'), + ('tenant_snapshot_id', 'int', 'false'), + ('tenant_snapshot_name', 'varchar:OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE', 'false'), + ('resource_pool_id', 'int', 'false'), + ('resource_pool_name', 'varchar:MAX_RESOURCE_POOL_LENGTH', 'false'), + ('unit_config_name', 'varchar:MAX_UNIT_CONFIG_LENGTH', 'false'), + ('restore_scn', 'uint', 'false', '0'), + ('status', 'varchar:64', 'false'), + ('job_type', 'varchar:16', 'false'), + ('clone_start_time', 'timestamp', 'false'), + ('clone_finished_time', 'timestamp', 'true'), + ('ret_code', 'int', 'true'), + ('error_msg', 'varchar:OB_MAX_ERROR_MSG_LEN', 'true'), + ], +) + +all_clone_job_history_def = dict( + owner = 'chensen.cs', + table_name = '__all_clone_job_history', + table_id = '486', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('tenant_id', 'int'), + ('job_id', 'int'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + normal_columns = [ + ('trace_id', 'varchar:OB_MAX_TRACE_ID_BUFFER_SIZE', 'false'), + ('source_tenant_id', 'int', 'false'), + ('source_tenant_name', 'varchar:OB_MAX_TENANT_NAME_LENGTH_STORE', 'false'), + ('clone_tenant_id', 'int', 'false', 'OB_INVALID_TENANT_ID'), + ('clone_tenant_name', 'varchar:OB_MAX_TENANT_NAME_LENGTH_STORE', 'false'), + ('tenant_snapshot_id', 'int', 'false'), + ('tenant_snapshot_name', 'varchar:OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH_STORE', 'false'), + ('resource_pool_id', 'int', 'false'), + ('resource_pool_name', 'varchar:MAX_RESOURCE_POOL_LENGTH', 'false'), + ('unit_config_name', 'varchar:MAX_UNIT_CONFIG_LENGTH', 'false'), + ('restore_scn', 'uint', 'false', '0'), + ('status', 'varchar:64', 'false'), + ('job_type', 'varchar:16', 'false'), + ('clone_start_time', 'timestamp', 'false'), + ('clone_finished_time', 'timestamp', 'false'), + ('ret_code', 'int', 'true'), + ('error_msg', 'varchar:OB_MAX_ERROR_MSG_LEN', 'true'), + ], +) +def_table_schema(**all_clone_job_history_def) + # 487 : __wr_system_event # 488 : __wr_event_name # 489 : __all_tenant_scheduler_running_job @@ -6427,7 +6564,28 @@ def_table_schema( # 497 : __all_client_to_server_session_info # 498 :__all_transfer_partition_task # 499 :__all_transfer_partition_task_history -# 500 : __all_tenant_snapshot_create_job + +def_table_schema( + owner = 'chensen.cs', + table_name = '__all_tenant_snapshot_job', + table_id = '500', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('tenant_id', 'int'), + ('snapshot_id', 'int', 'false'), + ('operation', 'varchar:32', 'false'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + normal_columns = [ + ('job_start_time', 'timestamp', 'false'), + ('trace_id', 'varchar:OB_MAX_TRACE_ID_BUFFER_SIZE', 'false'), + ('majority_succ_time', 'timestamp', 'false'), + ], +) + # 501 : __wr_sqltext def_table_schema( @@ -6449,7 +6607,32 @@ def_table_schema( # 504 : __all_audit_log_user # 505 : __all_column_privilege # 506 : __all_column_privilege_history -# 507 : __all_tenant_snapshot_ls_replica_history +all_tenant_snapshot_ls_replica_history_def = dict( + owner = 'chensen.cs', + table_name = '__all_tenant_snapshot_ls_replica_history', + table_id = '507', + table_type = 'SYSTEM_TABLE', + gm_columns = ['gmt_create', 'gmt_modified'], + rowkey_columns = [ + ('tenant_id', 'int'), + ('snapshot_id', 'int', 'false'), + ('ls_id', 'int', 'false'), + ('svr_ip', 'varchar:MAX_IP_ADDR_LENGTH', 'false'), + ('svr_port', 'int', 'false'), + ], + in_tenant_space = True, + is_cluster_private = True, + meta_record_in_sys = False, + normal_columns = [ + ('status', 'varchar:OB_DEFAULT_STATUS_LENTH', 'false'), + ('zone', 'varchar:MAX_ZONE_LENGTH', 'false'), + ('unit_id', 'int', 'false'), + ('begin_interval_scn', 'uint', 'false'), + ('end_interval_scn', 'uint', 'false'), + ('ls_meta_package', 'longtext', 'true') + ], +) +def_table_schema(**all_tenant_snapshot_ls_replica_history_def) # # 余留位置 ################################################################################ @@ -13111,10 +13294,21 @@ def_table_schema(**gen_iterate_private_virtual_table_def( table_name = '__all_virtual_tenant_parameter', in_tenant_space = True, keywords = all_def_keywords['__tenant_parameter'])) - -# 12402: __all_virtual_tenant_snapshots -# 12403: __all_virtual_tenant_snapshot_ls -# 12404: __all_virtual_tenant_snapshot_ls_meta_table +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12402', + table_name = '__all_virtual_tenant_snapshot', + in_tenant_space = True, + keywords = all_def_keywords['__all_tenant_snapshot'])) +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12403', + table_name = '__all_virtual_tenant_snapshot_ls', + in_tenant_space = True, + keywords = all_def_keywords['__all_tenant_snapshot_ls'])) +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12404', + table_name = '__all_virtual_tenant_snapshot_ls_replica', + in_tenant_space = True, + keywords = all_def_keywords['__all_tenant_snapshot_ls_replica'])) def_table_schema( owner = 'zhouxinlan.zxl', @@ -13241,8 +13435,18 @@ def_table_schema(**gen_iterate_private_virtual_table_def( # 12433: __all_virtual_storage_ha_error_diagnose # 12434: __all_virtual_storage_ha_perf_diagnose -# 12435: __all_virtual_clone_job -# 12436: __all_virtual_clone_job_history +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12435', + table_name = '__all_virtual_clone_job', + in_tenant_space = True, + keywords = all_def_keywords['__all_clone_job'])) + +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12436', + table_name = '__all_virtual_clone_job_history', + in_tenant_space = True, + keywords = all_def_keywords['__all_clone_job_history'])) + # 12437: __all_virtual_checkpoint_diagnose_memtable_info # 12438: __all_virtual_checkpoint_diagnose_checkpoint_unit_info # 12439: __all_virtual_checkpoint_diagnose_info @@ -13262,7 +13466,48 @@ def_table_schema(**gen_iterate_virtual_table_def( # 12450: __all_virtual_sys_variable_default_value # 12451: __all_virtual_transfer_partition_task # 12452: __all_virtual_transfer_partition_task_history -# 12453: __all_virtual_tenant_snapshot_create_job + +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12453', + table_name = '__all_virtual_tenant_snapshot_job', + keywords = all_def_keywords['__all_tenant_snapshot_job'], + in_tenant_space = True)) + +# 12454: __all_virtual_wr_sqltext +# 12455: __all_virtual_trusted_root_certificate_info +# 12456: __all_virtual_dbms_lock_allocated +# 12457: __all_virtual_sharing_storage_compaction_info + +def_table_schema( + owner = 'wendongbodongbo.wd', + table_name = '__all_virtual_ls_snapshot', + table_id = '12458', + table_type = 'VIRTUAL_TABLE', + gm_columns = [], + rowkey_columns = [], + in_tenant_space = True, + normal_columns = [ + ('tenant_id', 'int'), + ('snapshot_id', 'int'), + ('ls_id', 'int'), + ('svr_ip', 'varchar:MAX_IP_ADDR_LENGTH'), + ('svr_port', 'int'), + ('meta_existed', 'bool'), + ('build_status', 'varchar:32', 'true'), + ('rebuild_seq_start', 'int', 'true'), + ('rebuild_seq_end', 'int', 'true'), + ('end_interval_scn', 'int', 'true'), + ('ls_meta_package', 'longtext', 'true'), + ('tsnap_is_running', 'bool', 'true'), + ('tsnap_has_unfinished_create_dag', 'bool', 'true'), + ('tsnap_has_unfinished_gc_dag', 'bool', 'true'), + ('tsnap_clone_ref', 'int', 'true'), + ('tsnap_meta_existed', 'bool', 'true'), + ], + partition_columns = ['svr_ip', 'svr_port'], + vtable_route_policy = 'distributed' +) + # 12454: __all_virtual_wr_sqltext # 12456: __all_virtual_dbms_lock_allocated # 12457: __all_virtual_sharing_storage_compaction_info @@ -13277,7 +13522,11 @@ def_table_schema(**gen_iterate_virtual_table_def( # 12461: __all_virtual_audit_log_user # 12462: __all_virtual_column_privilege # 12463: __all_virtual_column_privilege_history -# 12464: __all_virtual_tenant_snapshot_ls_replica_history +def_table_schema(**gen_iterate_private_virtual_table_def( + table_id = '12464', + table_name = '__all_virtual_tenant_snapshot_ls_replica_history', + in_tenant_space = True, + keywords = all_def_keywords['__all_tenant_snapshot_ls_replica_history'])) # 12465: __all_virtual_share_storage_quota_assignment # 余留位置 # @@ -13701,7 +13950,8 @@ def_table_schema(**gen_oracle_mapping_real_virtual_table_def('15427', all_def_ke # 15436: __all_virtual_clone_job # 15437: __all_virtual_clone_job_history # 15438: __all_virtual_tenant_snapshot_create_job -# 15439: __all_virtual_ls_snapshot_in_storage_node +def_table_schema(**no_direct_access(gen_oracle_mapping_virtual_table_def('15439', all_def_keywords['__all_virtual_ls_snapshot']))) +# 15440: __all_virtual_index_usage_info def_table_schema(**no_direct_access(gen_oracle_mapping_real_virtual_table_def('15440', all_def_keywords['__all_index_usage_info']))) @@ -30424,7 +30674,6 @@ def_table_schema( #21506 CDB_WR_SQLTEXT #21507 GV$OB_ACTIVE_SESSION_HISTORY #21508 V$OB_ACTIVE_SESSION_HISTORY - def_table_schema( owner = 'tony.wzh', table_name = 'DBA_OB_TRUSTED_ROOT_CERTIFICATE', @@ -30444,7 +30693,38 @@ def_table_schema( """.replace("\n", " "), ) -#21510 DBA_OB_CLONE_PROGRESS +#### sys tenant only view +def_table_schema( + owner = 'chensen.cs', + table_name = 'DBA_OB_CLONE_PROGRESS', + table_id = '21510', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = False, + view_definition = """ +SELECT job_id AS CLONE_JOB_ID, + trace_id AS TRACE_ID, + source_tenant_id AS SOURCE_TENANT_ID, + source_tenant_name AS SOURCE_TENANT_NAME, + clone_tenant_id AS CLONE_TENANT_ID, + clone_tenant_name AS CLONE_TENANT_NAME, + tenant_snapshot_id AS TENANT_SNAPSHOT_ID, + tenant_snapshot_name AS TENANT_SNAPSHOT_NAME, + resource_pool_id AS RESOURCE_POOL_ID, + resource_pool_name AS RESOURCE_POOL_NAME, + unit_config_name AS UNIT_CONFIG_NAME, + restore_scn AS RESTORE_SCN, + status AS STATUS, + job_type AS CLONE_JOB_TYPE, + clone_start_time AS CLONE_START_TIME, + clone_finished_time AS CLONE_FINISHED_TIME, + ret_code AS RET_CODE, + error_msg AS ERROR_MESSAGE +FROM oceanbase.__all_clone_job ORDER BY CLONE_START_TIME +""".replace("\n", " ") +) #21511 mysql.role_edges #21512 mysql.default_roles @@ -30489,9 +30769,103 @@ def_table_schema( #21514 mysql.audit_log_filter #21515 mysql.audit_log_user #21516 mysql.columns_priv -#21517 GV$OB_LS_SNAPSHOTS -#21518 V$OB_LS_SNAPSHOTS -#21519 DBA_OB_CLONE_HISTORY +def_table_schema( + owner = 'wendongbodongbo.wd', + table_name = 'GV$OB_LS_SNAPSHOTS', + table_id = '21517', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = """SELECT + tenant_id AS TENANT_ID, + snapshot_id AS SNAPSHOT_ID, + ls_id AS LS_ID, + svr_ip AS SVR_IP, + svr_port AS SVR_PORT, + (CASE + WHEN meta_existed = 1 THEN 'YES' + ELSE 'NO' + END) AS META_EXISTED, + (CASE + WHEN build_status = 0 THEN 'BUILDING' + WHEN build_status = 1 THEN 'FAILED' + WHEN build_status = 2 THEN 'SUCCESSFUL' + ELSE 'UNKNOWN' + END) AS BUILD_STATUS, + rebuild_seq_start AS REBUILD_SEQ_START, + rebuild_seq_end AS REBUILD_SEQ_END, + end_interval_scn AS END_INTERVAL_SCN, + ls_meta_package AS LS_META_PACKAGE, + (CASE + WHEN tsnap_is_running = 1 THEN 'YES' + ELSE 'NO' + END) AS TSNAP_IS_RUNNING, + (CASE + WHEN tsnap_has_unfinished_create_dag = 1 THEN 'YES' + ELSE 'NO' + END) AS TSNAP_HAS_UNFINISHED_CREATE_DAG, + (CASE + WHEN tsnap_has_unfinished_gc_dag = 1 THEN 'YES' + ELSE 'NO' + END) AS TSNAP_HAS_UNFINISHED_GC_DAG, + tsnap_clone_ref AS TSNAP_CLONE_REF, + (CASE + WHEN tsnap_meta_existed = 1 THEN 'YES' + ELSE 'NO' + END) AS TSNAP_META_EXISTED + FROM oceanbase.__all_virtual_ls_snapshot +""".replace("\n", " "), +) + +def_table_schema( + owner = 'wendongbodongbo.wd', + table_name = 'V$OB_LS_SNAPSHOTS', + table_id = '21518', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = """SELECT * + FROM oceanbase.GV$OB_LS_SNAPSHOTS + WHERE SVR_IP = HOST_IP() AND SVR_PORT = RPC_PORT() +""".replace("\n", " "), +) + +#### sys tenant only view +def_table_schema( + owner = 'chensen.cs', + table_name = 'DBA_OB_CLONE_HISTORY', + table_id = '21519', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = False, + view_definition = """ +SELECT job_id AS CLONE_JOB_ID, + trace_id AS TRACE_ID, + source_tenant_id AS SOURCE_TENANT_ID, + source_tenant_name AS SOURCE_TENANT_NAME, + clone_tenant_id AS CLONE_TENANT_ID, + clone_tenant_name AS CLONE_TENANT_NAME, + tenant_snapshot_id AS TENANT_SNAPSHOT_ID, + tenant_snapshot_name AS TENANT_SNAPSHOT_NAME, + resource_pool_id AS RESOURCE_POOL_ID, + resource_pool_name AS RESOURCE_POOL_NAME, + unit_config_name AS UNIT_CONFIG_NAME, + restore_scn AS RESTORE_SCN, + status AS STATUS, + job_type AS CLONE_JOB_TYPE, + clone_start_time AS CLONE_START_TIME, + clone_finished_time AS CLONE_FINISHED_TIME, + ret_code AS RET_CODE, + error_msg AS ERROR_MESSAGE +FROM oceanbase.__all_clone_job_history ORDER BY CLONE_START_TIME +""".replace("\n", " ") +) #21520 GV$OB_SHARE_STORAGE_QUOTA_ASSIGNMENT #21521 V$OB_SHARE_STORAGE_QUOTA_ASSIGNMENT # 余留位置 @@ -55224,6 +55598,75 @@ def_table_schema( # 28217: GV$OB_SHARE_STORAGE_QUOTA_ASSIGNMENT # 28218: V$OB_SHARE_STORAGE_QUOTA_ASSIGNMENT +def_table_schema( + owner = 'wendongbodongbo.wd', + table_name = 'GV$OB_LS_SNAPSHOTS', + name_postfix = '_ORA', + database_id = 'OB_ORA_SYS_DATABASE_ID', + table_id = '28215', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = """SELECT + tenant_id AS TENANT_ID, + snapshot_id AS SNAPSHOT_ID, + ls_id AS LS_ID, + svr_ip AS SVR_IP, + svr_port AS SVR_PORT, + (CASE + WHEN meta_existed = 1 THEN 'YES' + ELSE 'NO' + END) AS META_EXISTED, + (CASE + WHEN build_status = 0 THEN 'BUILDING' + WHEN build_status = 1 THEN 'FAILED' + WHEN build_status = 2 THEN 'SUCCESSFUL' + ELSE 'UNKNOWN' + END) AS BUILD_STATUS, + rebuild_seq_start AS REBUILD_SEQ_START, + rebuild_seq_end AS REBUILD_SEQ_END, + end_interval_scn AS END_INTERVAL_SCN, + ls_meta_package AS LS_META_PACKAGE, + (CASE + WHEN tsnap_is_running = 1 THEN 'YES' + ELSE 'NO' + END) AS TSNAP_IS_RUNNING, + (CASE + WHEN tsnap_has_unfinished_create_dag = 1 THEN 'YES' + ELSE 'NO' + END) AS TSNAP_HAS_UNFINISHED_CREATE_DAG, + (CASE + WHEN tsnap_has_unfinished_gc_dag = 1 THEN 'YES' + ELSE 'NO' + END) AS TSNAP_HAS_UNFINISHED_GC_DAG, + tsnap_clone_ref AS TSNAP_CLONE_REF, + (CASE + WHEN tsnap_meta_existed = 1 THEN 'YES' + ELSE 'NO' + END) AS TSNAP_META_EXISTED + FROM SYS.ALL_VIRTUAL_LS_SNAPSHOT +""".replace("\n", " "), +) + +def_table_schema( + owner = 'wendongbodongbo.wd', + table_name = 'V$OB_LS_SNAPSHOTS', + name_postfix = '_ORA', + database_id = 'OB_ORA_SYS_DATABASE_ID', + table_id = '28216', + table_type = 'SYSTEM_VIEW', + rowkey_columns = [], + normal_columns = [], + gm_columns = [], + in_tenant_space = True, + view_definition = """SELECT * + FROM SYS.GV$OB_LS_SNAPSHOTS + WHERE SVR_IP = HOST_IP() AND SVR_PORT = RPC_PORT() +""".replace("\n", " "), +) + ################################################################################ # Lob Table (50000, 70000) ################################################################################ @@ -55989,7 +56432,13 @@ def_sys_index_table( index_type = 'INDEX_TYPE_NORMAL_LOCAL', keywords = all_def_keywords['__all_rls_context_history']) -# 101089 : placeholder for unique index of __all_tenant_snapshots +def_sys_index_table( + index_name = 'idx_tenant_snapshot_name', + index_table_id = 101089, + index_columns = ['snapshot_name'], + index_using_type = 'USING_BTREE', + index_type = 'INDEX_TYPE_UNIQUE_LOCAL', + keywords = all_def_keywords['__all_tenant_snapshot']) def_sys_index_table( index_name = 'idx_dbms_lock_allocated_lockhandle', diff --git a/src/share/inner_table/ob_inner_table_schema_misc.ipp b/src/share/inner_table/ob_inner_table_schema_misc.ipp index b8c1802e07..cee4a1d967 100644 --- a/src/share/inner_table/ob_inner_table_schema_misc.ipp +++ b/src/share/inner_table/ob_inner_table_schema_misc.ipp @@ -451,6 +451,8 @@ case OB_ALL_VIRTUAL_BACKUP_TASK_TID: case OB_ALL_VIRTUAL_BACKUP_TASK_HISTORY_TID: case OB_ALL_VIRTUAL_BALANCE_GROUP_LS_STAT_TID: case OB_ALL_VIRTUAL_BALANCE_TASK_HELPER_TID: +case OB_ALL_VIRTUAL_CLONE_JOB_TID: +case OB_ALL_VIRTUAL_CLONE_JOB_HISTORY_TID: case OB_ALL_VIRTUAL_COLUMN_CHECKSUM_ERROR_INFO_TID: case OB_ALL_VIRTUAL_DEADLOCK_EVENT_HISTORY_TID: case OB_ALL_VIRTUAL_GLOBAL_CONTEXT_VALUE_TID: @@ -490,6 +492,11 @@ case OB_ALL_VIRTUAL_TASK_OPT_STAT_GATHER_HISTORY_TID: case OB_ALL_VIRTUAL_TENANT_EVENT_HISTORY_TID: case OB_ALL_VIRTUAL_TENANT_INFO_TID: case OB_ALL_VIRTUAL_TENANT_PARAMETER_TID: +case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_TID: +case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_JOB_TID: +case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_TID: +case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TID: +case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID: case OB_ALL_VIRTUAL_TENANT_USER_FAILED_LOGIN_STAT_TID: case OB_ALL_VIRTUAL_WR_ACTIVE_SESSION_HISTORY_TID: case OB_ALL_VIRTUAL_WR_CONTROL_TID: @@ -890,6 +897,38 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: break; } + case OB_ALL_VIRTUAL_CLONE_JOB_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_CLONE_JOB_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + + case OB_ALL_VIRTUAL_CLONE_JOB_HISTORY_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_CLONE_JOB_HISTORY_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + case OB_ALL_VIRTUAL_COLUMN_CHECKSUM_ERROR_INFO_TID: { ObIteratePrivateVirtualTable *iter = NULL; const bool meta_record_in_sys = false; @@ -1113,7 +1152,9 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_LOG_RESTORE_SOURCE_TID: { ObIteratePrivateVirtualTable *iter = NULL; const bool meta_record_in_sys = false; @@ -1145,9 +1186,7 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_LS_ARB_REPLICA_TASK_HISTORY_TID: { ObIteratePrivateVirtualTable *iter = NULL; const bool meta_record_in_sys = false; @@ -1435,7 +1474,9 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TABLET_REPLICA_CHECKSUM_TID: { ObIteratePrivateVirtualTable *iter = NULL; const bool meta_record_in_sys = false; @@ -1467,9 +1508,7 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TENANT_EVENT_HISTORY_TID: { ObIteratePrivateVirtualTable *iter = NULL; const bool meta_record_in_sys = false; @@ -1518,6 +1557,86 @@ case OB_ALL_VIRTUAL_ZONE_MERGE_INFO_TID: break; } + case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_TENANT_SNAPSHOT_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + + case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_JOB_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_TENANT_SNAPSHOT_JOB_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + + case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_TENANT_SNAPSHOT_LS_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + + case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + + case OB_ALL_VIRTUAL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID: { + ObIteratePrivateVirtualTable *iter = NULL; + const bool meta_record_in_sys = false; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIteratePrivateVirtualTable, iter))) { + SERVER_LOG(WARN, "create iterate private virtual table iterator failed", KR(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID, meta_record_in_sys, index_schema, params))) { + SERVER_LOG(WARN, "iterate private virtual table iter init failed", KR(ret)); + iter->~ObIteratePrivateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + case OB_ALL_VIRTUAL_TENANT_USER_FAILED_LOGIN_STAT_TID: { ObIteratePrivateVirtualTable *iter = NULL; const bool meta_record_in_sys = false; @@ -4184,6 +4303,12 @@ case OB_ALL_BALANCE_GROUP_LS_STAT_AUX_LOB_PIECE_TID: case OB_ALL_BALANCE_TASK_HELPER_TID: case OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_META_TID: case OB_ALL_BALANCE_TASK_HELPER_AUX_LOB_PIECE_TID: +case OB_ALL_CLONE_JOB_TID: +case OB_ALL_CLONE_JOB_AUX_LOB_META_TID: +case OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID: +case OB_ALL_CLONE_JOB_HISTORY_TID: +case OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TID: +case OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TID: case OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_TID: case OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_META_TID: case OB_ALL_COLUMN_CHECKSUM_ERROR_INFO_AUX_LOB_PIECE_TID: @@ -4311,6 +4436,22 @@ case OB_ALL_TENANT_GLOBAL_TRANSACTION_AUX_LOB_PIECE_TID: case OB_ALL_TENANT_INFO_TID: case OB_ALL_TENANT_INFO_AUX_LOB_META_TID: case OB_ALL_TENANT_INFO_AUX_LOB_PIECE_TID: +case OB_ALL_TENANT_SNAPSHOT_TID: +case OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TID: +case OB_ALL_TENANT_SNAPSHOT_AUX_LOB_META_TID: +case OB_ALL_TENANT_SNAPSHOT_AUX_LOB_PIECE_TID: +case OB_ALL_TENANT_SNAPSHOT_JOB_TID: +case OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_META_TID: +case OB_ALL_TENANT_SNAPSHOT_JOB_AUX_LOB_PIECE_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_META_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_AUX_LOB_PIECE_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_META_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_AUX_LOB_PIECE_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_META_TID: +case OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_AUX_LOB_PIECE_TID: case OB_ALL_TENANT_USER_FAILED_LOGIN_STAT_TID: case OB_ALL_TENANT_USER_FAILED_LOGIN_STAT_AUX_LOB_META_TID: case OB_ALL_TENANT_USER_FAILED_LOGIN_STAT_AUX_LOB_PIECE_TID: @@ -4438,6 +4579,7 @@ case OB_ALL_RLS_GROUP_IDX_RLS_GROUP_TABLE_ID_TID: case OB_ALL_RLS_GROUP_HISTORY_IDX_RLS_GROUP_HIS_TABLE_ID_TID: case OB_ALL_RLS_CONTEXT_IDX_RLS_CONTEXT_TABLE_ID_TID: case OB_ALL_RLS_CONTEXT_HISTORY_IDX_RLS_CONTEXT_HIS_TABLE_ID_TID: +case OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TID: case OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_LOCKHANDLE_TID: case OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_EXPIRATION_TID: case OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TID: @@ -4502,6 +4644,7 @@ case OB_ALL_TENANT_HISTORY_TID: case OB_ALL_SUB_PART_TID: case OB_ALL_ROUTINE_TID: case OB_ALL_TENANT_DIRECTORY_TID: +case OB_ALL_TENANT_SNAPSHOT_TID: case OB_ALL_DDL_ERROR_MESSAGE_TID: case OB_ALL_TENANT_TRIGGER_HISTORY_TID: case OB_ALL_CONSTRAINT_TID: @@ -4919,6 +5062,12 @@ case OB_ALL_TENANT_DIRECTORY_TID: { } break; } +case OB_ALL_TENANT_SNAPSHOT_TID: { + if (FAILEDx(index_tids.push_back(OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TID))) { + LOG_WARN("fail to push back index tid", KR(ret)); + } + break; +} case OB_ALL_DDL_ERROR_MESSAGE_TID: { if (FAILEDx(index_tids.push_back(OB_ALL_DDL_ERROR_MESSAGE_IDX_DDL_ERROR_OBJECT_TID))) { LOG_WARN("fail to push back index tid", KR(ret)); @@ -5660,6 +5809,15 @@ case OB_ALL_TENANT_DIRECTORY_TID: { } break; } +case OB_ALL_TENANT_SNAPSHOT_TID: { + index_schema.reset(); + if (FAILEDx(ObInnerTableSchema::all_tenant_snapshot_idx_tenant_snapshot_name_schema(index_schema))) { + LOG_WARN("fail to create index schema", KR(ret), K(tenant_id), K(data_table_id)); + } else if (OB_FAIL(append_table_(tenant_id, index_schema, tables))) { + LOG_WARN("fail to append", KR(ret), K(tenant_id), K(data_table_id)); + } + break; +} case OB_ALL_DDL_ERROR_MESSAGE_TID: { index_schema.reset(); if (FAILEDx(ObInnerTableSchema::all_ddl_error_message_idx_ddl_error_object_schema(index_schema))) { @@ -6019,6 +6177,8 @@ case OB_ALL_FOREIGN_KEY_TID: { LOG_WARN("add index id failed", KR(ret), K(tenant_id)); } else if (OB_FAIL(table_ids.push_back(OB_ALL_RLS_CONTEXT_HISTORY_IDX_RLS_CONTEXT_HIS_TABLE_ID_TID))) { LOG_WARN("add index id failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_ids.push_back(OB_ALL_TENANT_SNAPSHOT_IDX_TENANT_SNAPSHOT_NAME_TID))) { + LOG_WARN("add index id failed", KR(ret), K(tenant_id)); } else if (OB_FAIL(table_ids.push_back(OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_LOCKHANDLE_TID))) { LOG_WARN("add index id failed", KR(ret), K(tenant_id)); } else if (OB_FAIL(table_ids.push_back(OB_ALL_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_EXPIRATION_TID))) { diff --git a/src/share/location_cache/ob_location_struct.cpp b/src/share/location_cache/ob_location_struct.cpp index 1fa369628a..9a53ccaf8d 100644 --- a/src/share/location_cache/ob_location_struct.cpp +++ b/src/share/location_cache/ob_location_struct.cpp @@ -72,7 +72,7 @@ void ObLSReplicaLocation::reset() sql_port_ = OB_INVALID_INDEX; replica_type_ = REPLICA_TYPE_FULL; property_.reset(); - restore_status_ = ObLSRestoreStatus::Status::RESTORE_NONE; + restore_status_ = ObLSRestoreStatus::Status::NONE; proposal_id_ = OB_INVALID_ID; } diff --git a/src/share/ls/ob_ls_creator.cpp b/src/share/ls/ob_ls_creator.cpp index 5abd3e022a..4d5b8c3196 100644 --- a/src/share/ls/ob_ls_creator.cpp +++ b/src/share/ls/ob_ls_creator.cpp @@ -32,6 +32,8 @@ #include "share/arbitration_service/ob_arbitration_service_info.h" // for ObArbitrationServiceInfo #include "share/arbitration_service/ob_arbitration_service_table_operator.h" // for ObArbitrationServiceTableOperator #endif +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "share/restore/ob_tenant_clone_table_operator.h" using namespace oceanbase::common; using namespace oceanbase::share; @@ -45,29 +47,16 @@ namespace share { ////ObLSReplicaAddr int ObLSReplicaAddr::init(const common::ObAddr &addr, - const common::ObReplicaType replica_type, - const common::ObReplicaProperty &replica_property, - const uint64_t unit_group_id, - const uint64_t unit_id, - const common::ObZone &zone) + const common::ObReplicaType replica_type) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!addr.is_valid() - || common::REPLICA_TYPE_MAX == replica_type - || !replica_property.is_valid() - || common::OB_INVALID_ID == unit_group_id - || common::OB_INVALID_ID == unit_id)) { + || common::REPLICA_TYPE_MAX == replica_type)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", KR(ret), K(addr), K(replica_type), - K(replica_property), K(unit_group_id), K(unit_id)); - } else if (OB_FAIL(zone_.assign(zone))) { - LOG_WARN("failed to assign zone", KR(ret), K(zone)); + LOG_WARN("invalid argument", KR(ret), K(addr), K(replica_type)); } else { addr_ = addr; replica_type_ = replica_type; - replica_property_ = replica_property; - unit_group_id_ = unit_group_id; - unit_id_ = unit_id; } return ret; @@ -122,11 +111,7 @@ int ObLSCreator::create_sys_tenant_ls( LOG_WARN("zone not match", KR(ret), K(rs_list), K(unit_array)); } else if (OB_FAIL(replica_addr.init( rs_list[i].server_, - replica_type, - replica_property, - 0,/* sys ls has no unit group id*/ - unit_array.at(i).unit_id_, - rs_list.at(i).zone_))) { + replica_type))) { LOG_WARN("failed to init replica addr", KR(ret), K(i), K(rs_list), K(replica_type), K(replica_property), K(unit_array)); } else if (OB_FAIL(addr.push_back(replica_addr))) { @@ -173,7 +158,8 @@ int ObLSCreator::create_user_ls( const SCN &create_scn, const common::ObCompatibilityMode &compat_mode, const bool create_with_palf, - const palf::PalfBaseInfo &palf_base_info) + const palf::PalfBaseInfo &palf_base_info, + const uint64_t source_tenant_id) { int ret = OB_SUCCESS; const int64_t start_time = ObTimeUtility::current_time(); @@ -199,15 +185,23 @@ int ObLSCreator::create_user_ls( share::ObLSStatusOperator ls_operator; ObMember arbitration_service; common::GlobalLearnerList learner_list; - if (status_info.is_duplicate_ls()) { - if (OB_FAIL(alloc_duplicate_ls_addr_(tenant_id_, zone_locality, addr))) { - LOG_WARN("failed to alloc duplicate ls addr", KR(ret), K_(tenant_id)); - } else { - LOG_INFO("finish alloc duplicate ls addr", K_(tenant_id), K(addr)); + if (OB_INVALID_TENANT_ID != source_tenant_id) { + // for clone tenant + if (OB_FAIL(construct_clone_tenant_ls_addrs_(source_tenant_id, addr))) { + LOG_WARN("fail to construct locations for clone tenant log stream", KR(ret), + K(source_tenant_id), K_(tenant_id), K_(id)); + } + } else { + if (status_info.is_duplicate_ls()) { + if (OB_FAIL(alloc_duplicate_ls_addr_(tenant_id_, zone_locality, addr))) { + LOG_WARN("failed to alloc duplicate ls addr", KR(ret), K_(tenant_id)); + } else { + LOG_INFO("finish alloc duplicate ls addr", K_(tenant_id), K(addr)); + } + } else if (OB_FAIL(alloc_user_ls_addr(tenant_id_, status_info.unit_group_id_, + zone_locality, addr))) { + LOG_WARN("failed to alloc user ls addr", KR(ret), K(tenant_id_), K(status_info)); } - } else if (OB_FAIL(alloc_user_ls_addr(tenant_id_, status_info.unit_group_id_, - zone_locality, addr))) { - LOG_WARN("failed to alloc user ls addr", KR(ret), K(tenant_id_), K(status_info)); } if (OB_FAIL(ret)) { @@ -238,7 +232,8 @@ int ObLSCreator::create_tenant_sys_ls( const common::ObCompatibilityMode &compat_mode, const ObString &zone_priority, const bool create_with_palf, - const palf::PalfBaseInfo &palf_base_info) + const palf::PalfBaseInfo &palf_base_info, + const uint64_t source_tenant_id) { int ret = OB_SUCCESS; LOG_INFO("start to create log stream", K_(id), K_(tenant_id)); @@ -270,9 +265,16 @@ int ObLSCreator::create_tenant_sys_ls( primary_zone, flag))) { LOG_WARN("failed to init ls info", KR(ret), K(id_), K(primary_zone), K(tenant_id_), K(flag)); + } else if (OB_INVALID_TENANT_ID != source_tenant_id) { + if (OB_FAIL(construct_clone_tenant_ls_addrs_(source_tenant_id, addr))) { + LOG_WARN("failed to alloc clone tenant ls addr", KR(ret), + K(source_tenant_id), K(tenant_id_), K(addr), K(source_tenant_id)); + } } else if (OB_FAIL(alloc_sys_ls_addr(tenant_id_, pool_list, zone_locality, addr))) { LOG_WARN("failed to alloc user ls addr", KR(ret), K(tenant_id_), K(pool_list)); + } + if (OB_FAIL(ret)) { } else { ret = ls_operator.get_ls_init_member_list(tenant_id_, id_, member_list, exist_status_info, *proxy_, arbitration_service, learner_list); if (OB_FAIL(ret) && OB_ENTRY_NOT_EXIST != ret) { @@ -300,6 +302,56 @@ int ObLSCreator::create_tenant_sys_ls( return ret; } +int ObLSCreator::construct_clone_tenant_ls_addrs_(const uint64_t source_tenant_id, + ObLSAddr &ls_addrs) +{ + int ret = OB_SUCCESS; + ls_addrs.reset(); + ObLSReplicaAddr replica_addr; + const common::ObReplicaType replica_type = ObReplicaType::REPLICA_TYPE_FULL; + ObTenantCloneTableOperator clone_op; + ObTenantSnapshotTableOperator snap_op; + ObCloneJob clone_job; + ObArray simple_items; + + if (OB_UNLIKELY(!is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K_(tenant_id), K_(id)); + } else { + MTL_SWITCH(OB_SYS_TENANT_ID) { + if (OB_FAIL(clone_op.init(tenant_id_, proxy_))) { + LOG_WARN("fail to init clone op", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(clone_op.get_clone_job_by_source_tenant_id(source_tenant_id, clone_job))) { + LOG_WARN("fail to get clone job", KR(ret), K(tenant_id_), K(source_tenant_id)); + } else if (OB_UNLIKELY(!clone_job.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("clone job is not valid", KR(ret), K(clone_job), K(source_tenant_id)); + } else if (OB_FAIL(snap_op.init(source_tenant_id, proxy_))) { + LOG_WARN("failed to init snap op", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(snap_op.get_tenant_snap_ls_replica_simple_items( + clone_job.get_tenant_snapshot_id(), id_, ObLSSnapStatus::NORMAL, simple_items))) { + LOG_WARN("failed to get ls replica simple items", KR(ret), K(clone_job), K(id_)); + } else if (OB_UNLIKELY(simple_items.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("simple_items is empty", KR(ret), K(simple_items), K(clone_job), K(id_)); + } + } + } + + if (OB_SUCC(ret)) { + ARRAY_FOREACH_N(simple_items, i, cnt) { + replica_addr.reset(); + const ObAddr &addr = simple_items.at(i).get_addr(); + if (OB_FAIL(replica_addr.init(addr, replica_type))) { + LOG_WARN("fail to construct replica addr", KR(ret), K(addr), K(replica_type)); + } else if (OB_FAIL(ls_addrs.push_back(replica_addr))) { + LOG_WARN("fail to add PbLSReplicaAddr to array", KR(ret), K(replica_addr)); + } + } + } + return ret; +} + int ObLSCreator::do_create_ls_(const ObLSAddr &addr, ObMember &arbitration_service, const share::ObLSStatusInfo &info, @@ -401,6 +453,7 @@ int ObLSCreator::create_ls_(const ObILSAddr &addrs, obrpc::ObCreateLSArg arg; int tmp_ret = OB_SUCCESS; ObArray return_code_array; + const common::ObReplicaProperty replica_property; lib::Worker::CompatMode new_compat_mode = compat_mode == ORACLE_MODE ? lib::Worker::CompatMode::ORACLE : lib::Worker::CompatMode::MYSQL; @@ -409,9 +462,9 @@ int ObLSCreator::create_ls_(const ObILSAddr &addrs, arg.reset(); const ObLSReplicaAddr &addr = addrs.at(i); if (OB_FAIL(arg.init(tenant_id_, id_, addr.replica_type_, - addr.replica_property_, tenant_info, create_scn, new_compat_mode, + replica_property, tenant_info, create_scn, new_compat_mode, create_with_palf, palf_base_info))) { - LOG_WARN("failed to init create log stream arg", KR(ret), K(addr), K(create_with_palf), + LOG_WARN("failed to init create log stream arg", KR(ret), K(addr), K(create_with_palf), K(replica_property), K_(id), K_(tenant_id), K(tenant_info), K(create_scn), K(new_compat_mode), K(palf_base_info)); } else if (OB_TMP_FAIL(create_ls_proxy_.call(addr.addr_, ctx.get_timeout(), GCONF.cluster_id, tenant_id_, arg))) { @@ -816,6 +869,41 @@ int ObLSCreator::check_set_memberlist_result_( } // OceanBase 4.0 interface +int ObLSCreator::construct_ls_addrs_according_to_locality_( + const share::schema::ZoneLocalityIArray &zone_locality_array, + const common::ObIArray &unit_info_array, + const bool is_sys_ls, + const bool is_duplicate_ls, + ObILSAddr &ls_addr) +{ + int ret = OB_SUCCESS; + ls_addr.reset(); + if (OB_UNLIKELY(0 >= zone_locality_array.count()) + || OB_UNLIKELY(0 >= unit_info_array.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(zone_locality_array), K(unit_info_array)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < zone_locality_array.count(); ++i) { + const share::ObZoneReplicaAttrSet &zone_locality = zone_locality_array.at(i); + ObLSReplicaAddr replica_addr; + if (OB_FAIL(alloc_zone_ls_addr(is_sys_ls, zone_locality, unit_info_array, replica_addr))) { + LOG_WARN("fail to alloc zone ls addr", KR(ret), K(zone_locality), K(unit_info_array)); + } else if (OB_FAIL(ls_addr.push_back(replica_addr))) { + LOG_WARN("fail to push back", KR(ret), K(replica_addr)); + } else if (is_duplicate_ls + && OB_FAIL(compensate_zone_readonly_replica_( + zone_locality, + replica_addr, + unit_info_array, + ls_addr))) { + LOG_WARN("fail to compensate readonly replica", KR(ret), K(zone_locality), + K(replica_addr), K(ls_addr)); + } + } + } + return ret; +} + int ObLSCreator::alloc_sys_ls_addr( const uint64_t tenant_id, const ObIArray &pools, @@ -825,6 +913,7 @@ int ObLSCreator::alloc_sys_ls_addr( int ret = OB_SUCCESS; common::ObArray unit_info_array; ObUnitTableOperator unit_operator; + ls_addr.reset(); if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || pools.count() <= 0 @@ -838,20 +927,14 @@ int ObLSCreator::alloc_sys_ls_addr( LOG_WARN("unit operator init failed", KR(ret)); } else if (OB_FAIL(unit_operator.get_units_by_resource_pools(pools, unit_info_array))) { LOG_WARN("fail to get unit infos", KR(ret), K(pools)); - } else { - ls_addr.reset(); - for (int64_t i = 0; OB_SUCC(ret) && i < zone_locality_array.count(); ++i) { - const share::ObZoneReplicaAttrSet &zone_locality = zone_locality_array.at(i); - const bool is_sys_ls = true; - ObLSReplicaAddr replica_addr; - if (OB_FAIL(alloc_zone_ls_addr( - is_sys_ls, zone_locality, unit_info_array, replica_addr))) { - LOG_WARN("fail to alloc zone ls addr", - KR(ret), K(zone_locality), K(unit_info_array)); - } else if (OB_FAIL(ls_addr.push_back(replica_addr))) { - LOG_WARN("fail to push back", KR(ret)); - } - } + } else if (OB_FAIL(construct_ls_addrs_according_to_locality_( + zone_locality_array, + unit_info_array, + true/*is_sys_ls*/, + false/*is_duplicate_ls*/, + ls_addr))) { + LOG_WARN("fail to construct ls addrs for tenant sys ls", KR(ret), K(zone_locality_array), + K(unit_info_array), K(ls_addr)); } return ret; } @@ -864,8 +947,9 @@ int ObLSCreator::alloc_user_ls_addr( { int ret = OB_SUCCESS; ObUnitTableOperator unit_operator; - common::ObArray unit_info_array; + ls_addr.reset(); + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || 0 == unit_group_id || OB_INVALID_ID == unit_group_id @@ -880,20 +964,14 @@ int ObLSCreator::alloc_user_ls_addr( LOG_WARN("unit operator init failed", KR(ret)); } else if (OB_FAIL(unit_operator.get_units_by_unit_group_id(unit_group_id, unit_info_array))) { LOG_WARN("fail to get unit group", KR(ret), K(tenant_id), K(unit_group_id)); - } else { - ls_addr.reset(); - for (int64_t i = 0; OB_SUCC(ret) && i < zone_locality_array.count(); ++i) { - const share::ObZoneReplicaAttrSet &zone_locality = zone_locality_array.at(i); - const bool is_sys_ls = false; - ObLSReplicaAddr replica_addr; - if (OB_FAIL(alloc_zone_ls_addr( - is_sys_ls, zone_locality, unit_info_array, replica_addr))) { - LOG_WARN("fail to alloc zone ls addr", - KR(ret), K(zone_locality), K(unit_info_array)); - } else if (OB_FAIL(ls_addr.push_back(replica_addr))) { - LOG_WARN("fail to push back", KR(ret)); - } - } + } else if (OB_FAIL(construct_ls_addrs_according_to_locality_( + zone_locality_array, + unit_info_array, + false/*is_sys_ls*/, + false/*is_duplicate_ls*/, + ls_addr))) { + LOG_WARN("fail to construct ls addrs for tenant user ls", KR(ret), K(zone_locality_array), + K(unit_info_array), K(ls_addr)); } return ret; } @@ -907,6 +985,7 @@ int ObLSCreator::alloc_duplicate_ls_addr_( int ret = OB_SUCCESS; ObUnitTableOperator unit_operator; common::ObArray unit_info_array; + ls_addr.reset(); if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || zone_locality_array.count() <= 0)) { @@ -919,25 +998,16 @@ int ObLSCreator::alloc_duplicate_ls_addr_( LOG_WARN("unit operator init failed", KR(ret)); } else if (OB_FAIL(unit_operator.get_units_by_tenant(tenant_id, unit_info_array))) { LOG_WARN("fail to get unit info array", KR(ret), K(tenant_id)); - } else { - ls_addr.reset(); - const bool is_duplicate_ls = true; - for (int64_t i = 0; OB_SUCC(ret) && i < zone_locality_array.count(); ++i) { - const share::ObZoneReplicaAttrSet &zone_locality = zone_locality_array.at(i); - ObLSReplicaAddr replica_addr; - if (OB_FAIL(alloc_zone_ls_addr(is_duplicate_ls, zone_locality, unit_info_array, replica_addr))) { - LOG_WARN("fail to alloc zone ls addr", KR(ret), K(zone_locality), K(unit_info_array)); - } else if (OB_FAIL(ls_addr.push_back(replica_addr))) { - LOG_WARN("fail to push back", KR(ret)); - } else if (OB_FAIL(compensate_zone_readonly_replica_( - zone_locality, - replica_addr, - unit_info_array, - ls_addr))) { - LOG_WARN("fail to compensate readonly replica", KR(ret), - K(zone_locality), K(replica_addr), K(ls_addr)); - } - } + } else if (OB_FAIL(construct_ls_addrs_according_to_locality_( + zone_locality_array, + unit_info_array, + true/*is_sys_ls*/, + true/*is_duplicate_ls*/, + ls_addr))) { + // although duplicate log stream is a user log steam, we use the same logic to alloc addrs as sys log stream + // so set is_sys_ls to true when execute construct_ls_addrs_according_to_locality_ + LOG_WARN("fail to construct ls addrs for tenant user ls", KR(ret), K(zone_locality_array), + K(unit_info_array), K(ls_addr)); } return ret; } @@ -950,7 +1020,6 @@ int ObLSCreator::compensate_zone_readonly_replica_( { int ret = OB_SUCCESS; const common::ObZone &locality_zone = zlocality.zone_; - const uint64_t unit_group_id = 0; // duplicate log stream if (OB_UNLIKELY(0 >= unit_info_array.count())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", KR(ret), K(unit_info_array)); @@ -959,25 +1028,17 @@ int ObLSCreator::compensate_zone_readonly_replica_( const share::ObUnit &unit = unit_info_array.at(i); if (locality_zone != unit.zone_) { // not match - } else if (exclude_replica.unit_id_ == unit.unit_id_) { + } else if (exclude_replica.addr_ == unit.server_) { // already exists in ls_addr } else if (ObUnit::UNIT_STATUS_DELETING == unit.status_) { // unit may be deleting LOG_TRACE("unit is not active", K(unit)); } else { ObLSReplicaAddr ls_replica_addr; - const int64_t m_percent = 100; - ObReplicaProperty replica_property; - replica_property.set_memstore_percent(m_percent); if (OB_FAIL(ls_replica_addr.init( unit.server_, - ObReplicaType::REPLICA_TYPE_READONLY, - replica_property, - unit_group_id, - unit.unit_id_, - locality_zone))) { - LOG_WARN("fail to init ls replica addr", KR(ret), K(unit), K(replica_property), - K(unit_group_id), K(locality_zone)); + ObReplicaType::REPLICA_TYPE_READONLY))) { + LOG_WARN("fail to init ls replica addr", KR(ret), K(unit), K(locality_zone)); } else if (OB_FAIL(ls_addr.push_back(ls_replica_addr))) { LOG_WARN("fail to push back", KR(ret), K(ls_replica_addr)); } @@ -1000,80 +1061,33 @@ int ObLSCreator::alloc_zone_ls_addr( ls_replica_addr.reset(); for (int64_t i = 0; !found && OB_SUCC(ret) && i < unit_info_array.count(); ++i) { const share::ObUnit &unit = unit_info_array.at(i); - const uint64_t unit_group_id = is_sys_ls ? 0 : unit.unit_group_id_; if (locality_zone != unit.zone_) { // not match } else { found = true; if (zlocality.replica_attr_set_.get_full_replica_attr_array().count() > 0) { - const int64_t m_percent = zlocality.replica_attr_set_ - .get_full_replica_attr_array().at(0) - .memstore_percent_; - ObReplicaProperty replica_property; - replica_property.set_memstore_percent(m_percent); if (OB_FAIL(ls_replica_addr.init( unit.server_, - ObReplicaType::REPLICA_TYPE_FULL, - replica_property, - unit_group_id, - unit.unit_id_, - locality_zone))) { - LOG_WARN("fail to init ls replica addr", - KR(ret), K(unit), K(replica_property), K(unit_group_id), - K(locality_zone)); + ObReplicaType::REPLICA_TYPE_FULL))) { + LOG_WARN("fail to init ls replica addr", KR(ret)); } } else if (zlocality.replica_attr_set_.get_logonly_replica_attr_array().count() > 0) { - const int64_t m_percent = zlocality.replica_attr_set_ - .get_logonly_replica_attr_array().at(0) - .memstore_percent_; - ObReplicaProperty replica_property; - replica_property.set_memstore_percent(m_percent); if (OB_FAIL(ls_replica_addr.init( unit.server_, - ObReplicaType::REPLICA_TYPE_LOGONLY, - replica_property, - unit_group_id, - unit.unit_id_, - locality_zone))) { - LOG_WARN("fail to init ls replica addr", - KR(ret), K(unit), K(replica_property), K(unit_group_id), - K(locality_zone)); + ObReplicaType::REPLICA_TYPE_LOGONLY))) { + LOG_WARN("fail to init ls replica addr", KR(ret)); } - } else if (zlocality.replica_attr_set_ - .get_encryption_logonly_replica_attr_array() - .count() > 0) { - const int64_t m_percent = zlocality.replica_attr_set_ - .get_encryption_logonly_replica_attr_array().at(0) - .memstore_percent_; - ObReplicaProperty replica_property; - replica_property.set_memstore_percent(m_percent); + } else if (zlocality.replica_attr_set_.get_encryption_logonly_replica_attr_array().count() > 0) { if (OB_FAIL(ls_replica_addr.init( unit.server_, - ObReplicaType::REPLICA_TYPE_ENCRYPTION_LOGONLY, - replica_property, - unit_group_id, - unit.unit_id_, - locality_zone))) { - LOG_WARN("fail to init ls replica addr", - KR(ret), K(unit), K(replica_property), K(unit_group_id), - K(locality_zone)); + ObReplicaType::REPLICA_TYPE_ENCRYPTION_LOGONLY))) { + LOG_WARN("fail to init ls replica addr", KR(ret)); } } else if (zlocality.replica_attr_set_.get_readonly_replica_attr_array().count() > 0) { - const int64_t m_percent = zlocality.replica_attr_set_ - .get_readonly_replica_attr_array().at(0) - .memstore_percent_; - ObReplicaProperty replica_property; - replica_property.set_memstore_percent(m_percent); if (OB_FAIL(ls_replica_addr.init( unit.server_, - ObReplicaType::REPLICA_TYPE_READONLY, - replica_property, - unit_group_id, - unit.unit_id_, - locality_zone))) { - LOG_WARN("fail to init ls replica addr", - KR(ret), K(unit), K(replica_property), K(unit_group_id), - K(locality_zone)); + ObReplicaType::REPLICA_TYPE_READONLY))) { + LOG_WARN("fail to init ls replica addr", KR(ret)); } } else { // zone locality shall has a paxos replica in 4.0 by // now(2021.10.25) diff --git a/src/share/ls/ob_ls_creator.h b/src/share/ls/ob_ls_creator.h index 3e3d46b7ef..8652461fed 100644 --- a/src/share/ls/ob_ls_creator.h +++ b/src/share/ls/ob_ls_creator.h @@ -49,33 +49,15 @@ struct ObLSReplicaAddr { common::ObAddr addr_; common::ObReplicaType replica_type_; - common::ObReplicaProperty replica_property_; - uint64_t unit_group_id_; - uint64_t unit_id_; - common::ObZone zone_; ObLSReplicaAddr() : addr_(), - replica_type_(common::REPLICA_TYPE_MAX), - replica_property_(), - unit_group_id_(common::OB_INVALID_ID), - unit_id_(common::OB_INVALID_ID), - zone_() {} + replica_type_(common::REPLICA_TYPE_MAX) {} void reset() { *this = ObLSReplicaAddr(); } int init(const common::ObAddr &addr, - const common::ObReplicaType replica_type, - const common::ObReplicaProperty &replica_property, - const uint64_t unit_group_id, - const uint64_t unit_id, - const common::ObZone &zone); - int64_t get_memstore_percent() const {return replica_property_.get_memstore_percent();} - int set_memstore_percent(const int64_t mp) {return replica_property_.set_memstore_percent(mp);} + const common::ObReplicaType replica_type); TO_STRING_KV(K_(addr), - K_(replica_type), - K_(replica_property), - K_(unit_group_id), - K_(unit_id), - K_(zone)); + K_(replica_type)); }; typedef common::ObArray ObLSAddr; @@ -100,18 +82,23 @@ public: const common::ObCompatibilityMode &compat_mode, const ObString &zone_priority, const bool create_with_palf, - const palf::PalfBaseInfo &palf_base_info); + const palf::PalfBaseInfo &palf_base_info, + const uint64_t source_tenant_id); int create_user_ls(const share::ObLSStatusInfo &status_info, const int64_t paxos_replica_num, const share::schema::ZoneLocalityIArray &zone_locality, const SCN &create_scn, const common::ObCompatibilityMode &compat_mode, const bool create_with_palf, - const palf::PalfBaseInfo &palf_base_info); + const palf::PalfBaseInfo &palf_base_info, + const uint64_t source_tenant_id); int create_sys_tenant_ls(const obrpc::ObServerInfoList &rs_list, const common::ObIArray &unit_array); bool is_valid(); + private: + int construct_clone_tenant_ls_addrs_(const uint64_t source_tenant_id, + ObLSAddr &addr); int do_create_ls_(const ObLSAddr &addr, ObMember &arbitration_service, const share::ObLSStatusInfo &info, @@ -153,6 +140,13 @@ private: const common::GlobalLearnerList &learner_list); // interface for oceanbase 4.0 + int construct_ls_addrs_according_to_locality_( + const share::schema::ZoneLocalityIArray &zone_locality_array, + const common::ObIArray &unit_info_array, + const bool is_sys_ls, + const bool is_duplicate_ls, + ObILSAddr &ls_addr); + int alloc_sys_ls_addr(const uint64_t tenant_id, const ObIArray &pools, const share::schema::ZoneLocalityIArray &zone_locality, diff --git a/src/share/ls/ob_ls_info.cpp b/src/share/ls/ob_ls_info.cpp index 20255d692b..625e33ffcc 100644 --- a/src/share/ls/ob_ls_info.cpp +++ b/src/share/ls/ob_ls_info.cpp @@ -148,7 +148,7 @@ void ObLSReplica::reset() replica_type_ = REPLICA_TYPE_FULL; proposal_id_ = 0; replica_status_ = REPLICA_STATUS_NORMAL; - restore_status_ = ObLSRestoreStatus::Status::RESTORE_NONE; + restore_status_ = ObLSRestoreStatus::Status::NONE; property_.reset(); //meta related unit_id_ = OB_INVALID_ID; diff --git a/src/share/ls/ob_ls_info.h b/src/share/ls/ob_ls_info.h index dfe0157369..36bbb0e0d7 100644 --- a/src/share/ls/ob_ls_info.h +++ b/src/share/ls/ob_ls_info.h @@ -135,7 +135,6 @@ public: inline bool is_paxos_replica() const { return common::REPLICA_TYPE_ENCRYPTION_LOGONLY == replica_type_ || common::REPLICA_TYPE_FULL == replica_type_ || common::REPLICA_TYPE_LOGONLY == replica_type_; } - inline bool is_in_restore() const { return !restore_status_.is_restore_none(); } int64_t to_string(char *buf, const int64_t buf_len) const; // operator-related functions int assign(const ObLSReplica &other); diff --git a/src/share/ls/ob_ls_operator.cpp b/src/share/ls/ob_ls_operator.cpp index c029194f9e..5b3eb0400d 100644 --- a/src/share/ls/ob_ls_operator.cpp +++ b/src/share/ls/ob_ls_operator.cpp @@ -25,6 +25,7 @@ #include "lib/utility/ob_unify_serialize.h" //OB_SERIALIZE_MEMBER #include "observer/ob_inner_sql_connection.h"//ObInnerSQLConnection #include "observer/ob_inner_sql_connection_pool.h"//ObInnerSQLConnectionPool +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" //ObTenantSnapshotUtil #include "share/rc/ob_tenant_base.h"//MTL_WITH_CHECK_TENANT #include "storage/tx/ob_trans_define.h"//MonotonicTs #include "storage/tx/ob_ts_mgr.h"//GET_GTS @@ -38,6 +39,7 @@ using namespace oceanbase; using namespace oceanbase::common; +using namespace oceanbase::rootserver; namespace oceanbase { using namespace transaction; @@ -299,6 +301,7 @@ int ObLSAttrOperator::operator_ls_in_trans_( ObMySQLTransaction &trans) { int ret = OB_SUCCESS; + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::MODIFY_LS); if (OB_UNLIKELY(!ls_attr.is_valid() || sql.empty() || !trans.is_started())) { @@ -320,6 +323,8 @@ int ObLSAttrOperator::operator_ls_in_trans_( only update ls table on normal switchover status */ } else if (OB_FAIL(get_ls_attr(SYS_LS, for_update, trans, sys_ls_attr))) { LOG_WARN("failed to load sys ls status", KR(ret)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(tenant_id_, case_to_check))) { + LOG_WARN("fail to check whether tenant is cloning", KR(ret), K_(tenant_id), K(case_to_check)); } else if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id_, proxy_, false /* for_update */, tenant_info))) { LOG_WARN("failed to load tenant info", KR(ret), K_(tenant_id)); } else if (working_sw_status != tenant_info.get_switchover_status()) { @@ -842,12 +847,18 @@ int ObLSAttrOperator::alter_ls_group_in_trans(const ObLSAttr &ls_info, { int ret = OB_SUCCESS; ObSqlString sql; + ObLSAttr lock_ls_attr; + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::MODIFY_LS); if (OB_UNLIKELY(!ls_info.is_valid() || OB_INVALID_ID == new_ls_group_id || !trans.is_started())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid_argument", KR(ret), K(ls_info), K(new_ls_group_id), "trans_started", trans.is_started()); + } else if (OB_FAIL(get_ls_attr(ls_info.get_ls_id(), true/*for_update*/, trans, lock_ls_attr))) { + LOG_WARN("failed to lock ls status for clone conflict check", KR(ret), K(ls_info)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(tenant_id_, case_to_check))) { + LOG_WARN("fail to check whether tenant is cloning", KR(ret), K_(tenant_id), K(case_to_check)); } else if (OB_FAIL(sql.assign_fmt( "UPDATE %s set ls_group_id = %lu where ls_id = %ld and ls_group_id = %lu", OB_ALL_LS_TNAME, new_ls_group_id, ls_info.get_ls_id().id(), ls_info.get_ls_group_id()))) { @@ -875,6 +886,8 @@ int ObLSAttrOperator::update_ls_flag_in_trans(const ObLSID &id, ObSqlString sql; ObLSFlagStr old_flag_str; ObLSFlagStr new_flag_str; + ObLSAttr lock_ls_attr; + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::MODIFY_LS); if (OB_UNLIKELY(!id.is_valid() || !new_flag.is_valid() @@ -889,6 +902,10 @@ int ObLSAttrOperator::update_ls_flag_in_trans(const ObLSID &id, id, EXCLUSIVE))) { LOG_WARN("lock ls in trans failed", KR(ret), K_(tenant_id), K(id)); + } else if (OB_FAIL(get_ls_attr(id, true/*for_update*/, trans, lock_ls_attr))) { + LOG_WARN("failed to lock ls status for clone conflict check", KR(ret), K(id)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(tenant_id_, case_to_check))) { + LOG_WARN("fail to check whether tenant is cloning", KR(ret), K_(tenant_id), K(case_to_check)); } else { DEBUG_SYNC(AFTER_LOCK_LS_AND_BEFORE_CHANGE_LS_FLAG); if (OB_FAIL(new_flag.flag_to_str(new_flag_str))) { diff --git a/src/share/ob_common_rpc_proxy.h b/src/share/ob_common_rpc_proxy.h index 2030dc10f4..4148b442a3 100644 --- a/src/share/ob_common_rpc_proxy.h +++ b/src/share/ob_common_rpc_proxy.h @@ -185,6 +185,7 @@ public: RPC_S(PR5 create_resource_unit, obrpc::OB_CREATE_RESOURCE_UNIT, (ObCreateResourceUnitArg)); RPC_S(PR5 alter_resource_unit, obrpc::OB_ALTER_RESOURCE_UNIT, (ObAlterResourceUnitArg)); RPC_S(PR5 drop_resource_unit, obrpc::OB_DROP_RESOURCE_UNIT, (ObDropResourceUnitArg)); + RPC_S(PRD clone_resource_pool, obrpc::OB_CLONE_RESOURCE_POOL, (ObCloneResourcePoolArg)); RPC_S(PRD create_resource_pool, obrpc::OB_CREATE_RESOURCE_POOL, (ObCreateResourcePoolArg)); RPC_S(PRD alter_resource_pool, obrpc::OB_ALTER_RESOURCE_POOL, (ObAlterResourcePoolArg)); RPC_S(PRD drop_resource_pool, obrpc::OB_DROP_RESOURCE_POOL, (ObDropResourcePoolArg)); @@ -277,6 +278,7 @@ public: // (ObDDLNopOpreatorArg)); // use ddl thread RPC_S(PR5 check_backup_scheduler_working, obrpc::OB_CHECK_BACKUP_SCHEDULER_WORKING, Bool); RPC_S(PR5 send_physical_restore_result, obrpc::OB_PHYSICAL_RESTORE_RES, (obrpc::ObPhysicalRestoreResult)); + RPC_S(PRD clone_tenant, obrpc::OB_CLONE_TENANT, (ObCloneTenantArg), ObCloneTenantRes); // auto part ddl RPC_S(PRD create_restore_point, obrpc::OB_CREATE_RESTORE_POINT, (ObCreateRestorePointArg)); diff --git a/src/share/ob_debug_sync_point.h b/src/share/ob_debug_sync_point.h index 4da2775e69..587a6ce271 100755 --- a/src/share/ob_debug_sync_point.h +++ b/src/share/ob_debug_sync_point.h @@ -563,6 +563,7 @@ class ObString; ACT(BEFORE_CHECK_LS_TRANSFER_SCN_FOR_STANDBY,)\ ACT(BEFORE_GET_CONFIG_VERSION_AND_TRANSFER_SCN,)\ ACT(LS_GC_BEFORE_OFFLINE,)\ + ACT(AFTER_LOCK_SNAPSHOT_MUTEX,)\ ACT(BEFORE_FETCH_SIMPLE_TABLES,)\ ACT(BEFORE_SEND_PARALLEL_CREATE_TABLE,)\ ACT(BEFORE_DROP_TENANT,)\ diff --git a/src/share/ob_errno.cpp b/src/share/ob_errno.cpp index b8b7d475db..d111b032fd 100755 --- a/src/share/ob_errno.cpp +++ b/src/share/ob_errno.cpp @@ -6808,10 +6808,10 @@ static const _error _error_OB_CONFLICT_WITH_CLONE = { .mysql_errno = -1, .sqlstate = "HY000", .str_error = "conflict case with clone operation", - .str_user_error = "Tenant (%ld) is in %.*s procedure, %.*s not allowed now", + .str_user_error = "Tenant (%ld) is in %s procedure, %s not allowed now", .oracle_errno = 600, .oracle_str_error = "ORA-00600: internal error code, arguments: -4770, conflict case with clone operation", - .oracle_str_user_error = "ORA-00600: internal error code, arguments: -4770, Tenant (%ld) is in %.*s procedure, %.*s not allowed now" + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -4770, Tenant (%ld) is in %s procedure, %s not allowed now" }; static const _error _error_OB_ERR_PARSER_INIT = { .error_name = "OB_ERR_PARSER_INIT", @@ -26265,6 +26265,90 @@ static const _error _error_OB_ERR_ARGUMENT_SHOULD_CONSTANT_OR_GROUP_EXPR = { .oracle_str_error = "ORA-30497: Argument should be a constant or a function of expressions in GROUP BY.", .oracle_str_user_error = "ORA-30497: Argument should be a constant or a function of expressions in GROUP BY." }; +static const _error _error_OB_TENANT_SNAPSHOT_NOT_EXIST = { + .error_name = "OB_TENANT_SNAPSHOT_NOT_EXIST", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "Tenant snapshot does not exist", + .str_user_error = "Tenant snapshot \'%.*s\' does not exist", + .oracle_errno = 600, + .oracle_str_error = "ORA-00600: internal error code, arguments: -12000, Tenant snapshot does not exist", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -12000, Tenant snapshot \'%.*s\' does not exist" +}; +static const _error _error_OB_TENANT_SNAPSHOT_EXIST = { + .error_name = "OB_TENANT_SNAPSHOT_EXIST", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "Tenant snapshot already exist", + .str_user_error = "Tenant snapshot \'%.*s\' already exist", + .oracle_errno = 600, + .oracle_str_error = "ORA-00600: internal error code, arguments: -12001, Tenant snapshot already exist", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -12001, Tenant snapshot \'%.*s\' already exist" +}; +static const _error _error_OB_TENANT_SNAPSHOT_TIMEOUT = { + .error_name = "OB_TENANT_SNAPSHOT_TIMEOUT", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "Tenant snapshot task timeout", + .str_user_error = "Tenant snapshot task timeout. %.*s", + .oracle_errno = 600, + .oracle_str_error = "ORA-00600: internal error code, arguments: -12002, Tenant snapshot task timeout", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -12002, Tenant snapshot task timeout. %.*s" +}; +static const _error _error_OB_CLONE_TENANT_TIMEOUT = { + .error_name = "OB_CLONE_TENANT_TIMEOUT", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "Clone tenant timeout", + .str_user_error = "Clone tenant timeout. %.*s", + .oracle_errno = 600, + .oracle_str_error = "ORA-00600: internal error code, arguments: -12003, Clone tenant timeout", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -12003, Clone tenant timeout. %.*s" +}; +static const _error _error_OB_ERR_CLONE_TENANT = { + .error_name = "OB_ERR_CLONE_TENANT", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "Tenant clone job failed", + .str_user_error = "%.*s", + .oracle_errno = 600, + .oracle_str_error = "ORA-00600: internal error code, arguments: -12004, Tenant clone job failed", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -12004, %.*s" +}; +static const _error _error_OB_ERR_TENANT_SNAPSHOT = { + .error_name = "OB_ERR_TENANT_SNAPSHOT", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "Tenant snapshot task failed", + .str_user_error = "%.*s", + .oracle_errno = 600, + .oracle_str_error = "ORA-00600: internal error code, arguments: -12005, Tenant snapshot task failed", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -12005, %.*s" +}; +static const _error _error_OB_TENANT_SNAPSHOT_LOCK_CONFLICT = { + .error_name = "OB_TENANT_SNAPSHOT_LOCK_CONFLICT", + .error_cause = "Internal Error", + .error_solution = "Contact OceanBase Support", + .mysql_errno = -1, + .sqlstate = "HY000", + .str_error = "Tenant snapshot lock conflict", + .str_user_error = "%s", + .oracle_errno = 600, + .oracle_str_error = "ORA-00600: internal error code, arguments: -12006, Tenant snapshot lock conflict", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -12006, %s" +}; static const _error _error_OB_SP_RAISE_APPLICATION_ERROR = { .error_name = "OB_SP_RAISE_APPLICATION_ERROR", .error_cause = "Internal Error", @@ -28543,6 +28627,13 @@ struct ObStrErrorInit _errors[-OB_ERR_NO_GRANT_DEFINED_FOR_USER] = &_error_OB_ERR_NO_GRANT_DEFINED_FOR_USER; _errors[-OB_ERR_USER_ALREADY_EXISTS] = &_error_OB_ERR_USER_ALREADY_EXISTS; _errors[-OB_ERR_ARGUMENT_SHOULD_CONSTANT_OR_GROUP_EXPR] = &_error_OB_ERR_ARGUMENT_SHOULD_CONSTANT_OR_GROUP_EXPR; + _errors[-OB_TENANT_SNAPSHOT_NOT_EXIST] = &_error_OB_TENANT_SNAPSHOT_NOT_EXIST; + _errors[-OB_TENANT_SNAPSHOT_EXIST] = &_error_OB_TENANT_SNAPSHOT_EXIST; + _errors[-OB_TENANT_SNAPSHOT_TIMEOUT] = &_error_OB_TENANT_SNAPSHOT_TIMEOUT; + _errors[-OB_CLONE_TENANT_TIMEOUT] = &_error_OB_CLONE_TENANT_TIMEOUT; + _errors[-OB_ERR_CLONE_TENANT] = &_error_OB_ERR_CLONE_TENANT; + _errors[-OB_ERR_TENANT_SNAPSHOT] = &_error_OB_ERR_TENANT_SNAPSHOT; + _errors[-OB_TENANT_SNAPSHOT_LOCK_CONFLICT] = &_error_OB_TENANT_SNAPSHOT_LOCK_CONFLICT; _errors[-OB_SP_RAISE_APPLICATION_ERROR] = &_error_OB_SP_RAISE_APPLICATION_ERROR; _errors[-OB_SP_RAISE_APPLICATION_ERROR_NUM] = &_error_OB_SP_RAISE_APPLICATION_ERROR_NUM; _errors[-OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN] = &_error_OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN; @@ -28584,7 +28675,7 @@ namespace oceanbase { namespace common { -int g_all_ob_errnos[2193] = {0, -4000, -4001, -4002, -4003, -4004, -4005, -4006, -4007, -4008, -4009, -4010, -4011, -4012, -4013, -4014, -4015, -4016, -4017, -4018, -4019, -4020, -4021, -4022, -4023, -4024, -4025, -4026, -4027, -4028, -4029, -4030, -4031, -4032, -4033, -4034, -4035, -4036, -4037, -4038, -4039, -4041, -4042, -4043, -4044, -4045, -4046, -4047, -4048, -4049, -4050, -4051, -4052, -4053, -4054, -4055, -4057, -4058, -4060, -4061, -4062, -4063, -4064, -4065, -4066, -4067, -4068, -4070, -4071, -4072, -4073, -4074, -4075, -4076, -4077, -4078, -4080, -4081, -4084, -4085, -4090, -4097, -4098, -4099, -4100, -4101, -4102, -4103, -4104, -4105, -4106, -4107, -4108, -4109, -4110, -4111, -4112, -4113, -4114, -4115, -4116, -4117, -4118, -4119, -4120, -4121, -4122, -4123, -4124, -4125, -4126, -4127, -4128, -4133, -4138, -4139, -4142, -4143, -4144, -4146, -4147, -4149, -4150, -4151, -4152, -4153, -4154, -4155, -4156, -4157, -4158, -4159, -4160, -4161, -4162, -4163, -4164, -4165, -4166, -4167, -4168, -4169, -4170, -4171, -4172, -4173, -4174, -4175, -4176, -4177, -4178, -4179, -4180, -4181, -4182, -4183, -4184, -4185, -4186, -4187, -4188, -4189, -4190, -4191, -4192, -4200, -4201, -4204, -4205, -4206, -4207, -4208, -4209, -4210, -4211, -4212, -4213, -4214, -4215, -4216, -4217, -4218, -4219, -4220, -4221, -4222, -4223, -4224, -4225, -4226, -4227, -4228, -4229, -4230, -4231, -4232, -4233, -4234, -4235, -4236, -4237, -4238, -4239, -4240, -4241, -4242, -4243, -4244, -4245, -4246, -4247, -4248, -4249, -4250, -4251, -4252, -4253, -4254, -4255, -4256, -4257, -4258, -4260, -4261, -4262, -4263, -4264, -4265, -4266, -4267, -4268, -4269, -4270, -4271, -4273, -4274, -4275, -4276, -4277, -4278, -4279, -4280, -4281, -4282, -4283, -4284, -4285, -4286, -4287, -4288, -4289, -4290, -4291, -4292, -4293, -4294, -4295, -4296, -4297, -4298, -4299, -4300, -4301, -4302, -4303, -4304, -4305, -4306, -4307, -4308, -4309, -4310, -4311, -4312, -4313, -4314, -4315, -4316, -4317, -4318, -4319, -4320, -4321, -4322, -4323, -4324, -4325, -4326, -4327, -4328, -4329, -4330, -4331, -4332, -4333, -4334, -4335, -4336, -4337, -4338, -4339, -4340, -4341, -4342, -4343, -4344, -4345, -4346, -4347, -4348, -4349, -4350, -4351, -4352, -4353, -4354, -4355, -4356, -4357, -4358, -4359, -4360, -4361, -4362, -4363, -4364, -4365, -4366, -4367, -4368, -4369, -4370, -4371, -4372, -4373, -4374, -4375, -4376, -4377, -4378, -4379, -4380, -4381, -4382, -4383, -4385, -4386, -4387, -4388, -4389, -4390, -4391, -4392, -4393, -4394, -4395, -4396, -4397, -4398, -4399, -4400, -4401, -4402, -4403, -4505, -4507, -4510, -4512, -4515, -4517, -4518, -4519, -4523, -4524, -4525, -4526, -4527, -4528, -4529, -4530, -4531, -4532, -4533, -4537, -4538, -4539, -4540, -4541, -4542, -4543, -4544, -4545, -4546, -4547, -4548, -4549, -4550, -4551, -4552, -4553, -4554, -4600, -4601, -4602, -4603, -4604, -4605, -4606, -4607, -4608, -4609, -4610, -4611, -4613, -4614, -4615, -4620, -4621, -4622, -4623, -4624, -4625, -4626, -4628, -4629, -4630, -4631, -4632, -4633, -4634, -4636, -4637, -4638, -4639, -4640, -4641, -4642, -4643, -4644, -4645, -4646, -4647, -4648, -4649, -4650, -4651, -4652, -4653, -4654, -4655, -4656, -4657, -4658, -4659, -4660, -4661, -4662, -4663, -4664, -4665, -4666, -4667, -4668, -4669, -4670, -4671, -4672, -4673, -4674, -4675, -4676, -4677, -4678, -4679, -4680, -4681, -4682, -4683, -4684, -4685, -4686, -4687, -4688, -4689, -4690, -4691, -4692, -4693, -4694, -4695, -4696, -4697, -4698, -4699, -4700, -4701, -4702, -4703, -4704, -4705, -4706, -4707, -4708, -4709, -4710, -4711, -4712, -4713, -4714, -4715, -4716, -4717, -4718, -4719, -4720, -4721, -4722, -4723, -4724, -4725, -4726, -4727, -4728, -4729, -4730, -4731, -4732, -4733, -4734, -4735, -4736, -4737, -4738, -4739, -4740, -4741, -4742, -4743, -4744, -4745, -4746, -4747, -4748, -4749, -4750, -4751, -4752, -4753, -4754, -4755, -4756, -4757, -4758, -4759, -4760, -4761, -4762, -4763, -4764, -4765, -4766, -4767, -4768, -4769, -4770, -5000, -5001, -5002, -5003, -5006, -5007, -5008, -5010, -5011, -5012, -5014, -5015, -5016, -5017, -5018, -5019, -5020, -5022, -5023, -5024, -5025, -5026, -5027, -5028, -5029, -5030, -5031, -5032, -5034, -5035, -5036, -5037, -5038, -5039, -5040, -5041, -5042, -5043, -5044, -5046, -5047, -5050, -5051, -5052, -5053, -5054, -5055, -5056, -5057, -5058, -5059, -5061, -5063, -5064, -5065, -5066, -5067, -5068, -5069, -5070, -5071, -5072, -5073, -5074, -5080, -5081, -5083, -5084, -5085, -5086, -5087, -5088, -5089, -5090, -5091, -5092, -5093, -5094, -5095, -5096, -5097, -5098, -5099, -5100, -5101, -5102, -5103, -5104, -5105, -5106, -5107, -5108, -5109, -5110, -5111, -5112, -5113, -5114, -5115, -5116, -5117, -5118, -5119, -5120, -5121, -5122, -5123, -5124, -5125, -5130, -5131, -5133, -5134, -5135, -5136, -5137, -5138, -5139, -5140, -5142, -5143, -5144, -5145, -5146, -5147, -5148, -5149, -5150, -5151, -5153, -5154, -5155, -5156, -5157, -5158, -5159, -5160, -5161, -5162, -5163, -5164, -5165, -5166, -5167, -5168, -5169, -5170, -5171, -5172, -5173, -5174, -5175, -5176, -5177, -5178, -5179, -5180, -5181, -5182, -5183, -5184, -5185, -5187, -5188, -5189, -5190, -5191, -5192, -5193, -5194, -5195, -5196, -5197, -5198, -5199, -5200, -5201, -5202, -5203, -5204, -5205, -5206, -5207, -5208, -5209, -5210, -5211, -5212, -5213, -5214, -5215, -5216, -5217, -5218, -5219, -5220, -5221, -5222, -5223, -5224, -5225, -5226, -5227, -5228, -5229, -5230, -5231, -5233, -5234, -5235, -5236, -5237, -5238, -5239, -5240, -5241, -5242, -5243, -5244, -5245, -5246, -5247, -5248, -5249, -5250, -5251, -5252, -5253, -5254, -5255, -5256, -5257, -5258, -5259, -5260, -5261, -5262, -5263, -5264, -5265, -5266, -5267, -5268, -5269, -5270, -5271, -5272, -5273, -5274, -5275, -5276, -5277, -5278, -5279, -5280, -5281, -5282, -5283, -5284, -5285, -5286, -5287, -5288, -5289, -5290, -5291, -5292, -5293, -5294, -5295, -5296, -5297, -5298, -5299, -5300, -5301, -5302, -5303, -5304, -5305, -5306, -5307, -5308, -5309, -5310, -5311, -5312, -5313, -5314, -5315, -5316, -5317, -5318, -5319, -5320, -5321, -5322, -5323, -5324, -5325, -5326, -5327, -5328, -5329, -5330, -5331, -5332, -5333, -5334, -5335, -5336, -5337, -5338, -5339, -5340, -5341, -5342, -5343, -5344, -5345, -5346, -5347, -5348, -5349, -5350, -5351, -5352, -5353, -5354, -5355, -5356, -5357, -5358, -5359, -5360, -5361, -5362, -5363, -5364, -5365, -5366, -5367, -5368, -5369, -5370, -5371, -5372, -5373, -5374, -5375, -5376, -5377, -5378, -5379, -5380, -5381, -5382, -5383, -5384, -5385, -5386, -5387, -5388, -5389, -5400, -5401, -5402, -5403, -5404, -5405, -5406, -5407, -5408, -5409, -5410, -5411, -5412, -5413, -5414, -5415, -5416, -5417, -5418, -5419, -5420, -5421, -5422, -5423, -5424, -5425, -5426, -5427, -5428, -5429, -5430, -5431, -5432, -5433, -5434, -5435, -5436, -5437, -5438, -5439, -5440, -5441, -5442, -5443, -5444, -5445, -5446, -5447, -5448, -5449, -5450, -5451, -5452, -5453, -5454, -5455, -5456, -5457, -5458, -5459, -5460, -5461, -5462, -5463, -5464, -5465, -5466, -5467, -5468, -5469, -5470, -5471, -5472, -5473, -5474, -5475, -5476, -5477, -5478, -5479, -5480, -5481, -5482, -5483, -5484, -5485, -5486, -5487, -5488, -5489, -5490, -5491, -5492, -5493, -5494, -5495, -5496, -5497, -5498, -5499, -5500, -5501, -5502, -5503, -5504, -5505, -5506, -5507, -5508, -5509, -5510, -5511, -5512, -5513, -5514, -5515, -5516, -5517, -5540, -5541, -5542, -5543, -5544, -5545, -5546, -5547, -5548, -5549, -5550, -5551, -5552, -5553, -5554, -5555, -5556, -5557, -5558, -5559, -5560, -5561, -5562, -5563, -5564, -5565, -5566, -5567, -5568, -5569, -5570, -5571, -5572, -5573, -5574, -5575, -5576, -5577, -5578, -5579, -5580, -5581, -5582, -5583, -5584, -5585, -5586, -5587, -5588, -5589, -5590, -5591, -5592, -5593, -5594, -5595, -5596, -5597, -5598, -5599, -5600, -5601, -5602, -5603, -5604, -5605, -5607, -5608, -5609, -5610, -5611, -5612, -5613, -5614, -5615, -5616, -5617, -5618, -5619, -5620, -5621, -5622, -5623, -5624, -5625, -5626, -5627, -5628, -5629, -5630, -5631, -5632, -5633, -5634, -5635, -5636, -5637, -5638, -5639, -5640, -5641, -5642, -5643, -5644, -5645, -5646, -5647, -5648, -5649, -5650, -5651, -5652, -5653, -5654, -5655, -5656, -5657, -5658, -5659, -5660, -5661, -5662, -5663, -5664, -5665, -5666, -5667, -5668, -5671, -5672, -5673, -5674, -5675, -5676, -5677, -5678, -5679, -5680, -5681, -5682, -5683, -5684, -5685, -5686, -5687, -5688, -5689, -5690, -5691, -5692, -5693, -5694, -5695, -5696, -5697, -5698, -5699, -5700, -5701, -5702, -5703, -5704, -5705, -5706, -5707, -5708, -5709, -5710, -5711, -5712, -5713, -5714, -5715, -5716, -5717, -5718, -5719, -5720, -5721, -5722, -5723, -5724, -5725, -5726, -5727, -5728, -5729, -5730, -5731, -5732, -5733, -5734, -5735, -5736, -5737, -5738, -5739, -5740, -5741, -5742, -5743, -5744, -5745, -5746, -5747, -5748, -5749, -5750, -5751, -5752, -5753, -5754, -5755, -5756, -5757, -5758, -5759, -5760, -5761, -5762, -5763, -5764, -5765, -5766, -5768, -5769, -5770, -5771, -5772, -5773, -5774, -5777, -5778, -5779, -5780, -5781, -5785, -5786, -5787, -5788, -5789, -5790, -5791, -5792, -5793, -5794, -5795, -5796, -5797, -5798, -5799, -5800, -5801, -5802, -5803, -5804, -5805, -5806, -5807, -5808, -5809, -5810, -5811, -5812, -5813, -5814, -5815, -5816, -5817, -5818, -5819, -5820, -5821, -5822, -5823, -5824, -5825, -5826, -5827, -5828, -5829, -5830, -5831, -5832, -5833, -5834, -5835, -5836, -5837, -5838, -5839, -5840, -5841, -5842, -5843, -5844, -5845, -5846, -5847, -5848, -5849, -5850, -5851, -5852, -5853, -5854, -5855, -5856, -5857, -5858, -5859, -5860, -5861, -5862, -5863, -5864, -5865, -5866, -5867, -5868, -5869, -5870, -5871, -5872, -5873, -5874, -5875, -5876, -5877, -5878, -5879, -5880, -5881, -5882, -5883, -5884, -5885, -5886, -5887, -5888, -5889, -5890, -5891, -5892, -5893, -5894, -5895, -5896, -5897, -5898, -5899, -5900, -5901, -5902, -5903, -5904, -5905, -5906, -5907, -5908, -5909, -5910, -5911, -5912, -5913, -5914, -5915, -5916, -5917, -5918, -5919, -5920, -5921, -5922, -5923, -5924, -5925, -5926, -5927, -5928, -5929, -5930, -5931, -5932, -5933, -5934, -5935, -5936, -5937, -5938, -5939, -5940, -5941, -5942, -5943, -5944, -5945, -5946, -5947, -5948, -5949, -5950, -5951, -5952, -5953, -5954, -5955, -5956, -5957, -5958, -5959, -5960, -5961, -5962, -5963, -5964, -5965, -5966, -5967, -5968, -5969, -5970, -5971, -5972, -5973, -5974, -5975, -5976, -5977, -5978, -5979, -5980, -5981, -5982, -5983, -5984, -5985, -5986, -5987, -5988, -5989, -5990, -5991, -5992, -5993, -5994, -5995, -5996, -5997, -5998, -5999, -6000, -6001, -6002, -6003, -6004, -6005, -6006, -6201, -6202, -6203, -6204, -6205, -6206, -6207, -6208, -6209, -6210, -6211, -6212, -6213, -6214, -6215, -6219, -6220, -6221, -6222, -6223, -6224, -6225, -6226, -6227, -6228, -6229, -6230, -6231, -6232, -6233, -6234, -6235, -6236, -6237, -6238, -6239, -6240, -6241, -6242, -6243, -6244, -6245, -6246, -6247, -6248, -6249, -6250, -6251, -6252, -6253, -6254, -6255, -6256, -6257, -6258, -6259, -6260, -6261, -6262, -6263, -6264, -6265, -6266, -6267, -6268, -6269, -6270, -6271, -6272, -6273, -6274, -6275, -6276, -6277, -6278, -6279, -6280, -6281, -6282, -6283, -6284, -6285, -6301, -6302, -6303, -6304, -6305, -6306, -6307, -6308, -6309, -6310, -6311, -6312, -6313, -6314, -6315, -6316, -6317, -6318, -6319, -6320, -6321, -6322, -6323, -6324, -6325, -7000, -7001, -7002, -7003, -7004, -7005, -7006, -7007, -7010, -7011, -7012, -7013, -7014, -7015, -7021, -7022, -7024, -7025, -7026, -7027, -7029, -7030, -7031, -7032, -7033, -7034, -7035, -7036, -7037, -7038, -7039, -7040, -7041, -7100, -7101, -7102, -7103, -7104, -7105, -7106, -7107, -7108, -7109, -7110, -7111, -7112, -7113, -7114, -7115, -7116, -7117, -7118, -7119, -7120, -7121, -7122, -7123, -7201, -7202, -7203, -7204, -7205, -7206, -7207, -7208, -7209, -7210, -7211, -7212, -7213, -7214, -7215, -7216, -7217, -7218, -7219, -7220, -7221, -7222, -7223, -7224, -7225, -7226, -7227, -7228, -7229, -7230, -7231, -7232, -7233, -7234, -7235, -7236, -7237, -7238, -7239, -7240, -7241, -7242, -7243, -7244, -7246, -7247, -7248, -7249, -7250, -7251, -7252, -7253, -7254, -7255, -7256, -7257, -7258, -7259, -7260, -7261, -7262, -7263, -7264, -7265, -7266, -7267, -7268, -7269, -7270, -7271, -7272, -7273, -7274, -7275, -7276, -7277, -7278, -7279, -7280, -7281, -7282, -7283, -7284, -7285, -7286, -7287, -7288, -7289, -7290, -7291, -7292, -7293, -7294, -7295, -7296, -7297, -7402, -7403, -7404, -7405, -7406, -7407, -7408, -7409, -7410, -7411, -7412, -7413, -7414, -7415, -7416, -7417, -7418, -7419, -7420, -7421, -7422, -7423, -7424, -7425, -7426, -7427, -7428, -7429, -7430, -7431, -7432, -7433, -8001, -8002, -8003, -8004, -8005, -9001, -9002, -9003, -9004, -9005, -9006, -9007, -9008, -9009, -9010, -9011, -9012, -9013, -9014, -9015, -9016, -9017, -9018, -9019, -9020, -9022, -9023, -9024, -9025, -9026, -9027, -9028, -9029, -9030, -9031, -9032, -9033, -9034, -9035, -9036, -9037, -9038, -9039, -9040, -9041, -9042, -9043, -9044, -9045, -9046, -9047, -9048, -9049, -9050, -9051, -9052, -9053, -9054, -9057, -9058, -9059, -9060, -9061, -9062, -9063, -9064, -9065, -9066, -9069, -9070, -9071, -9072, -9073, -9074, -9075, -9076, -9077, -9078, -9079, -9080, -9081, -9082, -9083, -9084, -9085, -9086, -9087, -9088, -9089, -9090, -9091, -9092, -9093, -9094, -9095, -9096, -9097, -9098, -9099, -9100, -9101, -9102, -9103, -9104, -9105, -9200, -9201, -9202, -9501, -9502, -9503, -9504, -9505, -9506, -9507, -9508, -9509, -9510, -9512, -9513, -9514, -9515, -9516, -9518, -9519, -9520, -9521, -9522, -9523, -9524, -9525, -9526, -9527, -9528, -9529, -9530, -9531, -9532, -9533, -9534, -9535, -9536, -9537, -9538, -9539, -9540, -9541, -9542, -9543, -9544, -9545, -9546, -9547, -9548, -9549, -9550, -9551, -9552, -9553, -9554, -9555, -9556, -9557, -9558, -9559, -9560, -9561, -9562, -9563, -9564, -9565, -9566, -9567, -9568, -9569, -9570, -9571, -9572, -9573, -9574, -9575, -9576, -9577, -9578, -9579, -9580, -9581, -9582, -9583, -9584, -9585, -9586, -9587, -9588, -9589, -9590, -9591, -9592, -9593, -9594, -9595, -9596, -9597, -9598, -9599, -9600, -9601, -9602, -9603, -9604, -9605, -9606, -9607, -9608, -9609, -9610, -9611, -9612, -9613, -9614, -9615, -9616, -9617, -9618, -9619, -9620, -9621, -9622, -9623, -9624, -9625, -9626, -9627, -9628, -9629, -9630, -9631, -9632, -9633, -9634, -9635, -9636, -9637, -9638, -9639, -9640, -9641, -9642, -9643, -9644, -9645, -9646, -9647, -9648, -9649, -9650, -9651, -9652, -9653, -9654, -9655, -9656, -9657, -9658, -9659, -9660, -9661, -9662, -9663, -9664, -9665, -9666, -9667, -9668, -9669, -9670, -9671, -9672, -9673, -9674, -9675, -9676, -9677, -9678, -9679, -9680, -9681, -9682, -9683, -9684, -9685, -9686, -9687, -9688, -9689, -9690, -9691, -9692, -9693, -9694, -9695, -9696, -9697, -9698, -9699, -9700, -9701, -9702, -9703, -9704, -9705, -9706, -9707, -9708, -9709, -9710, -9711, -9712, -9713, -9714, -9715, -9716, -9717, -9718, -9719, -9720, -9721, -9722, -9723, -9724, -9725, -9726, -9727, -9728, -9729, -9730, -9731, -9732, -9733, -9734, -9735, -9736, -9737, -9738, -9739, -9740, -9741, -9742, -9743, -9744, -9745, -9746, -9747, -9748, -9749, -9750, -9751, -9752, -9753, -9754, -9755, -9756, -9757, -9758, -9759, -9760, -9761, -9762, -9763, -9764, -10500, -10501, -10502, -10503, -10504, -10505, -10506, -10507, -10508, -11000, -11001, -11002, -11003, -11005, -11006, -11007, -11008, -11009, -11010, -20000, -21000, -22998, -30926, -32491, -38104, -38105}; +int g_all_ob_errnos[2200] = {0, -4000, -4001, -4002, -4003, -4004, -4005, -4006, -4007, -4008, -4009, -4010, -4011, -4012, -4013, -4014, -4015, -4016, -4017, -4018, -4019, -4020, -4021, -4022, -4023, -4024, -4025, -4026, -4027, -4028, -4029, -4030, -4031, -4032, -4033, -4034, -4035, -4036, -4037, -4038, -4039, -4041, -4042, -4043, -4044, -4045, -4046, -4047, -4048, -4049, -4050, -4051, -4052, -4053, -4054, -4055, -4057, -4058, -4060, -4061, -4062, -4063, -4064, -4065, -4066, -4067, -4068, -4070, -4071, -4072, -4073, -4074, -4075, -4076, -4077, -4078, -4080, -4081, -4084, -4085, -4090, -4097, -4098, -4099, -4100, -4101, -4102, -4103, -4104, -4105, -4106, -4107, -4108, -4109, -4110, -4111, -4112, -4113, -4114, -4115, -4116, -4117, -4118, -4119, -4120, -4121, -4122, -4123, -4124, -4125, -4126, -4127, -4128, -4133, -4138, -4139, -4142, -4143, -4144, -4146, -4147, -4149, -4150, -4151, -4152, -4153, -4154, -4155, -4156, -4157, -4158, -4159, -4160, -4161, -4162, -4163, -4164, -4165, -4166, -4167, -4168, -4169, -4170, -4171, -4172, -4173, -4174, -4175, -4176, -4177, -4178, -4179, -4180, -4181, -4182, -4183, -4184, -4185, -4186, -4187, -4188, -4189, -4190, -4191, -4192, -4200, -4201, -4204, -4205, -4206, -4207, -4208, -4209, -4210, -4211, -4212, -4213, -4214, -4215, -4216, -4217, -4218, -4219, -4220, -4221, -4222, -4223, -4224, -4225, -4226, -4227, -4228, -4229, -4230, -4231, -4232, -4233, -4234, -4235, -4236, -4237, -4238, -4239, -4240, -4241, -4242, -4243, -4244, -4245, -4246, -4247, -4248, -4249, -4250, -4251, -4252, -4253, -4254, -4255, -4256, -4257, -4258, -4260, -4261, -4262, -4263, -4264, -4265, -4266, -4267, -4268, -4269, -4270, -4271, -4273, -4274, -4275, -4276, -4277, -4278, -4279, -4280, -4281, -4282, -4283, -4284, -4285, -4286, -4287, -4288, -4289, -4290, -4291, -4292, -4293, -4294, -4295, -4296, -4297, -4298, -4299, -4300, -4301, -4302, -4303, -4304, -4305, -4306, -4307, -4308, -4309, -4310, -4311, -4312, -4313, -4314, -4315, -4316, -4317, -4318, -4319, -4320, -4321, -4322, -4323, -4324, -4325, -4326, -4327, -4328, -4329, -4330, -4331, -4332, -4333, -4334, -4335, -4336, -4337, -4338, -4339, -4340, -4341, -4342, -4343, -4344, -4345, -4346, -4347, -4348, -4349, -4350, -4351, -4352, -4353, -4354, -4355, -4356, -4357, -4358, -4359, -4360, -4361, -4362, -4363, -4364, -4365, -4366, -4367, -4368, -4369, -4370, -4371, -4372, -4373, -4374, -4375, -4376, -4377, -4378, -4379, -4380, -4381, -4382, -4383, -4385, -4386, -4387, -4388, -4389, -4390, -4391, -4392, -4393, -4394, -4395, -4396, -4397, -4398, -4399, -4400, -4401, -4402, -4403, -4505, -4507, -4510, -4512, -4515, -4517, -4518, -4519, -4523, -4524, -4525, -4526, -4527, -4528, -4529, -4530, -4531, -4532, -4533, -4537, -4538, -4539, -4540, -4541, -4542, -4543, -4544, -4545, -4546, -4547, -4548, -4549, -4550, -4551, -4552, -4553, -4554, -4600, -4601, -4602, -4603, -4604, -4605, -4606, -4607, -4608, -4609, -4610, -4611, -4613, -4614, -4615, -4620, -4621, -4622, -4623, -4624, -4625, -4626, -4628, -4629, -4630, -4631, -4632, -4633, -4634, -4636, -4637, -4638, -4639, -4640, -4641, -4642, -4643, -4644, -4645, -4646, -4647, -4648, -4649, -4650, -4651, -4652, -4653, -4654, -4655, -4656, -4657, -4658, -4659, -4660, -4661, -4662, -4663, -4664, -4665, -4666, -4667, -4668, -4669, -4670, -4671, -4672, -4673, -4674, -4675, -4676, -4677, -4678, -4679, -4680, -4681, -4682, -4683, -4684, -4685, -4686, -4687, -4688, -4689, -4690, -4691, -4692, -4693, -4694, -4695, -4696, -4697, -4698, -4699, -4700, -4701, -4702, -4703, -4704, -4705, -4706, -4707, -4708, -4709, -4710, -4711, -4712, -4713, -4714, -4715, -4716, -4717, -4718, -4719, -4720, -4721, -4722, -4723, -4724, -4725, -4726, -4727, -4728, -4729, -4730, -4731, -4732, -4733, -4734, -4735, -4736, -4737, -4738, -4739, -4740, -4741, -4742, -4743, -4744, -4745, -4746, -4747, -4748, -4749, -4750, -4751, -4752, -4753, -4754, -4755, -4756, -4757, -4758, -4759, -4760, -4761, -4762, -4763, -4764, -4765, -4766, -4767, -4768, -4769, -4770, -5000, -5001, -5002, -5003, -5006, -5007, -5008, -5010, -5011, -5012, -5014, -5015, -5016, -5017, -5018, -5019, -5020, -5022, -5023, -5024, -5025, -5026, -5027, -5028, -5029, -5030, -5031, -5032, -5034, -5035, -5036, -5037, -5038, -5039, -5040, -5041, -5042, -5043, -5044, -5046, -5047, -5050, -5051, -5052, -5053, -5054, -5055, -5056, -5057, -5058, -5059, -5061, -5063, -5064, -5065, -5066, -5067, -5068, -5069, -5070, -5071, -5072, -5073, -5074, -5080, -5081, -5083, -5084, -5085, -5086, -5087, -5088, -5089, -5090, -5091, -5092, -5093, -5094, -5095, -5096, -5097, -5098, -5099, -5100, -5101, -5102, -5103, -5104, -5105, -5106, -5107, -5108, -5109, -5110, -5111, -5112, -5113, -5114, -5115, -5116, -5117, -5118, -5119, -5120, -5121, -5122, -5123, -5124, -5125, -5130, -5131, -5133, -5134, -5135, -5136, -5137, -5138, -5139, -5140, -5142, -5143, -5144, -5145, -5146, -5147, -5148, -5149, -5150, -5151, -5153, -5154, -5155, -5156, -5157, -5158, -5159, -5160, -5161, -5162, -5163, -5164, -5165, -5166, -5167, -5168, -5169, -5170, -5171, -5172, -5173, -5174, -5175, -5176, -5177, -5178, -5179, -5180, -5181, -5182, -5183, -5184, -5185, -5187, -5188, -5189, -5190, -5191, -5192, -5193, -5194, -5195, -5196, -5197, -5198, -5199, -5200, -5201, -5202, -5203, -5204, -5205, -5206, -5207, -5208, -5209, -5210, -5211, -5212, -5213, -5214, -5215, -5216, -5217, -5218, -5219, -5220, -5221, -5222, -5223, -5224, -5225, -5226, -5227, -5228, -5229, -5230, -5231, -5233, -5234, -5235, -5236, -5237, -5238, -5239, -5240, -5241, -5242, -5243, -5244, -5245, -5246, -5247, -5248, -5249, -5250, -5251, -5252, -5253, -5254, -5255, -5256, -5257, -5258, -5259, -5260, -5261, -5262, -5263, -5264, -5265, -5266, -5267, -5268, -5269, -5270, -5271, -5272, -5273, -5274, -5275, -5276, -5277, -5278, -5279, -5280, -5281, -5282, -5283, -5284, -5285, -5286, -5287, -5288, -5289, -5290, -5291, -5292, -5293, -5294, -5295, -5296, -5297, -5298, -5299, -5300, -5301, -5302, -5303, -5304, -5305, -5306, -5307, -5308, -5309, -5310, -5311, -5312, -5313, -5314, -5315, -5316, -5317, -5318, -5319, -5320, -5321, -5322, -5323, -5324, -5325, -5326, -5327, -5328, -5329, -5330, -5331, -5332, -5333, -5334, -5335, -5336, -5337, -5338, -5339, -5340, -5341, -5342, -5343, -5344, -5345, -5346, -5347, -5348, -5349, -5350, -5351, -5352, -5353, -5354, -5355, -5356, -5357, -5358, -5359, -5360, -5361, -5362, -5363, -5364, -5365, -5366, -5367, -5368, -5369, -5370, -5371, -5372, -5373, -5374, -5375, -5376, -5377, -5378, -5379, -5380, -5381, -5382, -5383, -5384, -5385, -5386, -5387, -5388, -5389, -5400, -5401, -5402, -5403, -5404, -5405, -5406, -5407, -5408, -5409, -5410, -5411, -5412, -5413, -5414, -5415, -5416, -5417, -5418, -5419, -5420, -5421, -5422, -5423, -5424, -5425, -5426, -5427, -5428, -5429, -5430, -5431, -5432, -5433, -5434, -5435, -5436, -5437, -5438, -5439, -5440, -5441, -5442, -5443, -5444, -5445, -5446, -5447, -5448, -5449, -5450, -5451, -5452, -5453, -5454, -5455, -5456, -5457, -5458, -5459, -5460, -5461, -5462, -5463, -5464, -5465, -5466, -5467, -5468, -5469, -5470, -5471, -5472, -5473, -5474, -5475, -5476, -5477, -5478, -5479, -5480, -5481, -5482, -5483, -5484, -5485, -5486, -5487, -5488, -5489, -5490, -5491, -5492, -5493, -5494, -5495, -5496, -5497, -5498, -5499, -5500, -5501, -5502, -5503, -5504, -5505, -5506, -5507, -5508, -5509, -5510, -5511, -5512, -5513, -5514, -5515, -5516, -5517, -5540, -5541, -5542, -5543, -5544, -5545, -5546, -5547, -5548, -5549, -5550, -5551, -5552, -5553, -5554, -5555, -5556, -5557, -5558, -5559, -5560, -5561, -5562, -5563, -5564, -5565, -5566, -5567, -5568, -5569, -5570, -5571, -5572, -5573, -5574, -5575, -5576, -5577, -5578, -5579, -5580, -5581, -5582, -5583, -5584, -5585, -5586, -5587, -5588, -5589, -5590, -5591, -5592, -5593, -5594, -5595, -5596, -5597, -5598, -5599, -5600, -5601, -5602, -5603, -5604, -5605, -5607, -5608, -5609, -5610, -5611, -5612, -5613, -5614, -5615, -5616, -5617, -5618, -5619, -5620, -5621, -5622, -5623, -5624, -5625, -5626, -5627, -5628, -5629, -5630, -5631, -5632, -5633, -5634, -5635, -5636, -5637, -5638, -5639, -5640, -5641, -5642, -5643, -5644, -5645, -5646, -5647, -5648, -5649, -5650, -5651, -5652, -5653, -5654, -5655, -5656, -5657, -5658, -5659, -5660, -5661, -5662, -5663, -5664, -5665, -5666, -5667, -5668, -5671, -5672, -5673, -5674, -5675, -5676, -5677, -5678, -5679, -5680, -5681, -5682, -5683, -5684, -5685, -5686, -5687, -5688, -5689, -5690, -5691, -5692, -5693, -5694, -5695, -5696, -5697, -5698, -5699, -5700, -5701, -5702, -5703, -5704, -5705, -5706, -5707, -5708, -5709, -5710, -5711, -5712, -5713, -5714, -5715, -5716, -5717, -5718, -5719, -5720, -5721, -5722, -5723, -5724, -5725, -5726, -5727, -5728, -5729, -5730, -5731, -5732, -5733, -5734, -5735, -5736, -5737, -5738, -5739, -5740, -5741, -5742, -5743, -5744, -5745, -5746, -5747, -5748, -5749, -5750, -5751, -5752, -5753, -5754, -5755, -5756, -5757, -5758, -5759, -5760, -5761, -5762, -5763, -5764, -5765, -5766, -5768, -5769, -5770, -5771, -5772, -5773, -5774, -5777, -5778, -5779, -5780, -5781, -5785, -5786, -5787, -5788, -5789, -5790, -5791, -5792, -5793, -5794, -5795, -5796, -5797, -5798, -5799, -5800, -5801, -5802, -5803, -5804, -5805, -5806, -5807, -5808, -5809, -5810, -5811, -5812, -5813, -5814, -5815, -5816, -5817, -5818, -5819, -5820, -5821, -5822, -5823, -5824, -5825, -5826, -5827, -5828, -5829, -5830, -5831, -5832, -5833, -5834, -5835, -5836, -5837, -5838, -5839, -5840, -5841, -5842, -5843, -5844, -5845, -5846, -5847, -5848, -5849, -5850, -5851, -5852, -5853, -5854, -5855, -5856, -5857, -5858, -5859, -5860, -5861, -5862, -5863, -5864, -5865, -5866, -5867, -5868, -5869, -5870, -5871, -5872, -5873, -5874, -5875, -5876, -5877, -5878, -5879, -5880, -5881, -5882, -5883, -5884, -5885, -5886, -5887, -5888, -5889, -5890, -5891, -5892, -5893, -5894, -5895, -5896, -5897, -5898, -5899, -5900, -5901, -5902, -5903, -5904, -5905, -5906, -5907, -5908, -5909, -5910, -5911, -5912, -5913, -5914, -5915, -5916, -5917, -5918, -5919, -5920, -5921, -5922, -5923, -5924, -5925, -5926, -5927, -5928, -5929, -5930, -5931, -5932, -5933, -5934, -5935, -5936, -5937, -5938, -5939, -5940, -5941, -5942, -5943, -5944, -5945, -5946, -5947, -5948, -5949, -5950, -5951, -5952, -5953, -5954, -5955, -5956, -5957, -5958, -5959, -5960, -5961, -5962, -5963, -5964, -5965, -5966, -5967, -5968, -5969, -5970, -5971, -5972, -5973, -5974, -5975, -5976, -5977, -5978, -5979, -5980, -5981, -5982, -5983, -5984, -5985, -5986, -5987, -5988, -5989, -5990, -5991, -5992, -5993, -5994, -5995, -5996, -5997, -5998, -5999, -6000, -6001, -6002, -6003, -6004, -6005, -6006, -6201, -6202, -6203, -6204, -6205, -6206, -6207, -6208, -6209, -6210, -6211, -6212, -6213, -6214, -6215, -6219, -6220, -6221, -6222, -6223, -6224, -6225, -6226, -6227, -6228, -6229, -6230, -6231, -6232, -6233, -6234, -6235, -6236, -6237, -6238, -6239, -6240, -6241, -6242, -6243, -6244, -6245, -6246, -6247, -6248, -6249, -6250, -6251, -6252, -6253, -6254, -6255, -6256, -6257, -6258, -6259, -6260, -6261, -6262, -6263, -6264, -6265, -6266, -6267, -6268, -6269, -6270, -6271, -6272, -6273, -6274, -6275, -6276, -6277, -6278, -6279, -6280, -6281, -6282, -6283, -6284, -6285, -6301, -6302, -6303, -6304, -6305, -6306, -6307, -6308, -6309, -6310, -6311, -6312, -6313, -6314, -6315, -6316, -6317, -6318, -6319, -6320, -6321, -6322, -6323, -6324, -6325, -7000, -7001, -7002, -7003, -7004, -7005, -7006, -7007, -7010, -7011, -7012, -7013, -7014, -7015, -7021, -7022, -7024, -7025, -7026, -7027, -7029, -7030, -7031, -7032, -7033, -7034, -7035, -7036, -7037, -7038, -7039, -7040, -7041, -7100, -7101, -7102, -7103, -7104, -7105, -7106, -7107, -7108, -7109, -7110, -7111, -7112, -7113, -7114, -7115, -7116, -7117, -7118, -7119, -7120, -7121, -7122, -7123, -7201, -7202, -7203, -7204, -7205, -7206, -7207, -7208, -7209, -7210, -7211, -7212, -7213, -7214, -7215, -7216, -7217, -7218, -7219, -7220, -7221, -7222, -7223, -7224, -7225, -7226, -7227, -7228, -7229, -7230, -7231, -7232, -7233, -7234, -7235, -7236, -7237, -7238, -7239, -7240, -7241, -7242, -7243, -7244, -7246, -7247, -7248, -7249, -7250, -7251, -7252, -7253, -7254, -7255, -7256, -7257, -7258, -7259, -7260, -7261, -7262, -7263, -7264, -7265, -7266, -7267, -7268, -7269, -7270, -7271, -7272, -7273, -7274, -7275, -7276, -7277, -7278, -7279, -7280, -7281, -7282, -7283, -7284, -7285, -7286, -7287, -7288, -7289, -7290, -7291, -7292, -7293, -7294, -7295, -7296, -7297, -7402, -7403, -7404, -7405, -7406, -7407, -7408, -7409, -7410, -7411, -7412, -7413, -7414, -7415, -7416, -7417, -7418, -7419, -7420, -7421, -7422, -7423, -7424, -7425, -7426, -7427, -7428, -7429, -7430, -7431, -7432, -7433, -8001, -8002, -8003, -8004, -8005, -9001, -9002, -9003, -9004, -9005, -9006, -9007, -9008, -9009, -9010, -9011, -9012, -9013, -9014, -9015, -9016, -9017, -9018, -9019, -9020, -9022, -9023, -9024, -9025, -9026, -9027, -9028, -9029, -9030, -9031, -9032, -9033, -9034, -9035, -9036, -9037, -9038, -9039, -9040, -9041, -9042, -9043, -9044, -9045, -9046, -9047, -9048, -9049, -9050, -9051, -9052, -9053, -9054, -9057, -9058, -9059, -9060, -9061, -9062, -9063, -9064, -9065, -9066, -9069, -9070, -9071, -9072, -9073, -9074, -9075, -9076, -9077, -9078, -9079, -9080, -9081, -9082, -9083, -9084, -9085, -9086, -9087, -9088, -9089, -9090, -9091, -9092, -9093, -9094, -9095, -9096, -9097, -9098, -9099, -9100, -9101, -9102, -9103, -9104, -9105, -9200, -9201, -9202, -9501, -9502, -9503, -9504, -9505, -9506, -9507, -9508, -9509, -9510, -9512, -9513, -9514, -9515, -9516, -9518, -9519, -9520, -9521, -9522, -9523, -9524, -9525, -9526, -9527, -9528, -9529, -9530, -9531, -9532, -9533, -9534, -9535, -9536, -9537, -9538, -9539, -9540, -9541, -9542, -9543, -9544, -9545, -9546, -9547, -9548, -9549, -9550, -9551, -9552, -9553, -9554, -9555, -9556, -9557, -9558, -9559, -9560, -9561, -9562, -9563, -9564, -9565, -9566, -9567, -9568, -9569, -9570, -9571, -9572, -9573, -9574, -9575, -9576, -9577, -9578, -9579, -9580, -9581, -9582, -9583, -9584, -9585, -9586, -9587, -9588, -9589, -9590, -9591, -9592, -9593, -9594, -9595, -9596, -9597, -9598, -9599, -9600, -9601, -9602, -9603, -9604, -9605, -9606, -9607, -9608, -9609, -9610, -9611, -9612, -9613, -9614, -9615, -9616, -9617, -9618, -9619, -9620, -9621, -9622, -9623, -9624, -9625, -9626, -9627, -9628, -9629, -9630, -9631, -9632, -9633, -9634, -9635, -9636, -9637, -9638, -9639, -9640, -9641, -9642, -9643, -9644, -9645, -9646, -9647, -9648, -9649, -9650, -9651, -9652, -9653, -9654, -9655, -9656, -9657, -9658, -9659, -9660, -9661, -9662, -9663, -9664, -9665, -9666, -9667, -9668, -9669, -9670, -9671, -9672, -9673, -9674, -9675, -9676, -9677, -9678, -9679, -9680, -9681, -9682, -9683, -9684, -9685, -9686, -9687, -9688, -9689, -9690, -9691, -9692, -9693, -9694, -9695, -9696, -9697, -9698, -9699, -9700, -9701, -9702, -9703, -9704, -9705, -9706, -9707, -9708, -9709, -9710, -9711, -9712, -9713, -9714, -9715, -9716, -9717, -9718, -9719, -9720, -9721, -9722, -9723, -9724, -9725, -9726, -9727, -9728, -9729, -9730, -9731, -9732, -9733, -9734, -9735, -9736, -9737, -9738, -9739, -9740, -9741, -9742, -9743, -9744, -9745, -9746, -9747, -9748, -9749, -9750, -9751, -9752, -9753, -9754, -9755, -9756, -9757, -9758, -9759, -9760, -9761, -9762, -9763, -9764, -10500, -10501, -10502, -10503, -10504, -10505, -10506, -10507, -10508, -11000, -11001, -11002, -11003, -11005, -11006, -11007, -11008, -11009, -11010, -12000, -12001, -12002, -12003, -12004, -12005, -12006, -20000, -21000, -22998, -30926, -32491, -38104, -38105}; const char *ob_error_name(const int err) { const char *ret = "Unknown error"; diff --git a/src/share/ob_errno.def b/src/share/ob_errno.def index 1a9c2b9e2a..c2989dbbc4 100755 --- a/src/share/ob_errno.def +++ b/src/share/ob_errno.def @@ -671,7 +671,7 @@ DEFINE_ERROR_EXT_DEP(OB_LS_WAITING_SAFE_DESTROY, -4766, -1, "HY000", "ls waiting DEFINE_ERROR(OB_LS_NOT_LEADER, -4767, -1, "HY000", "log stream is not leader log stream"); DEFINE_ERROR_EXT_DEP(OB_LS_LOCK_CONFLICT, -4768, -1, "HY000", "ls lock conflict", "ls lock conflict, %s"); DEFINE_ERROR_EXT_DEP(OB_INVALID_ROOT_KEY, -4769, -1, "HY000", "invalid root key", "%s"); -DEFINE_ERROR_EXT(OB_CONFLICT_WITH_CLONE, -4770, -1, "HY000", "conflict case with clone operation", "Tenant (%ld) is in %.*s procedure, %.*s not allowed now"); +DEFINE_ERROR_EXT(OB_CONFLICT_WITH_CLONE, -4770, -1, "HY000", "conflict case with clone operation", "Tenant (%ld) is in %s procedure, %s not allowed now"); //////////////////////////////////////////////////////////////// // SQL & Schema specific error code, -5000 ~ -6000 @@ -2423,13 +2423,13 @@ DEFINE_ORACLE_ERROR(OB_ERR_ARGUMENT_SHOULD_CONSTANT_OR_GROUP_EXPR, -11010, -1, " //////////////////////////////////////////////////////////////// // tenant snapshot and tenant clone error codes [-12000 ~ -12100) //////////////////////////////////////////////////////////////// -//DEFINE_ERROR_EXT_DEP(OB_TENANT_SNAPSHOT_NOT_EXIST, -12000, -1, "HY000", "Tenant snapshot does not exist", "Tenant snapshot \'%.*s\' does not exist"); -//DEFINE_ERROR_EXT_DEP(OB_TENANT_SNAPSHOT_EXIST, -12001, -1, "HY000", "Tenant snapshot already exist", "Tenant snapshot \'%.*s\' already exist"); -//DEFINE_ERROR_EXT_DEP(OB_TENANT_SNAPSHOT_TIMEOUT, -12002, -1, "HY000", "Tenant snapshot task timeout", "Tenant snapshot task timeout. %.*s"); -//DEFINE_ERROR_EXT_DEP(OB_CLONE_TENANT_TIMEOUT, -12003, -1, "HY000", "Clone tenant timeout", "Clone tenant timeout. %.*s"); -//DEFINE_ERROR_EXT_DEP(OB_ERR_CLONE_TENANT, -12004, -1, "HY000", "Tenant clone job failed", "Tenant clone job failed during the %.*s stage"); -//DEFINE_ERROR_EXT_DEP(OB_ERR_TENANT_SNAPSHOT, -12005, -1, "HY000", "Tenant snapshot task failed", "%.*s"); -//DEFINE_ERROR_EXT_DEP(OB_TENANT_SNAPSHOT_LOCK_CONFLICT, -12006, -1, "HY000", "Tenant snapshot lock conflict", "%s"); +DEFINE_ERROR_EXT_DEP(OB_TENANT_SNAPSHOT_NOT_EXIST, -12000, -1, "HY000", "Tenant snapshot does not exist", "Tenant snapshot \'%.*s\' does not exist"); +DEFINE_ERROR_EXT_DEP(OB_TENANT_SNAPSHOT_EXIST, -12001, -1, "HY000", "Tenant snapshot already exist", "Tenant snapshot \'%.*s\' already exist"); +DEFINE_ERROR_EXT_DEP(OB_TENANT_SNAPSHOT_TIMEOUT, -12002, -1, "HY000", "Tenant snapshot task timeout", "Tenant snapshot task timeout. %.*s"); +DEFINE_ERROR_EXT_DEP(OB_CLONE_TENANT_TIMEOUT, -12003, -1, "HY000", "Clone tenant timeout", "Clone tenant timeout. %.*s"); +DEFINE_ERROR_EXT_DEP(OB_ERR_CLONE_TENANT, -12004, -1, "HY000", "Tenant clone job failed", "%.*s"); +DEFINE_ERROR_EXT_DEP(OB_ERR_TENANT_SNAPSHOT, -12005, -1, "HY000", "Tenant snapshot task failed", "%.*s"); +DEFINE_ERROR_EXT_DEP(OB_TENANT_SNAPSHOT_LOCK_CONFLICT, -12006, -1, "HY000", "Tenant snapshot lock conflict", "%s"); //////////////////////////////////////////////////////////////// // !!! text/blob || clob/blob erro code diff --git a/src/share/ob_errno.h b/src/share/ob_errno.h index aa07d1ff02..9d214c3074 100755 --- a/src/share/ob_errno.h +++ b/src/share/ob_errno.h @@ -2406,7 +2406,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_LS_NOT_LEADER__USER_ERROR_MSG "log stream is not leader log stream" #define OB_LS_LOCK_CONFLICT__USER_ERROR_MSG "ls lock conflict, %s" #define OB_INVALID_ROOT_KEY__USER_ERROR_MSG "%s" -#define OB_CONFLICT_WITH_CLONE__USER_ERROR_MSG "Tenant (%ld) is in %.*s procedure, %.*s not allowed now" +#define OB_CONFLICT_WITH_CLONE__USER_ERROR_MSG "Tenant (%ld) is in %s procedure, %s not allowed now" #define OB_ERR_PARSER_INIT__USER_ERROR_MSG "Failed to init SQL parser" #define OB_ERR_PARSE_SQL__USER_ERROR_MSG "%s near \'%.*s\' at line %d" #define OB_ERR_RESOLVE_SQL__USER_ERROR_MSG "Resolve error" @@ -4028,6 +4028,13 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_ERR_NO_GRANT_DEFINED_FOR_USER__USER_ERROR_MSG "There is no such grant defined for user '%.*s' on host '%.*s'" #define OB_ERR_USER_ALREADY_EXISTS__USER_ERROR_MSG "Authorization ID '%.*s'@'%.*s' already exists" #define OB_ERR_ARGUMENT_SHOULD_CONSTANT_OR_GROUP_EXPR__USER_ERROR_MSG "Argument should be a constant or a function of expressions in GROUP BY." +#define OB_TENANT_SNAPSHOT_NOT_EXIST__USER_ERROR_MSG "Tenant snapshot \'%.*s\' does not exist" +#define OB_TENANT_SNAPSHOT_EXIST__USER_ERROR_MSG "Tenant snapshot \'%.*s\' already exist" +#define OB_TENANT_SNAPSHOT_TIMEOUT__USER_ERROR_MSG "Tenant snapshot task timeout. %.*s" +#define OB_CLONE_TENANT_TIMEOUT__USER_ERROR_MSG "Clone tenant timeout. %.*s" +#define OB_ERR_CLONE_TENANT__USER_ERROR_MSG "%.*s" +#define OB_ERR_TENANT_SNAPSHOT__USER_ERROR_MSG "%.*s" +#define OB_TENANT_SNAPSHOT_LOCK_CONFLICT__USER_ERROR_MSG "%s" #define OB_SP_RAISE_APPLICATION_ERROR__USER_ERROR_MSG "%.*s" #define OB_SP_RAISE_APPLICATION_ERROR_NUM__USER_ERROR_MSG "error number argument to raise_application_error of '%d' is out of range" #define OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN__USER_ERROR_MSG "CLOB or NCLOB in multibyte character set not supported" @@ -4603,7 +4610,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_LS_NOT_LEADER__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4767, log stream is not leader log stream" #define OB_LS_LOCK_CONFLICT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4768, ls lock conflict, %s" #define OB_INVALID_ROOT_KEY__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4769, %s" -#define OB_CONFLICT_WITH_CLONE__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4770, Tenant (%ld) is in %.*s procedure, %.*s not allowed now" +#define OB_CONFLICT_WITH_CLONE__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -4770, Tenant (%ld) is in %s procedure, %s not allowed now" #define OB_ERR_PARSER_INIT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5000, Failed to init SQL parser" #define OB_ERR_PARSE_SQL__ORA_USER_ERROR_MSG "ORA-00900: %s near \'%.*s\' at line %d" #define OB_ERR_RESOLVE_SQL__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -5002, Resolve error" @@ -6225,6 +6232,13 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_ERR_NO_GRANT_DEFINED_FOR_USER__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -11008, There is no such grant defined for user '%.*s' on host '%.*s'" #define OB_ERR_USER_ALREADY_EXISTS__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -11009, Authorization ID '%.*s'@'%.*s' already exists" #define OB_ERR_ARGUMENT_SHOULD_CONSTANT_OR_GROUP_EXPR__ORA_USER_ERROR_MSG "ORA-30497: Argument should be a constant or a function of expressions in GROUP BY." +#define OB_TENANT_SNAPSHOT_NOT_EXIST__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -12000, Tenant snapshot \'%.*s\' does not exist" +#define OB_TENANT_SNAPSHOT_EXIST__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -12001, Tenant snapshot \'%.*s\' already exist" +#define OB_TENANT_SNAPSHOT_TIMEOUT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -12002, Tenant snapshot task timeout. %.*s" +#define OB_CLONE_TENANT_TIMEOUT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -12003, Clone tenant timeout. %.*s" +#define OB_ERR_CLONE_TENANT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -12004, %.*s" +#define OB_ERR_TENANT_SNAPSHOT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -12005, %.*s" +#define OB_TENANT_SNAPSHOT_LOCK_CONFLICT__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -12006, %s" #define OB_SP_RAISE_APPLICATION_ERROR__ORA_USER_ERROR_MSG "ORA%06ld: %.*s" #define OB_SP_RAISE_APPLICATION_ERROR_NUM__ORA_USER_ERROR_MSG "ORA-21000: error number argument to raise_application_error of '%d' is out of range" #define OB_CLOB_ONLY_SUPPORT_WITH_MULTIBYTE_FUN__ORA_USER_ERROR_MSG "ORA-22998: CLOB or NCLOB in multibyte character set not supported" @@ -6235,7 +6249,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_ERR_DATA_TOO_LONG_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-12899: value too large for column %.*s (actual: %ld, maximum: %ld)" #define OB_ERR_INVALID_DATE_MSG_FMT_V2__ORA_USER_ERROR_MSG "ORA-01861: Incorrect datetime value for column '%.*s' at row %ld" -extern int g_all_ob_errnos[2193]; +extern int g_all_ob_errnos[2200]; const char *ob_error_name(const int oberr); const char* ob_error_cause(const int oberr); diff --git a/src/share/ob_rpc_struct.cpp b/src/share/ob_rpc_struct.cpp index 63a7dd973a..237288287a 100755 --- a/src/share/ob_rpc_struct.cpp +++ b/src/share/ob_rpc_struct.cpp @@ -1033,7 +1033,7 @@ OB_SERIALIZE_MEMBER((ObAlterResourcePoolArg, ObDDLArg), bool ObDropResourcePoolArg::is_valid() const { - return !pool_name_.empty(); + return !pool_name_.empty() || pool_id_ != OB_INVALID_ID; } int ObDropResourcePoolArg::assign(const ObDropResourcePoolArg &other) @@ -1044,6 +1044,7 @@ int ObDropResourcePoolArg::assign(const ObDropResourcePoolArg &other) } else { pool_name_ = other.pool_name_; if_exist_ = other.if_exist_; + pool_id_ = other.pool_id_; } return ret; } @@ -1052,7 +1053,8 @@ DEF_TO_STRING(ObDropResourcePoolArg) { int64_t pos = 0; J_KV(K_(pool_name), - K_(if_exist)); + K_(if_exist), + K_(pool_id)); return pos; } @@ -1139,6 +1141,7 @@ int ObCreateTenantArg::assign(const ObCreateTenantArg &other) is_creating_standby_ = other.is_creating_standby_; log_restore_source_ = other.log_restore_source_; is_tmp_tenant_for_recover_ = other.is_tmp_tenant_for_recover_; + source_tenant_id_ = other.source_tenant_id_; } return ret; } @@ -1157,6 +1160,7 @@ void ObCreateTenantArg::reset() is_creating_standby_ = false; log_restore_source_.reset(); is_tmp_tenant_for_recover_ = false; + source_tenant_id_ = OB_INVALID_TENANT_ID; } int ObCreateTenantArg::init(const share::schema::ObTenantSchema &tenant_schema, @@ -1195,7 +1199,8 @@ DEF_TO_STRING(ObCreateTenantArg) K_(compatible_version), K_(is_creating_standby), K_(log_restore_source), - K_(is_tmp_tenant_for_recover)); + K_(is_tmp_tenant_for_recover), + K_(source_tenant_id)); return pos; } @@ -1211,7 +1216,8 @@ OB_SERIALIZE_MEMBER((ObCreateTenantArg, ObDDLArg), recovery_until_scn_, is_creating_standby_, log_restore_source_, - is_tmp_tenant_for_recover_); + is_tmp_tenant_for_recover_, + source_tenant_id_); bool ObCreateTenantEndArg::is_valid() const { @@ -5480,6 +5486,117 @@ int ObAlterTriggerArg::assign(const ObAlterTriggerArg &other) OB_SERIALIZE_MEMBER((ObAlterTriggerArg, ObDDLArg), trigger_database_, trigger_info_, trigger_infos_, is_set_status_, is_alter_compile_); +bool ObNotifyTenantSnapshotSchedulerArg::is_valid() const +{ + return is_user_tenant(tenant_id_); +} + +int ObNotifyTenantSnapshotSchedulerArg::assign(const ObNotifyTenantSnapshotSchedulerArg &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + } else { + tenant_id_ = other.tenant_id_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObNotifyTenantSnapshotSchedulerArg, tenant_id_); + +bool ObFlushLSArchiveArg::is_valid() const +{ + return tenant_id_ != OB_INVALID_TENANT_ID; +} + +int ObFlushLSArchiveArg::assign(const ObFlushLSArchiveArg &other) +{ + int ret = OB_SUCCESS; + if (this != &other) { + tenant_id_ = other.tenant_id_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObFlushLSArchiveArg, tenant_id_); + +int ObNotifyTenantSnapshotSchedulerResult::assign(const ObNotifyTenantSnapshotSchedulerResult &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + } else { + ret_ = other.ret_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObNotifyTenantSnapshotSchedulerResult, ret_); + +bool ObInnerCreateTenantSnapshotArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ && tenant_snapshot_id_.is_valid(); +} + +int ObInnerCreateTenantSnapshotArg::assign(const ObInnerCreateTenantSnapshotArg &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + } else { + tenant_id_ = other.tenant_id_; + tenant_snapshot_id_ = other.tenant_snapshot_id_; + } + return ret; +} +OB_SERIALIZE_MEMBER(ObInnerCreateTenantSnapshotArg, tenant_id_, tenant_snapshot_id_); + +bool ObInnerCreateTenantSnapshotResult::is_valid() const +{ + return true; +} + +int ObInnerCreateTenantSnapshotResult::assign(const ObInnerCreateTenantSnapshotResult &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + } else { + ret_ = other.ret_; + } + return ret; +} +OB_SERIALIZE_MEMBER(ObInnerCreateTenantSnapshotResult, ret_); + +bool ObInnerDropTenantSnapshotArg::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ && tenant_snapshot_id_.is_valid(); +} + +int ObInnerDropTenantSnapshotArg::assign(const ObInnerDropTenantSnapshotArg &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + } else { + tenant_id_ = other.tenant_id_; + tenant_snapshot_id_ = other.tenant_snapshot_id_; + } + return ret; +} +OB_SERIALIZE_MEMBER(ObInnerDropTenantSnapshotArg, tenant_id_, tenant_snapshot_id_); + +bool ObInnerDropTenantSnapshotResult::is_valid() const +{ + return true; +} + +int ObInnerDropTenantSnapshotResult::assign(const ObInnerDropTenantSnapshotResult &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + } else { + ret_ = other.ret_; + } + return ret; +} +OB_SERIALIZE_MEMBER(ObInnerDropTenantSnapshotResult, ret_); + bool ObCreateUDTArg::is_valid() const { return OB_INVALID_ID != udt_info_.get_tenant_id() @@ -9974,9 +10091,85 @@ int ObAdminUnlockMemberListOpArg::set( } return ret; } - OB_SERIALIZE_MEMBER(ObAdminUnlockMemberListOpArg, tenant_id_, ls_id_, lock_id_); +int ObCloneResourcePoolArg::init( + const ObString &pool_name, + const ObString &unit_config_name, + const uint64_t source_tenant_id, + const uint64_t resource_pool_id) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(pool_name.length() > MAX_RESOURCE_POOL_LENGTH) + || OB_UNLIKELY(unit_config_name.length() > MAX_UNIT_CONFIG_LENGTH) + || OB_UNLIKELY(OB_INVALID_TENANT_ID == source_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(pool_name), K(unit_config_name), K(source_tenant_id)); + } else if (OB_FAIL(pool_name_.assign(pool_name))) { + LOG_WARN("fail to assign resource pool name", KR(ret), K(pool_name)); + } else if (OB_FAIL(unit_config_name_.assign(unit_config_name))) { + LOG_WARN("fail to assign unit config name", KR(ret), K(unit_config_name)); + } else { + source_tenant_id_ = source_tenant_id; + resource_pool_id_ = resource_pool_id; + } + return ret; +} + +int ObCloneResourcePoolArg::assign(const ObCloneResourcePoolArg &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(pool_name_.assign(other.pool_name_))) { + LOG_WARN("fail to assign resource pool name", KR(ret), K(other)); + } else if (OB_FAIL(unit_config_name_.assign(other.unit_config_name_))) { + LOG_WARN("fail to assign unit config name", KR(ret), K(other)); + } else { + source_tenant_id_ = other.source_tenant_id_; + resource_pool_id_ = other.resource_pool_id_; + } + return ret; +} + +DEF_TO_STRING(ObCloneResourcePoolArg) +{ + int64_t pos = 0; + J_KV(K_(pool_name), + K_(unit_config_name), + K_(source_tenant_id), + K_(resource_pool_id)); + return pos; +} + +OB_SERIALIZE_MEMBER((ObCloneResourcePoolArg, ObDDLArg), + pool_name_, + unit_config_name_, + source_tenant_id_, + resource_pool_id_); + +bool ObCloneTenantArg::is_valid() const +{ + return !new_tenant_name_.is_empty() + && !source_tenant_name_.is_empty() + && !resource_pool_name_.is_empty() + && !unit_config_name_.is_empty(); +} + +int ObCloneTenantArg::assign(const ObCloneTenantArg &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(new_tenant_name_.assign(other.new_tenant_name_))) { + LOG_WARN("fail to assign", KR(ret), K(other.new_tenant_name_)); + } else if (OB_FAIL(source_tenant_name_.assign(other.source_tenant_name_))) { + LOG_WARN("fail to assign", KR(ret), K(other.source_tenant_name_)); + } else if (OB_FAIL(tenant_snapshot_name_.assign(other.tenant_snapshot_name_))) { + LOG_WARN("fail to assign", KR(ret), K(other.tenant_snapshot_name_)); + } else if (OB_FAIL(resource_pool_name_.assign(other.resource_pool_name_))) { + LOG_WARN("fail to assign", KR(ret), K(other.resource_pool_name_)); + } else if (OB_FAIL(unit_config_name_.assign(other.unit_config_name_))) { + LOG_WARN("fail to assign", KR(ret), K(other.unit_config_name_)); + } + return ret; +} ObTabletLocationSendArg::ObTabletLocationSendArg() : tasks_() { @@ -9997,6 +10190,43 @@ int ObTabletLocationSendArg::assign(const ObTabletLocationSendArg &other) return ret; } +int ObCloneTenantArg::init(const ObString &new_tenant_name, + const ObString &source_tenant_name, + const ObString &tenant_snapshot_name, + const ObString &resource_pool_name, + const ObString &unit_config_name) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(new_tenant_name.empty() + || new_tenant_name.length() > OB_MAX_TENANT_NAME_LENGTH)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(new_tenant_name)); + } else if (OB_UNLIKELY(source_tenant_name.empty() + || source_tenant_name.length() > OB_MAX_TENANT_NAME_LENGTH)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(source_tenant_name)); + } else if (OB_UNLIKELY(resource_pool_name.empty() + || resource_pool_name.length() > MAX_RESOURCE_POOL_LENGTH)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(resource_pool_name)); + } else if (OB_UNLIKELY(unit_config_name.empty() + || unit_config_name.length() > MAX_UNIT_CONFIG_LENGTH)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(unit_config_name)); + } else if (OB_FAIL(new_tenant_name_.assign(new_tenant_name))) { + LOG_WARN("fail to assign", KR(ret), K(new_tenant_name)); + } else if (OB_FAIL(source_tenant_name_.assign(source_tenant_name))) { + LOG_WARN("fail to assign", KR(ret), K(source_tenant_name)); + } else if (OB_FAIL(tenant_snapshot_name_.assign(tenant_snapshot_name))) { + LOG_WARN("fail to assign", KR(ret), K(tenant_snapshot_name)); + } else if (OB_FAIL(resource_pool_name_.assign(resource_pool_name))) { + LOG_WARN("fail to assign", KR(ret), K(resource_pool_name)); + } else if (OB_FAIL(unit_config_name_.assign(unit_config_name))) { + LOG_WARN("fail to assign", KR(ret), K(unit_config_name)); + } + return ret; +} + int ObTabletLocationSendArg::set( const ObIArray &tasks) { @@ -10010,6 +10240,53 @@ int ObTabletLocationSendArg::set( return ret; } +OB_SERIALIZE_MEMBER((ObCloneTenantArg, ObCmdArg), new_tenant_name_, source_tenant_name_, tenant_snapshot_name_, resource_pool_name_, unit_config_name_); + +int ObCloneTenantRes::assign(const ObCloneTenantRes &other) +{ + int ret = OB_SUCCESS; + job_id_ = other.job_id_; + return ret; +} + +void ObCloneTenantRes::reset() +{ + job_id_ = OB_INVALID_ID; +} + +OB_SERIALIZE_MEMBER(ObCloneTenantRes, job_id_); + +bool ObNotifyCloneSchedulerArg::is_valid() const +{ + return is_sys_tenant(tenant_id_); +} + +int ObNotifyCloneSchedulerArg::assign(const ObNotifyCloneSchedulerArg &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + } else { + tenant_id_ = other.tenant_id_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObNotifyCloneSchedulerArg, tenant_id_); + +bool ObNotifyCloneSchedulerResult::is_valid() const +{ + return true; +} + +int ObNotifyCloneSchedulerResult::assign(const ObNotifyCloneSchedulerResult &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + } else { + ret_ = other.ret_; + } + return ret; +} bool ObTabletLocationSendArg::is_valid() const { return !tasks_.empty(); @@ -10038,6 +10315,46 @@ int ObTabletLocationSendResult::assign(const ObTabletLocationSendResult &other) return ret; } +OB_SERIALIZE_MEMBER(ObNotifyCloneSchedulerResult, ret_); + +int ObCloneKeyArg::assign(const ObCloneKeyArg &other) +{ + int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; + source_tenant_id_ = other.source_tenant_id_; + return ret; +} + +OB_SERIALIZE_MEMBER(ObCloneKeyArg, tenant_id_, source_tenant_id_); + +int ObCloneKeyResult::assign(const ObCloneKeyResult &other) +{ + int ret = OB_SUCCESS; + ret_ = other.ret_; + return ret; +} + +OB_SERIALIZE_MEMBER(ObCloneKeyResult, ret_); + +int ObTrimKeyListArg::assign(const ObTrimKeyListArg &other) +{ + int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; + latest_master_key_id_ = other.latest_master_key_id_; + return ret; +} + +OB_SERIALIZE_MEMBER(ObTrimKeyListArg, tenant_id_, latest_master_key_id_); + +int ObTrimKeyListResult::assign(const ObTrimKeyListResult &other) +{ + int ret = OB_SUCCESS; + ret_ = other.ret_; + return ret; +} + +OB_SERIALIZE_MEMBER(ObTrimKeyListResult, ret_); + void ObTabletLocationSendResult::reset() { ret_ = common::OB_ERROR; @@ -10065,4 +10382,4 @@ int ObCancelGatherStatsArg::assign(const ObCancelGatherStatsArg &other) OB_SERIALIZE_MEMBER(ObCancelGatherStatsArg, tenant_id_, task_id_); }//end namespace obrpc -}//end namepsace oceanbase +}//end namespace oceanbase diff --git a/src/share/ob_rpc_struct.h b/src/share/ob_rpc_struct.h index 8735f0a6e8..8697ef77cd 100755 --- a/src/share/ob_rpc_struct.h +++ b/src/share/ob_rpc_struct.h @@ -72,6 +72,7 @@ #include "share/scn.h"//SCN #include "share/ob_server_table_operator.h" #include "share/restore/ob_import_arg.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" #include "share/location_cache/ob_location_update_task.h" namespace oceanbase @@ -512,9 +513,14 @@ public: : ObDDLArg(), tenant_schema_(), pool_list_(), if_not_exist_(false), sys_var_list_(), name_case_mode_(common::OB_NAME_CASE_INVALID), is_restore_(false), palf_base_info_(), compatible_version_(0), recovery_until_scn_(share::SCN::min_scn()), - is_creating_standby_(false), log_restore_source_(), is_tmp_tenant_for_recover_(false) {} + is_creating_standby_(false), log_restore_source_(), is_tmp_tenant_for_recover_(false), + source_tenant_id_(OB_INVALID_TENANT_ID) {} virtual ~ObCreateTenantArg() {}; bool is_valid() const; + bool is_clone_tenant() const { return OB_INVALID_TENANT_ID != source_tenant_id_; } + bool is_restore_tenant() const { return is_restore_; } + bool is_standby_tenant() const { return is_creating_standby_; } + uint64_t get_source_tenant_id() const { return source_tenant_id_; } int check_valid() const; void reset(); int assign(const ObCreateTenantArg &other); @@ -541,6 +547,7 @@ public: bool is_creating_standby_; common::ObString log_restore_source_; // for create standby tenant bool is_tmp_tenant_for_recover_; //tmp tenant for recover table + uint64_t source_tenant_id_; // for create clone tenant }; struct ObCreateTenantEndArg : public ObDDLArg @@ -6503,6 +6510,151 @@ public: bool is_alter_compile_; }; +struct ObNotifyTenantSnapshotSchedulerArg +{ + OB_UNIS_VERSION(1); +public: + ObNotifyTenantSnapshotSchedulerArg() + : tenant_id_(common::OB_INVALID_TENANT_ID) + {} + ~ObNotifyTenantSnapshotSchedulerArg() {} + bool is_valid() const; + int assign(const ObNotifyTenantSnapshotSchedulerArg &other); + uint64_t get_tenant_id() const { return tenant_id_; } + void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } + TO_STRING_KV(K_(tenant_id)); +private: + DISALLOW_COPY_AND_ASSIGN(ObNotifyTenantSnapshotSchedulerArg); +private: + uint64_t tenant_id_; +}; + +struct ObNotifyTenantSnapshotSchedulerResult +{ + OB_UNIS_VERSION(1); +public: + ObNotifyTenantSnapshotSchedulerResult(): ret_(common::OB_SUCCESS) {} + ~ObNotifyTenantSnapshotSchedulerResult() {} + bool is_valid() const; + int assign(const ObNotifyTenantSnapshotSchedulerResult &other); + void init(const int ret) { ret_ = ret; } + TO_STRING_KV(K_(ret)); + int get_result() const { return ret_; } +private: + DISALLOW_COPY_AND_ASSIGN(ObNotifyTenantSnapshotSchedulerResult); +private: + int ret_; +}; + +struct ObFlushLSArchiveArg +{ + OB_UNIS_VERSION(1); +public: + ObFlushLSArchiveArg() + : tenant_id_(common::OB_INVALID_TENANT_ID) + {} + virtual ~ObFlushLSArchiveArg() {} + bool is_valid() const; + int assign(const ObFlushLSArchiveArg &other); + TO_STRING_KV(K_(tenant_id)); +public: + uint64_t tenant_id_; +}; + +struct ObInnerCreateTenantSnapshotArg +{ + OB_UNIS_VERSION(1); +public: + ObInnerCreateTenantSnapshotArg() + : tenant_id_(OB_INVALID_TENANT_ID), + tenant_snapshot_id_() + {} + ~ObInnerCreateTenantSnapshotArg() + { + tenant_id_ = OB_INVALID_TENANT_ID; + tenant_snapshot_id_.reset(); + } + bool is_valid() const; + int assign(const ObInnerCreateTenantSnapshotArg &other); + const share::ObTenantSnapshotID &get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + void set_tenant_snapshot_id(const share::ObTenantSnapshotID &tenant_snapshot_id) + { + tenant_snapshot_id_ = tenant_snapshot_id; + } + uint64_t get_tenant_id() const { return tenant_id_; } + void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } + TO_STRING_KV(K(tenant_id_), K(tenant_snapshot_id_)); +private: + DISALLOW_COPY_AND_ASSIGN(ObInnerCreateTenantSnapshotArg); +private: + uint64_t tenant_id_; + share::ObTenantSnapshotID tenant_snapshot_id_; +}; + +struct ObInnerCreateTenantSnapshotResult +{ + OB_UNIS_VERSION(1); +public: + ObInnerCreateTenantSnapshotResult(): ret_(common::OB_SUCCESS) {} + ~ObInnerCreateTenantSnapshotResult() {} + bool is_valid() const; + int assign(const ObInnerCreateTenantSnapshotResult &other); + void init(const int ret) { ret_ = ret; } + TO_STRING_KV(K_(ret)); + int get_result() const { return ret_; } +private: + DISALLOW_COPY_AND_ASSIGN(ObInnerCreateTenantSnapshotResult); +private: + int ret_; +}; + +struct ObInnerDropTenantSnapshotArg +{ + OB_UNIS_VERSION(1); +public: + ObInnerDropTenantSnapshotArg() + : tenant_id_(OB_INVALID_TENANT_ID), + tenant_snapshot_id_() + {} + ~ObInnerDropTenantSnapshotArg() + { + tenant_id_ = OB_INVALID_TENANT_ID; + tenant_snapshot_id_.reset(); + } + bool is_valid() const; + int assign(const ObInnerDropTenantSnapshotArg &other); + const share::ObTenantSnapshotID &get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + void set_tenant_snapshot_id(const share::ObTenantSnapshotID &tenant_snapshot_id) + { + tenant_snapshot_id_ = tenant_snapshot_id; + } + uint64_t get_tenant_id() const { return tenant_id_; } + void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } + TO_STRING_KV(K(tenant_id_), K(tenant_snapshot_id_)); +private: + DISALLOW_COPY_AND_ASSIGN(ObInnerDropTenantSnapshotArg); +private: + uint64_t tenant_id_; + share::ObTenantSnapshotID tenant_snapshot_id_; +}; + +struct ObInnerDropTenantSnapshotResult +{ + OB_UNIS_VERSION(1); +public: + ObInnerDropTenantSnapshotResult(): ret_(common::OB_SUCCESS) {} + ~ObInnerDropTenantSnapshotResult() {} + bool is_valid() const; + int assign(const ObInnerDropTenantSnapshotResult &other); + void init(const int ret) { ret_ = ret; } + TO_STRING_KV(K_(ret)); + int get_result() const { return ret_; } +private: + DISALLOW_COPY_AND_ASSIGN(ObInnerDropTenantSnapshotResult); +private: + int ret_; +}; + struct ObCreateUDTArg : public ObDDLArg { OB_UNIS_VERSION(1); @@ -10406,6 +10558,203 @@ public: bool have_kill_auth_; }; +struct ObCloneResourcePoolArg : public ObDDLArg +{ + OB_UNIS_VERSION(1); +public: + ObCloneResourcePoolArg(): + ObDDLArg(), + source_tenant_id_(OB_INVALID_TENANT_ID), + resource_pool_id_(OB_INVALID_ID) {} + + virtual ~ObCloneResourcePoolArg() {} + bool is_valid() const { return !pool_name_.is_empty() && !unit_config_name_.is_empty() && + OB_INVALID_TENANT_ID != source_tenant_id_ && + OB_INVALID_ID != resource_pool_id_; } + virtual int assign(const ObCloneResourcePoolArg &other); + int init(const ObString &pool_name, + const ObString &unit_config_name, + const uint64_t source_tenant_id, + const uint64_t resource_pool_id); + + const ObString get_pool_name() const { return pool_name_.str(); } + const ObString get_unit_config_name() const { return unit_config_name_.str(); } + uint64_t get_source_tenant_id() const { return source_tenant_id_; } + uint64_t get_resource_pool_id() const { return resource_pool_id_; } + DECLARE_TO_STRING; + +private: + common::ObFixedLengthString pool_name_; + common::ObFixedLengthString unit_config_name_; + uint64_t source_tenant_id_; + uint64_t resource_pool_id_; +}; + +struct ObCloneTenantArg : public ObCmdArg +{ +public: + OB_UNIS_VERSION(1); +public: + ObCloneTenantArg() + : new_tenant_name_(), + source_tenant_name_(), + tenant_snapshot_name_(), + resource_pool_name_(), + unit_config_name_() + {} + virtual ~ObCloneTenantArg() {} + bool is_valid() const; + int assign(const ObCloneTenantArg &other); + int init(const ObString &new_tenant_name, + const ObString &source_tenant_name, + const ObString &tenant_snapshot_name, + const ObString &resource_pool_name, + const ObString &unit_config_name); + const ObString get_new_tenant_name() const { return new_tenant_name_.str(); } + const ObString get_source_tenant_name() const { return source_tenant_name_.str(); } + const ObString get_tenant_snapshot_name() const { return tenant_snapshot_name_.str(); } + const ObString get_resource_pool_name() const { return resource_pool_name_.str(); } + const ObString get_unit_config_name() const { return unit_config_name_.str(); } + TO_STRING_KV(K_(new_tenant_name), K_(source_tenant_name), + K_(tenant_snapshot_name), K_(resource_pool_name), + K_(unit_config_name)); +private: + DISALLOW_COPY_AND_ASSIGN(ObCloneTenantArg); +private: + common::ObFixedLengthString new_tenant_name_; + common::ObFixedLengthString source_tenant_name_; + common::ObFixedLengthString tenant_snapshot_name_; + common::ObFixedLengthString resource_pool_name_; + common::ObFixedLengthString unit_config_name_; +}; + +struct ObCloneTenantRes +{ + OB_UNIS_VERSION(1); +public: + ObCloneTenantRes(): + job_id_(OB_INVALID_ID) {} + ~ObCloneTenantRes() {} + bool is_valid() const { return 0 < job_id_; } + void reset(); + int assign(const ObCloneTenantRes &other); + int64_t get_job_id() const { return job_id_; } + void set_job_id(const int64_t job_id) { job_id_ = job_id; } + TO_STRING_KV(K_(job_id)); +private: + DISALLOW_COPY_AND_ASSIGN(ObCloneTenantRes); +private: + int64_t job_id_; +}; + +struct ObNotifyCloneSchedulerArg +{ + OB_UNIS_VERSION(1); +public: + ObNotifyCloneSchedulerArg() + : tenant_id_(common::OB_INVALID_TENANT_ID) + {} + ~ObNotifyCloneSchedulerArg() {} + bool is_valid() const; + int assign(const ObNotifyCloneSchedulerArg &other); + uint64_t get_tenant_id() const { return tenant_id_; } + void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } + TO_STRING_KV(K_(tenant_id)); +private: + DISALLOW_COPY_AND_ASSIGN(ObNotifyCloneSchedulerArg); +private: + uint64_t tenant_id_; +}; + +struct ObNotifyCloneSchedulerResult +{ + OB_UNIS_VERSION(1); +public: + ObNotifyCloneSchedulerResult(): ret_(common::OB_SUCCESS) {} + ~ObNotifyCloneSchedulerResult() {} + bool is_valid() const; + int assign(const ObNotifyCloneSchedulerResult &other); + void init(const int ret) { ret_ = ret; } + TO_STRING_KV(K_(ret)); + int get_result() const { return ret_; } +private: + DISALLOW_COPY_AND_ASSIGN(ObNotifyCloneSchedulerResult); +private: + int ret_; +}; + +struct ObCloneKeyArg +{ + OB_UNIS_VERSION(1); +public: + ObCloneKeyArg() + : tenant_id_(OB_INVALID_TENANT_ID), + source_tenant_id_(OB_INVALID_TENANT_ID) + {} + ~ObCloneKeyArg() {} + uint64_t get_tenant_id() const { return tenant_id_; } + void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } + uint64_t get_source_tenant_id() const { return source_tenant_id_; } + void set_source_tenant_id(const uint64_t source_tenant_id) { source_tenant_id_ = source_tenant_id; } + bool is_valid() const { return OB_INVALID_TENANT_ID != tenant_id_ + && OB_INVALID_TENANT_ID != source_tenant_id_; } + int assign(const ObCloneKeyArg &other); + TO_STRING_KV(K_(tenant_id), K_(source_tenant_id)); +private: + uint64_t tenant_id_; + uint64_t source_tenant_id_; +}; + +struct ObCloneKeyResult +{ + OB_UNIS_VERSION(1); +public: + ObCloneKeyResult() : ret_(common::OB_ERROR) {} + ~ObCloneKeyResult() {} + int assign(const ObCloneKeyResult &other); + void set_ret(int ret) { ret_ = ret; } + int64_t get_ret() const { return ret_; } + TO_STRING_KV(K_(ret)); +private: + int ret_; +}; + +struct ObTrimKeyListArg +{ + OB_UNIS_VERSION(1); +public: + ObTrimKeyListArg() + : tenant_id_(OB_INVALID_TENANT_ID), + latest_master_key_id_(0) + {} + ~ObTrimKeyListArg() {} + uint64_t get_tenant_id() const { return tenant_id_; } + void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } + uint64_t get_latest_master_key_id() const { return latest_master_key_id_; } + void set_latest_master_key_id(const uint64_t latest_master_key_id) { latest_master_key_id_ = latest_master_key_id; } + bool is_valid() const { return OB_INVALID_TENANT_ID != tenant_id_ + && OB_INVALID_ID != latest_master_key_id_; } + int assign(const ObTrimKeyListArg &other); + TO_STRING_KV(K_(tenant_id), K_(latest_master_key_id)); +private: + uint64_t tenant_id_; + uint64_t latest_master_key_id_; +}; + +struct ObTrimKeyListResult +{ + OB_UNIS_VERSION(1); +public: + ObTrimKeyListResult() : ret_(common::OB_ERROR) {} + ~ObTrimKeyListResult() {} + int assign(const ObTrimKeyListResult &other); + void set_ret(int ret) { ret_ = ret; } + int64_t get_ret() const { return ret_; } + TO_STRING_KV(K_(ret)); +private: + int ret_; +}; + struct ObTabletLocationSendArg final { OB_UNIS_VERSION(1); diff --git a/src/share/ob_share_util.cpp b/src/share/ob_share_util.cpp index 60370e6b9a..dc01f70e8c 100644 --- a/src/share/ob_share_util.cpp +++ b/src/share/ob_share_util.cpp @@ -446,5 +446,35 @@ bool ObShareUtil::is_tenant_enable_transfer(const uint64_t tenant_id) return bret; } +int ObShareUtil::check_compat_version_for_clone_tenant( + const uint64_t tenant_id, + bool &is_compatible) +{ + int ret = OB_SUCCESS; + is_compatible = false; + uint64_t data_version = 0; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(OB_SYS_TENANT_ID, data_version))) { + LOG_WARN("fail to get sys tenant data version", KR(ret)); + } else if (DATA_VERSION_4_3_0_0 > data_version) { + is_compatible = false; + } else if (is_sys_tenant(tenant_id)) { + is_compatible = true; + } else if (OB_FAIL(GET_MIN_DATA_VERSION(gen_user_tenant_id(tenant_id), data_version))) { + LOG_WARN("fail to get user tenant data version", KR(ret), "tenant_id", gen_user_tenant_id(tenant_id)); + } else if (DATA_VERSION_4_3_0_0 > data_version) { + is_compatible = false; + } else if (OB_FAIL(GET_MIN_DATA_VERSION(gen_meta_tenant_id(tenant_id), data_version))) { + LOG_WARN("fail to get meta tenant data version", KR(ret), "tenant_id", gen_meta_tenant_id(tenant_id)); + } else if (DATA_VERSION_4_3_0_0 > data_version) { + is_compatible = false; + } else { + is_compatible = true; + } + return ret; +} + } //end namespace share } //end namespace oceanbase diff --git a/src/share/ob_share_util.h b/src/share/ob_share_util.h index 4093041a72..9d15357eeb 100644 --- a/src/share/ob_share_util.h +++ b/src/share/ob_share_util.h @@ -78,6 +78,12 @@ public: static int check_compat_version_for_arbitration_service( const uint64_t tenant_id, bool &is_compatible); + // data version must up to 4.3 with clone tenant + // params[in] tenant_id, which tenant to check + // params[out] is_compatible, whether it is up to 4.3 + static int check_compat_version_for_clone_tenant( + const uint64_t tenant_id, + bool &is_compatible); // generate the count of arb replica of a log stream // @params[in] tenant_id, which tenant to check // @params[in] ls_id, which log stream to check diff --git a/src/share/ob_srv_rpc_proxy.h b/src/share/ob_srv_rpc_proxy.h index ed56ed6601..5f6fada717 100755 --- a/src/share/ob_srv_rpc_proxy.h +++ b/src/share/ob_srv_rpc_proxy.h @@ -173,6 +173,8 @@ public: RPC_S(PR5 get_master_key, OB_GET_MASTER_KEY, (obrpc::Int64), ObGetMasterKeyResultArg); RPC_AP(PR5 restore_key, OB_RESTORE_KEY, (obrpc::ObRestoreKeyArg), obrpc::ObRestoreKeyResult); RPC_AP(PR5 set_root_key, OB_SET_ROOT_KEY, (obrpc::ObRootKeyArg), obrpc::ObRootKeyResult); + RPC_AP(PR5 clone_key, OB_CLONE_KEY, (obrpc::ObCloneKeyArg), obrpc::ObCloneKeyResult); + RPC_AP(PR5 trim_key_list, OB_TRIM_KEY_LIST, (obrpc::ObTrimKeyListArg), obrpc::ObTrimKeyListResult); #endif RPC_S(PR5 handle_part_trans_ctx, OB_HANDLE_PART_TRANS_CTX, (obrpc::ObTrxToolArg), ObTrxToolRes); RPC_S(PR5 flush_local_opt_stat_monitoring_info, obrpc::OB_SERVER_FLUSH_OPT_STAT_MONITORING_INFO, (obrpc::ObFlushOptStatArg)); @@ -237,6 +239,11 @@ public: RPC_S(PR5 direct_load_control, OB_DIRECT_LOAD_CONTROL, (observer::ObDirectLoadControlRequest), observer::ObDirectLoadControlResult); RPC_S(PR5 dispatch_ttl, OB_TABLE_TTL, (obrpc::ObTTLRequestArg), obrpc::ObTTLResponseArg); RPC_S(PR5 admin_unlock_member_list_op, OB_HA_UNLOCK_MEMBER_LIST, (obrpc::ObAdminUnlockMemberListOpArg)); + RPC_S(PR5 notify_tenant_snapshot_scheduler, OB_NOTIFY_TENANT_SNAPSHOT_SCHEDULER, (obrpc::ObNotifyTenantSnapshotSchedulerArg), obrpc::ObNotifyTenantSnapshotSchedulerResult); + RPC_AP(PR5 inner_create_tenant_snapshot, OB_INNER_CREATE_TENANT_SNAPSHOT, (obrpc::ObInnerCreateTenantSnapshotArg), obrpc::ObInnerCreateTenantSnapshotResult); + RPC_AP(PR5 inner_drop_tenant_snapshot, OB_INNER_DROP_TENANT_SNAPSHOT, (obrpc::ObInnerDropTenantSnapshotArg), obrpc::ObInnerDropTenantSnapshotResult); + RPC_AP(PR5 flush_ls_archive, OB_FLUSH_LS_ARCHIVE, (obrpc::ObFlushLSArchiveArg), obrpc::Int64); + RPC_S(PR5 notify_clone_scheduler, OB_NOTIFY_CLONE_SCHEDULER, (obrpc::ObNotifyCloneSchedulerArg), obrpc::ObNotifyCloneSchedulerResult); RPC_AP(PR5 tablet_major_freeze, OB_TABLET_MAJOR_FREEZE, (ObTabletMajorFreezeArg), obrpc::Int64); RPC_AP(PR5 kill_client_session, OB_KILL_CLIENT_SESSION, (ObKillClientSessionArg), ObKillClientSessionRes); RPC_S(PR5 client_session_create_time, OB_CLIENT_SESSION_CONNECT_TIME, (ObClientSessionCreateTimeAndAuthArg), ObClientSessionCreateTimeAndAuthRes); diff --git a/src/share/ob_tenant_info_proxy.cpp b/src/share/ob_tenant_info_proxy.cpp index 37260a91bd..450516fb02 100755 --- a/src/share/ob_tenant_info_proxy.cpp +++ b/src/share/ob_tenant_info_proxy.cpp @@ -29,10 +29,12 @@ #include "common/ob_timeout_ctx.h"//ObTimeoutCtx #include "rootserver/ob_root_utils.h"//ObRootUtils #include "rootserver/ob_rs_event_history_table_operator.h" // ROOTSERVICE_EVENT_ADD +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" // ObTenantSnapshotUtil #include "share/restore/ob_log_restore_source_mgr.h" // ObLogRestoreSourceMgr using namespace oceanbase; using namespace oceanbase::common; +using namespace rootserver; namespace oceanbase { namespace share @@ -592,6 +594,7 @@ int ObAllTenantInfoProxy::update_tenant_role( ObSqlString sql; int64_t affected_rows = 0; ObTimeoutCtx ctx; + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::SWITCHOVER); if (OB_UNLIKELY(!is_user_tenant(tenant_id) || OB_INVALID_VERSION == old_switchover_epoch @@ -604,6 +607,8 @@ int ObAllTenantInfoProxy::update_tenant_role( } else if (OB_ISNULL(proxy)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("proxy is null", KR(ret), KP(proxy)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(tenant_id, case_to_check))) { + LOG_WARN("fail to check whether tenant is in cloning procedure", KR(ret), K(tenant_id)); } else if (OB_FAIL(get_new_switchover_epoch_(old_switchover_epoch, old_status, new_status, new_switchover_ts))) { LOG_WARN("fail to get_new_switchover_epoch_", KR(ret), K(old_switchover_epoch), K(old_status), @@ -770,6 +775,7 @@ int ObAllTenantInfoProxy::update_tenant_status( ObTimeoutCtx ctx; int64_t new_switchover_epoch = OB_INVALID_VERSION; ObLogRestoreSourceMgr restore_source_mgr; + ObConflictCaseWithClone case_to_check(ObConflictCaseWithClone::SWITCHOVER); if (OB_UNLIKELY(!is_user_tenant(tenant_id) || !new_role.is_valid() @@ -785,6 +791,8 @@ int ObAllTenantInfoProxy::update_tenant_status( LOG_WARN("tenant_info is invalid", KR(ret), K(tenant_id), K(new_role), K(old_status), K(new_status), K(sync_scn), K(replayable_scn), K(readable_scn), K(recovery_until_scn), K(old_switchover_epoch)); + } else if (OB_FAIL(ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(tenant_id, case_to_check))) { + LOG_WARN("fail to check whether tenant is in cloning procedure", KR(ret), K(tenant_id)); } else if (OB_FAIL(get_new_switchover_epoch_(old_switchover_epoch, old_status, new_status, new_switchover_epoch))) { LOG_WARN("fail to get_new_switchover_epoch_", KR(ret), K(old_switchover_epoch), K(old_status), diff --git a/src/share/ob_tenant_info_proxy.h b/src/share/ob_tenant_info_proxy.h index 3c869f203d..2462b1feb9 100755 --- a/src/share/ob_tenant_info_proxy.h +++ b/src/share/ob_tenant_info_proxy.h @@ -85,6 +85,7 @@ public: bool is_standby() const { return tenant_role_.is_standby(); } bool is_primary() const { return tenant_role_.is_primary(); } bool is_restore() const { return tenant_role_.is_restore(); } + bool is_clone() const { return tenant_role_.is_clone(); } /** * @description: diff --git a/src/share/ob_tenant_role.cpp b/src/share/ob_tenant_role.cpp index ee0c6b7fb2..48c507e0c9 100644 --- a/src/share/ob_tenant_role.cpp +++ b/src/share/ob_tenant_role.cpp @@ -29,6 +29,7 @@ static const char* TENANT_ROLE_ARRAY[] = "PRIMARY", "STANDBY", "RESTORE", + "CLONE", }; OB_SERIALIZE_MEMBER(ObTenantRole, value_); @@ -73,6 +74,7 @@ GEN_IS_TENANT_ROLE(ObTenantRole::Role::INVALID_TENANT, invalid) GEN_IS_TENANT_ROLE(ObTenantRole::Role::PRIMARY_TENANT, primary) GEN_IS_TENANT_ROLE(ObTenantRole::Role::STANDBY_TENANT, standby) GEN_IS_TENANT_ROLE(ObTenantRole::Role::RESTORE_TENANT, restore) +GEN_IS_TENANT_ROLE(ObTenantRole::Role::CLONE_TENANT, clone) #undef GEN_IS_TENANT_ROLE diff --git a/src/share/ob_tenant_role.h b/src/share/ob_tenant_role.h index 6dcc38f796..693cc87fdc 100644 --- a/src/share/ob_tenant_role.h +++ b/src/share/ob_tenant_role.h @@ -32,7 +32,8 @@ public: PRIMARY_TENANT = 1, STANDBY_TENANT = 2, RESTORE_TENANT = 3, - MAX_TENANT = 4, + CLONE_TENANT = 4, + MAX_TENANT = 5, }; public: ObTenantRole() : value_(INVALID_TENANT) {} @@ -57,6 +58,7 @@ public: bool is_primary() const { return PRIMARY_TENANT == value_; } bool is_standby() const { return STANDBY_TENANT == value_; } bool is_restore() const { return RESTORE_TENANT == value_; } + bool is_clone() const { return CLONE_TENANT == value_; } TO_STRING_KV(K_(value)); DECLARE_TO_YSON_KV; @@ -71,12 +73,14 @@ GEN_IS_TENANT_ROLE_DECLARE(ObTenantRole::Role::INVALID_TENANT, invalid) GEN_IS_TENANT_ROLE_DECLARE(ObTenantRole::Role::PRIMARY_TENANT, primary) GEN_IS_TENANT_ROLE_DECLARE(ObTenantRole::Role::STANDBY_TENANT, standby) GEN_IS_TENANT_ROLE_DECLARE(ObTenantRole::Role::RESTORE_TENANT, restore) +GEN_IS_TENANT_ROLE_DECLARE(ObTenantRole::Role::CLONE_TENANT, clone) #undef GEN_IS_TENANT_ROLE_DECLARE static const ObTenantRole INVALID_TENANT_ROLE(ObTenantRole::INVALID_TENANT); static const ObTenantRole PRIMARY_TENANT_ROLE(ObTenantRole::PRIMARY_TENANT); static const ObTenantRole STANDBY_TENANT_ROLE(ObTenantRole::STANDBY_TENANT); static const ObTenantRole RESTORE_TENANT_ROLE(ObTenantRole::RESTORE_TENANT); +static const ObTenantRole CLONE_TENANT_ROLE(ObTenantRole::CLONE_TENANT); } // share } // oceanbase diff --git a/src/share/ob_thread_define.h b/src/share/ob_thread_define.h index 4621732afb..eac4a91a4d 100755 --- a/src/share/ob_thread_define.h +++ b/src/share/ob_thread_define.h @@ -28,6 +28,7 @@ TG_DEF(PartSerMigRetryQt, PartSerMigRetryQt, THREAD_POOL, 1) // !lib::is_mini_mode() ? (common::REPLAY_TASK_QUEUE_SIZE + 1) * OB_MAX_PARTITION_NUM_PER_SERVER : (common::REPLAY_TASK_QUEUE_SIZE + 1) * OB_MINI_MODE_MAX_PARTITION_NUM_PER_SERVER) TG_DEF(TransMigrate, TransMigrate, QUEUE_THREAD, ThreadCountPair(GET_THREAD_NUM_BY_NPROCESSORS(24), 1), 10000) TG_DEF(StandbyTimestampService, StandbyTimestampService, THREAD_POOL, 1) +TG_DEF(TSnapSvc, TSnapSvc, THREAD_POOL, 1) TG_DEF(WeakReadService, WeakRdSrv, THREAD_POOL, 1) TG_DEF(TransTaskWork, TransTaskWork, QUEUE_THREAD, ThreadCountPair(GET_THREAD_NUM_BY_NPROCESSORS(12), 1), transaction::ObThreadLocalTransCtx::MAX_BIG_TRANS_TASK) TG_DEF(DDLTaskExecutor3, DDLTaskExecutor3, THREAD_POOL, ThreadCountPair(8, 2)) @@ -160,9 +161,7 @@ TG_DEF(InfoPoolResize, InfoPoolResize, TIMER) TG_DEF(TenantTransferService, TransferSrv, REENTRANT_THREAD_POOL, ThreadCountPair(4 ,1)) TG_DEF(WR_TIMER_THREAD, WrTimer, TIMER) -TG_DEF(SvrStartupHandler, SvrStartupHandler, QUEUE_THREAD, - ThreadCountPair(observer::ObServerStartupTaskHandler::get_thread_num(), observer::ObServerStartupTaskHandler::get_thread_num()), - observer::ObServerStartupTaskHandler::MAX_QUEUED_TASK_NUM) +TG_DEF(StartupAccelHandler, StartupAccelHandler, QUEUE_THREAD, 1, observer::ObStartupAccelTaskHandler::MAX_QUEUED_TASK_NUM) TG_DEF(TenantTTLManager, TTLManager, TIMER) TG_DEF(TenantTabletTTLMgr, TTLTabletMgr, TIMER) TG_DEF(TntSharedTimer, TntSharedTimer, TIMER) diff --git a/src/share/ob_thread_mgr.cpp b/src/share/ob_thread_mgr.cpp index f0ff3c2e61..51cf0d84d6 100644 --- a/src/share/ob_thread_mgr.cpp +++ b/src/share/ob_thread_mgr.cpp @@ -17,7 +17,7 @@ #include "storage/tx_storage/ob_ls_freeze_thread.h" #include "rootserver/ob_index_builder.h" #include "observer/ob_srv_deliver.h" -#include "observer/ob_server_startup_task_handler.h" +#include "observer/ob_startup_accel_task_handler.h" #ifdef OB_BUILD_ARBITRATION #include "logservice/arbserver/ob_arb_srv_deliver.h" #endif @@ -26,6 +26,7 @@ #include "logservice/palf/log_define.h" #include "logservice/palf/fetch_log_engine.h" #include "logservice/rcservice/ob_role_change_service.h" +#include "observer/ob_startup_accel_task_handler.h" using namespace oceanbase::common; using namespace oceanbase::lib; diff --git a/src/share/ob_unit_table_operator.cpp b/src/share/ob_unit_table_operator.cpp index 192e29c1fb..2a7c65304d 100644 --- a/src/share/ob_unit_table_operator.cpp +++ b/src/share/ob_unit_table_operator.cpp @@ -22,6 +22,7 @@ #include "observer/ob_sql_client_decorator.h" #include "common/ob_timeout_ctx.h" #include "rootserver/ob_root_utils.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" // ObTenantSnapshotUtil namespace oceanbase { @@ -189,12 +190,15 @@ int ObUnitTableOperator::get_units(const common::ObIArray &pool_ids, } int ObUnitTableOperator::update_unit(common::ObISQLClient &client, - const ObUnit &unit) + const ObUnit &unit, + const bool need_check_conflict_with_clone) { int ret = OB_SUCCESS; char ip[OB_MAX_SERVER_ADDR_SIZE] = ""; char migrate_from_svr_ip[OB_MAX_SERVER_ADDR_SIZE] = ""; const char *unit_status_str = NULL; + rootserver::ObConflictCaseWithClone case_to_check(rootserver::ObConflictCaseWithClone::MODIFY_UNIT); + uint64_t tenant_id = OB_INVALID_TENANT_ID; if (!inited_) { ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); @@ -215,6 +219,16 @@ int ObUnitTableOperator::update_unit(common::ObISQLClient &client, } } + if (OB_FAIL(ret)) { + } else if (need_check_conflict_with_clone) { + if (OB_FAIL(rootserver::ObTenantSnapshotUtil::lock_unit_for_tenant(client, unit, tenant_id))) { + LOG_WARN("fail to lock __all_unit_table for clone check", KR(ret), K(unit), K(need_check_conflict_with_clone)); + } else if (!is_valid_tenant_id(tenant_id)) { + // this unit is not granted to tenant, just ignore + } else if (OB_FAIL(rootserver::ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure(tenant_id, case_to_check))) { + LOG_WARN("fail to check whether tenant is cloning", KR(ret), K(tenant_id), K(case_to_check), K(need_check_conflict_with_clone)); + } + } if (OB_FAIL(ret)) { } else if (OB_FAIL(unit.get_unit_status_str(unit_status_str))) { LOG_WARN("fail to get unit status", K(ret)); @@ -434,9 +448,12 @@ int ObUnitTableOperator::get_resource_pool(common::ObISQLClient &sql_client, } int ObUnitTableOperator::update_resource_pool(common::ObISQLClient &client, - const ObResourcePool &resource_pool) + const ObResourcePool &resource_pool, + const bool need_check_conflict_with_clone) { int ret = OB_SUCCESS; + ObResourcePool resource_pool_to_lock; + rootserver::ObConflictCaseWithClone case_to_check(rootserver::ObConflictCaseWithClone::MODIFY_RESOURCE_POOL); SMART_VAR(char[MAX_ZONE_LIST_LENGTH], zone_list_str) { zone_list_str[0] = '\0'; @@ -452,6 +469,21 @@ int ObUnitTableOperator::update_resource_pool(common::ObISQLClient &client, } else if (OB_FAIL(zone_list2str(resource_pool.zone_list_, zone_list_str, MAX_ZONE_LIST_LENGTH))) { LOG_WARN("zone_list2str failed", "zone_list", resource_pool.zone_list_, K(ret)); + // try lock resource pool to update for clone tenant conflict check + } else if (need_check_conflict_with_clone) { + if (!is_valid_tenant_id(resource_pool.tenant_id_)) { + // this resource pool has not granted to any tenant, just ignore + } else if (OB_FAIL(rootserver::ObTenantSnapshotUtil::lock_resource_pool_for_tenant( + client, resource_pool))) { + LOG_WARN("fail to lock the resource pool to update", KR(ret), K(resource_pool), K(need_check_conflict_with_clone)); + } else if (OB_FAIL(rootserver::ObTenantSnapshotUtil::check_tenant_not_in_cloning_procedure( + resource_pool.tenant_id_, + case_to_check))) { + LOG_WARN("fail to check whether tenant is in cloning procedure", KR(ret), K(resource_pool), + K(case_to_check), K(need_check_conflict_with_clone)); + } + } + if (OB_FAIL(ret)) { } else { ObDMLSqlSplicer dml; ObString resource_pool_name(strlen(resource_pool.name_.ptr()), resource_pool.name_.ptr()); @@ -888,7 +920,7 @@ int ObUnitTableOperator::read_unit_group(const ObMySQLResult &result, ObSimpleUn return ret; } -int ObUnitTableOperator::read_unit(const ObMySQLResult &result, ObUnit &unit) const +int ObUnitTableOperator::read_unit(const ObMySQLResult &result, ObUnit &unit) { int ret = OB_SUCCESS; unit.reset(); @@ -898,28 +930,23 @@ int ObUnitTableOperator::read_unit(const ObMySQLResult &result, ObUnit &unit) co char migrate_from_svr_ip[OB_IP_STR_BUFF] = ""; char status[MAX_UNIT_STATUS_LENGTH] = ""; int64_t migrate_from_svr_port = 0; - if (!inited_) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else { - EXTRACT_INT_FIELD_MYSQL(result, "unit_id", unit.unit_id_, uint64_t); - EXTRACT_INT_FIELD_MYSQL(result, "resource_pool_id", unit.resource_pool_id_, uint64_t); - EXTRACT_INT_FIELD_MYSQL(result, "unit_group_id", unit.unit_group_id_, uint64_t); - EXTRACT_STRBUF_FIELD_MYSQL(result, "zone", unit.zone_.ptr(), MAX_ZONE_LENGTH, tmp_real_str_len); - EXTRACT_STRBUF_FIELD_MYSQL(result, "svr_ip", ip, OB_IP_STR_BUFF, tmp_real_str_len); - EXTRACT_INT_FIELD_MYSQL(result, "svr_port", port, int64_t); - EXTRACT_STRBUF_FIELD_MYSQL(result, "migrate_from_svr_ip", migrate_from_svr_ip, - OB_IP_STR_BUFF, tmp_real_str_len); - EXTRACT_INT_FIELD_MYSQL(result, "migrate_from_svr_port", migrate_from_svr_port, int64_t); - EXTRACT_BOOL_FIELD_MYSQL(result, "manual_migrate", unit.is_manual_migrate_); - EXTRACT_STRBUF_FIELD_MYSQL(result, "status", status, MAX_UNIT_STATUS_LENGTH, tmp_real_str_len); - EXTRACT_INT_FIELD_MYSQL_SKIP_RET(result, "replica_type", unit.replica_type_, common::ObReplicaType); - (void) tmp_real_str_len; // make compiler happy - unit.server_.set_ip_addr(ip, static_cast(port)); - unit.migrate_from_server_.set_ip_addr( - migrate_from_svr_ip, static_cast(migrate_from_svr_port)); - unit.status_ = ObUnit::str_to_unit_status(status); - } + EXTRACT_INT_FIELD_MYSQL(result, "unit_id", unit.unit_id_, uint64_t); + EXTRACT_INT_FIELD_MYSQL(result, "resource_pool_id", unit.resource_pool_id_, uint64_t); + EXTRACT_INT_FIELD_MYSQL(result, "unit_group_id", unit.unit_group_id_, uint64_t); + EXTRACT_STRBUF_FIELD_MYSQL(result, "zone", unit.zone_.ptr(), MAX_ZONE_LENGTH, tmp_real_str_len); + EXTRACT_STRBUF_FIELD_MYSQL(result, "svr_ip", ip, OB_IP_STR_BUFF, tmp_real_str_len); + EXTRACT_INT_FIELD_MYSQL(result, "svr_port", port, int64_t); + EXTRACT_STRBUF_FIELD_MYSQL(result, "migrate_from_svr_ip", migrate_from_svr_ip, + OB_IP_STR_BUFF, tmp_real_str_len); + EXTRACT_INT_FIELD_MYSQL(result, "migrate_from_svr_port", migrate_from_svr_port, int64_t); + EXTRACT_BOOL_FIELD_MYSQL(result, "manual_migrate", unit.is_manual_migrate_); + EXTRACT_STRBUF_FIELD_MYSQL(result, "status", status, MAX_UNIT_STATUS_LENGTH, tmp_real_str_len); + EXTRACT_INT_FIELD_MYSQL_SKIP_RET(result, "replica_type", unit.replica_type_, common::ObReplicaType); + (void) tmp_real_str_len; // make compiler happy + unit.server_.set_ip_addr(ip, static_cast(port)); + unit.migrate_from_server_.set_ip_addr( + migrate_from_svr_ip, static_cast(migrate_from_svr_port)); + unit.status_ = ObUnit::str_to_unit_status(status); return ret; } diff --git a/src/share/ob_unit_table_operator.h b/src/share/ob_unit_table_operator.h index 7ffe478adf..6a017de8d0 100644 --- a/src/share/ob_unit_table_operator.h +++ b/src/share/ob_unit_table_operator.h @@ -41,7 +41,8 @@ public: virtual int get_units(const common::ObIArray &pool_ids, common::ObIArray &units) const; virtual int update_unit(common::ObISQLClient &client, - const ObUnit &unit); + const ObUnit &unit, + const bool need_check_conflict_with_clone); virtual int remove_units(common::ObISQLClient &client, const uint64_t resource_pool_id); virtual int remove_unit(common::ObISQLClient &client, @@ -60,7 +61,8 @@ public: const bool select_for_update, ObResourcePool &resource_pool) const; virtual int update_resource_pool(common::ObISQLClient &client, - const ObResourcePool &resource_pool); + const ObResourcePool &resource_pool, + const bool need_check_conflict_with_clone); virtual int remove_resource_pool(common::ObISQLClient &client, const uint64_t resource_pool_id); @@ -86,13 +88,13 @@ public: virtual int get_unit_stats(common::ObIArray &unit_stats) const; + static int read_unit(const common::sqlclient::ObMySQLResult &result, ObUnit &unit); private: static int zone_list2str(const common::ObIArray &zone_list, char *str, const int64_t buf_size); static int str2zone_list(const char *str, common::ObIArray &zone_list); - int read_unit(const common::sqlclient::ObMySQLResult &result, ObUnit &unit) const; int read_units(common::ObSqlString &sql, common::ObIArray &units) const; int read_unit_config(const common::sqlclient::ObMySQLResult &result, diff --git a/src/share/rc/ob_tenant_base.h b/src/share/rc/ob_tenant_base.h index 9c3830524f..98d544fdf2 100755 --- a/src/share/rc/ob_tenant_base.h +++ b/src/share/rc/ob_tenant_base.h @@ -89,6 +89,7 @@ class ObTenantMdsService; class ObTransferService; class ObRebuildService; class ObTableScanIterator; + class ObTenantSnapshotService; class ObTenantCGReadInfoMgr; class ObEmptyReadBucket; class ObTabletMemtableMgrPool; @@ -170,12 +171,15 @@ namespace rootserver class ObArbitrationService; class ObHeartbeatService; class ObStandbySchemaRefreshTrigger; + class ObTenantSnapshotScheduler; + class ObCloneScheduler; } namespace observer { class ObTenantMetaChecker; class QueueThread; class ObTableLoadService; + class ObStartupAccelTaskHandler; class ObTabletTableUpdater; } @@ -340,6 +344,9 @@ using ObTableScanIteratorObjPool = common::ObServerObjectPoolis_invalid_tenant() // 租户是否处于恢复中 #define MTL_TENANT_ROLE_CACHE_IS_RESTORE() share::ObTenantEnv::get_tenant()->is_restore_tenant() +// 租户是否处于克隆中 +#define MTL_TENANT_ROLE_CACHE_IS_CLONE() share::ObTenantEnv::get_tenant()->is_clone_tenant() // 更新租户role #define MTL_SET_TENANT_ROLE_CACHE(tenant_role) share::ObTenantEnv::get_tenant()->set_tenant_role(tenant_role) // 获取租户role @@ -557,6 +566,11 @@ public: return share::is_restore_tenant(ATOMIC_LOAD(&tenant_role_value_)); } + bool is_clone_tenant() + { + return share::is_clone_tenant(ATOMIC_LOAD(&tenant_role_value_)); + } + bool is_invalid_tenant() { return share::is_invalid_tenant(ATOMIC_LOAD(&tenant_role_value_)); diff --git a/src/share/restore/ob_ls_restore_status.cpp b/src/share/restore/ob_ls_restore_status.cpp index b3c2f7ecc3..eb3a33c155 100644 --- a/src/share/restore/ob_ls_restore_status.cpp +++ b/src/share/restore/ob_ls_restore_status.cpp @@ -30,39 +30,69 @@ ObLSRestoreStatus &ObLSRestoreStatus::operator=(const ObLSRestoreStatus &restore return *this; } +#define LS_RESTORE_STATUS_CASE_TO_TYPE \ + LRS_CASE_TO_TYPE(NONE); \ + LRS_CASE_TO_TYPE(RESTORE_START); \ + LRS_CASE_TO_TYPE(RESTORE_SYS_TABLETS); \ + LRS_CASE_TO_TYPE(WAIT_RESTORE_SYS_TABLETS); \ + LRS_CASE_TO_TYPE(RESTORE_TABLETS_META); \ + LRS_CASE_TO_TYPE(WAIT_RESTORE_TABLETS_META); \ + LRS_CASE_TO_TYPE(RESTORE_TO_CONSISTENT_SCN); \ + LRS_CASE_TO_TYPE(WAIT_RESTORE_TO_CONSISTENT_SCN); \ + LRS_CASE_TO_TYPE(QUICK_RESTORE); \ + LRS_CASE_TO_TYPE(WAIT_QUICK_RESTORE); \ + LRS_CASE_TO_TYPE(QUICK_RESTORE_FINISH); \ + LRS_CASE_TO_TYPE(RESTORE_MAJOR_DATA); \ + LRS_CASE_TO_TYPE(WAIT_RESTORE_MAJOR_DATA); \ + LRS_CASE_TO_TYPE(RESTORE_FAILED); \ + LRS_CASE_TO_TYPE(CLONE_START); \ + LRS_CASE_TO_TYPE(CLONE_COPY_ALL_TABLET_META); \ + LRS_CASE_TO_TYPE(CLONE_COPY_LS_META); \ + LRS_CASE_TO_TYPE(CLONE_CLOG_REPLAY); \ + LRS_CASE_TO_TYPE(CLONE_FAILED); + const char *ObLSRestoreStatus::get_restore_status_str(const ObLSRestoreStatus &status) { - const char *str = "UNKNOWN"; - const char *restore_status_str[] = { - "RESTORE_NONE", - "RESTORE_START", - "RESTORE_SYS_TABLETS", - "WAIT_RESTORE_SYS_TABLETS", - "RESTORE_TABLETS_META", - "WAIT_RESTORE_TABLETS_META", - "RESTORE_TO_CONSISTENT_SCN", - "WAIT_RESTORE_TO_CONSISTENT_SCN", - "QUICK_RESTORE", - "WAIT_QUICK_RESTORE", - "QUICK_RESTORE_FINISH", - "RESTORE_MAJOR_DATA", - "WAIT_RESTORE_MAJOR_DATA", - "RESTORE_FAILED", - }; - STATIC_ASSERT(LS_RESTORE_STATUS_MAX == ARRAYSIZEOF(restore_status_str), "status count mismatch"); - if (status.status_ < 0 || status.status_ >= LS_RESTORE_STATUS_MAX) { - LOG_ERROR_RET(OB_ERR_UNEXPECTED, "invalid status", K(status)); - } else { - str = restore_status_str[status.status_]; +#define LRS_CASE_TO_TYPE(state) \ + case state: { \ + str = #state; \ + break; \ } - return str; + const char* str = "INVALID"; + switch (status) { + LS_RESTORE_STATUS_CASE_TO_TYPE + default: + break; + } +#undef LRS_CASE_TO_TYPE + return str; } +bool ObLSRestoreStatus::is_valid_(int32_t status) const +{ +#define LRS_CASE_TO_TYPE(state) \ + case state: { \ + bool_ret = true; \ + break; \ + } + + bool bool_ret = false; + switch (status) { + LS_RESTORE_STATUS_CASE_TO_TYPE + default: + break; + } +#undef LRS_CASE_TO_TYPE + return bool_ret; +} + +#undef LS_RESTORE_STATUS_CASE_TO_TYPE + int ObLSRestoreStatus::set_status(int32_t status) { int ret = OB_SUCCESS; - if (RESTORE_NONE > status || LS_RESTORE_STATUS_MAX <= status) { + if (!is_valid_(status)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid status", K(ret), K(status)); } else { diff --git a/src/share/restore/ob_ls_restore_status.h b/src/share/restore/ob_ls_restore_status.h index 9c1466b21a..839f55ba26 100644 --- a/src/share/restore/ob_ls_restore_status.h +++ b/src/share/restore/ob_ls_restore_status.h @@ -28,8 +28,9 @@ class ObLSRestoreStatus final public: enum Status : uint8_t { - // Not restore or restore finish, default status - RESTORE_NONE = 0, + // default status + NONE = 0, + // restore // log stream restore initial state RESTORE_START = 1, // restore sys tablets and create user tables @@ -56,11 +57,24 @@ public: WAIT_RESTORE_MAJOR_DATA = 12, // restore failed RESTORE_FAILED = 13, - LS_RESTORE_STATUS_MAX + + // clone + // log stream clone initial state + CLONE_START = 101, + // copy all tablets meta from tenant_snapshot + CLONE_COPY_ALL_TABLET_META = 102, + // copy ls meta from tenant snapshot + CLONE_COPY_LS_META = 103, + // wait clog replay finished + CLONE_CLOG_REPLAY = 104, + // clone failed + CLONE_FAILED = 105, + + LS_RESTORE_STATUS_MAX = 255 }; public: - ObLSRestoreStatus() : status_(RESTORE_NONE) {} + ObLSRestoreStatus() : status_(Status::NONE) {} ~ObLSRestoreStatus() = default; explicit ObLSRestoreStatus(const Status &status); ObLSRestoreStatus &operator=(const ObLSRestoreStatus &restore_status); @@ -69,11 +83,12 @@ public: bool operator !=(const ObLSRestoreStatus &other) const { return status_ != other.status_; } operator Status() const { return status_; } static const char *get_restore_status_str(const ObLSRestoreStatus &status); - bool is_valid() const { return status_ >= Status::RESTORE_NONE && status_ < Status::LS_RESTORE_STATUS_MAX; } + bool is_valid() const { return is_valid_(status_); } bool is_restore_start() const { return Status::RESTORE_START == status_; } bool is_quick_restore() const { return Status::QUICK_RESTORE == status_; } bool is_restore_major_data() const { return Status::RESTORE_MAJOR_DATA == status_; } - bool is_restore_none() const { return Status::RESTORE_NONE == status_; } + bool is_none() const { return Status::NONE == status_; } + bool is_failed() const { return Status::RESTORE_FAILED == status_ || Status::CLONE_FAILED == status_; } bool is_restore_sys_tablets() const { return Status::RESTORE_SYS_TABLETS == status_; } bool is_restore_tablets_meta() const { return Status::RESTORE_TABLETS_META == status_; } bool is_restore_to_consistent_scn() const { return Status::RESTORE_TO_CONSISTENT_SCN == status_; } @@ -83,8 +98,8 @@ public: bool is_wait_quick_restore() const { return Status::WAIT_QUICK_RESTORE == status_; } bool is_wait_restore_major_data() const { return Status::WAIT_RESTORE_MAJOR_DATA == status_; } bool is_quick_restore_finish() const { return Status::QUICK_RESTORE_FINISH == status_;} - bool is_restore_failed() const { return Status::RESTORE_FAILED == status_; } - bool is_in_restore() const { return status_ != Status::RESTORE_NONE; } + bool is_in_restore() const { return status_ >= Status::RESTORE_START && status_ <= Status::RESTORE_FAILED; } + bool is_in_restore_or_none() const { return is_none() || is_in_restore(); } bool is_wait_status() const { return is_wait_restore_sys_tablets() @@ -94,20 +109,40 @@ public: || is_wait_restore_major_data(); } - // enable sync and online ls restore handler in [RESTORE_START, RESTORE_SYS_TABLETS] or RESTORE_FAILED - bool is_enable_for_restore() const + // offline ls and enable sync and online ls restore handler in [RESTORE_START, RESTORE_SYS_TABLETS] or RESTORE_FAILED + bool is_required_to_switch_ls_state_for_restore() const { return ((status_ >= Status::RESTORE_START && status_ <= Status::RESTORE_SYS_TABLETS) || status_ == Status::RESTORE_FAILED); } + + bool is_in_clone() const { return status_ >= Status::CLONE_START && status_ <= Status::CLONE_FAILED; } + bool is_in_clone_or_none() const { return is_none() || is_in_clone(); } + bool is_in_clone_and_tablet_meta_incomplete() const + { + return status_ >= Status::CLONE_START && status_ <= Status::CLONE_COPY_ALL_TABLET_META; + } + bool is_required_to_switch_ls_state_for_clone() const + { + return ((status_ >= Status::CLONE_START && status_ <= Status::CLONE_COPY_LS_META) || + Status::CLONE_FAILED == status_); + } + // if restore status is not in [RESTORE_START, RESTORE_SYS_TABLETS], log_replay_service can replay log. // if restore status is not in [RESTORE_START, RESTORE_SYS_TABLETS] or restore_failed, log_replay_service can replay log. - bool can_replay_log() const { return ! (status_ >= Status::RESTORE_START && status_ <= Status::RESTORE_SYS_TABLETS) - && status_ != Status::RESTORE_FAILED; } - bool can_restore_log() const { return status_ == RESTORE_NONE || (status_ >= RESTORE_TO_CONSISTENT_SCN && status_ < RESTORE_FAILED); } + bool can_replay_log() const { return !(status_ >= Status::RESTORE_START && status_ <= Status::RESTORE_SYS_TABLETS) && + !(status_ >= Status::CLONE_START && status_ <= Status::CLONE_COPY_LS_META) && + status_ != Status::RESTORE_FAILED && + status_ != Status::CLONE_FAILED; } + + bool can_restore_log() const { return status_ == NONE || + (status_ >= RESTORE_TO_CONSISTENT_SCN && status_ < RESTORE_FAILED) || + (status_ >= CLONE_CLOG_REPLAY && status_ < CLONE_FAILED); } + bool can_migrate() const { - return !(status_ >= RESTORE_START && status_ <= RESTORE_SYS_TABLETS); + return !(status_ >= RESTORE_START && status_ <= RESTORE_SYS_TABLETS) && + !(status_ >= Status::CLONE_START && status_ <= Status::CLONE_CLOG_REPLAY); } bool is_in_restore_and_before_quick_restore() const { @@ -125,7 +160,8 @@ public: int64_t get_serialize_size() const; TO_STRING_KV(K_(status)); - +private: + bool is_valid_(int32_t status) const; private: Status status_; }; diff --git a/src/share/restore/ob_physical_restore_table_operator.cpp b/src/share/restore/ob_physical_restore_table_operator.cpp index f9a5ee4a06..7f1029e2d1 100644 --- a/src/share/restore/ob_physical_restore_table_operator.cpp +++ b/src/share/restore/ob_physical_restore_table_operator.cpp @@ -1099,14 +1099,14 @@ int ObPhysicalRestoreTableOperator::check_finish_restore_to_consistent_scn( if (OB_FAIL(ret)) { } else if (OB_FAIL(ls_restore_status.set_status(restore_status))) { LOG_WARN("failed to set status", KR(ret), K(restore_status)); - } else if (ls_restore_status.is_restore_failed()) { + } else if (!ls_restore_status.is_in_restore_or_none() || ls_restore_status.is_failed()) { //restore failed is_finished = true; is_success = false; } else { const ObLSRestoreStatus target_status(ObLSRestoreStatus::Status::WAIT_RESTORE_TO_CONSISTENT_SCN); if (ls_restore_status.get_status() < target_status.get_status() - && !ls_restore_status.is_restore_none() + && !ls_restore_status.is_none() && is_finished && is_success) { is_finished = false; } @@ -1119,4 +1119,4 @@ int ObPhysicalRestoreTableOperator::check_finish_restore_to_consistent_scn( } } return ret; -} \ No newline at end of file +} diff --git a/src/share/restore/ob_tenant_clone_table_operator.cpp b/src/share/restore/ob_tenant_clone_table_operator.cpp new file mode 100644 index 0000000000..343f7f2363 --- /dev/null +++ b/src/share/restore/ob_tenant_clone_table_operator.cpp @@ -0,0 +1,1212 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE +#include "share/restore/ob_tenant_clone_table_operator.h" +#include "share/ob_dml_sql_splicer.h" +#include "share/inner_table/ob_inner_table_schema_constants.h" + +using namespace oceanbase::share; +using namespace oceanbase::common; + +ObTenantCloneStatus &ObTenantCloneStatus::operator=(const ObTenantCloneStatus &status) +{ + status_ = status.status_; + return *this; +} + +ObTenantCloneStatus &ObTenantCloneStatus::operator=(const Status &status) +{ + status_ = status; + return *this; +} + +const ObTenantCloneStatus::TenantCloneStatusStrPair ObTenantCloneStatus::TENANT_CLONE_STATUS_ARRAY[] = { + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_LOCK, + "CLONE_SYS_LOCK"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL, + "CLONE_SYS_CREATE_INNER_RESOURCE_POOL"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT, + "CLONE_SYS_CREATE_SNAPSHOT"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT, + "CLONE_SYS_WAIT_CREATE_SNAPSHOT"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT, + "CLONE_SYS_CREATE_TENANT"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH, + "CLONE_SYS_WAIT_TENANT_RESTORE_FINISH"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE, + "CLONE_SYS_RELEASE_RESOURCE"), + + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_USER_PREPARE, "CLONE_USER_PREPARE"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_USER_CREATE_INIT_LS, "CLONE_USER_CREATE_INIT_LS"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_USER_WAIT_LS, "CLONE_USER_WAIT_LS"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_USER_POST_CHECK, "CLONE_USER_POST_CHECK"), + + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_USER_SUCCESS, "CLONE_USER_SUCCESS"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_USER_FAIL, "CLONE_USER_FAIL"), + + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_SUCCESS, "CLONE_SYS_SUCCESS"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_LOCK_FAIL, "CLONE_SYS_LOCK_FAIL"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL_FAIL, + "CLONE_SYS_CREATE_INNER_RESOURCE_POOL_FAIL"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT_FAIL, + "CLONE_SYS_CREATE_SNAPSHOT_FAIL"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT_FAIL, + "CLONE_SYS_WAIT_CREATE_SNAPSHOT_FAIL"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT_FAIL, + "CLONE_SYS_CREATE_TENANT_FAIL"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH_FAIL, + "CLONE_SYS_WAIT_TENANT_RESTORE_FINISH_FAIL"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE_FAIL, + "CLONE_SYS_RELEASE_RESOURCE_FAIL"), + TenantCloneStatusStrPair(ObTenantCloneStatus::Status::CLONE_SYS_CANCELED, + "CLONE_SYS_CANCELED"), +}; + +const char *ObTenantCloneStatus::get_clone_status_str(const Status &status) +{ + const char* str = "CLONE_MAX_STATUS"; + bool find = false; + + for (int64_t i = 0; !find && i < ARRAYSIZEOF(TENANT_CLONE_STATUS_ARRAY); i++) { + if (status == TENANT_CLONE_STATUS_ARRAY[i].status_) { + find = true; + if (OB_NOT_NULL(TENANT_CLONE_STATUS_ARRAY[i].str_)) { + str = TENANT_CLONE_STATUS_ARRAY[i].str_; + } else { + LOG_WARN_RET(OB_ERR_UNEXPECTED, "unexpected null"); + } + } + } + + if (!find) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid clone status", K(status)); + } + return str; +} + +ObTenantCloneStatus ObTenantCloneStatus::get_clone_status(const ObString &status_str) +{ + ObTenantCloneStatus::Status ret_status = ObTenantCloneStatus::Status::CLONE_MAX_STATUS; + bool find = false; + + if (!status_str.empty()) { + for (int64_t i = 0; !find && i < ARRAYSIZEOF(TENANT_CLONE_STATUS_ARRAY); i++) { + if (0 == status_str.case_compare(TENANT_CLONE_STATUS_ARRAY[i].str_)) { + ret_status = TENANT_CLONE_STATUS_ARRAY[i].status_; + find = true; + } + } + } + + if (!find) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid clone status str", K(status_str)); + } + return ObTenantCloneStatus(ret_status); +} + +bool ObTenantCloneStatus::is_user_status() const +{ + bool b_ret = false; + + if (ObTenantCloneStatus::Status::CLONE_USER_PREPARE == status_ || + ObTenantCloneStatus::Status::CLONE_USER_CREATE_INIT_LS == status_ || + ObTenantCloneStatus::Status::CLONE_USER_WAIT_LS == status_ || + ObTenantCloneStatus::Status::CLONE_USER_POST_CHECK == status_ || + ObTenantCloneStatus::Status::CLONE_USER_SUCCESS == status_ || + ObTenantCloneStatus::Status::CLONE_USER_FAIL == status_) { + b_ret = true; + } + + return b_ret; +} + +bool ObTenantCloneStatus::is_user_success_status() const +{ + return ObTenantCloneStatus::Status::CLONE_USER_SUCCESS == status_; +} + +bool ObTenantCloneStatus::is_sys_status() const +{ + return !is_user_status(); +} + +bool ObTenantCloneStatus::is_sys_success_status() const +{ + return ObTenantCloneStatus::Status::CLONE_SYS_SUCCESS == status_; +} + +bool ObTenantCloneStatus::is_sys_processing_status() const +{ + bool b_ret = false; + + if (ObTenantCloneStatus::Status::CLONE_SYS_LOCK == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE == status_) { + b_ret = true; + } + + return b_ret; +} + +bool ObTenantCloneStatus::is_sys_canceled_status() const +{ + return ObTenantCloneStatus::Status::CLONE_SYS_CANCELED == status_; +} + +bool ObTenantCloneStatus::is_sys_failed_status() const +{ + bool b_ret = false; + + if (ObTenantCloneStatus::Status::CLONE_SYS_LOCK_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_INNER_RESOURCE_POOL_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_SNAPSHOT_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CANCELED == status_) { + b_ret = true; + } + + return b_ret; +} + +bool ObTenantCloneStatus::is_sys_valid_snapshot_status_for_fork() const +{ + bool b_ret = false; + + if (ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_WAIT_CREATE_SNAPSHOT_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_CREATE_TENANT_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_WAIT_TENANT_RESTORE_FINISH_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE_FAIL == status_ || + ObTenantCloneStatus::Status::CLONE_SYS_SUCCESS == status_) { + b_ret = true; + } + + return b_ret; +} + +bool ObTenantCloneStatus::is_sys_release_resource_status() const +{ + bool b_ret = false; + + if (is_sys_failed_status() || + ObTenantCloneStatus::Status::CLONE_SYS_RELEASE_RESOURCE == status_) { + b_ret = true; + } + + return b_ret; +} + +ObCloneJob::ObCloneJob() : + trace_id_(), + tenant_id_(OB_INVALID_TENANT_ID), + job_id_(OB_INVALID_ID), + source_tenant_id_(OB_INVALID_TENANT_ID), + source_tenant_name_(), + clone_tenant_id_(OB_INVALID_TENANT_ID), + clone_tenant_name_(), + tenant_snapshot_id_(), + tenant_snapshot_name_(), + resource_pool_id_(OB_INVALID_ID), + resource_pool_name_(), + unit_config_name_(), + restore_scn_(), + status_(ObTenantCloneStatus::Status::CLONE_MAX_STATUS), + job_type_(ObTenantCloneJobType::CLONE_JOB_MAX_TYPE), + allocator_("CloneJob") +{} + +int ObCloneJob::init(const ObCloneJobInitArg &init_arg) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!init_arg.trace_id_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid trace_id", KR(ret), K(init_arg.trace_id_)); + } else if (OB_UNLIKELY(!is_sys_tenant(init_arg.tenant_id_) && !is_user_tenant(init_arg.tenant_id_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_id", KR(ret), K(init_arg.tenant_id_)); + } else if (OB_UNLIKELY(0 > init_arg.job_id_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid job_id", KR(ret), K(init_arg.job_id_)); + } else if (OB_UNLIKELY(!is_user_tenant(init_arg.source_tenant_id_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid source_tenant_id", KR(ret), K(init_arg.source_tenant_id_)); + } else if (OB_UNLIKELY(init_arg.source_tenant_name_.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid source_tenant_name", KR(ret), K(init_arg.source_tenant_name_)); + } else if (OB_UNLIKELY(init_arg.clone_tenant_name_.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid clone_tenant_name", KR(ret), K(init_arg.clone_tenant_name_)); + } else if (OB_UNLIKELY(init_arg.resource_pool_name_.empty() || init_arg.unit_config_name_.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid resource_pool_name or unit_config_name", KR(ret), + K(init_arg.resource_pool_name_), K(init_arg.unit_config_name_)); + } else if (OB_UNLIKELY(!init_arg.status_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid status", KR(ret), K(init_arg.status_)); + } else if (ObTenantCloneJobType::CLONE_JOB_MAX_TYPE == init_arg.job_type_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid job_type", KR(ret), K(init_arg.job_type_)); + } else if (ObTenantCloneJobType::RESTORE == init_arg.job_type_) { + if (OB_UNLIKELY(init_arg.tenant_snapshot_name_.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_snapshot_name", KR(ret), K(init_arg.tenant_snapshot_name_), K(init_arg.job_type_)); + } else if (OB_UNLIKELY(!init_arg.tenant_snapshot_id_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid tenant_snapshot_id", KR(ret), K(init_arg.tenant_snapshot_id_), K(init_arg.job_type_)); + } else if (OB_UNLIKELY(!init_arg.restore_scn_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid restore_scn", KR(ret), K(init_arg.restore_scn_), K(init_arg.job_type_)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(deep_copy_ob_string(allocator_, init_arg.source_tenant_name_, source_tenant_name_))) { + LOG_WARN("source_tenant_name deep copy failed", KR(ret), K(init_arg.source_tenant_name_)); + } else if (OB_FAIL(deep_copy_ob_string(allocator_, init_arg.clone_tenant_name_, clone_tenant_name_))) { + LOG_WARN("clone_tenant_name deep copy failed", KR(ret), K(init_arg.clone_tenant_name_)); + } else if (OB_FAIL(deep_copy_ob_string(allocator_, init_arg.tenant_snapshot_name_, tenant_snapshot_name_))) { + LOG_WARN("tenant_snapshot_name deep copy failed", KR(ret), K(init_arg.tenant_snapshot_name_)); + } else if (OB_FAIL(deep_copy_ob_string(allocator_, init_arg.resource_pool_name_, resource_pool_name_))) { + LOG_WARN("resource_pool_name deep copy failed", KR(ret), K(init_arg.resource_pool_name_)); + } else if (OB_FAIL(deep_copy_ob_string(allocator_, init_arg.unit_config_name_, unit_config_name_))) { + LOG_WARN("unit_config_name deep copy failed", KR(ret), K(init_arg.unit_config_name_)); + } else { + trace_id_ = init_arg.trace_id_; + tenant_id_ = init_arg.tenant_id_; + job_id_ = init_arg.job_id_; + source_tenant_id_ = init_arg.source_tenant_id_; + clone_tenant_id_ = init_arg.clone_tenant_id_; + tenant_snapshot_id_ = init_arg.tenant_snapshot_id_; + resource_pool_id_ = init_arg.resource_pool_id_; + restore_scn_ = init_arg.restore_scn_; + status_ = init_arg.status_; + job_type_ = init_arg.job_type_; + ret_code_ = init_arg.ret_code_; + } + return ret; +} + +int ObCloneJob::assign(const ObCloneJob &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(deep_copy_ob_string(allocator_, other.source_tenant_name_, source_tenant_name_))) { + LOG_WARN("source_tenant_name deep copy failed", KR(ret), K(other)); + } else if (OB_FAIL(deep_copy_ob_string(allocator_, other.clone_tenant_name_, clone_tenant_name_))) { + LOG_WARN("clone_tenant_name deep copy failed", KR(ret), K(other)); + } else if (OB_FAIL(deep_copy_ob_string(allocator_, other.tenant_snapshot_name_, tenant_snapshot_name_))) { + LOG_WARN("tenant_snapshot_name deep copy failed", KR(ret), K(other)); + } else if (OB_FAIL(deep_copy_ob_string(allocator_, other.resource_pool_name_, resource_pool_name_))) { + LOG_WARN("resource_pool_name deep copy failed", KR(ret), K(other)); + } else if (OB_FAIL(deep_copy_ob_string(allocator_, other.unit_config_name_, unit_config_name_))) { + LOG_WARN("unit_config_name deep copy failed", KR(ret), K(other)); + } else { + trace_id_ = other.trace_id_; + tenant_id_ = other.tenant_id_; + job_id_ = other.job_id_; + source_tenant_id_ = other.source_tenant_id_; + clone_tenant_id_ = other.clone_tenant_id_; + tenant_snapshot_id_ = other.tenant_snapshot_id_; + resource_pool_id_ = other.resource_pool_id_; + restore_scn_ = other.restore_scn_; + status_ = other.status_; + job_type_ = other.job_type_; + ret_code_ = ret_code_; + } + return ret; +} + +void ObCloneJob::reset() +{ + trace_id_.reset(); + tenant_id_ = OB_INVALID_TENANT_ID; + job_id_ = OB_INVALID_ID; + source_tenant_id_ = OB_INVALID_TENANT_ID; + source_tenant_name_.reset(); + clone_tenant_name_.reset(); + clone_tenant_id_ = OB_INVALID_TENANT_ID; + tenant_snapshot_id_.reset(); + tenant_snapshot_name_.reset(); + resource_pool_id_ = OB_INVALID_ID; + resource_pool_name_.reset(); + unit_config_name_.reset(); + restore_scn_.reset(); + status_.reset(); + job_type_ = ObTenantCloneJobType::CLONE_JOB_MAX_TYPE; + ret_code_ = OB_SUCCESS; + allocator_.reset(); +} + +bool ObCloneJob::is_valid() const + { + bool bret = trace_id_.is_valid() + && (is_sys_tenant(tenant_id_) || is_user_tenant(tenant_id_)) + && job_id_ > 0 + && is_user_tenant(source_tenant_id_) + && !source_tenant_name_.empty() + && !clone_tenant_name_.empty() + && !resource_pool_name_.empty() + && !unit_config_name_.empty() + && status_.is_valid() + && ObTenantCloneJobType::CLONE_JOB_MAX_TYPE != job_type_; + if (bret && ObTenantCloneJobType::RESTORE == job_type_) { + bret = tenant_snapshot_id_.is_valid() + && !tenant_snapshot_name_.empty() + && restore_scn_.is_valid(); + } + return bret; +} + +bool ObCloneJob::is_valid_status_allows_user_tenant_to_do_ls_recovery() const +{ + return ObTenantCloneStatus::Status::CLONE_USER_WAIT_LS == status_ + || ObTenantCloneStatus::Status::CLONE_USER_POST_CHECK == status_ + || ObTenantCloneStatus::Status::CLONE_USER_SUCCESS == status_; +} + +ObTenantCloneTableOperator::ObTenantCloneTableOperator() : + is_inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), + proxy_(NULL) +{} + +const TenantCloneJobTypeStrPair ObTenantCloneTableOperator::TENANT_CLONE_JOB_TYPE_ARRAY[] = { + TenantCloneJobTypeStrPair(ObTenantCloneJobType::RESTORE, "RESTORE"), + TenantCloneJobTypeStrPair(ObTenantCloneJobType::FORK, "FORK"), +}; + +ObTenantCloneJobType ObTenantCloneTableOperator::get_job_type(const ObString &str) +{ + ObTenantCloneJobType ret_type = ObTenantCloneJobType::CLONE_JOB_MAX_TYPE; + bool find = false; + + if (!str.empty()) { + for (int64_t i = 0; !find && i < ARRAYSIZEOF(TENANT_CLONE_JOB_TYPE_ARRAY); i++) { + if (0 == str.case_compare(TENANT_CLONE_JOB_TYPE_ARRAY[i].str_)) { + ret_type = TENANT_CLONE_JOB_TYPE_ARRAY[i].type_; + find = true; + } + } + } + + if (!find) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid clone job type str", K(str)); + } + return ret_type; +} + +const char* ObTenantCloneTableOperator::get_job_type_str(ObTenantCloneJobType job_type) +{ + const char* str = "CLONE_JOB_MAX_TYPE"; + bool find = false; + + for (int64_t i = 0; !find && i < ARRAYSIZEOF(TENANT_CLONE_JOB_TYPE_ARRAY); i++) { + if (job_type == TENANT_CLONE_JOB_TYPE_ARRAY[i].type_) { + find = true; + if (OB_NOT_NULL(TENANT_CLONE_JOB_TYPE_ARRAY[i].str_)) { + str = TENANT_CLONE_JOB_TYPE_ARRAY[i].str_; + } else { + LOG_WARN_RET(OB_ERR_UNEXPECTED, "unexpected null"); + } + } + } + + if (!find) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid clone job type", K(job_type)); + } + + return str; +} + +int ObTenantCloneTableOperator::init(const uint64_t tenant_id, ObISQLClient *proxy) +{ + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("clone table operator init twice", KR(ret)); + } else if (OB_UNLIKELY(!is_sys_tenant(tenant_id) && !is_user_tenant(tenant_id) + || OB_ISNULL(proxy))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), KP(proxy)); + } else { + tenant_id_ = tenant_id; + proxy_ = proxy; + is_inited_ = true; + } + return ret; +} + +//get clone job according to source_tenant_id +//a source tenant only has one clone_job at the same time +int ObTenantCloneTableOperator::get_clone_job_by_source_tenant_id( + const uint64_t source_tenant_id, + ObCloneJob &job) +{ + int ret = OB_SUCCESS; + job.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!is_user_tenant(source_tenant_id))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(source_tenant_id)); + } else if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu AND source_tenant_id = %lu", + OB_ALL_CLONE_JOB_TNAME, tenant_id_, source_tenant_id))) { + LOG_WARN("assign sql failed", KR(ret), K(tenant_id_), K(source_tenant_id)); + } else if (OB_FAIL(read_only_exist_one_job_(sql, job))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to read job", KR(ret), K(sql)); + } else { + LOG_INFO("clone job not exist", KR(ret), K(sql)); + } + } + return ret; +} + +int ObTenantCloneTableOperator::get_clone_job_by_job_id(const int64_t job_id, + ObCloneJob &job) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t count = 0; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (job_id < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id)); + } else if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %ld AND job_id = %ld", + OB_ALL_CLONE_JOB_TNAME, tenant_id_, job_id))) { + LOG_WARN("assign sql failed", KR(ret)); + } else if (OB_FAIL(read_only_exist_one_job_(sql, job))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to read job", KR(ret), K(sql)); + } else { + LOG_INFO("clone job not exist", KR(ret), K(sql)); + } + } + + return ret; +} + +//get clone job according to clone_tenant_name +int ObTenantCloneTableOperator::get_clone_job_by_clone_tenant_name( + const ObString &clone_tenant_name, + const bool need_lock, + ObCloneJob &job) +{ + int ret = OB_SUCCESS; + job.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(clone_tenant_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(clone_tenant_name)); + } else if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu AND clone_tenant_name = '%.*s'", + OB_ALL_CLONE_JOB_TNAME, tenant_id_, clone_tenant_name.length(), clone_tenant_name.ptr()))) { + LOG_WARN("assign sql failed", KR(ret), K(tenant_id_), K(clone_tenant_name)); + } else if (need_lock && OB_FAIL(sql.append_fmt(" FOR UPDATE "))) { /*lock row*/ + LOG_WARN("assign sql failed", KR(ret)); + } else if (OB_FAIL(read_only_exist_one_job_(sql, job))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to read job", KR(ret), K(sql)); + } else { + LOG_INFO("clone job not exist", KR(ret), K(sql)); + } + } + return ret; +} + +int ObTenantCloneTableOperator::get_all_clone_jobs(ObArray &jobs) +{ + int ret = OB_SUCCESS; + jobs.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu", + OB_ALL_CLONE_JOB_TNAME, tenant_id_))) { + LOG_WARN("assign sql failed", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(read_jobs_(sql, jobs))) { + LOG_WARN("fail to read jobs", KR(ret), K(sql)); + } + return ret; +} + +int ObTenantCloneTableOperator::insert_clone_job(const ObCloneJob &job) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + const int64_t start_time = 0; // in add_time_column(), "0" means now(6) + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_FAIL(build_insert_dml_(job, dml))) { + LOG_WARN("fail to build insert dml", KR(ret), K(job)); + } else if (OB_FAIL(dml.add_time_column("clone_start_time", start_time))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.splice_insert_sql(OB_ALL_CLONE_JOB_TNAME, sql))) { + LOG_WARN("splice insert sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(gen_meta_tenant_id(tenant_id_)), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + + return ret; +} + +int ObTenantCloneTableOperator::update_job_status( + const int64_t job_id, + const ObTenantCloneStatus &old_status, + const ObTenantCloneStatus &new_status) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(job_id < 0 + || !old_status.is_valid() + || !new_status.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid job_id", KR(ret), K(tenant_id_), K(job_id), K(old_status), K(new_status)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("job_id", job_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("status", ObTenantCloneStatus::get_clone_status_str(new_status)))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s = '%s'", + "status", ObTenantCloneStatus::get_clone_status_str(old_status)))) { + LOG_WARN("add extra_condition failed", KR(ret), K(old_status)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_CLONE_JOB_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(gen_meta_tenant_id(tenant_id_)), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("the job with old_status doesn't exist", KR(ret), K(affected_rows), + K(job_id), K(old_status)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObTenantCloneTableOperator::update_job_failed_info(const int64_t job_id, + const int ret_code, + const ObString& err_msg) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + const int64_t finished_time = 0; // in add_time_column(), "0" means now(6) + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(job_id < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid job_id", KR(ret), K(tenant_id_), K(job_id)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("job_id", job_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("ret_code", ret_code))) { + LOG_WARN("add column failed", KR(ret)); + } else if (!err_msg.empty() && OB_FAIL(dml.add_column("error_msg", ObHexEscapeSqlStr(err_msg)))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_time_column("clone_finished_time", finished_time))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_CLONE_JOB_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(gen_meta_tenant_id(tenant_id_)), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObTenantCloneTableOperator::update_job_clone_tenant_id( + const int64_t job_id, + const uint64_t clone_tenant_id) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(job_id < 0 + || OB_INVALID_TENANT_ID == clone_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid job_id", KR(ret), K(tenant_id_), K(job_id), K(clone_tenant_id)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("job_id", job_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("clone_tenant_id", clone_tenant_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s = %lu", + "clone_tenant_id", + OB_INVALID_TENANT_ID))) { + LOG_WARN("add extra_condition failed", KR(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_CLONE_JOB_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(gen_meta_tenant_id(tenant_id_)), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + + return ret; +} + +int ObTenantCloneTableOperator::update_job_resource_pool_id(const int64_t job_id, + const uint64_t resource_pool_id) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (job_id < 0 || OB_INVALID_ID == resource_pool_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id_), K(job_id), K(resource_pool_id)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("job_id", job_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("resource_pool_id", resource_pool_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s = %ld", + "resource_pool_id", + OB_INVALID_ID))) { + LOG_WARN("add extra_condition failed", KR(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_CLONE_JOB_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret), K(sql)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K(gen_meta_tenant_id(tenant_id_))); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObTenantCloneTableOperator::update_job_snapshot_info(const int64_t job_id, + const ObTenantSnapshotID snapshot_id, + const ObString &snapshot_name) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (job_id < 0 || !snapshot_id.is_valid() || snapshot_name.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id_), K(job_id), K(snapshot_id), K(snapshot_name)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("job_id", job_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("tenant_snapshot_id", snapshot_id.id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("tenant_snapshot_name", snapshot_name))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s = %ld AND %s = %s", + "tenant_snapshot_id", + ObTenantSnapshotID::OB_INVALID_SNAPSHOT_ID, + "tenant_snapshot_name", + "\'\'"))) { + LOG_WARN("add extra_condition failed", KR(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_CLONE_JOB_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret), K(sql)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K(gen_meta_tenant_id(tenant_id_))); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows), K(sql)); + } + return ret; +} + +int ObTenantCloneTableOperator::update_job_snapshot_scn(const int64_t job_id, + const SCN &restore_scn) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", K(ret)); + } else if (job_id < 0 || !restore_scn.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id_), K(job_id), K(restore_scn)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("job_id", job_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("restore_scn", restore_scn.get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s = %lu", + "restore_scn", + SCN::invalid_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add extra_condition failed", KR(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_CLONE_JOB_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret), K(sql)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K(gen_meta_tenant_id(tenant_id_))); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObTenantCloneTableOperator::remove_clone_job(const ObCloneJob &job) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", job.get_tenant_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("job_id", job.get_job_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.splice_delete_sql(OB_ALL_CLONE_JOB_TNAME, sql))) { + LOG_WARN("splice delete sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(gen_meta_tenant_id(tenant_id_)), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + + return ret; +} + +int ObTenantCloneTableOperator::insert_clone_job_history(const ObCloneJob &job) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + int64_t start_time = 0; + int64_t finished_time = 0; + int ret_code = OB_SUCCESS; + ObString err_msg; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_FAIL(sql.assign_fmt("SELECT clone_start_time, clone_finished_time, ret_code, error_msg " + "FROM %s WHERE tenant_id = %lu AND job_id = %ld", + OB_ALL_CLONE_JOB_TNAME, + job.get_tenant_id(), job.get_job_id()))) { + LOG_WARN("assign sql failed", KR(ret)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(job.get_tenant_id()), sql.ptr()))) { + LOG_WARN("failed to execute sql", KR(ret), K(sql), K(job)); + } else if (NULL == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + LOG_WARN("next failed", KR(ret)); + } else { + EXTRACT_TIMESTAMP_FIELD_MYSQL(*result, "clone_start_time", start_time); + EXTRACT_TIMESTAMP_FIELD_MYSQL_SKIP_RET(*result, "clone_finished_time", finished_time); + EXTRACT_INT_FIELD_MYSQL_SKIP_RET(*result, "ret_code", ret_code, int); + EXTRACT_VARCHAR_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "error_msg", err_msg, + true /*skip_null_error*/, + false /*skip_column_error*/, + "" /*default_value*/); + } + } + sql.reset(); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(build_insert_dml_(job, dml))) { + LOG_WARN("fail to build insert dml", KR(ret), K(job)); + } else if (OB_FAIL(dml.add_time_column("clone_start_time", start_time))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_time_column("clone_finished_time", finished_time))) { + LOG_WARN("add column failed", KR(ret)); + } else if (!err_msg.empty() && OB_FAIL(dml.add_column("error_msg", ObHexEscapeSqlStr(err_msg)))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("ret_code", ret_code))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.splice_insert_sql(OB_ALL_CLONE_JOB_HISTORY_TNAME, sql))) { + LOG_WARN("splice insert sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(gen_meta_tenant_id(tenant_id_)), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + + return ret; +} + +int ObTenantCloneTableOperator::get_user_clone_job_history(ObCloneJob &job) +{ + int ret = OB_SUCCESS; + job.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!is_user_tenant(tenant_id_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu", + OB_ALL_CLONE_JOB_HISTORY_TNAME, tenant_id_))) { + LOG_WARN("assign sql failed", KR(ret), K(tenant_id_)); + } else if (OB_FAIL(read_only_exist_one_job_(sql, job))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to read job", KR(ret), K(sql)); + } else { + LOG_INFO("clone job not exist", KR(ret), K(sql)); + } + } + return ret; +} + +int ObTenantCloneTableOperator::get_sys_clone_job_history( + const int64_t job_id, + ObCloneJob &job) +{ + int ret = OB_SUCCESS; + job.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(job_id < 0 + || !is_sys_tenant(tenant_id_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id), K(tenant_id_)); + } else if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE job_id = %ld", + OB_ALL_CLONE_JOB_HISTORY_TNAME, job_id))) { + LOG_WARN("assign sql failed", KR(ret), K(job_id)); + } else if (OB_FAIL(read_only_exist_one_job_(sql, job))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to read job", KR(ret), K(sql)); + } else { + LOG_INFO("clone job not exist", KR(ret), K(sql)); + } + } + return ret; +} + +int ObTenantCloneTableOperator::get_job_failed_message( + const int64_t job_id, + ObIAllocator &allocator, + ObString &err_msg) +{ + int ret = OB_SUCCESS; + err_msg.reset(); + const int32_t table_num = 2; + ObString tables[2] = {OB_ALL_CLONE_JOB_TNAME, OB_ALL_CLONE_JOB_HISTORY_TNAME}; + ObSqlString sql; + bool find = false; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant clone table operator not init", KR(ret)); + } else if (OB_UNLIKELY(job_id < 0 + || !is_sys_tenant(tenant_id_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id), K(tenant_id_)); + } else { + for (int32_t i = 0; !find && OB_SUCC(ret) && i < table_num; i++) { + sql.reset(); + if (OB_FAIL(sql.assign_fmt("SELECT error_msg FROM %.*s WHERE job_id = %ld", + tables[i].length(), tables[i].ptr(), job_id))) { + LOG_WARN("assign sql failed", KR(ret), K(job_id)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(tenant_id_), sql.ptr()))) { + LOG_WARN("failed to execute sql", KR(ret), K(gen_meta_tenant_id(tenant_id_)), K(sql)); + } else if (NULL == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next result", KR(ret)); + } else { + ret = OB_SUCCESS; + } + } else { + find = true; + ObString tmp_msg; + EXTRACT_VARCHAR_FIELD_MYSQL_WITH_DEFAULT_VALUE(*result, "error_msg", tmp_msg, + true /*skip_null_error*/, + false /*skip_column_error*/, + "" /*default_value*/); + if (FAILEDx(deep_copy_ob_string(allocator, tmp_msg, err_msg))) { + LOG_WARN("error_msg deep copy failed", KR(ret), K(tmp_msg)); + } + } + } // end SMART_VAR + } + } // end for + + if (OB_SUCC(ret) && !find) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("the job doesn't exist", KR(ret), K(job_id)); + } + } + return ret; +} + +//job num <= 1 in a certain tenant +int ObTenantCloneTableOperator::read_only_exist_one_job_( + const ObSqlString &sql, + ObCloneJob &job) +{ + int ret = OB_SUCCESS; + job.reset(); + ObArray jobs; + if (OB_UNLIKELY(sql.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(sql)); + } else if (OB_FAIL(read_jobs_(sql, jobs))) { + LOG_WARN("fail to read jobs", KR(ret), K(sql)); + } else if (jobs.empty()) { + ret = OB_ENTRY_NOT_EXIST; + LOG_INFO("clone job not exist", KR(ret)); + } else if (jobs.count() > 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected clone job count", KR(ret), K(jobs)); + } else if (OB_FAIL(job.assign(jobs.at(0)))) { + LOG_WARN("assign failed", KR(ret), K(jobs)); + } else if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid job", KR(ret), K(job)); + } + return ret; +} + +int ObTenantCloneTableOperator::read_jobs_( + const ObSqlString &sql, + ObArray &jobs) +{ + int ret = OB_SUCCESS; + jobs.reset(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_UNLIKELY(sql.empty() || OB_ISNULL(proxy_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(sql), KP(proxy_)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(tenant_id_), sql.ptr()))) { + LOG_WARN("failed to execute sql", KR(ret), K(gen_meta_tenant_id(tenant_id_)), K(sql)); + } else if (NULL == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else { + while (OB_SUCC(ret) && OB_SUCC(result->next())) { + ObCloneJob job; + if (OB_FAIL(fill_job_from_result_(result, job))) { + LOG_WARN("fill job from result failed", KR(ret)); + } else if (OB_FAIL(jobs.push_back(job))) { + LOG_WARN("fail to push back job", KR(ret), K(job)); + } + } + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next result", KR(ret)); + } else { + ret = OB_SUCCESS; + } + } + } + } + return ret; +} + +int ObTenantCloneTableOperator::build_insert_dml_( + const ObCloneJob &job, + ObDMLSqlSplicer &dml) +{ + int ret = OB_SUCCESS; + char trace_id_buf[OB_MAX_TRACE_ID_BUFFER_SIZE] = {'\0'}; + + if (OB_UNLIKELY(!job.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", job.get_tenant_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("job_id", job.get_job_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (FALSE_IT(job.get_trace_id().to_string(trace_id_buf, sizeof(trace_id_buf)))) { + } else if (OB_FAIL(dml.add_column("trace_id", trace_id_buf))) { + LOG_WARN("add column failed", KR(ret), K(trace_id_buf)); + } else if (OB_FAIL(dml.add_column("source_tenant_id", job.get_source_tenant_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("source_tenant_name", job.get_source_tenant_name()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("clone_tenant_name", job.get_clone_tenant_name()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("clone_tenant_id", job.get_clone_tenant_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("tenant_snapshot_id", job.get_tenant_snapshot_id().id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("tenant_snapshot_name", job.get_tenant_snapshot_name().empty() ? + "" : + job.get_tenant_snapshot_name()))) { + LOG_WARN("add column failed", K(ret)); + } else if (OB_FAIL(dml.add_column("resource_pool_id", job.get_resource_pool_id()))) { + LOG_WARN("add column failed", K(ret)); + } else if (OB_FAIL(dml.add_column("resource_pool_name", job.get_resource_pool_name()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("unit_config_name", job.get_unit_config_name()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("restore_scn", job.get_restore_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("status", ObTenantCloneStatus::get_clone_status_str(job.get_status())))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("job_type", get_job_type_str(job.get_job_type())))) { + LOG_WARN("add column failed", K(ret)); + } + + return ret; +} + +int ObTenantCloneTableOperator::fill_job_from_result_(const ObMySQLResult *result, + ObCloneJob &job) +{ + int ret = OB_SUCCESS; + int64_t real_length = 0; + common::ObCurTraceId::TraceId trace_id; + char trace_id_buf[OB_MAX_TRACE_ID_BUFFER_SIZE] = {'\0'}; + uint64_t tenant_id = OB_INVALID_TENANT_ID; + int64_t job_id = OB_INVALID_ID; + uint64_t source_tenant_id = OB_INVALID_TENANT_ID; + ObString clone_tenant_name; + ObString source_tenant_name; + uint64_t clone_tenant_id = OB_INVALID_TENANT_ID; + ObTenantSnapshotID tenant_snapshot_id; + ObString tenant_snapshot_name; + uint64_t resource_pool_id; + ObString resource_pool_name; + ObString unit_config_name; + uint64_t restore_scn_val = OB_INVALID_SCN_VAL; + SCN restore_scn; + ObString status_str; + ObString job_type_str; + int ret_code = OB_SUCCESS; + EXTRACT_INT_FIELD_MYSQL(*result, "tenant_id", tenant_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "job_id", job_id, int64_t); + EXTRACT_STRBUF_FIELD_MYSQL(*result, "trace_id", trace_id_buf, sizeof(trace_id_buf), real_length); + EXTRACT_INT_FIELD_MYSQL(*result, "source_tenant_id", source_tenant_id, uint64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "source_tenant_name", source_tenant_name); + EXTRACT_INT_FIELD_MYSQL(*result, "clone_tenant_id", clone_tenant_id, uint64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "clone_tenant_name", clone_tenant_name); + EXTRACT_INT_FIELD_MYSQL(*result, "tenant_snapshot_id", tenant_snapshot_id, int64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "tenant_snapshot_name", tenant_snapshot_name); + EXTRACT_INT_FIELD_MYSQL(*result, "resource_pool_id", resource_pool_id, uint64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "resource_pool_name", resource_pool_name); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "unit_config_name", unit_config_name); + EXTRACT_UINT_FIELD_MYSQL(*result, "restore_scn", restore_scn_val, uint64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "status", status_str); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "job_type", job_type_str); + EXTRACT_INT_FIELD_MYSQL_SKIP_RET(*result, "ret_code", ret_code, int); + if (OB_SUCC(ret)) { + if (OB_FAIL(trace_id.parse_from_buf(trace_id_buf))) { + LOG_WARN("fail to parse trace id from buf", KR(ret), K(trace_id_buf)); + } else if (OB_INVALID_SCN_VAL != restore_scn_val + && OB_FAIL(restore_scn.convert_for_inner_table_field(restore_scn_val))) { + LOG_WARN("fail to convert_for_inner_table_field", KR(ret), K(restore_scn_val)); + } else { + const ObCloneJob::ObCloneJobInitArg init_arg = { + .trace_id_ = trace_id, + .tenant_id_ = tenant_id, + .job_id_ = job_id, + .source_tenant_id_ = source_tenant_id, + .source_tenant_name_ = source_tenant_name, + .clone_tenant_id_ = clone_tenant_id, + .clone_tenant_name_ = clone_tenant_name, + .tenant_snapshot_id_ = tenant_snapshot_id, + .tenant_snapshot_name_ = tenant_snapshot_name, + .resource_pool_id_ = resource_pool_id, + .resource_pool_name_ = resource_pool_name, + .unit_config_name_ = unit_config_name, + .restore_scn_ = restore_scn, + .status_ = ObTenantCloneStatus::get_clone_status(status_str), + .job_type_ = get_job_type(job_type_str), + .ret_code_ = ret_code, + }; + if (OB_FAIL(job.init(init_arg))) { + LOG_WARN("fail to init clone job", KR(ret), K(init_arg)); + } + } + } + return ret; +} diff --git a/src/share/restore/ob_tenant_clone_table_operator.h b/src/share/restore/ob_tenant_clone_table_operator.h new file mode 100644 index 0000000000..48f473fbbf --- /dev/null +++ b/src/share/restore/ob_tenant_clone_table_operator.h @@ -0,0 +1,269 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_SHARE_OB_TENANT_CLONE_TABLE_OPERATOR_H_ +#define OCEANBASE_SHARE_OB_TENANT_CLONE_TABLE_OPERATOR_H_ + +#include "lib/mysqlclient/ob_mysql_proxy.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" +#include "src/share/scn.h" + +namespace oceanbase +{ +namespace share +{ +class ObDMLSqlSplicer; +class TenantCloneStatusStrPair; + +class ObTenantCloneStatus +{ +public: + enum class Status : int64_t + { + // Attention!!! + // If you want to add new status, please be sure to add the corresponding string + // in ObTenantCloneStatus::TENANT_CLONE_STATUS_ARRAY[] + CLONE_SYS_LOCK = 0, + CLONE_SYS_CREATE_INNER_RESOURCE_POOL, + CLONE_SYS_CREATE_SNAPSHOT, // only for fork tenant job + CLONE_SYS_WAIT_CREATE_SNAPSHOT, // only for fork tenant job + CLONE_SYS_CREATE_TENANT, + CLONE_SYS_WAIT_TENANT_RESTORE_FINISH, + CLONE_SYS_RELEASE_RESOURCE, + + CLONE_USER_PREPARE = 50, + CLONE_USER_CREATE_INIT_LS, + CLONE_USER_WAIT_LS, + CLONE_USER_POST_CHECK, + + CLONE_USER_SUCCESS = 100, + CLONE_USER_FAIL, + + CLONE_SYS_SUCCESS = 150, + CLONE_SYS_LOCK_FAIL, + CLONE_SYS_CREATE_INNER_RESOURCE_POOL_FAIL, + CLONE_SYS_CREATE_SNAPSHOT_FAIL, + CLONE_SYS_WAIT_CREATE_SNAPSHOT_FAIL, + CLONE_SYS_CREATE_TENANT_FAIL, + CLONE_SYS_WAIT_TENANT_RESTORE_FINISH_FAIL, + CLONE_SYS_RELEASE_RESOURCE_FAIL, + //This status corresponds to the user's command to cancel cloning job + CLONE_SYS_CANCELED, + CLONE_MAX_STATUS = 200 + }; + +private: + struct TenantCloneStatusStrPair + { + TenantCloneStatusStrPair(ObTenantCloneStatus::Status status, const char *str) : status_(status), str_(str) {} + ObTenantCloneStatus::Status status_; + const char *str_; + }; + static const TenantCloneStatusStrPair TENANT_CLONE_STATUS_ARRAY[]; + +public: + ObTenantCloneStatus() : status_(Status::CLONE_MAX_STATUS) {} + ~ObTenantCloneStatus() {}; + explicit ObTenantCloneStatus(const Status &status): status_(status) {} + ObTenantCloneStatus &operator=(const ObTenantCloneStatus &status); + ObTenantCloneStatus &operator=(const Status &status); + bool operator ==(const ObTenantCloneStatus &other) const { return status_ == other.status_; } + bool operator !=(const ObTenantCloneStatus &other) const { return status_ != other.status_; } + operator Status() const { return status_; } + static const char *get_clone_status_str(const Status &status); + static ObTenantCloneStatus get_clone_status(const ObString &status_str); + Status get_status() const { return status_; } + bool is_valid() const { return status_ != Status::CLONE_MAX_STATUS; } + void reset() {status_ = Status::CLONE_MAX_STATUS; } + bool is_user_status() const; + bool is_user_success_status() const; + bool is_sys_status() const; + bool is_sys_canceled_status() const; + bool is_sys_failed_status() const; + bool is_sys_success_status() const; + bool is_sys_processing_status() const; + bool is_sys_valid_snapshot_status_for_fork() const; + bool is_sys_release_resource_status() const; + + TO_STRING_KV(K_(status)); + +private: + Status status_; +}; + +enum class ObTenantCloneJobType : int64_t +{ + RESTORE = 0, + FORK = 1, + CLONE_JOB_MAX_TYPE = 200 +}; + +struct TenantCloneJobTypeStrPair +{ + TenantCloneJobTypeStrPair(ObTenantCloneJobType type, const char *str) : type_(type), str_(str) {} + ObTenantCloneJobType type_; + const char *str_; +}; + +struct ObCloneJob { +public: + ObCloneJob(); +public: + const common::ObCurTraceId::TraceId &get_trace_id() const { return trace_id_; } + uint64_t get_tenant_id() const { return tenant_id_; } + void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } + int64_t get_job_id() const { return job_id_; } + uint64_t get_source_tenant_id() const { return source_tenant_id_; } + const ObString &get_source_tenant_name() const { return source_tenant_name_; } + uint64_t get_clone_tenant_id() const { return clone_tenant_id_; } + const ObString &get_clone_tenant_name() const { return clone_tenant_name_; } + void set_clone_tenant_id(const uint64_t clone_tenant_id) { clone_tenant_id_ = clone_tenant_id; } + const ObTenantSnapshotID &get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + const ObString &get_tenant_snapshot_name() const { return tenant_snapshot_name_; } + uint64_t get_resource_pool_id() const { return resource_pool_id_; } + const ObString &get_resource_pool_name() const { return resource_pool_name_; } + const ObString &get_unit_config_name() const { return unit_config_name_; } + const SCN &get_restore_scn() const { return restore_scn_; } + const ObTenantCloneStatus &get_status() const { return status_; } + const ObTenantCloneJobType &get_job_type() const { return job_type_; } + void set_status(const ObTenantCloneStatus::Status &status) { status_ = status; } + int get_ret_code() const { return ret_code_; } + + struct ObCloneJobInitArg + { + common::ObCurTraceId::TraceId trace_id_; + uint64_t tenant_id_; + int64_t job_id_; + uint64_t source_tenant_id_; + ObString source_tenant_name_; + uint64_t clone_tenant_id_; //new cloned user_tenant_id + ObString clone_tenant_name_; + ObTenantSnapshotID tenant_snapshot_id_; + ObString tenant_snapshot_name_; + uint64_t resource_pool_id_; + ObString resource_pool_name_; + ObString unit_config_name_; + SCN restore_scn_; + ObTenantCloneStatus status_; + ObTenantCloneJobType job_type_; + int ret_code_; + TO_STRING_KV(K_(trace_id), K_(tenant_id), K_(job_id), + K_(source_tenant_id), K_(source_tenant_name), + K_(clone_tenant_id), K_(clone_tenant_name), + K_(tenant_snapshot_id), K_(tenant_snapshot_name), + K_(resource_pool_id), K_(resource_pool_name), + K_(unit_config_name), K_(restore_scn), + K_(status), K_(job_type), K_(ret_code)); + }; + int init(const ObCloneJobInitArg &init_arg); + int assign(const ObCloneJob &other); + void reset(); + bool is_valid() const; + bool is_valid_status_allows_user_tenant_to_do_ls_recovery() const; + TO_STRING_KV(K_(trace_id), K_(tenant_id), K_(job_id), + K_(source_tenant_id), K_(source_tenant_name), + K_(clone_tenant_id), K_(clone_tenant_name), + K_(tenant_snapshot_id), K_(tenant_snapshot_name), + K_(resource_pool_id), K_(resource_pool_name), + K_(unit_config_name), K_(restore_scn), + K_(status), K_(job_type), K_(ret_code)); +private: + common::ObCurTraceId::TraceId trace_id_; + //in sys tenant space, tenant_id_ is OB_SYS_TENANT_ID + //in user tenant space, tenant_id_ is new cloned user_tenant_id + uint64_t tenant_id_; + int64_t job_id_; + uint64_t source_tenant_id_; + ObString source_tenant_name_; + uint64_t clone_tenant_id_; //new cloned user_tenant_id + ObString clone_tenant_name_; + ObTenantSnapshotID tenant_snapshot_id_; + ObString tenant_snapshot_name_; + uint64_t resource_pool_id_; + ObString resource_pool_name_; + ObString unit_config_name_; + SCN restore_scn_; + ObTenantCloneStatus status_; + ObTenantCloneJobType job_type_; + int ret_code_; + ObArenaAllocator allocator_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObCloneJob); +}; + +class ObTenantCloneTableOperator +{ +public: + ObTenantCloneTableOperator(); + + int init(const uint64_t user_tenant_id, ObISQLClient *proxy); + //get clone job according to source_tenant_id + //a source tenant only has one clone_job in OB_ALL_CLONE_JOB_TNAME + int get_clone_job_by_source_tenant_id(const uint64_t source_tenant_id, + ObCloneJob &job); + int get_clone_job_by_job_id(const int64_t job_id, ObCloneJob &job); + //get clone job according to clone_tenant_name + int get_clone_job_by_clone_tenant_name(const ObString &clone_tenant_name, + const bool need_lock, + ObCloneJob &job); + int get_all_clone_jobs(ObArray &jobs); + int insert_clone_job(const ObCloneJob &job); + int update_job_status(const int64_t job_id, + const ObTenantCloneStatus &old_status, + const ObTenantCloneStatus &new_status); + int update_job_failed_info(const int64_t job_id, const int ret_code, const ObString& err_msg); + int update_job_resource_pool_id(const int64_t job_id, const uint64_t resource_pool_id); + int update_job_clone_tenant_id(const int64_t job_id, + const uint64_t clone_tenant_id); + int update_job_snapshot_info(const int64_t job_id, + const ObTenantSnapshotID snapshot_id, + const ObString &snapshot_name); + int update_job_snapshot_scn(const int64_t job_id, + const SCN &restore_scn); + int remove_clone_job(const ObCloneJob &job); + int insert_clone_job_history(const ObCloneJob &job); + //get user clone job history + int get_user_clone_job_history(ObCloneJob &job); + //get clone job history according to job_id + int get_sys_clone_job_history(const int64_t job_id, + ObCloneJob &job); + int get_job_failed_message(const int64_t job_id, ObIAllocator &allocator, ObString &err_msg); + +public: + static const char* get_job_type_str(ObTenantCloneJobType job_type); + static ObTenantCloneJobType get_job_type(const ObString &str); +private: + //job num <= 1 in a certain tenant + int read_only_exist_one_job_(const ObSqlString &sql, + ObCloneJob &job); + int read_jobs_(const ObSqlString &sql, + ObArray &jobs); + int build_insert_dml_(const ObCloneJob &job, + ObDMLSqlSplicer &dml); + int fill_job_from_result_(const common::sqlclient::ObMySQLResult *result, + ObCloneJob &job); +private: + static const TenantCloneJobTypeStrPair TENANT_CLONE_JOB_TYPE_ARRAY[]; +private: + bool is_inited_; + uint64_t tenant_id_; + ObISQLClient *proxy_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantCloneTableOperator); + +}; + +} +} + +#endif /* OCEANBASE_SHARE_OB_TENANT_CLONE_TABLE_OPERATOR_H_ */ diff --git a/src/share/scheduler/ob_dag_scheduler_config.h b/src/share/scheduler/ob_dag_scheduler_config.h index 001e07dec0..c39f0490ac 100644 --- a/src/share/scheduler/ob_dag_scheduler_config.h +++ b/src/share/scheduler/ob_dag_scheduler_config.h @@ -165,9 +165,12 @@ DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TRANSFER_BACKFILL_TX, ObDagPrio::DAG_PRIO_HA DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TRANSFER_REPLACE_TABLE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::TRANSFER_TASK, "TRANSFER_REPLACE_TABLE", "TRANSFER", true, 2, {"tenant_id", "desc_ls_id"}) // DAG_TYPE_TRANSFER END - DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TTL, ObDagPrio::DAG_PRIO_TTL, ObSysTaskType::TABLE_API_TTL_TASK, "TTL_DELTE_DAG", "TTL", false, 4, {"tenant_id", "ls_id", "table_id", "tablet_id"}) +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TENANT_SNAPSHOT_CREATE, ObDagPrio::DAG_PRIO_HA_MID, ObSysTaskType::TENANT_SNAPSHOT_CREATE_TASK, "TENANT_SNAPSHOT_CREATE", "TSNAP_CR8", + false, 1, {"tsnap_id"}) +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TENANT_SNAPSHOT_GC, ObDagPrio::DAG_PRIO_HA_LOW, ObSysTaskType::TENANT_SNAPSHOT_GC_TASK, "TENANT_SNAPSHOT_GC","TSNAP_GC", + false, 1, {"tsnap_id"}) DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MAX, ObDagPrio::DAG_PRIO_MAX, ObSysTaskType::MAX_SYS_TASK_TYPE, "DAG_TYPE_MAX", "INVALID", false, 0, {}) #endif diff --git a/src/share/scheduler/ob_sys_task_stat.cpp b/src/share/scheduler/ob_sys_task_stat.cpp index 81bc470314..aec91ce0f8 100644 --- a/src/share/scheduler/ob_sys_task_stat.cpp +++ b/src/share/scheduler/ob_sys_task_stat.cpp @@ -38,7 +38,9 @@ const static char *ObSysTaskTypeStr[] = { "REMOVE_MEMBER", "TRANSFER", "MDS_TABLE_MERGE", - "TTL_TASK" + "TTL_TASK", + "TENANT_SNAPSHOT_CREATE", + "TENANT_SNAPSHOT_GC" }; const char *sys_task_type_to_str(const ObSysTaskType &type) diff --git a/src/share/scheduler/ob_sys_task_stat.h b/src/share/scheduler/ob_sys_task_stat.h index 327e86efa5..b8329bc6e3 100644 --- a/src/share/scheduler/ob_sys_task_stat.h +++ b/src/share/scheduler/ob_sys_task_stat.h @@ -52,6 +52,8 @@ enum ObSysTaskType TRANSFER_TASK, MDS_TABLE_MERGE_TASK, TABLE_API_TTL_TASK, + TENANT_SNAPSHOT_CREATE_TASK, + TENANT_SNAPSHOT_GC_TASK, MAX_SYS_TASK_TYPE }; diff --git a/src/share/scheduler/ob_tenant_dag_scheduler.h b/src/share/scheduler/ob_tenant_dag_scheduler.h index 08ac523efc..da3097ce2e 100644 --- a/src/share/scheduler/ob_tenant_dag_scheduler.h +++ b/src/share/scheduler/ob_tenant_dag_scheduler.h @@ -208,6 +208,8 @@ public: TASK_TYPE_TRANSFER_REPLACE_TABLE = 52, TASK_TYPE_MDS_TABLE_MERGE = 53, TASK_TYPE_TTL_DELETE = 54, + TASK_TYPE_TENANT_SNAPSHOT_CREATE = 55, + TASK_TYPE_TENANT_SNAPSHOT_GC = 56, TASK_TYPE_MAX, }; diff --git a/src/share/tenant_snapshot/ob_tenant_snapshot_id.cpp b/src/share/tenant_snapshot/ob_tenant_snapshot_id.cpp new file mode 100644 index 0000000000..79779542a2 --- /dev/null +++ b/src/share/tenant_snapshot/ob_tenant_snapshot_id.cpp @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE +#include "lib/oblog/ob_log_module.h" // LOG_* +#include "lib/oblog/ob_log.h" // LOG_* +#include "lib/utility/ob_unify_serialize.h" +#include "lib/utility/serialization.h" +#include "share/ob_errno.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" + +namespace oceanbase +{ +using namespace common; +namespace share +{ + +int ObTenantSnapshotID::serialize(char* buf, const int64_t buf_len, int64_t& pos) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(serialization::encode_i64(buf, buf_len, pos, id_))) { + LOG_WARN("serialize tenant snapshot id failed", KR(ret), KP(buf), K(buf_len), K(pos)); + } + return ret; +} + +int ObTenantSnapshotID::deserialize(const char* buf, const int64_t data_len, int64_t& pos) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(buf) || OB_UNLIKELY(data_len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", KR(ret), KP(buf), K(data_len)); + } else if (OB_FAIL(serialization::decode_i64(buf, data_len, pos, &id_))) { + LOG_WARN("deserialize tenant snapshot id failed", KR(ret), KP(buf), K(data_len), K(pos)); + } + return ret; +} + +int64_t ObTenantSnapshotID::get_serialize_size() const +{ + int64_t size = 0; + size += serialization::encoded_length_i64(id_); + return size; +} + +} // end namespace share +} // end namespace oceanbase diff --git a/src/share/tenant_snapshot/ob_tenant_snapshot_id.h b/src/share/tenant_snapshot/ob_tenant_snapshot_id.h new file mode 100644 index 0000000000..db300497c7 --- /dev/null +++ b/src/share/tenant_snapshot/ob_tenant_snapshot_id.h @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2021 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. + */ + + +#ifndef OCEANBASE_SHARE_OB_TENANT_SNAPSHOT_ID_H_ +#define OCEANBASE_SHARE_OB_TENANT_SNAPSHOT_ID_H_ + +#include +#include "lib/utility/ob_print_utils.h" // TO_STRING_KV + +namespace oceanbase +{ +namespace share +{ +class ObTenantSnapshotID final +{ +public: + static const int64_t OB_INVALID_SNAPSHOT_ID = -1; + +public: + ObTenantSnapshotID() : id_(OB_INVALID_SNAPSHOT_ID) {} + ObTenantSnapshotID(const ObTenantSnapshotID &other) : id_(other.id_) {} + explicit ObTenantSnapshotID(const int64_t id) : id_(id) {} + ~ObTenantSnapshotID() { reset(); } + +public: + int64_t id() const { return id_; } + void reset() { id_ = OB_INVALID_SNAPSHOT_ID; } + bool is_valid() const { return id_ != OB_INVALID_SNAPSHOT_ID; } + // assignment + ObTenantSnapshotID &operator=(const int64_t id) { id_ = id; return *this; } + ObTenantSnapshotID &operator=(const ObTenantSnapshotID &other) { id_ = other.id_; return *this; } + + // compare operator + bool operator == (const ObTenantSnapshotID &other) const { return id_ == other.id_; } + bool operator > (const ObTenantSnapshotID &other) const { return id_ > other.id_; } + bool operator != (const ObTenantSnapshotID &other) const { return id_ != other.id_; } + bool operator < (const ObTenantSnapshotID &other) const { return id_ < other.id_; } + int compare(const ObTenantSnapshotID &other) const + { + if (id_ == other.id_) { + return 0; + } else if (id_ < other.id_) { + return -1; + } else { + return 1; + } + } + + uint64_t hash() const + { + OB_ASSERT(id_ != UINT64_MAX); + return id_; + } + + int hash(uint64_t &hash_val) const + { + int ret = OB_SUCCESS; + hash_val = hash(); + return ret; + } + + NEED_SERIALIZE_AND_DESERIALIZE; + TO_STRING_KV(K_(id)); + +private: + int64_t id_; +}; + +} // end namespace share +} // end namespace oceanbase + +#endif //OCEANBASE_SHARE_OB_TENANT_SNAPSHOT_ID_H_ diff --git a/src/share/tenant_snapshot/ob_tenant_snapshot_table_operator.cpp b/src/share/tenant_snapshot/ob_tenant_snapshot_table_operator.cpp new file mode 100644 index 0000000000..1a192220ae --- /dev/null +++ b/src/share/tenant_snapshot/ob_tenant_snapshot_table_operator.cpp @@ -0,0 +1,2034 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SHARE +#include "ob_tenant_snapshot_table_operator.h" +#include "lib/string/ob_hex_utils_base.h" + +using namespace oceanbase::share; +using namespace oceanbase::common; +using namespace oceanbase::common::sqlclient; + +int ObCreateSnapshotJob::init(const int64_t create_active_ts, + const int64_t create_expire_ts, + const int64_t paxos_replica_num, + const ObArbitrationServiceStatus &arbitration_service_status, + const ObTenantSnapJobItem& job_item) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_TIMESTAMP == create_active_ts + || OB_INVALID_TIMESTAMP == create_expire_ts + || OB_INVALID_COUNT == paxos_replica_num + || !arbitration_service_status.is_valid() + || !job_item.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(create_active_ts), + K(create_expire_ts), K(paxos_replica_num), + K(arbitration_service_status), K(job_item)); + } else if (OB_FAIL(job_item_.assign(job_item))) { + LOG_WARN("fail to assign create job item", KR(ret), K(job_item)); + } else { + create_active_ts_ = create_active_ts; + create_expire_ts_ = create_expire_ts; + paxos_replica_num_ = paxos_replica_num; + arbitration_service_status_ = arbitration_service_status; + } + return ret; +} + +void ObCreateSnapshotJob::reset() +{ + job_item_.reset(); + create_active_ts_ = 0; + create_expire_ts_ = INT64_MAX; + paxos_replica_num_ = 0; + arbitration_service_status_.reset(); +} + +int ObCreateSnapshotJob::assign(const ObCreateSnapshotJob& other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("assign to itself", KR(ret), K(other)); + } else if (OB_FAIL(job_item_.assign(other.job_item_))) { + LOG_WARN("fail to assign job", KR(ret), K(other)); + } else { + create_active_ts_ = other.create_active_ts_; + create_expire_ts_ = other.create_expire_ts_; + paxos_replica_num_ = other.paxos_replica_num_; + arbitration_service_status_ = other.arbitration_service_status_; + } + + return ret; +} + +int ObDeleteSnapshotJob::init(const ObTenantSnapJobItem& job_item) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!job_item.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_item)); + } else if (OB_FAIL(job_item_.assign(job_item))) { + LOG_WARN("fail to assign job", KR(ret), K(job_item)); + } + + return ret; +} + +void ObDeleteSnapshotJob::reset() +{ + job_item_.reset(); +} + +int ObDeleteSnapshotJob::assign(const ObDeleteSnapshotJob& other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("assign to itself", KR(ret), K(other)); + } else if (OB_FAIL(job_item_.assign(other.job_item_))) { + LOG_WARN("fail to assign job", KR(ret), K(other)); + } + + return ret; +} + +ObTenantSnapItem::ObTenantSnapItem() : + tenant_id_(OB_INVALID_TENANT_ID), + tenant_snapshot_id_(), + status_(ObTenantSnapStatus::MAX), + snapshot_scn_(), + clog_start_scn_(), + type_(ObTenantSnapType::MAX), + create_time_(OB_INVALID_TIMESTAMP), + data_version_(0), + owner_job_id_(OB_INVALID_ID) +{ + snapshot_name_[0] = '\0'; +} + +int ObTenantSnapItem::init(const uint64_t tenant_id, + const ObTenantSnapshotID &snapshot_id, + const ObString &snapshot_name, + const ObTenantSnapStatus &status, + const SCN &snapshot_scn, + const SCN &clog_start_scn, + const ObTenantSnapType &type, + const int64_t create_time, + const uint64_t data_version, + const int64_t owner_job_id) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !snapshot_id.is_valid() + || snapshot_name.empty() + || ObTenantSnapStatus::MAX == status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(snapshot_id), K(snapshot_name), K(status)); + } else if (OB_FAIL(databuff_printf(snapshot_name_, sizeof(snapshot_name_), pos, "%.*s", + snapshot_name.length(), snapshot_name.ptr()))) { + LOG_WARN("snapshot_name assign failed", K(snapshot_name)); + } else { + tenant_id_ = tenant_id; + tenant_snapshot_id_ = snapshot_id; + status_ = status; + snapshot_scn_ = snapshot_scn; + clog_start_scn_ = clog_start_scn; + type_ = type; + create_time_ = create_time; + data_version_ = data_version; + owner_job_id_ = owner_job_id; + } + return ret; +} + + +int ObTenantSnapItem::assign(const ObTenantSnapItem &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(databuff_printf(snapshot_name_, sizeof(snapshot_name_), "%s", other.snapshot_name_))) { + LOG_WARN("snapshot_name assign failed", K(other.snapshot_name_)); + } else { + tenant_id_ = other.tenant_id_; + tenant_snapshot_id_ = other.tenant_snapshot_id_; + status_ = other.status_; + snapshot_scn_ = other.snapshot_scn_; + clog_start_scn_ = other.clog_start_scn_; + type_ = other.type_; + create_time_ = other.create_time_; + data_version_ = other.data_version_; + owner_job_id_ = other.owner_job_id_; + } + return ret; +} + +void ObTenantSnapItem::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + tenant_snapshot_id_.reset(); + snapshot_name_[0] = '\0'; + status_ = ObTenantSnapStatus::MAX; + snapshot_scn_.reset(); + clog_start_scn_.reset(); + type_ = ObTenantSnapType::MAX; + create_time_ = OB_INVALID_TIMESTAMP; + data_version_ = 0; + owner_job_id_ = OB_INVALID_ID; +} + +int ObTenantSnapLSItem::init(const uint64_t tenant_id, + const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSAttr &ls_attr) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !tenant_snapshot_id.is_valid() + || !ls_attr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_snapshot_id), K(ls_attr)); + } else if (OB_FAIL(ls_attr_.assign(ls_attr))) { + LOG_WARN("assign failed", KR(ret), K(ls_attr)); + } else { + tenant_id_ = tenant_id; + tenant_snapshot_id_ = tenant_snapshot_id; + } + return ret; +} + +int ObTenantSnapLSItem::assign(const ObTenantSnapLSItem &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ls_attr_.assign(other.ls_attr_))) { + LOG_WARN("assign failed", KR(ret), K(other)); + } else { + tenant_id_ = other.tenant_id_; + tenant_snapshot_id_ = other.tenant_snapshot_id_; + } + return ret; +} + +void ObTenantSnapLSItem::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + tenant_snapshot_id_.reset(); + ls_attr_.reset(); +} + +ObTenantSnapLSReplicaSimpleItem::ObTenantSnapLSReplicaSimpleItem() : + tenant_id_(OB_INVALID_TENANT_ID), + tenant_snapshot_id_(), + ls_id_(), + addr_(), + status_(ObLSSnapStatus::MAX), + zone_(), + unit_id_(OB_INVALID_ID), + begin_interval_scn_(), + end_interval_scn_() +{ +} + +int ObTenantSnapLSReplicaSimpleItem::init(const uint64_t tenant_id, + const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + const common::ObAddr &addr, + const ObLSSnapStatus &status, + const ObZone &zone, + const uint64_t unit_id, + const SCN &begin_interval_scn, + const SCN &end_interval_scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !tenant_snapshot_id.is_valid() + || !ls_id.is_valid()) + || !addr.is_valid() + || ObLSSnapStatus::MAX == status + || zone.is_empty() + || OB_INVALID_ID == unit_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(tenant_snapshot_id), K(ls_id), + K(addr), K(status), K(zone), K(unit_id)); + } else if (OB_FAIL(zone_.assign(zone))) { + LOG_WARN("zone assign failed", K(zone)); + } else { + tenant_id_ = tenant_id; + tenant_snapshot_id_ = tenant_snapshot_id; + ls_id_ = ls_id; + addr_ = addr; + status_ = status; + unit_id_ = unit_id; + begin_interval_scn_ = begin_interval_scn; + end_interval_scn_ = end_interval_scn; + } + return ret; +} + +int ObTenantSnapLSReplicaSimpleItem::assign(const ObTenantSnapLSReplicaSimpleItem &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(zone_.assign(other.zone_))) { + LOG_WARN("zone assign failed", K(other.zone_)); + } else { + tenant_id_ = other.tenant_id_; + tenant_snapshot_id_ = other.tenant_snapshot_id_; + ls_id_ = other.ls_id_; + addr_ = other.addr_; + status_ = other.status_; + unit_id_ = other.unit_id_; + begin_interval_scn_ = other.begin_interval_scn_; + end_interval_scn_ = other.end_interval_scn_; + } + return ret; +} + +void ObTenantSnapLSReplicaSimpleItem::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + tenant_snapshot_id_.reset(); + ls_id_.reset(); + addr_.reset(); + status_ = ObLSSnapStatus::MAX; + zone_.reset(); + unit_id_ = OB_INVALID_ID; + begin_interval_scn_.reset(); + end_interval_scn_.reset(); +} + +int ObTenantSnapLSReplicaItem::assign(const ObTenantSnapLSReplicaItem &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(s_.assign(other.s_))) { + LOG_WARN("simple item assign failed", K(other.s_)); + } else { + ls_meta_package_ = other.ls_meta_package_; + } + return ret; +} + +int ObTenantSnapJobItem::assign(const ObTenantSnapJobItem &other) +{ + int ret = OB_SUCCESS; + if (this == &other) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("assign to itself", KR(ret), K(other)); + } else if (!other.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(other)); + } else { + tenant_id_ = other.tenant_id_; + tenant_snapshot_id_ = other.tenant_snapshot_id_; + operation_ = other.operation_; + trace_id_ = other.trace_id_; + majority_succ_time_ = other.majority_succ_time_; + } + return ret; +} + +bool ObTenantSnapJobItem::is_valid() const +{ + return tenant_id_ != OB_INVALID_TENANT_ID && + tenant_snapshot_id_.is_valid() && + operation_ != ObTenantSnapOperation::MAX && + trace_id_.is_valid(); +} + +void ObTenantSnapJobItem::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + tenant_snapshot_id_.reset(); + operation_ = ObTenantSnapOperation::MAX; + trace_id_.reset(); + majority_succ_time_ = OB_INVALID_TIMESTAMP; +} + +const char* ObTenantSnapshotTableOperator::TENANT_SNAP_STATUS_ARRAY[] = +{ + "CREATING", + "DECIDED", + "NORMAL", + "RESTORING", + "DELETING", + "FAILED", +}; + +const char* ObTenantSnapshotTableOperator::LS_SNAP_STATUS_ARRAY[] = +{ + "CREATING", + "NORMAL", + "RESTORING", + "FAILED", +}; + +const char* ObTenantSnapshotTableOperator::TENANT_SNAP_TYPE_ARRAY[] = +{ + "AUTO", + "MANUAL", +}; + +const char* ObTenantSnapshotTableOperator::TENANT_SNAP_OPERATION_ARRAY[] = +{ + "CREATE", + "DELETE", +}; + +ObTenantSnapStatus ObTenantSnapshotTableOperator::str_to_tenant_snap_status(const ObString &status_str) +{ + ObTenantSnapStatus ret_status = ObTenantSnapStatus::MAX; + if (status_str.empty()) { + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(TENANT_SNAP_STATUS_ARRAY); i++) { + if (0 == status_str.case_compare(TENANT_SNAP_STATUS_ARRAY[i])) { + ret_status = static_cast(i); + break; + } + } + } + return ret_status; +} + +const char* ObTenantSnapshotTableOperator::tenant_snap_status_to_str(const ObTenantSnapStatus &status) +{ + STATIC_ASSERT(ARRAYSIZEOF(TENANT_SNAP_STATUS_ARRAY) == static_cast(ObTenantSnapStatus::MAX), + "type string array size mismatch with enum tenant snapshot status count"); + const char* str = INVALID_STR; + if (status >= ObTenantSnapStatus::CREATING && status < ObTenantSnapStatus::MAX) { + str = TENANT_SNAP_STATUS_ARRAY[static_cast(status)]; + } else { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid tenant snapshot status", K(status)); + } + return str; +} + +ObLSSnapStatus ObTenantSnapshotTableOperator::str_to_ls_snap_status(const ObString &status_str) +{ + ObLSSnapStatus ret_status = ObLSSnapStatus::MAX; + if (!status_str.empty()) { + for (int64_t i = 0; i < ARRAYSIZEOF(LS_SNAP_STATUS_ARRAY); i++) { + if (0 == status_str.case_compare(LS_SNAP_STATUS_ARRAY[i])) { + ret_status = static_cast(i); + break; + } + } + } + return ret_status; +} + +const char* ObTenantSnapshotTableOperator::ls_snap_status_to_str(const ObLSSnapStatus &status) +{ + STATIC_ASSERT(ARRAYSIZEOF(LS_SNAP_STATUS_ARRAY) == static_cast(ObLSSnapStatus::MAX), + "type string array size mismatch with enum ls snapshot status count"); + const char* str = INVALID_STR; + if (status >= ObLSSnapStatus::CREATING && status < ObLSSnapStatus::MAX) { + str = LS_SNAP_STATUS_ARRAY[static_cast(status)]; + } else { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid ls snapshot status", K(status)); + } + return str; +} + +ObTenantSnapType ObTenantSnapshotTableOperator::str_to_type(const ObString &type_str) +{ + ObTenantSnapType ret_type = ObTenantSnapType::MAX; + if (type_str.empty()) { + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(TENANT_SNAP_TYPE_ARRAY); i++) { + if (0 == type_str.case_compare(TENANT_SNAP_TYPE_ARRAY[i])) { + ret_type = static_cast(i); + break; + } + } + } + return ret_type; +} + +const char* ObTenantSnapshotTableOperator::type_to_str(const ObTenantSnapType &type) +{ + STATIC_ASSERT(ARRAYSIZEOF(TENANT_SNAP_TYPE_ARRAY) == static_cast(ObTenantSnapType::MAX), + "type string array size mismatch with enum tenant snapshot type count"); + const char* str = INVALID_STR; + if (type >= ObTenantSnapType::AUTO && type < ObTenantSnapType::MAX) { + str = TENANT_SNAP_TYPE_ARRAY[static_cast(type)]; + } else { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid tenant snapshot type", K(type)); + } + return str; +} + +ObTenantSnapOperation ObTenantSnapshotTableOperator::str_to_operation(const ObString &str) +{ + ObTenantSnapOperation ret_type = ObTenantSnapOperation::MAX; + if (str.empty()) { + } else { + for (int64_t i = 0; i < ARRAYSIZEOF(TENANT_SNAP_OPERATION_ARRAY); i++) { + if (0 == str.case_compare(TENANT_SNAP_OPERATION_ARRAY[i])) { + ret_type = static_cast(i); + break; + } + } + } + return ret_type; +} + +const char* ObTenantSnapshotTableOperator::operation_to_str(const ObTenantSnapOperation &operation) +{ + STATIC_ASSERT(ARRAYSIZEOF(TENANT_SNAP_OPERATION_ARRAY) == static_cast(ObTenantSnapOperation::MAX), + "operation string array size mismatch with enum tenant snapshot operation count"); + const char* str = INVALID_STR; + if (operation >= ObTenantSnapOperation::CREATE && operation < ObTenantSnapOperation::MAX) { + str = TENANT_SNAP_OPERATION_ARRAY[static_cast(operation)]; + } else { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid tenant snapshot operation", K(operation)); + } + return str; +} + +ObTenantSnapshotTableOperator::ObTenantSnapshotTableOperator() : + is_inited_(false), + user_tenant_id_(OB_INVALID_TENANT_ID), + proxy_(NULL) +{} + +int ObTenantSnapshotTableOperator::init(const uint64_t user_tenant_id, ObISQLClient *proxy) +{ + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("snapshot table operator init twice", KR(ret)); + } else if (!is_user_tenant(user_tenant_id) || OB_ISNULL(proxy)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(user_tenant_id), KP(proxy)); + } else { + user_tenant_id_ = user_tenant_id; + proxy_ = proxy; + is_inited_ = true; + } + return ret; +} + +int ObTenantSnapshotTableOperator::insert_tenant_snap_item(const ObTenantSnapItem& item) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!item.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(item)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", item.get_tenant_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", item.get_tenant_snapshot_id().id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("snapshot_name", item.get_snapshot_name()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("status", tenant_snap_status_to_str(item.get_status())))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("snapshot_scn", item.get_snapshot_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("clog_start_scn", item.get_clog_start_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("type", type_to_str(item.get_type())))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_time_column("create_time", item.get_create_time()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("data_version", item.get_data_version()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("owner_job_id", item.get_owner_job_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.splice_insert_sql(OB_ALL_TENANT_SNAPSHOT_TNAME, sql))) { + LOG_WARN("splice insert sql failed", KR(ret), K(item)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret || OB_ERR_DUPLICATED_UNIQUE_KEY == ret) { + ret = OB_TENANT_SNAPSHOT_EXIST; + } + LOG_WARN("exec sql failed", KR(ret), K(item), K(sql), K(gen_meta_tenant_id(user_tenant_id_))); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected affected rows", KR(ret), K(affected_rows)); + } + return ret; +} + + +int ObTenantSnapshotTableOperator::get_tenant_snap_item(const ObTenantSnapshotID &tenant_snapshot_id, + const bool need_lock, + ObTenantSnapItem &item) +{ + int ret = OB_SUCCESS; + item.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu AND snapshot_id = %ld", + OB_ALL_TENANT_SNAPSHOT_TNAME, user_tenant_id_, tenant_snapshot_id.id()))) { + LOG_WARN("assign sql failed", KR(ret)); + } else if (need_lock && OB_FAIL(sql.append_fmt(" FOR UPDATE "))) { /*lock row*/ + LOG_WARN("assign sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("failed to execute sql", KR(ret), K(sql), K(gen_meta_tenant_id(user_tenant_id_))); + } else if (NULL == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_TENANT_SNAPSHOT_NOT_EXIST; + } else { + LOG_WARN("next failed", KR(ret)); + } + } else if (OB_FAIL(fill_item_from_result_(result, item))) { + LOG_WARN("fill item from result failed", KR(ret)); + } + } + } + return ret; +} + +//for sys tenant to call +int ObTenantSnapshotTableOperator::get_tenant_snap_item(const ObString &snapshot_name, + const bool need_lock, + ObTenantSnapItem &item) +{ + int ret = OB_SUCCESS; + item.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(snapshot_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(snapshot_name)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu AND snapshot_name = '%.*s'", + OB_ALL_TENANT_SNAPSHOT_TNAME, user_tenant_id_, + snapshot_name.length(), snapshot_name.ptr()))) { + LOG_WARN("assign sql failed", KR(ret)); + } else if (need_lock && OB_FAIL(sql.append_fmt(" FOR UPDATE "))) { /*lock row*/ + LOG_WARN("assign sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("failed to execute sql", KR(ret), K(sql), K(gen_meta_tenant_id(user_tenant_id_))); + } else if (NULL == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_TENANT_SNAPSHOT_NOT_EXIST; + } else { + LOG_WARN("next failed", KR(ret)); + } + } else if (OB_FAIL(fill_item_from_result_(result, item))) { + LOG_WARN("fill item from result failed", KR(ret)); + } + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_all_user_tenant_snap_items(ObArray &items) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + items.reset(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu AND snapshot_id != %ld", + OB_ALL_TENANT_SNAPSHOT_TNAME, user_tenant_id_, GLOBAL_STATE_ID))) { + LOG_WARN("assign sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("failed to execute sql", KR(ret), K(sql), K(gen_meta_tenant_id(user_tenant_id_))); + } else if (NULL == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else { + ObTenantSnapItem item; + while (OB_SUCC(ret) && OB_SUCC(result->next())) { + item.reset(); + if (OB_FAIL(fill_item_from_result_(result, item))) { + LOG_WARN("fill item from result failed", KR(ret)); + } else if (OB_FAIL(items.push_back(item))) { + LOG_WARN("push back item failed", KR(ret), K(item)); + } + } + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next result", KR(ret)); + } else { + ret = OB_SUCCESS; + } + } + } + } + return ret; +} + +//Note: if new_snapshot_scn is invalid, we will not update column "snapshot_scn" +// if new_create_time is invalid(OB_INVALID_TIMESTAMP), we will not update column "create_time" +int ObTenantSnapshotTableOperator::update_special_tenant_snap_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapStatus &old_status, + const ObTenantSnapStatus &new_status, + const int64_t owner_job_id, + const SCN &new_snapshot_scn, + const int64_t new_create_time) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(ObTenantSnapshotID(GLOBAL_STATE_ID) != tenant_snapshot_id + || ObTenantSnapStatus::MAX == old_status + || ObTenantSnapStatus::MAX == new_status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(old_status), K(new_status)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", tenant_snapshot_id.id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("status", tenant_snap_status_to_str(new_status)))) { + LOG_WARN("add column failed", KR(ret)); + } else if (new_snapshot_scn.is_valid() && + OB_FAIL(dml.add_uint64_column("snapshot_scn", new_snapshot_scn.get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (new_create_time != OB_INVALID_TIMESTAMP && + OB_FAIL(dml.add_time_column("create_time", new_create_time))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("owner_job_id", owner_job_id))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s = '%s'", + "status", tenant_snap_status_to_str(old_status)))) { + LOG_WARN("add extra_condition failed", KR(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_TENANT_SNAPSHOT_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K(gen_meta_tenant_id(user_tenant_id_))); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected affected rows", KR(ret), K(affected_rows)); + } + return ret; +} + +//if clog_start_scn is not valid, we don't update the column +//if snapshot_scn is not valid, we don't update the column +int ObTenantSnapshotTableOperator::update_tenant_snap_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapStatus &old_status, + const ObTenantSnapStatus &new_status, + const SCN &new_snapshot_scn, + const SCN &new_clog_start_scn) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || ObTenantSnapStatus::MAX == old_status + || ObTenantSnapStatus::MAX == new_status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(old_status), K(new_status)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("add column failed", KR(ret), K(user_tenant_id_)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", tenant_snapshot_id.id()))) { + LOG_WARN("add column failed", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(dml.add_column("status", tenant_snap_status_to_str(new_status)))) { + LOG_WARN("add column failed", KR(ret), K(new_status)); + } else if (new_snapshot_scn.is_valid() && + OB_FAIL(dml.add_uint64_column("snapshot_scn", new_snapshot_scn.get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (new_clog_start_scn.is_valid() && + OB_FAIL(dml.add_uint64_column("clog_start_scn", new_clog_start_scn.get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s = '%s'", + "status", tenant_snap_status_to_str(old_status)))) { + LOG_WARN("add extra_condition failed", KR(ret), K(old_status)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_TENANT_SNAPSHOT_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret), K(tenant_snapshot_id), K(old_status), K(new_status)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K(gen_meta_tenant_id(user_tenant_id_))); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected affected rows", KR(ret), K(affected_rows), K(sql)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::update_tenant_snap_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapStatus &old_status_1, + const ObTenantSnapStatus &old_status_2, + const ObTenantSnapStatus &new_status) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || ObTenantSnapStatus::MAX == old_status_1 + || ObTenantSnapStatus::MAX == old_status_2 + || ObTenantSnapStatus::MAX == new_status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", + KR(ret), K(tenant_snapshot_id), K(old_status_1), K(old_status_2), K(new_status)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("add column failed", KR(ret), K(user_tenant_id_)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", tenant_snapshot_id.id()))) { + LOG_WARN("add column failed", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(dml.add_column("status", tenant_snap_status_to_str(new_status)))) { + LOG_WARN("add column failed", KR(ret), K(new_status)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("(status = '%s' OR status = '%s')", + tenant_snap_status_to_str(old_status_1), + tenant_snap_status_to_str(old_status_2)))) { + LOG_WARN("add extra_condition failed", KR(ret), K(old_status_1), K(old_status_2)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_TENANT_SNAPSHOT_TNAME, sql))) { + LOG_WARN("splice update sql failed", + KR(ret), K(tenant_snapshot_id), K(old_status_1), K(old_status_2), K(new_status)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K(gen_meta_tenant_id(user_tenant_id_))); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected affected rows", KR(ret), K(affected_rows), K(sql)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::update_tenant_snap_item(const ObString &snapshot_name, + const ObTenantSnapStatus &old_status, + const ObTenantSnapStatus &new_status) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(snapshot_name.empty() + || ObTenantSnapStatus::MAX == old_status + || ObTenantSnapStatus::MAX == new_status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(snapshot_name), K(old_status), K(new_status)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("status", tenant_snap_status_to_str(new_status)))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().assign_fmt("%s = '%.*s'", + "snapshot_name", snapshot_name.length(), snapshot_name.ptr()))) { + LOG_WARN("add extra_condition failed", KR(ret)); + } else if (OB_FAIL(dml.get_extra_condition().append_fmt(" AND %s = '%s'", + "status", tenant_snap_status_to_str(old_status)))) { + LOG_WARN("add extra_condition failed", KR(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_TENANT_SNAPSHOT_TNAME, sql))) { + LOG_WARN("splice update sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K(gen_meta_tenant_id(user_tenant_id_))); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected affected rows", KR(ret), K(affected_rows), K(sql)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::delete_tenant_snap_item(const ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + ObDMLSqlSplicer dml; + int64_t affected_rows = 0; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", tenant_snapshot_id.id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.splice_delete_sql(OB_ALL_TENANT_SNAPSHOT_TNAME, sql))) { + LOG_WARN("splice delete sql failed", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::insert_tenant_snap_ls_items(const ObArray &items) +{ + int ret = OB_SUCCESS; + ObDMLSqlSplicer dml; + ObSqlString sql; + int64_t affected_rows = 0; + ObLSFlagStr flag_str; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < items.count(); i++) { + flag_str.reset(); + const ObTenantSnapLSItem &item = items.at(i); + if (OB_UNLIKELY(!item.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(item)); + } else if (OB_FAIL(item.get_ls_attr().get_ls_flag().flag_to_str(flag_str))) { + LOG_WARN("fail to convert flag to string", KR(ret), K(item)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", item.get_tenant_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", item.get_tenant_snapshot_id().id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("ls_id", item.get_ls_attr().get_ls_id().id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("ls_group_id", item.get_ls_attr().get_ls_group_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("status", ls_status_to_str(item.get_ls_attr().get_ls_status())))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("flag", flag_str.ptr()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("create_scn", + item.get_ls_attr().get_create_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.finish_row())) { + LOG_WARN("fail to finish row", KR(ret), K(user_tenant_id_)); + } + } + } + + if (FAILEDx(dml.splice_batch_insert_sql(OB_ALL_TENANT_SNAPSHOT_LS_TNAME, sql))) { + LOG_WARN("fail to generate sql", KR(ret), K(user_tenant_id_)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("fail to execute sql", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (affected_rows != items.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("affected_rows not match", KR(ret), K(user_tenant_id_), K(affected_rows), K(items.count())); + } + + return ret; +} + +int ObTenantSnapshotTableOperator::delete_tenant_snap_ls_items(const ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + ObDMLSqlSplicer dml; + int64_t affected_rows = 0; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("fail to add column", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", tenant_snapshot_id.id()))) { + LOG_WARN("fail to add column", KR(ret)); + } else if (OB_FAIL(dml.splice_delete_sql(OB_ALL_TENANT_SNAPSHOT_LS_TNAME, sql))) { + LOG_WARN("failed to splice delete sql", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_tenant_snap_ls_items(const ObTenantSnapshotID &tenant_snapshot_id, + ObArray &items) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + items.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id)); + } else { + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu AND snapshot_id = %ld", + OB_ALL_TENANT_SNAPSHOT_LS_TNAME, user_tenant_id_, tenant_snapshot_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret)); + } else { + while (OB_SUCC(ret) && OB_SUCC(result->next())) { + ObTenantSnapLSItem item; + if (OB_FAIL(fill_item_from_result_(result, item))) { + LOG_WARN("fill tenant snapshot ls item failed", KR(ret)); + } else if (OB_FAIL(items.push_back(item))) { + LOG_WARN("array push back failed", KR(ret), K(item)); + } + } + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next result", KR(ret)); + } else { + ret = OB_SUCCESS; + } + } + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_tenant_snap_ls_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObTenantSnapLSItem &item) +{ + int ret = OB_SUCCESS; + item.reset(); + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else { + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %lu AND snapshot_id = %ld AND ls_id = %ld", + OB_ALL_TENANT_SNAPSHOT_LS_TNAME, user_tenant_id_, tenant_snapshot_id.id(), ls_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (NULL == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } else { + LOG_WARN("next failed", KR(ret)); + } + } else if (OB_FAIL(fill_item_from_result_(result, item))) { + LOG_WARN("fill item from result failed", KR(ret)); + } + } + } + + return ret; +} + +int ObTenantSnapshotTableOperator::get_tenant_snap_related_addrs(const ObTenantSnapshotID &tenant_snapshot_id, + ObArray &addrs) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + addrs.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id)); + } else { + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT DISTINCT svr_ip, svr_port FROM %s " + "WHERE tenant_id = %lu AND snapshot_id = %ld", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, tenant_snapshot_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret)); + } else { + while (OB_SUCC(ret) && OB_SUCC(result->next())) { + ObAddr addr; + ObString svr_ip; + int32_t svr_port = 0; + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "svr_ip", svr_ip); + EXTRACT_INT_FIELD_MYSQL(*result, "svr_port", svr_port, int32_t); + if (OB_SUCC(ret)) { + if (!(addr.set_ip_addr(svr_ip, svr_port))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("set addr failed", KR(ret), K(svr_ip), K(svr_port)); + } else if (OB_FAIL(addrs.push_back(addr))) { + LOG_WARN("array push back failed", KR(ret), K(addr)); + } + } + } + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next result", KR(ret)); + } else { + ret = OB_SUCCESS; + } + } + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_proper_ls_meta_package(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObLSMetaPackage& ls_meta_package) +{ + int ret = OB_SUCCESS; + ls_meta_package.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else { + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %ld " + "AND snapshot_id = %ld AND ls_id = %ld AND status = 'NORMAL'" + "ORDER BY begin_interval_scn, svr_ip, svr_port limit 1", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, tenant_snapshot_id.id(), ls_id.id()))) { + LOG_WARN("fail to assign get_proper_ls_meta_package sql", + KR(ret), K(user_tenant_id_), K(tenant_snapshot_id), K(ls_id)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } else { + LOG_WARN("next failed", KR(ret)); + } + } else { + ObString ls_meta_package_str; + ObArenaAllocator allocator; + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "ls_meta_package", ls_meta_package_str); + if (FAILEDx(decode_hex_string_to_package_(ls_meta_package_str, allocator, ls_meta_package))) { + LOG_WARN("fail to decode", KR(ret), K(ls_meta_package_str)); + } + } + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_ls_meta_package(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + const ObAddr& addr, + ObLSMetaPackage& ls_meta_package) +{ + int ret = OB_SUCCESS; + char ip_buf[OB_IP_STR_BUFF] = {'\0'}; + + ls_meta_package.reset(); + ObSqlString sql; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator is not init", KR(ret)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant snapshot id is not valid", KR(ret), K(tenant_snapshot_id), K(ls_id), K(addr)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is not valid", KR(ret), K(tenant_snapshot_id), K(ls_id), K(addr)); + } else if (!addr.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("addr is not valid", KR(ret), K(tenant_snapshot_id), K(ls_id), K(addr)); + } else if (!addr.ip_to_string(ip_buf, sizeof(ip_buf))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ip to string failed", KR(ret), K(addr)); + } else { + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(sql.assign_fmt("SELECT ls_meta_package " + "FROM %s WHERE tenant_id = %ld AND snapshot_id = %ld AND ls_id = %ld " + "AND svr_ip = '%s' AND svr_port = %ld", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, tenant_snapshot_id.id(), ls_id.id(), + ip_buf, (int64_t)addr.get_port()))) { + LOG_WARN("fail to assign get_ls_meta_package sql", + KR(ret), K(user_tenant_id_), K(tenant_snapshot_id), K(ls_id), K(ip_buf), K(addr)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("fail to execute get_ls_meta_package sql", + KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is unexpected nullptr", + KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } else { + LOG_WARN("fail to exec result next", + KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } + } else { + ObString ls_meta_package_str; + ObArenaAllocator allocator; + char *unhex_buf = NULL; + int64_t unhex_buf_len = 0; + int64_t pos = 0; + EXTRACT_VARCHAR_FIELD_MYSQL_SKIP_RET(*result, "ls_meta_package", ls_meta_package_str); + if (FAILEDx(decode_hex_string_to_package_(ls_meta_package_str, allocator, ls_meta_package))) { + LOG_WARN("fail to decode_hex_string_to_package_", + KR(ret), K(ls_meta_package_str), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } + } + } + } + return ret; +} + +//get all simple_items by tenant_snapshot_id +int ObTenantSnapshotTableOperator::get_tenant_snap_ls_replica_simple_items(const ObTenantSnapshotID &tenant_snapshot_id, + ObArray &simple_items) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + simple_items.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(sql.assign_fmt("SELECT tenant_id, snapshot_id, ls_id, svr_ip, svr_port, status, " + "zone, unit_id, begin_interval_scn, end_interval_scn " + "FROM %s WHERE tenant_id = %lu AND snapshot_id = %ld", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, tenant_snapshot_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(get_tenant_snap_ls_replica_simple_items_(sql, simple_items))) { + LOG_WARN("failed to get snap ls replica simple items", KR(ret), K(sql)); + } + return ret; +} + +//get all simple_items by tenant_snapshot_id and addr +int ObTenantSnapshotTableOperator::get_tenant_snap_ls_replica_simple_items(const ObTenantSnapshotID &tenant_snapshot_id, + const common::ObAddr& addr, + ObArray &simple_items) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + simple_items.reset(); + char ip_buf[OB_IP_STR_BUFF] = {'\0'}; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(addr)); + } else if (!addr.ip_to_string(ip_buf, sizeof(ip_buf))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ip to string failed", KR(ret), K(addr)); + } else if (OB_FAIL(sql.assign_fmt("SELECT tenant_id, snapshot_id, ls_id, svr_ip, svr_port, status, " + "zone, unit_id, begin_interval_scn, end_interval_scn " + "FROM %s WHERE tenant_id = %lu AND snapshot_id = %ld " + "AND svr_ip = '%s' AND svr_port = %d", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, tenant_snapshot_id.id(), + ip_buf, addr.get_port()))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(get_tenant_snap_ls_replica_simple_items_(sql, simple_items))) { + LOG_WARN("failed to get snap ls replica simple items", KR(ret), K(sql)); + } + return ret; +} + +//get all simple_items by tenant_snapshot_id and ls_id +int ObTenantSnapshotTableOperator::get_tenant_snap_ls_replica_simple_items(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObArray &simple_items) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + simple_items.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (OB_FAIL(sql.assign_fmt("SELECT tenant_id, snapshot_id, ls_id, svr_ip, svr_port, status, " + "zone, unit_id, begin_interval_scn, end_interval_scn " + "FROM %s WHERE tenant_id = %lu AND snapshot_id = %ld and ls_id = %ld", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, tenant_snapshot_id.id(), ls_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(get_tenant_snap_ls_replica_simple_items_(sql, simple_items))) { + LOG_WARN("failed to get snap ls replica simple items", KR(ret), K(sql)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_tenant_snap_ls_replica_simple_items(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + const ObLSSnapStatus &status, + ObArray &simple_items) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + simple_items.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !ls_id.is_valid() + || ObLSSnapStatus::MAX == status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(ls_id), K(status)); + } else if (OB_FAIL(sql.assign_fmt("SELECT tenant_id, snapshot_id, ls_id, svr_ip, svr_port, status, " + "zone, unit_id, begin_interval_scn, end_interval_scn " + "FROM %s WHERE tenant_id = %lu AND snapshot_id = %ld " + "and ls_id = %ld and status = '%s'", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, tenant_snapshot_id.id(), ls_id.id(), ls_snap_status_to_str(status)))) { + LOG_WARN("failed to assign sql", KR(ret), K(tenant_snapshot_id), K(ls_id), K(status)); + } else if (OB_FAIL(get_tenant_snap_ls_replica_simple_items_(sql, simple_items))) { + LOG_WARN("failed to get snap ls replica simple items", KR(ret), K(sql)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_tenant_snap_ls_replica_simple_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + const ObAddr& addr, + const bool need_lock, + ObTenantSnapLSReplicaSimpleItem &simple_item) +{ + int ret = OB_SUCCESS; + simple_item.reset(); + ObSqlString sql; + char ip_buf[OB_IP_STR_BUFF] = {'\0'}; + ObArray simple_items; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() + || !ls_id.is_valid() + || !addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(ls_id), K(addr)); + } else if (!addr.ip_to_string(ip_buf, sizeof(ip_buf))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ip to string failed", KR(ret), K(addr)); + } else if (OB_FAIL(sql.assign_fmt("SELECT tenant_id, snapshot_id, ls_id, svr_ip, svr_port, status, " + "zone, unit_id, begin_interval_scn, end_interval_scn " + "FROM %s WHERE tenant_id = %lu AND snapshot_id = %ld AND ls_id = %ld " + "AND svr_ip = '%s' AND svr_port = %d", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, tenant_snapshot_id.id(), ls_id.id(), + ip_buf, addr.get_port()))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (need_lock && OB_FAIL(sql.append_fmt(" FOR UPDATE "))) { /*lock row*/ + LOG_WARN("assign sql failed", KR(ret)); + } else if (OB_FAIL(get_tenant_snap_ls_replica_simple_items_(sql, simple_items))) { + LOG_WARN("failed to get snap ls replica simple items", KR(ret), K(sql)); + } else { + if (simple_items.count() == 0) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("item not exist", KR(ret), K(sql), K(simple_items)); + } else if (simple_items.count() > 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the count of simple_items is not as expected", KR(ret), K(sql), K(simple_items)); + } else if (OB_FAIL(simple_item.assign(simple_items.at(0)))) { + LOG_WARN("failed to assign", KR(ret), K(sql), K(simple_items)); + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_tenant_snap_ls_replica_simple_items_(const ObSqlString &sql, + ObArray &simple_items) +{ + int ret = OB_SUCCESS; + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = NULL; + if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (OB_ISNULL(result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret)); + } else { + ObTenantSnapLSReplicaSimpleItem simple_item; + while (OB_SUCC(ret) && OB_SUCC(result->next())) { + simple_item.reset(); + if (OB_FAIL(fill_item_from_result_(result, simple_item))) { + LOG_WARN("fill simple item failed", KR(ret)); + } else if (OB_FAIL(simple_items.push_back(simple_item))) { + LOG_WARN("failed push back item", KR(ret), K(simple_item)); + } + } + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next result", KR(ret)); + } else { + ret = OB_SUCCESS; + } + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::fill_item_from_result_(const ObMySQLResult *result, + ObTenantSnapItem &item) +{ + int ret = OB_SUCCESS; + item.reset(); + if (OB_ISNULL(result)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("result is null", KR(ret)); + } else { + uint64_t tenant_id = OB_INVALID_TENANT_ID; + ObTenantSnapshotID tenant_snapshot_id; + ObString snapshot_name; + ObString status_str; + uint64_t snapshot_scn_val = OB_INVALID_SCN_VAL; + SCN snapshot_scn; + uint64_t clog_start_scn_val = OB_INVALID_SCN_VAL; + SCN clog_start_scn; + ObString type_str; + int64_t create_time = OB_INVALID_TIMESTAMP; + uint64_t data_version = 0; + int64_t owner_job_id; + + EXTRACT_INT_FIELD_MYSQL(*result, "tenant_id", tenant_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "snapshot_id", tenant_snapshot_id, int64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "snapshot_name", snapshot_name); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "status", status_str); + EXTRACT_UINT_FIELD_MYSQL(*result, "snapshot_scn", snapshot_scn_val, uint64_t); + EXTRACT_UINT_FIELD_MYSQL(*result, "clog_start_scn", clog_start_scn_val, uint64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "type", type_str); + EXTRACT_TIMESTAMP_FIELD_MYSQL(*result, "create_time", create_time); + EXTRACT_UINT_FIELD_MYSQL(*result, "data_version", data_version, uint64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "owner_job_id", owner_job_id, int64_t); + if (OB_SUCC(ret)) { + if (OB_INVALID_SCN_VAL != snapshot_scn_val && + OB_FAIL(snapshot_scn.convert_for_inner_table_field(snapshot_scn_val))) { + LOG_WARN("fail to convert_for_inner_table_field", KR(ret), K(snapshot_scn_val)); + } else if (OB_INVALID_SCN_VAL != clog_start_scn_val && + OB_FAIL(clog_start_scn.convert_for_inner_table_field(clog_start_scn_val))) { + LOG_WARN("fail to convert_for_inner_table_field", KR(ret), K(clog_start_scn_val)); + } else if (OB_FAIL(item.init(tenant_id, tenant_snapshot_id, snapshot_name, + str_to_tenant_snap_status(status_str), snapshot_scn, clog_start_scn, + str_to_type(type_str), create_time, data_version, owner_job_id))) { + LOG_WARN("fail to init item", KR(ret), K(tenant_id), K(tenant_snapshot_id), K(snapshot_name), + K(str_to_tenant_snap_status(status_str)), K(snapshot_scn), K(clog_start_scn), + K(str_to_type(type_str)), K(create_time), K(data_version), K(owner_job_id)); + } + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::fill_item_from_result_(const ObMySQLResult *result, + ObTenantSnapLSItem &item) +{ + int ret = OB_SUCCESS; + item.reset(); + if (OB_ISNULL(result)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("result is null", KR(ret)); + } else { + uint64_t tenant_id = OB_INVALID_TENANT_ID; + ObTenantSnapshotID tenant_snapshot_id; + ObLSID ls_id; + uint64_t ls_group_id = OB_INVALID_ID; + ObString status_str; + ObLSStatus status; + ObString flag_str; + ObLSFlag flag; + uint64_t create_scn_val = OB_INVALID_SCN_VAL; + SCN create_scn; + ObLSOperationType type; + ObLSAttr ls_attr; + EXTRACT_INT_FIELD_MYSQL(*result, "tenant_id", tenant_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "snapshot_id", tenant_snapshot_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "ls_id", ls_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "ls_group_id", ls_group_id, uint64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "status", status_str); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "flag", flag_str); + EXTRACT_UINT_FIELD_MYSQL(*result, "create_scn", create_scn_val, uint64_t); + if (OB_SUCC(ret)) { + status = str_to_ls_status(status_str); + type = ObLSAttrOperator::get_ls_operation_by_status(status); + if (OB_FAIL(flag.str_to_flag(flag_str))) { + LOG_WARN("failed to convert flag", KR(ret), K(flag_str)); + } else if (OB_INVALID_SCN_VAL == create_scn_val) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected create_scn_val", KR(ret), K(create_scn_val)); + } else if (OB_FAIL(create_scn.convert_for_inner_table_field(create_scn_val))) { + LOG_WARN("failed to convert_for_inner_table_field", KR(ret), K(create_scn_val)); + } else if (OB_FAIL(ls_attr.init(ls_id, ls_group_id, flag, status, type, create_scn))) { + LOG_WARN("failed to init ls attr", KR(ret), K(ls_group_id), + K(ls_id), K(status_str), K(status), K(type), K(create_scn)); + } else if (OB_FAIL(item.init(tenant_id, tenant_snapshot_id, ls_attr))) { + LOG_WARN("failed to init item", KR(ret), K(tenant_id), K(tenant_snapshot_id), K(ls_attr)); + } + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::fill_item_from_result_(const ObMySQLResult *result, + ObTenantSnapLSReplicaSimpleItem &simple_item) +{ + int ret = OB_SUCCESS; + simple_item.reset(); + if (OB_ISNULL(result)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("result is null", KR(ret)); + } else { + uint64_t tenant_id = OB_INVALID_TENANT_ID; + ObTenantSnapshotID tenant_snapshot_id; + ObLSID ls_id; + ObString svr_ip; + int64_t svr_port = 0; + ObAddr addr; + ObString status_str; + ObString zone_str; + ObZone zone; + uint64_t unit_id = OB_INVALID_ID; + uint64_t begin_interval_scn_val = OB_INVALID_SCN_VAL; + SCN begin_interval_scn; + uint64_t end_interval_scn_val = OB_INVALID_SCN_VAL; + SCN end_interval_scn; + EXTRACT_INT_FIELD_MYSQL(*result, "tenant_id", tenant_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "snapshot_id", tenant_snapshot_id, int64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "ls_id", ls_id, int64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "svr_ip", svr_ip); + EXTRACT_INT_FIELD_MYSQL(*result, "svr_port", svr_port, int64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "status", status_str); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "zone", zone_str); + EXTRACT_INT_FIELD_MYSQL(*result, "unit_id", unit_id, uint64_t); + EXTRACT_UINT_FIELD_MYSQL(*result, "begin_interval_scn", begin_interval_scn_val, uint64_t); + EXTRACT_UINT_FIELD_MYSQL(*result, "end_interval_scn", end_interval_scn_val, uint64_t); + if (OB_SUCC(ret)) { + if (OB_INVALID_SCN_VAL != begin_interval_scn_val && + OB_FAIL(begin_interval_scn.convert_for_inner_table_field(begin_interval_scn_val))) { + LOG_WARN("fail to convert_for_inner_table_field", KR(ret), K(begin_interval_scn_val)); + } else if (OB_INVALID_SCN_VAL != end_interval_scn_val && + OB_FAIL(end_interval_scn.convert_for_inner_table_field(end_interval_scn_val))) { + LOG_WARN("fail to convert_for_inner_table_field", KR(ret), K(end_interval_scn_val)); + } else if (OB_UNLIKELY(!addr.set_ip_addr(svr_ip, static_cast(svr_port)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to set_ip_addr", KR(ret), K(svr_ip), K(svr_port)); + } else if (OB_FAIL(zone.assign(zone_str))) { + LOG_WARN("fail to assign zone", KR(ret), K(zone_str)); + } else if (OB_FAIL(simple_item.init(tenant_id, tenant_snapshot_id, ls_id, addr, str_to_ls_snap_status(status_str), + zone, unit_id, begin_interval_scn, end_interval_scn))) { + LOG_WARN("fail to init simple_item", KR(ret), K(tenant_id), K(tenant_snapshot_id), K(ls_id), K(addr), + K(str_to_ls_snap_status(status_str)), K(zone), K(unit_id), K(begin_interval_scn), K(end_interval_scn)); + } + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::fill_item_from_result_(const ObMySQLResult *result, + ObTenantSnapJobItem &item) +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = OB_INVALID_TENANT_ID; + ObTenantSnapshotID tenant_snapshot_id; + int64_t job_start_time = OB_INVALID_TIMESTAMP; + int64_t majority_succ_time = OB_INVALID_TIMESTAMP; + ObString operation_str; + + int64_t real_length = 0; + common::ObCurTraceId::TraceId trace_id; + char trace_id_buf[OB_MAX_TRACE_ID_BUFFER_SIZE] = {'\0'}; + + EXTRACT_INT_FIELD_MYSQL(*result, "tenant_id", tenant_id, uint64_t); + EXTRACT_INT_FIELD_MYSQL(*result, "snapshot_id", tenant_snapshot_id, int64_t); + EXTRACT_VARCHAR_FIELD_MYSQL(*result, "operation", operation_str); + EXTRACT_TIMESTAMP_FIELD_MYSQL(*result, "job_start_time", job_start_time); + EXTRACT_STRBUF_FIELD_MYSQL(*result, "trace_id", trace_id_buf, sizeof(trace_id_buf), real_length); + EXTRACT_TIMESTAMP_FIELD_MYSQL(*result, "majority_succ_time", majority_succ_time); + + if (OB_SUCC(ret)) { + if (OB_FAIL(trace_id.parse_from_buf(trace_id_buf))) { + LOG_WARN("fail to parse trace id from buf", KR(ret), K(trace_id_buf)); + } else { + item.set_tenant_id(tenant_id); + item.set_tenant_snapshot_id(tenant_snapshot_id); + item.set_operation(str_to_operation(operation_str)); + item.set_job_start_time(job_start_time); + item.set_trace_id(trace_id); + item.set_majority_succ_time(majority_succ_time); + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::delete_tenant_snap_ls_replica_items(const ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + ObDMLSqlSplicer dml; + int64_t affected_rows = 0; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("fail to add column", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", tenant_snapshot_id.id()))) { + LOG_WARN("fail to add column", KR(ret)); + } else if (OB_FAIL(dml.splice_delete_sql(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, sql))) { + LOG_WARN("failed to splice delete sql", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("failed to exec sql", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::update_tenant_snap_ls_replica_item(const ObTenantSnapLSReplicaSimpleItem &simple_item, + const ObLSMetaPackage* ls_meta_package) +{ + int ret = OB_SUCCESS; + ObDMLSqlSplicer dml; + ObSqlString sql; + int64_t affected_rows = 0; + char ip_buf[OB_IP_STR_BUFF] = {'\0'}; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else { + ObString hex_meta_package; + ObArenaAllocator allocator; + if (!simple_item.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(simple_item)); + } else if (NULL != ls_meta_package && !ls_meta_package->is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), KPC(ls_meta_package)); + } else if (!simple_item.get_addr().ip_to_string(ip_buf, sizeof(ip_buf))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ip to string failed", KR(ret), K(simple_item.get_addr())); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", simple_item.get_tenant_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", simple_item.get_tenant_snapshot_id().id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("ls_id", simple_item.get_ls_id().id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("svr_ip", ip_buf))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("svr_port", simple_item.get_addr().get_port()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("status", ls_snap_status_to_str(simple_item.get_status())))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("zone", simple_item.get_zone().ptr()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("unit_id", simple_item.get_unit_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("begin_interval_scn", + simple_item.get_begin_interval_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("end_interval_scn", + simple_item.get_end_interval_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (NULL != ls_meta_package) { + if (OB_FAIL(encode_package_to_hex_string_(*ls_meta_package, allocator, hex_meta_package))) { + LOG_WARN("encode package failed", KR(ret), KPC(ls_meta_package)); + } else if (OB_FAIL(dml.add_column("ls_meta_package", hex_meta_package))) { + LOG_WARN("add column failed", KR(ret)); + } + } + } + + if (FAILEDx(dml.splice_update_sql(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, sql))) { + LOG_WARN("fail to generate sql", KR(ret), K(user_tenant_id_)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("fail to execute sql", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("affected_rows not match", KR(ret), K(user_tenant_id_), K(affected_rows), K(simple_item)); + } + + return ret; +} + +int ObTenantSnapshotTableOperator::archive_tenant_snap_ls_replica_history(const ObTenantSnapshotID &snapshot_id) +{ + int ret = OB_SUCCESS; + ObDMLSqlSplicer dml; + ObSqlString sql; + int64_t affected_rows = 0; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!snapshot_id.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tenant snapshot id", KR(ret), K(snapshot_id)); + } else if (OB_FAIL(sql.assign_fmt("INSERT INTO %s SELECT * FROM %s WHERE " + "tenant_id = %ld AND " + "snapshot_id = %ld", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, + user_tenant_id_, + snapshot_id.id() + ))) { + LOG_WARN("fail to build sql", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("fail to execute sql", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } + + return ret; +} + +// lazy eliminate +int ObTenantSnapshotTableOperator::eliminate_tenant_snap_ls_replica_history() +{ + int ret = OB_SUCCESS; + ObSqlString sql; + int64_t replica_num = 0; + int64_t affected_rows = 0; + static const int64_t REPLICA_NUM_LIMIT = 1000; + static const int64_t ELIMINATED_NUM = 200; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_FAIL(sql.assign_fmt("SELECT COUNT(1) AS REPLICA_NUM FROM %s ", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME))) { + LOG_WARN("fail to build sql", KR(ret)); + } else { + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = nullptr; + if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(user_tenant_id_), K(sql)); + } else if (nullptr == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } + LOG_WARN("next failed", KR(ret), K(user_tenant_id_), K(sql)); + } else { + EXTRACT_INT_FIELD_MYSQL(*result, "REPLICA_NUM", replica_num, int64_t); + } + } + } + + if (OB_SUCC(ret) && replica_num > REPLICA_NUM_LIMIT) { + sql.reset(); + if (OB_FAIL(sql.assign_fmt("DELETE FROM %s WHERE snapshot_id IN " + "(SELECT snapshot_id FROM %s " + "ORDER BY gmt_create ASC " + "LIMIT %ld)", + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME, + OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_HISTORY_TNAME, + ELIMINATED_NUM))) { + LOG_WARN("fail to build sql", KR(ret)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("fail to execute sql", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (is_zero_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("affected_rows not match", KR(ret), K(user_tenant_id_), K(affected_rows), K(sql)); + } + } + + return ret; +} + +int ObTenantSnapshotTableOperator::insert_tenant_snap_ls_replica_simple_items(const ObArray &simple_items) +{ + int ret = OB_SUCCESS; + ObDMLSqlSplicer dml; + ObSqlString sql; + int64_t affected_rows = 0; + char ip_buf[OB_IP_STR_BUFF] = {'\0'}; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < simple_items.count(); i++) { + MEMSET(ip_buf, '\0', sizeof(ip_buf)); + const ObTenantSnapLSReplicaSimpleItem &simple_item = simple_items.at(i); + if (!simple_item.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(simple_item)); + } else if (!simple_item.get_addr().ip_to_string(ip_buf, sizeof(ip_buf))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ip to string failed", KR(ret), K(simple_item.get_addr())); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", simple_item.get_tenant_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", simple_item.get_tenant_snapshot_id().id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("ls_id", simple_item.get_ls_id().id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("svr_ip", ip_buf))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("svr_port", simple_item.get_addr().get_port()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("status", ls_snap_status_to_str(simple_item.get_status())))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("zone", simple_item.get_zone().ptr()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_column("unit_id", simple_item.get_unit_id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("begin_interval_scn", + simple_item.get_begin_interval_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_uint64_column("end_interval_scn", + simple_item.get_end_interval_scn().get_val_for_inner_table_field()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.finish_row())) { + LOG_WARN("fail to finish row", KR(ret), K(user_tenant_id_)); + } + } + if (FAILEDx(dml.splice_batch_insert_sql(OB_ALL_TENANT_SNAPSHOT_LS_REPLICA_TNAME, sql))) { + LOG_WARN("fail to generate sql", KR(ret), K(user_tenant_id_)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("fail to execute sql", KR(ret), K(gen_meta_tenant_id(user_tenant_id_)), K(sql)); + } else if (affected_rows != simple_items.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("affected_rows not match", KR(ret), K(user_tenant_id_), K(affected_rows), K(simple_items.count())); + } + } + return ret; +} + +int ObTenantSnapshotTableOperator::get_tenant_snap_job_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapOperation operation, + ObTenantSnapJobItem &item) +{ + int ret = OB_SUCCESS; + item.reset(); + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else { + SMART_VAR(common::ObMySQLProxy::MySQLResult, res) { + ObMySQLResult *result = nullptr; + if (OB_FAIL(sql.assign_fmt("SELECT * FROM %s WHERE tenant_id = %ld " + "AND snapshot_id = %ld AND operation = '%s'", + OB_ALL_TENANT_SNAPSHOT_JOB_TNAME, + user_tenant_id_, + tenant_snapshot_id.id(), + operation_to_str(operation)))) { + LOG_WARN("failed to assign sql", + KR(ret), K(user_tenant_id_), K(tenant_snapshot_id), K(operation)); + } else if (OB_FAIL(proxy_->read(res, gen_meta_tenant_id(user_tenant_id_), sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(sql)); + } else if (nullptr == (result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get sql result", KR(ret), K(sql)); + } else if (OB_FAIL(result->next())) { + if (OB_ITER_END == ret) { + ret = OB_ENTRY_NOT_EXIST; + } + LOG_WARN("next failed", KR(ret), K(sql)); + } else if (OB_FAIL(fill_item_from_result_(result, item))) { + LOG_WARN("fill item from result failed", KR(ret), K(sql)); + } + } + } + + return ret; +} + +int ObTenantSnapshotTableOperator::insert_tenant_snap_job_item(const ObTenantSnapJobItem &item) +{ + int ret = OB_SUCCESS; + char trace_id_buf[OB_MAX_TRACE_ID_BUFFER_SIZE] = {'\0'}; + + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + int64_t job_start_time = 0; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!item.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(item)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("add column failed", KR(ret), K(item)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", item.get_tenant_snapshot_id().id()))) { + LOG_WARN("add column failed", KR(ret), K(item)); + } else if (OB_FAIL(dml.add_pk_column("operation", operation_to_str(item.get_operation())))) { + LOG_WARN("add column failed", KR(ret), K(item)); + } else if (OB_FAIL(dml.add_time_column("job_start_time", job_start_time))) { + LOG_WARN("add column failed", KR(ret)); + } else if (FALSE_IT(item.get_trace_id().to_string(trace_id_buf, sizeof(trace_id_buf)))) { + } else if (OB_FAIL(dml.add_column("trace_id", trace_id_buf))) { + LOG_WARN("add column failed", KR(ret), K(trace_id_buf), K(item)); + } else if (OB_FAIL(dml.add_raw_time_column("majority_succ_time", item.get_majority_succ_time()))) { + LOG_WARN("add column failed", KR(ret), K(item)); + } else if (OB_FAIL(dml.splice_insert_sql(OB_ALL_TENANT_SNAPSHOT_JOB_TNAME, sql))) { + LOG_WARN("splice insert sql failed", KR(ret), K(item)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(item), K(sql), K_(user_tenant_id)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected affected rows", KR(ret), K(affected_rows)); + } + + return ret; +} + +int ObTenantSnapshotTableOperator::update_tenant_snap_job_majority_succ_time( + const ObTenantSnapshotID &tenant_snapshot_id, + const int64_t majority_succ_time) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObDMLSqlSplicer dml; + ObSqlString sql; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid() || 0 >= majority_succ_time)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), K(majority_succ_time)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", tenant_snapshot_id.id()))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("operation", operation_to_str(ObTenantSnapOperation::CREATE)))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.add_raw_time_column("majority_succ_time", majority_succ_time))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(dml.splice_update_sql(OB_ALL_TENANT_SNAPSHOT_JOB_TNAME, sql))) { + LOG_WARN("splice insert sql failed", KR(ret), K(tenant_snapshot_id), K(majority_succ_time)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K_(user_tenant_id)); + } else if (!is_single_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + + return ret; +} + +int ObTenantSnapshotTableOperator::delete_tenant_snap_job_item( + const ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + ObDMLSqlSplicer dml; + int64_t affected_rows = 0; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("tenant snapshot table operator not init", KR(ret)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", user_tenant_id_))) { + LOG_WARN("add column failed", KR(ret), K(user_tenant_id_), K(tenant_snapshot_id)); + } else if (OB_FAIL(dml.add_pk_column("snapshot_id", tenant_snapshot_id.id()))) { + LOG_WARN("add column failed", KR(ret), K(user_tenant_id_), K(tenant_snapshot_id)); + } else if (OB_FAIL(dml.splice_delete_sql(OB_ALL_TENANT_SNAPSHOT_JOB_TNAME, sql))) { + LOG_WARN("splice delete sql failed", KR(ret), K(sql), K(user_tenant_id_), K(tenant_snapshot_id)); + } else if (OB_FAIL(proxy_->write(gen_meta_tenant_id(user_tenant_id_), sql.ptr(), affected_rows))) { + LOG_WARN("exec sql failed", KR(ret), K(sql), K(user_tenant_id_), K(tenant_snapshot_id)); + } else if (!is_zero_row(affected_rows) + && !is_single_row(affected_rows) + && !is_double_row(affected_rows)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected rows", KR(ret), K(affected_rows)); + } + return ret; +} + +int ObTenantSnapshotTableOperator::encode_package_to_hex_string_(const ObLSMetaPackage& ls_meta_package, + ObArenaAllocator& allocator, + ObString& hex_str) +{ + int ret = OB_SUCCESS; + char* buf = nullptr; + int64_t buf_len = ls_meta_package.get_serialize_size(); + int64_t pos = 0; + int64_t need_len = 0; + + if (!ls_meta_package.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_meta_package)); + } else if (OB_ISNULL(buf = static_cast(allocator.alloc(buf_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory", KR(ret), K(buf_len)); + } else if (OB_FAIL(ls_meta_package.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize", KR(ret)); + } else if (OB_FAIL(ObHexUtilsBase::hex(hex_str, allocator, buf, buf_len))) { + LOG_WARN("fail to hex", KR(ret)); + } + + return ret; +} + +int ObTenantSnapshotTableOperator::decode_hex_string_to_package_(const ObString& hex_str, + ObArenaAllocator& allocator, + ObLSMetaPackage& ls_meta_package) +{ + int ret = OB_SUCCESS; + char *unhex_buf = nullptr; + int64_t unhex_buf_len = 0; + int64_t pos = 0; + + if (hex_str.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(hex_str)); + } else if (OB_FAIL(ObHexUtilsBase::unhex(hex_str, allocator, unhex_buf, unhex_buf_len))) { + LOG_WARN("fail to unhex", KR(ret), K(hex_str)); + } else if (OB_FAIL(ls_meta_package.deserialize(unhex_buf, unhex_buf_len, pos))) { + LOG_WARN("deserialize ls meta package failed", KR(ret), K(hex_str)); + } + + return ret; +} diff --git a/src/share/tenant_snapshot/ob_tenant_snapshot_table_operator.h b/src/share/tenant_snapshot/ob_tenant_snapshot_table_operator.h new file mode 100644 index 0000000000..fba066003e --- /dev/null +++ b/src/share/tenant_snapshot/ob_tenant_snapshot_table_operator.h @@ -0,0 +1,487 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_SHARE_OB_TENANT_SNAPSHOT_TABLE_OPERATOR_H_ +#define OCEANBASE_SHARE_OB_TENANT_SNAPSHOT_TABLE_OPERATOR_H_ + +#include "storage/ls/ob_ls_meta_package.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" + +namespace oceanbase +{ +namespace share +{ +// Attention!!! +// if a tenant_snapshot is created failed, the status of it is DELETING rather than FAILED. +// only if a tmp snapshot for fork tenant (a type of tenant clone job) is created failed, +// the snapshot will be set as FAILED. +// And this type of snapshot will be recycled after user executes the recycle sql for clone_job. +enum class ObTenantSnapStatus : int64_t +{ + CREATING = 0, + DECIDED, + NORMAL, + RESTORING, + DELETING, + FAILED, + MAX, +}; + +enum class ObLSSnapStatus : int64_t +{ + CREATING = 0, + NORMAL, + RESTORING, + FAILED, + MAX, +}; + +enum class ObTenantSnapType : int64_t +{ + AUTO, + MANUAL, + MAX, +}; + +enum class ObTenantSnapOperation : int64_t +{ + CREATE = 0, + DELETE, + MAX, +}; + +struct ObTenantSnapJobItem +{ +public: + ObTenantSnapJobItem() : tenant_id_(OB_INVALID_TENANT_ID), + tenant_snapshot_id_(), + operation_(ObTenantSnapOperation::MAX), + job_start_time_(OB_INVALID_TIMESTAMP), + trace_id_(), + majority_succ_time_(OB_INVALID_TIMESTAMP) {} + ObTenantSnapJobItem(uint64_t tenant_id, + ObTenantSnapshotID tenant_snapshot_id, + ObTenantSnapOperation operation, + const common::ObCurTraceId::TraceId& trace_id) : + tenant_id_(tenant_id), + tenant_snapshot_id_(tenant_snapshot_id), + operation_(operation), + job_start_time_(OB_INVALID_TIMESTAMP), + trace_id_(trace_id), + majority_succ_time_(OB_INVALID_TIMESTAMP) {} + int assign(const ObTenantSnapJobItem &other); + ObTenantSnapJobItem &operator=(const ObTenantSnapJobItem &other) = delete; + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(tenant_id), K_(tenant_snapshot_id), K_(operation), + K_(job_start_time), K_(trace_id), K_(majority_succ_time)); + +public: + uint64_t get_tenant_id() const { return tenant_id_; } + void set_tenant_id(const uint64_t tenant_id) { tenant_id_ = tenant_id; } + ObTenantSnapshotID get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + void set_tenant_snapshot_id(const ObTenantSnapshotID tenant_snapshot_id) + { + tenant_snapshot_id_ = tenant_snapshot_id; + } + + ObTenantSnapOperation get_operation() const { return operation_; } + void set_operation(ObTenantSnapOperation operation) { operation_ = operation; } + + const common::ObCurTraceId::TraceId& get_trace_id() const { return trace_id_; } + void set_trace_id(common::ObCurTraceId::TraceId& trace_id) { trace_id_ = trace_id; } + + int64_t get_job_start_time() const { return job_start_time_; } + void set_job_start_time(int64_t job_start_time) { job_start_time_ = job_start_time; } + + int64_t get_majority_succ_time() const { return majority_succ_time_; } + void set_majority_succ_time(const int64_t majority_succ_time) + { + majority_succ_time_ = majority_succ_time; + } + +private: + uint64_t tenant_id_; + ObTenantSnapshotID tenant_snapshot_id_; + ObTenantSnapOperation operation_; + int64_t job_start_time_; + common::ObCurTraceId::TraceId trace_id_; + int64_t majority_succ_time_; +}; + +struct ObCreateSnapshotJob +{ +public: + ObCreateSnapshotJob() : create_active_ts_(OB_INVALID_TIMESTAMP), + create_expire_ts_(OB_INVALID_TIMESTAMP), + paxos_replica_num_(OB_INVALID_COUNT), + arbitration_service_status_(), + job_item_() {} + ~ObCreateSnapshotJob() {} + + int init(const int64_t create_active_ts, + const int64_t create_expire_ts, + const int64_t paxos_replica_num, + const ObArbitrationServiceStatus &arbitration_service_status, + const ObTenantSnapJobItem& job_item); + + void reset(); + int assign(const ObCreateSnapshotJob& other); + bool is_valid() const { return job_item_.is_valid() + && OB_INVALID_TIMESTAMP != create_active_ts_ + && OB_INVALID_TIMESTAMP != create_expire_ts_ + && OB_INVALID_COUNT != paxos_replica_num_ + && arbitration_service_status_.is_valid(); } + +public: + int64_t get_create_active_ts() const { return create_active_ts_; } + int64_t get_create_expire_ts() const { return create_expire_ts_; } + int64_t get_paxos_replica_num() const { return paxos_replica_num_; } + const ObArbitrationServiceStatus &get_arbitration_service_status() const { return arbitration_service_status_; } + ObTenantSnapshotID get_tenant_snapshot_id() const { return job_item_.get_tenant_snapshot_id(); } + int64_t get_majority_succ_time() const { return job_item_.get_majority_succ_time(); } + const common::ObCurTraceId::TraceId& get_trace_id() const { return job_item_.get_trace_id(); } + + TO_STRING_KV(K_(create_active_ts), + K_(create_expire_ts), + K_(paxos_replica_num), + K_(arbitration_service_status), + K_(job_item)); +private: + int64_t create_active_ts_; + int64_t create_expire_ts_; + int64_t paxos_replica_num_; + ObArbitrationServiceStatus arbitration_service_status_; + ObTenantSnapJobItem job_item_; +}; + +struct ObDeleteSnapshotJob +{ +public: + ObDeleteSnapshotJob() : job_item_() {} +public: + ObTenantSnapshotID get_tenant_snapshot_id() const { return job_item_.get_tenant_snapshot_id(); } + const common::ObCurTraceId::TraceId& get_trace_id() const { return job_item_.get_trace_id(); } + int64_t get_job_start_time() const { return job_item_.get_job_start_time(); } + + int init(const ObTenantSnapJobItem& job_item); + void reset(); + int assign(const ObDeleteSnapshotJob& other); + bool is_valid() const { return job_item_.is_valid(); } + + TO_STRING_KV(K_(job_item)); +private: + ObTenantSnapJobItem job_item_; +}; + +struct ObTenantSnapItem +{ +public: + ObTenantSnapItem(); +public: + uint64_t get_tenant_id() const { return tenant_id_; } + const ObTenantSnapshotID &get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + const char *get_snapshot_name() const { return snapshot_name_; } + const ObTenantSnapStatus &get_status() const { return status_; } + void set_status(const ObTenantSnapStatus &status) { status_ = status; } + const SCN &get_snapshot_scn() const { return snapshot_scn_; } + void set_snapshot_scn(const SCN &snapshot_scn) { snapshot_scn_ = snapshot_scn; } + const SCN &get_clog_start_scn() const { return clog_start_scn_; } + const ObTenantSnapType &get_type() const { return type_; } + int64_t get_create_time() const { return create_time_; } + void set_create_time(const int64_t create_time) { create_time_ = create_time; } + uint64_t get_data_version() const { return data_version_; } + void set_owner_job_id(const int64_t owner_job_id) { owner_job_id_ = owner_job_id; } + int64_t get_owner_job_id() const { return owner_job_id_; } + int init(const uint64_t tenant_id, + const ObTenantSnapshotID &snapshot_id, + const ObString &snapshot_name, + const ObTenantSnapStatus &status, + const SCN &snapshot_scn, + const SCN &clog_start_scn, + const ObTenantSnapType &type, + const int64_t create_time, + const uint64_t data_version, + const int64_t owner_job_id); + int assign(const ObTenantSnapItem &other); + void reset(); + bool is_valid() const { return OB_INVALID_TENANT_ID != tenant_id_ + && tenant_snapshot_id_.is_valid() + && ObTenantSnapStatus::MAX != status_; } + TO_STRING_KV(K_(tenant_id), K_(tenant_snapshot_id), K_(snapshot_name), + K_(status), K_(snapshot_scn), K_(clog_start_scn), + K_(type), K_(create_time), K_(data_version), + K_(owner_job_id)); +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapItem); +private: + uint64_t tenant_id_; + ObTenantSnapshotID tenant_snapshot_id_; + char snapshot_name_[common::OB_MAX_TENANT_SNAPSHOT_NAME_LENGTH + 1]; + ObTenantSnapStatus status_; + SCN snapshot_scn_; + SCN clog_start_scn_; + ObTenantSnapType type_; + int64_t create_time_; + uint64_t data_version_; + // when the status_ is RESTORING, the clone_job id will be owner_job_id of "global_lock"(snapshot_id == 0) + // for the other status or the other snapshot, the owner_job_id always be OB_INVALID_ID + int64_t owner_job_id_; +}; + +struct ObTenantSnapLSItem { +public: + ObTenantSnapLSItem() : tenant_id_(OB_INVALID_TENANT_ID), + tenant_snapshot_id_(), + ls_attr_() {} +public: + uint64_t get_tenant_id() const { return tenant_id_; } + const ObTenantSnapshotID &get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + const ObLSAttr &get_ls_attr() const { return ls_attr_; } + int init(const uint64_t tenant_id, + const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSAttr &ls_attr); + int assign(const ObTenantSnapLSItem &other); + void reset(); + bool is_valid() const { return OB_INVALID_TENANT_ID != tenant_id_ + && tenant_snapshot_id_.is_valid() + && ls_attr_.is_valid(); } + TO_STRING_KV(K_(tenant_id), K_(tenant_snapshot_id), K_(ls_attr)); +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapLSItem); +private: + uint64_t tenant_id_; + ObTenantSnapshotID tenant_snapshot_id_; + ObLSAttr ls_attr_; +}; + +struct ObTenantSnapLSReplicaSimpleItem { +public: + ObTenantSnapLSReplicaSimpleItem(); +public: + uint64_t get_tenant_id() const { return tenant_id_; } + const ObTenantSnapshotID &get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + const ObLSID &get_ls_id() const { return ls_id_; } + const ObAddr &get_addr() const { return addr_; } + void set_status(const ObLSSnapStatus &status) { status_ = status; } + const ObLSSnapStatus &get_status() const { return status_; } + void set_zone(const ObZone &zone) { zone_ = zone; } + const ObZone &get_zone() const { return zone_; } + void set_unit_id(const uint64_t unit_id) { unit_id_ = unit_id; } + uint64_t get_unit_id() const { return unit_id_; } + void set_begin_interval_scn(const SCN &begin_interval_scn) { begin_interval_scn_ = begin_interval_scn; } + const SCN &get_begin_interval_scn() const { return begin_interval_scn_; } + void set_end_interval_scn(const SCN &end_interval_scn) { end_interval_scn_ = end_interval_scn; } + const SCN &get_end_interval_scn() const { return end_interval_scn_; } + int init(const uint64_t tenant_id, + const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + const common::ObAddr &addr, + const ObLSSnapStatus &status, + const common::ObZone &zone, + const uint64_t unit_id, + const SCN &begin_interval_scn, + const SCN &end_interval_scn); + int assign(const ObTenantSnapLSReplicaSimpleItem &other); + void reset(); + bool is_valid() const { return OB_INVALID_TENANT_ID != tenant_id_ + && tenant_snapshot_id_.is_valid() + && ls_id_.is_valid() + && addr_.is_valid() + && ObLSSnapStatus::MAX != status_; } + TO_STRING_KV(K_(tenant_id), K_(tenant_snapshot_id), K_(ls_id), + K_(addr), K_(status), K_(zone), K_(unit_id), + K_(begin_interval_scn), K_(end_interval_scn)); +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapLSReplicaSimpleItem); +private: + uint64_t tenant_id_; + ObTenantSnapshotID tenant_snapshot_id_; + ObLSID ls_id_; + common::ObAddr addr_; + ObLSSnapStatus status_; + common::ObZone zone_; + uint64_t unit_id_; + SCN begin_interval_scn_; + SCN end_interval_scn_; +}; + +struct ObTenantSnapLSReplicaItem { +public: + ObTenantSnapLSReplicaSimpleItem s_; + ObLSMetaPackage ls_meta_package_; +public: + ObTenantSnapLSReplicaItem() : s_(), ls_meta_package_() {} + int assign(const ObTenantSnapLSReplicaItem &other); + bool is_valid() const { return s_.is_valid(); } + void reset() { s_.reset(); ls_meta_package_.reset(); } + TO_STRING_KV(K_(s), K_(ls_meta_package)); +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapLSReplicaItem); +}; + +//TODO: Eliminate redundancy and simplify functions +class ObTenantSnapshotTableOperator +{ +public: + ObTenantSnapshotTableOperator(); + int init(const uint64_t user_tenant_id, ObISQLClient *proxy); + +public: + ObTenantSnapStatus str_to_tenant_snap_status(const ObString &status_str); + const char* tenant_snap_status_to_str(const ObTenantSnapStatus &status); + ObLSSnapStatus str_to_ls_snap_status(const ObString &status_str); + const char* ls_snap_status_to_str(const ObLSSnapStatus &status); + + ObTenantSnapType str_to_type(const ObString &type_str); + const char* type_to_str(const ObTenantSnapType &type); + + ObTenantSnapOperation str_to_operation(const ObString &str); + const char* operation_to_str(const ObTenantSnapOperation &operation); + + //************************OB_ALL_TENANT_SNAPSHOTS_TNAME********************************** + /*for special record in inner table __all_tenant_snapshots*/ + int insert_tenant_snap_item(const ObTenantSnapItem& item); + int get_tenant_snap_item(const ObTenantSnapshotID &snapshot_id, + const bool need_lock, + ObTenantSnapItem &item); + int get_tenant_snap_item(const ObString &snapshot_name, + const bool need_lock, + ObTenantSnapItem &item); + int get_all_user_tenant_snap_items(ObArray &items); + //for the item (snapshot = OB_TENANT_SNAPSHOT_GLOBAL_STATE) + //Note: if new_snapshot_scn use default value(invalid scn), we will not update column "snapshot_scn" + // if new_create_time use default value(OB_INVALID_TIMESTAMP), we will not update column "create_time" + int update_special_tenant_snap_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapStatus &old_status, + const ObTenantSnapStatus &new_status, + const int64_t owner_job_id, + const SCN &new_snapshot_scn = SCN::invalid_scn(), + const int64_t new_create_time = OB_INVALID_TIMESTAMP); + int update_tenant_snap_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapStatus &old_status, + const ObTenantSnapStatus &new_status, + const SCN &new_snapshot_scn = SCN::invalid_scn(), + const SCN &new_clog_start_scn = SCN::invalid_scn()); + int update_tenant_snap_item(const ObString &snapshot_name, + const ObTenantSnapStatus &old_status, + const ObTenantSnapStatus &new_status); + int update_tenant_snap_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapStatus &old_status_1, + const ObTenantSnapStatus &old_status_2, + const ObTenantSnapStatus &new_status); + int delete_tenant_snap_item(const ObTenantSnapshotID &snapshot_id); + //**************************************************************************************** + + //**********************OB_ALL_TENANT_SNAPSHOT_LS_TNAME*********************************** + int insert_tenant_snap_ls_items(const ObArray &items); + int delete_tenant_snap_ls_items(const ObTenantSnapshotID &snapshot_id); + int get_tenant_snap_ls_items(const ObTenantSnapshotID &tenant_snapshot_id, + ObArray &items); + int get_tenant_snap_ls_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObTenantSnapLSItem &item); + //**************************************************************************************** + + //******************OB_ALL_TENANT_SNAPSHOT_LS_META_TABLE_TNAME**************************** + int get_tenant_snap_related_addrs(const ObTenantSnapshotID &tenant_snapshot_id, + ObArray &addrs); + int get_proper_ls_meta_package(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObLSMetaPackage& ls_meta_package); + int get_ls_meta_package(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + const ObAddr& addr, + ObLSMetaPackage& ls_meta_package); + //get all simple_items by tenant_snapshot_id + int get_tenant_snap_ls_replica_simple_items(const ObTenantSnapshotID &tenant_snapshot_id, + ObArray &simple_items); + //get all simple_items by tenant_snapshot_id and addr + int get_tenant_snap_ls_replica_simple_items(const ObTenantSnapshotID &tenant_snapshot_id, + const common::ObAddr& addr, + ObArray &simple_items); + //get simple_item by tenant_snapshot_id and ls_id and addr + int get_tenant_snap_ls_replica_simple_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + const ObAddr& addr, + const bool need_lock, + ObTenantSnapLSReplicaSimpleItem &simple_item); + //get all simple_items by tenant_snapshot_id and ls_id + int get_tenant_snap_ls_replica_simple_items(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObArray &simple_items); + int get_tenant_snap_ls_replica_simple_items(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + const ObLSSnapStatus &status, + ObArray &simple_items); + + int delete_tenant_snap_ls_replica_items(const ObTenantSnapshotID &snapshot_id); + int insert_tenant_snap_ls_replica_simple_items(const ObArray &simple_items); + int update_tenant_snap_ls_replica_item(const ObTenantSnapLSReplicaSimpleItem &simple_item, + const ObLSMetaPackage* ls_meta_package); + //**************************************************************************************** + + //******************OB_ALL_TENANT_SNAPSHOT_LS_META_TABLE_TNAME**************************** + int archive_tenant_snap_ls_replica_history(const ObTenantSnapshotID &snapshot_id); + int eliminate_tenant_snap_ls_replica_history(); + //**************************************************************************************** + + //******************OB_ALL_TENANT_SNAPSHOT_CREATE_JOB_TNAME**************************** + int get_tenant_snap_job_item(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapOperation operation, + ObTenantSnapJobItem &item); + int insert_tenant_snap_job_item(const ObTenantSnapJobItem &item); + int update_tenant_snap_job_majority_succ_time(const ObTenantSnapshotID &tenant_snapshot_id, + const int64_t majority_succ_time); + int delete_tenant_snap_job_item(const ObTenantSnapshotID &snapshot_id); + +private: + int get_tenant_snap_ls_replica_simple_items_(const ObSqlString &sql, + ObArray &simple_items); + int fill_item_from_result_(const common::sqlclient::ObMySQLResult *result, + ObTenantSnapItem &item); + int fill_item_from_result_(const common::sqlclient::ObMySQLResult *result, + ObTenantSnapLSItem &item); + int fill_item_from_result_(const common::sqlclient::ObMySQLResult *result, + ObTenantSnapLSReplicaSimpleItem &simple_item); + int fill_item_from_result_(const common::sqlclient::ObMySQLResult *result, + ObTenantSnapJobItem &item); + int encode_package_to_hex_string_(const ObLSMetaPackage& ls_meta_package, + ObArenaAllocator& allocator, + ObString& hex_str); + int decode_hex_string_to_package_(const ObString& hex_str, + ObArenaAllocator& allocator, + ObLSMetaPackage& ls_meta_package); + //**************************************************************************************** +public: + static const int64_t GLOBAL_STATE_ID = 0; + static constexpr const char *GLOBAL_STATE_NAME = "_snapshot_global_state"; + +private: + static const char* TENANT_SNAP_STATUS_ARRAY[]; + static const char* LS_SNAP_STATUS_ARRAY[]; + static const char* TENANT_SNAP_TYPE_ARRAY[]; + static const char* TENANT_SNAP_OPERATION_ARRAY[]; + static constexpr const char* INVALID_STR = "invalid"; + +private: + bool is_inited_; + uint64_t user_tenant_id_; + ObISQLClient *proxy_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapshotTableOperator); +}; + +} +} + +#endif /* OCEANBASE_SHARE_OB_TENANT_SNAPSHOT_TABLE_OPERATOR_H_ */ diff --git a/src/share/unit/ob_unit_info.h b/src/share/unit/ob_unit_info.h index 84db6cfd0c..b2bf0376b1 100644 --- a/src/share/unit/ob_unit_info.h +++ b/src/share/unit/ob_unit_info.h @@ -112,6 +112,7 @@ public: uint64_t get_unit_group_id() const { return unit_group_id_; } ObUnit::Status get_status() const { return status_; } TO_STRING_KV(K_(unit_group_id), K_(status)); + bool operator<(const ObSimpleUnitGroup &that) { return unit_group_id_ < that.unit_group_id_; } private: uint64_t unit_group_id_; ObUnit::Status status_; diff --git a/src/sql/CMakeLists.txt b/src/sql/CMakeLists.txt index ee47e37780..833166eb39 100644 --- a/src/sql/CMakeLists.txt +++ b/src/sql/CMakeLists.txt @@ -195,6 +195,7 @@ ob_set_subtarget(ob_sql engine_cmd engine/cmd/ob_profile_cmd_executor.cpp engine/cmd/ob_resource_executor.cpp engine/cmd/ob_restore_executor.cpp + engine/cmd/ob_clone_executor.cpp engine/cmd/ob_role_cmd_executor.cpp engine/cmd/ob_routine_executor.cpp engine/cmd/ob_sequence_executor.cpp @@ -214,6 +215,7 @@ ob_set_subtarget(ob_sql engine_cmd engine/cmd/ob_context_executor.cpp engine/cmd/ob_table_direct_insert_ctx.cpp engine/cmd/ob_table_direct_insert_service.cpp + engine/cmd/ob_tenant_snapshot_executor.cpp ) @@ -969,6 +971,8 @@ ob_set_subtarget(ob_sql resolver_cmd resolver/cmd/ob_variable_set_resolver.cpp resolver/cmd/ob_variable_set_stmt.cpp resolver/cmd/ob_alter_system_resolver.cpp + resolver/cmd/ob_tenant_snapshot_resolver.cpp + resolver/cmd/ob_tenant_clone_resolver.cpp ) ob_set_subtarget(ob_sql resolver_dcl diff --git a/src/sql/das/ob_das_location_router.cpp b/src/sql/das/ob_das_location_router.cpp index 8e04c75152..2e12f6c503 100755 --- a/src/sql/das/ob_das_location_router.cpp +++ b/src/sql/das/ob_das_location_router.cpp @@ -1127,7 +1127,7 @@ OB_NOINLINE int ObDASLocationRouter::get_vt_ls_location(uint64_t table_id, ObReplicaProperty mock_prop; ObLSReplicaLocation ls_replica; ObAddr server; - ObLSRestoreStatus restore_status(ObLSRestoreStatus::RESTORE_NONE); + ObLSRestoreStatus restore_status(ObLSRestoreStatus::NONE); if (OB_FAIL(location.init(GCONF.cluster_id, MTL_ID(), ObLSID(ObLSID::VT_LS_ID), now))) { LOG_WARN("init location failed", KR(ret)); } else if (OB_FAIL(server_pair->get_server_by_tablet_id(tablet_id, server))) { @@ -1247,7 +1247,7 @@ int ObDASLocationRouter::get_external_table_ls_location(ObLSLocation &location) int64_t now = ObTimeUtility::current_time(); ObReplicaProperty mock_prop; ObLSReplicaLocation ls_replica; - ObLSRestoreStatus ls_restore_status(ObLSRestoreStatus::RESTORE_NONE); + ObLSRestoreStatus ls_restore_status(ObLSRestoreStatus::NONE); OZ (location.init(GCONF.cluster_id, MTL_ID(), ObLSID(ObLSID::VT_LS_ID), now)); OZ (ls_replica.init(GCTX.self_addr(), common::LEADER, GCONF.mysql_port, REPLICA_TYPE_FULL, diff --git a/src/sql/engine/cmd/ob_alter_system_executor.cpp b/src/sql/engine/cmd/ob_alter_system_executor.cpp index 41d2b1d696..27d7ad85a9 100644 --- a/src/sql/engine/cmd/ob_alter_system_executor.cpp +++ b/src/sql/engine/cmd/ob_alter_system_executor.cpp @@ -46,6 +46,7 @@ #include "sql/plan_cache/ob_plan_cache.h" #include "sql/plan_cache/ob_ps_cache.h" #include "share/table/ob_ttl_util.h" +#include "rootserver/restore/ob_tenant_clone_util.h" namespace oceanbase { using namespace common; @@ -2699,5 +2700,52 @@ int ObResetConfigExecutor::execute(ObExecContext &ctx, ObResetConfigStmt &stmt) return ret; } +int ObCancelCloneExecutor::execute(ObExecContext &ctx, ObCancelCloneStmt &stmt) +{ + int ret = OB_SUCCESS; + ObTaskExecutorCtx *task_exec_ctx = NULL; + common::ObMySQLProxy *sql_proxy = nullptr; + const ObString &clone_tenant_name = stmt.get_clone_tenant_name(); + bool clone_already_finish = false; + + if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) { + ret = OB_NOT_INIT; + LOG_WARN("get task executor context failed", KR(ret)); + } else if (OB_ISNULL(sql_proxy = ctx.get_sql_proxy())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy must not be null", KR(ret)); + } else { + ObSchemaGetterGuard guard; + const ObTenantSchema *tenant_schema = nullptr; + if (OB_FAIL(GSCHEMASERVICE.get_tenant_schema_guard(OB_SYS_TENANT_ID, guard))) { + LOG_WARN("failed to get sys tenant schema guard", KR(ret)); + } else if (OB_FAIL(guard.get_tenant_info(clone_tenant_name, tenant_schema))) { + LOG_WARN("failed to get tenant info", KR(ret), K(stmt)); + } else if (OB_ISNULL(tenant_schema)) { + LOG_INFO("tenant not exist", KR(ret), K(clone_tenant_name)); + } else if (tenant_schema->is_normal()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("the new tenant has completed the cloning operation", KR(ret), K(clone_tenant_name)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "The new tenant has completed the cloning operation, " + "or this is not the name of a cloning tenant. " + "Cancel cloning"); + } + } + + if (FAILEDx(rootserver::ObTenantCloneUtil::cancel_clone_job(*sql_proxy, + clone_tenant_name, + clone_already_finish))) { + LOG_WARN("cancel clone job failed", KR(ret), K(clone_tenant_name)); + } else if (clone_already_finish) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("the new tenant has completed the cloning operation", KR(ret), K(clone_tenant_name)); + LOG_USER_ERROR(OB_OP_NOT_ALLOW, "The new tenant has completed the cloning operation, " + "or this is not the name of a cloning tenant. " + "Cancel cloning"); + } + + return ret; +} + } // end namespace sql } // end namespace oceanbase diff --git a/src/sql/engine/cmd/ob_alter_system_executor.h b/src/sql/engine/cmd/ob_alter_system_executor.h index 0951ee170a..5d2b93a33a 100644 --- a/src/sql/engine/cmd/ob_alter_system_executor.h +++ b/src/sql/engine/cmd/ob_alter_system_executor.h @@ -138,6 +138,8 @@ DEF_SIMPLE_EXECUTOR(ObCheckpointSlog); DEF_SIMPLE_EXECUTOR(ObBootstrap); DEF_SIMPLE_EXECUTOR(ObResetConfig); +DEF_SIMPLE_EXECUTOR(ObCancelClone); + class ObCancelTaskExecutor { public: diff --git a/src/sql/engine/cmd/ob_clone_executor.cpp b/src/sql/engine/cmd/ob_clone_executor.cpp new file mode 100644 index 0000000000..cce07af095 --- /dev/null +++ b/src/sql/engine/cmd/ob_clone_executor.cpp @@ -0,0 +1,189 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SQL_ENG +#include "share/ob_common_rpc_proxy.h" +#include "sql/engine/ob_exec_context.h" +#include "sql/engine/cmd/ob_clone_executor.h" +#include "sql/resolver/cmd/ob_tenant_clone_stmt.h" +#include "share/restore/ob_tenant_clone_table_operator.h" +#include "rootserver/restore/ob_tenant_clone_util.h" + +namespace oceanbase +{ +using namespace common; +using namespace share; +using namespace share::schema; +using namespace rootserver; +namespace sql +{ + +int ObCloneTenantExecutor::execute(ObExecContext &ctx, ObCloneTenantStmt &stmt) +{ + int ret = OB_SUCCESS; + ObTaskExecutorCtx *task_exec_ctx = NULL; + obrpc::ObCommonRpcProxy *common_rpc_proxy = NULL; + const obrpc::ObCloneTenantArg &clone_tenant_arg = stmt.get_clone_tenant_arg(); + obrpc::ObCloneTenantRes clone_tenant_res; + const int64_t abs_timeout = ObTimeUtility::current_time() + GCONF._ob_ddl_timeout; + THIS_WORKER.set_timeout_ts(abs_timeout); + + if (OB_ISNULL(task_exec_ctx = GET_TASK_EXECUTOR_CTX(ctx))) { + ret = OB_NOT_INIT; + LOG_WARN("get task executor context failed", KR(ret)); + } else if (true == stmt.get_if_not_exists()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("if not exists is true", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "clone tenant with IF NOT EXISTS"); + } else if (OB_ISNULL(ctx.get_physical_plan_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("physical plan ctx is null", KR(ret)); + } else if (FALSE_IT(ctx.get_physical_plan_ctx()->set_timeout_timestamp(abs_timeout))) { + } else if (OB_ISNULL(common_rpc_proxy = task_exec_ctx->get_common_rpc())) { + ret = OB_NOT_INIT; + LOG_WARN("get common rpc proxy failed", KR(ret)); + } else if (!clone_tenant_arg.get_tenant_snapshot_name().empty()) { + // TODO: support tenant snapshot in future + ret = OB_NOT_SUPPORTED; + LOG_WARN("clone tenant with using snapshot clause is not supported", KR(ret), K(clone_tenant_arg)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "clone tenant with using snapshot clause is"); + } else if (OB_FAIL(common_rpc_proxy->clone_tenant(clone_tenant_arg, clone_tenant_res))) { + LOG_WARN("rpc proxy clone tenant failed", KR(ret), K(clone_tenant_arg)); + } else if (!clone_tenant_res.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is not valid", KR(ret), K(clone_tenant_res)); + } else if (OB_FAIL(wait_clone_tenant_finished_(ctx, clone_tenant_res.get_job_id()))) { + LOG_WARN("wait clone tenant finish failed", KR(ret), K(clone_tenant_res)); + } + return ret; +} + +ERRSIM_POINT_DEF(ERRSIM_WAIT_CLONE_TENANT_FINISHED_ERROR); +int ObCloneTenantExecutor::wait_clone_tenant_finished_(ObExecContext &ctx, + const int64_t job_id) +{ + int ret = OB_SUCCESS; + ObCloneJob job; + common::ObMySQLProxy *sql_proxy = nullptr; + ObTimeoutCtx timeout_ctx; + const int64_t trx_timeout = 10 * 60 * 1000 * 1000; // 10min + const int64_t abs_timeout = ObTimeUtility::current_time() + OB_MAX_USER_SPECIFIED_TIMEOUT; // 102 years + THIS_WORKER.set_timeout_ts(abs_timeout); + + if (OB_UNLIKELY(ERRSIM_WAIT_CLONE_TENANT_FINISHED_ERROR)) { + ret = ERRSIM_WAIT_CLONE_TENANT_FINISHED_ERROR; + } else if (OB_UNLIKELY(job_id < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(job_id)); + } else if (OB_ISNULL(ctx.get_physical_plan_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("physical plan ctx is null", KR(ret)); + } else if (FALSE_IT(ctx.get_physical_plan_ctx()->set_timeout_timestamp(abs_timeout))) { + } else if (OB_FAIL(timeout_ctx.set_trx_timeout_us(trx_timeout))) { + LOG_WARN("failed to set trx timeout us", KR(ret)); + } else if (OB_FAIL(timeout_ctx.set_abs_timeout(abs_timeout))) { + LOG_WARN("failed to set abs timeout", KR(ret)); + } else if (OB_ISNULL(sql_proxy = ctx.get_sql_proxy())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy must not be null", KR(ret)); + } else { + // if the clone job is successful, + // the according record will be moved to __all_clone_job_history from __all_clone_job; + // if the clone job is failed, + // the according record will be set as failed status in __all_clone_job and + // will be moved to __all_clone_job_history after user executes the "recycle" sql + bool clone_over = false; + while (OB_SUCC(ret) && !clone_over) { + job.reset(); + ob_usleep(2 * 1000 * 1000L); // 2s + ObTenantCloneTableOperator table_op; + ObMySQLTransaction trans; + bool exist_in_history = false; + + if (THIS_WORKER.is_timeout()) { + ret = OB_TIMEOUT; + LOG_WARN("wait clone tenant timeout", KR(ret), K(job_id)); + } else if (OB_FAIL(ctx.check_status())) { + LOG_WARN("check exec ctx failed", KR(ret)); + } else if (OB_FAIL(trans.start(sql_proxy, OB_SYS_TENANT_ID))) { + LOG_WARN("fail to start trans", KR(ret)); + } else if (OB_FAIL(table_op.init(OB_SYS_TENANT_ID, &trans))) { + LOG_WARN("failed to init table op", KR(ret)); + } else if (OB_FAIL(table_op.get_sys_clone_job_history(job_id, job))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get clone job history", KR(ret), K(job_id)); + } + } else { + exist_in_history = true; + if (job.get_status().is_sys_success_status()) { + clone_over = true; + LOG_INFO("clone tenant successful", K(job)); + } else if (job.get_status().is_sys_failed_status()) { + ret = OB_ERR_CLONE_TENANT; + LOG_WARN("clone tenant failed", KR(ret), K(job)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected status", KR(ret), K(job)); + } + } + + if (OB_SUCC(ret) && !exist_in_history) { + int tmp_ret = OB_SUCCESS; + if (OB_FAIL(table_op.get_clone_job_by_job_id(job_id, job))) { + LOG_WARN("failed to get clone job", KR(ret), K(job)); + } else if (job.get_status().is_sys_failed_status()) { + ret = OB_ERR_CLONE_TENANT; + LOG_WARN("clone tenant failed", KR(ret), K(job)); + } else if (OB_TMP_FAIL(ObTenantCloneUtil::notify_clone_scheduler(OB_SYS_TENANT_ID))) { + // clone job is running + LOG_WARN("notify clone scheduler failed", KR(tmp_ret)); + } + } + + if (OB_UNLIKELY(OB_TIMEOUT == ret)) { + ret = OB_CLONE_TENANT_TIMEOUT; + LOG_WARN("wait clone tenant timeout", KR(ret), K(job_id)); + ObString msg("Please check the details of clone job by DBA_OB_CLONE_PROGRESS or DBA_OB_CLONE_HISTORY"); + LOG_USER_ERROR(OB_CLONE_TENANT_TIMEOUT, msg.length(), msg.ptr()); + } else if (OB_UNLIKELY(OB_ERR_CLONE_TENANT == ret)) { + int tmp_ret = OB_SUCCESS; + ObArenaAllocator allocator; + ObString err_msg; + if (OB_TMP_FAIL(ObTenantCloneUtil::get_clone_job_failed_message(*sql_proxy, + job_id, + MTL_ID(), + allocator, + err_msg))) { + LOG_WARN("fail to get clone job failed message", KR(ret), K(job_id), K(MTL_ID())); + } else if (!err_msg.empty()) { + LOG_USER_ERROR(OB_ERR_CLONE_TENANT, err_msg.length(), err_msg.ptr()); + } else { + ObSqlString format_msg; + ObString failed_status(ObTenantCloneStatus::get_clone_status_str(job.get_status())); + if (OB_TMP_FAIL(format_msg.append_fmt("Tenant clone job failed during the %.*s stage. " + "Please check the details of clone job by " + "DBA_OB_CLONE_PROGRESS or DBA_OB_CLONE_HISTORY", + failed_status.length(), failed_status.ptr()))) { + LOG_WARN("fail to append format", KR(tmp_ret), K(job_id), K(MTL_ID())); + } + LOG_USER_ERROR(OB_ERR_CLONE_TENANT, format_msg.string().length(), format_msg.ptr()); + } + } + } + } + return ret; +} + +} //end namespace sql +} //end namespace oceanbase diff --git a/src/sql/engine/cmd/ob_clone_executor.h b/src/sql/engine/cmd/ob_clone_executor.h new file mode 100644 index 0000000000..02a052ff41 --- /dev/null +++ b/src/sql/engine/cmd/ob_clone_executor.h @@ -0,0 +1,39 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_SQL_OB_CLONE_EXECUTOR_ +#define OCEANBASE_SQL_OB_CLONE_EXECUTOR_ + +namespace oceanbase +{ +namespace sql +{ +class ObExecContext; +class ObCloneTenantStmt; + +class ObCloneTenantExecutor +{ +public: + ObCloneTenantExecutor() {} + virtual ~ObCloneTenantExecutor() {} + int execute(ObExecContext &ctx, ObCloneTenantStmt &stmt); + int wait_clone_tenant_finished_(ObExecContext &ctx, + const int64_t job_id); +private: + DISALLOW_COPY_AND_ASSIGN(ObCloneTenantExecutor); +}; + +} //end namespace sql +} //end namespace oceanbase + + +#endif //OCEANBASE_SQL_OB_CLONE_EXECUTOR_ diff --git a/src/sql/engine/cmd/ob_tenant_snapshot_executor.cpp b/src/sql/engine/cmd/ob_tenant_snapshot_executor.cpp new file mode 100644 index 0000000000..ad1f0ad4e1 --- /dev/null +++ b/src/sql/engine/cmd/ob_tenant_snapshot_executor.cpp @@ -0,0 +1,135 @@ +/** + * Copyright (c) 2021 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. + */ +#define USING_LOG_PREFIX SQL_ENG +#include "sql/engine/cmd/ob_tenant_snapshot_executor.h" +#include "sql/engine/ob_exec_context.h" +#include "sql/resolver/cmd/ob_tenant_snapshot_stmt.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_util.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" + +namespace oceanbase +{ +using namespace common; +using namespace share; +using namespace share::schema; +namespace sql +{ + +ERRSIM_POINT_DEF(ERRSIM_WAIT_SNAPSHOT_RESULT_ERROR); +int ObCreateTenantSnapshotExecutor::execute(ObExecContext &ctx, ObCreateTenantSnapshotStmt &stmt) +{ + int ret = OB_SUCCESS; + const ObString &tenant_name = stmt.get_tenant_name(); + const ObString &tenant_snapshot_name = stmt.get_tenant_snapshot_name(); + uint64_t tenant_id = OB_INVALID_TENANT_ID; + share::ObTenantSnapshotID tenant_snapshot_id; + + // TODO: support tenant snapshot in future + ret = OB_NOT_SUPPORTED; + LOG_WARN("create tenant snapshot is not supported", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "create tenant snapshot is"); + + // if (OB_FAIL(rootserver::ObTenantSnapshotUtil::create_tenant_snapshot(tenant_name, + // tenant_snapshot_name, + // tenant_id, + // tenant_snapshot_id))) { + // LOG_WARN("create tenant snapshot failed", KR(ret), K(tenant_name), K(tenant_snapshot_name)); + // if (OB_TENANT_SNAPSHOT_EXIST == ret) { + // LOG_USER_ERROR(OB_TENANT_SNAPSHOT_EXIST, tenant_snapshot_name.length(), tenant_snapshot_name.ptr()); + // } + // } else if (OB_UNLIKELY(ERRSIM_WAIT_SNAPSHOT_RESULT_ERROR)) { + // ret = ERRSIM_WAIT_SNAPSHOT_RESULT_ERROR; + // LOG_WARN("[ERRSIM CLONE] errsim wait snapshot creation finished", KR(ret)); + // } else if (OB_FAIL(wait_create_finish_(tenant_id, tenant_snapshot_id, ctx))) { + // LOG_WARN("wait create snapshot finish failed", KR(ret), K(tenant_id), K(tenant_snapshot_id)); + // } + return ret; +} + +int ObCreateTenantSnapshotExecutor::wait_create_finish_(const uint64_t tenant_id, + const share::ObTenantSnapshotID &tenant_snapshot_id, + ObExecContext &ctx) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotTableOperator table_op; + ObTenantSnapItem item; + const int64_t SNAPSHOT_CREATION_TIMEOUT = 300 * 1000 * 1000L; + const int64_t TIME_DEVIATION = 10 * 1000 * 1000L; + int64_t timeout = max(SNAPSHOT_CREATION_TIMEOUT, GCONF._ob_ddl_timeout) + TIME_DEVIATION; + common::ObMySQLProxy *sql_proxy = nullptr; + THIS_WORKER.set_timeout_ts(ObTimeUtility::current_time() + timeout); + + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id + || !tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_id or tenant_snapshot_id is not valid", KR(ret), K(tenant_id), K(tenant_snapshot_id)); + } else if (OB_ISNULL(sql_proxy = ctx.get_sql_proxy())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy must not be null", KR(ret)); + } else if (OB_FAIL(table_op.init(tenant_id, sql_proxy))) { + LOG_WARN("fail to init table op", KR(ret)); + } else { + while (OB_SUCC(ret)) { + item.reset(); + ob_usleep(2 * 1000 * 1000L); // 2s + if (THIS_WORKER.is_timeout()) { + // TODO: provides a view for user to query the snapshot status and tips user how to acquire it + ret = OB_TENANT_SNAPSHOT_TIMEOUT; + LOG_WARN("wait create tenant snapshot timeout", KR(ret), K(tenant_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_op.get_tenant_snap_item(tenant_snapshot_id, false, item))) { + LOG_WARN("fail to get snapshot item", KR(ret), K(tenant_snapshot_id)); + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + // if creating snapshot is failed, the according record might be deleted in the inner_table + ret = OB_ERR_UNEXPECTED; + LOG_USER_ERROR(OB_ERR_UNEXPECTED, "create snapshot failed"); + } + } else if (ObTenantSnapStatus::NORMAL == item.get_status()) { + break; + } else if (ObTenantSnapStatus::CREATING == item.get_status() + || ObTenantSnapStatus::DECIDED == item.get_status()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(rootserver::ObTenantSnapshotUtil::notify_scheduler(tenant_id))) { + LOG_WARN("fail to notify scheduler", KR(tmp_ret), K(tenant_id)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected item status", KR(ret), K(tenant_snapshot_id), K(item.get_status())); + } + } + } + return ret; +} + +int ObDropTenantSnapshotExecutor::execute(ObExecContext &ctx, ObDropTenantSnapshotStmt &stmt) +{ + int ret = OB_SUCCESS; + const ObString &tenant_name = stmt.get_tenant_name(); + const ObString &tenant_snapshot_name = stmt.get_tenant_snapshot_name(); + + // TODO: support tenant snapshot in future + ret = OB_NOT_SUPPORTED; + LOG_WARN("drop tenant snapshot is not supported", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "drop tenant snapshot is"); + + // if (OB_FAIL(rootserver::ObTenantSnapshotUtil::drop_tenant_snapshot(tenant_name, + // tenant_snapshot_name))) { + // LOG_WARN("drop tenant snapshot failed", KR(ret), K(tenant_name), K(tenant_snapshot_name)); + // if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + // LOG_USER_ERROR(OB_TENANT_SNAPSHOT_NOT_EXIST, tenant_snapshot_name.length(), tenant_snapshot_name.ptr()); + // } + // } + return ret; +} + +} // namespace sql +} // namespace oceanbase diff --git a/src/sql/engine/cmd/ob_tenant_snapshot_executor.h b/src/sql/engine/cmd/ob_tenant_snapshot_executor.h new file mode 100644 index 0000000000..f96f02ea3d --- /dev/null +++ b/src/sql/engine/cmd/ob_tenant_snapshot_executor.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef __OB_SQL_TENANT_SNAPSHOT_EXECUTOR_H__ +#define __OB_SQL_TENANT_SNAPSHOT_EXECUTOR_H__ + +#include "sql/engine/ob_exec_context.h" + +namespace oceanbase +{ +namespace share +{ +class ObTenantSnapshotID; +} + +namespace sql +{ +class ObCreateTenantSnapshotStmt; +class ObDropTenantSnapshotStmt; + +class ObCreateTenantSnapshotExecutor +{ +public: + ObCreateTenantSnapshotExecutor() {} + virtual ~ObCreateTenantSnapshotExecutor() {} + int execute(ObExecContext &ctx, ObCreateTenantSnapshotStmt &stmt); +private: + int wait_create_finish_(const uint64_t tenant_id, + const share::ObTenantSnapshotID &tenant_snapshot_id, + ObExecContext &ctx); + DISALLOW_COPY_AND_ASSIGN(ObCreateTenantSnapshotExecutor); +}; + +class ObDropTenantSnapshotExecutor +{ +public: + ObDropTenantSnapshotExecutor() {} + virtual ~ObDropTenantSnapshotExecutor() {} + int execute(ObExecContext &ctx, ObDropTenantSnapshotStmt &stmt); +private: + DISALLOW_COPY_AND_ASSIGN(ObDropTenantSnapshotExecutor); +}; + +} //end namespace sql +} //end namespace oceanbase + +#endif //__OB_SQL_TENANT_SNAPSHOT_EXECUTOR_H__ diff --git a/src/sql/executor/ob_cmd_executor.cpp b/src/sql/executor/ob_cmd_executor.cpp index 24800bd3c7..504f5a05e2 100644 --- a/src/sql/executor/ob_cmd_executor.cpp +++ b/src/sql/executor/ob_cmd_executor.cpp @@ -142,6 +142,10 @@ #include "sql/resolver/ddl/ob_create_context_resolver.h" #include "sql/resolver/ddl/ob_drop_context_resolver.h" #include "sql/engine/cmd/ob_context_executor.h" +#include "sql/resolver/cmd/ob_tenant_snapshot_stmt.h" +#include "sql/engine/cmd/ob_tenant_snapshot_executor.h" +#include "sql/resolver/cmd/ob_tenant_clone_stmt.h" +#include "sql/engine/cmd/ob_clone_executor.h" #ifdef OB_BUILD_TDE_SECURITY #include "sql/resolver/ddl/ob_create_keystore_stmt.h" #include "sql/resolver/ddl/ob_alter_keystore_stmt.h" @@ -1005,10 +1009,26 @@ int ObCmdExecutor::execute(ObExecContext &ctx, ObICmd &cmd) DEFINE_EXECUTE_CMD(ObTableTTLStmt, ObTableTTLExecutor); break; } + case stmt::T_CREATE_TENANT_SNAPSHOT: { + DEFINE_EXECUTE_CMD(ObCreateTenantSnapshotStmt, ObCreateTenantSnapshotExecutor); + break; + } + case stmt::T_DROP_TENANT_SNAPSHOT: { + DEFINE_EXECUTE_CMD(ObDropTenantSnapshotStmt, ObDropTenantSnapshotExecutor); + break; + } + case stmt::T_CLONE_TENANT: { + DEFINE_EXECUTE_CMD(ObCloneTenantStmt, ObCloneTenantExecutor); + break; + } case stmt::T_ALTER_SYSTEM_RESET_PARAMETER: { DEFINE_EXECUTE_CMD(ObResetConfigStmt, ObResetConfigExecutor); break; } + case stmt::T_CANCEL_CLONE: { + DEFINE_EXECUTE_CMD(ObCancelCloneStmt, ObCancelCloneExecutor); + break; + } case stmt::T_CS_DISKMAINTAIN: case stmt::T_TABLET_CMD: case stmt::T_SWITCH_ROOTSERVER: diff --git a/src/sql/parser/non_reserved_keywords_mysql_mode.c b/src/sql/parser/non_reserved_keywords_mysql_mode.c index bbb7095746..fbfcd1d6d2 100644 --- a/src/sql/parser/non_reserved_keywords_mysql_mode.c +++ b/src/sql/parser/non_reserved_keywords_mysql_mode.c @@ -1002,6 +1002,8 @@ static const NonReservedKeyword Mysql_none_reserved_keywords[] = {"statement_id", STATEMENT_ID}, {"TTL", TTL}, {"kv_attributes", KV_ATTRIBUTES}, + {"RESOURCE_POOL", RESOURCE_POOL}, + {"clone", CLONE}, }; /** https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html diff --git a/src/sql/parser/sql_parser_mysql_mode.y b/src/sql/parser/sql_parser_mysql_mode.y index e8faf4fa5a..466495bf6f 100644 --- a/src/sql/parser/sql_parser_mysql_mode.y +++ b/src/sql/parser/sql_parser_mysql_mode.y @@ -262,7 +262,7 @@ END_P SET_VAR DELIMITER BADFILE CACHE CALIBRATION CALIBRATION_INFO CANCEL CASCADED CAST CATALOG_NAME CHAIN CHANGED CHARSET CHECKSUM CHECKPOINT CHUNK CIPHER - CLASS_ORIGIN CLEAN CLEAR CLIENT CLOG CLOSE CLUSTER CLUSTER_ID CLUSTER_NAME COALESCE COLUMN_STAT + CLASS_ORIGIN CLEAN CLEAR CLIENT CLONE CLOG CLOSE CLUSTER CLUSTER_ID CLUSTER_NAME COALESCE COLUMN_STAT CODE COLLATION COLUMN_FORMAT COLUMN_NAME COLUMNS COMMENT COMMIT COMMITTED COMPACT COMPLETION COMPRESSED COMPRESSION COMPUTE CONCURRENT CONDENSED CONNECTION CONSISTENT CONSISTENT_MODE CONSTRAINT_CATALOG CONSTRAINT_NAME CONSTRAINT_SCHEMA CONTAINS CONTEXT CONTRIBUTORS COPY COUNT CPU CREATE_TIMESTAMP @@ -326,7 +326,7 @@ END_P SET_VAR DELIMITER REBUILD RECOVER RECOVERY_WINDOW RECYCLE REDO_BUFFER_SIZE REDOFILE REDUNDANCY REDUNDANT REFRESH REGION RELAY RELAYLOG RELAY_LOG_FILE RELAY_LOG_POS RELAY_THREAD RELOAD REMAP REMOVE REORGANIZE REPAIR REPEATABLE REPLICA - REPLICA_NUM REPLICA_TYPE REPLICATION REPORT RESET RESOURCE RESOURCE_POOL_LIST RESPECT RESTART + REPLICA_NUM REPLICA_TYPE REPLICATION REPORT RESET RESOURCE RESOURCE_POOL RESOURCE_POOL_LIST RESPECT RESTART RESTORE RESUME RETURNED_SQLSTATE RETURNS RETURNING REVERSE ROLLBACK ROLLUP ROOT ROOTTABLE ROOTSERVICE ROOTSERVICE_LIST ROUTINE ROW ROLLING ROW_COUNT ROW_FORMAT ROWS RTREE RUN RECYCLEBIN ROTATE ROW_NUMBER RUDUNDANT RECURSIVE RANDOM REDO_TRANSPORT_OPTIONS REMOTE_OSS RT @@ -522,6 +522,7 @@ END_P SET_VAR DELIMITER %type json_table_ordinality_column_def json_table_exists_column_def json_table_value_column_def json_table_nested_column_def %type opt_value_on_empty_or_error_or_mismatch opt_on_mismatch %type table_values_caluse table_values_caluse_with_order_by_and_limit values_row_list row_value +%type create_tenant_snapshot_stmt snapshot_name drop_tenant_snapshot_stmt clone_tenant_stmt clone_snapshot_option clone_tenant_option clone_tenant_option_list %type ttl_definition ttl_expr ttl_unit %start sql_stmt @@ -689,6 +690,9 @@ stmt: | method_opt { $$ = $1; check_question_mark($$, result); } | switchover_tenant_stmt { $$ = $1; check_question_mark($$, result); } | recover_tenant_stmt { $$ = $1; check_question_mark($$, result); } + | create_tenant_snapshot_stmt { $$ = $1; check_question_mark($$, result); } + | drop_tenant_snapshot_stmt { $$ = $1; check_question_mark($$, result); } + | clone_tenant_stmt { $$ = $1; check_question_mark($$, result); } ; /***************************************************************************** @@ -3987,6 +3991,88 @@ ALTER TENANT relation_name opt_set opt_tenant_option_list opt_global_sys_vars_se } ; +create_tenant_snapshot_stmt: +CREATE SNAPSHOT snapshot_name FOR TENANT relation_name +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_CREATE_TENANT_SNAPSHOT, 2, + $3, /* snapshot name */ + $6); /* tenant name */ +} +| CREATE SNAPSHOT snapshot_name +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_CREATE_TENANT_SNAPSHOT, 2, + $3, /* snapshot name */ + NULL); +} +; + +snapshot_name: +relation_name +{ $$ = $1; } +| /* EMPTY */ +{ $$ = NULL; } +; + +drop_tenant_snapshot_stmt: +DROP SNAPSHOT relation_name FOR TENANT relation_name +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_DROP_TENANT_SNAPSHOT, 2, + $3, /* snapshot name */ + $6); /* tenant name */ +} +| DROP SNAPSHOT relation_name +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_DROP_TENANT_SNAPSHOT, 2, + $3, /* snapshot name */ + NULL); +} +; + +clone_tenant_stmt: +create_with_opt_hint TENANT opt_if_not_exists relation_name FROM relation_name +clone_snapshot_option WITH clone_tenant_option_list +{ + (void)($1); + malloc_non_terminal_node($$, result->malloc_pool_, T_CLONE_TENANT, 5, + $3, /* if not exist */ + $4, /* cloned tenant name */ + $6, /* source tenant name */ + $7, /* tenant snapshot name */ + $9); /* clone option list */ +} +; + +clone_snapshot_option: +USING SNAPSHOT relation_name +{ + $$ = $3; +} +| /*EMPTY*/ +{ + $$ = NULL; +} +; + +clone_tenant_option: +RESOURCE_POOL opt_equal_mark relation_name_or_string +{ + (void)($2); + malloc_non_terminal_node($$, result->malloc_pool_, T_RESOURCE_POOL_LIST, 1, $3); +} +| UNIT opt_equal_mark relation_name_or_string +{ + (void)($2); + malloc_non_terminal_node($$, result->malloc_pool_, T_UNIT, 1, $3); +} +; + +clone_tenant_option_list: +clone_tenant_option ',' clone_tenant_option +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_LINK_NODE, 2, $1, $3); +} +; + drop_tenant_stmt: DROP TENANT opt_if_exists relation_name opt_force_purge { @@ -16207,6 +16293,10 @@ ALTER SYSTEM RESET alter_system_reset_parameter_actions merge_nodes($$, result, T_SYTEM_ACTION_LIST, $4); malloc_non_terminal_node($$, result->malloc_pool_, T_ALTER_SYSTEM_RESET_PARAMETER, 1, $$); } +| ALTER SYSTEM CANCEL CLONE relation_name +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_CANCEL_CLONE, 1, $5); +} ; opt_sql_throttle_for_priority: @@ -18577,6 +18667,7 @@ ACCOUNT | CLEAN | CLEAR | CLIENT +| CLONE | CLOSE | CLOG | CLUSTER @@ -19002,6 +19093,7 @@ ACCOUNT | REPORT | RESET | RESOURCE +| RESOURCE_POOL | RESOURCE_POOL_LIST | RESPECT | RESTART diff --git a/src/sql/resolver/cmd/ob_alter_system_resolver.cpp b/src/sql/resolver/cmd/ob_alter_system_resolver.cpp index 5b71fd51f7..c3ff248a63 100644 --- a/src/sql/resolver/cmd/ob_alter_system_resolver.cpp +++ b/src/sql/resolver/cmd/ob_alter_system_resolver.cpp @@ -6011,5 +6011,64 @@ int ObAlterSystemResetResolver::resolve(const ParseNode &parse_tree) return ret; } +int ObCancelCloneResolver::resolve(const ParseNode &parse_tree) +{ + int ret = OB_SUCCESS; + ParseNode *node = const_cast(&parse_tree); + ObCancelCloneStmt *mystmt = NULL; + ObString tenant_name; + + if (OB_ISNULL(node)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(T_CANCEL_CLONE != node->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(1 != node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_ISNULL(session_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("session info should not be null", KR(ret)); + } else { + bool is_compatible = false; + const uint64_t tenant_id = session_info_->get_login_tenant_id(); + if (OB_FAIL(share::ObShareUtil::check_compat_version_for_clone_tenant(tenant_id, is_compatible))) { + LOG_WARN("fail to check compat version", KR(ret), K(tenant_id)); + } else if (!is_compatible) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("tenant data version is below 4.3", KR(ret), K(tenant_id), K(is_compatible)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "cancel tenant cloning below 4.3"); + } + } + + if (OB_SUCC(ret)) { + if (OB_ISNULL(mystmt = create_stmt())) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("failed to create stmt", KR(ret)); + } else { + stmt_ = mystmt; + } + } + + if (OB_SUCC(ret)) { + if (OB_ISNULL(node->children_[0])) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(T_IDENT != node->children_[0]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + tenant_name.assign_ptr((char *)(node->children_[0]->str_value_), + static_cast(node->children_[0]->str_len_)); + if (OB_FAIL(mystmt->set_clone_tenant_name(tenant_name))) { + LOG_WARN("set clone tenant name failed", KR(ret), K(tenant_name)); + } + } + } + + return ret; +} + } // end namespace sql } // end namespace oceanbase diff --git a/src/sql/resolver/cmd/ob_alter_system_resolver.h b/src/sql/resolver/cmd/ob_alter_system_resolver.h index 0d5078cf71..8b6a73b55d 100644 --- a/src/sql/resolver/cmd/ob_alter_system_resolver.h +++ b/src/sql/resolver/cmd/ob_alter_system_resolver.h @@ -304,6 +304,7 @@ private: }; DEF_SIMPLE_CMD_RESOLVER(ObTableTTLResolver); +DEF_SIMPLE_CMD_RESOLVER(ObCancelCloneResolver); #undef DEF_SIMPLE_CMD_RESOLVER diff --git a/src/sql/resolver/cmd/ob_alter_system_stmt.h b/src/sql/resolver/cmd/ob_alter_system_stmt.h index e910b857ca..1565afd02e 100644 --- a/src/sql/resolver/cmd/ob_alter_system_stmt.h +++ b/src/sql/resolver/cmd/ob_alter_system_stmt.h @@ -1351,6 +1351,20 @@ private: obrpc::ObAdminSetConfigArg rpc_arg_; }; +class ObCancelCloneStmt : public ObSystemCmdStmt +{ +public: + ObCancelCloneStmt() + : ObSystemCmdStmt(stmt::T_CANCEL_CLONE), + clone_tenant_name_() {} + virtual ~ObCancelCloneStmt() {} + int set_clone_tenant_name(const ObString &tenant_name) { return clone_tenant_name_.assign(tenant_name); } + const ObString get_clone_tenant_name() { return clone_tenant_name_.str(); } + TO_STRING_KV(N_STMT_TYPE, ((int)stmt_type_), K_(clone_tenant_name)); +private: + common::ObFixedLengthString clone_tenant_name_; +}; + } // end namespace sql } // end namespace oceanbase diff --git a/src/sql/resolver/cmd/ob_tenant_clone_resolver.cpp b/src/sql/resolver/cmd/ob_tenant_clone_resolver.cpp new file mode 100644 index 0000000000..518351353b --- /dev/null +++ b/src/sql/resolver/cmd/ob_tenant_clone_resolver.cpp @@ -0,0 +1,205 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SQL_RESV + +#include "sql/resolver/cmd/ob_tenant_clone_stmt.h" +#include "sql/resolver/cmd/ob_tenant_clone_resolver.h" +#include "sql/resolver/ob_resolver_utils.h" + +namespace oceanbase +{ +using namespace common; +using namespace share::schema; +namespace sql +{ + +ObCloneTenantResolver::ObCloneTenantResolver(ObResolverParams ¶ms) + : ObCMDResolver(params) +{ +} + +ObCloneTenantResolver::~ObCloneTenantResolver() +{ +} + +int ObCloneTenantResolver::resolve(const ParseNode &parse_tree) +{ + int ret = OB_SUCCESS; + ParseNode *node = const_cast(&parse_tree); + ObCloneTenantStmt *mystmt = NULL; + ObString new_tenant_name; + ObString source_tenant_name; + ObString tenant_snapshot_name; + ObString resource_pool_name; + ObString unit_config_name; + + if (OB_ISNULL(node)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(T_CLONE_TENANT != node->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(5 != node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_ISNULL(session_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("session info should not be null", KR(ret)); + } else { + bool is_compatible = false; + const uint64_t tenant_id = session_info_->get_login_tenant_id(); + if (OB_FAIL(share::ObShareUtil::check_compat_version_for_clone_tenant(tenant_id, is_compatible))) { + LOG_WARN("fail to check compat version", KR(ret), K(tenant_id)); + } else if (!is_compatible) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("tenant data version is below 4.3", KR(ret), K(tenant_id), K(is_compatible)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "clone tenant below 4.3"); + } + } + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(NULL == (mystmt = create_stmt()))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("failed to create stmt"); + } else { + stmt_ = mystmt; + } + } + + /* if not exist */ + if (OB_SUCC(ret)) { + if (NULL != parse_tree.children_[0]) { + if (OB_UNLIKELY(T_IF_NOT_EXISTS != parse_tree.children_[0]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + mystmt->set_if_not_exists(true); + } + } else { + mystmt->set_if_not_exists(false); + } + } + + /* new tenant name */ + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(NULL == node->children_[1])) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(T_IDENT != node->children_[1]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + new_tenant_name.assign_ptr((char *)(node->children_[1]->str_value_), + static_cast(node->children_[1]->str_len_)); + if (OB_FAIL(ObResolverUtils::check_not_supported_tenant_name(new_tenant_name))) { + LOG_WARN("unsupported tenant name", KR(ret), K(new_tenant_name)); + } + } + } + + /* source tenant name */ + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(NULL == node->children_[2])) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(T_IDENT != node->children_[2]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + source_tenant_name.assign_ptr((char *)(node->children_[2]->str_value_), + static_cast(node->children_[2]->str_len_)); + } + } + + /* tenant snapshot name */ + if (OB_SUCC(ret)) { + if (NULL == node->children_[3]) { + } else if (OB_UNLIKELY(T_IDENT != node->children_[3]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + tenant_snapshot_name.assign_ptr((char *)(node->children_[3]->str_value_), + static_cast(node->children_[3]->str_len_)); + } + } + + /* clone option list */ + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(NULL == node->children_[4])) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(T_LINK_NODE != node->children_[4]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + if (OB_FAIL(resolve_option_list_(node->children_[4], resource_pool_name, unit_config_name))) { + LOG_WARN("resolve option list failed", KR(ret)); + } else if (resource_pool_name.empty()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("resource pool name is empty", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "clone tenant without resource pool"); + } else if (unit_config_name.empty()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("unit config name is empty", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "clone tenant without unit config"); + } + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(mystmt->init(new_tenant_name, source_tenant_name, + tenant_snapshot_name, resource_pool_name, unit_config_name))) { + LOG_WARN("mystmt init failed", KR(ret), K(new_tenant_name), K(source_tenant_name), + K(tenant_snapshot_name), K(resource_pool_name), K(unit_config_name)); + } + } + + return ret; +} + +int ObCloneTenantResolver::resolve_option_list_(const ParseNode *node, + ObString &resource_pool_name, + ObString &unit_config_name) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(NULL == node)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(2 != node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < node->num_child_; i++) { + const ParseNode *option_node = node->children_[i]; + if (OB_UNLIKELY(NULL == option_node)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (OB_UNLIKELY(1 != option_node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else if (T_RESOURCE_POOL_LIST == option_node->type_) { + resource_pool_name.assign_ptr((char *)(option_node->children_[0]->str_value_), + static_cast(option_node->children_[0]->str_len_)); + } else if (T_UNIT == option_node->type_) { + unit_config_name.assign_ptr((char *)(option_node->children_[0]->str_value_), + static_cast(option_node->children_[0]->str_len_)); + } + } + } + + return ret; +} + +} +} diff --git a/src/sql/resolver/cmd/ob_tenant_clone_resolver.h b/src/sql/resolver/cmd/ob_tenant_clone_resolver.h new file mode 100644 index 0000000000..06ad26ae1e --- /dev/null +++ b/src/sql/resolver/cmd/ob_tenant_clone_resolver.h @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef _OB_CLONE_TENANT_RESOLVER_H +#define _OB_CLONE_TENANT_RESOLVER_H +#include "sql/resolver/cmd/ob_cmd_resolver.h" +namespace oceanbase +{ +namespace sql +{ +class ObCloneTenantResolver : public ObCMDResolver +{ +public: + explicit ObCloneTenantResolver(ObResolverParams ¶ms); + virtual ~ObCloneTenantResolver(); + + virtual int resolve(const ParseNode &parse_tree); +private: + int resolve_option_list_(const ParseNode *node, + ObString &resource_pool_name, + ObString &unit_config_name); +private: + DISALLOW_COPY_AND_ASSIGN(ObCloneTenantResolver); +}; + +} +} + +#endif /*_OB_CREATE_SNAPSHOT_RESOLVER_H*/ diff --git a/src/sql/resolver/cmd/ob_tenant_clone_stmt.h b/src/sql/resolver/cmd/ob_tenant_clone_stmt.h new file mode 100644 index 0000000000..5289712a78 --- /dev/null +++ b/src/sql/resolver/cmd/ob_tenant_clone_stmt.h @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_SQL_OB_CLONE_TENANT_STMT_H_ +#define OCEANBASE_SQL_OB_CLONE_TENANT_STMT_H_ + +#include "sql/resolver/cmd/ob_cmd_stmt.h" + +namespace oceanbase +{ +namespace sql +{ + +class ObCloneTenantStmt : public ObCMDStmt +{ +public: + explicit ObCloneTenantStmt(common::ObIAllocator *name_pool) + : ObCMDStmt(name_pool, stmt::T_CLONE_TENANT), + clone_tenant_arg_(), + if_not_exists_(false) {} + ObCloneTenantStmt() + : ObCMDStmt(stmt::T_CLONE_TENANT), + clone_tenant_arg_(), + if_not_exists_(false) {} + virtual ~ObCloneTenantStmt() {} + inline obrpc::ObCloneTenantArg &get_clone_tenant_arg() { return clone_tenant_arg_; } + inline bool get_if_not_exists() const { return if_not_exists_; } + int init(const ObString &new_tenant_name, + const ObString &source_tenant_name, + const ObString &tenant_snapshot_name, + const ObString &resource_pool_name, + const ObString &unit_config_name) + { + return clone_tenant_arg_.init(new_tenant_name, + source_tenant_name, + tenant_snapshot_name, + resource_pool_name, + unit_config_name); + } + void set_if_not_exists(const bool is_exist) + { + if_not_exists_ = is_exist; + } +private: + obrpc::ObCloneTenantArg clone_tenant_arg_; + bool if_not_exists_; + DISALLOW_COPY_AND_ASSIGN(ObCloneTenantStmt); +}; + +} /* sql */ +} /* oceanbase */ + +#endif //OCEANBASE_SQL_OB_CLONE_TENANT_STMT_H_ diff --git a/src/sql/resolver/cmd/ob_tenant_snapshot_resolver.cpp b/src/sql/resolver/cmd/ob_tenant_snapshot_resolver.cpp new file mode 100644 index 0000000000..e2ff62ef73 --- /dev/null +++ b/src/sql/resolver/cmd/ob_tenant_snapshot_resolver.cpp @@ -0,0 +1,200 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX SQL_RESV + +#include "sql/resolver/cmd/ob_tenant_snapshot_stmt.h" +#include "sql/resolver/cmd/ob_tenant_snapshot_resolver.h" +#include "sql/session/ob_sql_session_info.h" +#include "share/ob_share_util.h" + +namespace oceanbase +{ +using namespace common; +using namespace share::schema; +namespace sql +{ + +ObCreateTenantSnapshotResolver::ObCreateTenantSnapshotResolver(ObResolverParams ¶ms) + : ObCMDResolver(params) +{ +} + +ObCreateTenantSnapshotResolver::~ObCreateTenantSnapshotResolver() +{ +} + +int ObCreateTenantSnapshotResolver::resolve(const ParseNode &parse_tree) +{ + int ret = OB_SUCCESS; + ParseNode *node = const_cast(&parse_tree); + ObCreateTenantSnapshotStmt *mystmt = NULL; + uint64_t tenant_id = OB_INVALID_TENANT_ID; + + if (OB_ISNULL(node) + || OB_UNLIKELY(T_CREATE_TENANT_SNAPSHOT != node->type_) + || OB_UNLIKELY(2 != node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid param", KR(ret)); + } else if (OB_ISNULL(session_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("session info should not be null", KR(ret)); + } else { + bool is_compatible = false; + tenant_id = session_info_->get_login_tenant_id(); + if (OB_FAIL(share::ObShareUtil::check_compat_version_for_clone_tenant(tenant_id, is_compatible))) { + LOG_WARN("fail to check compat version", KR(ret), K(tenant_id)); + } else if (!is_compatible) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("tenant data version is below 4.3", KR(ret), K(tenant_id), K(is_compatible)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "create tenant snapshot below 4.3"); + } + } + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(NULL == (mystmt = create_stmt()))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("failed to create stmt"); + } else { + stmt_ = mystmt; + } + } + + /* snapshot name */ + if (OB_SUCC(ret)) { + if (NULL != node->children_[0]) { + if (OB_UNLIKELY(T_IDENT != node->children_[0]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + ObString snapshot_name; + snapshot_name.assign_ptr((char *)(node->children_[0]->str_value_), + static_cast(node->children_[0]->str_len_)); + if (OB_FAIL(mystmt->set_tenant_snapshot_name(snapshot_name))) { + LOG_WARN("fail to set tenant snapshot name", KR(ret), K(snapshot_name)); + } + } + } else { + //create snapshot name later + } + } + + /* tenant name */ + if (OB_SUCC(ret)) { + if (NULL != node->children_[1]) { + if (OB_SYS_TENANT_ID != tenant_id) { + ret = OB_ERR_NO_PRIVILEGE; + LOG_WARN("Only sys tenant can add suffix opt(for tenant name)", KR(ret), K(tenant_id)); + } else if (OB_UNLIKELY(T_IDENT != node->children_[1]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + ObString tenant_name; + tenant_name.assign_ptr((char *)(node->children_[1]->str_value_), + static_cast(node->children_[1]->str_len_)); + if (OB_FAIL(mystmt->set_tenant_name(tenant_name))) { + LOG_WARN("fail to set tenant name", KR(ret), K(tenant_name)); + } + } + } + } + + return ret; +} + +ObDropTenantSnapshotResolver::ObDropTenantSnapshotResolver(ObResolverParams ¶ms) + : ObCMDResolver(params) +{ +} + +ObDropTenantSnapshotResolver::~ObDropTenantSnapshotResolver() +{ +} + +int ObDropTenantSnapshotResolver::resolve(const ParseNode &parse_tree) +{ + int ret = OB_SUCCESS; + ParseNode *node = const_cast(&parse_tree); + ObDropTenantSnapshotStmt *mystmt = NULL; + uint64_t tenant_id = OB_INVALID_TENANT_ID; + + if (OB_ISNULL(node) + || OB_UNLIKELY(T_DROP_TENANT_SNAPSHOT != node->type_) + || OB_UNLIKELY(2 != node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid param", KR(ret)); + } else if (OB_ISNULL(session_info_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("session info should not be null", KR(ret)); + } else { + bool is_compatible = false; + tenant_id = session_info_->get_login_tenant_id(); + if (OB_FAIL(share::ObShareUtil::check_compat_version_for_clone_tenant(tenant_id, is_compatible))) { + LOG_WARN("fail to check compat version", KR(ret), K(tenant_id)); + } else if (!is_compatible) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("tenant data version is below 4.3", KR(ret), K(tenant_id), K(is_compatible)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "drop tenant snapshot below 4.3"); + } + } + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(NULL == (mystmt = create_stmt()))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_ERROR("failed to create stmt"); + } else { + stmt_ = mystmt; + } + } + + /* snapshot name */ + if (OB_SUCC(ret)) { + if (NULL != node->children_[0]) { + if (OB_UNLIKELY(T_IDENT != node->children_[0]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + ObString snapshot_name; + snapshot_name.assign_ptr((char *)(node->children_[0]->str_value_), + static_cast(node->children_[0]->str_len_)); + if (OB_FAIL(mystmt->set_tenant_snapshot_name(snapshot_name))) { + LOG_WARN("fail to set tenant snapshot name", KR(ret), K(snapshot_name)); + } + } + } + } + + /* tenant name */ + if (OB_SUCC(ret)) { + if (NULL != node->children_[1]) { + if (OB_SYS_TENANT_ID != tenant_id) { + ret = OB_ERR_NO_PRIVILEGE; + LOG_WARN("Only sys tenant can add suffix opt(for tenant name)", KR(ret), K(tenant_id)); + } else if (OB_UNLIKELY(T_IDENT != node->children_[1]->type_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid node", KR(ret)); + } else { + ObString tenant_name; + tenant_name.assign_ptr((char *)(node->children_[1]->str_value_), + static_cast(node->children_[1]->str_len_)); + if (OB_FAIL(mystmt->set_tenant_name(tenant_name))) { + LOG_WARN("fail to set tenant name", KR(ret), K(tenant_name)); + } + } + } + } + + return ret; +} + +} +} diff --git a/src/sql/resolver/cmd/ob_tenant_snapshot_resolver.h b/src/sql/resolver/cmd/ob_tenant_snapshot_resolver.h new file mode 100644 index 0000000000..5d3d8cb499 --- /dev/null +++ b/src/sql/resolver/cmd/ob_tenant_snapshot_resolver.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef _OB_TENANT_SNAPSHOT_RESOLVER_H +#define _OB_TENANT_SNAPSHOT_RESOLVER_H + +#include "sql/resolver/cmd/ob_cmd_resolver.h" + +namespace oceanbase +{ +namespace sql +{ +class ObCreateTenantSnapshotResolver : public ObCMDResolver +{ +public: + explicit ObCreateTenantSnapshotResolver(ObResolverParams ¶ms); + virtual ~ObCreateTenantSnapshotResolver(); + + virtual int resolve(const ParseNode &parse_tree); +private: + DISALLOW_COPY_AND_ASSIGN(ObCreateTenantSnapshotResolver); +}; + +class ObDropTenantSnapshotResolver : public ObCMDResolver +{ +public: + explicit ObDropTenantSnapshotResolver(ObResolverParams ¶ms); + virtual ~ObDropTenantSnapshotResolver(); + + virtual int resolve(const ParseNode &parse_tree); +private: + DISALLOW_COPY_AND_ASSIGN(ObDropTenantSnapshotResolver); +}; + +} // end namespace sql +} // end namespace oceanbase + +#endif /*_OB_TENANT_SNAPSHOT_RESOLVER_H*/ diff --git a/src/sql/resolver/cmd/ob_tenant_snapshot_stmt.h b/src/sql/resolver/cmd/ob_tenant_snapshot_stmt.h new file mode 100644 index 0000000000..069b24e634 --- /dev/null +++ b/src/sql/resolver/cmd/ob_tenant_snapshot_stmt.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_SQL_OB_TENANT_SNAPSHOT_STMT_H_ +#define OCEANBASE_SQL_OB_TENANT_SNAPSHOT_STMT_H_ + +#include "sql/resolver/cmd/ob_cmd_stmt.h" + +namespace oceanbase +{ +namespace sql +{ + +class ObCreateTenantSnapshotStmt : public ObCMDStmt +{ +public: + explicit ObCreateTenantSnapshotStmt(common::ObIAllocator *name_pool) + : ObCMDStmt(name_pool, stmt::T_CREATE_TENANT_SNAPSHOT), + tenant_name_(), + tenant_snapshot_name_() + {} + ObCreateTenantSnapshotStmt() + : ObCMDStmt(stmt::T_CREATE_TENANT_SNAPSHOT), + tenant_name_(), + tenant_snapshot_name_() + {} + virtual ~ObCreateTenantSnapshotStmt() {} + const common::ObString get_tenant_name() const { return tenant_name_.str(); } + const common::ObString get_tenant_snapshot_name() const { return tenant_snapshot_name_.str(); } + + int set_tenant_name(const common::ObString &tenant_name) + { + return tenant_name_.assign(tenant_name); + } + int set_tenant_snapshot_name(const common::ObString &tenant_snapshot_name) + { + return tenant_snapshot_name_.assign(tenant_snapshot_name); + } +private: + common::ObFixedLengthString tenant_name_; + common::ObFixedLengthString tenant_snapshot_name_; + DISALLOW_COPY_AND_ASSIGN(ObCreateTenantSnapshotStmt); +}; + +class ObDropTenantSnapshotStmt : public ObCMDStmt +{ +public: + explicit ObDropTenantSnapshotStmt(common::ObIAllocator *name_pool) + : ObCMDStmt(name_pool, stmt::T_DROP_TENANT_SNAPSHOT), + tenant_name_(), + tenant_snapshot_name_() + {} + ObDropTenantSnapshotStmt() + : ObCMDStmt(stmt::T_DROP_TENANT_SNAPSHOT), + tenant_name_(), + tenant_snapshot_name_() + {} + virtual ~ObDropTenantSnapshotStmt() {} + const common::ObString get_tenant_name() const { return tenant_name_.str(); } + const common::ObString get_tenant_snapshot_name() const { return tenant_snapshot_name_.str(); } + + int set_tenant_name(const common::ObString &tenant_name) + { + return tenant_name_.assign(tenant_name); + } + int set_tenant_snapshot_name(const common::ObString &tenant_snapshot_name) + { + return tenant_snapshot_name_.assign(tenant_snapshot_name); + } +private: + common::ObFixedLengthString tenant_name_; + common::ObFixedLengthString tenant_snapshot_name_; + DISALLOW_COPY_AND_ASSIGN(ObDropTenantSnapshotStmt); +}; + +} /* sql */ +} /* oceanbase */ + +#endif //OCEANBASE_SQL_OB_TENANT_SNAPSHOT_STMT_H_ diff --git a/src/sql/resolver/ob_resolver.cpp b/src/sql/resolver/ob_resolver.cpp index 961ef11aa7..89d6f7d6dd 100644 --- a/src/sql/resolver/ob_resolver.cpp +++ b/src/sql/resolver/ob_resolver.cpp @@ -131,6 +131,8 @@ #include "pl/ob_pl_package.h" #include "sql/resolver/ddl/ob_create_context_resolver.h" #include "sql/resolver/ddl/ob_drop_context_resolver.h" +#include "sql/resolver/cmd/ob_tenant_snapshot_resolver.h" +#include "sql/resolver/cmd/ob_tenant_clone_resolver.h" #ifdef OB_BUILD_TDE_SECURITY #include "sql/resolver/ddl/ob_create_tablespace_resolver.h" #include "sql/resolver/ddl/ob_alter_tablespace_resolver.h" @@ -1149,6 +1151,18 @@ int ObResolver::resolve(IsPrepared if_prepared, const ParseNode &parse_tree, ObS REGISTER_STMT_RESOLVER(TableTTL); break; } + case T_CREATE_TENANT_SNAPSHOT: { + REGISTER_STMT_RESOLVER(CreateTenantSnapshot); + break; + } + case T_DROP_TENANT_SNAPSHOT: { + REGISTER_STMT_RESOLVER(DropTenantSnapshot); + break; + } + case T_CLONE_TENANT: { + REGISTER_STMT_RESOLVER(CloneTenant); + break; + } case T_ALTER_SYSTEM_RESET_PARAMETER: { REGISTER_STMT_RESOLVER(ResetConfig); break; @@ -1157,6 +1171,10 @@ int ObResolver::resolve(IsPrepared if_prepared, const ParseNode &parse_tree, ObS REGISTER_STMT_RESOLVER(AlterSystemReset); break; } + case T_CANCEL_CLONE: { + REGISTER_STMT_RESOLVER(CancelClone); + break; + } default: { ret = OB_NOT_SUPPORTED; const char *type_name = get_type_name(parse_tree.type_); diff --git a/src/sql/resolver/ob_stmt_type.h b/src/sql/resolver/ob_stmt_type.h index f499de1f14..4de02f0f4a 100644 --- a/src/sql/resolver/ob_stmt_type.h +++ b/src/sql/resolver/ob_stmt_type.h @@ -286,11 +286,11 @@ OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CANCEL_RESTORE, get_sys_tenant_alter_system_priv, OB_STMT_TYPE_DEF_UNKNOWN_AT(T_TABLE_TTL, get_sys_tenant_alter_system_priv, 287) OB_STMT_TYPE_DEF_UNKNOWN_AT(T_RECOVER_TABLE, get_sys_tenant_alter_system_priv, 288) OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CANCEL_RECOVER_TABLE, get_sys_tenant_alter_system_priv, 289) -// OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CREATE_TENANT_SNAPSHOT, get_sys_tenant_alter_system_priv, 290) -// OB_STMT_TYPE_DEF_UNKNOWN_AT(T_DROP_TENANT_SNAPSHOT, get_sys_tenant_alter_system_priv, 291) +OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CREATE_TENANT_SNAPSHOT, get_sys_tenant_alter_system_priv, 290) +OB_STMT_TYPE_DEF_UNKNOWN_AT(T_DROP_TENANT_SNAPSHOT, get_sys_tenant_alter_system_priv, 291) OB_STMT_TYPE_DEF(T_ALTER_SYSTEM_RESET_PARAMETER, get_sys_tenant_alter_system_priv, 292, ACTION_TYPE_ALTER_SYSTEM) -// OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CLONE_TENANT, get_sys_tenant_alter_system_priv, 293) -// OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CANCEL_CLONE, get_sys_tenant_alter_system_priv, 294) +OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CLONE_TENANT, get_sys_tenant_alter_system_priv, 293) +OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CANCEL_CLONE, get_sys_tenant_alter_system_priv, 294) // OB_STMT_TYPE_DEF_UNKNOWN_AT(T_CREATE_MLOG, get_create_mlog_stmt_need_privs, 295) // OB_STMT_TYPE_DEF_UNKNOWN_AT(T_DROP_MLOG, get_drop_mlog_stmt_need_privs, 296) // OB_STMT_TYPE_DEF_UNKNOWN_AT(T_TRANSFER_PARTITION, get_sys_tenant_alter_system_priv, 297) diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt index c41759e5f1..510d7ecde1 100644 --- a/src/storage/CMakeLists.txt +++ b/src/storage/CMakeLists.txt @@ -162,6 +162,7 @@ ob_set_subtarget(ob_storage ckpt slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp + slog_ckpt/ob_tenant_meta_snapshot_handler.cpp slog_ckpt/ob_tablet_replay_create_handler.cpp ) @@ -764,6 +765,17 @@ ob_set_subtarget(ob_storage lob lob/ob_lob_rpc_struct.cpp ) +ob_set_subtarget(ob_storage tenant_snapshot + tenant_snapshot/ob_tenant_snapshot_service.cpp + tenant_snapshot/ob_tenant_clone_service.cpp + tenant_snapshot/ob_tenant_snapshot_task.cpp + tenant_snapshot/ob_tenant_snapshot_mgr.cpp + tenant_snapshot/ob_tenant_snapshot_defs.cpp + tenant_snapshot/ob_ls_snapshot_mgr.cpp + tenant_snapshot/ob_ls_snapshot_defs.cpp + tenant_snapshot/ob_tenant_snapshot_meta_table.cpp +) + ob_add_new_object_target(ob_storage ob_storage) target_link_libraries(ob_storage PUBLIC ob_base) diff --git a/src/storage/blocksstable/index_block/ob_sstable_meta_info.cpp b/src/storage/blocksstable/index_block/ob_sstable_meta_info.cpp index 4241ef3c73..e9de2d52b2 100644 --- a/src/storage/blocksstable/index_block/ob_sstable_meta_info.cpp +++ b/src/storage/blocksstable/index_block/ob_sstable_meta_info.cpp @@ -1118,15 +1118,14 @@ int ObSSTableMacroInfo::write_block_ids( MacroBlockId &entry_id) const { int ret = OB_SUCCESS; - const bool need_disk_addr = false; const int64_t data_blk_cnt = data_ids.count(); const int64_t other_blk_cnt = other_ids.count(); if (OB_UNLIKELY(0 == data_blk_cnt && 0 == other_blk_cnt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("data_blk_cnt and other_blk_cnt shouldn't be both 0", K(ret), K(data_blk_cnt), K(other_blk_cnt)); - } else if (OB_FAIL(writer.init(need_disk_addr))) { - LOG_WARN("fail to initialize item writer", K(ret), K(need_disk_addr)); + } else if (OB_FAIL(writer.init(false /*whether need addr*/))) { + LOG_WARN("fail to initialize item writer", K(ret)); } else if (OB_FAIL(flush_ids(data_ids, writer))) { LOG_WARN("fail to flush data block ids", K(ret), K(data_blk_cnt)); } else if (OB_FAIL(flush_ids(other_ids, writer))) { diff --git a/src/storage/compaction/ob_tablet_merge_checker.cpp b/src/storage/compaction/ob_tablet_merge_checker.cpp index 266c70b08a..7ae7de375a 100644 --- a/src/storage/compaction/ob_tablet_merge_checker.cpp +++ b/src/storage/compaction/ob_tablet_merge_checker.cpp @@ -110,7 +110,7 @@ int ObTabletMergeChecker::check_ls_state_in_major(ObLS &ls, bool &need_merge) // do nothing } else if (OB_FAIL(ls.get_ls_meta().get_restore_status(restore_status))) { LOG_WARN("failed to get restore status", K(ret), K(ls)); - } else if (OB_UNLIKELY(!restore_status.is_restore_none())) { + } else if (OB_UNLIKELY(!restore_status.is_none())) { if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { LOG_INFO("ls is in restore status, should not loop tablet to schedule", K(ret), "ls_id", ls.get_ls_id()); } diff --git a/src/storage/high_availability/ob_ls_migration.cpp b/src/storage/high_availability/ob_ls_migration.cpp index 09da0c59fd..36c73cc88f 100644 --- a/src/storage/high_availability/ob_ls_migration.cpp +++ b/src/storage/high_availability/ob_ls_migration.cpp @@ -1447,7 +1447,7 @@ int ObStartMigrationTask::check_before_ls_migrate_(const ObLSMeta &ls_meta) LOG_WARN("start migration task do not init", K(ret)); } else if (OB_FAIL(ls_meta.get_restore_status(ls_restore_status))) { LOG_WARN("failed to get restore status", K(ret), KPC(ctx_)); - } else if (ls_restore_status.is_restore_failed()) { + } else if (ls_restore_status.is_failed()) { ret = OB_LS_RESTORE_FAILED; LOG_WARN("ls restore failed, cannot migrate", K(ret), KPC(ctx_), K(ls_restore_status)); } else if (!ls_restore_status.can_migrate()) { diff --git a/src/storage/high_availability/ob_ls_restore.cpp b/src/storage/high_availability/ob_ls_restore.cpp index 0ba5fc4620..82719f3484 100644 --- a/src/storage/high_availability/ob_ls_restore.cpp +++ b/src/storage/high_availability/ob_ls_restore.cpp @@ -1030,7 +1030,7 @@ int ObStartLSRestoreTask::update_ls_meta_and_create_all_tablets_() LOG_WARN("failed to get restore status", K(ret), K(ls_meta_package)); } else if (ctx_->arg_.is_leader_ && (ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status - || ObLSRestoreStatus::RESTORE_NONE != restore_status)) { + || ObLSRestoreStatus::NONE != restore_status)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("leader ls restore get unexpected migration status or restore status", K(ret), K(migration_status), K(restore_status), K(ls_meta_package)); diff --git a/src/storage/high_availability/ob_storage_ha_src_provider.cpp b/src/storage/high_availability/ob_storage_ha_src_provider.cpp index e4873d5bcf..45e9cde775 100644 --- a/src/storage/high_availability/ob_storage_ha_src_provider.cpp +++ b/src/storage/high_availability/ob_storage_ha_src_provider.cpp @@ -200,7 +200,7 @@ int ObStorageHASrcProvider::inner_choose_ob_src_(const uint64_t tenant_id, const LOG_INFO("do not choose this src", K(tenant_id), K(ls_id), K(addr), K(ls_info)); } else if (OB_FAIL(ls_info.ls_meta_package_.ls_meta_.get_restore_status(restore_status))) { LOG_WARN("failed to get restore status", K(ret), K(ls_info)); - } else if (restore_status.is_restore_failed()) { + } else if (restore_status.is_failed()) { choose_member_idx = -1; LOG_INFO("some ls replica restore failed, can not migrate", K(ls_info)); break; diff --git a/src/storage/ls/ob_ls.cpp b/src/storage/ls/ob_ls.cpp index 50d3da29ee..145f3d5701 100644 --- a/src/storage/ls/ob_ls.cpp +++ b/src/storage/ls/ob_ls.cpp @@ -25,6 +25,8 @@ #include "observer/ob_srv_network_frame.h" #include "observer/report/ob_i_meta_report.h" #include "rootserver/freeze/ob_major_freeze_service.h" +#include "rootserver/tenant_snapshot/ob_tenant_snapshot_scheduler.h" +#include "rootserver/restore/ob_clone_scheduler.h" #ifdef OB_BUILD_ARBITRATION #include "rootserver/ob_arbitration_service.h" #endif @@ -290,6 +292,15 @@ int ObLS::init(const share::ObLSID &ls_id, REGISTER_TO_LOGSERVICE(logservice::RESTORE_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObRestoreService *)); } + if (OB_SUCC(ret) && is_meta_tenant(tenant_id) && ls_id.is_sys_ls()) { + REGISTER_TO_LOGSERVICE(logservice::SNAPSHOT_SCHEDULER_LOG_BASE_TYPE, MTL(rootserver::ObTenantSnapshotScheduler *)); + } + + if (OB_SUCC(ret) && !is_user_tenant(tenant_id) && ls_id.is_sys_ls()) { + //sys and meta tenant + REGISTER_TO_LOGSERVICE(logservice::CLONE_SCHEDULER_LOG_BASE_TYPE, MTL(rootserver::ObCloneScheduler *)); + } + #ifdef OB_BUILD_ARBITRATION if (OB_SUCC(ret) && !is_user_tenant(tenant_id) && ls_id.is_sys_ls()) { REGISTER_TO_LOGSERVICE(logservice::ARBITRATION_SERVICE_LOG_BASE_TYPE, MTL(rootserver::ObArbitrationService *)); @@ -565,7 +576,7 @@ bool ObLS::is_need_gc() const return bool_ret; } -bool ObLS::is_enable_for_restore() const +bool ObLS::is_required_to_switch_state_for_restore_() const { int ret = OB_SUCCESS; bool bool_ret = false; @@ -573,7 +584,20 @@ bool ObLS::is_enable_for_restore() const if (OB_FAIL(ls_meta_.get_restore_status(restore_status))) { LOG_WARN("fail to get restore status", K(ret), K(ls_meta_.ls_id_)); } else { - bool_ret = restore_status.is_enable_for_restore(); + bool_ret = restore_status.is_required_to_switch_ls_state_for_restore(); + } + return bool_ret; +} + +bool ObLS::is_required_to_switch_state_for_clone_() const +{ + int ret = OB_SUCCESS; + bool bool_ret = false; + ObLSRestoreStatus restore_status; + if (OB_FAIL(ls_meta_.get_restore_status(restore_status))) { + LOG_WARN("fail to get restore status", K(ret), K(ls_meta_.ls_id_)); + } else { + bool_ret = restore_status.is_required_to_switch_ls_state_for_clone(); } return bool_ret; } @@ -877,6 +901,14 @@ void ObLS::destroy() rootserver::ObHeartbeatService * heartbeat_service = MTL(rootserver::ObHeartbeatService*); UNREGISTER_FROM_LOGSERVICE(logservice::HEARTBEAT_SERVICE_LOG_BASE_TYPE, heartbeat_service); } + if (is_meta_tenant(MTL_ID()) && ls_meta_.ls_id_.is_sys_ls()) { + rootserver::ObTenantSnapshotScheduler * snapshot_scheduler = MTL(rootserver::ObTenantSnapshotScheduler*); + UNREGISTER_FROM_LOGSERVICE(logservice::SNAPSHOT_SCHEDULER_LOG_BASE_TYPE, snapshot_scheduler); + } + if (!is_user_tenant(MTL_ID()) && ls_meta_.ls_id_.is_sys_ls()) { + rootserver::ObCloneScheduler * clone_scheduler = MTL(rootserver::ObCloneScheduler*); + UNREGISTER_FROM_LOGSERVICE(logservice::CLONE_SCHEDULER_LOG_BASE_TYPE, clone_scheduler); + } #ifdef OB_BUILD_ARBITRATION if (!is_user_tenant(MTL_ID()) && ls_meta_.ls_id_.is_sys_ls()) { rootserver::ObArbitrationService * arbitration_service = MTL(rootserver::ObArbitrationService*); @@ -2375,7 +2407,7 @@ int ObLS::set_migration_status( } else if (OB_FAIL(ls_meta_.set_migration_status(migration_status, write_slog))) { LOG_WARN("failed to set migration status", K(ret), K(migration_status)); } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE == migration_status - && restore_status.is_restore_none()) { + && restore_status.is_none()) { ls_tablet_svr_.enable_to_read(); } else { ls_tablet_svr_.disable_to_read(); @@ -2411,7 +2443,7 @@ int ObLS::set_restore_status( } else if (OB_FAIL(ls_meta_.set_restore_status(restore_status))) { LOG_WARN("failed to set restore status", K(ret), K(restore_status)); } else if (ObMigrationStatus::OB_MIGRATION_STATUS_NONE == migration_status - && restore_status.is_restore_none()) { + && restore_status.is_none()) { ls_tablet_svr_.enable_to_read(); } else { ls_tablet_svr_.disable_to_read(); diff --git a/src/storage/ls/ob_ls.h b/src/storage/ls/ob_ls.h index 87c31b8942..a1b264c453 100644 --- a/src/storage/ls/ob_ls.h +++ b/src/storage/ls/ob_ls.h @@ -310,7 +310,6 @@ public: bool is_create_committed() const; bool is_need_gc() const; bool is_in_gc(); - bool is_enable_for_restore() const; // for rebuild // remove inner tablet, the memtable and minor sstable of data tablet, disable replay // int prepare_rebuild(); @@ -406,6 +405,8 @@ private: ObTabletHandle &handle); int offline_advance_epoch_(); int online_advance_epoch_(); + bool is_required_to_switch_state_for_restore_() const; + bool is_required_to_switch_state_for_clone_() const; public: // ObLSMeta interface: int update_ls_meta(const bool update_restore_status, diff --git a/src/storage/ls/ob_ls_meta.cpp b/src/storage/ls/ob_ls_meta.cpp index c3a3e053b1..5871529d69 100644 --- a/src/storage/ls/ob_ls_meta.cpp +++ b/src/storage/ls/ob_ls_meta.cpp @@ -301,12 +301,12 @@ int ObLSMeta::set_migration_status(const ObMigrationStatus &migration_status, ObLSMeta tmp(*this); tmp.migration_status_ = migration_status; tmp.ls_persistent_state_ = (OB_MIGRATION_STATUS_NONE == migration_status && - ObLSRestoreStatus::RESTORE_NONE == restore_status_ ? + ObLSRestoreStatus::NONE == restore_status_ ? ObLSPersistentState::State::LS_NORMAL : ls_persistent_state_); if (write_slog && OB_FAIL(write_slog_(tmp))) { LOG_WARN("migration_status write slog failed", K(ret)); - } else if ((OB_MIGRATION_STATUS_NONE == migration_status && ObLSRestoreStatus::RESTORE_NONE == restore_status_) + } else if ((OB_MIGRATION_STATUS_NONE == migration_status && ObLSRestoreStatus::NONE == restore_status_) && OB_FAIL(set_finish_ha_state())) { LOG_WARN("set finish ha state failed", K(ret), K(ls_id_)); } else { @@ -394,12 +394,12 @@ int ObLSMeta::set_restore_status(const ObLSRestoreStatus &restore_status) } else { ObLSMeta tmp(*this); tmp.restore_status_ = restore_status; - tmp.ls_persistent_state_ = (ObLSRestoreStatus::RESTORE_NONE == restore_status && + tmp.ls_persistent_state_ = (ObLSRestoreStatus::NONE == restore_status && OB_MIGRATION_STATUS_NONE == migration_status_ ? ObLSPersistentState::State::LS_NORMAL : ls_persistent_state_); if (OB_FAIL(write_slog_(tmp))) { LOG_WARN("restore_status write slog failed", K(ret)); - } else if ((ObLSRestoreStatus::RESTORE_NONE == restore_status && OB_MIGRATION_STATUS_NONE == migration_status_) + } else if ((ObLSRestoreStatus::NONE == restore_status && OB_MIGRATION_STATUS_NONE == migration_status_) && OB_FAIL(set_finish_ha_state())) { LOG_WARN("set finish ha state failed", KR(ret), K(ls_id_)); } else { @@ -560,7 +560,7 @@ int ObLSMeta::check_valid_for_backup() const if (!is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream meta is not valid", K(ret), KPC(this)); - } else if (!restore_status_.is_restore_none()) { + } else if (!restore_status_.is_none()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("restore status is not none", K(ret), KPC(this)); } else if (OB_MIGRATION_STATUS_NONE != migration_status_) { @@ -806,10 +806,12 @@ int ObLSMeta::get_create_type(int64_t &create_type) const ret = OB_ERR_UNEXPECTED; LOG_WARN("log stream meta is not valid, cannot get restore status", K(ret), K(*this)); // before 4.3 - } else if (restore_status_.is_enable_for_restore()) { + } else if (restore_status_.is_required_to_switch_ls_state_for_restore()) { create_type = ObLSCreateType::RESTORE; } else if (ObMigrationStatus::OB_MIGRATION_STATUS_REBUILD == migration_status_) { create_type = ObLSCreateType::MIGRATE; + } else if (restore_status_.is_required_to_switch_ls_state_for_clone()) { + create_type = ObLSCreateType::CLONE; // before 4.3 end // after 4.3 } else if (ls_persistent_state_.is_ha_state()) { @@ -883,6 +885,13 @@ ObLSMeta::ObReentrantRLockGuard::ObReentrantRLockGuard(ObLatch &lock, time_guard_.click("after lock"); } +void ObLSMeta::update_clog_checkpoint_in_ls_meta_package_(const share::SCN& clog_checkpoint_scn, + const palf::LSN& clog_base_lsn) +{ + clog_checkpoint_scn_ = clog_checkpoint_scn; + clog_base_lsn_ = clog_base_lsn; +} + ObLSMeta::ObReentrantRLockGuard::~ObReentrantRLockGuard() { if (OB_LIKELY(OB_SUCCESS == ret_) && first_locked_) { diff --git a/src/storage/ls/ob_ls_meta.h b/src/storage/ls/ob_ls_meta.h index 5d71e3042e..97cfeb270f 100644 --- a/src/storage/ls/ob_ls_meta.h +++ b/src/storage/ls/ob_ls_meta.h @@ -39,10 +39,13 @@ public: static const int64_t NORMAL = 0; static const int64_t RESTORE = 1; static const int64_t MIGRATE = 2; + static const int64_t CLONE = 3; }; class ObLSMeta { + friend class ObLSMetaPackage; + OB_UNIS_VERSION_V(1); public: ObLSMeta(); @@ -162,6 +165,10 @@ public: mutable common::ObLatch lock_; uint64_t tenant_id_; share::ObLSID ls_id_; + +private: + void update_clog_checkpoint_in_ls_meta_package_(const share::SCN& clog_checkpoint_scn, + const palf::LSN& clog_base_lsn); private: ObReplicaType unused_replica_type_; ObLSPersistentState ls_persistent_state_; diff --git a/src/storage/ls/ob_ls_meta_package.cpp b/src/storage/ls/ob_ls_meta_package.cpp index e772f9dab7..626ca484fd 100644 --- a/src/storage/ls/ob_ls_meta_package.cpp +++ b/src/storage/ls/ob_ls_meta_package.cpp @@ -76,5 +76,11 @@ bool ObLSMetaPackage::is_valid() const dup_ls_meta_.is_valid()); } +void ObLSMetaPackage::update_clog_checkpoint_in_ls_meta(const share::SCN& clog_checkpoint_scn, + const palf::LSN& clog_base_lsn) +{ + ls_meta_.update_clog_checkpoint_in_ls_meta_package_(clog_checkpoint_scn, clog_base_lsn); +} + } } diff --git a/src/storage/ls/ob_ls_meta_package.h b/src/storage/ls/ob_ls_meta_package.h index 349ca7ed25..81279e68f3 100644 --- a/src/storage/ls/ob_ls_meta_package.h +++ b/src/storage/ls/ob_ls_meta_package.h @@ -34,6 +34,8 @@ public: ObLSMetaPackage &operator=(const ObLSMetaPackage &other); void reset(); bool is_valid() const; + void update_clog_checkpoint_in_ls_meta(const share::SCN& clog_checkpoint_scn, + const palf::LSN& clog_base_lsn); TO_STRING_KV(K_(ls_meta), K_(palf_meta), K_(dup_ls_meta)); public: diff --git a/src/storage/ls/ob_ls_tablet_service.cpp b/src/storage/ls/ob_ls_tablet_service.cpp index c0144b525a..e2059d9bf0 100644 --- a/src/storage/ls/ob_ls_tablet_service.cpp +++ b/src/storage/ls/ob_ls_tablet_service.cpp @@ -6077,7 +6077,7 @@ int ObLSTabletService::set_allow_to_read_(ObLS *ls) LOG_WARN("failed to get ls migration and restore status", K(ret), KPC(ls)); } else if ((ObMigrationStatus::OB_MIGRATION_STATUS_NONE != migration_status && ObMigrationStatus::OB_MIGRATION_STATUS_HOLD != migration_status) - || ObLSRestoreStatus::RESTORE_NONE != restore_status) { + || ObLSRestoreStatus::NONE != restore_status) { allow_to_read_mgr_.disable_to_read(); FLOG_INFO("set ls do not allow to read", KPC(ls), K(migration_status), K(restore_status)); } else { diff --git a/src/storage/ob_super_block_struct.cpp b/src/storage/ob_super_block_struct.cpp index df691c4907..cd13dbc31e 100644 --- a/src/storage/ob_super_block_struct.cpp +++ b/src/storage/ob_super_block_struct.cpp @@ -22,6 +22,7 @@ namespace storage using namespace oceanbase::common; using namespace oceanbase::blocksstable; +using namespace oceanbase::share; const MacroBlockId ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK(0, MacroBlockId::EMPTY_ENTRY_BLOCK_INDEX, 0); @@ -241,6 +242,40 @@ int ObServerSuperBlock::format_startup_super_block( return ret; } +// ========================== ObTenantSnapshotMetaMeta ============================== +int ObTenantSnapshotMeta::serialize(char *buf, const int64_t buf_len, int64_t &pos) const +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, ls_meta_entry_, snapshot_id_); + return ret; +} + +int ObTenantSnapshotMeta::deserialize(const char *buf, const int64_t data_len, int64_t &pos) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, ls_meta_entry_, snapshot_id_); + return ret; +} + +int64_t ObTenantSnapshotMeta::get_serialize_size() const +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, ls_meta_entry_, snapshot_id_); + return len; +} + +bool ObTenantSnapshotMeta::is_valid() const +{ + return ls_meta_entry_.is_valid() + && snapshot_id_.is_valid(); +} + +void ObTenantSnapshotMeta::reset() +{ + ls_meta_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK; + snapshot_id_.reset(); +} + // ========================== ObTenantSuperBlock ============================== ObTenantSuperBlock::ObTenantSuperBlock() @@ -249,13 +284,39 @@ ObTenantSuperBlock::ObTenantSuperBlock() } ObTenantSuperBlock::ObTenantSuperBlock(const uint64_t tenant_id, const bool is_hidden) - : tenant_id_(tenant_id), is_hidden_(is_hidden), version_(TENANT_SUPER_BLOCK_VERSION) + : tenant_id_(tenant_id), is_hidden_(is_hidden), version_(TENANT_SUPER_BLOCK_VERSION), snapshot_cnt_(0) { replay_start_point_.file_id_ = 1; replay_start_point_.log_id_ = 1; // // Due to the design of slog, the log_id_'s initial value must be 1 replay_start_point_.offset_ = 0; tablet_meta_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK; ls_meta_entry_ = ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK; + for (int64_t i = 0; i < MAX_SNAPSHOT_NUM; i++) { + tenant_snapshots_[i].reset(); + } +} + +ObTenantSuperBlock::ObTenantSuperBlock(const ObTenantSuperBlock &other) +{ + *this = other; +} + +ObTenantSuperBlock &ObTenantSuperBlock::operator=(const ObTenantSuperBlock &other) +{ + if (this != &other) { + reset(); + tenant_id_ = other.tenant_id_; + replay_start_point_ = other.replay_start_point_; + ls_meta_entry_ = other.ls_meta_entry_; + tablet_meta_entry_ = other.tablet_meta_entry_; + is_hidden_ = other.is_hidden_; + version_ = other.version_; + snapshot_cnt_ = other.snapshot_cnt_; + for (int64_t i = 0; i < snapshot_cnt_; i++) { + tenant_snapshots_[i] = other.tenant_snapshots_[i]; + } + } + return *this; } void ObTenantSuperBlock::reset() @@ -266,6 +327,18 @@ void ObTenantSuperBlock::reset() tablet_meta_entry_.reset(); is_hidden_= false; version_ = TENANT_SUPER_BLOCK_VERSION; + for (int64_t i = 0; i < MAX_SNAPSHOT_NUM; i++) { + tenant_snapshots_[i].reset(); + } + snapshot_cnt_ = 0; +} + +void ObTenantSuperBlock::copy_snapshots_from(const ObTenantSuperBlock &other) +{ + snapshot_cnt_ = other.snapshot_cnt_; + for (int64_t i = 0; i < snapshot_cnt_; i++) { + tenant_snapshots_[i] = other.tenant_snapshots_[i]; + } } bool ObTenantSuperBlock::is_valid() const @@ -275,10 +348,84 @@ bool ObTenantSuperBlock::is_valid() const && ls_meta_entry_.is_valid() && tablet_meta_entry_.is_valid() && version_ > MIN_SUPER_BLOCK_VERSION - && (is_old_version() || IS_EMPTY_BLOCK_LIST(tablet_meta_entry_)); + && (is_old_version() || IS_EMPTY_BLOCK_LIST(tablet_meta_entry_)) + && snapshot_cnt_ >= 0; return is_valid; } +int ObTenantSuperBlock::get_snapshot(const ObTenantSnapshotID &snapshot_id, ObTenantSnapshotMeta &snapshot) const +{ + int ret = OB_SUCCESS; + bool found = false; + + for (int64_t i = 0; OB_SUCC(ret) && !found && i < snapshot_cnt_; i++) { + if (snapshot_id == tenant_snapshots_[i].snapshot_id_) { + if (OB_UNLIKELY(!tenant_snapshots_[i].is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("snapshot is invalid", K(ret), K(tenant_snapshots_[i])); + } else { + snapshot = tenant_snapshots_[i]; + found = true; + } + } + } + if (OB_SUCC(ret) && OB_UNLIKELY(!found)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("snapshot doesn't exist", K(ret), K(snapshot_id)); + } + return ret; +} + +int ObTenantSuperBlock::add_snapshot(const ObTenantSnapshotMeta &snapshot) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(check_new_snapshot(snapshot.snapshot_id_))) { + LOG_WARN("fail to check new snapshot", K(ret), K(snapshot)); + } else { + tenant_snapshots_[snapshot_cnt_] = snapshot; + snapshot_cnt_++; + } + return ret; +} + +int ObTenantSuperBlock::check_new_snapshot(const ObTenantSnapshotID &snapshot_id) const +{ + int ret = OB_SUCCESS; + if (snapshot_cnt_ >= MAX_SNAPSHOT_NUM) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("num of snapshots has reached the limit", K(ret), K(snapshot_cnt_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < snapshot_cnt_; i++) { + if (snapshot_id == tenant_snapshots_[i].snapshot_id_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("repeated snapshot id", K(ret), K(snapshot_id)); + } + } + } + return ret; +} + +int ObTenantSuperBlock::delete_snapshot(const ObTenantSnapshotID &snapshot_id) +{ + int ret = OB_SUCCESS; + int64_t index = -1; + for (int64_t i = 0; -1 == index && i < snapshot_cnt_; i++) { + if (tenant_snapshots_[i].snapshot_id_ == snapshot_id) { + index = i; + } + } + if (OB_UNLIKELY(index < 0)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("target snapshot desn't exist", K(ret), K(snapshot_id), K(index)); + } else { + for (int64_t i = index; i < snapshot_cnt_ - 1; i++) { + tenant_snapshots_[i] = tenant_snapshots_[i + 1]; + } + snapshot_cnt_--; + } + return ret; +} + int ObTenantSuperBlock::serialize(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; @@ -310,7 +457,9 @@ int ObTenantSuperBlock::serialize_(char *buf, const int64_t buf_len, int64_t &po replay_start_point_, ls_meta_entry_, tablet_meta_entry_, - is_hidden_); + is_hidden_, + tenant_snapshots_, + snapshot_cnt_); return ret; } @@ -350,7 +499,9 @@ int ObTenantSuperBlock::deserialize_(const char *buf, const int64_t data_len, in replay_start_point_, ls_meta_entry_, tablet_meta_entry_, - is_hidden_); + is_hidden_, + tenant_snapshots_, + snapshot_cnt_); return ret; } @@ -369,7 +520,9 @@ int64_t ObTenantSuperBlock::get_serialize_size_(void) const replay_start_point_, ls_meta_entry_, tablet_meta_entry_, - is_hidden_); + is_hidden_, + tenant_snapshots_, + snapshot_cnt_); return len; } diff --git a/src/storage/ob_super_block_struct.h b/src/storage/ob_super_block_struct.h index 32ae03241b..ff8d5a162c 100644 --- a/src/storage/ob_super_block_struct.h +++ b/src/storage/ob_super_block_struct.h @@ -15,6 +15,7 @@ #include "common/log/ob_log_cursor.h" #include "storage/blocksstable/ob_macro_block_id.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" namespace oceanbase { @@ -103,26 +104,53 @@ public: ServerSuperBlockBody body_; }; +struct ObTenantSnapshotMeta final +{ +public: + ObTenantSnapshotMeta() + : ls_meta_entry_(oceanbase::storage::ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK), snapshot_id_() + { + } + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(ls_meta_entry), K_(snapshot_id)); + OB_UNIS_VERSION(1); +public: + blocksstable::MacroBlockId ls_meta_entry_; + share::ObTenantSnapshotID snapshot_id_; +}; + struct ObTenantSuperBlock final { public: + static const int64_t MAX_SNAPSHOT_NUM = 32; static const int64_t MIN_SUPER_BLOCK_VERSION = 0; static const int64_t TENANT_SUPER_BLOCK_VERSION_V1 = 1; static const int64_t TENANT_SUPER_BLOCK_VERSION = 3; ObTenantSuperBlock(); ObTenantSuperBlock(const uint64_t tenant_id, const bool is_hidden = false); ~ObTenantSuperBlock() = default; + ObTenantSuperBlock(const ObTenantSuperBlock &other); + ObTenantSuperBlock &operator=(const ObTenantSuperBlock &other); + ObTenantSuperBlock &operator==(const ObTenantSuperBlock &other) = delete; + ObTenantSuperBlock &operator!=(const ObTenantSuperBlock &other) = delete; + void copy_snapshots_from(const ObTenantSuperBlock &other); void reset(); bool is_valid() const; + int get_snapshot(const share::ObTenantSnapshotID &snapshot_id, ObTenantSnapshotMeta &snapshot) const; bool is_old_version() const { return version_ < TENANT_SUPER_BLOCK_VERSION; } - bool is_trival_version() const { return version_ == TENANT_SUPER_BLOCK_VERSION_V1; } + int add_snapshot(const ObTenantSnapshotMeta &snapshot); + int delete_snapshot(const share::ObTenantSnapshotID &snapshot_id); + int check_new_snapshot(const share::ObTenantSnapshotID &snapshot_id) const; + bool is_trivial_version() const { return version_ == TENANT_SUPER_BLOCK_VERSION_V1; } TO_STRING_KV(K_(tenant_id), K_(replay_start_point), K_(ls_meta_entry), K_(tablet_meta_entry), K_(is_hidden), - K_(version)); + K_(version), + K_(snapshot_cnt)); OB_UNIS_VERSION(TENANT_SUPER_BLOCK_VERSION); public: uint64_t tenant_id_; @@ -131,6 +159,8 @@ public: blocksstable::MacroBlockId tablet_meta_entry_; bool is_hidden_; int64_t version_; + ObTenantSnapshotMeta tenant_snapshots_[MAX_SNAPSHOT_NUM]; + int64_t snapshot_cnt_; }; #define IS_EMPTY_BLOCK_LIST(entry_block) (entry_block == oceanbase::storage::ObServerSuperBlock::EMPTY_LIST_ENTRY_BLOCK) diff --git a/src/storage/restore/ob_ls_restore_handler.cpp b/src/storage/restore/ob_ls_restore_handler.cpp index d78cb0b4e1..d3162b6056 100644 --- a/src/storage/restore/ob_ls_restore_handler.cpp +++ b/src/storage/restore/ob_ls_restore_handler.cpp @@ -133,7 +133,7 @@ int ObLSRestoreHandler::online() LOG_INFO("ls restore handler is already online"); } else if (OB_FAIL(ls_->get_restore_status(new_status))) { LOG_WARN("fail to get_restore_status", K(ret), KPC(ls_)); - } else if (new_status.is_restore_none()) { + } else if (!new_status.is_in_restore()) { is_online_ = true; } else { lib::ObMutexGuard guard(mtx_); @@ -323,14 +323,14 @@ int ObLSRestoreHandler::check_before_do_restore_(bool &can_do_restore) } else if (!is_normal) { } else if (OB_FAIL(ls_->get_restore_status(restore_status))) { LOG_WARN("fail to get_restore_status", K(ret), KPC(ls_)); - } else if (restore_status.is_restore_none()) { + } else if (!restore_status.is_in_restore()) { lib::ObMutexGuard guard(mtx_); if (OB_NOT_NULL(state_handler_)) { state_handler_->~ObILSRestoreState(); allocator_.free(state_handler_); state_handler_ = nullptr; } - } else if (restore_status.is_restore_failed()) { + } else if (restore_status.is_failed()) { } else if (OB_FAIL(check_restore_job_exist_(is_exist))) { } else if (!is_exist) { if (OB_FAIL(ls_->set_restore_status(ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_FAILED), get_rebuild_seq()))) { @@ -524,7 +524,7 @@ int ObLSRestoreHandler::get_restore_state_handler_(const share::ObLSRestoreStatu } break; } - case ObLSRestoreStatus::Status::RESTORE_NONE: { + case ObLSRestoreStatus::Status::NONE: { ObLSRestoreFinishState *tmp_ptr = nullptr; if (OB_FAIL(construct_state_handler_(tmp_ptr))) { LOG_WARN("fail to construct ObLSRestoreFinishState", K(ret), K(new_status)); @@ -1221,7 +1221,7 @@ int ObILSRestoreState::check_follower_restore_finish(const share::ObLSRestoreSta K(ret), K(leader_status)); } else if (leader_status == follower_status) { is_finish = true; - } else if (leader_status.is_wait_restore_major_data() && follower_status.is_restore_none()) { + } else if (leader_status.is_wait_restore_major_data() && follower_status.is_none()) { is_finish = true; } else if (leader_status.get_status() < follower_status.get_status()) { // when switch leader, follower state may ahead leader @@ -1235,9 +1235,9 @@ bool ObILSRestoreState::check_leader_restore_finish_( const share::ObLSRestoreStatus &follower_status) const { bool ret = false; - if (!leader_status.is_valid() || leader_status.is_restore_failed()) { + if (!leader_status.is_in_restore_or_none() || leader_status.is_failed()) { // leader may restore failed or switch leader - } else if (leader_status.is_restore_none()) { + } else if (leader_status.is_none()) { ret= true; } else if (leader_status.get_status() > follower_status.get_status()) { ret = true; @@ -1600,7 +1600,7 @@ int ObLSRestoreStartState::do_with_uncreated_ls_() { int ret = OB_SUCCESS; bool restore_finish = false; - ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::RESTORE_NONE); + ObLSRestoreStatus next_status(ObLSRestoreStatus::Status::NONE); bool is_created = false; if (OB_FAIL(check_sys_ls_restore_finished_(restore_finish))) { LOG_WARN("fail to check sys ls restore finished", K(ret), KPC(this)); @@ -1762,7 +1762,7 @@ int ObLSRestoreStartState::check_sys_ls_restore_finished_(bool &restore_finish) const ObIArray &replica_locations = location.get_replica_locations(); for (int64_t i = 0; OB_SUCC(ret) && i < replica_locations.count(); ++i) { const ObLSReplicaLocation &replica = replica_locations.at(i); - if (replica.get_restore_status().is_restore_none()) { + if (replica.get_restore_status().is_none()) { } else { tmp_finish = false; } @@ -2654,7 +2654,7 @@ int ObLSRestoreMajorState::do_restore_major_( //================================ObLSRestoreFinishState======================================= ObLSRestoreFinishState::ObLSRestoreFinishState() - : ObILSRestoreState(ObLSRestoreStatus::Status::RESTORE_NONE) + : ObILSRestoreState(ObLSRestoreStatus::Status::NONE) { } @@ -2770,7 +2770,7 @@ int ObLSRestoreWaitState::leader_wait_follower_() next_status = ObLSRestoreStatus::Status::QUICK_RESTORE_FINISH; } else if (ls_restore_status_.is_wait_restore_major_data()) { DEBUG_SYNC(BEFORE_WAIT_MAJOR_RESTORE); - next_status = ObLSRestoreStatus::Status::RESTORE_NONE; + next_status = ObLSRestoreStatus::Status::NONE; } LOG_INFO("leader is wait follower", "leader current status", ls_restore_status_, "next status", next_status, KPC(ls_)); if (OB_FAIL(check_all_follower_restore_finish_(all_finish))) { @@ -2801,7 +2801,7 @@ int ObLSRestoreWaitState::follower_wait_leader_() } else if (ls_restore_status_.is_wait_quick_restore()) { next_status = ObLSRestoreStatus::Status::QUICK_RESTORE_FINISH; } else if (ls_restore_status_.is_wait_restore_major_data()) { - next_status = ObLSRestoreStatus::Status::RESTORE_NONE; + next_status = ObLSRestoreStatus::Status::NONE; } LOG_INFO("follower is wait leader", "follower current status", ls_restore_status_, "next status", next_status, KPC(ls_)); diff --git a/src/storage/slog_ckpt/ob_linked_macro_block_struct.cpp b/src/storage/slog_ckpt/ob_linked_macro_block_struct.cpp index c48928cb61..e65d6b61f8 100644 --- a/src/storage/slog_ckpt/ob_linked_macro_block_struct.cpp +++ b/src/storage/slog_ckpt/ob_linked_macro_block_struct.cpp @@ -107,10 +107,10 @@ int ObMetaBlockListHandle::add_macro_blocks(const ObIArray &tablet_item_map) + const common::hash::ObHashMap &tablet_item_map, + const ObTabletRepalyOperationType replay_type) { int ret = OB_SUCCESS; int64_t cost_time_us = 0; @@ -186,40 +188,42 @@ int ObTabletReplayCreateHandler::init( if (OB_SUCC(ret)) { cost_time_us = ObTimeUtility::current_time() - start_time; FLOG_INFO("finish init ObTabletReplayCreateHandler", K(ret), K(total_tablet_cnt_), K(cost_time_us)); + replay_type_ = replay_type; is_inited_ = true; } return ret; } -int ObTabletReplayCreateHandler::concurrent_replay() +int ObTabletReplayCreateHandler::concurrent_replay(ObStartupAccelTaskHandler* startup_accel_handler) { // for version <= 4.1 or FILE type addr, only support discrete replay -#define ADD_ITEM_RANGE_TO_TASK(start_item_idx, end_item_idx, only_support_discrete) \ +#define ADD_ITEM_RANGE_TO_TASK( \ + startup_accel_handler, start_item_idx, end_item_idx, only_support_discrete) \ ObTabletReplayItemRange range(start_item_idx, end_item_idx); \ if (only_support_discrete) { \ - if (OB_FAIL(add_item_range_to_task_( \ + if (OB_FAIL(add_item_range_to_task_(startup_accel_handler, \ ObTabletReplayCreateTask::DISCRETE, range, discrete_task_))) { \ LOG_WARN("fail to add_item_range_to_task_", K(ret), KPC(discrete_task_)); \ } \ } else if (is_suitable_to_aggregate_(tablet_cnt_in_block, valid_size_in_block)) { \ - if (OB_FAIL(add_item_range_to_task_( \ + if (OB_FAIL(add_item_range_to_task_(startup_accel_handler, \ ObTabletReplayCreateTask::AGGREGATE, range, aggrgate_task_))) { \ LOG_WARN("fail to add_item_range_to_task_", K(ret), KPC(aggrgate_task_)); \ } \ } else { \ - if (OB_FAIL(add_item_range_to_task_( \ + if (OB_FAIL(add_item_range_to_task_(startup_accel_handler, \ ObTabletReplayCreateTask::DISCRETE, range, discrete_task_))) { \ LOG_WARN("fail to add_item_range_to_task_", K(ret), KPC(discrete_task_)); \ } \ } -#define ADD_LAST_TASK(task) \ +#define ADD_LAST_TASK(startup_accel_handler, task) \ if (OB_SUCC(ret)) { \ - if (OB_NOT_NULL(task) && OB_FAIL(add_task_(task))) { \ + if (OB_NOT_NULL(task) && OB_FAIL(add_task_(startup_accel_handler, task))) { \ LOG_WARN("fail to add last task", K(ret), KPC(task), K(inflight_task_cnt_)); \ task->~ObTabletReplayCreateTask(); \ - SERVER_STARTUP_TASK_HANDLER.get_task_allocator().free(task); \ + startup_accel_handler->get_task_allocator().free(task); \ task = nullptr; \ } \ } @@ -230,6 +234,9 @@ int ObTabletReplayCreateHandler::concurrent_replay() if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("ObTabletReplayCreateHandler not inited", K(ret)); + } else if (OB_ISNULL(startup_accel_handler)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("startup_accel_handler is unexpected nullptr", K(ret)); } else if (0 == total_tablet_cnt_) { // do nothing } else { @@ -243,7 +250,7 @@ int ObTabletReplayCreateHandler::concurrent_replay() i++; } if (i > 0) { // addrs of the file type is expected not much, so only use one task here - ADD_ITEM_RANGE_TO_TASK(0, i, true); + ADD_ITEM_RANGE_TO_TASK(startup_accel_handler, 0, i, true); } // <2> handle block addr @@ -255,18 +262,20 @@ int ObTabletReplayCreateHandler::concurrent_replay() tablet_cnt_in_block ++; valid_size_in_block += upper_align(total_tablet_item_arr_[i].addr_.size(), 4096); } else { - ADD_ITEM_RANGE_TO_TASK(i - tablet_cnt_in_block, i, is_old_version); // [start_item_idx, end_item_idx) + ADD_ITEM_RANGE_TO_TASK( + startup_accel_handler, i - tablet_cnt_in_block, i, is_old_version); // [start_item_idx, end_item_idx) pre_block_id = curr_block_id; tablet_cnt_in_block = 1; valid_size_in_block = upper_align(total_tablet_item_arr_[i].addr_.size(), 4096); } } if (OB_SUCC(ret)) { // handle last range - ADD_ITEM_RANGE_TO_TASK(total_tablet_cnt_ - tablet_cnt_in_block, total_tablet_cnt_, is_old_version); + ADD_ITEM_RANGE_TO_TASK( + startup_accel_handler, total_tablet_cnt_ - tablet_cnt_in_block, total_tablet_cnt_, is_old_version); } // handle last task - ADD_LAST_TASK(aggrgate_task_); - ADD_LAST_TASK(discrete_task_); + ADD_LAST_TASK(startup_accel_handler, aggrgate_task_); + ADD_LAST_TASK(startup_accel_handler, discrete_task_); #undef ADD_ITEM_RANGE_TO_TASK #undef ADD_LAST_TASK @@ -291,14 +300,14 @@ int ObTabletReplayCreateHandler::concurrent_replay() return ret; } -int ObTabletReplayCreateHandler::add_item_range_to_task_( +int ObTabletReplayCreateHandler::add_item_range_to_task_(ObStartupAccelTaskHandler* startup_accel_handler, const ObTabletReplayCreateTask::Type type, const ObTabletReplayItemRange &range, ObTabletReplayCreateTask *&task) { int ret = OB_SUCCESS; if (nullptr == task) { if (OB_ISNULL(task = reinterpret_cast( - SERVER_STARTUP_TASK_HANDLER.get_task_allocator().alloc(sizeof(ObTabletReplayCreateTask))))) { + startup_accel_handler->get_task_allocator().alloc(sizeof(ObTabletReplayCreateTask))))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("fail to alloc task buf", K(ret)); } else if (FALSE_IT(task = new(task) ObTabletReplayCreateTask())) { @@ -312,7 +321,7 @@ int ObTabletReplayCreateHandler::add_item_range_to_task_( if (OB_FAIL(task->add_item_range(range, is_enough))) { LOG_WARN("fail to add tablet item range", K(ret), K(range.first), K(range.second), KPC(task)); } else if (is_enough) { // tablet count of this task is enough and will create a new task at next round - if (OB_FAIL(add_task_(task))) { + if (OB_FAIL(add_task_(startup_accel_handler, task))) { LOG_WARN("fail to add replay tablet task", K(ret), KPC(task), K(inflight_task_cnt_)); } else { task = nullptr; @@ -322,13 +331,14 @@ int ObTabletReplayCreateHandler::add_item_range_to_task_( if (OB_FAIL(ret) && OB_NOT_NULL(task)) { task->~ObTabletReplayCreateTask(); - SERVER_STARTUP_TASK_HANDLER.get_task_allocator().free(task); + startup_accel_handler->get_task_allocator().free(task); task = nullptr; } return ret; } -int ObTabletReplayCreateHandler::add_task_(ObTabletReplayCreateTask *task) +int ObTabletReplayCreateHandler::add_task_(ObStartupAccelTaskHandler* startup_accel_handler, + ObTabletReplayCreateTask *task) { int ret = OB_SUCCESS; bool need_retry = false; @@ -337,7 +347,7 @@ int ObTabletReplayCreateHandler::add_task_(ObTabletReplayCreateTask *task) need_retry = false; if (OB_FAIL(ATOMIC_LOAD(&errcode_))) { LOG_WARN("someone ObTabletReplayCreateTask has failed", K(ret), K(inflight_task_cnt_)); - } else if (OB_FAIL(SERVER_STARTUP_TASK_HANDLER.push_task(task))) { + } else if (OB_FAIL(startup_accel_handler->push_task(task))) { if (OB_EAGAIN == ret) { LOG_INFO("task queue is full, wait and retry", KPC(task), K(inflight_task_cnt_)); need_retry = true; @@ -375,7 +385,6 @@ int ObTabletReplayCreateHandler::replay_discrete_tablets(const ObIArrayread_from_disk(addr, io_allocator, buf, buf_len))) { - LOG_WARN("fail to read from disk", K(ret), K(addr), KP(buf), K(buf_len)); - } else if (OB_FAIL(get_tablet_svr_(key.ls_id_, ls_tablet_svr, ls_handle))) { - LOG_WARN("fail to get ls tablet service", K(ret)); - } else if (OB_FAIL(ls_tablet_svr->replay_create_tablet(addr, buf, buf_len, key.tablet_id_, tablet_transfer_info))) { - LOG_WARN("fail to create tablet for replay", K(ret), K(key), K(addr)); + if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->read_from_disk(replay_item.addr_, io_allocator, buf, buf_len))) { + LOG_WARN("fail to read from disk", K(ret), K(replay_item), KP(buf), K(buf_len)); } } while (OB_FAIL(ret) && OB_TIMEOUT == ret && max_retry_time-- > 0); - - if (OB_SUCC(ret)) { - if (tablet_transfer_info.has_transfer_table() && - OB_FAIL(record_ls_transfer_info_(ls_handle, key.tablet_id_, tablet_transfer_info))) { - LOG_WARN("fail to record_ls_transfer_info", K(ret), K(key), K(tablet_transfer_info)); - } + if (OB_SUCC(ret) && OB_FAIL(do_replay(replay_item, buf, buf_len, io_allocator))) { + LOG_WARN("fail to do replay", K(ret), K(replay_item)); } } } @@ -422,7 +419,6 @@ int ObTabletReplayCreateHandler::replay_aggregate_tablets(const ObIArrayreplay_create_tablet(addr, buf, buf_len, key.tablet_id_, tablet_transfer_info))) { - LOG_WARN("fail to create tablet for replay", K(ret), K(key), K(addr)); - } else if (tablet_transfer_info.has_transfer_table() && - OB_FAIL(record_ls_transfer_info_(ls_handle, key.tablet_id_, tablet_transfer_info))) { - LOG_WARN("fail to record_ls_transfer_info", K(ret), K(key), K(tablet_transfer_info)); + } else if (OB_FAIL(ObSharedBlockReaderWriter::parse_data_from_macro_block(macro_handle, replay_item.addr_, buf, buf_len))) { + LOG_WARN("fail to parse_data_from_macro_block", K(ret), K(macro_handle), K(replay_item), K(i), K(idx)); + } else if (OB_FAIL(do_replay(replay_item, buf, buf_len, io_allocator))) { + LOG_WARN("fail to do replay", K(ret), K(replay_item)); } } } @@ -473,6 +460,105 @@ int ObTabletReplayCreateHandler::replay_aggregate_tablets(const ObIArrayget_restore_status(ls_restore_status))) { + LOG_WARN("fail to get ls handle", K(ret), K(key)); + } else if (ls_restore_status.is_in_clone_and_tablet_meta_incomplete()) { + LOG_INFO("the ls is_in_clone_and_tablet_meta_incomplete", K(key), K(ls_restore_status)); + } else if (OB_FAIL(ls_tablet_svr->replay_create_tablet(addr, buf, buf_len, key.tablet_id_, tablet_transfer_info))) { + LOG_WARN("fail to create tablet for replay", K(ret), K(key), K(addr)); + } else if (tablet_transfer_info.has_transfer_table() && + OB_FAIL(record_ls_transfer_info_(ls_handle, key.tablet_id_, tablet_transfer_info))) { + LOG_WARN("fail to record_ls_transfer_info", K(ret), K(key), K(tablet_transfer_info)); + } + return ret; +} + +int ObTabletReplayCreateHandler::replay_inc_macro_ref( + const ObTabletReplayItem &replay_item, + const char *buf, + const int64_t buf_len, + ObArenaAllocator &allocator) +{ + int ret = OB_SUCCESS; + const ObTabletMapKey &key = replay_item.key_; + const ObMetaDiskAddr &addr = replay_item.addr_; + ObTablet tablet; + int64_t pos = 0; + tablet.set_tablet_addr(addr); + if (OB_FAIL(tablet.inc_snapshot_ref_cnt(allocator, buf, buf_len, pos))) { + LOG_WARN("fail to increase macro ref cnt", K(ret), K(tablet)); + } + return ret; +} + +int ObTabletReplayCreateHandler::replay_clone_tablet(const ObTabletReplayItem &replay_item, const char *buf, const int64_t buf_len) +{ + int ret = OB_SUCCESS; + ObLSTabletService *ls_tablet_svr = nullptr; + ObLSHandle ls_handle; + const ObTabletMapKey &key = replay_item.key_; + const ObMetaDiskAddr &addr = replay_item.addr_; + ObTabletTransferInfo tablet_transfer_info; + ObTabletHandle tablet_handle; + if (OB_FAIL(get_tablet_svr_(key.ls_id_, ls_tablet_svr, ls_handle))) { + LOG_WARN("fail to get ls tablet service", K(ret)); + } else if (OB_FAIL(ls_tablet_svr->replay_create_tablet(addr, buf, buf_len, key.tablet_id_, tablet_transfer_info))) { + LOG_WARN("fail to create tablet for replay", K(ret), K(key), K(addr)); + } else if (tablet_transfer_info.has_transfer_table() && + OB_FAIL(record_ls_transfer_info_(ls_handle, key.tablet_id_, tablet_transfer_info))) { + LOG_WARN("fail to record_ls_transfer_info", K(ret), K(key), K(tablet_transfer_info)); + } else if (OB_FAIL(ls_tablet_svr->get_tablet(key.tablet_id_, + tablet_handle, + ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US * 10, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("fail to get tablet", K(ret), K(key), K(addr)); + } + return ret; +} + int ObTabletReplayCreateHandler::check_is_need_record_transfer_info_( const share::ObLSID &src_ls_id, const share::SCN &transfer_start_scn, @@ -559,4 +645,4 @@ int ObTabletReplayCreateHandler::record_ls_transfer_info_( } } // namespace storage -} // namespace oceanbase \ No newline at end of file +} // namespace oceanbase diff --git a/src/storage/slog_ckpt/ob_tablet_replay_create_handler.h b/src/storage/slog_ckpt/ob_tablet_replay_create_handler.h index 67592e4144..67f253200a 100644 --- a/src/storage/slog_ckpt/ob_tablet_replay_create_handler.h +++ b/src/storage/slog_ckpt/ob_tablet_replay_create_handler.h @@ -15,13 +15,17 @@ #define OB_STORAGE_SLOG_CKPT_TBALET_REPLAY_CREATE_HANDLER_H #include "storage/meta_mem/ob_tablet_map_key.h" -#include "observer/ob_server_startup_task_handler.h" +#include "observer/ob_startup_accel_task_handler.h" #include "storage/meta_mem/ob_meta_obj_struct.h" namespace oceanbase { +namespace observer +{ +class ObStartupAccelTaskHandler; +} namespace share { class ObTenantBase; @@ -35,6 +39,14 @@ class ObTabletReplayCreateHandler; class ObTabletTransferInfo; class ObLSTabletService; +enum class ObTabletRepalyOperationType +{ + REPLAY_CREATE_TABLET = 0, + REPLAY_INC_MACRO_REF = 1, + REPLAY_CLONE_TABLET = 2, + INVALID_MODULE +}; + struct ObTabletReplayItem { public: @@ -44,6 +56,7 @@ public: : key_(), addr_() {} ~ObTabletReplayItem() {} bool operator<(const ObTabletReplayItem &r) const; + TO_STRING_KV(K_(key), K_(addr)); ObTabletMapKey key_; ObMetaDiskAddr addr_; @@ -51,7 +64,7 @@ public: using ObTabletReplayItemRange = std::pair; // record the start_item_idx and end_item_idx in total_tablet_item_arr -class ObTabletReplayCreateTask : public observer::ObServerStartupTask +class ObTabletReplayCreateTask : public observer::ObStartupAccelTask { public: enum Type @@ -107,8 +120,10 @@ public: ObTabletReplayCreateHandler(); ~ObTabletReplayCreateHandler() {} - int init(const common::hash::ObHashMap &tablet_item_map); - int concurrent_replay(); + int init( + const common::hash::ObHashMap &tablet_item_map, + const ObTabletRepalyOperationType replay_type); + int concurrent_replay(observer::ObStartupAccelTaskHandler* startup_accel_handler); int replay_discrete_tablets(const ObIArray &range_arr); int replay_aggregate_tablets(const ObIArray &range_arr); @@ -123,18 +138,34 @@ private: { return tablet_cnt_in_block > AGGREGATE_CNT_THRESHOLD && valid_size_in_block > AGGREGATE_SIZE_THRESHOLD; } - int add_item_range_to_task_(const ObTabletReplayCreateTask::Type type, - const ObTabletReplayItemRange &range, ObTabletReplayCreateTask *&task); - int add_task_(ObTabletReplayCreateTask *task); - int get_tablet_svr_(const share::ObLSID &ls_id, ObLSTabletService *&ls_tablet_svr, ObLSHandle &ls_handle); - int record_ls_transfer_info_( + int do_replay( + const ObTabletReplayItem &replay_item, + const char *buf, + const int64_t buf_len, + ObArenaAllocator &allocator) const; + static int replay_create_tablet(const ObTabletReplayItem &replay_item, const char *buf, const int64_t buf_len); + static int replay_inc_macro_ref( + const ObTabletReplayItem &replay_item, + const char *buf, + const int64_t buf_len, + ObArenaAllocator &allocator); + static int replay_clone_tablet(const ObTabletReplayItem &replay_item, const char *buf, const int64_t buf_len); + static int get_tablet_svr_(const share::ObLSID &ls_id, ObLSTabletService *&ls_tablet_svr, ObLSHandle &ls_handle); + static int record_ls_transfer_info_( const ObLSHandle &ls_handle, const ObTabletID &tablet_id, const ObTabletTransferInfo &tablet_transfer_info); - int check_is_need_record_transfer_info_( + static int check_is_need_record_transfer_info_( const share::ObLSID &src_ls_id, const share::SCN &transfer_start_scn, bool &is_need); + int add_item_range_to_task_( + observer::ObStartupAccelTaskHandler* startup_accel_handler, + const ObTabletReplayCreateTask::Type type, + const ObTabletReplayItemRange &range, ObTabletReplayCreateTask *&task); + int add_task_( + observer::ObStartupAccelTaskHandler* startup_accel_handler, + ObTabletReplayCreateTask *task); private: @@ -149,6 +180,7 @@ private: int errcode_; ObTabletReplayItem *total_tablet_item_arr_; int64_t total_tablet_cnt_; + ObTabletRepalyOperationType replay_type_; ObTabletReplayCreateTask *aggrgate_task_; ObTabletReplayCreateTask *discrete_task_; }; @@ -157,4 +189,4 @@ private: } // namespace storage } // namespace oceanbase -#endif \ No newline at end of file +#endif diff --git a/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp b/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp index cf15226f2a..157d2f3bda 100644 --- a/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp +++ b/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.cpp @@ -34,12 +34,14 @@ #include "storage/tx_storage/ob_ls_handle.h" #include "sql/das/ob_das_id_service.h" #include "storage/tablet/ob_tablet.h" +#include "storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h" namespace oceanbase { using namespace share; using namespace common; using namespace blocksstable; +using namespace observer; namespace storage { @@ -63,6 +65,13 @@ void ObLSCkptMember::reset() dup_ls_meta_.reset(); } +bool ObLSCkptMember::is_valid() const +{ + return ls_meta_.is_valid() + && dup_ls_meta_.is_valid() + && tablet_meta_entry_.is_valid(); +} + int ObLSCkptMember::serialize(char *buf, const int64_t buf_len, int64_t &pos) const { int ret = OB_SUCCESS; @@ -157,7 +166,6 @@ void ObTenantCheckpointSlogHandler::ObWriteCheckpointTask::runTimerTask() } } - ObTenantCheckpointSlogHandler::ObTenantCheckpointSlogHandler() : is_inited_(false), is_writing_checkpoint_(false), @@ -174,6 +182,8 @@ ObTenantCheckpointSlogHandler::ObTenantCheckpointSlogHandler() write_ckpt_task_(this), replay_tablet_disk_addr_map_(), shared_block_rwriter_(), + super_block_mutex_(), + is_trivial_version_(false), shared_block_raw_rwriter_() { } @@ -220,6 +230,7 @@ int ObTenantCheckpointSlogHandler::start() } else if (OB_UNLIKELY(!super_block.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tenant super block invalid", K(ret), K(super_block)); + } else if (FALSE_IT(ATOMIC_STORE(&is_trivial_version_, super_block.is_trivial_version()))) { } else if (OB_FAIL(replay_checkpoint_and_slog(super_block))) { LOG_WARN("fail to read_checkpoint_and_replay_slog", K(ret), K(super_block)); } else if (OB_FAIL(TG_START(tg_id_))) { @@ -281,6 +292,8 @@ int ObTenantCheckpointSlogHandler::replay_checkpoint_and_slog(const ObTenantSupe LOG_WARN("ObTenantCheckpointSlogHandler not init", K(ret)); } else if (OB_FAIL(replay_tablet_disk_addr_map_.create(replay_tablet_cnt, mem_attr, mem_attr))) { LOG_WARN("fail to create replay map", K(ret)); + } else if (OB_FAIL(replay_snapshot(super_block))) { + LOG_WARN("fail to replay snapshot", K(ret), K(super_block)); } else if (OB_FAIL(replay_checkpoint(super_block))) { LOG_WARN("fail to read_ls_checkpoint", K(ret), K(super_block)); } else if (OB_FAIL(replay_tenant_slog(super_block.replay_start_point_))) { @@ -294,7 +307,8 @@ int ObTenantCheckpointSlogHandler::replay_checkpoint_and_slog(const ObTenantSupe int ObTenantCheckpointSlogHandler::replay_checkpoint(const ObTenantSuperBlock &super_block) { int ret = OB_SUCCESS; - const bool is_replay_old = super_block.is_trival_version(); + const bool is_replay_old = super_block.is_trivial_version(); + replay_tablet_disk_addr_map_.reuse(); if (OB_UNLIKELY(is_replay_old)) { if (OB_FAIL(replay_old_checkpoint(super_block))) { @@ -318,11 +332,11 @@ int ObTenantCheckpointSlogHandler::replay_old_checkpoint(const ObTenantSuperBloc ObTenantStorageCheckpointReader tenant_storage_ckpt_reader; ObArray meta_block_list; - ObTenantStorageCheckpointReader::ObCheckpointMetaOp replay_ls_op = + ObTenantStorageCheckpointReader::ObStorageMetaOp replay_ls_op = std::bind(&ObTenantCheckpointSlogHandler::replay_ls_meta, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); - ObTenantStorageCheckpointReader::ObCheckpointMetaOp replay_tablet_op = + ObTenantStorageCheckpointReader::ObStorageMetaOp replay_tablet_op = std::bind(&ObTenantCheckpointSlogHandler::replay_tablet, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); @@ -332,12 +346,12 @@ int ObTenantCheckpointSlogHandler::replay_old_checkpoint(const ObTenantSuperBloc } else if (!replay_tablet_op.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("replay_tablet_op invalid", K(ret)); - } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_checkpoint_item( + } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_meta_item( super_block.ls_meta_entry_, replay_ls_op, meta_block_list))) { LOG_WARN("fail to replay ls meta checkpoint", K(ret)); } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(meta_block_list))) { LOG_WARN("fail to add_macro_blocks", K(ret)); - } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_checkpoint_item( + } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_meta_item( super_block.tablet_meta_entry_, replay_tablet_op, meta_block_list))) { LOG_WARN("fail to replay tablet checkpoint", K(ret)); } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(meta_block_list))) { @@ -347,104 +361,6 @@ int ObTenantCheckpointSlogHandler::replay_old_checkpoint(const ObTenantSuperBloc return ret; } -int ObTenantCheckpointSlogHandler::replay_new_checkpoint(const ObTenantSuperBlock &super_block) -{ - int ret = OB_SUCCESS; - const MacroBlockId &ls_meta_entry = super_block.ls_meta_entry_; - ObLinkedMacroBlockItemReader ls_ckpt_reader; - ObSArray tablet_block_list; - - if (OB_UNLIKELY(IS_EMPTY_BLOCK_LIST(ls_meta_entry))) { - LOG_INFO("no ls checkpoint", K(ret)); - } else if (OB_FAIL(ls_ckpt_reader.init(ls_meta_entry))) { - LOG_WARN("fail to init log stream item reader", K(ret), K(ls_meta_entry)); - } else { - char *item_buf = nullptr; - int64_t item_buf_len = 0; - ObLSCkptMember ls_ckpt_member; - int64_t pos = 0; - ObMetaDiskAddr addr; - while (OB_SUCC(ret)) { - item_buf = nullptr; - item_buf_len = 0; - pos = 0; - ls_ckpt_member.reset(); - if (OB_FAIL(ls_ckpt_reader.get_next_item(item_buf, item_buf_len, addr))) { - if (OB_ITER_END != ret) { - LOG_WARN("fail to get next log stream item", K(ret)); - } else { - ret = OB_SUCCESS; - break; - } - } else if (OB_FAIL(ls_ckpt_member.deserialize(item_buf, item_buf_len, pos))) { - LOG_WARN("fail to deserialize ls ckpt member", K(ret), KP(item_buf), K(item_buf_len), K(pos)); - } else if (OB_FAIL(MTL(ObLSService *)->replay_create_ls(ls_ckpt_member.ls_meta_))) { - LOG_WARN("fail to replay put ls", K(ret), K(ls_ckpt_member)); - } else if (OB_FAIL(replay_dup_table_ls_meta(ls_ckpt_member.dup_ls_meta_))) { - LOG_WARN("fail to replay set dup table ls meta", K(ret), K(ls_ckpt_member)); - } else if (OB_FAIL(replay_new_tablet_checkpoint(ls_ckpt_member.tablet_meta_entry_, tablet_block_list))) { - LOG_WARN("fail to replay new tablet ckpt", K(ret), K(ls_ckpt_member)); - } - } - - if (OB_FAIL(ret)) { - // do nothing - } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(ls_ckpt_reader.get_meta_block_list()))) { - LOG_WARN("fail to add ls macro blocks", K(ret)); - } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(tablet_block_list))) { - LOG_WARN("fail to add tablet macro blocks", K(ret)); - } - } - - return ret; -} - -int ObTenantCheckpointSlogHandler::replay_new_tablet_checkpoint( - const blocksstable::MacroBlockId &tablet_entry_block, - ObIArray &tablet_block_list) -{ - int ret = OB_SUCCESS; - ObLinkedMacroBlockItemReader tablet_ckpt_reader; - - if (OB_UNLIKELY(IS_EMPTY_BLOCK_LIST(tablet_entry_block))) { - LOG_INFO("no tablet checkpoint", K(tablet_entry_block)); - } else if (OB_FAIL(tablet_ckpt_reader.init(tablet_entry_block))) { - LOG_WARN("fail to init tablet ckpt reader", K(ret), K(tablet_entry_block)); - } else { - char *item_buf = nullptr; - int64_t item_buf_len = 0; - int64_t pos = 0; - ObMetaDiskAddr addr; - while (OB_SUCC(ret)) { - item_buf = nullptr; - item_buf_len = 0; - pos = 0; - if (OB_FAIL(tablet_ckpt_reader.get_next_item(item_buf, item_buf_len, addr))) { - if (OB_ITER_END != ret) { - LOG_WARN("fail to get next log stream item", K(ret)); - } else { - ret = OB_SUCCESS; - break; - } - } else if (OB_FAIL(inner_replay_deserialize( - item_buf, item_buf_len, false /* allow to overwrite the map's element or not */))) { - LOG_WARN("fail to replay tablet", K(ret), KP(item_buf), K(item_buf_len)); - } - } - - if (OB_SUCC(ret)) { - const ObIArray ¯o_block_list = tablet_ckpt_reader.get_meta_block_list(); - for (int64_t i = 0; i < macro_block_list.count() && OB_SUCC(ret); i++) { - if (OB_FAIL(tablet_block_list.push_back(macro_block_list.at(i)))) { - LOG_WARN("fail to push back macro block id", K(ret)); - } - } - } - } - - return ret; -} - int ObTenantCheckpointSlogHandler::replay_ls_meta( const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len) { @@ -464,6 +380,156 @@ int ObTenantCheckpointSlogHandler::replay_ls_meta( return ret; } +int ObTenantCheckpointSlogHandler::replay_tablet( + const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!addr.is_valid() || nullptr == buf || buf_len <= 0 || !addr.is_block())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(addr)); + } else if (OB_FAIL(inner_replay_old_deserialize( + addr, + buf, + buf_len, + false /* allow to overwrite the map's element or not */))) { + LOG_WARN("fail to replay old tablet", K(ret), K(addr), KP(buf), K(buf_len)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_snapshot(const ObTenantSuperBlock &super_block) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < super_block.snapshot_cnt_; i++) { + const ObTenantSnapshotMeta &snapshot = super_block.tenant_snapshots_[i]; + replay_tablet_disk_addr_map_.reuse(); + if (OB_FAIL(do_replay_single_snapshot(snapshot.ls_meta_entry_))) { + LOG_WARN("fail to replay single snapshot", K(ret), K(snapshot)); + } + } + return ret; +} + +int ObTenantCheckpointSlogHandler::do_replay_single_snapshot(const blocksstable::MacroBlockId &ls_meta_entry) +{ + int ret = OB_SUCCESS; + ObTenantStorageCheckpointReader ls_ckpt_reader; + ObSArray ls_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("ReplaySnap", MTL_ID())); + ObTenantStorageCheckpointReader::ObStorageMetaOp replay_snapshot_ls_op = std::bind( + &ObTenantCheckpointSlogHandler::replay_snapshot_ls, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3); + bool inc_ls_blocks_ref_succ = false; + + if (OB_FAIL(ls_ckpt_reader.iter_read_meta_item( + ls_meta_entry, replay_snapshot_ls_op, ls_block_list))) { + LOG_WARN("fail to iter replay ls", K(ret), K(ls_meta_entry)); + } else if (OB_FAIL(ObTenantMetaSnapshotHandler::inc_linked_block_ref( + ls_block_list, inc_ls_blocks_ref_succ))) { + LOG_WARN("fail to increase ls linked blocks' ref cnt", K(ret)); + } else { + ObTabletReplayCreateHandler handler; + if (OB_FAIL(handler.init(replay_tablet_disk_addr_map_, ObTabletRepalyOperationType::REPLAY_INC_MACRO_REF))) { + LOG_WARN("fail to init ObTabletReplayCreateHandler", K(ret)); + } else if (OB_FAIL(handler.concurrent_replay(GCTX.startup_accel_handler_))) { + LOG_WARN("fail to concurrent replay tablets", K(ret)); + } + } + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_snapshot_ls( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len) +{ + int ret = OB_SUCCESS; + ObLSCkptMember ls_ckpt_member; + int64_t pos = 0; + ObTenantStorageCheckpointReader tablet_ckpt_reader; + ObSArray tablet_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("ReplaySnap", MTL_ID())); + ObTenantStorageCheckpointReader::ObStorageMetaOp replay_tablet_op = + std::bind(&ObTenantCheckpointSlogHandler::replay_new_tablet, + this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); + bool inc_tablet_blocks_ref_succ = false; + + if (OB_FAIL(ls_ckpt_member.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize ls_ckpt_member", K(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(tablet_ckpt_reader.iter_read_meta_item( + ls_ckpt_member.tablet_meta_entry_, replay_tablet_op, tablet_block_list))) { + LOG_WARN("fail to iter replay tablet", K(ret), K(ls_ckpt_member)); + } else if (OB_FAIL(ObTenantMetaSnapshotHandler::inc_linked_block_ref( + tablet_block_list, inc_tablet_blocks_ref_succ))) { + LOG_WARN("fail to increase tablet linked blocks' ref cnt", K(ret)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_new_checkpoint(const ObTenantSuperBlock &super_block) +{ + int ret = OB_SUCCESS; + ObTenantStorageCheckpointReader ls_ckpt_reader; + ObSArray tablet_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("ReplayCKPT", MTL_ID())); + ObSArray ls_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("ReplayCKPT", MTL_ID())); + ObTenantStorageCheckpointReader::ObStorageMetaOp replay_ls_op = std::bind( + &ObTenantCheckpointSlogHandler::replay_new_ls, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + tablet_block_list); + + if (OB_FAIL(ls_ckpt_reader.iter_read_meta_item( + super_block.ls_meta_entry_, replay_ls_op, ls_block_list))) { + LOG_WARN("fail to iter replay ls", K(ret), K(super_block)); + } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(ls_block_list))) { + LOG_WARN("fail to add ls linked blocks", K(ret), K(ls_block_list)); + } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(tablet_block_list))) { + LOG_WARN("fail to add tablet linked blocks", K(ret), K(tablet_block_list)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_new_ls( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &tablet_block_list) +{ + int ret = OB_SUCCESS; + ObLSCkptMember ls_ckpt_member; + int64_t pos = 0; + ObTenantStorageCheckpointReader tablet_ckpt_reader; + ObTenantStorageCheckpointReader::ObStorageMetaOp replay_tablet_op = + std::bind(&ObTenantCheckpointSlogHandler::replay_new_tablet, + this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); + + if (OB_FAIL(ls_ckpt_member.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize ls_ckpt_member", K(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(MTL(ObLSService *)->replay_create_ls(ls_ckpt_member.ls_meta_))) { + LOG_WARN("fail to replay put ls", K(ret), K(ls_ckpt_member)); + } else if (OB_FAIL(replay_dup_table_ls_meta(ls_ckpt_member.dup_ls_meta_))) { + LOG_WARN("fail to replay set dup table ls meta", K(ret), K(ls_ckpt_member)); + } else if (OB_FAIL(tablet_ckpt_reader.iter_read_meta_item( + ls_ckpt_member.tablet_meta_entry_, replay_tablet_op, tablet_block_list))) { + LOG_WARN("fail to iter replay tablet", K(ret), K(ls_ckpt_member)); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::replay_new_tablet( + const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(inner_replay_deserialize( + buf, buf_len, false /* allow to overwrite the map's element or not */))) { + LOG_WARN("fail to replay tablet", K(ret), KP(buf), K(buf_len)); + } + return ret; +} + int ObTenantCheckpointSlogHandler::replay_dup_table_ls_meta( const transaction::ObDupTableLSCheckpoint::ObLSDupTableMeta &dup_ls_meta) { @@ -499,13 +565,20 @@ int ObTenantCheckpointSlogHandler::replay_tenant_slog(const common::ObLogCursor if (OB_FAIL(replayer.init(MTL(ObStorageLogger *)->get_dir(), log_file_spec))) { LOG_WARN("fail to init slog replayer", K(ret)); - } else if (OB_FAIL(replayer.register_redo_module( - ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, this))) { + } else if (OB_FAIL(replayer.register_redo_module(ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, this))) { LOG_WARN("fail to register redo module", K(ret)); } else if (OB_FAIL(replayer.replay(start_point, replay_finish_point, MTL_ID()))) { LOG_WARN("fail to replay tenant slog", K(ret)); - } else if (OB_FAIL(concurrent_replay_load_tablets())) { - LOG_WARN("fail to concurrent replay load tablets", K(ret)); + } else { + ObTabletReplayCreateHandler handler; + if (OB_FAIL(handler.init(replay_tablet_disk_addr_map_, ObTabletRepalyOperationType::REPLAY_CREATE_TABLET))) { + LOG_WARN("fail to init ObTabletReplayCreateHandler", K(ret)); + } else if (OB_FAIL(handler.concurrent_replay(GCTX.startup_accel_handler_))) { + LOG_WARN("fail to concurrent replay tablets", K(ret)); + } + } + if (OB_FAIL(ret)) { + // do nothing } else if (OB_FAIL(replayer.replay_over())) { LOG_WARN("fail to replay over", K(ret)); } else if (OB_FAIL(MTL(ObStorageLogger *)->start_log(replay_finish_point))) { @@ -547,11 +620,7 @@ int ObTenantCheckpointSlogHandler::read_from_disk( int ret = OB_SUCCESS; char *read_buf = nullptr; const int64_t read_buf_len = addr.size(); - const ObTenantSuperBlock super_block = static_cast(MTL_CTX())->get_super_block(); - if (OB_UNLIKELY(!super_block.is_valid())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("super block is invalid", K(ret), K(super_block)); - } else if (!super_block.is_trival_version()) { + if (!ATOMIC_LOAD(&is_trivial_version_)) { if (ObMetaDiskAddr::DiskType::FILE == addr.type()) { if (OB_FAIL(read_empty_shell_file(addr, allocator, buf, buf_len))) { LOG_WARN("fail to read empty shell", K(ret), K(addr), K(buf), K(buf_len)); @@ -570,14 +639,69 @@ int ObTenantCheckpointSlogHandler::read_from_disk( return ret; } -int ObTenantCheckpointSlogHandler::concurrent_replay_load_tablets() +int ObTenantCheckpointSlogHandler::clone_ls(ObStartupAccelTaskHandler* startup_accel_handler, + const blocksstable::MacroBlockId &tablet_meta_entry) { int ret = OB_SUCCESS; - ObTabletReplayCreateHandler handler; - if (OB_FAIL(handler.init(replay_tablet_disk_addr_map_))) { - LOG_WARN("fail to init ObTabletReplayCreateHandler", K(ret)); - } else if (OB_FAIL(handler.concurrent_replay())) { - LOG_WARN("fail to concurrent replay tablets", K(ret)); + const ObMemAttr mem_attr(MTL_ID(), "SnapCreate"); + const int64_t replay_tablet_cnt = 10003; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantCheckpointSlogHandler not init", K(ret)); + } else if (OB_ISNULL(startup_accel_handler)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("startup_accel_handler is unexpected nullptr", K(ret)); + } else if (OB_FAIL(replay_tablet_disk_addr_map_.create(replay_tablet_cnt, mem_attr, mem_attr))) { + LOG_WARN("fail to create replay map", K(ret)); + } else { + ObTenantStorageCheckpointReader tablet_snapshot_reader; + ObSArray meta_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("SnapCreate", MTL_ID())); + ObArenaAllocator arena_allocator("SnapRecovery", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + ObTenantStorageCheckpointReader::ObStorageMetaOp clone_tablet_op = std::bind( + &ObTenantCheckpointSlogHandler::clone_tablet, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3); + + if (OB_UNLIKELY(!tablet_meta_entry.is_valid() || IS_EMPTY_BLOCK_LIST(tablet_meta_entry))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(tablet_meta_entry)); + } else if (OB_FAIL(tablet_snapshot_reader.iter_read_meta_item( + tablet_meta_entry, clone_tablet_op, meta_block_list))) { + LOG_WARN("fail to iter create tablet", K(ret), K(tablet_meta_entry)); + } else { + ObTabletReplayCreateHandler handler; + if (OB_FAIL(handler.init(replay_tablet_disk_addr_map_, ObTabletRepalyOperationType::REPLAY_CLONE_TABLET))) { + LOG_WARN("fail to init ObTabletReplayCreateHandler", K(ret)); + } else if (OB_FAIL(handler.concurrent_replay(startup_accel_handler))) { + LOG_WARN("fail to concurrent replay tablets", K(ret)); + } + } + replay_tablet_disk_addr_map_.destroy(); + } + + return ret; +} + +int ObTenantCheckpointSlogHandler::clone_tablet( + const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len) +{ + int ret = OB_SUCCESS; + ObUpdateTabletLog slog; + ObTabletMapKey tablet_key; + int64_t pos = 0; + if (OB_FAIL(slog.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize create tablet slog", K(ret), K(pos), K(buf_len), K(slog)); + } else if (OB_UNLIKELY(!slog.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("slog is invalid", K(ret), K(slog)); + } else { + tablet_key.ls_id_ = slog.ls_id_; + tablet_key.tablet_id_ = slog.tablet_id_; + if (OB_FAIL(replay_tablet_disk_addr_map_.set_refactored(tablet_key, slog.disk_addr_, /*allow_override*/ 0))) { + LOG_WARN("fail to update tablet meta addr", K(ret), K(slog)); + } } return ret; } @@ -638,6 +762,19 @@ int ObTenantCheckpointSlogHandler::check_slog(const ObTabletMapKey &tablet_key, return ret; } +int ObTenantCheckpointSlogHandler::add_macro_blocks( + const common::ObIArray &ls_block_list, + const common::ObIArray &tablet_block_list) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ls_block_handle_.add_macro_blocks(ls_block_list))) { + LOG_WARN("fail to add ls macro blocks", K(ret)); + } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(tablet_block_list))) { + LOG_WARN("fail to add tablet blocks", K(ret)); + } + return ret; +} + int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) { int ret = OB_SUCCESS; @@ -645,10 +782,10 @@ int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) int64_t min_interval = ObWriteCheckpointTask::RETRY_WRITE_CHECKPOINT_MIN_INTERVAL; uint64_t tenant_id = MTL_ID(); - ObTenantSuperBlock tmp_super_block(tenant_id); + ObTenantSuperBlock super_block(tenant_id); ObTenantStorageCheckpointWriter tenant_storage_ckpt_writer; omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); - ObTenantSuperBlock last_super_block = tenant->get_super_block(); + const ObTenantSuperBlock last_super_block = tenant->get_super_block(); //Don't compare to MTL(ObTenantTabletScheduler*)->get_frozen_version(), because we expect to do //checkpoint after merge finish. @@ -695,34 +832,39 @@ int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) && ckpt_cursor_.newer_than(last_super_block.replay_start_point_) &&(ckpt_cursor_.log_id_ - last_super_block.replay_start_point_.log_id_ >= ObWriteCheckpointTask::MIN_WRITE_CHECKPOINT_LOG_CNT))) { DEBUG_SYNC(AFTER_CHECKPOINT_GET_CURSOR); - - tmp_super_block.replay_start_point_ = ckpt_cursor_; - if (OB_FAIL(tenant_storage_ckpt_writer.init())) { - LOG_WARN("fail to init tenant_storage_ckpt_writer_", K(ret)); - } else if (OB_FAIL(tenant_storage_ckpt_writer.write_checkpoint(tmp_super_block))) { + super_block.replay_start_point_ = ckpt_cursor_; + if (OB_FAIL(tenant_storage_ckpt_writer.init(ObTenantStorageMetaType::CKPT))) { + LOG_WARN("fail to init tenant_storage_meta_writer", K(ret)); + } else if (OB_FAIL(tenant_storage_ckpt_writer.record_meta(super_block.ls_meta_entry_))) { LOG_WARN("fail to write_checkpoint", K(ret)); } clean_copy_status(); + + if (OB_SUCC(ret)) { + lib::ObMutexGuard guard(super_block_mutex_); + super_block.copy_snapshots_from(tenant->get_super_block()); + if (OB_FAIL(ObServerCheckpointSlogHandler::get_instance().write_tenant_super_block_slog(super_block))) { + LOG_WARN("fail to write_tenant_super_block_slog", K(ret), K(super_block)); + } else { + tenant->set_tenant_super_block(super_block); + } + } if (OB_FAIL(ret)) { // do nothing - } else if (OB_FAIL(ObServerCheckpointSlogHandler::get_instance().write_tenant_super_block_slog(tmp_super_block))) { - LOG_WARN("fail to write_tenant_super_block_slog", K(ret), K(tmp_super_block)); } else if (OB_FAIL(update_tablet_meta_addr_and_block_list( - last_super_block.is_trival_version(), tenant_storage_ckpt_writer))) { + last_super_block.is_trivial_version(), tenant_storage_ckpt_writer))) { LOG_ERROR("fail to update_tablet_meta_addr_and_block_list", K(ret), K(last_super_block)); // abort if failed, because it cannot be rolled back if partially success. // otherwise, updates need to be transactional. ob_usleep(1000 * 1000); ob_abort(); + } else if (OB_FAIL(MTL(ObStorageLogger *)->remove_useless_log_file(ckpt_cursor_.file_id_, MTL_ID()))) { + LOG_WARN("fail to remove_useless_log_file", K(ret), K(super_block)); } else { - tenant->set_tenant_super_block(tmp_super_block); - if (OB_FAIL(MTL(ObStorageLogger *)->remove_useless_log_file(ckpt_cursor_.file_id_, MTL_ID()))) { - LOG_WARN("fail to remove_useless_log_file", K(ret), K(tmp_super_block)); - } else { - last_ckpt_time_ = start_time; - last_frozen_version_ = frozen_version; - cost_time = ObTimeUtility::current_time() - start_time; - } + ATOMIC_STORE(&is_trivial_version_, super_block.is_trivial_version()); + last_ckpt_time_ = start_time; + last_frozen_version_ = frozen_version; + cost_time = ObTimeUtility::current_time() - start_time; } int tmp_ret = OB_SUCCESS; @@ -730,7 +872,7 @@ int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) LOG_ERROR("fail to rollback checkpoint, macro blocks leak", K(tmp_ret)); } - FLOG_INFO("finish write tenant checkpoint", K(ret), K(last_super_block), K(tmp_super_block), + FLOG_INFO("finish write tenant checkpoint", K(ret), K(last_super_block), K(super_block), K_(last_ckpt_time), K(start_time), K(broadcast_version),K(frozen_version), K_(last_frozen_version), K(is_force), K(cost_time)); SERVER_EVENT_ADD("storage", "write slog checkpoint", "tenant_id", tenant_id, @@ -743,6 +885,74 @@ int ObTenantCheckpointSlogHandler::write_checkpoint(bool is_force) return ret; } +int ObTenantCheckpointSlogHandler::add_snapshot(const ObTenantSnapshotMeta &tenant_snapshot) +{ + int ret = OB_SUCCESS; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + lib::ObMutexGuard guard(super_block_mutex_); + ObTenantSuperBlock super_block = tenant->get_super_block(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantCheckpointSlogHandler hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(tenant_snapshot)); + } else if (OB_FAIL(super_block.add_snapshot(tenant_snapshot))) { + LOG_WARN("fail to add snapshot to super block", K(ret), K(tenant_snapshot)); + } else if (OB_FAIL(ObServerCheckpointSlogHandler::get_instance().write_tenant_super_block_slog(super_block))) { + LOG_WARN("fail to write_tenant_super_block_slog", K(ret), K(super_block)); + } else { + tenant->set_tenant_super_block(super_block); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::delete_snapshot(const ObTenantSnapshotID &snapshot_id) +{ + int ret = OB_SUCCESS; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + lib::ObMutexGuard guard(super_block_mutex_); + ObTenantSuperBlock super_block = tenant->get_super_block(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantCheckpointSlogHandler hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(snapshot_id)); + } else if (OB_FAIL(super_block.delete_snapshot(snapshot_id))) { + LOG_WARN("fail to delete target snapshot", K(ret), K(snapshot_id)); + } else if (OB_FAIL(ObServerCheckpointSlogHandler::get_instance().write_tenant_super_block_slog(super_block))) { + LOG_WARN("fail to write_tenant_super_block_slog", K(ret), K(super_block)); + } else { + tenant->set_tenant_super_block(super_block); + } + return ret; +} + +int ObTenantCheckpointSlogHandler::swap_snapshot(const ObTenantSnapshotMeta &tenant_snapshot) +{ + int ret = OB_SUCCESS; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + lib::ObMutexGuard guard(super_block_mutex_); + ObTenantSuperBlock super_block = tenant->get_super_block(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantCheckpointSlogHandler hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!tenant_snapshot.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(tenant_snapshot)); + } else if (OB_FAIL(super_block.delete_snapshot(tenant_snapshot.snapshot_id_))) { + LOG_WARN("fail to delete target snapshot", K(ret), K(tenant_snapshot)); + } else if (OB_FAIL(super_block.add_snapshot(tenant_snapshot))) { + LOG_WARN("fail to add snapshot", K(ret), K(tenant_snapshot)); + } else if (OB_FAIL(ObServerCheckpointSlogHandler::get_instance().write_tenant_super_block_slog(super_block))) { + LOG_WARN("fail to write_tenant_super_block_slog", K(ret), K(super_block)); + } else { + tenant->set_tenant_super_block(super_block); + } + return ret; +} + int ObTenantCheckpointSlogHandler::get_cur_cursor() { int ret = OB_SUCCESS; @@ -767,7 +977,7 @@ void ObTenantCheckpointSlogHandler::clean_copy_status() int ObTenantCheckpointSlogHandler::update_tablet_meta_addr_and_block_list( const bool is_replay_old, - ObTenantStorageCheckpointWriter &ckpt_writer) + ObTenantStorageCheckpointWriter &meta_writer) { int ret = OB_SUCCESS; ObIArray *meta_block_list = nullptr; @@ -780,7 +990,7 @@ int ObTenantCheckpointSlogHandler::update_tablet_meta_addr_and_block_list( // update the tablet addr. to resolve the dead lock, update_tablet_meta_addr is moved out of lock, // but this may cause t3m read a new addr which is not in the tablet_block_handle_. when this // happens, t3m needs to retry. - if (OB_FAIL(ckpt_writer.batch_compare_and_swap_tablet(is_replay_old))) { + if (OB_FAIL(meta_writer.batch_compare_and_swap_tablet(is_replay_old))) { LOG_WARN("fail to update_tablet_meta_addr", K(ret), K(is_replay_old)); } @@ -788,19 +998,16 @@ int ObTenantCheckpointSlogHandler::update_tablet_meta_addr_and_block_list( if (OB_FAIL(ret)) { } else { do { - if (OB_FAIL(ckpt_writer.get_ls_block_list(meta_block_list))) { + if (OB_FAIL(meta_writer.get_ls_block_list(meta_block_list))) { LOG_WARN("fail to get_ls_block_list", K(ret)); } else if (OB_FAIL(ls_block_handle_.add_macro_blocks(*meta_block_list))) { LOG_WARN("fail to add_macro_blocks", K(ret)); - } else if (OB_FAIL(ckpt_writer.get_tablet_block_list(meta_block_list))) { + } else if (OB_FAIL(meta_writer.get_tablet_block_list(meta_block_list))) { LOG_WARN("fail to get_tablet_block_list", K(ret)); } else if (OB_FAIL(tablet_block_handle_.add_macro_blocks(*meta_block_list))) { LOG_WARN("fail to set_tablet_block_list", K(ret)); } - if (OB_UNLIKELY(OB_ALLOCATE_MEMORY_FAILED == ret)) { - LOG_WARN("memory is insufficient, retry", K(ret)); - } - } while (OB_UNLIKELY(OB_ALLOCATE_MEMORY_FAILED == ret)); + } while (OB_ALLOCATE_MEMORY_FAILED == ret); } return ret; @@ -1109,23 +1316,6 @@ int ObTenantCheckpointSlogHandler::inner_replay_put_old_tablet(const ObRedoModul return ret; } -int ObTenantCheckpointSlogHandler::replay_tablet( - const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!addr.is_valid() || nullptr == buf || buf_len <= 0 || !addr.is_block())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(addr)); - } else if (OB_FAIL(inner_replay_old_deserialize( - addr, - buf, - buf_len, - false /* allow to overwrite the map's element or not */))) { - LOG_WARN("fail to replay old tablet", K(ret), K(addr), KP(buf), K(buf_len)); - } - return ret; -} - int ObTenantCheckpointSlogHandler::inner_replay_old_deserialize( const ObMetaDiskAddr &addr, const char *buf, diff --git a/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h b/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h index 4ad829a260..6914fb6399 100644 --- a/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h +++ b/src/storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h @@ -29,6 +29,7 @@ namespace oceanbase namespace share { class ObLSID; +class ObTenantSnapshotID; } namespace storage { @@ -47,6 +48,7 @@ public: DISALLOW_COPY_AND_ASSIGN(ObLSCkptMember); void reset(); + bool is_valid() const; int serialize(char *buf, const int64_t len, int64_t &pos) const; int deserialize( const char *buf, @@ -86,8 +88,6 @@ public: ObTenantCheckpointSlogHandler *handler_; }; - - ObTenantCheckpointSlogHandler(); ~ObTenantCheckpointSlogHandler() = default; ObTenantCheckpointSlogHandler(const ObTenantCheckpointSlogHandler &) = delete; @@ -99,6 +99,13 @@ public: void stop(); void wait(); void destroy(); + + int add_macro_blocks( + const common::ObIArray &ls_block_list, + const common::ObIArray &tablet_block_list); + int add_snapshot(const ObTenantSnapshotMeta &tenant_snapshot); + int delete_snapshot(const share::ObTenantSnapshotID &snapshot_id); + int swap_snapshot(const ObTenantSnapshotMeta &tenant_snapshot); int report_slog(const ObTabletMapKey &tablet_key, const ObMetaDiskAddr &slog_addr); int check_slog(const ObTabletMapKey &tablet_key, bool &has_slog); int read_tablet_checkpoint_by_addr( @@ -117,22 +124,33 @@ public: common::ObArenaAllocator &allocator, char *&buf, int64_t &buf_len); - + int clone_ls( + observer::ObStartupAccelTaskHandler* startup_accel_handler, + const blocksstable::MacroBlockId &tablet_meta_entry); private: + int clone_tablet(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len); int read_from_share_blk(const ObMetaDiskAddr &addr, common::ObArenaAllocator &allocator, char *&buf, int64_t &buf_len); - int concurrent_replay_load_tablets(); int get_cur_cursor(); void clean_copy_status(); virtual int parse(const int32_t cmd, const char *buf, const int64_t len, FILE *stream) override; int replay_checkpoint_and_slog(const ObTenantSuperBlock &super_block); int replay_checkpoint(const ObTenantSuperBlock &super_block); + int replay_snapshot(const ObTenantSuperBlock &super_block); + int do_replay_single_snapshot(const blocksstable::MacroBlockId &ls_meta_entry); int replay_new_checkpoint(const ObTenantSuperBlock &super_block); int replay_old_checkpoint(const ObTenantSuperBlock &super_block); - int replay_new_tablet_checkpoint( - const blocksstable::MacroBlockId &tablet_entry_block, - common::ObIArray &tablet_block_list); int replay_ls_meta(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len); int replay_tablet(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len); + int replay_snapshot_ls( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len); + int replay_new_ls( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &tablet_block_list); + int replay_new_tablet(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len); int update_tablet_meta_addr_and_block_list( const bool is_replay_old, ObTenantStorageCheckpointWriter &ckpt_writer); int replay_dup_table_ls_meta(const transaction::ObDupTableLSCheckpoint::ObLSDupTableMeta &dup_ls_meta); @@ -185,6 +203,8 @@ private: ObWriteCheckpointTask write_ckpt_task_; ReplayTabletDiskAddrMap replay_tablet_disk_addr_map_; ObSharedBlockReaderWriter shared_block_rwriter_; + lib::ObMutex super_block_mutex_; + bool is_trivial_version_; ObSharedBlockReaderWriter shared_block_raw_rwriter_; }; diff --git a/src/storage/slog_ckpt/ob_tenant_meta_snapshot_handler.cpp b/src/storage/slog_ckpt/ob_tenant_meta_snapshot_handler.cpp new file mode 100644 index 0000000000..c96186897b --- /dev/null +++ b/src/storage/slog_ckpt/ob_tenant_meta_snapshot_handler.cpp @@ -0,0 +1,625 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "ob_tenant_meta_snapshot_handler.h" +#include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" +#include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" +#include "storage/meta_mem/ob_meta_obj_struct.h" +#include "storage/ob_super_block_struct.h" +#include "storage/tx/ob_timestamp_service.h" +#include "observer/omt/ob_tenant.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_slog_helper.h" +#include "storage/slog/ob_storage_logger.h" +#include "observer/ob_startup_accel_task_handler.h" + +namespace oceanbase +{ +using namespace common; +using namespace blocksstable; +namespace storage +{ +int ObTenantMetaSnapshotHandler::create_tenant_snapshot(const ObTenantSnapshotID &snapshot_id) +{ + int ret = OB_SUCCESS; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + const ObTenantSuperBlock last_super_block = tenant->get_super_block(); + ObTenantSnapshotMeta snapshot; + snapshot.snapshot_id_ = snapshot_id; + + if (OB_UNLIKELY(!snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(snapshot_id)); + } else if (OB_FAIL(last_super_block.check_new_snapshot(snapshot_id))) { + LOG_WARN("fail to check snapshot version", K(ret)); + } else if (OB_UNLIKELY(tenant->is_hidden())) { + ret = OB_NOT_SUPPORTED; + LOG_INFO("shouldn't create snapshot for hidden tenant", K(ret)); + } else if (OB_UNLIKELY(!last_super_block.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get tenant super block", K(ret), K(last_super_block)); + } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->add_snapshot(snapshot))) { + LOG_WARN("fail to add snapshot", K(ret), K(snapshot)); + } + + FLOG_INFO("finish creating tenant snapshot", K(ret), K(last_super_block)); + return ret; +} + +int ObTenantMetaSnapshotHandler::create_single_ls_snapshot(const ObTenantSnapshotID &snapshot_id, const ObLSID &ls_id, share::SCN &clog_max_scn) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(update_single_ls_snapshot(snapshot_id, ls_id, MetaRecordMode::ADD_LS, clog_max_scn))) { + LOG_WARN("fail to update single ls snapshot", K(ret), K(snapshot_id), K(ls_id)); + } + return ret; +} + +int ObTenantMetaSnapshotHandler::delete_single_ls_snapshot(const ObTenantSnapshotID &snapshot_id, const ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + share::SCN unused_scn; + if (OB_FAIL(update_single_ls_snapshot(snapshot_id, ls_id, MetaRecordMode::DELETE_LS, unused_scn))) { + LOG_WARN("fail to update single ls snapshot", K(ret), K(snapshot_id), K(ls_id)); + } + return ret; +} + +int ObTenantMetaSnapshotHandler::update_single_ls_snapshot( + const ObTenantSnapshotID &snapshot_id, + const ObLSID &ls_id, + const MetaRecordMode modify_mode, + share::SCN &clog_max_scn) +{ + int ret = OB_SUCCESS; + ObTenantStorageCheckpointWriter tenant_storage_meta_writer; + MacroBlockId orig_ls_meta_entry; + ObTenantSnapshotMeta snapshot; + ObSArray ls_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("CreateSnapLS", MTL_ID())); + bool inc_ls_blocks_ref_succ = false; + bool inc_tablet_blocks_ref_succ = false; + + if (OB_UNLIKELY(!snapshot_id.is_valid() || !ls_id.is_valid() || MetaRecordMode::INVALID_MODE == modify_mode)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(snapshot_id), K(ls_id), K(modify_mode)); + } else if (OB_FAIL(get_ls_meta_entry(snapshot_id, orig_ls_meta_entry))) { + LOG_WARN("fail to get ls meta entry", K(ret), K(snapshot_id)); + } else if (OB_FAIL(tenant_storage_meta_writer.init(ObTenantStorageMetaType::SNAPSHOT))) { + LOG_WARN("fail to init tenant storage checkpoint writer", K(ret)); + } else if (MetaRecordMode::ADD_LS == modify_mode + && OB_FAIL(tenant_storage_meta_writer.record_single_ls_meta(orig_ls_meta_entry, ls_id, ls_block_list, snapshot.ls_meta_entry_, clog_max_scn))) { + LOG_WARN("fail to record_single_ls_meta", K(ret), K(orig_ls_meta_entry), K(ls_id)); + } else if (MetaRecordMode::DELETE_LS == modify_mode + && OB_FAIL(tenant_storage_meta_writer.delete_single_ls_meta(orig_ls_meta_entry, ls_id, ls_block_list, snapshot.ls_meta_entry_))) { + LOG_WARN("fail to delete_single_ls_meta", K(ret), K(orig_ls_meta_entry), K(ls_id)); + } else if (FALSE_IT(snapshot.snapshot_id_ = snapshot_id)) { + } else if (OB_FAIL(inc_all_linked_block_ref(tenant_storage_meta_writer, inc_ls_blocks_ref_succ, inc_tablet_blocks_ref_succ))) { + LOG_WARN("fail to increase ref cnt for all linked blocks", K(ret)); + } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->swap_snapshot(snapshot))) { + LOG_WARN("fail to swap snapshot", K(ret), K(snapshot)); + } + + if (OB_FAIL(ret)) { + rollback_ref_cnt(inc_ls_blocks_ref_succ, inc_tablet_blocks_ref_succ, tenant_storage_meta_writer); + } else { + dec_meta_block_ref(ls_block_list); + } + FLOG_INFO("finish updating snapshot", K(ret), K(ls_id), K(snapshot_id), K(snapshot), K(modify_mode)); + return ret; +} + +int ObTenantMetaSnapshotHandler::inc_all_linked_block_ref( + ObTenantStorageCheckpointWriter &tenant_storage_meta_writer, + bool &inc_ls_blocks_ref_succ, + bool &inc_tablet_blocks_ref_succ) +{ + int ret = OB_SUCCESS; + ObIArray *meta_block_list = nullptr; + if (OB_FAIL(tenant_storage_meta_writer.get_ls_block_list(meta_block_list))) { + LOG_WARN("fail to get ls block list", K(ret)); + } else if (OB_FAIL(inc_linked_block_ref(*meta_block_list, inc_ls_blocks_ref_succ))) { + LOG_WARN("fail to increase macro block ref for ls block", K(ret)); + } else if (OB_FAIL(tenant_storage_meta_writer.get_tablet_block_list(meta_block_list))) { + LOG_WARN("fail to get tablet block list", K(ret)); + } else if (OB_FAIL(inc_linked_block_ref(*meta_block_list, inc_tablet_blocks_ref_succ))) { + LOG_WARN("fail to increase macro block ref for tablet block", K(ret)); + } + return ret; +} + +void ObTenantMetaSnapshotHandler::rollback_ref_cnt( + const bool inc_ls_blocks_ref_succ, + const bool inc_tablet_blocks_ref_succ, + ObTenantStorageCheckpointWriter &tenant_storage_meta_writer) +{ + int ret = OB_SUCCESS; + ObIArray *meta_block_list = nullptr; + // ignore all ret, because we need to rollback the ref cnt as much as possible + if (OB_FAIL(tenant_storage_meta_writer.rollback())) { + LOG_ERROR("fail to rollback checkpoint, macro blocks may leak", K(ret)); + } + if (inc_ls_blocks_ref_succ) { + if (OB_FAIL(tenant_storage_meta_writer.get_ls_block_list(meta_block_list))) { + LOG_ERROR("fail to get ls block list, macro blocks may leak", K(ret)); + } else { + dec_meta_block_ref(*meta_block_list); + } + } + if (inc_tablet_blocks_ref_succ) { + if (OB_FAIL(tenant_storage_meta_writer.get_tablet_block_list(meta_block_list))) { + LOG_ERROR("fail to get tablet block list, macro blocks may leak", K(ret)); + } else { + dec_meta_block_ref(*meta_block_list); + } + } +} + +int ObTenantMetaSnapshotHandler::get_ls_meta_entry( + const ObTenantSnapshotID &snapshot_id, + blocksstable::MacroBlockId &ls_meta_entry) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotMeta snapshot; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + const ObTenantSuperBlock super_block = tenant->get_super_block(); + if (OB_UNLIKELY(!snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(snapshot_id)); + } else if (OB_UNLIKELY(tenant->is_hidden())) { + ret = OB_NOT_SUPPORTED; + LOG_INFO("shouldn't get snapshot from hidden tenant", K(ret)); + } else if (OB_UNLIKELY(!super_block.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get tenant super block", K(ret), K(super_block)); + } else if (OB_FAIL(super_block.get_snapshot(snapshot_id, snapshot))) { + LOG_WARN("fail to get snapshot", K(ret), K(snapshot_id), K(super_block)); + } else { + ls_meta_entry = snapshot.ls_meta_entry_; + } + return ret; +} + +int ObTenantMetaSnapshotHandler::inc_linked_block_ref( + const ObIArray &meta_block_list, + bool &inc_success) +{ + int ret = OB_SUCCESS; + inc_success = false; + int64_t meta_block_num = 0; + + for (int64_t i = 0; OB_SUCC(ret) && i < meta_block_list.count(); i++) { + if (OB_FAIL(OB_SERVER_BLOCK_MGR.inc_ref(meta_block_list.at(i)))) { + LOG_WARN("fail to increase meta block ref", K(ret), K(meta_block_list.at(i))); + } else { + meta_block_num++; + } + } + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + for (int64_t i = 0; i < meta_block_num; i++) { + if (OB_TMP_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(meta_block_list.at(i)))) { + LOG_WARN("fail to decrease meta block ref, macro block may leak", K(tmp_ret), K(meta_block_list.at(i))); + } + } + } else { + inc_success = true; + } + return ret; +} + +void ObTenantMetaSnapshotHandler::dec_meta_block_ref(const ObIArray &meta_block_list) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; i < meta_block_list.count(); i++) { + if (OB_FAIL(OB_SERVER_BLOCK_MGR.dec_ref(meta_block_list.at(i)))) { + LOG_WARN("fail to decrease meta block ref, macro block may leak", K(ret), K(meta_block_list.at(i))); + } + } +} + +int ObTenantMetaSnapshotHandler::delete_tenant_snapshot(const ObTenantSnapshotID &snapshot_id) +{ + int ret = OB_SUCCESS; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + const ObTenantSuperBlock last_super_block = tenant->get_super_block(); + ObTenantStorageCheckpointReader ls_snapshot_reader; + ObTenantSnapshotMeta snapshot; + ObSArray ls_meta_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("DelSnap", MTL_ID())); + ObSArray deleted_tablet_addrs(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("DelSnap", MTL_ID())); + ObSArray tablet_meta_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("DelSnap", MTL_ID())); + ObTenantStorageCheckpointReader::ObStorageMetaOp del_ls_snapshot_op = std::bind( + &ObTenantMetaSnapshotHandler::delete_ls_snapshot, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::ref(deleted_tablet_addrs), + std::ref(tablet_meta_block_list)); + + if (OB_UNLIKELY(!snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(snapshot_id)); + } else if (OB_UNLIKELY(tenant->is_hidden())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can't delete snapshot for hidden tenant", K(ret)); + } else if (OB_UNLIKELY(!last_super_block.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("super block is invalid", K(ret), K(last_super_block)); + } else if (OB_FAIL(last_super_block.get_snapshot(snapshot_id, snapshot))) { + LOG_WARN("fail to get snapshot", K(ret), K(snapshot_id), K(last_super_block)); + } else if (OB_FAIL(ls_snapshot_reader.iter_read_meta_item( + snapshot.ls_meta_entry_, del_ls_snapshot_op, ls_meta_block_list))) { + LOG_WARN("fail to delete ls snapshot", K(ret), K(snapshot)); + } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->delete_snapshot(snapshot_id))) { + LOG_WARN("fail to delete snapshot", K(ret), K(snapshot_id)); + } else { + dec_meta_block_ref(ls_meta_block_list); + dec_meta_block_ref(tablet_meta_block_list); + ObArenaAllocator arena_allocator("DelSnapTablet", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + ObTablet tablet; + for (int64_t i = 0; i < deleted_tablet_addrs.count(); i++) { + tablet.reset(); + arena_allocator.reuse(); + int64_t buf_len = 0; + char *buf = nullptr; + int64_t pos = 0; + do { + if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->read_from_disk( + deleted_tablet_addrs[i], + arena_allocator, + buf, + buf_len))) { + LOG_WARN("fail to read from disk", K(ret), K(deleted_tablet_addrs[i])); + } + } while (ObTenantStorageCheckpointWriter::ignore_ret(ret)); + if (OB_SUCC(ret)) { + tablet.set_tablet_addr(deleted_tablet_addrs[i]); + if (OB_FAIL(tablet.release_ref_cnt(arena_allocator, buf, buf_len, pos))) { + LOG_ERROR("fail to decrease macro ref cnt, macro block may leak", K(ret), K(tablet)); + } + } + } + } + + FLOG_INFO("finish deleting tenant snapshot", K(ret), K(last_super_block)); + return ret; +} + +int ObTenantMetaSnapshotHandler::delete_ls_snapshot( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &deleted_tablet_addrs, + ObIArray &tablet_meta_block_list) +{ + UNUSED(addr); + int ret = OB_SUCCESS; + ObLSCkptMember ls_ckpt_member; + int64_t pos = 0; + ObTenantStorageCheckpointReader tablet_snapshot_reader; + ObSArray meta_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("SnapTablet", MTL_ID())); + ObTenantStorageCheckpointReader::ObStorageMetaOp del_tablet_snapshot_op = std::bind( + &ObTenantMetaSnapshotHandler::delete_tablet_snapshot, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::ref(deleted_tablet_addrs)); + + if (OB_FAIL(ls_ckpt_member.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize ls_ckpt_member", K(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(tablet_snapshot_reader.iter_read_meta_item( + ls_ckpt_member.tablet_meta_entry_, del_tablet_snapshot_op, meta_block_list))) { + LOG_WARN("fail to delete tablet snapshot", K(ret), K(ls_ckpt_member)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < meta_block_list.count(); i++) { + if (OB_FAIL(tablet_meta_block_list.push_back(meta_block_list.at(i)))) { + LOG_WARN("fail to push back meta block id", K(ret), K(i), K(meta_block_list.at(i))); + } + } + } + return ret; +} + +int ObTenantMetaSnapshotHandler::delete_tablet_snapshot( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &deleted_tablet_addrs) +{ + UNUSED(addr); + int ret = OB_SUCCESS; + ObUpdateTabletLog slog; + int64_t pos = 0; + if (OB_FAIL(slog.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize update tablet slog", K(ret), KP(buf), K(buf_len)); + } else if (OB_UNLIKELY(!slog.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("slog is invalid", K(ret), K(slog)); + } else if (OB_FAIL(deleted_tablet_addrs.push_back(slog.disk_addr_))) { + LOG_WARN("fail to push back tablet's disk addr", K(ret), K(slog)); + } + return ret; +} + +int ObTenantMetaSnapshotHandler::get_all_tenant_snapshot(ObIArray &snapshot_ids) +{ + int ret = OB_SUCCESS; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + const ObTenantSuperBlock super_block = tenant->get_super_block(); + + if (OB_UNLIKELY(tenant->is_hidden())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can't get snapshot from hidden tenant", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < super_block.snapshot_cnt_; i++) { + const ObTenantSnapshotMeta &snapshot = super_block.tenant_snapshots_[i]; + if (OB_UNLIKELY(!snapshot.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("snapshot meta is invalid", K(ret), K(snapshot)); + } else if (OB_FAIL(snapshot_ids.push_back(snapshot.snapshot_id_))) { + LOG_WARN("fail to push back to snapshot ids", K(ret), K(snapshot), K(i)); + } + } + } + return ret; +} + +int ObTenantMetaSnapshotHandler::get_all_ls_snapshot( + const ObTenantSnapshotID &snapshot_id, + ObIArray &ls_ids) +{ + int ret = OB_SUCCESS; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + const ObTenantSuperBlock super_block = tenant->get_super_block(); + ObTenantSnapshotMeta snapshot; + ObTenantStorageCheckpointReader ls_ckpt_reader; + ObSArray meta_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("GetAllLS", MTL_ID())); + ObTenantStorageCheckpointReader::ObStorageMetaOp push_ls_op = std::bind( + &ObTenantMetaSnapshotHandler::push_ls_snapshot, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::ref(ls_ids)); + + if (OB_UNLIKELY(!snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(snapshot_id)); + } else if (OB_UNLIKELY(tenant->is_hidden())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can't get snapshot from hidden tenant", K(ret), K(snapshot_id)); + } else if (OB_UNLIKELY(!super_block.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("super block is invalid", K(ret), K(super_block), K(snapshot_id)); + } else if (OB_FAIL(super_block.get_snapshot(snapshot_id, snapshot))) { + LOG_WARN("fail to get snapshot", K(ret), K(snapshot_id)); + } else if (OB_FAIL(ls_ckpt_reader.iter_read_meta_item(snapshot.ls_meta_entry_, push_ls_op, meta_block_list))) { + LOG_WARN("fail to iter push ls", K(ret), K(snapshot)); + } + return ret; +} + +int ObTenantMetaSnapshotHandler::push_ls_snapshot( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &ls_ids) +{ + UNUSED(addr); + int ret = OB_SUCCESS; + int64_t pos = 0; + ObLSCkptMember ls_ckpt_member; + if (OB_FAIL(ls_ckpt_member.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize ls ckpt member", K(ret), KP(buf), K(buf_len), K(pos)); + } else if (OB_FAIL(ls_ids.push_back(ls_ckpt_member.ls_meta_.ls_id_))) { + LOG_WARN("fail to push back ls id", K(ret), K(ls_ckpt_member)); + } + return ret; +} + +int ObTenantMetaSnapshotHandler::get_ls_snapshot( + const ObTenantSnapshotID &snapshot_id, + const ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotMeta snapshot; + omt::ObTenant *tenant = static_cast(share::ObTenantEnv::get_tenant()); + const ObTenantSuperBlock super_block = tenant->get_super_block(); + + if (OB_UNLIKELY(!snapshot_id.is_valid() || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(snapshot_id), K(ls_id)); + } else if (OB_UNLIKELY(tenant->is_hidden())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can't get ls snapshot from hidden tenant", K(ret), K(snapshot_id), K(ls_id)); + } else if (OB_UNLIKELY(!super_block.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("super block is invalid", K(ret), K(super_block)); + } else if (OB_FAIL(super_block.get_snapshot(snapshot_id, snapshot))) { + LOG_WARN("fail to get snapshot", K(ret), K(snapshot_id), K(super_block)); + } else if (OB_FAIL(find_tablet_meta_entry(snapshot.ls_meta_entry_, ls_id, tablet_meta_entry))) { + LOG_WARN("fail to get tablet meta entry", K(ret), K(snapshot), K(ls_id)); + } + return ret; +} + +int ObTenantMetaSnapshotHandler::find_tablet_meta_entry( + const blocksstable::MacroBlockId &ls_meta_entry, + const ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry) +{ + int ret = OB_SUCCESS; + ObLinkedMacroBlockItemReader ls_ckpt_reader; + + if (OB_UNLIKELY(!ls_meta_entry.is_valid() || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_meta_entry), K(ls_id)); + } else if (OB_UNLIKELY(IS_EMPTY_BLOCK_LIST(ls_meta_entry))) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("ls snapshot doesn't exist", K(ret), K(ls_meta_entry)); + } else if (OB_FAIL(ls_ckpt_reader.init(ls_meta_entry))) { + LOG_WARN("fail to init log stream item reader", K(ret), K(ls_meta_entry)); + } else { + char *item_buf = nullptr; + int64_t item_buf_len = 0; + ObLSCkptMember ls_ckpt_member; + int64_t pos = 0; + ObMetaDiskAddr addr; + while (OB_SUCC(ret)) { + item_buf = nullptr; + item_buf_len = 0; + pos = 0; + ls_ckpt_member.reset(); + if (OB_FAIL(ls_ckpt_reader.get_next_item(item_buf, item_buf_len, addr))) { + if (OB_ITER_END != ret) { + LOG_WARN("fail to get next log stream item", K(ret)); + } else { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("can't find target ls snapshot", K(ret)); + } + } else if (OB_FAIL(ls_ckpt_member.deserialize(item_buf, item_buf_len, pos))) { + LOG_WARN("fail to deserialize ls ckpt member", K(ret), KP(item_buf), K(item_buf_len), K(pos)); + } else if (ls_ckpt_member.ls_meta_.ls_id_ == ls_id) { + tablet_meta_entry = ls_ckpt_member.tablet_meta_entry_; + break; + } + } + } + return ret; +} + +int ObTenantMetaSnapshotHandler::create_all_tablet(observer::ObStartupAccelTaskHandler* startup_accel_handler, + const blocksstable::MacroBlockId &tablet_meta_entry) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!tablet_meta_entry.is_valid() || IS_EMPTY_BLOCK_LIST(tablet_meta_entry))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(tablet_meta_entry)); + } + + if (OB_SUCC(ret)) { + ObTenantStorageCheckpointReader tablet_snapshot_reader; + ObSArray meta_block_list(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("SnapCreate", MTL_ID())); + ObSArray slog_arr; + slog_arr.set_attr(ObMemAttr(MTL_ID(), "SnapRecovery")); + + ObTenantStorageCheckpointReader::ObStorageMetaOp write_slog_op = std::bind( + &ObTenantMetaSnapshotHandler::batch_write_slog, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + std::ref(slog_arr)); + + if (OB_FAIL(tablet_snapshot_reader.iter_read_meta_item(tablet_meta_entry, write_slog_op, meta_block_list))) { + LOG_WARN("fail to iter write slog", K(ret), K(tablet_meta_entry)); + } else if (0 != slog_arr.count() && OB_FAIL(do_write_slog(slog_arr))) { + LOG_WARN("fail to write and report slogs", K(ret), K(slog_arr)); + } else { + FLOG_INFO("write all tablet slog done"); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->clone_ls(startup_accel_handler, tablet_meta_entry))) { + LOG_WARN("fail to clone one ls", K(ret)); + } + } + return ret; +} + +int ObTenantMetaSnapshotHandler::batch_write_slog( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &slog_arr) +{ + UNUSED(addr); + int ret = OB_SUCCESS; + ObUpdateTabletLog slog; + ObStorageLogParam log_param; + int64_t pos = 0; + + if (MAX_SLOG_BATCH_NUM <= slog_arr.count()) { + if (OB_FAIL(do_write_slog(slog_arr))) { + LOG_WARN("fail to write and report slogs", K(ret), K(slog_arr)); + } else { + slog_arr.reuse(); + } + } + + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(slog.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize update tablet slog", K(ret), KP(buf), K(buf_len)); + } else if (OB_UNLIKELY(!slog.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("slog is invalid", K(ret), K(slog)); + } else if (OB_FAIL(slog_arr.push_back(slog))) { + LOG_WARN("fail to push back slog entry", K(ret), K(slog)); + } + return ret; +} + +int ObTenantMetaSnapshotHandler::do_write_slog(ObIArray &slog_arr) +{ + int ret = OB_SUCCESS; + ObSArray param_arr; + param_arr.set_attr(ObMemAttr(MTL_ID(), "SnapRecovery")); + ObStorageLogParam log_param; + log_param.cmd_ = ObIRedoModule::gen_cmd( + ObRedoLogMainType::OB_REDO_LOG_TENANT_STORAGE, + ObRedoLogSubType::OB_REDO_LOG_UPDATE_TABLET); + if (OB_FAIL(param_arr.reserve(slog_arr.count()))) { + LOG_WARN("fail to reserve memory for slog param arr", K(ret), K(slog_arr.count())); + } + for (int64_t i = 0; OB_SUCC(ret) && i < slog_arr.count(); i++) { + log_param.data_ = &(slog_arr.at(i)); + if (OB_FAIL(param_arr.push_back(log_param))) { + LOG_WARN("fail to push back slog param", K(ret), K(log_param)); + } + } + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(MTL(ObStorageLogger*)->write_log(param_arr))) { + LOG_WARN("fail to batch write slog", K(ret), K(param_arr.count())); + } else if (OB_FAIL(batch_report_slog(param_arr))) { + LOG_WARN("fail to batch report slog", K(ret), K(param_arr.count())); + } + return ret; +} + +int ObTenantMetaSnapshotHandler::batch_report_slog(const ObIArray ¶m_arr) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < param_arr.count(); i++) { + const ObStorageLogParam &log_param = param_arr.at(i); + const ObUpdateTabletLog *slog = reinterpret_cast(log_param.data_); + const ObTabletMapKey tablet_key(slog->ls_id_, slog->tablet_id_); + do { + if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->report_slog(tablet_key, log_param.disk_addr_))) { + if (OB_ALLOCATE_MEMORY_FAILED != ret) { + LOG_WARN("fail to report slog", K(ret), K(tablet_key), K(log_param)); + } else if (REACH_TIME_INTERVAL(1000 * 1000L)) { // 1s + LOG_WARN("fail to report slog due to memory limit", K(ret), K(tablet_key), K(log_param)); + } + } + } while (OB_ALLOCATE_MEMORY_FAILED == ret); + } + return ret; +} + +} +} diff --git a/src/storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h b/src/storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h new file mode 100644 index 0000000000..15be6cabac --- /dev/null +++ b/src/storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h @@ -0,0 +1,115 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OB_STORAGE_TENANT_META_SNAPSHOT_HANDLER_H_ +#define OB_STORAGE_TENANT_META_SNAPSHOT_HANDLER_H_ + +#include "storage/slog_ckpt/ob_linked_macro_block_struct.h" +#include "storage/meta_mem/ob_tablet_map_key.h" +#include "storage/ob_super_block_struct.h" +#include "storage/ls/ob_ls_meta.h" +#include "storage/tx/ob_dup_table_base.h" +#include "storage/high_availability/ob_tablet_transfer_info.h" +#include "storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.h" +#include "storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h" +#include "storage/slog/ob_storage_log_struct.h" +#include "storage/slog/ob_storage_log.h" + +namespace oceanbase +{ +namespace share +{ +class ObTenantSnapshotID; +} +namespace observer +{ +class ObStartupAccelTaskHandler; +} +namespace storage +{ +class ObTenantStorageCheckpointWriter; +class ObTenantMetaSnapshotHandler +{ +public: + static const int64_t MAX_SLOG_BATCH_NUM = 30000; // almost 2MB +public: + ObTenantMetaSnapshotHandler() {} + ~ObTenantMetaSnapshotHandler() = default; + DISALLOW_COPY_AND_ASSIGN(ObTenantMetaSnapshotHandler); + + // create snapshot + static int create_tenant_snapshot(const ObTenantSnapshotID &snapshot_id); + static int create_single_ls_snapshot(const ObTenantSnapshotID &snapshot_id, const ObLSID &ls_id, share::SCN &clog_max_scn); + + // delete snapshot + static int delete_tenant_snapshot(const ObTenantSnapshotID &snapshot_id); + static int delete_single_ls_snapshot(const ObTenantSnapshotID &snapshot_id, const ObLSID &ls_id); + + // clone snapshot + static int get_ls_snapshot( + const ObTenantSnapshotID &snapshot_id, + const ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry); + static int create_all_tablet(observer::ObStartupAccelTaskHandler* startup_accel_handler, + const blocksstable::MacroBlockId &tablet_meta_entry); + static int get_ls_meta_entry(const ObTenantSnapshotID &snapshot_id, blocksstable::MacroBlockId &ls_meta_entry); + + // recover snapshot for restart + static int get_all_tenant_snapshot(ObIArray &snapshot_ids); + static int get_all_ls_snapshot(const ObTenantSnapshotID &snapshot_id, ObIArray &ls_ids); + + // increase ref cnt for linked blocks + static int inc_linked_block_ref(const ObIArray &meta_block_list, bool &inc_success); + +private: + static int update_single_ls_snapshot( + const ObTenantSnapshotID &snapshot_id, + const ObLSID &ls_id, + const MetaRecordMode modify_mode, + share::SCN &clog_max_scn); + static int find_tablet_meta_entry( + const blocksstable::MacroBlockId &ls_meta_entry, + const ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry); + static int push_ls_snapshot(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len, ObIArray &ls_ids); + static int inc_all_linked_block_ref( + ObTenantStorageCheckpointWriter &tenant_storage_meta_writer, + bool &inc_ls_blocks_ref_succ, + bool &inc_tablet_blocks_ref_succ); + static void rollback_ref_cnt( + const bool inc_ls_blocks_ref_succ, + const bool inc_tablet_blocks_ref_succ, + ObTenantStorageCheckpointWriter &tenant_storage_meta_writer); + static void dec_meta_block_ref(const ObIArray &meta_block_list); + static int delete_ls_snapshot( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &deleted_tablet_addrs, + ObIArray &tablet_meta_block_list); + static int delete_tablet_snapshot( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &deleted_tablet_addrs); + static int batch_write_slog( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + ObIArray &slog_array); + static int batch_report_slog(const ObIArray ¶m_arr); + static int do_write_slog(ObIArray &slog_arr); +}; +} +} + +#endif diff --git a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp index 4cb88d4c25..4a12313a36 100644 --- a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp +++ b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.cpp @@ -29,16 +29,17 @@ namespace storage ObTenantStorageCheckpointReader::ObTenantStorageCheckpointReader() {} -int ObTenantStorageCheckpointReader::iter_read_checkpoint_item(const MacroBlockId &entry_block, - const ObCheckpointMetaOp &op, - ObIArray &block_list) +int ObTenantStorageCheckpointReader::iter_read_meta_item( + const MacroBlockId &entry_block, + const ObStorageMetaOp &op, + ObIArray &block_list) { int ret = OB_SUCCESS; ObLinkedMacroBlockItemReader item_reader; block_list.reset(); if (OB_UNLIKELY(IS_EMPTY_BLOCK_LIST(entry_block))) { - LOG_INFO("has no checkpoint of log stream", K(ret)); + LOG_INFO("has no snapshot of log stream", K(ret)); } else if (OB_FAIL(item_reader.init(entry_block))) { LOG_WARN("failed to init log stream item reader"); } else { @@ -73,7 +74,9 @@ int ObTenantStorageCheckpointReader::iter_read_checkpoint_item(const MacroBlockI } int ObTenantStorageCheckpointReader::read_tablet_checkpoint_by_addr( - const ObIArray &block_list, const ObMetaDiskAddr &addr, char *item_buf, + const ObIArray &block_list, + const ObMetaDiskAddr &addr, + char *item_buf, int64_t &item_buf_len) { int ret = OB_SUCCESS; diff --git a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.h b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.h index e8968b317f..da66363b0b 100644 --- a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.h +++ b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_reader.h @@ -27,13 +27,13 @@ struct ObMetaDiskAddr; class ObTenantStorageCheckpointReader final { public: - using ObCheckpointMetaOp = common::ObFunction; + using ObStorageMetaOp = common::ObFunction; ObTenantStorageCheckpointReader(); ~ObTenantStorageCheckpointReader() = default; ObTenantStorageCheckpointReader(const ObTenantStorageCheckpointReader &) = delete; ObTenantStorageCheckpointReader &operator=(const ObTenantStorageCheckpointReader &) = delete; - int iter_read_checkpoint_item(const blocksstable::MacroBlockId &entry_block, - const ObCheckpointMetaOp &op, + int iter_read_meta_item(const blocksstable::MacroBlockId &entry_block, + const ObStorageMetaOp &op, ObIArray &block_list); static int read_tablet_checkpoint_by_addr(const ObIArray &block_list, @@ -44,4 +44,4 @@ public: } // end namespace storage } // end namespace oceanbase -#endif // OB_STORAGE_CKPT_TENANT_STORAGE_CHECKPOINT_READER_H_ +#endif // OB_STORAGE_CKPT_TENANT_STORAGE_META_READER_H_ diff --git a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp index ea14110952..0cbd16ae64 100644 --- a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp +++ b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.cpp @@ -25,6 +25,7 @@ #include "sql/das/ob_das_id_service.h" #include "storage/tablet/ob_tablet_persister.h" #include "storage/blockstore/ob_shared_block_reader_writer.h" +#include "observer/omt/ob_tenant.h" namespace oceanbase { @@ -36,19 +37,28 @@ using namespace oceanbase::blocksstable; ObTenantStorageCheckpointWriter::ObTenantStorageCheckpointWriter() : is_inited_(false), + meta_type_(ObTenantStorageMetaType::INVALID_TYPE), tablet_item_addr_info_arr_(OB_MALLOC_NORMAL_BLOCK_SIZE, ModulePageAllocator("TabletCkptArr", MTL_ID())), ls_item_writer_(), tablet_item_writer_() { } -int ObTenantStorageCheckpointWriter::init() +int ObTenantStorageCheckpointWriter::init(const ObTenantStorageMetaType meta_type) { int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("ObTenantStorageCheckpointWriter init twice", K(ret)); + } else if (OB_UNLIKELY(ObTenantStorageMetaType::INVALID_TYPE == meta_type)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(meta_type)); + } else if (OB_FAIL(ls_item_writer_.init(false /*whether need addr*/))) { + LOG_WARN("fail to init ls item writer", K(ret)); + } else if (OB_FAIL(tablet_item_writer_.init(false /*whether need addr*/))) { + LOG_WARN("fail to init tablet item writer", K(ret)); } else { + meta_type_ = meta_type; is_inited_ = true; } return ret; @@ -60,16 +70,17 @@ void ObTenantStorageCheckpointWriter::reset() tablet_item_addr_info_arr_.reset(); ls_item_writer_.reset(); tablet_item_writer_.reset(); + meta_type_ = ObTenantStorageMetaType::INVALID_TYPE; } -int ObTenantStorageCheckpointWriter::write_checkpoint(ObTenantSuperBlock &super_block) +int ObTenantStorageCheckpointWriter::record_meta(MacroBlockId &ls_meta_entry) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("ObTenantStorageCheckpointWriter not inited", K(ret)); - } else if (OB_FAIL(write_ls_checkpoint(super_block.ls_meta_entry_))) { + } else if (OB_FAIL(record_ls_meta(ls_meta_entry))) { LOG_WARN("fail to construct ls ckpt linked list", K(ret)); } else if (OB_FAIL(THE_IO_DEVICE->fsync_block())) { LOG_WARN("fail to fsync_block", K(ret)); @@ -77,16 +88,70 @@ int ObTenantStorageCheckpointWriter::write_checkpoint(ObTenantSuperBlock &super_ return ret; } -int ObTenantStorageCheckpointWriter::write_ls_checkpoint(MacroBlockId &ls_entry_block) +int ObTenantStorageCheckpointWriter::record_single_ls_meta( + const MacroBlockId &orig_ls_meta_entry, + const ObLSID &ls_id, + ObIArray &orig_linked_block_list, + blocksstable::MacroBlockId &ls_meta_entry, + share::SCN &clog_max_scn) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObTenantStorageCheckpointReader ls_ckpt_reader; + ObTenantStorageCheckpointReader::ObStorageMetaOp copy_ls_meta_op = std::bind( + &ObTenantStorageCheckpointWriter::copy_ls_meta_for_creating, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3); + + if (OB_UNLIKELY(!orig_ls_meta_entry.is_valid() || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(orig_ls_meta_entry), K(ls_id)); + } else if (OB_FAIL(ls_ckpt_reader.iter_read_meta_item(orig_ls_meta_entry, copy_ls_meta_op, orig_linked_block_list))) { + LOG_WARN("fail to iter read and write ls snapshot", K(ret), K(orig_ls_meta_entry)); + } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", K(ret)); + } else if (OB_FAIL(do_record_ls_meta(*(ls_handle.get_ls()), clog_max_scn))) { + LOG_WARN("fail to record single ls meta", K(ret), K(ls_handle)); + } else if (OB_FAIL(close(ls_meta_entry))) { + LOG_WARN("fail to close tenant storage checkpoint writer", K(ret)); + } + return ret; +} + +int ObTenantStorageCheckpointWriter::delete_single_ls_meta( + const MacroBlockId &orig_ls_meta_entry, + const ObLSID &ls_id, + ObIArray &orig_linked_block_list, + blocksstable::MacroBlockId &ls_meta_entry) +{ + int ret = OB_SUCCESS; + ObTenantStorageCheckpointReader ls_ckpt_reader; + ObTenantStorageCheckpointReader::ObStorageMetaOp copy_ls_meta_op = std::bind( + &ObTenantStorageCheckpointWriter::copy_ls_meta_for_deleting, + this, + std::placeholders::_1, + std::placeholders::_2, + std::placeholders::_3, + ls_id); + + if (OB_UNLIKELY(!orig_ls_meta_entry.is_valid() || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(orig_ls_meta_entry), K(ls_id)); + } else if (OB_FAIL(ls_ckpt_reader.iter_read_meta_item(orig_ls_meta_entry, copy_ls_meta_op, orig_linked_block_list))) { + LOG_WARN("fail to iter read and write ls snapshot", K(ret), K(orig_ls_meta_entry)); + } else if (OB_FAIL(close(ls_meta_entry))) { + LOG_WARN("fail to close tenant storage checkpoint writer", K(ret)); + } + return ret; +} + +int ObTenantStorageCheckpointWriter::record_ls_meta(MacroBlockId &ls_entry_block) { int ret = OB_SUCCESS; common::ObSharedGuard ls_iter; ObLS *ls = nullptr; - char *buf = nullptr; - int64_t buf_len = 0; - int64_t pos = 0; - ObLSCkptMember ls_ckpt_member; - int64_t count = 0; ls_item_writer_.reset(); tablet_item_writer_.reset(); @@ -95,6 +160,7 @@ int ObTenantStorageCheckpointWriter::write_ls_checkpoint(MacroBlockId &ls_entry_ } else if (OB_FAIL(ls_item_writer_.init(false /*whether need addr*/))) { LOG_WARN("failed to init log stream item writer", K(ret)); } else { + share::SCN unused_scn; while (OB_SUCC(ret)) { if (OB_FAIL(ls_iter->get_next(ls))) { if (OB_ITER_END == ret) { @@ -105,59 +171,127 @@ int ObTenantStorageCheckpointWriter::write_ls_checkpoint(MacroBlockId &ls_entry_ } } - if (OB_SUCC(ret)) { - ObLSLockGuard lock_ls(ls); - if (OB_FAIL(ls->get_ls_meta(ls_ckpt_member.ls_meta_))) { - LOG_WARN("fail to get ls meta", K(ret)); - } else if (OB_FAIL(ls->get_dup_table_ls_meta(ls_ckpt_member.dup_ls_meta_))) { - LOG_WARN("fail to get dup ls meta", K(ret)); - } - } - - if (OB_FAIL(ret)) { - // do nothing - } else if (OB_FAIL(write_tablet_checkpoint(*ls, ls_ckpt_member.tablet_meta_entry_))) { - LOG_WARN("fail to write tablet checkpoint for this ls", K(ret), KPC(ls)); - } else { - buf_len = ls_ckpt_member.get_serialize_size(); - pos = 0; - if (OB_ISNULL(buf = static_cast(ob_malloc(buf_len, "SlogCkptWriter")))) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("fail to allocate memory", K(ret)); - } else if (OB_FAIL(ls_ckpt_member.serialize(buf, buf_len, pos))) { - LOG_WARN("fail to serialize ls ckpt member", K(ret), KP(buf), K(buf_len), K(pos)); - } else if (OB_FAIL(ls_item_writer_.write_item(buf, buf_len, nullptr /*item idx*/))) { - LOG_WARN("fail to write ls ckpt item", K(ret), KP(buf), K(buf_len)); - } else { - count++; - } - if (OB_LIKELY(nullptr != buf)) { - ob_free(buf); - } + if (OB_SUCC(ret) && OB_FAIL(do_record_ls_meta(*ls, unused_scn))) { + LOG_WARN("fail to do record storage meta", K(ret), KPC(ls)); } } if (OB_FAIL(ret)) { // do nothing - } else if (OB_FAIL(ls_item_writer_.close())) { - LOG_WARN("fail to close ls item writer", K(ret)); - } else if (OB_FAIL(ls_item_writer_.get_entry_block(ls_entry_block))) { - LOG_WARN("fail to get ls entry block", K(ret)); + } else if (OB_FAIL(close(ls_entry_block))) { + LOG_WARN("fail to close ls meta writer", K(ret)); } } - LOG_INFO("write ls checkpoint finish", K(ret), K(count), K(ls_entry_block)); + LOG_INFO("write ls checkpoint finish", K(ret), K(ls_entry_block)); return ret; } -int ObTenantStorageCheckpointWriter::write_tablet_checkpoint( - ObLS &ls, MacroBlockId &tablet_meta_entry) +int ObTenantStorageCheckpointWriter::do_record_ls_meta(ObLS &ls, share::SCN &clog_max_scn) +{ + int ret = OB_SUCCESS; + ObLSCkptMember ls_ckpt_member; + { + ObLSLockGuard lock_ls(&ls); + if (OB_FAIL(ls.get_ls_meta(ls_ckpt_member.ls_meta_))) { + LOG_WARN("fail to get ls meta", K(ret)); + } else if (OB_FAIL(ls.get_dup_table_ls_meta(ls_ckpt_member.dup_ls_meta_))) { + LOG_WARN("fail to get dup ls meta", K(ret)); + } + } + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(record_tablet_meta(ls, ls_ckpt_member.tablet_meta_entry_, clog_max_scn))) { + LOG_WARN("fail to write tablet checkpoint for this ls", K(ret), K(ls)); + } else if (OB_FAIL(write_item(ls_ckpt_member))) { + LOG_WARN("fail to write ls item", K(ret), K(ls_ckpt_member)); + } + return ret; +} + +int ObTenantStorageCheckpointWriter::write_item(const ObLSCkptMember &ls_ckpt_member) +{ + int ret = OB_SUCCESS; + int64_t buf_len = ls_ckpt_member.get_serialize_size(); + int64_t pos = 0; + char *buf = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("meta writer hasn't been inited", K(ret)); + } else if (OB_UNLIKELY(!ls_ckpt_member.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_ckpt_member)); + } else if (OB_ISNULL(buf = static_cast(ob_malloc(buf_len, "MetaWriter")))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocate memory", K(ret)); + } else if (OB_FAIL(ls_ckpt_member.serialize(buf, buf_len, pos))) { + LOG_WARN("fail to serialize ls ckpt member", K(ret), KP(buf), K(buf_len), K(pos)); + } else if (OB_FAIL(ls_item_writer_.write_item(buf, buf_len, nullptr /*item idx*/))) { + LOG_WARN("fail to write ls ckpt item", K(ret), KP(buf), K(buf_len)); + } else { + } + if (OB_LIKELY(nullptr != buf)) { + ob_free(buf); + } + return ret; +} + +int ObTenantStorageCheckpointWriter::copy_ls_meta_for_deleting( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len, + const ObLSID &ls_id) +{ + UNUSED(addr); + int ret = OB_SUCCESS; + ObLSCkptMember ls_ckpt_member; + int64_t pos = 0; + if (OB_FAIL(ls_ckpt_member.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize ls_ckpt_member", K(ret), KP(buf), K(buf_len)); + } else if (ls_id != ls_ckpt_member.ls_meta_.ls_id_ && OB_FAIL(write_item(ls_ckpt_member))) { + LOG_WARN("fail to write ls snapshot", K(ret), K(ls_id), K(ls_ckpt_member)); + } + return ret; +} + +int ObTenantStorageCheckpointWriter::copy_ls_meta_for_creating( + const ObMetaDiskAddr &addr, + const char *buf, + const int64_t buf_len) +{ + UNUSED(addr); + int ret = OB_SUCCESS; + ObLSCkptMember ls_ckpt_member; + int64_t pos = 0; + if (OB_FAIL(ls_ckpt_member.deserialize(buf, buf_len, pos))) { + LOG_WARN("fail to deserialize ls_ckpt_member", K(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(write_item(ls_ckpt_member))) { + LOG_WARN("fail to write ls snapshot", K(ret), K(ls_ckpt_member)); + } + return ret; +} + +int ObTenantStorageCheckpointWriter::close(blocksstable::MacroBlockId &ls_meta_entry) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("meta writer hasn't been inited", K(ret)); + } else if (OB_FAIL(ls_item_writer_.close())) { + LOG_WARN("fail to close ls item writer", K(ret)); + } else if (OB_FAIL(ls_item_writer_.get_entry_block(ls_meta_entry))) { + LOG_WARN("fail to get ls entry block", K(ret)); + } + return ret; +} + +int ObTenantStorageCheckpointWriter::record_tablet_meta(ObLS &ls, MacroBlockId &tablet_meta_entry, share::SCN &clog_max_scn) { int ret = OB_SUCCESS; ObMetaDiskAddr addr; ObLSTabletIterator tablet_iter(ObMDSGetTabletMode::READ_READABLE_COMMITED); ObTabletMapKey tablet_key; - bool has_slog = false; char slog_buf[sizeof(ObUpdateTabletLog)]; tablet_item_writer_.reuse_for_next_round(); @@ -183,10 +317,10 @@ int ObTenantStorageCheckpointWriter::write_tablet_checkpoint( } else if (addr.is_none()) { ret = OB_NEED_RETRY; // tablet slog has been written, but the addr hasn't been updated LOG_WARN("addr is none", K(ret)); - } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->check_slog(tablet_key, has_slog))) { - LOG_WARN("fail to check whether tablet has been written slog", K(ret), K(tablet_key)); - } else if (!has_slog && OB_FAIL(copy_one_tablet_item(tablet_key, addr, slog_buf))) { - LOG_WARN("fail to copy_one_tablet_item", K(ret), K(tablet_key), K(addr)); + } else if ((ObTenantStorageMetaType::CKPT == meta_type_) && OB_FAIL(persist_and_copy_tablet(tablet_key, addr, slog_buf))) { + LOG_WARN("fail to persist_and_copy_tablet", K(ret), K(tablet_key), K(addr)); + } else if (ObTenantStorageMetaType::SNAPSHOT == meta_type_ && OB_FAIL(copy_tablet(tablet_key, slog_buf, clog_max_scn))) { + LOG_WARN("fail to copy tablet", K(ret), K(tablet_key)); } } @@ -202,7 +336,7 @@ int ObTenantStorageCheckpointWriter::write_tablet_checkpoint( return ret; } -int ObTenantStorageCheckpointWriter::copy_one_tablet_item( +int ObTenantStorageCheckpointWriter::persist_and_copy_tablet( const ObTabletMapKey &tablet_key, const ObMetaDiskAddr &old_addr, char *slog_buf) @@ -221,8 +355,13 @@ int ObTenantStorageCheckpointWriter::copy_one_tablet_item( ObUpdateTabletLog slog; slog.ls_id_ = tablet_key.ls_id_; slog.tablet_id_ = tablet_key.tablet_id_; + bool has_slog = false; if (OB_FAIL(OB_E(EventTable::EN_SLOG_CKPT_ERROR) OB_SUCCESS)) { + } else if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->check_slog(tablet_key, has_slog))) { + LOG_WARN("fail to check whether tablet has been written slog", K(ret), K(tablet_key)); + } else if (has_slog) { + // tablet has been updated, skip } else if (OB_FAIL(t3m->get_tablet_with_allocator(WashTabletPriority::WTP_LOW, tablet_key, allocator, old_tablet_handle))) { if (OB_ENTRY_NOT_EXIST == ret) { // skip write this tablet's checkpoint @@ -262,6 +401,74 @@ int ObTenantStorageCheckpointWriter::copy_one_tablet_item( return ret; } +int ObTenantStorageCheckpointWriter::copy_tablet(const ObTabletMapKey &tablet_key, char *slog_buf, share::SCN &clog_max_scn) +{ + int ret = OB_SUCCESS; + ObArenaAllocator allocator("MetaSnapshot"); + ObTabletHandle tablet_handle; + ObTabletHandle new_empty_shell_handle; + ObTablet *tablet = nullptr; + int64_t slog_buf_pos = 0; + MEMSET(slog_buf, 0, sizeof(ObUpdateTabletLog)); + ObUpdateTabletLog slog; + slog.ls_id_ = tablet_key.ls_id_; + slog.tablet_id_ = tablet_key.tablet_id_; + ObMetaDiskAddr old_addr; + + if (OB_FAIL(MTL(ObTenantMetaMemMgr*)->get_tablet_with_allocator(WashTabletPriority::WTP_LOW, tablet_key, allocator, tablet_handle))) { + if (OB_ENTRY_NOT_EXIST == ret) { + LOG_INFO("skip writing snapshot for this tablet", K(tablet_key)); + } else { + LOG_WARN("fail to get tablet with allocator", K(ret), K(tablet_key)); + } + } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { + } else if (tablet->get_tablet_addr().is_file()) { + if (OB_UNLIKELY(!tablet->is_empty_shell())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("addr format normal tablet's shouldn't be file", K(ret), KPC(tablet)); + } else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tablet, new_empty_shell_handle))) { + if (OB_ENTRY_NOT_EXIST == ret) { + LOG_INFO("skip writing snapshot for this tablet", K(tablet_key)); + } else { + LOG_WARN("fail to persist and transform tablet", K(ret), K(tablet_key), KPC(tablet)); + } + } else { + old_addr = tablet->get_tablet_addr(); + tablet = new_empty_shell_handle.get_obj(); + } + } else { + old_addr = tablet->get_tablet_addr(); + } + + if (OB_FAIL(ret)) { + // do nothing + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } + } else if (FALSE_IT(slog.disk_addr_ = tablet->get_tablet_addr())) { + } else if (OB_FAIL(slog.serialize(slog_buf, sizeof(ObUpdateTabletLog), slog_buf_pos))) { + LOG_WARN("fail to serialize update tablet slog", K(ret), K(slog_buf_pos)); + } else if (OB_FAIL(tablet_item_writer_.write_item(slog_buf, slog.get_serialize_size()))) { + LOG_WARN("fail to write update tablet slog into ckpt", K(ret)); + } else if (OB_FAIL(tablet->inc_macro_ref_cnt())) { + LOG_WARN("fail to increase meta and data macro blocks' ref cnt", K(ret)); + } else { + share::SCN tmp_scn = tablet->get_tablet_meta().clog_checkpoint_scn_; + clog_max_scn = tmp_scn > clog_max_scn ? tmp_scn : clog_max_scn; + TabletItemAddrInfo addr_info; + addr_info.tablet_key_ = tablet_key; + addr_info.old_addr_ = old_addr; + addr_info.new_addr_ = slog.disk_addr_; + addr_info.need_rollback_ = true; + if (OB_FAIL(ObTenantMetaMemMgr::get_tablet_pool_type(tablet_handle.get_buf_len(), addr_info.tablet_pool_type_))) { + LOG_WARN("fail to get tablet pool type", K(ret), K(addr_info)); + } else if (OB_FAIL(tablet_item_addr_info_arr_.push_back(addr_info))) { + LOG_WARN("fail to push back addr info", K(ret), K(addr_info)); + } + } + return ret; +} + int ObTenantStorageCheckpointWriter::get_ls_block_list(common::ObIArray *&block_list) { int ret = OB_SUCCESS; @@ -269,8 +476,7 @@ int ObTenantStorageCheckpointWriter::get_ls_block_list(common::ObIArray &ls_block_list = ls_item_writer_.get_meta_block_list(); - block_list = &ls_block_list; + block_list = &(ls_item_writer_.get_meta_block_list()); } return ret; } @@ -369,9 +575,7 @@ int ObTenantStorageCheckpointWriter::batch_compare_and_swap_tablet(const bool is LOG_WARN("fail to compare and swap tablet with seq check", K(ret), K(addr_info)); } } while (ignore_ret(ret)); - if (OB_FAIL(ret)) { - // do nothing - } else { + if (OB_SUCC(ret)) { old_tablet_handle.get_obj()->dec_macro_ref_cnt(); } } @@ -392,12 +596,31 @@ int ObTenantStorageCheckpointWriter::rollback() if (!is_inited_ || 0 == tablet_item_addr_info_arr_.count()) { // there's no new tablet, no need to rollback } else { + ObArenaAllocator allocator("CkptRollback"); + ObTablet tablet; for (int64_t i = 0; i < tablet_item_addr_info_arr_.count(); i++) { + tablet.reset(); + allocator.reuse(); + int64_t buf_len = 0; + char *buf = nullptr; + int64_t pos = 0; const TabletItemAddrInfo &addr_info = tablet_item_addr_info_arr_.at(i); if (addr_info.need_rollback_) { rollback_cnt++; - if (OB_FAIL(do_rollback(addr_info.new_addr_))) { - LOG_ERROR("fail to rollback ref cnt", K(ret), K(addr_info)); + do { + if (OB_FAIL(MTL(ObTenantCheckpointSlogHandler*)->read_from_disk( + addr_info.new_addr_, + allocator, + buf, + buf_len))) { + LOG_WARN("fail to read from disk", K(ret), K(addr_info)); + } + } while (ignore_ret(ret)); + if (OB_SUCC(ret)) { + tablet.set_tablet_addr(addr_info.new_addr_); + if (OB_FAIL(tablet.release_ref_cnt(allocator, buf, buf_len, pos))) { + LOG_ERROR("fail to dec macro ref for tablet, macro block may leak", K(ret), K(tablet)); + } } } } @@ -406,41 +629,6 @@ int ObTenantStorageCheckpointWriter::rollback() return ret; } -int ObTenantStorageCheckpointWriter::do_rollback(const ObMetaDiskAddr &load_addr) -{ - int ret = OB_SUCCESS; - ObArenaAllocator allocator("CkptRollback", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); - ObTablet tablet; - ObSharedBlockReadInfo read_info; - int64_t buf_len; - char *buf = nullptr; - int64_t pos = 0; - read_info.addr_ = load_addr; - read_info.io_desc_.set_wait_event(ObWaitEventIds::DB_FILE_DATA_READ); - do { - allocator.reuse(); - ObSharedBlockReadHandle block_handle(allocator); - if (OB_FAIL(ObSharedBlockReaderWriter::async_read(read_info, block_handle))) { - LOG_WARN("fail to read tablet buf from macro block", K(ret), K(read_info)); - } else if (OB_FAIL(block_handle.wait())) { - LOG_WARN("fail to wait async read", K(ret)); - } else if (OB_FAIL(block_handle.get_data(allocator, buf, buf_len))) { - LOG_WARN("fail to get tablet buf and buf_len", K(ret), K(block_handle)); - } - } while (ignore_ret(ret)); - if (OB_FAIL(ret)) { - // do nothing - } else if (OB_ISNULL(buf) || OB_UNLIKELY(buf_len <= 0)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("data of block handle is invalid", K(ret)); - } else if (FALSE_IT(tablet.set_tablet_addr(load_addr))) { - } else if (OB_FAIL(tablet.rollback_ref_cnt(allocator, buf, buf_len, pos))) { - LOG_WARN("fail to rollback ref cnt", K(ret), KP(buf), K(buf_len), K(pos)); - } - - return ret; -} - int ObTenantStorageCheckpointWriter::get_tablet_with_addr( const TabletItemAddrInfo &addr_info, ObTabletHandle &tablet_handle) diff --git a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h index 60789166f0..2b691dc985 100644 --- a/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h +++ b/src/storage/slog_ckpt/ob_tenant_storage_checkpoint_writer.h @@ -20,20 +20,57 @@ namespace oceanbase { +namespace share +{ +class ObLSID; +} + namespace storage { -class ObSharedBlockReaderWriter; +struct ObLSCkptMember; +enum class MetaRecordMode +{ + ADD_LS = 0, + DELETE_LS = 1, + INVALID_MODE +}; + +enum class ObTenantStorageMetaType +{ + CKPT = 0, + SNAPSHOT = 1, + CLONE = 2, + INVALID_TYPE +}; + class ObTenantStorageCheckpointWriter final { +public: + static bool ignore_ret(int ret); public: ObTenantStorageCheckpointWriter(); ~ObTenantStorageCheckpointWriter() = default; ObTenantStorageCheckpointWriter(const ObTenantStorageCheckpointWriter &) = delete; ObTenantStorageCheckpointWriter &operator=(const ObTenantStorageCheckpointWriter &) = delete; - - int init(); + int init(const ObTenantStorageMetaType meta_type); void reset(); - int write_checkpoint(ObTenantSuperBlock &super_block); + + // record meta for ckpt + int record_meta(blocksstable::MacroBlockId &ls_meta_entry); + + // record meta for snapshot + int record_single_ls_meta( + const blocksstable::MacroBlockId &orig_ls_meta_entry, + const share::ObLSID &ls_id, + ObIArray &orig_linked_block_list, + blocksstable::MacroBlockId &ls_meta_entry, + share::SCN &clog_max_scn); + int delete_single_ls_meta( + const blocksstable::MacroBlockId &orig_ls_meta_entry, + const share::ObLSID &ls_id, + ObIArray &orig_linked_block_list, + blocksstable::MacroBlockId &ls_meta_entry); + int get_ls_block_list(common::ObIArray *&block_list); int get_tablet_block_list(common::ObIArray *&block_list); int batch_compare_and_swap_tablet(const bool is_replay_old); @@ -58,20 +95,26 @@ private: TO_STRING_KV(K_(tablet_key), K_(old_addr), K_(new_addr), K_(tablet_pool_type), K_(need_rollback)); }; - static bool ignore_ret(int ret); + int copy_ls_meta_for_deleting(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len, + const share::ObLSID &ls_id); + int copy_ls_meta_for_creating(const ObMetaDiskAddr &addr, const char *buf, const int64_t buf_len); + int write_item(const ObLSCkptMember &ls_ckpt_member); + int close(blocksstable::MacroBlockId &ls_meta_entry); + int do_record_ls_meta(ObLS &ls, share::SCN &clog_max_scn); int get_tablet_with_addr( const TabletItemAddrInfo &addr_info, ObTabletHandle &tablet_handle); - int do_rollback(const ObMetaDiskAddr &load_addr); - int write_ls_checkpoint(blocksstable::MacroBlockId &ls_entry_block); - int write_tablet_checkpoint(ObLS &ls, blocksstable::MacroBlockId &tablet_meta_entry); - int copy_one_tablet_item( + int record_ls_meta(blocksstable::MacroBlockId &ls_entry_block); + int record_tablet_meta(ObLS &ls, blocksstable::MacroBlockId &tablet_meta_entry, share::SCN &clog_max_scn); + int persist_and_copy_tablet( const ObTabletMapKey &tablet_key, const ObMetaDiskAddr &old_addr, char *slog_buf); + int copy_tablet(const ObTabletMapKey &tablet_key, char *slog_buf, share::SCN &clog_max_scn); private: bool is_inited_; + ObTenantStorageMetaType meta_type_; common::ObArray tablet_item_addr_info_arr_; ObLinkedMacroBlockItemWriter ls_item_writer_; ObLinkedMacroBlockItemWriter tablet_item_writer_; diff --git a/src/storage/tablelock/ob_lock_utils.h b/src/storage/tablelock/ob_lock_utils.h index 5702ed82a1..6ea9c3b8c6 100644 --- a/src/storage/tablelock/ob_lock_utils.h +++ b/src/storage/tablelock/ob_lock_utils.h @@ -36,7 +36,8 @@ public: static bool in_inner_table_lock_white_list(const uint64_t inner_table_id) { bool b_ret = share::OB_ALL_BALANCE_JOB_TID == inner_table_id - || share::OB_ALL_RECOVER_TABLE_JOB_TID == inner_table_id; + || share::OB_ALL_RECOVER_TABLE_JOB_TID == inner_table_id + || share::OB_ALL_LS_REPLICA_TASK_TID == inner_table_id; return b_ret; } /* @@ -83,4 +84,4 @@ public: } // end namespace tablelock } // end namespace transaction } // end namespace oceanbase -#endif \ No newline at end of file +#endif diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index 7828c450cb..6f62c99012 100644 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -1400,7 +1400,38 @@ int ObTablet::self_serialize(char *buf, const int64_t len, int64_t &pos) const return ret; } -int ObTablet::rollback_ref_cnt( +int ObTablet::release_ref_cnt( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(partial_deserialize(allocator, buf, len, pos))) { + LOG_WARN("fail to deserialize partial tablet", K(ret)); + } else { + hold_ref_cnt_ = true; + dec_macro_ref_cnt(); + } + return ret; +} + +int ObTablet::inc_snapshot_ref_cnt( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(partial_deserialize(allocator, buf, len, pos))) { + LOG_WARN("fail to deserialize partial tablet", K(ret)); + } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { + LOG_WARN("fail to increase macro ref cnt", K(ret)); + } + return ret; +} + +int ObTablet::partial_deserialize( common::ObArenaAllocator &allocator, const char *buf, const int64_t len, @@ -1438,14 +1469,11 @@ int ObTablet::rollback_ref_cnt( } else if (tablet_meta_.has_next_tablet_) { ObTablet next_tablet; next_tablet.set_tablet_addr(tablet_addr_); - if (OB_FAIL(next_tablet.rollback_ref_cnt(allocator, buf, len, new_pos))) { + if (OB_FAIL(next_tablet.partial_deserialize(allocator, buf, len, new_pos))) { LOG_WARN("fail to deserialize next tablet for rollback", K(ret), KP(buf), K(len), K(new_pos)); } } - if (OB_SUCC(ret)) { - hold_ref_cnt_ = true; - dec_macro_ref_cnt(); pos = new_pos; } return ret; @@ -3466,7 +3494,7 @@ int ObTablet::inner_get_all_sstables(ObTableStoreIterator &iter, const bool need return ret; } -int ObTablet::get_sstables_size(int64_t &used_size, const bool ignore_shared_block) const +int ObTablet::get_sstables_size(const bool ignore_shared_block, int64_t &used_size) const { int ret = OB_SUCCESS; ObTableStoreIterator table_store_iter; @@ -3503,10 +3531,8 @@ int ObTablet::get_sstables_size(int64_t &used_size, const bool ignore_shared_blo used_size += sstable_meta_hdl.get_sstable_meta().get_total_macro_block_count() * sstable->get_macro_read_size(); } } - if (OB_FAIL(ret)) { - // do nothing - } else if (tablet_meta_.has_next_tablet_ && OB_FAIL( - next_tablet_guard_.get_obj()->get_sstables_size(used_size, ignore_shared_block/*ignore shared block*/))) { + if (OB_SUCC(ret) && tablet_meta_.has_next_tablet_ && OB_FAIL( + next_tablet_guard_.get_obj()->get_sstables_size(ignore_shared_block, used_size))) { LOG_WARN("failed to get size of tablets on the list", K(ret), K(used_size)); } else { used_size += mem_block_cnt * common::OB_DEFAULT_MACRO_BLOCK_SIZE; @@ -3531,7 +3557,7 @@ int ObTablet::get_tablet_size(const bool ignore_shared_block, int64_t &meta_size if (!ignore_shared_block) { data_size += space_usage.shared_data_size_; } - } else if (OB_FAIL(get_sstables_size(data_size, ignore_shared_block))) { + } else if (OB_FAIL(get_sstables_size(ignore_shared_block, data_size))) { LOG_WARN("fail to get all sstables' size", K(ret), K(ignore_shared_block)); } } diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index f8deccb147..719efbd96b 100644 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -295,7 +295,12 @@ public: const char *buf, const int64_t len, int64_t &pos); - int rollback_ref_cnt( + int release_ref_cnt( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + int64_t &pos); + int inc_snapshot_ref_cnt( common::ObArenaAllocator &allocator, const char *buf, const int64_t len, @@ -589,6 +594,12 @@ protected:// for MDS use return static_cast(pointer_hdl_.get_resource_ptr()); } private: + int partial_deserialize( + common::ObArenaAllocator &allocator, + const char *buf, + const int64_t len, + int64_t &pos); + int get_sstables_size(const bool ignore_shared_block, int64_t &used_size) const; static int deserialize_macro_info( common::ObArenaAllocator &allocator, const char *buf, @@ -596,7 +607,6 @@ private: int64_t &pos, ObTabletMacroInfo *&tablet_macro_info); int init_aggregated_info(common::ObArenaAllocator &allocator, ObLinkedMacroBlockItemWriter &linked_writer); - int get_sstables_size(int64_t &used_size, const bool ignore_shared_block = false) const; void set_initial_addr(); int check_meta_addr() const; static int parse_meta_addr(const ObMetaDiskAddr &addr, ObIArray &meta_ids); diff --git a/src/storage/tablet/ob_tablet_persister.cpp b/src/storage/tablet/ob_tablet_persister.cpp index 782c3af943..413acaaeec 100644 --- a/src/storage/tablet/ob_tablet_persister.cpp +++ b/src/storage/tablet/ob_tablet_persister.cpp @@ -677,6 +677,8 @@ int ObTabletPersister::transform_empty_shell(const ObTablet &old_tablet, ObTable } else if (OB_FAIL(persister.persist_and_fill_tablet(old_tablet, linked_writer, total_write_ctxs, new_handle, space_usage, tablet_macro_info, shared_meta_id_arr))) { LOG_WARN("fail to persist old empty shell", K(ret), K(old_tablet)); + } else { + new_handle.get_obj()->tablet_meta_.space_usage_ = space_usage; } return ret; diff --git a/src/storage/tablet/ob_tablet_space_usage.cpp b/src/storage/tablet/ob_tablet_space_usage.cpp index cece6adff2..a3b54702dc 100644 --- a/src/storage/tablet/ob_tablet_space_usage.cpp +++ b/src/storage/tablet/ob_tablet_space_usage.cpp @@ -13,8 +13,6 @@ #define USING_LOG_PREFIX STORAGE #include "storage/tablet/ob_tablet_space_usage.h" -#include "storage/tablet/ob_tablet_block_aggregated_info.h" - namespace oceanbase { diff --git a/src/storage/tablet/ob_tablet_space_usage.h b/src/storage/tablet/ob_tablet_space_usage.h index c8394ee36e..e28dc73e71 100644 --- a/src/storage/tablet/ob_tablet_space_usage.h +++ b/src/storage/tablet/ob_tablet_space_usage.h @@ -19,8 +19,6 @@ namespace oceanbase { namespace storage { - -class ObTabletMacroInfo; struct ObTabletSpaceUsage final { public: diff --git a/src/storage/tenant_snapshot/ob_ls_snapshot_defs.cpp b/src/storage/tenant_snapshot/ob_ls_snapshot_defs.cpp new file mode 100644 index 0000000000..4de881541a --- /dev/null +++ b/src/storage/tenant_snapshot/ob_ls_snapshot_defs.cpp @@ -0,0 +1,429 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "storage/ls/ob_ls.h" +#include "storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h" + +namespace oceanbase +{ +namespace storage +{ + +int ObLSSnapshot::init(const ObTenantSnapshotID& tenant_snapshot_id, + const ObLSID& ls_id, + common::ObConcurrentFIFOAllocator* build_ctx_allocator, + ObTenantMetaSnapshotHandler* meta_handler) +{ + int ret = OB_SUCCESS; + + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObLSSnapshot init twice", KR(ret), KPC(this)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_id is not valid", KR(ret)); + } else if (OB_ISNULL(build_ctx_allocator)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("build_ctx_allocator is unexpected nullptr", KR(ret)); + } else if (OB_ISNULL(meta_handler)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("meta_handler is unexpected nullptr", KR(ret)); + } else { + tenant_snapshot_id_ = tenant_snapshot_id; + ls_id_ = ls_id; + build_ctx_allocator_ = build_ctx_allocator; + meta_handler_ = meta_handler; + is_inited_ = true; + } + return ret; +} + +void ObLSSnapshot::destroy() +{ + if (IS_INIT) { + LOG_INFO("ls snapshot destroy", KPC(this)); + reset(); + } +} + +int ObLSSnapshot::build_ls_snapshot(ObLS* ls) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObLSSnapshot is not init", KR(ret)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("ls is nullptr", KR(ret), KPC(this)); + } else { + FLOG_INFO("build_ls_snapshot start", KPC(this)); + + if (is_build_ctx_lost_()) { + LOG_INFO("ls_snapshot build ctx lost, maybe observer restart before snapshot result reported", + KPC(this)); + if (OB_FAIL(clear_meta_snapshot_())) { + LOG_WARN("fail to clear_meta_snapshot_", KR(ret), KPC(this)); + } + } + + if (OB_SUCC(ret)) { + SCN max_sstable_range_scn; + if (OB_FAIL(try_alloc_build_ctx_())) { + LOG_WARN("fail to try_alloc_build_ctx_", KR(ret), KPC(this)); + } else if (OB_ISNULL(build_ctx_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("build_ctx_ is unexpected nullptr", KR(ret), KPC(this)); + } else if (FALSE_IT(build_ctx_->set_rebuild_seq_start(ls->get_ls_meta().get_rebuild_seq()))) { + } else if (OB_FAIL(ls->get_ls_meta().check_valid_for_backup())) { + LOG_WARN("fail to check valid for backup", KR(ret), "ls_meta", ls->get_ls_meta()); + } else if (OB_FAIL(build_ctx_->set_ls_meta_package(ls))) { + LOG_WARN("fail to set ls meta package", KR(ret), K(tenant_snapshot_id_), K(ls_id_)); + } else if (OB_FAIL(build_meta_snapshot_(max_sstable_range_scn))) { + LOG_WARN("fail to build_meta_snapshot_", KR(ret), K(tenant_snapshot_id_), K(ls_id_)); + } else if (FALSE_IT(build_ctx_->set_end_interval_scn( + MAX(max_sstable_range_scn, build_ctx_->get_begin_interval_scn())))) { + } else if (OB_FAIL(ls->get_ls_meta().check_valid_for_backup())) { + LOG_WARN("fail to check valid for backup", KR(ret), "ls_meta", ls->get_ls_meta()); + } else if (FALSE_IT(build_ctx_->set_rebuild_seq_end(ls->get_ls_meta().get_rebuild_seq()))) { + LOG_WARN("fail to get end scn", KR(ret), KPC(this), "ls_meta", ls->get_ls_meta()); + } else { + if (meta_existed_) { + build_ctx_->determine_final_rlt(); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls snapshot meta is not existed", KR(ret), KPC(this), KPC(ls)); + build_ctx_->set_failed(); + } + } + } + } + + FLOG_INFO("build_ls_snapshot finished", KR(ret), KPC(this)); + return ret; +} + +int ObLSSnapshot::gc_ls_snapshot() +{ + int ret = OB_SUCCESS; + + try_free_build_ctx_(); + + if (OB_FAIL(clear_meta_snapshot_())) { + LOG_WARN("fail to clear_meta_snapshot_", KR(ret), KPC(this)); + } + + LOG_INFO("gc ls snapshot finished", KR(ret), KPC(this)); + return ret; +} + +void ObLSSnapshot::notify_tenant_gc() +{ + LOG_INFO("notify tenant gc", KPC(this)); + + try_free_build_ctx_(); + meta_existed_ = false; +} + +int ObLSSnapshot::get_report_info(ObLSSnapshotReportInfo& info) +{ + int ret = OB_SUCCESS; + + if (!info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObLSSnapshotReportInfo is not valid", KR(ret), K(info), KPC(this)); + } else if (!is_valid_for_reporting_succ()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("ObLSSnapshot state is not valid for reporting", KR(ret), KPC(this)); + } else { + info.to_success(build_ctx_->get_begin_interval_scn(), + build_ctx_->get_end_interval_scn(), + build_ctx_->get_ls_meta_package_const_ptr()); + } + return ret; +} + +int ObLSSnapshot::get_ls_snapshot_vt_info(ObLSSnapshotVTInfo &info) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObLSSnapshot is not init", KR(ret), KPC(this)); + } else { + info.set_ls_id(ls_id_); + info.set_tenant_snapshot_id(tenant_snapshot_id_); + info.set_meta_existed(meta_existed_); + // build_ctx_ might be deleted if create ls_snapshot successfully, + // it's ok that we leave it be + lib::ObMutexGuard build_ctx_guard(build_ctx_mutex_); + if (OB_NOT_NULL(build_ctx_)) { + info.set_has_build_ctx(true); + ObLSSnapshotBuildCtxVTInfo &build_ctx_info = info.get_build_ctx_info(); + build_ctx_info.set_build_status( + ObString::make_string(ObLSSnapshotBuildCtx::status_to_str(build_ctx_->get_build_status()))); + build_ctx_info.set_rebuild_seq_start(build_ctx_->get_rebuild_seq_start()); + build_ctx_info.set_rebuild_seq_end(build_ctx_->get_rebuild_seq_end()); + build_ctx_->get_ls_meta_package(build_ctx_info.get_ls_meta_package()); + build_ctx_info.set_end_interval_scn(build_ctx_->get_end_interval_scn()); + } else { + info.set_has_build_ctx(false); + } + } + return ret; +} + +void ObLSSnapshot::try_free_build_ctx() +{ + try_free_build_ctx_(); +} + +void ObLSSnapshot::try_set_failed() +{ + if (OB_NOT_NULL(build_ctx_)) { + build_ctx_->set_failed(); + } + + LOG_INFO("ObLSSnapshot exec try_set_failed", KPC(this)); +} + +bool ObLSSnapshot::is_build_finished() const +{ + return build_ctx_ != nullptr && build_ctx_->is_finished(); +} + +bool ObLSSnapshot::is_build_ctx_lost_() const +{ + return meta_existed_ && nullptr == build_ctx_; +} + +bool ObLSSnapshot::is_valid_for_reporting_succ() const +{ + return meta_existed_ && build_ctx_ != nullptr && build_ctx_->is_succ(); +} + +int ObLSSnapshot::load() +{ + int ret = OB_SUCCESS; + + meta_existed_ = true; + LOG_INFO("ls snapshot load succ", KPC(this)); + return ret; +} + +int ObLSSnapshot::build_meta_snapshot_(SCN& max_sstable_range_scn) +{ + int ret = OB_SUCCESS; + + SCN tmp_clog_max_scn; + if (meta_existed_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls snapshot meta is already existed", KR(ret), KPC(this)); + } else if (OB_FAIL(meta_handler_->create_single_ls_snapshot(tenant_snapshot_id_, + ls_id_, + tmp_clog_max_scn))) { + LOG_ERROR("fail to create_single_ls_snapshot", KR(ret), KPC(this)); + } else { + meta_existed_ = true; + max_sstable_range_scn = tmp_clog_max_scn; + } + + LOG_INFO("build ls meta snapshot finished", KR(ret), KPC(this), K(tmp_clog_max_scn)); + return ret; +} + +int ObLSSnapshot::clear_meta_snapshot_() +{ + int ret = OB_SUCCESS; + + if (meta_existed_) { + if (OB_FAIL(meta_handler_->delete_single_ls_snapshot(tenant_snapshot_id_, ls_id_))) { + LOG_ERROR("fail to delete_single_ls_snapshot", KR(ret), KPC(this)); + } else { + meta_existed_ = false; + } + } + + LOG_INFO("clear ls meta snapshot finished", KR(ret), KPC(this)); + return ret; +} + +int ObLSSnapshot::try_alloc_build_ctx_() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + ObMemAttr memattr(tenant_id, "LSSnapBuildCtx"); + + lib::ObMutexGuard build_ctx_guard(build_ctx_mutex_); + if (nullptr == build_ctx_) { + void *buf = nullptr; + if (OB_ISNULL(buf = build_ctx_allocator_->alloc(sizeof(ObLSSnapshotBuildCtx), memattr))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc ObLSSnapshotBuildCtx", KR(ret), KPC(this)); + } else { + build_ctx_ = new (buf) ObLSSnapshotBuildCtx(); + } + } + return ret; +} + +void ObLSSnapshot::try_free_build_ctx_() +{ + lib::ObMutexGuard build_ctx_guard(build_ctx_mutex_); + if (build_ctx_ != nullptr) { + build_ctx_->~ObLSSnapshotBuildCtx(); + build_ctx_allocator_->free(build_ctx_); + build_ctx_ = nullptr; + } +} + +int ObLSSnapshot::get_tablet_meta_entry(blocksstable::MacroBlockId &tablet_meta_entry) +{ + int ret = OB_SUCCESS; + + if (!meta_existed_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("ObLSSnapshot's meta not exsited", KR(ret), KPC(this)); + } else if (OB_FAIL(meta_handler_->get_ls_snapshot(tenant_snapshot_id_, + ls_id_, + tablet_meta_entry))) { + LOG_WARN("fail to get ls snapshot tablet meta entry", KR(ret), KPC(this)); + } + return ret; +} + +const char* ObLSSnapshot::ObLSSnapshotBuildCtx::LS_SNAPSHOT_BUILD_STATUS_ARRAY[] = +{ + "BUILDING", + "FAILED", + "SUCCESSFUL" +}; + +const char* ObLSSnapshot::ObLSSnapshotBuildCtx::status_to_str(ObLSSnapshotBuildCtx::BuildStatus status) +{ + STATIC_ASSERT(ARRAYSIZEOF(LS_SNAPSHOT_BUILD_STATUS_ARRAY) == static_cast(ObLSSnapshotBuildCtx::BuildStatus::MAX), + "type string array size mismatch with enum ls snapshot build status count"); + const char* str = "INVALID"; + if (status >= 0 && status < ObLSSnapshotBuildCtx::BuildStatus::MAX) { + str = LS_SNAPSHOT_BUILD_STATUS_ARRAY[static_cast(status)]; + } else { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "invalid ls snapshot build status", K(status)); + } + return str; +} + +bool ObLSSnapshot::ObLSSnapshotBuildCtx::is_valid_for_reporting_succ() const +{ + int ret = OB_SUCCESS; + + bool bret = true; + if (bret) { + bret = rebuild_seq_start_ >= 0 && rebuild_seq_end_ >= 0 && rebuild_seq_start_ == rebuild_seq_end_; + if (!bret) { + ret = OB_INVALID_ERROR; + LOG_WARN("rebuild seq is not valid for reporting succ", KR(ret), KPC(this)); + } + } + + if (bret) { + bret = ls_meta_package_.is_valid(); + if (!bret) { + ret = OB_INVALID_ERROR; + LOG_WARN("ls_meta_package is not valid for reporting succ", KR(ret), KPC(this)); + } + } + + if (bret) { + bret = end_interval_scn_.is_valid() && + ls_meta_package_.ls_meta_.get_clog_checkpoint_scn() <= end_interval_scn_; + if (!bret) { + ret = OB_INVALID_ERROR; + LOG_WARN("clog interval is not valid for reporting succ", KR(ret), KPC(this)); + } + } + + return bret; +} + +bool ObLSSnapshot::ObLSSnapshotBuildCtx::is_finished() const +{ + return FAILED == build_status_ || SUCCESSFUL == build_status_; +} + +bool ObLSSnapshot::ObLSSnapshotBuildCtx::is_succ() const +{ + return SUCCESSFUL == build_status_; +} + +bool ObLSSnapshot::ObLSSnapshotBuildCtx::is_failed() const +{ + return FAILED == build_status_; +} + +void ObLSSnapshot::ObLSSnapshotBuildCtx::set_failed() +{ + build_status_ = FAILED; +} + +void ObLSSnapshot::ObLSSnapshotBuildCtx::determine_final_rlt() +{ + int ret = OB_SUCCESS; + + if (is_finished()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("ObLSSnapshotBuildCtx is not in building status", KR(ret), KPC(this)); + } else if (!is_valid_for_reporting_succ()) { + ret = OB_INVALID_ERROR; + build_status_ = FAILED; + LOG_WARN("ObLSSnapshotBuildCtx is not valid for reporting succ, switch state to failed", + KR(ret), KPC(this)); + } else { + build_status_ = SUCCESSFUL; + LOG_INFO("ObLSSnapshotBuildCtx switch state to succ", KPC(this)); + } +} + +SCN ObLSSnapshot::ObLSSnapshotBuildCtx::get_begin_interval_scn() const +{ + return ls_meta_package_.ls_meta_.get_clog_checkpoint_scn(); +} + +int ObLSSnapshot::ObLSSnapshotBuildCtx::set_ls_meta_package(ObLS* ls) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(ls_meta_package_mutex_); + + if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("ls is nullptr", KR(ret), KPC(this)); + } else if (OB_FAIL(ls->get_ls_meta_package(false, ls_meta_package_))) { + LOG_WARN("fail to get ls meta package", + KR(ret), KPC(this), KPC(ls)); + } + + return ret; +} + +void ObLSSnapshot::ObLSSnapshotBuildCtx::get_ls_meta_package(ObLSMetaPackage& out) +{ + lib::ObMutexGuard guard(ls_meta_package_mutex_); + out = ls_meta_package_; +} + +} +} diff --git a/src/storage/tenant_snapshot/ob_ls_snapshot_defs.h b/src/storage/tenant_snapshot/ob_ls_snapshot_defs.h new file mode 100644 index 0000000000..097fd72016 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_ls_snapshot_defs.h @@ -0,0 +1,243 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_STORAGE_OB_LS_SNAPSHOT_DEFS_ +#define OCEANBASE_STORAGE_OB_LS_SNAPSHOT_DEFS_ + +#include "lib/hash/ob_link_hashmap.h" +#include "share/ob_ls_id.h" +#include "storage/ls/ob_ls_meta_package.h" + +namespace oceanbase +{ +namespace storage +{ +class ObLS; +class ObTenantSnapshot; +class ObLSSnapshot; +class ObLSSnapshotReportInfo; +class ObTenantMetaSnapshotHandler; +class ObLSSnapshotVTInfo; + +class ObLSSnapshotMapKey final +{ +public: + ObLSSnapshotMapKey() : tenant_snapshot_id_(), + ls_id_(ObLSID::INVALID_LS_ID) {} + ObLSSnapshotMapKey(const ObLSSnapshotMapKey &other) : + tenant_snapshot_id_(other.tenant_snapshot_id_), + ls_id_(other.ls_id_) {} + explicit ObLSSnapshotMapKey(const int64_t tenant_snapshot_id, const int64_t ls_id) : + tenant_snapshot_id_(tenant_snapshot_id), + ls_id_(ls_id) {} + explicit ObLSSnapshotMapKey(const share::ObTenantSnapshotID& tenant_snapshot_id, const share::ObLSID& ls_id) : + tenant_snapshot_id_(tenant_snapshot_id), + ls_id_(ls_id) {} + ~ObLSSnapshotMapKey() { reset(); } + +public: + void reset() + { + tenant_snapshot_id_.reset(); + ls_id_.reset(); + } + bool is_valid() const { return tenant_snapshot_id_.is_valid() && ls_id_.is_valid(); } + // assignment + ObLSSnapshotMapKey &operator=(const ObLSSnapshotMapKey &other) + { + tenant_snapshot_id_ = other.tenant_snapshot_id_; + ls_id_ = other.ls_id_; + return *this; + } + + // compare operator + bool operator == (const ObLSSnapshotMapKey &other) const + { return tenant_snapshot_id_ == other.tenant_snapshot_id_ && ls_id_ == other.ls_id_; } + + bool operator != (const ObLSSnapshotMapKey &other) const + { return tenant_snapshot_id_ != other.tenant_snapshot_id_ || ls_id_ != other.ls_id_; } + + int compare(const ObLSSnapshotMapKey &other) const + { + int compare_ret = tenant_snapshot_id_.compare(other.tenant_snapshot_id_); + if (0 == compare_ret) { + compare_ret = ls_id_.compare(other.ls_id_); + } + return compare_ret; + } + + uint64_t hash() const + { + uint64_t hash_val = 0; + hash_val = murmurhash(&tenant_snapshot_id_, sizeof(tenant_snapshot_id_), hash_val); + hash_val = murmurhash(&ls_id_, sizeof(ls_id_), hash_val); + return hash_val; + } + + TO_STRING_KV(K_(tenant_snapshot_id), K_(ls_id)); + +public: + share::ObTenantSnapshotID tenant_snapshot_id_; + share::ObLSID ls_id_; +}; + +typedef common::LinkHashValue ObLSSnapshotValue; +class ObLSSnapshot : public ObLSSnapshotValue +{ +public: + ObLSSnapshot() + : is_inited_(false), + tenant_snapshot_id_(), + ls_id_(), + meta_existed_(false), + build_ctx_(nullptr), + build_ctx_allocator_(nullptr), + meta_handler_(nullptr), + build_ctx_mutex_() {}; + + ~ObLSSnapshot() {}; + + int init(const share::ObTenantSnapshotID& tenant_snapshot_id, + const ObLSID& ls_id, + common::ObConcurrentFIFOAllocator* build_ctx_allocator, + ObTenantMetaSnapshotHandler* meta_handler); + void destroy(); + + void reset() + { + tenant_snapshot_id_.reset(); + ls_id_.reset(); + meta_existed_ = false; + try_free_build_ctx_(); + build_ctx_allocator_ = nullptr; + meta_handler_ = nullptr; + is_inited_ = false; + } + + ObLSSnapshot &operator=(const ObLSSnapshot &other) = delete; + +public: + share::ObTenantSnapshotID get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + share::ObLSID get_ls_id() const { return ls_id_; } + + int load(); + + int gc_ls_snapshot(); + void notify_tenant_gc(); + + bool is_build_finished() const; + bool is_valid_for_reporting_succ() const; + int get_report_info(ObLSSnapshotReportInfo& info); + int get_ls_snapshot_vt_info(ObLSSnapshotVTInfo &info); + void try_free_build_ctx(); + + void try_determine_final_rlt(); + void try_set_failed(); + + int build_ls_snapshot(ObLS* ls); + + int get_tablet_meta_entry(blocksstable::MacroBlockId &tablet_meta_entry); + TO_STRING_KV(K(is_inited_), + K(tenant_snapshot_id_), + K(ls_id_), + K(meta_existed_), + KPC(build_ctx_), + KP(build_ctx_allocator_), + KP(meta_handler_)); +private: + bool is_build_ctx_lost_() const; + int build_meta_snapshot_(share::SCN& max_sstable_range_scn); + int clear_meta_snapshot_(); + int try_alloc_build_ctx_(); + void try_free_build_ctx_(); + +private: + class ObLSSnapshotBuildCtx + { + enum BuildStatus + { + BUILDING = 0, + FAILED = 1, + SUCCESSFUL = 2, + MAX = 3, + }; + + public: + ObLSSnapshotBuildCtx () : build_status_(BUILDING), + rebuild_seq_start_(-1), + rebuild_seq_end_(-1), + ls_meta_package_(), + end_interval_scn_() {} + + ~ObLSSnapshotBuildCtx () {} + + TO_STRING_KV(K(build_status_), + K(rebuild_seq_start_), + K(rebuild_seq_end_), + K(ls_meta_package_), + K(end_interval_scn_)); + + ObLSSnapshotBuildCtx &operator=(const ObLSSnapshotBuildCtx &other) = delete; + + public: + bool is_valid_for_reporting_succ() const; + bool is_finished() const; + bool is_succ() const; + bool is_failed() const; + void set_failed(); + void determine_final_rlt(); + share::SCN get_begin_interval_scn() const; + + public: + static const char * status_to_str(BuildStatus status); + BuildStatus get_build_status() const { return build_status_; } + int64_t get_rebuild_seq_start() const { return rebuild_seq_start_; } + int64_t get_rebuild_seq_end() const { return rebuild_seq_end_; } + share::SCN get_end_interval_scn() const { return end_interval_scn_; } + + void set_build_status(BuildStatus build_status) { build_status_ = build_status; } + void set_rebuild_seq_start(int64_t rebuild_seq_start) { rebuild_seq_start_ = rebuild_seq_start; } + void set_rebuild_seq_end(int64_t rebuild_seq_end) { rebuild_seq_end_ = rebuild_seq_end; } + void set_end_interval_scn(const share::SCN& end_interval_scn) { end_interval_scn_ = end_interval_scn; } + + int set_ls_meta_package(ObLS* ls); + void get_ls_meta_package(ObLSMetaPackage& out); + const ObLSMetaPackage* get_ls_meta_package_const_ptr() const { return &ls_meta_package_; } + + private: + static const char *LS_SNAPSHOT_BUILD_STATUS_ARRAY[]; + + private: + BuildStatus build_status_; + int64_t rebuild_seq_start_; + int64_t rebuild_seq_end_; + + lib::ObMutex ls_meta_package_mutex_; + ObLSMetaPackage ls_meta_package_; + + share::SCN end_interval_scn_; + }; + +private: + bool is_inited_; + share::ObTenantSnapshotID tenant_snapshot_id_; + share::ObLSID ls_id_; + bool meta_existed_; + ObLSSnapshotBuildCtx *build_ctx_; + common::ObConcurrentFIFOAllocator* build_ctx_allocator_; + ObTenantMetaSnapshotHandler* meta_handler_; + lib::ObMutex build_ctx_mutex_; +}; + +} +} +#endif diff --git a/src/storage/tenant_snapshot/ob_ls_snapshot_mgr.cpp b/src/storage/tenant_snapshot/ob_ls_snapshot_mgr.cpp new file mode 100644 index 0000000000..0a4cc6472a --- /dev/null +++ b/src/storage/tenant_snapshot/ob_ls_snapshot_mgr.cpp @@ -0,0 +1,241 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "storage/tenant_snapshot/ob_ls_snapshot_mgr.h" + +namespace oceanbase +{ +namespace storage +{ + +int ObLSSnapshotMgr::init(ObTenantMetaSnapshotHandler* meta_handler) +{ + int ret = OB_SUCCESS; + + const uint64_t tenant_id = MTL_ID(); + const char *OB_LS_SNAPSHOT_MGR = "LSSnapshotMgr"; + const int64_t SNAPSHOT_ALLOC_TOTAL_LIMIT = 1024 * 1024 * 1024; + + if (OB_UNLIKELY(IS_INIT)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObLSSnapshotMgr has inited", KR(ret)); + } else if (OB_ISNULL(meta_handler)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("meta_handler is unexpected nullptr", KR(ret)); + } else if (OB_FAIL(ls_snapshot_map_.init("LSSnapMap", tenant_id))) { + LOG_WARN("fail to init ls snapshot map", KR(ret)); + } else if (OB_FAIL(build_ctx_allocator_.init(common::OB_MALLOC_NORMAL_BLOCK_SIZE, + OB_LS_SNAPSHOT_MGR, + tenant_id, + SNAPSHOT_ALLOC_TOTAL_LIMIT))) { + LOG_WARN("fail to init tenant snapshot allocator", KR(ret)); + } else { + meta_handler_ = meta_handler; + is_inited_ = true; + LOG_INFO("ObLSSnapshotMgr init succ", KPC(this)); + } + + return ret; +} + +void ObLSSnapshotMgr::destroy() +{ + int ret = OB_SUCCESS; + + if (IS_INIT) { + int64_t value_cnt = ls_snapshot_map_.get_alloc_handle().get_value_cnt(); + if (0 != value_cnt) { + LOG_ERROR("ls snapshot value cnt is not zero, memory leak", K(value_cnt)); + } + + int64_t map_cnt = ls_snapshot_map_.count(); + if (0 == map_cnt) { + ls_snapshot_map_.destroy(); + build_ctx_allocator_.destroy(); + LOG_INFO("ls snapshot mgr destroy succ"); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls snapshot map cnt is not zero", KR(ret), K(map_cnt)); + } + is_inited_ = false; + } +} + +int ObLSSnapshotMgr::get_ls_snapshot(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObLSSnapshot *&ls_snapshot) +{ + int ret = OB_SUCCESS; + ObLSSnapshot *tmp_ls_snapshot = nullptr; + ObLSSnapshotMapKey ls_snapshot_key(tenant_snapshot_id, ls_id); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLSSnapshotMgr not inited", KR(ret)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_id is not valid", KR(ret), K(ls_id)); + } else if (OB_UNLIKELY(!ls_snapshot_key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_snapshot_key is not valid", KR(ret), K(ls_snapshot_key)); + } else if (OB_FAIL(ls_snapshot_map_.get(ls_snapshot_key, tmp_ls_snapshot))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("fail to get ls snapshot", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } + } else if (OB_ISNULL(tmp_ls_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls_snapshot is unexpected null", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else { + ls_snapshot = tmp_ls_snapshot; + } + + return ret; +} + +int ObLSSnapshotMgr::create_ls_snapshot_(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObLSSnapshot *&ls_snapshot) +{ + int ret = OB_SUCCESS; + ObLSSnapshotMapKey ls_snapshot_key(tenant_snapshot_id, ls_id); + + ObLSSnapshot* tmp_ls_snapshot = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLSSnapshotMgr not inited", KR(ret)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_id is not valid", KR(ret), K(ls_id)); + } else if (OB_UNLIKELY(!ls_snapshot_key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_snapshot_key is not valid", KR(ret), K(ls_snapshot_key)); + } else if (OB_FAIL(ls_snapshot_map_.alloc_value(tmp_ls_snapshot))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc tenant snapshot", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (OB_ISNULL(tmp_ls_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to alloc tenant snapshot", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (OB_FAIL(tmp_ls_snapshot->init(tenant_snapshot_id, + ls_id, + &build_ctx_allocator_, + meta_handler_))) { + LOG_WARN("fail to init tenant snapshot", KR(ret), K(ls_snapshot_key)); + } else if (OB_FAIL(ls_snapshot_map_.insert_and_get(ls_snapshot_key, tmp_ls_snapshot))) { + LOG_WARN("fail to insert_and_get tenant snapshot", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else { + ls_snapshot = tmp_ls_snapshot; + } + + if (OB_FAIL(ret) && tmp_ls_snapshot != nullptr) { + ls_snapshot_map_.free_value(tmp_ls_snapshot); + } + return ret; +} + +int ObLSSnapshotMgr::acquire_ls_snapshot(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObLSSnapshot *&ls_snapshot) +{ + int ret = OB_SUCCESS; + ObLSSnapshot *tmp_ls_snapshot = nullptr; + bool is_existed = false; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLSSnapshotMgr has not been inited", KR(ret), KPC(this)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is invalid", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (OB_UNLIKELY(!ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_id is invalid", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (OB_FAIL(get_ls_snapshot(tenant_snapshot_id, ls_id, tmp_ls_snapshot))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + is_existed = false; + } else { + LOG_WARN("fail to get tenant snapshot", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } + } else { + ls_snapshot = tmp_ls_snapshot; + is_existed = true; + } + + if (OB_SUCC(ret) && !is_existed) { + if (OB_FAIL(create_ls_snapshot_(tenant_snapshot_id, ls_id, tmp_ls_snapshot))) { + LOG_WARN("fail to create ls snapshot", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else { + ls_snapshot = tmp_ls_snapshot; + } + } + + return ret; +} + +int ObLSSnapshotMgr::revert_ls_snapshot(ObLSSnapshot *ls_snapshot) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLSSnapshotMgr not inited", KR(ret)); + } else if (OB_ISNULL(ls_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls snapshot is nullptr", KR(ret)); + } else { + ls_snapshot_map_.revert(ls_snapshot); + } + + return ret; +} + +int ObLSSnapshotMgr::del_ls_snapshot(const ObTenantSnapshotID& tenant_snapshot_id, + const ObLSID& ls_id) +{ + int ret = OB_SUCCESS; + ObLSSnapshotMapKey ls_snapshot_key(tenant_snapshot_id, ls_id); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLSSnapshotMgr not inited", KR(ret)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_id is not valid", KR(ret), K(ls_id)); + } else if (OB_UNLIKELY(!ls_snapshot_key.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_snapshot_key is not valid", KR(ret), K(ls_snapshot_key)); + } else if (OB_FAIL(ls_snapshot_map_.del(ls_snapshot_key))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_ERROR("fail to del ls_snapshot from ls_snapshot_map_", + KR(ret), K(tenant_snapshot_id), K(ls_id)); + } + } + + return ret; +} + +} +} diff --git a/src/storage/tenant_snapshot/ob_ls_snapshot_mgr.h b/src/storage/tenant_snapshot/ob_ls_snapshot_mgr.h new file mode 100644 index 0000000000..e895aed99e --- /dev/null +++ b/src/storage/tenant_snapshot/ob_ls_snapshot_mgr.h @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_STORAGE_OB_LS_SNAPSHOT_MGR_ +#define OCEANBASE_STORAGE_OB_LS_SNAPSHOT_MGR_ + +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_defs.h" + +namespace oceanbase +{ +namespace storage +{ + +typedef common::LinkHashNode ObLSSnapshotNode; +class ObLSSnapshotHashAlloc +{ +public: + ObLSSnapshotHashAlloc() : value_cnt_(0) {} + ~ObLSSnapshotHashAlloc() { value_cnt_ = 0; } + + ObLSSnapshotHashAlloc(const ObLSSnapshotHashAlloc* other) : + value_cnt_(other->value_cnt_) { } + + ObLSSnapshot* alloc_value() + { + ObMemAttr memattr(MTL_ID(), "LSSnapshot"); + ObLSSnapshot* ls_snapshot = OB_NEW(ObLSSnapshot, memattr); + if (OB_NOT_NULL(ls_snapshot)) { + ATOMIC_INC(&value_cnt_); + } + return ls_snapshot; + } + void free_value(ObLSSnapshot* snapshot) + { + if (NULL != snapshot) { + ObMemAttr memattr(MTL_ID(), "LSSnapshot"); + OB_DELETE(ObLSSnapshot, memattr, snapshot); + ATOMIC_DEC(&value_cnt_); + } + } + ObLSSnapshotNode* alloc_node(ObLSSnapshot* snapshot) + { + UNUSED(snapshot); + ObMemAttr memattr(MTL_ID(), "LSSnapshotNode"); + return OB_NEW(ObLSSnapshotNode, memattr); + } + void free_node(ObLSSnapshotNode* node) + { + if (NULL != node) { + ObMemAttr memattr(MTL_ID(), "LSSnapshotNode"); + OB_DELETE(ObLSSnapshotNode, memattr, node); + } + } + + int64_t get_value_cnt() const { return ATOMIC_LOAD(&value_cnt_); } +private: + int64_t value_cnt_; +}; + +typedef common::ObLinkHashMap ObLSSnapshotMap; + +class ObLSSnapshotMgr +{ +public: + ObLSSnapshotMgr() + : is_inited_(false), + ls_snapshot_map_(), + build_ctx_allocator_(), + meta_handler_(nullptr) {} + + virtual ~ObLSSnapshotMgr() {} + int init(ObTenantMetaSnapshotHandler* meta_handler); + void destroy(); + +public: + int get_ls_snapshot(const share::ObTenantSnapshotID &tenant_snapshot_id, + const share::ObLSID &ls_id, + ObLSSnapshot *&ls_snapshot); + + int acquire_ls_snapshot(const share::ObTenantSnapshotID &tenant_snapshot_id, + const share::ObLSID &ls_id, + ObLSSnapshot *&ls_snapshot); + + int revert_ls_snapshot(ObLSSnapshot *ls_snapshot); + int del_ls_snapshot(const share::ObTenantSnapshotID& tenant_snapshot_id, + const share::ObLSID& ls_id); + + template int for_each(Fn &fn) { return ls_snapshot_map_.for_each(fn); } + template int remove_if(Fn &fn) { return ls_snapshot_map_.remove_if(fn); } +private: + int create_ls_snapshot_(const share::ObTenantSnapshotID &tenant_snapshot_id, + const share::ObLSID &ls_id, + ObLSSnapshot *&ls_snapshot); + +private: + bool is_inited_; + ObLSSnapshotMap ls_snapshot_map_; + common::ObConcurrentFIFOAllocator build_ctx_allocator_; + ObTenantMetaSnapshotHandler* meta_handler_; + +public: + TO_STRING_KV(K(is_inited_)); +}; + +} +} + +#endif diff --git a/src/storage/tenant_snapshot/ob_tenant_clone_service.cpp b/src/storage/tenant_snapshot/ob_tenant_clone_service.cpp new file mode 100644 index 0000000000..c8f279e542 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_clone_service.cpp @@ -0,0 +1,501 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "lib/lock/mutex.h" +#include "logservice/restoreservice/ob_log_restore_handler.h" +#include "share/restore/ob_ls_restore_status.h" +#include "observer/ob_server_event_history_table_operator.h" +#include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" +#include "storage/tx_storage/ob_ls_map.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_service.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_task.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h" +#include "storage/tenant_snapshot/ob_tenant_clone_service.h" + +namespace oceanbase +{ +using namespace share; +using namespace observer; +namespace storage +{ + +int ObTenantCloneService::init(ObTenantMetaSnapshotHandler* meta_handler) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(meta_handler)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("meta_handler is unexpected null", KR(ret)); + } else if (OB_FAIL(startup_accel_handler_.init(ObStartupAccelType::TENANT_ACCEL))) { + LOG_WARN("fail to init startup_accel_handler_", KR(ret)); + } else { + meta_handler_ = meta_handler; + is_inited_ = true; + } + return ret; +} + +int ObTenantCloneService::start() +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(startup_accel_handler_.start())) { + LOG_WARN("fail to start startup_accel_handler_", KR(ret)); + } else { + is_started_ = true; + } + return ret; +} + +void ObTenantCloneService::stop() +{ + if (is_started_) { + startup_accel_handler_.stop(); + is_started_ = false; + } +} + +void ObTenantCloneService::wait() +{ + startup_accel_handler_.wait(); +} + +void ObTenantCloneService::destroy() +{ + startup_accel_handler_.destroy(); +} + +int ObTenantCloneService::get_clone_job_(ObArray& clone_jobs) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + ObTenantCloneTableOperator clone_op; + clone_jobs.reset(); + + if (OB_FAIL(clone_op.init(tenant_id, GCTX.sql_proxy_))) { + LOG_WARN("fail init", KR(ret)); + } else if (OB_FAIL(clone_op.get_all_clone_jobs(clone_jobs))) { + LOG_WARN("fail to get all clone jobs", KR(ret)); + } else if (clone_jobs.empty()) { + ret = OB_ENTRY_NOT_EXIST; + LOG_INFO("clone jobs in inner table not exist", KR(ret)); + } else if (clone_jobs.count() != 1) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("clone job count not validate", KR(ret), K(clone_jobs)); + } else if (!clone_jobs.at(0).is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("clone job is not valid", KR(ret), K(clone_jobs.at(0))); + } else { + LOG_INFO("get clone jobs succ", K(clone_jobs)); + } + + return ret; +} + +int ObTenantCloneService::try_clone_(const ObCloneJob& job) +{ + int ret = OB_SUCCESS; + ObTraceIDGuard trace_guard(job.get_trace_id()); + + common::ObSharedGuard ls_iter_guard; + ObLSIterator *ls_iter = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantCloneService does not init", KR(ret)); + } else if (!job.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("clone job is not valid", KR(ret), K(job)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls_iter(ls_iter_guard, ObLSGetMod::HA_MOD))) { + LOG_WARN("fail to get ls iter", KR(ret)); + } else if (OB_ISNULL(ls_iter = ls_iter_guard.get_ptr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls iter should not be NULL", KR(ret)); + } else { + while (OB_SUCC(ret)) { + ObLS *ls = nullptr; + if (OB_FAIL(ls_iter->get_next(ls))) { + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + break; + } + } else if (OB_ISNULL(ls)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", KR(ret)); + } else { + try_clone_one_ls_(job, ls); + } + } + } + + return ret; +} + +void ObTenantCloneService::try_clone_one_ls_(const ObCloneJob& job, ObLS* ls) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + + if (!job.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("clone job is not valid", KR(ret), K(job)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is unexpected nullptr", KR(ret)); + } else { + bool next_loop = false; + do { + next_loop = false; + ObLSRestoreStatus restore_status; + ObMigrationStatus migration_status = OB_MIGRATION_STATUS_MAX; + if (OB_FAIL(ls->get_restore_status(restore_status))) { + LOG_WARN("fail to get_restore_status", KR(ret), KPC(ls)); + } else if (!restore_status.is_in_clone()) { + if (restore_status.is_none()) { + LOG_INFO("the ls is in none status", KR(ret), KPC(ls)); + } else { + LOG_WARN("the ls is in unexpected restore status", KR(ret), KPC(ls), K(restore_status)); + } + } else if (OB_FAIL(ls->get_migration_status(migration_status))) { + LOG_WARN("fail to get migration status", KR(ret), KPC(ls)); + } else if (OB_MIGRATION_STATUS_NONE != migration_status) { + LOG_INFO("the ls is in migrate status, will not be executed", KR(ret), KPC(ls)); + } else { + LOG_INFO("the ls is in clone status", KR(ret), KPC(ls), K(restore_status)); + + share::ObLSRestoreStatus next_status = restore_status; + drive_clone_ls_sm_(job, restore_status, ls, next_status, next_loop); + + if (next_status != restore_status) { + if (OB_FAIL(advance_status_(ls, next_status))) { + LOG_WARN("advance_status_ failed", KR(ret), KPC(ls), K(restore_status)); + } else { + if (OB_TMP_FAIL(ls->report_replica_info())) { + LOG_WARN("fail to report replica info", KR(tmp_ret), KPC(ls)); + } + SERVER_EVENT_ADD("clone", "clone_ls", + "tenant_id", MTL_ID(), + "ls_id", ls->get_ls_id().id(), + "curr_status", ObLSRestoreStatus::get_restore_status_str(restore_status), + "next_status", ObLSRestoreStatus::get_restore_status_str(next_status)); + } + } + } + } while(next_loop); + } +} + +int ObTenantCloneService::advance_status_(ObLS* ls, const share::ObLSRestoreStatus &next_status) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is unexpected nullptr", KR(ret)); + } else if (OB_FAIL(ls->set_restore_status(next_status, ls->get_rebuild_seq()))) { + LOG_WARN("failed to update restore status", KR(ret), KPC(ls), K(next_status)); + } else { + LOG_INFO("advance clone status success", "ls_id", ls->get_ls_id(), K(next_status)); + } + + return ret; +} + +void ObTenantCloneService::drive_clone_ls_sm_(const ObCloneJob& job, + const ObLSRestoreStatus& restore_status, + ObLS* ls, + ObLSRestoreStatus& next_status, + bool& next_loop) +{ + int ret = OB_SUCCESS; + next_status = restore_status; + next_loop = false; + + if (!job.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("clone job is not valid", KR(ret), K(job)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is unexpected nullptr", KR(ret)); + } else { + switch (restore_status) + { + case ObLSRestoreStatus::Status::CLONE_START: + handle_clone_start_(job, ls, next_status, next_loop); + break; + case ObLSRestoreStatus::Status::CLONE_COPY_ALL_TABLET_META: + handle_copy_all_tablet_meta_(job, ls, next_status, next_loop); + break; + case ObLSRestoreStatus::Status::CLONE_COPY_LS_META: + handle_copy_ls_meta_(job, ls, next_status, next_loop); + break; + case ObLSRestoreStatus::Status::CLONE_CLOG_REPLAY: + handle_clog_replay_(job, ls, next_status, next_loop); + break; + case ObLSRestoreStatus::Status::CLONE_FAILED: + break; + default: + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("invalid clone status", KR(ret), K(restore_status), KPC(ls)); + break; + } + } +} + +int ObTenantCloneService::check_ls_status_valid_(const ObLSID& ls_id) +{ + int ret = OB_SUCCESS; + + ObLSStatusInfo status_info; + ObLSStatusOperator ls_status_operator; + if (OB_FAIL(ls_status_operator.get_ls_status_info(MTL_ID(), ls_id, status_info, *GCTX.sql_proxy_))) { + LOG_WARN("fail to get ls status info", KR(ret), K(ls_id)); + } else if (!status_info.ls_is_created() && + !status_info.ls_is_normal() && + !status_info.ls_is_dropping()) { + ret = OB_STATE_NOT_MATCH; + LOG_INFO("ls status info is not valid", KR(ret), K(ls_id), K(status_info)); + } else { + LOG_INFO("ls status info is valid", K(ls_id), K(status_info)); + } + return ret; +} + +void ObTenantCloneService::handle_clone_start_(const ObCloneJob& job, + ObLS* ls, + ObLSRestoreStatus& next_status, + bool& next_loop) +{ + int ret = OB_SUCCESS; + if (!job.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("clone job is not valid", KR(ret), K(job)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is unexpected nullptr", KR(ret)); + } else if (OB_FAIL(check_ls_status_valid_(ls->get_ls_id()))) { + LOG_INFO("fail to check_ls_status_valid_", KR(ret), KPC(ls)); + } else { + next_status = ObLSRestoreStatus::Status::CLONE_COPY_ALL_TABLET_META; + next_loop = true; + FLOG_INFO("handle_clone_start_ succ", KPC(ls)); + } +} + +void ObTenantCloneService::handle_copy_all_tablet_meta_(const ObCloneJob& job, + ObLS* ls, + ObLSRestoreStatus& next_status, + bool& next_loop) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLSID ls_id; + blocksstable::MacroBlockId tablet_meta_entry; + bool has_inc_clone_ref = false; + + if (!job.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("clone job is not valid", KR(ret), K(job)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is unexpected nullptr", KR(ret)); + } else if (ls->get_tablet_svr()->get_tablet_count() != 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls tablet count is not zero", KR(ret), KPC(ls), KPC(ls->get_tablet_svr())); + } else { + ls_id = ls->get_ls_id(); + } + + if (OB_SUCC(ret)) { + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (OB_FAIL(guard.switch_to(job.get_source_tenant_id(), false))) { + LOG_WARN("fail to switch to tenant", KR(ret), K(job.get_source_tenant_id())); + } else if (OB_FAIL(MTL(ObTenantSnapshotService*)->start_clone(job.get_tenant_snapshot_id(), + ls_id, + tablet_meta_entry))) { + LOG_WARN("fail to start_clone", + KR(ret), K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id)); + } else { + has_inc_clone_ref = true; + FLOG_INFO("inc snapshot clone ref succ", + K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id), K(tablet_meta_entry)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(meta_handler_->create_all_tablet(&startup_accel_handler_, tablet_meta_entry))) { + LOG_WARN("fail to create_all_tablet", + KR(ret), K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id), K(tablet_meta_entry)); + } else { + FLOG_INFO("create_all_tablet succ", + K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id), K(tablet_meta_entry)); + } + } + + if (has_inc_clone_ref) { + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (OB_TMP_FAIL(guard.switch_to(job.get_source_tenant_id(), false))) { + LOG_ERROR("fail to switch to tenant", KR(ret), K(job.get_source_tenant_id())); + } else if (OB_TMP_FAIL(MTL(ObTenantSnapshotService*)->end_clone(job.get_tenant_snapshot_id()))) { + LOG_ERROR("fail to end_clone", + KR(ret), K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id), K(tablet_meta_entry)); + } else { + FLOG_INFO("dec snapshot clone ref succ", + K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id), K(tablet_meta_entry)); + } + } + + if (OB_SUCC(ret)) { + next_status = ObLSRestoreStatus::Status::CLONE_COPY_LS_META; + next_loop = true; + FLOG_INFO("handle_copy_all_tablet_meta_ succ", + K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id), K(tablet_meta_entry)); + } else if (OB_EAGAIN == ret) { + FLOG_INFO("handle_copy_all_tablet_meta_ eagain", + K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id), K(tablet_meta_entry)); + } else { + next_status = ObLSRestoreStatus::Status::CLONE_FAILED; + next_loop = false; + } + return ; +} + +void ObTenantCloneService::handle_copy_ls_meta_(const ObCloneJob& job, + ObLS* ls, + ObLSRestoreStatus& next_status, + bool& next_loop) +{ + int ret = OB_SUCCESS; + ObLSID ls_id; + + if (!job.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("clone job is not valid", KR(ret), K(job)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is unexpected nullptr", KR(ret)); + } else if (!ls->is_offline()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is unexpected online", KR(ret), KPC(ls)); + } else { + ls_id = ls->get_ls_id(); + } + + if (OB_SUCC(ret)) { + HEAP_VAR(ObLSMetaPackage, ls_meta_package) { + { + ObTenantSnapshotTableOperator snap_op; + + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (OB_FAIL(guard.switch_to(job.get_source_tenant_id(), false))) { + LOG_WARN("fail to switch to tenant", KR(ret), K(job.get_source_tenant_id())); + } else if (OB_FAIL(ObTenantSnapshotMetaTable::acquire_clone_ls_meta_package(job.get_tenant_snapshot_id(), + ls_id, + ls_meta_package))) { + LOG_WARN("fail to acquire_clone_ls_meta_package", KR(ret), K(job), K(ls_id)); + } else if (!ls_meta_package.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls_meta_package is not valid", + KR(ret), K(ls_meta_package), K(job.get_tenant_snapshot_id()), K(ls_id)); + } else { + LOG_INFO("acquire_clone_ls_meta_package succ", K(job), K(ls_id), K(ls_meta_package.ls_meta_)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(ls->update_ls_meta(false, ls_meta_package.ls_meta_))) { + LOG_WARN("fail to update ls meta", KR(ret), K(job), KPC(ls)); + } else if (OB_FAIL(ls->set_dup_table_ls_meta(ls_meta_package.dup_ls_meta_, true))) { + LOG_WARN("fail to set dup table ls meta", KR(ret), K(job), KPC(ls)); + } else if (OB_FAIL(ls->online())) { + LOG_WARN("fail to online ls", KR(ret), KPC(ls)); + } + } + } + } + + if (OB_SUCC(ret)) { + next_status = ObLSRestoreStatus::Status::CLONE_CLOG_REPLAY; + next_loop = false; + FLOG_INFO("handle_copy_ls_meta_ succ", + K(job.get_source_tenant_id()), K(job.get_tenant_snapshot_id()), K(ls_id)); + } else { + next_status = ObLSRestoreStatus::Status::CLONE_FAILED; + next_loop = false; + } + return ; +} + +void ObTenantCloneService::handle_clog_replay_(const ObCloneJob& job, + ObLS* ls, + ObLSRestoreStatus& next_status, + bool& next_loop) +{ + int ret = OB_SUCCESS; + + if (!job.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("clone job is not valid", KR(ret), K(job)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls is unexpected nullptr", KR(ret)); + } + + if (OB_SUCC(ret)) { + bool restore_clog_done = false; + logservice::ObLogRestoreHandler *log_restore_handle = nullptr; + if (OB_ISNULL(log_restore_handle = ls->get_log_restore_handler())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("log restore handler is unexpected nullptr", KR(ret)); + } else if (OB_FAIL(log_restore_handle->check_restore_done(job.get_restore_scn(), restore_clog_done))) { + if (OB_EAGAIN != ret) { + LOG_WARN("fail to check log restore done", KR(ret), K(job), KPC(ls), K(restore_clog_done)); + } else { + LOG_INFO("fail to check log restore done", KR(ret), K(job), KPC(ls), K(restore_clog_done)); + } + } else { + next_status = ObLSRestoreStatus::Status::NONE; + next_loop = false; + FLOG_INFO("handle_clog_replay_ succ", KPC(ls)); + } + } + return ; +} + +void ObTenantCloneService::run() +{ + int ret = OB_SUCCESS; + + ObArray clone_jobs; + if (OB_SUCC(ret)) { + if (OB_FAIL(get_clone_job_(clone_jobs))) { + LOG_WARN("fail to get_clone_job_", KR(ret)); + } else { + LOG_INFO("get clone job succ", K(clone_jobs)); + } + } + + if (OB_SUCC(ret)) { + ObCloneJob &job = clone_jobs.at(0); + if (OB_FAIL(try_clone_(job))) { + LOG_INFO("fail to try_clone_", KR(ret), K(job)); + } + } + + return ; +} + +} +} diff --git a/src/storage/tenant_snapshot/ob_tenant_clone_service.h b/src/storage/tenant_snapshot/ob_tenant_clone_service.h new file mode 100644 index 0000000000..9d9cb0e248 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_clone_service.h @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_STORAGE_OB_TENANT_CLONE_SERVICE_ +#define OCEANBASE_STORAGE_OB_TENANT_CLONE_SERVICE_ + +#include "share/ob_rpc_struct.h" +#include "lib/lock/ob_rwlock.h" +#include "share/restore/ob_ls_restore_status.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_mgr.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_mgr.h" +#include "storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h" +#include "share/restore/ob_tenant_clone_table_operator.h" +#include "observer/ob_startup_accel_task_handler.h" + +namespace oceanbase +{ +namespace storage +{ + +// When it was originally designed, ObTenantCloneService was an independent service. +// Later, in order to reduce the number of threads, the thread of ObTenantSnapshotService was +// used to drive ObTenantCloneService. +// Logically, ObTenantCloneService is located on the upper layer of ObTenantSnapshotService +class ObTenantCloneService final +{ +public: + ObTenantCloneService() : is_inited_(false), + is_started_(false), + meta_handler_(nullptr), + startup_accel_handler_(){} + + virtual ~ObTenantCloneService() { } + + int init(ObTenantMetaSnapshotHandler* meta_handler); + int start(); + void stop(); + void wait(); + void destroy(); + void run(); + + bool is_started() { return is_started_; } +private: + int get_clone_job_(ObArray& clone_jobs); + int try_clone_(const ObCloneJob& job); + void try_clone_one_ls_(const ObCloneJob& job, ObLS* ls); + void drive_clone_ls_sm_(const ObCloneJob& job, + const share::ObLSRestoreStatus& restore_status, + ObLS* ls, + share::ObLSRestoreStatus& next_status, + bool& next_loop); + int check_ls_status_valid_(const share::ObLSID& ls_id); + void handle_clone_start_(const ObCloneJob& job, + ObLS* ls, + share::ObLSRestoreStatus& next_status, + bool& next_loop); + void handle_copy_all_tablet_meta_(const ObCloneJob& job, + ObLS* ls, + share::ObLSRestoreStatus& next_status, + bool& next_loop); + void handle_copy_ls_meta_(const ObCloneJob& job, + ObLS* ls, + ObLSRestoreStatus& next_status, + bool& next_loop); + void handle_clog_replay_(const ObCloneJob& job, + ObLS* ls, + share::ObLSRestoreStatus& next_status, + bool& next_loop); + int advance_status_(ObLS* ls, const share::ObLSRestoreStatus &next_status); + +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantCloneService); + + bool is_inited_; + bool is_started_; + ObTenantMetaSnapshotHandler* meta_handler_; + observer::ObStartupAccelTaskHandler startup_accel_handler_; +}; + +} +} + +#endif diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_defs.cpp b/src/storage/tenant_snapshot/ob_tenant_snapshot_defs.cpp new file mode 100644 index 0000000000..28e9a51b3a --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_defs.cpp @@ -0,0 +1,847 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "share/ob_errno.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_mgr.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h" + +namespace oceanbase +{ +namespace storage +{ + +int ObTenantSnapshot::init(const ObTenantSnapshotID& tenant_snapshot_id, + ObLSSnapshotMgr* ls_snapshot_mgr, + ObTenantMetaSnapshotHandler* meta_handler) +{ + int ret = OB_SUCCESS; + + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTenantSnapshot init twice", KR(ret), K(tenant_snapshot_id_)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is invalid", KR(ret), K(tenant_snapshot_id_)); + } else if (OB_ISNULL(ls_snapshot_mgr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_snapshot_mgr is nullptr", KR(ret)); + } else { + tenant_snapshot_id_ = tenant_snapshot_id; + is_inited_ = true; + is_running_ = true; + has_unfinished_create_dag_ = false; + has_unfinished_gc_dag_ = false; + clone_ref_ = 0; + meta_existed_ = false; + ls_snapshot_mgr_ = ls_snapshot_mgr; + meta_handler_ = meta_handler; + } + + return ret; +} + +int ObTenantSnapshot::load() +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard snapshot_guard(mutex_); + + meta_existed_ = true; + ObArray ls_id_arr; + if (OB_FAIL(meta_handler_->get_all_ls_snapshot(tenant_snapshot_id_, ls_id_arr))) { + LOG_WARN("fail to get_all_ls_snapshot", KR(ret), KPC(this)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < ls_id_arr.count(); ++i) { + ObLSID ls_id = ls_id_arr.at(i); + ObLSSnapshot* ls_snapshot = nullptr; + if (OB_FAIL(ls_snapshot_mgr_->acquire_ls_snapshot(tenant_snapshot_id_, ls_id, ls_snapshot))) { + LOG_WARN("fail to acquire_ls_snapshot", KR(ret), K(ls_id)); + } else { + if (OB_FAIL(ls_snapshot->load())) { + LOG_WARN("fail to load", KR(ret), K(tenant_snapshot_id_), K(ls_id)); + } else { + LOG_INFO("ls snapshot load succ", K(tenant_snapshot_id_), K(ls_id)); + } + ls_snapshot_mgr_->revert_ls_snapshot(ls_snapshot); + } + } + } + LOG_INFO("tenant snapshot load finished", KR(ret), K(tenant_snapshot_id_)); + return ret; +} + +int ObTenantSnapshot::try_start_create_tenant_snapshot_dag(ObArray& creating_ls_id_arr, + common::ObCurTraceId::TraceId& trace_id) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard snapshot_guard(mutex_); + ObTenantSnapshotSvrInfo svr_info; + creating_ls_id_arr.reset(); + trace_id.reset(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshot is not init", KR(ret)); + } else if (!ATOMIC_LOAD(&is_running_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("ObTenantSnapshot is not running", KR(ret), KPC(this)); + } else if (has_unfinished_dag_()) { + ret = OB_EAGAIN; + LOG_INFO("ObTenantSnapshot has unfinished dag", KR(ret), KPC(this)); + } else if (OB_FAIL(ObTenantSnapshotMetaTable::acquire_tenant_snapshot_svr_info(tenant_snapshot_id_, + svr_info))) { + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + ret = OB_NO_NEED_UPDATE; + } else { + LOG_WARN("fail to acquire_tenant_snapshot_svr_info", KR(ret), K(tenant_snapshot_id_)); + } + // TODO: Currently, how to get the maximum scn in ObLSMetaPackage has not yet been solved; + } else if (ObTenantSnapStatus::CREATING != svr_info.get_tenant_snap_item_const().get_status()) { + ret = OB_NO_NEED_UPDATE; + LOG_INFO("tenant snapshot status in the meta table is not creating", + KR(ret), K(tenant_snapshot_id_)); + } else if (OB_FAIL(svr_info.get_creating_ls_id_arr(creating_ls_id_arr))) { + LOG_WARN("fail to get_creating_ls_id_arr", KR(ret), K(tenant_snapshot_id_), K(svr_info)); + } else if (creating_ls_id_arr.empty()) { + ret = OB_NO_NEED_UPDATE; + LOG_INFO("creating_ls_id_arr is empty", KR(ret), K(tenant_snapshot_id_), K(svr_info)); + } else { + ObTenantSnapshotMetaTable::acquire_tenant_snapshot_trace_id(tenant_snapshot_id_, + ObTenantSnapOperation::CREATE, + trace_id); + create_dag_start_(); + } + + return ret; +} + +int ObTenantSnapshot::try_start_gc_tenant_snapshot_dag(bool &gc_all_tenant_snapshot, + ObArray &gc_ls_id_arr, + common::ObCurTraceId::TraceId& trace_id) +{ + int ret = OB_SUCCESS; + bool need_gc = false; + ObTenantSnapshotSvrInfo svr_info; + + lib::ObMutexGuard snapshot_guard(mutex_); + // gc tenant snapshot when: + // 1. no entry for this snapshot in __all_tenant_snapshot(but we see it in local storage); + // 2. snapshot status in __all_tenant_snapshot is DELETING. + // or gc ls_snapshot only + gc_all_tenant_snapshot = false; + gc_ls_id_arr.reset(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshot is not init", KR(ret)); + } else if (0 != clone_ref_) { + ret = OB_EAGAIN; + LOG_INFO("This tenant snapshot is being used for cloning and cannot be gc currently", + KR(ret), KPC(this)); + } else if (has_unfinished_dag_()) { + ret = OB_EAGAIN; + LOG_INFO("ObTenantSnapshot has unfinished dag", KR(ret), KPC(this)); + } else if (OB_FAIL(ObTenantSnapshotMetaTable::acquire_tenant_snapshot_svr_info(tenant_snapshot_id_, + svr_info))) { + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + ret = OB_SUCCESS; + need_gc = true; + LOG_INFO("tenant snapshot not exist, need gc", K(tenant_snapshot_id_)); + } + } else if (ObTenantSnapStatus::DELETING == svr_info.get_tenant_snap_item().get_status()) { + need_gc = true; + LOG_INFO("tenant snapshot status is DELETING, need gc", K(tenant_snapshot_id_)); + } + + if (OB_SUCC(ret)) { + if (need_gc) { // gc tenant snapshot (with corresponding ls_snapshot) + gc_all_tenant_snapshot = true; + is_running_ = false; + } else if (OB_FAIL(get_need_gc_ls_snapshot_arr_(svr_info.get_ls_snap_item_arr(), + gc_ls_id_arr))) { + LOG_WARN("fail to get_need_gc_ls_snapshot_arr_", KR(ret), K(svr_info)); + } else if (gc_ls_id_arr.count() > 0) { + need_gc = true; + gc_all_tenant_snapshot = false; // gc ls_snapshot only (maybe cause by ls transfer) + LOG_INFO("ls snapshot need gc", KR(ret), K(gc_ls_id_arr)); + } + } + + if (OB_SUCC(ret)) { + if (need_gc) { + ObTenantSnapshotMetaTable::acquire_tenant_snapshot_trace_id(tenant_snapshot_id_, + ObTenantSnapOperation::DELETE, + trace_id); + gc_dag_start_(); + } else { + ret = OB_NO_NEED_UPDATE; + } + } else { + LOG_WARN("fail to try_start_gc_tenant_snapshot_dag", KR(ret), KPC(this)); + } + return ret; +} + +int ObTenantSnapshot::execute_gc_tenant_snapshot_dag(const bool gc_all_tenant_snapshot, const ObArray &gc_ls_id_arr) +{ + int ret = OB_SUCCESS; + { + lib::ObMutexGuard snapshot_guard(mutex_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshot not init", KR(ret)); + } else if (!has_unfinished_gc_dag_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObTenantSnapshot does not have unfinished gc dag", KR(ret), KPC(this)); + } else if (0 != clone_ref_) { + ret = OB_EAGAIN; + LOG_INFO("This tenant snapshot is being used for cloning and cannot be gc currently", + KR(ret), KPC(this)); + } + } + if (OB_SUCC(ret)) { + if (gc_all_tenant_snapshot) { + LOG_INFO("gc_tenant_snapshot_ with ls_snapshot", K(tenant_snapshot_id_)); + if (OB_FAIL(gc_tenant_snapshot_())) { + LOG_WARN("fail to gc_tenant_snapshot_", KR(ret), KPC(this)); + } + } else { + LOG_INFO("gc_ls_snapshots_ only", K(tenant_snapshot_id_), K(gc_ls_id_arr)); + if (OB_FAIL(gc_ls_snapshots_(gc_ls_id_arr))) { + LOG_WARN("fail to gc_ls_snapshots_", KR(ret), KPC(this)); + } + } + } + return ret; +} + +int ObTenantSnapshot::execute_create_tenant_snapshot_dag(const ObArray &creating_ls_id_arr) +{ + int ret = OB_SUCCESS; + + { + lib::ObMutexGuard snapshot_guard(mutex_); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (!ATOMIC_LOAD(&is_running_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("ObTenantSnapshot is not in running state", KR(ret), KPC(this)); + } else if (!has_unfinished_create_dag_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObTenantSnapshot does not have unfinished dag", KR(ret), KPC(this)); + } + } + + if (OB_SUCC(ret)) { + build_all_snapshots_(creating_ls_id_arr); + } + return ret; +} + +int ObTenantSnapshot::finish_create_tenant_snapshot_dag() +{ + lib::ObMutexGuard snapshot_guard(mutex_); + return create_dag_finish_(); +} + +int ObTenantSnapshot::create_dag_start_() +{ + int ret = OB_SUCCESS; + if (has_unfinished_create_dag_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObTenantSnapshot has unfinished dag", KR(ret), KPC(this)); + } else { + has_unfinished_create_dag_ = true; + } + return ret; +} + +int ObTenantSnapshot::create_dag_finish_() +{ + int ret = OB_SUCCESS; + if (!has_unfinished_create_dag_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tenant snapshot does not have unfinished dag", KR(ret), KPC(this)); + } else { + has_unfinished_create_dag_ = false; + } + return ret; +} + +int ObTenantSnapshot::gc_dag_start_() +{ + int ret = OB_SUCCESS; + if (has_unfinished_gc_dag_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObTenantSnapshot has unfinished gc dag", KR(ret), KPC(this)); + } else { + has_unfinished_gc_dag_ = true; + } + return ret; +} + +int ObTenantSnapshot::gc_dag_finish_() +{ + int ret = OB_SUCCESS; + if (!has_unfinished_gc_dag_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tenant snapshot does not have unfinished gc dag", KR(ret), KPC(this)); + } else { + has_unfinished_gc_dag_ = false; + } + return ret; +} + +int ObTenantSnapshot::finish_gc_tenant_snapshot_dag() +{ + lib::ObMutexGuard snapshot_guard(mutex_); + return gc_dag_finish_(); +} + +int ObTenantSnapshot::clear_meta_snapshot_() +{ + LOG_INFO("clear tenant meta snapshot", KPC(this)); + + int ret = OB_SUCCESS; + if (meta_existed_) { + if (OB_FAIL(meta_handler_->delete_tenant_snapshot(tenant_snapshot_id_))) { + LOG_ERROR("fail to delete_tenant_snapshot", KR(ret), KPC(this)); + } else { + meta_existed_ = false; + } + } + return ret; +} + +void ObTenantSnapshot::build_all_snapshots_(const ObArray& creating_ls_id_arr) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(build_tenant_snapshot_meta_())) { + LOG_WARN("fail to do build_tenant_snapshot_meta_", KR(ret), KPC(this)); + } else { + build_all_ls_snapshots_(creating_ls_id_arr); + } +} + +int ObTenantSnapshot::build_tenant_snapshot_meta_() +{ + int ret = OB_SUCCESS; + + if (!ATOMIC_LOAD(&meta_existed_)) { + if (OB_FAIL(meta_handler_->create_tenant_snapshot(tenant_snapshot_id_))) { + LOG_WARN("fail to do ObTenantMetaSnapshotHandler::create_tenant_snapshot", KR(ret), KPC(this)); + } else { + meta_existed_ = true; + LOG_INFO("ObTenantMetaSnapshotHandler::create_tenant_snapshot succ", KPC(this)); + } + } else { + LOG_INFO("the tenant snapshot meta already existed", KPC(this)); + } + return ret; +} + +void ObTenantSnapshot::build_all_ls_snapshots_(const ObArray& creating_ls_id_arr) +{ + int ret = OB_SUCCESS; + + for (int64_t i = 0; i < creating_ls_id_arr.count(); i++) { + const ObLSID creating_ls_id = creating_ls_id_arr.at(i); + + if (OB_FAIL(build_one_ls_snapshot_(creating_ls_id))) { + LOG_WARN("failed to build_one_ls_snapshot_", KR(ret), KPC(this), K(creating_ls_id)); + } + } + + LOG_INFO("build_all_ls_snapshots_ complete"); +} + +int ObTenantSnapshot::build_one_ls_snapshot_(const ObLSID& creating_ls_id) +{ + int ret = OB_SUCCESS; + ObLSSnapshot* ls_snapshot = nullptr; + + if (OB_FAIL(ls_snapshot_mgr_->acquire_ls_snapshot(tenant_snapshot_id_, + creating_ls_id, + ls_snapshot))) { + LOG_WARN("fail to acquire_ls_snapshot", + KR(ret), K(tenant_snapshot_id_), K(creating_ls_id)); + } else if (OB_ISNULL(ls_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls_snapshot is unexpected nullptr", KR(ret)); + } else if (ls_snapshot->is_build_finished()) { + LOG_INFO("ls_snapshot is already build finished", KR(ret), KPC(this), KPC(ls_snapshot)); + } else if (OB_FAIL(build_one_ls_snapshot_meta_(ls_snapshot))) { + LOG_WARN("fail to build_one_ls_snapshot_meta_", KR(ret), KPC(this), KPC(ls_snapshot)); + } + + report_one_ls_snapshot_build_rlt_(ls_snapshot, ret); + + if (ls_snapshot != nullptr) { + ls_snapshot_mgr_->revert_ls_snapshot(ls_snapshot); + } + return ret; +} + +int ObTenantSnapshot::build_one_ls_snapshot_meta_(ObLSSnapshot* ls_snapshot) +{ + int ret = OB_SUCCESS; + + ObLS* ls = nullptr; + ObLSHandle ls_handle; + ObLSID creating_ls_id; + + if (OB_ISNULL(ls_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_snapshot is nullptr", KR(ret), KPC(this)); + } else if (FALSE_IT(creating_ls_id = ls_snapshot->get_ls_id())) { + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(creating_ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("failed to get ls", KR(ret), KPC(this), KPC(ls_snapshot)); + } else if (OB_ISNULL((ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), KPC(this), KPC(ls_snapshot)); + } else if (OB_FAIL(ls->get_tablet_gc_handler()->disable_gc())) { + LOG_WARN("fail to disable gc", KR(ret), KPC(ls_snapshot), KPC(ls)); + if (OB_TABLET_GC_LOCK_CONFLICT == ret) { + ret = OB_EAGAIN; + } + } else { + if (OB_FAIL(ls_snapshot->build_ls_snapshot(ls))) { + LOG_WARN("fail to build_ls_snapshot", KR(ret), KPC(ls_snapshot), KPC(ls)); + } + ls->get_tablet_gc_handler()->enable_gc(); + } + return ret; +} + +void ObTenantSnapshot::report_one_ls_snapshot_build_rlt_(ObLSSnapshot* ls_snapshot, + const int ls_ret) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(ls_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls_snapshot is unexpected nullptr", KR(ret)); + } else { + const ObLSID creating_ls_id = ls_snapshot->get_ls_id(); + + if (OB_SUCCESS != ls_ret && OB_EAGAIN != ls_ret) { + ls_snapshot->try_set_failed(); + } + + if (OB_SUCCESS == ls_ret && ls_snapshot->is_valid_for_reporting_succ()) { + if (OB_FAIL(report_create_ls_snapshot_succ_rlt_(ls_snapshot))) { + LOG_WARN("fail to report_create_ls_snapshot_succ_rlt_", + KR(ret), K(creating_ls_id), KPC(ls_snapshot)); + } + } else { + if (OB_EAGAIN != ls_ret) { + if (OB_FAIL(report_create_ls_snapshot_fail_rlt_(creating_ls_id))) { + LOG_WARN("fail to report_create_ls_snapshot_succ_rlt_", KR(ret), K(creating_ls_id)); + } + } else { + LOG_INFO("ls_ret is OB_EAGAIN, which can be retried", KR(ret), K(creating_ls_id)); + } + } + + if (OB_SUCC(ret)) { + ls_snapshot->try_free_build_ctx(); + } + } +} + +int ObTenantSnapshot::report_create_ls_snapshot_succ_rlt_(ObLSSnapshot* ls_snapshot) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(ls_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls_snapshot is unexpected nullptr", KR(ret)); + } else { + ObLSSnapshotReportInfo info(ls_snapshot->get_ls_id()); + if (OB_FAIL(ls_snapshot->get_report_info(info))) { + LOG_WARN("fail to get_report_info", KR(ret), KPC(ls_snapshot)); + } else if (OB_FAIL(ObTenantSnapshotMetaTable:: + report_create_ls_snapshot_rlt(tenant_snapshot_id_, info))) { + LOG_WARN("fail to report_create_ls_snapshot_rlt", KR(ret), KPC(ls_snapshot), K(info)); + } + } + + return ret; +} + +int ObTenantSnapshot::report_create_ls_snapshot_fail_rlt_(const ObLSID& ls_id) +{ + int ret = OB_SUCCESS; + + ObLSSnapshotReportInfo info(ls_id); + info.to_failed(); + if (OB_FAIL(ObTenantSnapshotMetaTable:: + report_create_ls_snapshot_rlt(tenant_snapshot_id_, info))) { + LOG_WARN("fail to report_create_ls_snapshot_rlt", KR(ret), K(info)); + } + return ret; +} + +void ObTenantSnapshot::stop() +{ + lib::ObMutexGuard snapshot_guard(mutex_); + is_running_ = false; +} + +bool ObTenantSnapshot::is_stopped() +{ + return !ATOMIC_LOAD(&is_running_); +} + +template +bool ObTenantSnapshot::ForEachFilterFunctor::operator()( + const ObLSSnapshotMapKey &snapshot_key, ObLSSnapshot* ls_snapshot) +{ + int ret = OB_SUCCESS; + bool bool_ret = false; + + if (!snapshot_key.is_valid() || OB_ISNULL(ls_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(snapshot_key), KP(ls_snapshot)); + } else if (snapshot_key.tenant_snapshot_id_ != tenant_snapshot_id_) { + bool_ret = true; + } else { + bool_ret = fn_(snapshot_key.ls_id_, ls_snapshot); + } + return bool_ret; +} + +template int ObTenantSnapshot::for_each_(Fn &fn) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(ls_snapshot_mgr_)) { + ret = OB_NOT_INIT; + LOG_WARN("ls_snapshot_mgr_ is nullptr", KR(ret), K(tenant_snapshot_id_)); + } else { + ForEachFilterFunctor filter_fn(tenant_snapshot_id_, fn); + ret = ls_snapshot_mgr_->for_each(filter_fn); + } + return ret; +} + +template +bool ObTenantSnapshot::RemoveIfFilterFunctor::operator()( + const ObLSSnapshotMapKey &snapshot_key, ObLSSnapshot* ls_snapshot) +{ + int ret = OB_SUCCESS; + bool bool_ret = false; + + if (!snapshot_key.is_valid() || OB_ISNULL(ls_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(snapshot_key), KP(ls_snapshot)); + } else if (snapshot_key.tenant_snapshot_id_ != tenant_snapshot_id_) { + bool_ret = false; + } else { + bool_ret = fn_(snapshot_key.ls_id_, ls_snapshot); + } + return bool_ret; +} + +template int ObTenantSnapshot::remove_if_(Fn &fn) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(ls_snapshot_mgr_)) { + ret = OB_NOT_INIT; + LOG_WARN("ls_snapshot_mgr_ is nullptr", KR(ret), K(tenant_snapshot_id_)); + } else { + RemoveIfFilterFunctor filter_fn(tenant_snapshot_id_, fn); + ret = ls_snapshot_mgr_->remove_if(filter_fn); + } + return ret; +} + +int ObTenantSnapshot::gc_tenant_snapshot_() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(clear_meta_snapshot_())) { + LOG_WARN("fail to clear_meta_snapshot_", KR(ret), KPC(this)); + } else { + notify_ls_snapshots_tenant_gc_(); + } + + LOG_INFO("gc tenant snapshot finished", KR(ret), KPC(this)); + return ret; +} + +int ObTenantSnapshot::gc_ls_snapshots_(const ObArray &gc_ls_id_arr) +{ + int ret = OB_SUCCESS; + + for (int64_t i = 0; i < gc_ls_id_arr.count(); ++i) { + ObLSSnapshot* ls_snapshot = nullptr; + const ObLSID gc_ls_id = gc_ls_id_arr[i]; + if (OB_FAIL(ls_snapshot_mgr_->get_ls_snapshot(tenant_snapshot_id_, + gc_ls_id, + ls_snapshot))) { + LOG_WARN("fail to get_ls_snapshot", KR(ret), KPC(this), K(gc_ls_id)); + } else if (OB_ISNULL(ls_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls_snapshot is unexpected nullptr", KR(ret), KPC(this), K(gc_ls_id)); + } else { + if (OB_FAIL(ls_snapshot->gc_ls_snapshot())) { + LOG_WARN("fail to gc_ls_snapshot", KR(ret), KPC(ls_snapshot)); + } else if (OB_FAIL(ls_snapshot_mgr_->del_ls_snapshot(tenant_snapshot_id_, gc_ls_id))) { + LOG_WARN("fail to gc_ls_snapshot", KR(ret), KPC(ls_snapshot)); + } + ls_snapshot_mgr_->revert_ls_snapshot(ls_snapshot); + } + } + return ret; +} + +class ObLSSnapshotNotifyTenantGcFunctor +{ +public: + bool operator()(const ObLSID &ls_id, ObLSSnapshot* ls_snapshot) + { + int ret = OB_SUCCESS; + bool bool_ret = false; + + if (!ls_id.is_valid() || OB_ISNULL(ls_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_id), KP(ls_snapshot)); + } else { + ls_snapshot->notify_tenant_gc(); + bool_ret = true; + } + return bool_ret; + } +}; + +void ObTenantSnapshot::notify_ls_snapshots_tenant_gc_() +{ + int ret = OB_SUCCESS; + ObLSSnapshotNotifyTenantGcFunctor fn; + if (OB_FAIL(remove_if_(fn))) { + LOG_ERROR("fail to remove_if for notify_ls_snapshots_tenant_gc_", KR(ret), KPC(this)); + } +} + +class ObCheckLSSnapshotNeedGCFunctor +{ +public: + ObCheckLSSnapshotNeedGCFunctor(const ObArray& item_arr, + ObArray& gc_ls_id_arr) + : item_arr_(item_arr), gc_ls_id_arr_(gc_ls_id_arr) {} + ~ObCheckLSSnapshotNeedGCFunctor() {} + + bool operator()(const ObLSID &ls_id, ObLSSnapshot* ls_snapshot) + { + int ret = OB_SUCCESS; + + if (!ls_id.is_valid() || OB_ISNULL(ls_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_id), KP(ls_snapshot)); + } else { + bool found = false; + int64_t i = 0; + for (i = 0; i < item_arr_.count(); ++i) { + if (item_arr_.at(i).get_ls_id() == ls_id) { + found = true; + break; + } + } + + bool need_gc = false; + if (!found) { + need_gc = true; + } else if (ObLSSnapStatus::FAILED == item_arr_.at(i).get_status()) { + need_gc = true; + } + + if (need_gc) { + gc_ls_id_arr_.push_back(ls_id); + } + } + return true; + } + +private: + const ObArray& item_arr_; + ObArray& gc_ls_id_arr_; +}; + +int ObTenantSnapshot::get_need_gc_ls_snapshot_arr_( + const ObArray& item_arr, + ObArray& gc_ls_id_arr) +{ + int ret = OB_SUCCESS; + gc_ls_id_arr.reset(); + + ObCheckLSSnapshotNeedGCFunctor fn(item_arr, gc_ls_id_arr); + if (OB_FAIL(for_each_(fn))) { + LOG_ERROR("fail to for_each_ ls_snapshots", KR(ret), KPC(this)); + } + return ret; +} + +int ObTenantSnapshot::destroy() +{ + int ret = OB_SUCCESS; + + if (IS_INIT) { + lib::ObMutexGuard snapshot_guard(mutex_); + if (ATOMIC_LOAD(&is_running_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("when the tenant snapshot is to be destroyed, it should not be in the running state", + KR(ret), KPC(this)); + } else if (OB_FAIL(destroy_all_ls_snapshots_())) { + LOG_ERROR("fail to destroy_all_ls_snapshots_", KR(ret), KPC(this)); + } else { + LOG_INFO("tenant snapshot destroy succ"); + } + is_inited_ = false; + } + + return ret; +} + +class ObLSSnapshotDestroyFunctor +{ +public: + bool operator()(const ObLSID &ls_id, ObLSSnapshot* ls_snapshot) + { + int ret = OB_SUCCESS; + bool bool_ret = false; + + if (!ls_id.is_valid() || OB_ISNULL(ls_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(ls_id), KP(ls_snapshot)); + } else { + ls_snapshot->destroy(); + bool_ret = true; + } + return bool_ret; + } +}; + +int ObTenantSnapshot::destroy_all_ls_snapshots_() +{ + int ret = OB_SUCCESS; + + ObLSSnapshotDestroyFunctor fn; + if (OB_FAIL(remove_if_(fn))) { + LOG_ERROR("fail to remove_if for destroy ls snapshots", KR(ret), KPC(this)); + } + return ret; +} + +int ObTenantSnapshot::inc_clone_ref() +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard snapshot_guard(mutex_); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshot is not init", KR(ret)); + } else if (!ATOMIC_LOAD(&is_running_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("ObTenantSnapshot is not running", KR(ret), KPC(this)); + } else if (has_unfinished_dag_()) { + ret = OB_EAGAIN; + LOG_INFO("ObTenantSnapshot has unfinished dag", KR(ret), KPC(this)); + } else if (!meta_existed_) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("ObTenantSnapshot meta not existed", KR(ret), KPC(this)); + } else { + ++clone_ref_; + LOG_INFO("ObTenantSnapshot inc clone ref succ", KPC(this)); + } + + return ret; +} + +int ObTenantSnapshot::dec_clone_ref() +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard snapshot_guard(mutex_); + + if (clone_ref_ <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ObTenantSnapshot clone_ref_ is unexpected value", KR(ret), KPC(this)); + } else { + --clone_ref_; + LOG_INFO("ObTenantSnapshot dec clone ref succ", KPC(this)); + } + + return ret; +} + +int ObTenantSnapshot::get_tenant_snapshot_vt_info(ObTenantSnapshotVTInfo &info) +{ + int ret = OB_SUCCESS; + + info.reset(); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshot is not init", KR(ret), KPC(this)); + } else { + lib::ObMutexGuard snapshot_guard(mutex_); + info.set_tsnap_is_running(is_running_); + info.set_tsnap_has_unfinished_create_dag(has_unfinished_create_dag_); + info.set_tsnap_has_unfinished_gc_dag(has_unfinished_gc_dag_); + info.set_tsnap_clone_ref(clone_ref_); + info.set_tsnap_meta_existed(meta_existed_); + } + return ret; +} + +int ObTenantSnapshot::get_ls_snapshot_tablet_meta_entry(const ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry) +{ + int ret = OB_SUCCESS; + lib::ObMutexGuard snapshot_guard(mutex_); + + ObLSSnapshot* ls_snapshot = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshot is not init", KR(ret)); + } else if (!ATOMIC_LOAD(&is_running_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("ObTenantSnapshot is not running", KR(ret), KPC(this)); + } else if (has_unfinished_dag_()) { + ret = OB_EAGAIN; + LOG_WARN("ObTenantSnapshot has unfinished dag", KR(ret), KPC(this)); + } else if (!ATOMIC_LOAD(&meta_existed_)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("ObTenantSnapshot meta not existed", KR(ret), KPC(this)); + } else if (OB_FAIL(ls_snapshot_mgr_->get_ls_snapshot(tenant_snapshot_id_, ls_id, ls_snapshot))){ + LOG_WARN("fail to get_ls_snapshot", KR(ret), KPC(this)); + } else { + if (OB_FAIL(ls_snapshot->get_tablet_meta_entry(tablet_meta_entry))) { + LOG_WARN("fail to get_tablet_meta_entry", KR(ret), KPC(this)); + } else { + LOG_INFO("get_tablet_meta_entry succ", KR(ret), KPC(this), K(tablet_meta_entry)); + } + ls_snapshot_mgr_->revert_ls_snapshot(ls_snapshot); + } + return ret; +} + +} +} diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_defs.h b/src/storage/tenant_snapshot/ob_tenant_snapshot_defs.h new file mode 100644 index 0000000000..15b233e685 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_defs.h @@ -0,0 +1,175 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_DEFS_ +#define OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_DEFS_ + +#include "lib/hash/ob_link_hashmap.h" +#include "share/ob_ls_id.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_defs.h" + +namespace oceanbase +{ +using namespace share; +namespace storage +{ + +class ObLSSnapshotMgr; +class ObLSSnapshot; +class ObTenantMetaSnapshotHandler; +class ObTenantSnapshotVTInfo; + +typedef common::LinkHashValue ObTenantSnapshotValue; +class ObTenantSnapshot : public ObTenantSnapshotValue +{ +public: + ObTenantSnapshot() : + is_inited_(false), + is_running_(false), + tenant_snapshot_id_(), + has_unfinished_create_dag_(false), + has_unfinished_gc_dag_(false), + clone_ref_(0), + meta_existed_(false), + ls_snapshot_mgr_(nullptr), + meta_handler_(nullptr), + mutex_() {} + + ~ObTenantSnapshot() {} + int destroy(); + + int init(const ObTenantSnapshotID& tenant_snapshot_id, + ObLSSnapshotMgr* ls_snapshot_manager, + ObTenantMetaSnapshotHandler* meta_handler); + + void reset() + { + is_inited_ = false; + is_running_ = false; + tenant_snapshot_id_.reset(); + has_unfinished_create_dag_ = false; + has_unfinished_gc_dag_ = false; + clone_ref_ = 0; + meta_existed_ = false; + ls_snapshot_mgr_ = nullptr; + meta_handler_ = nullptr; + } + +public: + int is_valid() const { return tenant_snapshot_id_.is_valid(); } + ObTenantSnapshotID get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + + int load(); + int try_start_create_tenant_snapshot_dag(ObArray& creating_ls_id_arr, + common::ObCurTraceId::TraceId& trace_id); + int try_start_gc_tenant_snapshot_dag(bool &gc_all_tenant_snapshot, + ObArray &gc_ls_id_arr, + common::ObCurTraceId::TraceId& trace_id); + int execute_create_tenant_snapshot_dag(const ObArray &creating_ls_id_arr); + int execute_gc_tenant_snapshot_dag(const bool gc_all_tenant_snapshot, const ObArray &gc_ls_id_arr); + int finish_create_tenant_snapshot_dag(); + int finish_gc_tenant_snapshot_dag(); + + void stop(); + bool is_stopped(); + + int get_tenant_snapshot_vt_info(ObTenantSnapshotVTInfo &info); + int get_ls_snapshot_tablet_meta_entry(const ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry); + + int inc_clone_ref(); + int dec_clone_ref(); + + TO_STRING_KV(K(is_inited_), + K(is_running_), + K(tenant_snapshot_id_), + K(has_unfinished_create_dag_), + K(has_unfinished_gc_dag_), + K(clone_ref_), + K(meta_existed_), + KP(ls_snapshot_mgr_), + KP(meta_handler_)); +private: + template class ForEachFilterFunctor + { + public: + explicit ForEachFilterFunctor(const ObTenantSnapshotID &tenant_snapshot_id, Fn& fn) + : tenant_snapshot_id_(tenant_snapshot_id), fn_(fn) {} + ~ForEachFilterFunctor() {} + bool operator()(const ObLSSnapshotMapKey &snapshot_key, ObLSSnapshot* ls_snapshot); + + private: + const ObTenantSnapshotID tenant_snapshot_id_; + Fn &fn_; + }; + + template class RemoveIfFilterFunctor + { + public: + explicit RemoveIfFilterFunctor(const ObTenantSnapshotID &tenant_snapshot_id, Fn& fn) + : tenant_snapshot_id_(tenant_snapshot_id), fn_(fn) {} + ~RemoveIfFilterFunctor() {} + bool operator()(const ObLSSnapshotMapKey &snapshot_key, ObLSSnapshot* ls_snapshot); + + private: + const ObTenantSnapshotID tenant_snapshot_id_; + Fn &fn_; + }; + template int for_each_(Fn &fn); + template int remove_if_(Fn &fn); + +private: + int clear_meta_snapshot_(); + + int create_dag_start_(); + int create_dag_finish_(); + int gc_dag_start_(); + int gc_dag_finish_(); + void build_all_snapshots_(const ObArray& creating_ls_id_arr); + int build_tenant_snapshot_meta_(); + void build_all_ls_snapshots_(const ObArray& creating_ls_id_arr); + int build_one_ls_snapshot_(const ObLSID& creating_ls_id); + int build_one_ls_snapshot_meta_(ObLSSnapshot* ls_snapshot); + + void report_one_ls_snapshot_build_rlt_(ObLSSnapshot* ls_snapshot, const int ls_ret); + int report_create_ls_snapshot_succ_rlt_(ObLSSnapshot* ls_snapshot); + int report_create_ls_snapshot_fail_rlt_(const ObLSID& ls_id); + + bool has_unfinished_dag_() { return has_unfinished_create_dag_ || has_unfinished_gc_dag_; } + int gc_tenant_snapshot_(); + void notify_ls_snapshots_tenant_gc_(); + int gc_ls_snapshots_(const ObArray &gc_ls_id_arr); + int destroy_all_ls_snapshots_(); + int get_need_gc_ls_snapshot_arr_( + const ObArray& item_arr, + ObArray& gc_ls_id_arr); + +private: + bool is_inited_; + bool is_running_; + ObTenantSnapshotID tenant_snapshot_id_; + + bool has_unfinished_create_dag_; + bool has_unfinished_gc_dag_; + int64_t clone_ref_; + bool meta_existed_; + ObLSSnapshotMgr* ls_snapshot_mgr_; + + ObTenantMetaSnapshotHandler* meta_handler_; + lib::ObMutex mutex_; +}; + +} +} +#endif diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_meta_table.cpp b/src/storage/tenant_snapshot/ob_tenant_snapshot_meta_table.cpp new file mode 100644 index 0000000000..2ff09b631e --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_meta_table.cpp @@ -0,0 +1,359 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h" + +namespace oceanbase +{ +namespace storage +{ + +void ObLSSnapshotBuildCtxVTInfo::reset() +{ + build_status_.reset(); + rebuild_seq_start_ = 0; + rebuild_seq_end_ = 0; + ls_meta_package_.reset(); + end_interval_scn_.reset(); +} + +void ObTenantSnapshotVTInfo::reset() +{ + tsnap_is_running_ = false; + tsnap_has_unfinished_create_dag_ = false; + tsnap_has_unfinished_gc_dag_ = false; + tsnap_clone_ref_ = 0; + tsnap_meta_existed_ = false; +} + +void ObLSSnapshotVTInfo::reset() +{ + ls_id_.reset(); + tenant_snapshot_id_.reset(); + meta_existed_ = false; + has_build_ctx_ = false; + build_ctx_info_.reset(); + has_tsnap_info_ = false; + tsnap_info_.reset(); +} + +bool ObLSSnapshotReportInfo::is_valid() const +{ + bool b_ret = ls_id_.is_valid(); + if (is_creating_succ_) { + b_ret = b_ret && + end_interval_scn_.is_valid() && + begin_interval_scn_.is_valid() && + end_interval_scn_ >= begin_interval_scn_ && + ls_meta_package_ != nullptr && ls_meta_package_->is_valid(); + } + return b_ret; +} + +void ObLSSnapshotReportInfo::to_failed() +{ + is_creating_succ_ = false; + begin_interval_scn_.reset(); + end_interval_scn_.reset(); + ls_meta_package_ = nullptr; +} + +void ObLSSnapshotReportInfo::to_success(const SCN& begin_interval_scn, + const SCN& end_interval_scn, + const ObLSMetaPackage* ls_meta_package) +{ + is_creating_succ_ = true; + begin_interval_scn_ = begin_interval_scn; + end_interval_scn_ = end_interval_scn; + ls_meta_package_ = ls_meta_package; +} + +bool ObLSSnapshotReportInfo::scn_range_is_valid(const ObTenantSnapItem &tenant_snap_item) const +{ + int ret = OB_SUCCESS; + bool bret = true; + + if ((ObTenantSnapStatus::RESTORING == tenant_snap_item.get_status() || + ObTenantSnapStatus::NORMAL == tenant_snap_item.get_status())) { + if (begin_interval_scn_ < tenant_snap_item.get_clog_start_scn() || + end_interval_scn_ > tenant_snap_item.get_snapshot_scn()) { + ret = OB_BEYOND_THE_RANGE; + bret = false; + } + } + return bret; +} + +void ObTenantSnapshotSvrInfo::reset() +{ + tenant_snap_item_.reset(); + ls_snap_item_arr_.reset(); +} + +int ObTenantSnapshotSvrInfo::get_creating_ls_id_arr(common::ObArray& creating_ls_id_arr) +{ + int ret = OB_SUCCESS; + + creating_ls_id_arr.reset(); + for (int64_t i = 0; OB_SUCC(ret) && i < ls_snap_item_arr_.count(); ++i) { + if (ObLSSnapStatus::CREATING == ls_snap_item_arr_[i].get_status()) { + if(OB_FAIL(creating_ls_id_arr.push_back(ls_snap_item_arr_[i].get_ls_id()))) { + LOG_WARN("creating_ls_id_arr push back failed", KR(ret), KPC(this)); + } + } + } + + return ret; +} + +int ObTenantSnapshotMetaTable::report_create_ls_snapshot_rlt(const ObTenantSnapshotID& tenant_snapshot_id, + ObLSSnapshotReportInfo& info) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + + ObTenantSnapItem tenant_snap_item; + ObMySQLTransaction trans; + ObTenantSnapshotTableOperator table_operator; + ObTenantSnapLSReplicaSimpleItem ls_snap_replica_item; + + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant snapshot id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (!info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObLSSnapshotReportInfo is not valid", KR(ret), K(info)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, gen_meta_tenant_id(tenant_id)))) { + LOG_WARN("trans start failed", KR(ret)); + } else if (OB_FAIL(table_operator.init(tenant_id, &trans))) { + LOG_WARN("fail to init operator", KR(ret)); + } else if (OB_FAIL(table_operator.get_tenant_snap_item(tenant_snapshot_id, + true /*need lock*/, + tenant_snap_item))) { + LOG_WARN("fail to get tenant snapshot item", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(table_operator.get_tenant_snap_ls_replica_simple_item(tenant_snapshot_id, + info.get_ls_id(), + GCTX.self_addr(), + true, + ls_snap_replica_item))) { + LOG_WARN("fail to get_tenant_snap_ls_replica_simple_item", + KR(ret), K(tenant_snapshot_id), K(GCTX.self_addr()), K(info)); + } else if (ObTenantSnapStatus::DELETING == tenant_snap_item.get_status()) { + ret = OB_TENANT_SNAPSHOT_NOT_EXIST; + LOG_WARN("tenant snapshot is already in deleting status, do not need to be reported", + KR(ret), K(tenant_snapshot_id), K(tenant_snap_item)); + } else if (ObLSSnapStatus::NORMAL == ls_snap_replica_item.get_status()) { + LOG_INFO("ls snapshot is already in normal status, do not need to be reported", + K(tenant_snapshot_id), K(info), K(ls_snap_replica_item)); + } else if (ObLSSnapStatus::CREATING != ls_snap_replica_item.get_status()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("ls snapshot status not match", + KR(ret), K(tenant_snapshot_id), K(info), K(ls_snap_replica_item)); + } else { + // TODO: Currently, how to get the maximum scn in ObLSMetaPackage has not yet been solved; + if (info.is_creating_succ()) { + if (tenant_snap_item.get_status() != ObTenantSnapStatus::CREATING && + // ls_snap_replica_item.status condition will definitely be true, + // just to enhance the check; + ObLSSnapStatus::NORMAL != ls_snap_replica_item.get_status()) { + LOG_WARN("local snapshot was created successfully, but the tenant snapshot status" + " in the meta table is not creating", K(info), K(tenant_snap_item)); + info.to_failed(); + } + } + + if (OB_FAIL(update_ls_snap_replica_item_(info, ls_snap_replica_item))) { + LOG_WARN("fail to update_ls_snap_replica_item_", + KR(ret), K(tenant_snapshot_id), K(info), K(ls_snap_replica_item)); + } else if (OB_FAIL(table_operator.update_tenant_snap_ls_replica_item(ls_snap_replica_item, + info.get_ls_meta_package()))) { + LOG_WARN("fail to update_tenant_snap_ls_replica_item", + KR(ret), K(tenant_snapshot_id), K(info), K(ls_snap_replica_item)); + } + } + + const bool need_commit = OB_SUCC(ret); + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(need_commit))) { + LOG_WARN("trans end failed", K(need_commit), KR(tmp_ret), KR(ret)); + ret = need_commit ? tmp_ret : ret; + } + } + return ret; +} + +int ObTenantSnapshotMetaTable::update_ls_snap_replica_item_(const ObLSSnapshotReportInfo& info, + ObTenantSnapLSReplicaSimpleItem& item) +{ + int ret = OB_SUCCESS; + + if (!info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObLSSnapshotReportInfo is not valid", KR(ret), K(info)); + } else if (!item.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObTenantSnapLSReplicaSimpleItem is not valid", KR(ret), K(item)); + } else { + item.set_status(info.is_creating_succ() ? ObLSSnapStatus::NORMAL : ObLSSnapStatus::FAILED); + item.set_begin_interval_scn(info.get_begin_interval_scn()); + item.set_end_interval_scn(info.get_end_interval_scn()); + } + + return ret; +} + +int ObTenantSnapshotMetaTable::acquire_tenant_snapshot_svr_info(const ObTenantSnapshotID& tenant_snapshot_id, + ObTenantSnapshotSvrInfo& svr_info) +{ + int ret = OB_SUCCESS; + ObMySQLTransaction trans; + ObTenantSnapshotTableOperator table_operator; + const uint64_t tenant_id = MTL_ID(); + + svr_info.reset(); + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant snapshot id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(trans.start(GCTX.sql_proxy_, gen_meta_tenant_id(tenant_id)))) { + LOG_WARN("trans start failed", KR(ret)); + } else if (OB_FAIL(table_operator.init(tenant_id, &trans))) { + LOG_WARN("fail to init operator", KR(ret)); + } else if (OB_FAIL(table_operator.get_tenant_snap_item(tenant_snapshot_id, + true /*need lock*/, + svr_info.get_tenant_snap_item()))) { + LOG_WARN("fail to get snapshot item", KR(ret), K(tenant_snapshot_id)); + } else if (ObTenantSnapStatus::DELETING == svr_info.get_tenant_snap_item_const().get_status()) { + LOG_INFO("tenant snapshot is deleting", KR(ret), K(tenant_snapshot_id), K(svr_info)); + } else if (OB_FAIL(table_operator.get_tenant_snap_ls_replica_simple_items(tenant_snapshot_id, + GCTX.self_addr(), + svr_info.get_ls_snap_item_arr()))) { + LOG_WARN("fail to get_tenant_snap_ls_replica_simple_items", KR(ret), + K(GCTX.self_addr()), K(tenant_snapshot_id)); + } + + if (trans.is_started()) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(trans.end(false))) { + LOG_WARN("trans abort failed", KR(tmp_ret)); + } + } + + return ret; +} + +int ObTenantSnapshotMetaTable::acquire_all_tenant_snapshots(ObArray& item_arr) +{ + int ret = OB_SUCCESS; + + const uint64_t tenant_id = MTL_ID(); + + ObMySQLProxy *sql_client = GCTX.sql_proxy_; + ObTenantSnapshotTableOperator table_operator; + + item_arr.reset(); + if (OB_FAIL(table_operator.init(tenant_id, sql_client))) { + LOG_WARN("fail to init operator", KR(ret)); + } else if (OB_FAIL(table_operator.get_all_user_tenant_snap_items(item_arr))){ + LOG_WARN("fail to get_all_user_tenant_snap_items", KR(ret)); + } + + return ret; +} + +void ObTenantSnapshotMetaTable::acquire_tenant_snapshot_trace_id(const ObTenantSnapshotID &tenant_snapshot_id, + const ObTenantSnapOperation operation, + common::ObCurTraceId::TraceId& trace_id) +{ + int ret = OB_SUCCESS; + + trace_id.reset(); + + ObTenantSnapJobItem job_item; + const uint64_t tenant_id = MTL_ID(); + + ObMySQLProxy *sql_client = GCTX.sql_proxy_; + ObTenantSnapshotTableOperator table_operator; + + if (OB_FAIL(table_operator.init(tenant_id, sql_client))) { + LOG_WARN("fail to init operator", KR(ret)); + } else if (OB_FAIL(table_operator.get_tenant_snap_job_item(tenant_snapshot_id, operation, job_item))) { + if (ret != OB_ENTRY_NOT_EXIST) { + LOG_WARN("fail to get tenant snapshot job item", KR(ret), K(tenant_snapshot_id), K(operation)); + } + } else if (!job_item.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("job item is not valid", KR(ret), K(tenant_snapshot_id), K(operation), K(job_item)); + } + + if (OB_SUCC(ret)) { + trace_id = job_item.get_trace_id(); + } else { + trace_id.init(GCTX.self_addr()); + } +} + +int ObTenantSnapshotMetaTable::acquire_clone_ls_meta_package(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + ObLSMetaPackage& ls_meta_package) +{ + int ret = OB_SUCCESS; + + const uint64_t tenant_id = MTL_ID(); + ls_meta_package.reset(); + + share::SCN clog_checkpoint_scn; + palf::LSN clog_base_lsn; + ObTenantSnapshotTableOperator snap_op; + + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant snapshot id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls id is not valid", KR(ret), K(ls_id), K(tenant_snapshot_id)); + } else if (OB_FAIL(snap_op.init(tenant_id, GCTX.sql_proxy_))) { + LOG_WARN("fail to init snap op", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (OB_FAIL(snap_op.get_proper_ls_meta_package(tenant_snapshot_id, + ls_id, + ls_meta_package))) { + LOG_WARN("fail to get proper ls meta package", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (!ls_meta_package.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("min checkpoint ls replica's ls_meta_package is not valid", + KR(ret), K(ls_meta_package), K(tenant_snapshot_id), K(ls_id)); + } else if (FALSE_IT(clog_checkpoint_scn = ls_meta_package.ls_meta_.get_clog_checkpoint_scn())) { + } else if (FALSE_IT(clog_base_lsn = ls_meta_package.ls_meta_.get_clog_base_lsn())) { + } else if (FALSE_IT(ls_meta_package.reset())) { + } else if (OB_FAIL(snap_op.get_ls_meta_package(tenant_snapshot_id, + ls_id, + GCTX.self_addr(), + ls_meta_package))) { + LOG_WARN("fail to get ls meta package", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (!ls_meta_package.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("this ls replica's ls_meta_package is not valid", + KR(ret), K(ls_meta_package), K(tenant_snapshot_id), K(ls_id)); + } else { + ls_meta_package.update_clog_checkpoint_in_ls_meta(clog_checkpoint_scn, clog_base_lsn); + } + + if (OB_FAIL(ret)) { + ls_meta_package.reset(); + } + + return ret; +} + +} +} diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h b/src/storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h new file mode 100644 index 0000000000..feb466e359 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h @@ -0,0 +1,230 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_META_TABLE_ +#define OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_META_TABLE_ + +#include "lib/container/ob_iarray.h" +#include "lib/mysqlclient/ob_mysql_proxy.h" +#include "storage/ls/ob_ls.h" +#include "lib/hash/ob_hashset.h" +#include "share/tenant_snapshot/ob_tenant_snapshot_table_operator.h" + +namespace oceanbase +{ +namespace storage +{ + +struct ObLSSnapshotBuildCtxVTInfo +{ +public: + ObLSSnapshotBuildCtxVTInfo() : build_status_(), + rebuild_seq_start_(0), + rebuild_seq_end_(0), + ls_meta_package_(), + end_interval_scn_() {} + void reset(); + + void set_build_status(const common::ObString &build_status) { build_status_ = build_status; } + void set_rebuild_seq_start(int64_t rebuild_seq_start) { rebuild_seq_start_ = rebuild_seq_start; } + void set_rebuild_seq_end(int64_t rebuild_seq_end) { rebuild_seq_end_ = rebuild_seq_end; } + void set_ls_meta_package(const ObLSMetaPackage &ls_meta_package) { ls_meta_package_ = ls_meta_package; } + void set_end_interval_scn(const share::SCN &end_interval_scn) { end_interval_scn_ = end_interval_scn_; } + + const common::ObString &get_build_status() { return build_status_; } + int64_t get_rebuild_seq_start() const { return rebuild_seq_start_; } + int64_t get_rebuild_seq_end() const { return rebuild_seq_end_; } + + ObLSMetaPackage &get_ls_meta_package() { return ls_meta_package_; } + share::SCN get_end_interval_scn() const { return end_interval_scn_; } + + TO_STRING_KV(K(build_status_),K(rebuild_seq_start_), K(rebuild_seq_end_), + K(ls_meta_package_),K(end_interval_scn_)); +private: + common::ObString build_status_; + int64_t rebuild_seq_start_; + int64_t rebuild_seq_end_; + ObLSMetaPackage ls_meta_package_; // copy ls_meta_package + share::SCN end_interval_scn_; +}; + +struct ObTenantSnapshotVTInfo +{ +public: + ObTenantSnapshotVTInfo() : tsnap_is_running_(false), + tsnap_has_unfinished_create_dag_(false), + tsnap_clone_ref_(0), + tsnap_meta_existed_(false) {} + void reset(); + + void set_tsnap_is_running(bool tsnap_is_running) { tsnap_is_running_ = tsnap_is_running; } + void set_tsnap_has_unfinished_create_dag(bool tsnap_has_unfinished_create_dag) + { + tsnap_has_unfinished_create_dag_ = tsnap_has_unfinished_create_dag; + } + void set_tsnap_has_unfinished_gc_dag(bool tsnap_has_unfinished_gc_dag) + { + tsnap_has_unfinished_gc_dag_ = tsnap_has_unfinished_gc_dag; + } + void set_tsnap_clone_ref(int64_t tsnap_clone_ref) { tsnap_clone_ref_ = tsnap_clone_ref; } + void set_tsnap_meta_existed(bool tsnap_meta_existed) { tsnap_meta_existed_ = tsnap_meta_existed; } + + bool get_tsnap_is_running() const { return tsnap_is_running_; } + bool get_tsnap_has_unfinished_create_dag() const { return tsnap_has_unfinished_create_dag_; } + bool get_tsnap_has_unfinished_gc_dag() const { return tsnap_has_unfinished_gc_dag_; } + int64_t get_tsnap_clone_ref() const { return tsnap_clone_ref_; } + bool get_tsnap_meta_existed() const { return tsnap_meta_existed_; } + + TO_STRING_KV(K(tsnap_is_running_), K(tsnap_has_unfinished_create_dag_), + K(tsnap_has_unfinished_gc_dag_), K(tsnap_clone_ref_), K(tsnap_meta_existed_)); +private: + bool tsnap_is_running_; + bool tsnap_has_unfinished_create_dag_; + bool tsnap_has_unfinished_gc_dag_; + int64_t tsnap_clone_ref_; + bool tsnap_meta_existed_; +}; + +// info collection of ObLSSnapshot(for vtable) +struct ObLSSnapshotVTInfo +{ +public: + ObLSSnapshotVTInfo () : ls_id_(), + tenant_snapshot_id_(), + meta_existed_(false), + has_build_ctx_(false), + has_tsnap_info_(false) {} + void reset(); + + void set_ls_id(share::ObLSID ls_id) { ls_id_ = ls_id; } + void set_tenant_snapshot_id(const share::ObTenantSnapshotID &tenant_snapshot_id) + { + tenant_snapshot_id_ = tenant_snapshot_id; + } + void set_meta_existed(bool meta_existed) { meta_existed_ = meta_existed; } + void set_has_build_ctx(bool has_build_ctx) { has_build_ctx_ = has_build_ctx; } + void set_build_ctx_info(ObLSSnapshotBuildCtxVTInfo &build_ctx_info) { build_ctx_info = build_ctx_info; } + void set_has_tsnap_info(bool has_tsnap_info) { has_tsnap_info_ = has_tsnap_info; } + void set_tsnap_info(ObTenantSnapshotVTInfo &tsnap_info) { tsnap_info_ = tsnap_info; } + + share::ObLSID get_ls_id() const { return ls_id_; } + share::ObTenantSnapshotID get_tenant_snapshot_id() const { return tenant_snapshot_id_; } + bool get_meta_existed() const { return meta_existed_; } + bool get_has_build_ctx() const { return has_build_ctx_; } + ObLSSnapshotBuildCtxVTInfo &get_build_ctx_info() { return build_ctx_info_; } + bool get_has_tsnap_info() const { return has_tsnap_info_; } + ObTenantSnapshotVTInfo &get_tsnap_info() { return tsnap_info_; } + + TO_STRING_KV(K(ls_id_), K(tenant_snapshot_id_), K(meta_existed_), + K(has_build_ctx_), K(build_ctx_info_), + K(has_tsnap_info_), K(tsnap_info_)); +private: + share::ObLSID ls_id_; + share::ObTenantSnapshotID tenant_snapshot_id_; + bool meta_existed_; + + bool has_build_ctx_; // flag to indicate whether carries build_ctx info, not show in vtable + ObLSSnapshotBuildCtxVTInfo build_ctx_info_; + + bool has_tsnap_info_; // flag to indicate whether carries tenant snapshot info, not show in vtable + ObTenantSnapshotVTInfo tsnap_info_; +}; + +class ObLSSnapshotReportInfo +{ +public: + ObLSSnapshotReportInfo(const share::ObLSID& ls_id): ls_id_(ls_id), + is_creating_succ_(false), + begin_interval_scn_(), + end_interval_scn_(), + ls_meta_package_(nullptr) {} + bool is_valid() const; + void to_failed(); + void to_success(const share::SCN& begin_interval_scn, + const share::SCN& end_interval_scn, + const ObLSMetaPackage* ls_meta_package); + bool scn_range_is_valid(const ObTenantSnapItem &tenant_snap_item) const; + +public: + TO_STRING_KV(K(ls_id_), + K(is_creating_succ_), + K(begin_interval_scn_), + K(end_interval_scn_), + KPC(ls_meta_package_)); + +public: + share::ObLSID get_ls_id() const { return ls_id_; } + bool is_creating_succ() const { return is_creating_succ_; } + share::SCN get_begin_interval_scn() const { return begin_interval_scn_; } + share::SCN get_end_interval_scn() const { return end_interval_scn_; } + const ObLSMetaPackage* get_ls_meta_package() const { return ls_meta_package_; } +private: + share::ObLSID ls_id_; + bool is_creating_succ_; + share::SCN begin_interval_scn_; + share::SCN end_interval_scn_; + const ObLSMetaPackage* ls_meta_package_; +}; + +class ObTenantSnapshotSvrInfo +{ +public: + ObTenantSnapshotSvrInfo() : tenant_snap_item_(), + ls_snap_item_arr_() {} + + void reset(); + int get_creating_ls_id_arr(common::ObArray& creating_ls_id_arr); +public: + TO_STRING_KV(K(tenant_snap_item_), K(ls_snap_item_arr_)); + +public: + share::ObTenantSnapItem& get_tenant_snap_item() { return tenant_snap_item_; } + const share::ObTenantSnapItem& get_tenant_snap_item_const() const { return tenant_snap_item_; } + + common::ObArray& get_ls_snap_item_arr() { + return ls_snap_item_arr_; + } + const common::ObArray& get_ls_snap_item_arr_const() const { + return ls_snap_item_arr_; + } +private: + share::ObTenantSnapItem tenant_snap_item_; + common::ObArray ls_snap_item_arr_; +}; + +class ObTenantSnapshotMetaTable +{ +public: + static int report_create_ls_snapshot_rlt(const share::ObTenantSnapshotID& tenant_snapshot_id, + ObLSSnapshotReportInfo& info); + + static int acquire_tenant_snapshot_svr_info(const share::ObTenantSnapshotID& tenant_snapshot_id, + ObTenantSnapshotSvrInfo& svr_info); + + static int acquire_all_tenant_snapshots(common::ObArray& item_arr); + + static int acquire_clone_ls_meta_package(const share::ObTenantSnapshotID &tenant_snapshot_id, + const share::ObLSID &ls_id, + ObLSMetaPackage& ls_meta_package); + + static void acquire_tenant_snapshot_trace_id(const share::ObTenantSnapshotID &tenant_snapshot_id, + const share::ObTenantSnapOperation operation, + common::ObCurTraceId::TraceId& trace_id); +private: + static int update_ls_snap_replica_item_(const ObLSSnapshotReportInfo& info, + share::ObTenantSnapLSReplicaSimpleItem& item); + +}; + +} +} +#endif diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_mgr.cpp b/src/storage/tenant_snapshot/ob_tenant_snapshot_mgr.cpp new file mode 100644 index 0000000000..203bac5e83 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_mgr.cpp @@ -0,0 +1,297 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "storage/tenant_snapshot/ob_ls_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_mgr.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_mgr.h" + +namespace oceanbase +{ +namespace storage +{ + +int ObTenantSnapshotMgr::init(ObLSSnapshotMgr* ls_snapshot_mgr, + ObTenantMetaSnapshotHandler* meta_handler) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + + if (OB_UNLIKELY(IS_INIT)) { + ret = OB_INIT_TWICE; + LOG_WARN("ob_tenant_snapshot_mgr has inited", KR(ret)); + } else if (OB_ISNULL(ls_snapshot_mgr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_snapshot_mgr is nullptr", KR(ret)); + } else if (OB_ISNULL(meta_handler)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("meta_handler is nullptr", KR(ret)); + } else if (OB_FAIL(tenant_snapshot_map_.init("TSMap", tenant_id))) { + LOG_WARN("fail to init tenant snapshot map", KR(ret)); + } else { + ls_snapshot_mgr_ = ls_snapshot_mgr; + meta_handler_ = meta_handler; + is_inited_ = true; + LOG_INFO("tenant snapshot manager thread init succ", KPC(this)); + } + + return ret; +} + +class ObTenantSnapshotStopFunctor +{ +public: + bool operator()(const ObTenantSnapshotID &tenant_snapshot_id, ObTenantSnapshot* tenant_snapshot) + { + int ret = OB_SUCCESS; + + if (!tenant_snapshot_id.is_valid() || OB_ISNULL(tenant_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), KP(tenant_snapshot)); + } else { + tenant_snapshot->stop(); + } + return true; + } +}; + +void ObTenantSnapshotMgr::stop() +{ + int ret = OB_SUCCESS; + ObTenantSnapshotStopFunctor fn; + if (OB_FAIL(tenant_snapshot_map_.for_each(fn))) { + LOG_ERROR("fail to tenant snapshot stop", KR(ret)); + } +} + +class ObTenantSnapshotDestroyFunctor +{ +public: + bool operator()(const ObTenantSnapshotID &tenant_snapshot_id, ObTenantSnapshot* tenant_snapshot) + { + int ret = OB_SUCCESS; + bool bool_ret = false; + + if (!tenant_snapshot_id.is_valid() || OB_ISNULL(tenant_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), KP(tenant_snapshot)); + } else { + tenant_snapshot->destroy(); + bool_ret = true; + } + return bool_ret; + } +}; + +void ObTenantSnapshotMgr::destroy() +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ObTenantSnapshotDestroyFunctor fn; + tenant_snapshot_map_.remove_if(fn); + + int64_t value_cnt = tenant_snapshot_map_.get_alloc_handle().get_value_cnt(); + if (0 != value_cnt) { + LOG_ERROR("tenant snapshot value cnt is not zero, memory leak", K(value_cnt)); + } + + int64_t map_cnt = tenant_snapshot_map_.count(); + if (0 == map_cnt) { + tenant_snapshot_map_.destroy(); + LOG_INFO("tenant snapshot mgr destroy succ"); + } else { + LOG_ERROR("tenant snapshot map cnt is not zero", K(map_cnt)); + } + + is_inited_ = false; + } +} + +int ObTenantSnapshotMgr::get_tenant_snapshot(const ObTenantSnapshotID &tenant_snapshot_id, + ObTenantSnapshot *&tenant_snapshot) +{ + int ret = OB_SUCCESS; + ObTenantSnapshot *tmp_tenant_snapshot = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotMgr has not been inited.", KR(ret), KPC(this)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is invalid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(tenant_snapshot_map_.get(tenant_snapshot_id, tmp_tenant_snapshot))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_TENANT_SNAPSHOT_NOT_EXIST; + } else { + LOG_WARN("fail to get tenant_snapshot", KR(ret), K(tenant_snapshot_id)); + } + } else if (OB_ISNULL(tmp_tenant_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tmp_tenant_snapshot is nullptr", KR(ret), K(tenant_snapshot_id)); + } else { + tenant_snapshot = tmp_tenant_snapshot; + } + + return ret; +} + +int ObTenantSnapshotMgr::acquire_tenant_snapshot(const ObTenantSnapshotID &tenant_snapshot_id, + ObTenantSnapshot *&tenant_snapshot) +{ + int ret = OB_SUCCESS; + ObTenantSnapshot *tmp_tenant_snapshot = nullptr; + bool is_existed = false; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotMgr has not been inited.", KR(ret), KPC(this)); + } else if (OB_UNLIKELY(!tenant_snapshot_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is invalid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(get_tenant_snapshot(tenant_snapshot_id, tmp_tenant_snapshot))) { + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + ret = OB_SUCCESS; + is_existed = false; + } else { + LOG_WARN("fail to get tenant snapshot", KR(ret), K(tenant_snapshot_id)); + } + } else { + tenant_snapshot = tmp_tenant_snapshot; + is_existed = true; + } + + if (OB_SUCC(ret) && !is_existed) { + if (OB_FAIL(create_tenant_snapshot_(tenant_snapshot_id, tmp_tenant_snapshot))) { + if (OB_ENTRY_EXIST == ret) { + LOG_INFO("create a existed tenant snapshot, maybe some concurrent request is processed", + KR(ret), K(tenant_snapshot_id)); + } else { + LOG_WARN("fail to create tenant snapshot", KR(ret), K(tenant_snapshot_id)); + } + } else { + tenant_snapshot = tmp_tenant_snapshot; + } + } + + return ret; +} + +int ObTenantSnapshotMgr::revert_tenant_snapshot(ObTenantSnapshot *tenant_snapshot) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotMgr has not been inited", KR(ret), KPC(this)); + } else if (OB_ISNULL(tenant_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant snapshot is nullptr", KR(ret)); + } else { + tenant_snapshot_map_.revert(tenant_snapshot); + } + return ret; +} + +int ObTenantSnapshotMgr::create_tenant_snapshot_(const ObTenantSnapshotID &tenant_snapshot_id, + ObTenantSnapshot *&tenant_snapshot) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + + ObTenantSnapshot* tmp_tenant_snapshot = nullptr; + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is invalid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(tenant_snapshot_map_.alloc_value(tmp_tenant_snapshot))) { + LOG_WARN("failed to alloc tenant snapshot", KR(ret)); + } else if (OB_ISNULL(tmp_tenant_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to alloc tenant snapshot", KR(ret)); + } else if (OB_FAIL(tmp_tenant_snapshot->init(tenant_snapshot_id, ls_snapshot_mgr_, meta_handler_))) { + LOG_WARN("failed to init tenant snapshot", KR(ret), KPC(this)); + } else if (OB_FAIL(tenant_snapshot_map_.insert_and_get(tenant_snapshot_id, tmp_tenant_snapshot))) { + if (OB_ENTRY_EXIST == ret) { + LOG_INFO("create a existed tenant snapshot, maybe some concurrent request is processed", + KR(ret), K(tenant_snapshot_id)); + } else { + LOG_WARN("failed to insert_and_get tenant snapshot", KR(ret), K(tenant_snapshot_id)); + } + } else { + tenant_snapshot = tmp_tenant_snapshot; + } + + if (OB_FAIL(ret) && tmp_tenant_snapshot != nullptr) { + tenant_snapshot_map_.free_value(tmp_tenant_snapshot); + } + return ret; +} + +int ObTenantSnapshotMgr::del_tenant_snapshot(const ObTenantSnapshotID& tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is invalid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(tenant_snapshot_map_.del(tenant_snapshot_id))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_ERROR("del from map failed", KR(ret), K(tenant_snapshot_id)); + } + } + + return ret; +} + +class ObCheckTenantSnapshotStoppedFunctor +{ +public: + ObCheckTenantSnapshotStoppedFunctor() : has_stopped_tenant_snapshot_(false) {} + ~ObCheckTenantSnapshotStoppedFunctor() {} + + bool operator()(const ObTenantSnapshotID &tenant_snapshot_id, ObTenantSnapshot* tenant_snapshot) + { + int ret = OB_SUCCESS; + + if (!tenant_snapshot_id.is_valid() || OB_ISNULL(tenant_snapshot)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_snapshot_id), KP(tenant_snapshot)); + } else { + if (tenant_snapshot->is_stopped()) { + has_stopped_tenant_snapshot_ = true; + } + } + return true; + } +public: + bool has_stopped_tenant_snapshot_; +}; + +int ObTenantSnapshotMgr::has_tenant_snapshot_stopped(bool& has_tenant_snapshot_stopped) +{ + int ret = OB_SUCCESS; + + ObCheckTenantSnapshotStoppedFunctor fn; + + if (OB_FAIL(tenant_snapshot_map_.for_each(fn))) { + LOG_ERROR("fail to check tenant snapshot is stopped", KR(ret)); + } else { + has_tenant_snapshot_stopped = fn.has_stopped_tenant_snapshot_; + } + return ret; +} + +} +} diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_mgr.h b/src/storage/tenant_snapshot/ob_tenant_snapshot_mgr.h new file mode 100644 index 0000000000..0cf8dffb05 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_mgr.h @@ -0,0 +1,124 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_MGR_ +#define OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_MGR_ + +#include "share/tenant_snapshot/ob_tenant_snapshot_id.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_defs.h" + +namespace oceanbase +{ +namespace storage +{ + +class ObLSSnapshotMgr; + +typedef common::LinkHashNode ObTenantSnapshotNode; +class ObTenantSnapshotHashAlloc +{ +public: + ObTenantSnapshotHashAlloc() : value_cnt_(0) {} + ~ObTenantSnapshotHashAlloc() { value_cnt_ = 0; } + + ObTenantSnapshotHashAlloc(const ObTenantSnapshotHashAlloc* other) : + value_cnt_(other->value_cnt_) { } + + ObTenantSnapshot* alloc_value() + { + ObMemAttr memattr(MTL_ID(), "TenantSnapshot"); + ObTenantSnapshot* tenant_snapshot = OB_NEW(ObTenantSnapshot, memattr); + if (OB_NOT_NULL(tenant_snapshot)) { + ATOMIC_INC(&value_cnt_); + } + return tenant_snapshot; + } + void free_value(ObTenantSnapshot* snapshot) + { + if (NULL != snapshot) { + ObMemAttr memattr(MTL_ID(), "TenantSnapshot"); + OB_DELETE(ObTenantSnapshot, memattr, snapshot); + ATOMIC_DEC(&value_cnt_); + } + } + ObTenantSnapshotNode* alloc_node(ObTenantSnapshot* snapshot) + { + UNUSED(snapshot); + ObMemAttr memattr(MTL_ID(), "TSNode"); + return OB_NEW(ObTenantSnapshotNode, memattr); + } + void free_node(ObTenantSnapshotNode* node) + { + if (NULL != node) { + ObMemAttr memattr(MTL_ID(), "TSNode"); + OB_DELETE(ObTenantSnapshotNode, memattr, node); + node = NULL; + } + } + + int64_t get_value_cnt() const { return ATOMIC_LOAD(&value_cnt_); } + +private: + int64_t value_cnt_; +}; + +typedef common::ObLinkHashMap ObTenantSnapshotMap; + +class ObTenantSnapshotMgr +{ +public: + ObTenantSnapshotMgr() + : is_inited_(false), + ls_snapshot_mgr_(nullptr), + meta_handler_(nullptr), + tenant_snapshot_map_() {} + + virtual ~ObTenantSnapshotMgr() {} + + int init(ObLSSnapshotMgr* ls_snapshot_mgr, ObTenantMetaSnapshotHandler* meta_handler); + void stop(); + void destroy(); + +public: + int get_tenant_snapshot(const share::ObTenantSnapshotID &tenant_snapshot_id, + ObTenantSnapshot *&tenant_snapshot); + + int acquire_tenant_snapshot(const share::ObTenantSnapshotID &tenant_snapshot_id, + ObTenantSnapshot *&tenant_snapshot); + + int has_tenant_snapshot_stopped(bool& has_tenant_snapshot_stopped); + + int revert_tenant_snapshot(ObTenantSnapshot *tenant_snapshot); + + int del_tenant_snapshot(const share::ObTenantSnapshotID& tenant_snapshot_id); + + template int for_each(Fn &fn) { return tenant_snapshot_map_.for_each(fn); } + template int remove_if(Fn &fn) { return tenant_snapshot_map_.remove_if(fn); } + +private: + int create_tenant_snapshot_(const share::ObTenantSnapshotID &tenant_snapshot_id, + ObTenantSnapshot *&tenant_snapshot); + +private: + bool is_inited_; + ObLSSnapshotMgr *ls_snapshot_mgr_; + ObTenantMetaSnapshotHandler* meta_handler_; + ObTenantSnapshotMap tenant_snapshot_map_; +public: + TO_STRING_KV(K(is_inited_)); +}; + +} +} + +#endif diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_service.cpp b/src/storage/tenant_snapshot/ob_tenant_snapshot_service.cpp new file mode 100644 index 0000000000..5ebf554493 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_service.cpp @@ -0,0 +1,826 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE +#include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" +#include "storage/tx_storage/ob_ls_map.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_service.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_task.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h" +#include "lib/lock/mutex.h" + +namespace oceanbase +{ +using namespace share; +namespace storage +{ + +ObTenantSnapshotService::ObTenantSnapshotService() + : is_inited_(false), + is_running_(false), + meta_loaded_(false), + tenant_snapshot_mgr_(), + ls_snapshot_mgr_(), + meta_handler_(), + cond_(), + tg_id_(INT32_MAX), + running_mode_(RUNNING_MODE::INVALID), + clone_service_() +{} + +ObTenantSnapshotService::~ObTenantSnapshotService() { } + +int ObTenantSnapshotService::mtl_init(ObTenantSnapshotService* &service) +{ + return service->init(); +} + +int ObTenantSnapshotService::init() +{ + int ret = OB_SUCCESS; + + const uint64_t tenant_id = MTL_ID(); + + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTenantSnapshotService is already inited", KR(ret), KPC(this)); + } else if (!is_valid_tenant_id(tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("virtual tenant do not need ObTenantSnapshotService"); + } else if (OB_FAIL(clone_service_.init(&meta_handler_))) { + LOG_WARN("fail to init clone service", KR(ret), KPC(this)); + } else if (OB_FAIL(ls_snapshot_mgr_.init(&meta_handler_))) { + LOG_WARN("fail to init ls snapshot mgr", KR(ret), KPC(this)); + } else if (OB_FAIL(tenant_snapshot_mgr_.init(&ls_snapshot_mgr_, &meta_handler_))) { + LOG_WARN("fail to init tenant snapshot mgr", KR(ret), KPC(this)); + } else if (OB_FAIL(cond_.init(ObWaitEventIds::TENANT_SNAPSHOT_SERVICE_COND_WAIT))) { + LOG_WARN("fail to init TENANT_SNAPSHOT_SERVICE_COND_WAIT", KR(ret), KPC(this)); + } else if (OB_FAIL(TG_CREATE_TENANT(lib::TGDefIDs::TSnapSvc, tg_id_))) { + LOG_ERROR("fail to create tenant snapshot service thread", KR(ret), KPC(this)); + } else if (OB_FAIL(TG_SET_RUNNABLE(tg_id_, *this))) { + LOG_ERROR("fail to set tenant snapshot service thread runnable", KR(ret), KPC(this)); + } else { + meta_loaded_ = false; + running_mode_ = RUNNING_MODE::INVALID; + is_inited_ = true; + } + + return ret; +} + +void ObTenantSnapshotService::destroy() +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + LOG_INFO("ObTenantSnapshotService::destroy start"); + + if (is_running_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObTenantSnapshotService is still running when destroy function called", + KR(ret), KPC(this)); + } + if (OB_SUCC(ret)) { + TG_DESTROY(tg_id_); + tenant_snapshot_mgr_.destroy(); + ls_snapshot_mgr_.destroy(); + is_inited_ = false; + } + LOG_INFO("ObTenantSnapshotService::destroy end", KR(ret)); + } +} + +void ObTenantSnapshotService::stop() +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObTenantSnapshotService not inited, cannot stop", KR(ret), KPC(this)); + } else if (!ATOMIC_LOAD(&is_running_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("ObTenantSnapshotService already has stopped", KR(ret), KPC(this)); + } else { + TG_STOP(tg_id_); + tenant_snapshot_mgr_.stop(); + is_running_ = false; + { + ObThreadCondGuard guard(cond_); + cond_.signal(); + } + LOG_INFO("ObTenantSnapshotService stopped", KR(ret), KPC(this)); + } +} + +void ObTenantSnapshotService::wait() +{ + int ret = OB_SUCCESS; + while(OB_FAIL(wait_())) { + usleep(100000); + } +} + +int ObTenantSnapshotService::wait_() +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotService not inited", KR(ret), KPC(this)); + } else if (ATOMIC_LOAD(&is_running_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObTenantSnapshotService is running when wait function is called", KR(ret), KPC(this)); + stop(); + } else { + TG_WAIT(tg_id_); + } + return ret; +} + +int ObTenantSnapshotService::start() +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObTenantSnapshotService is not inited, cannot start", KR(ret), KPC(this)); + } else if (ATOMIC_LOAD(&is_running_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ObTenantSnapshotService is already running", KR(ret), KPC(this)); + } else if (OB_FAIL(TG_START(tg_id_))) { + LOG_ERROR("fail to start ObTenantSnapshotService thread", KR(ret), KPC(this)); + } else { + is_running_ = true; + LOG_INFO("ObTenantSnapshotService start successfully", KPC(this)); + } + return ret; +} + +int ObTenantSnapshotService::load_() +{ + int ret = OB_SUCCESS; + + ObArray tsnap_id_arr; + if (OB_FAIL(meta_handler_.get_all_tenant_snapshot(tsnap_id_arr))) { + LOG_WARN("fail to get_all_tenant_snapshot", KR(ret), KPC(this)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tsnap_id_arr.count(); ++i) { + const ObTenantSnapshotID tenant_snapshot_id = tsnap_id_arr.at(i); + ObTenantSnapshot *tenant_snapshot = nullptr; + if (OB_FAIL(tenant_snapshot_mgr_.acquire_tenant_snapshot(tenant_snapshot_id, + tenant_snapshot))) { + LOG_WARN("fail to acquire tenant snapshot", KR(ret), K(tenant_snapshot_id)); + } else { + if (OB_FAIL(tenant_snapshot->load())) { + LOG_WARN("fail to load tenant snapshot", KR(ret), K(tenant_snapshot_id)); + } else { + LOG_INFO("tenant snapshot load succ", K(tenant_snapshot_id), KPC(tenant_snapshot)); + } + tenant_snapshot_mgr_.revert_tenant_snapshot(tenant_snapshot); + } + } + } + + LOG_INFO("all tenant snapshot load finished", KR(ret)); + return ret; +} + +int ObTenantSnapshotService::get_tenant_status_(ObTenantStatus& tenant_status) +{ + int ret = OB_SUCCESS; + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTenantSchema *tenant_schema = NULL; + + if (OB_ISNULL(GCTX.schema_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("GCTX.schema_service_ is unexpected nullptr", KR(ret)); + } else if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard( + OB_SYS_TENANT_ID, schema_guard))) { + LOG_WARN("fail to get schema guard", KR(ret)); + } else if (OB_FAIL(schema_guard.get_tenant_info(MTL_ID(), tenant_schema))) { + LOG_WARN("fail to get tenant info", KR(ret)); + } else if (OB_ISNULL(tenant_schema)) { + ret = OB_TENANT_NOT_EXIST; + LOG_WARN("tenant not exist", KR(ret)); + } else { + tenant_status = tenant_schema->get_status(); + } + return ret; +} + +int ObTenantSnapshotService::get_tenant_role_(ObTenantRole& tenant_role) +{ + int ret = OB_SUCCESS; + ObAllTenantInfo tenant_info; + if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(MTL_ID(), + GCTX.sql_proxy_, + false /*for_update*/, + tenant_info))) { + LOG_WARN("fail to load tenant info", KR(ret)); + } else { + tenant_role = tenant_info.get_tenant_role(); + } + + return ret; +} + +int ObTenantSnapshotService::common_env_check_() +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotService has not been inited", KR(ret), KPC(this)); + } else if (!ATOMIC_LOAD(&is_running_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("ObTenantSnapshotService is not running", KR(ret), KPC(this)); + } else if (OB_UNLIKELY(!ObServerCheckpointSlogHandler::get_instance().is_started())) { + ret = OB_NOT_RUNNING; + LOG_INFO("ObTenantSnapshotService does not work before server slog replay finished", + KR(ret), KPC(this)); + } + + return ret; +} + +int ObTenantSnapshotService::normal_running_env_check_() +{ + int ret = OB_SUCCESS; + uint64_t data_version = 0; + + if (ATOMIC_LOAD(&running_mode_) != NORMAL) { + ret = OB_STATE_NOT_MATCH; + LOG_INFO("the running mode is not NORMAL", KR(ret), KPC(this)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), data_version))) { + LOG_WARN("get_min_data_version failed", KR(ret), KPC(this)); + } else if (OB_UNLIKELY(data_version < DATA_VERSION_4_3_0_0)) { + ret = OB_NOT_SUPPORTED; + LOG_INFO("ObTenantSnapshotService does not work before data version upgrade to 4_3_0_0", + KR(ret), KPC(this), K(data_version)); + } else { + LOG_INFO("normal_running_env_check_ succ", KPC(this)); + } + + return ret; +} + +int ObTenantSnapshotService::clone_running_env_check_() +{ + int ret = OB_SUCCESS; + + if (ATOMIC_LOAD(&running_mode_) != CLONE) { + ret = OB_STATE_NOT_MATCH; + LOG_INFO("the running mode is not CLONE", KR(ret), KPC(this)); + } else { + LOG_INFO("clone_running_env_check_ succ", KPC(this)); + } + return ret; +} + +int ObTenantSnapshotService::decide_running_mode_(enum RUNNING_MODE& running_mode) +{ + int ret = OB_SUCCESS; + + share::schema::ObSchemaGetterGuard schema_guard; + const share::schema::ObTenantSchema *tenant_schema = NULL; + ObTenantStatus tenant_status = TENANT_STATUS_MAX; + + if (OB_FAIL(get_tenant_status_(tenant_status))) { + LOG_WARN("fail to get_tenant_status_", KR(ret)); + } else if (TENANT_STATUS_NORMAL == tenant_status) { + running_mode = NORMAL; + } else if (TENANT_STATUS_RESTORE == tenant_status) { + ObTenantRole tenant_role; + if (OB_FAIL(get_tenant_role_(tenant_role))) { + LOG_WARN("fail to get_tenant_role", KR(ret)); + } else if (tenant_role.is_clone()) { + running_mode = CLONE; + } else if (tenant_role.is_restore()) { + running_mode = RESTORE; + } else { + ret = OB_NOT_RUNNING; + LOG_WARN("ObTenantSnapshotService does not work", KR(ret), K(tenant_status), K(tenant_role)); + } + } else { + ret = OB_NOT_RUNNING; + LOG_INFO("ObTenantSnapshotService does not work in current tenant status", + KR(ret), K(tenant_status)); + } + return ret; +} + +int ObTenantSnapshotService::create_tenant_snapshot(const obrpc::ObInnerCreateTenantSnapshotArg &arg) +{ + int ret = OB_SUCCESS; + ObTenantSnapshotID tenant_snapshot_id; + + if (!arg.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObInnerCreateTenantSnapshotArg is not valid", KR(ret), K(arg)); + } else if (FALSE_IT(tenant_snapshot_id = arg.get_tenant_snapshot_id())) { + } else if (OB_FAIL(common_env_check_())) { + LOG_WARN("fail to common_env_check_", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(normal_running_env_check_())) { + LOG_WARN("fail to normal_running_env_check_", KR(ret), K(tenant_snapshot_id)); + } else if (!ATOMIC_LOAD(&meta_loaded_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("storage node cannot process create tenant snapshot request before meta loaded", + KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(try_create_tenant_snapshot_(tenant_snapshot_id))) { + LOG_WARN("fail to try_create_tenant_snapshot_", KR(ret), K(tenant_snapshot_id)); + } + + LOG_INFO("execute create_tenant_snapshot finished", KR(ret), K(arg)); + return ret; +} + +int ObTenantSnapshotService::try_create_tenant_snapshot_(const ObTenantSnapshotID& tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + ObTenantSnapshot *tenant_snapshot = nullptr; + ObArray creating_ls_id_arr; + common::ObCurTraceId::TraceId trace_id; + + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(tenant_snapshot_mgr_.acquire_tenant_snapshot(tenant_snapshot_id, + tenant_snapshot))) { + if (OB_ENTRY_EXIST == ret) { + LOG_INFO("some concurrent request is processed", KR(ret), K(tenant_snapshot_id)); + } else { + LOG_WARN("fail to acquire tenant snapshot", KR(ret), K(tenant_snapshot_id)); + } + } else if (OB_FAIL(tenant_snapshot->try_start_create_tenant_snapshot_dag(creating_ls_id_arr, + trace_id))) { + if (OB_NO_NEED_UPDATE == ret || OB_EAGAIN == ret) { + LOG_INFO("fail to start_create_tenant_snapshot_dag", KR(ret), KPC(tenant_snapshot)); + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to start_create_tenant_snapshot_dag", KR(ret), KPC(tenant_snapshot)); + } + } else { + ObTraceIDGuard trace_guard(trace_id); + if (OB_FAIL(schedule_create_tenant_snapshot_dag_(tenant_snapshot_id, + creating_ls_id_arr, + trace_id))) { + LOG_WARN("fail to schedule create tenant snapshot dag", KR(ret), K(tenant_snapshot_id)); + tenant_snapshot->finish_create_tenant_snapshot_dag(); + } else { + LOG_INFO("schedule create tenant snapshot dag success", K(tenant_snapshot_id)); + } + } + + if (tenant_snapshot != nullptr) { + tenant_snapshot_mgr_.revert_tenant_snapshot(tenant_snapshot); + } + + return ret; +} + +int ObTenantSnapshotService::drop_tenant_snapshot(const obrpc::ObInnerDropTenantSnapshotArg &arg) +{ + int ret = OB_SUCCESS; + + ObTenantSnapshot *tenant_snapshot = nullptr; + ObTenantSnapshotID tenant_snapshot_id; + + if (!arg.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObInnerDropTenantSnapshotArg is not valid", KR(ret), K(arg)); + } else if (FALSE_IT(tenant_snapshot_id = arg.get_tenant_snapshot_id())) { + } else if (OB_FAIL(common_env_check_())) { + LOG_WARN("failed to common_env_check_", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(normal_running_env_check_())) { + LOG_WARN("failed to normal_env_check_", KR(ret), K(tenant_snapshot_id)); + } else if (!ATOMIC_LOAD(&meta_loaded_)) { + ret = OB_NOT_RUNNING; + LOG_WARN("observer cannot process drop tenant snapshot request before load meta finished", + KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(tenant_snapshot_mgr_.get_tenant_snapshot(tenant_snapshot_id, tenant_snapshot))){ + if (OB_TENANT_SNAPSHOT_NOT_EXIST == ret) { + LOG_INFO("tenant snapshot already not existed", KR(ret), K(arg)); + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get tenant_snapshot", KR(ret), K(arg)); + } + } else { + tenant_snapshot->stop(); + { + ObThreadCondGuard guard(cond_); + cond_.signal(); + } + tenant_snapshot_mgr_.revert_tenant_snapshot(tenant_snapshot); + } + + LOG_INFO("exec drop_tenant_snapshot finished", KR(ret), K(arg)); + return ret; +} + +int ObTenantSnapshotService::schedule_create_tenant_snapshot_dag_(const ObTenantSnapshotID& tenant_snapshot_id, + const ObArray& creating_ls_id_arr, + const common::ObCurTraceId::TraceId& trace_id) +{ + int ret = OB_SUCCESS; + + ObTenantDagScheduler* dag_scheduler = MTL(ObTenantDagScheduler*); + + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (creating_ls_id_arr.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("creating_ls_id_arr is empty", KR(ret), K(tenant_snapshot_id)); + } else if (!trace_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("trace_id is not valid", KR(ret), K(tenant_snapshot_id), K(trace_id)); + } else if (OB_ISNULL(dag_scheduler)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag_scheduler is nullptr", KR(ret)); + } else { + ObTenantSnapshotCreateParam param(tenant_snapshot_id, creating_ls_id_arr, trace_id, &tenant_snapshot_mgr_); + if (OB_FAIL(dag_scheduler->create_and_add_dag(¶m))) { + LOG_WARN("fail to create ObTenantSnapshotCreateDag", KR(ret), K(param)); + } else { + LOG_INFO("schedule ObTenantSnapshotCreateDag success", K(param)); + } + } + return ret; +} + +int ObTenantSnapshotService::schedule_gc_tenant_snapshot_dag_(const ObTenantSnapshotID &tenant_snapshot_id, + const ObArray &gc_ls_id_arr, + const bool gc_all_tenant_snapshot, + const common::ObCurTraceId::TraceId& trace_id) +{ + int ret = OB_SUCCESS; + + ObTenantSnapshotGCParam param(tenant_snapshot_id, + gc_ls_id_arr, + gc_all_tenant_snapshot, + trace_id, + &tenant_snapshot_mgr_); + ObTenantDagScheduler *dag_scheduler = MTL(ObTenantDagScheduler*); + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_ISNULL(dag_scheduler)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag scheduler is null", KR(ret)); + } else if (OB_FAIL(dag_scheduler->create_and_add_dag(¶m))) { + LOG_WARN("fail to create ObTenantSnapshotGCDag", KR(ret), K(param)); + } else { + LOG_INFO("schedule ObTenantSnapshotGCDag success", K(param)); + } + return ret; +} + +void ObTenantSnapshotService::run_in_clone_mode_() +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(clone_running_env_check_())) { + LOG_INFO("fail to clone_running_env_check_", KR(ret), KPC(this)); + } else { + clone_service_.run(); + } +} + +void ObTenantSnapshotService::run_in_normal_mode_() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(normal_running_env_check_())) { + LOG_INFO("fail to normal_running_env_check_", KR(ret)); + } + + if (OB_SUCC(ret) && !meta_loaded_) { + if (OB_FAIL(load_())) { + LOG_ERROR("fail to load slog meta", KR(ret), KPC(this)); + } else { + meta_loaded_ = true; + LOG_INFO("ObTenantSnapshotService load slog meta succ", KR(ret), KPC(this)); + } + } + + if (OB_SUCC(ret) && meta_loaded_) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_gc_tenant_snapshot_())) { + LOG_WARN("fail to try_gc_tenant_snapshot_", KR(tmp_ret)); + } + if (OB_TMP_FAIL(try_create_tenant_snapshot_in_meta_table_())) { + LOG_WARN("fail to try_create_tenant_snapshot_in_meta_table_", KR(tmp_ret)); + } + } +} + +int ObTenantSnapshotService::start_clone(const ObTenantSnapshotID &tenant_snapshot_id, + const ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry) +{ + int ret = OB_SUCCESS; + ObTenantSnapshot* tenant_snapshot = nullptr; + + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (!ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ls_id is not valid", KR(ret), K(tenant_snapshot_id), K(ls_id)); + } else if (OB_FAIL(tenant_snapshot_mgr_.get_tenant_snapshot(tenant_snapshot_id, tenant_snapshot))) { + LOG_WARN("fail to get tenant snapshot", KR(ret), K(tenant_snapshot_id)); + } else if (OB_ISNULL(tenant_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant_snapshot is unexpected nullptr", KR(ret), K(tenant_snapshot_id)); + } else { + if (OB_FAIL(tenant_snapshot->inc_clone_ref())) { + LOG_WARN("fail to inc_clone_ref", KR(ret), KPC(tenant_snapshot)); + } else { + if (OB_FAIL(tenant_snapshot->get_ls_snapshot_tablet_meta_entry(ls_id, tablet_meta_entry))) { + LOG_WARN("fail to get_ls_snapshot_tablet_meta_entry", KR(ret), KPC(tenant_snapshot), K(ls_id)); + } else { + LOG_INFO("start clone succ", KPC(tenant_snapshot), K(tablet_meta_entry)); + } + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(tenant_snapshot->dec_clone_ref())) { + LOG_ERROR("fail to dec_clone_ref", KR(ret), KPC(tenant_snapshot)); + } + } + } + + tenant_snapshot_mgr_.revert_tenant_snapshot(tenant_snapshot); + } + return ret; +} + +int ObTenantSnapshotService::end_clone(const ObTenantSnapshotID &tenant_snapshot_id) +{ + int ret = OB_SUCCESS; + + ObTenantSnapshot* tenant_snapshot = nullptr; + + if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(tenant_snapshot_mgr_.get_tenant_snapshot(tenant_snapshot_id, tenant_snapshot))) { + LOG_WARN("fail to get tenant snapshot", KR(ret), K(tenant_snapshot_id)); + } else { + if (OB_FAIL(tenant_snapshot->dec_clone_ref())) { + LOG_WARN("fail to dec_clone_ref", KR(ret), KPC(tenant_snapshot)); + } else { + LOG_INFO("end clone succ", KPC(tenant_snapshot)); + } + tenant_snapshot_mgr_.revert_tenant_snapshot(tenant_snapshot); + } + return ret; +} + +int ObTenantSnapshotService::try_gc_tenant_snapshot_() +{ + int ret = OB_SUCCESS; + + TryGcTenantSnapshotFunctor fn; + if (OB_FAIL(tenant_snapshot_mgr_.for_each(fn))) { + LOG_WARN("fail to add all try_gc dag task", KR(ret)); + } + LOG_INFO("try_gc_tenant_snapshot finished", KR(ret), KPC(this)); + return ret; +} + +bool ObTenantSnapshotService::TryGcTenantSnapshotFunctor::operator()( + const ObTenantSnapshotID &tenant_snapshot_id, ObTenantSnapshot* tenant_snapshot) +{ + int ret = OB_SUCCESS; + bool gc_all_tenant_snapshot = false; + ObArray gc_ls_id_arr; + common::ObCurTraceId::TraceId trace_id; + + ObTenantSnapshotService *tenant_snapshot_service = MTL(ObTenantSnapshotService *); + if (OB_UNLIKELY(OB_ISNULL(tenant_snapshot_service))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ObTenantSnapshotService is null", KR(ret), K(tenant_snapshot_service)); + } else if (OB_UNLIKELY(OB_ISNULL(tenant_snapshot))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant_snapshot is null", KR(ret), K(tenant_snapshot)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is not valid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_FAIL(tenant_snapshot->try_start_gc_tenant_snapshot_dag(gc_all_tenant_snapshot, + gc_ls_id_arr, + trace_id))) { + if (OB_NO_NEED_UPDATE == ret || OB_EAGAIN == ret) { + LOG_INFO("fail to try_start_gc_tenant_snapshot_dag now, try later", KR(ret), K(tenant_snapshot_id)); + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to start try_start_gc_tenant_snapshot_dag", KR(ret), K(tenant_snapshot_id)); + } + } else { + ObTraceIDGuard trace_guard(trace_id); + if (OB_FAIL(tenant_snapshot_service->schedule_gc_tenant_snapshot_dag_(tenant_snapshot_id, + gc_ls_id_arr, + gc_all_tenant_snapshot, + trace_id))) { + LOG_WARN("fail to schedule_gc_tenant_snapshot_dag_", KR(ret), KPC(tenant_snapshot)); + tenant_snapshot->finish_gc_tenant_snapshot_dag(); + } else { + LOG_INFO("schedule_gc_tenant_snapshot success", KR(ret), KPC(tenant_snapshot)); + } + } + return true; +} + +int ObTenantSnapshotService::try_create_tenant_snapshot_in_meta_table_() +{ + int ret = OB_SUCCESS; + + ObArray tsnap_item_arr; + if (OB_FAIL(ObTenantSnapshotMetaTable::acquire_all_tenant_snapshots(tsnap_item_arr))) { + LOG_WARN("fail to acquire_all_tenant_snapshot", KR(ret)); + } else { + for (int64_t i = 0; i < tsnap_item_arr.count(); ++i) { + const ObTenantSnapItem& tsnap_item = tsnap_item_arr.at(i); + if (tsnap_item.get_status() != ObTenantSnapStatus::DELETING) { + if (OB_FAIL(try_create_tenant_snapshot_(tsnap_item.get_tenant_snapshot_id()))) { + LOG_WARN("fail to try_create_tenant_snapshot_", KR(ret), K(tsnap_item)); + } + } + } + } + return ret; +} + +void ObTenantSnapshotService::run1() +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + lib::set_thread_name("TSnapSvc"); + + while (is_user_tenant(tenant_id) && !has_set_stop()) { + if (OB_FAIL(common_env_check_())) { + LOG_INFO("failed to common_env_check_", KR(ret)); + } + + if (OB_SUCC(ret) && NORMAL != running_mode_) { + RUNNING_MODE tmp_running_mode = RUNNING_MODE::INVALID; + if (OB_FAIL(decide_running_mode_(tmp_running_mode))) { + LOG_INFO("fail to decide_running_mode_", KR(ret), KPC(this)); + } else { + running_mode_ = tmp_running_mode; + } + } + + if (OB_SUCC(ret) && CLONE == running_mode_) { + if (!clone_service_.is_started()) { + if (OB_FAIL(clone_service_.start())) { + LOG_WARN("fail to do clone_service_ start", KR(ret)); + } + } + + if (OB_SUCC(ret)) { + run_in_clone_mode_(); + } + } + + if (OB_SUCC(ret) && NORMAL == running_mode_) { + if (clone_service_.is_started()) { + clone_service_.stop(); + } + + run_in_normal_mode_(); + } + + { + ObThreadCondGuard guard(cond_); + const uint64_t idle_time = calculate_idle_time_(); + cond_.wait(idle_time); + } + } + + if (has_set_stop() && clone_service_.is_started()) { + clone_service_.stop(); + clone_service_.wait(); + } + + LOG_INFO("ObTenantSnapshotService thread stop", K_(tg_id)); +} + +uint64_t ObTenantSnapshotService::calculate_idle_time_() +{ + uint64_t idle_time = 60 * 1000; // ms + + if (RUNNING_MODE::INVALID == running_mode_) { + idle_time = 1 * 1000; + } else if (RESTORE == running_mode_) { + idle_time = 60 * 1000; + } else if (CLONE == running_mode_) { + idle_time = 1 * 1000; + } else if (NORMAL == running_mode_) { + int tmp_ret = OB_SUCCESS; + bool has_tenant_snapshot_stopped = true; + + if (OB_TMP_FAIL(tenant_snapshot_mgr_. + has_tenant_snapshot_stopped(has_tenant_snapshot_stopped))) { + idle_time = 60 * 1000; + } else if (has_tenant_snapshot_stopped) { + idle_time = 5 * 1000; + } else { + idle_time = 60 * 1000; + } + } else { + idle_time = 60 * 1000; + } + + LOG_INFO("ObTenantSnapshotService thread idle time", K(tg_id_), K(idle_time), K(running_mode_)); + return idle_time; +} + +bool ObTenantSnapshotService::GetAllLSSnapshotMapKeyFunctor::operator()( + const ObLSSnapshotMapKey &ls_snap_map_key, ObLSSnapshot *ls_snapshot) +{ + int ret = OB_SUCCESS; + if (!ls_snap_map_key.is_valid()) { + LOG_DEBUG("invalid ObLSSnapshotMapKey, skip", K(ls_snap_map_key)); + } else if (OB_UNLIKELY(OB_ISNULL(ls_snapshot_key_arr_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls_snapshot_key_arr_ is null", KR(ret)); + } else if (OB_FAIL(ls_snapshot_key_arr_->push_back(ls_snap_map_key))){ + LOG_WARN("fail to push back ls_snap_map_key", KR(ret), K(ls_snap_map_key)); + } + return true; +} + +int ObTenantSnapshotService::get_all_ls_snapshot_keys(ObArray &ls_snapshot_key_arr) +{ + int ret = OB_SUCCESS; + ls_snapshot_key_arr.reset(); + GetAllLSSnapshotMapKeyFunctor fn(&ls_snapshot_key_arr); + if (OB_FAIL(ls_snapshot_mgr_.for_each(fn))) { + LOG_WARN("fail to add all ls snapshot map keys", KR(ret)); + } + return ret; +} + +int ObTenantSnapshotService::get_ls_snapshot_vt_info(const ObLSSnapshotMapKey &ls_snapshot_key, + ObLSSnapshotVTInfo &ls_snapshot_vt_info) +{ + int ret = OB_SUCCESS; + ls_snapshot_vt_info.reset(); + + ObLSSnapshot *ls_snapshot = nullptr; + if (!ls_snapshot_key.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ObLSSnapshotMapKey", KR(ret), K(ls_snapshot_key)); + } else if (OB_FAIL(ls_snapshot_mgr_.get_ls_snapshot(ls_snapshot_key.tenant_snapshot_id_, + ls_snapshot_key.ls_id_, + ls_snapshot))){ + LOG_WARN("fail to get ObLSSnapshot", KR(ret), K(ls_snapshot_key)); + } else if (OB_UNLIKELY(OB_ISNULL(ls_snapshot))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls_snapshot is nullptr", KR(ret), K(ls_snapshot_key)); + } else { + if (OB_FAIL(ls_snapshot->get_ls_snapshot_vt_info(ls_snapshot_vt_info))) { + LOG_WARN("fail to get ls_snapshot_vt_info", KR(ret), K(ls_snapshot_key)); + } + ls_snapshot_mgr_.revert_ls_snapshot(ls_snapshot); + } + + ObTenantSnapshot *tenant_snapshot = nullptr; + ObTenantSnapshotID tenant_snapshot_id = ls_snapshot_key.tenant_snapshot_id_; + if (FAILEDx(tenant_snapshot_mgr_.get_tenant_snapshot(tenant_snapshot_id, tenant_snapshot))){ + ls_snapshot_vt_info.set_has_tsnap_info(false); + if (OB_ENTRY_NOT_EXIST == ret) { + // tenant snapshot info may be deleted while we are collecting ls snapshot info, + // it's ok that we do not collect tenant snapshot info related to this ls snap + LOG_INFO("tenant snapshot entry not exist", KR(ret), K(ls_snapshot_key)); + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get tenant snapshot", KR(ret), K(ls_snapshot_key)); + } + } else if (OB_UNLIKELY(OB_ISNULL(tenant_snapshot))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant_snapshot is nullptr", KR(ret), K(tenant_snapshot_id)); + } else { + ls_snapshot_vt_info.get_tsnap_info().reset(); + ObTenantSnapshotVTInfo &tsnap_info = ls_snapshot_vt_info.get_tsnap_info(); + if (OB_FAIL(tenant_snapshot->get_tenant_snapshot_vt_info(tsnap_info))) { + LOG_WARN("fail to get tenant_snapshot_vt_info", KR(ret), K(tenant_snapshot_id)); + } else { + ls_snapshot_vt_info.set_has_tsnap_info(true); + } + tenant_snapshot_mgr_.revert_tenant_snapshot(tenant_snapshot); + } + return ret; +} +} // storage +} // oceanbase diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_service.h b/src/storage/tenant_snapshot/ob_tenant_snapshot_service.h new file mode 100644 index 0000000000..372df312b2 --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_service.h @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_SERVICE_ +#define OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_SERVICE_ + +#include "share/ob_rpc_struct.h" +#include "lib/lock/ob_rwlock.h" +#include "storage/slog_ckpt/ob_tenant_meta_snapshot_handler.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_mgr.h" +#include "storage/tenant_snapshot/ob_ls_snapshot_mgr.h" +#include "storage/tenant_snapshot/ob_tenant_clone_service.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTenantSnapshot; + +class ObTenantSnapshotService : public lib::TGRunnable +{ +public: + ObTenantSnapshotService(); + virtual ~ObTenantSnapshotService(); + + static int mtl_init(ObTenantSnapshotService* &service); + int init(); + int start(); + void stop(); + void wait(); + void destroy(); + void run1(); +public: + int get_all_ls_snapshot_keys(common::ObArray &ls_snapshot_key_arr); + int get_ls_snapshot_vt_info(const ObLSSnapshotMapKey &ls_snapshot_key, ObLSSnapshotVTInfo &ls_snapshot_vt_info); + + int create_tenant_snapshot(const obrpc::ObInnerCreateTenantSnapshotArg &arg); + + int drop_tenant_snapshot(const obrpc::ObInnerDropTenantSnapshotArg &arg); + + int get_ls_snapshot_tablet_meta_entry(const share::ObTenantSnapshotID &tenant_snapshot_id, + const share::ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry); + + int start_clone(const share::ObTenantSnapshotID &tenant_snapshot_id, + const share::ObLSID &ls_id, + blocksstable::MacroBlockId &tablet_meta_entry); + + int end_clone(const share::ObTenantSnapshotID &tenant_snapshot_id); + + TO_STRING_KV(K(is_inited_), K(is_running_), K(running_mode_), K(meta_loaded_), K(tg_id_)); +private: + enum RUNNING_MODE + { + INVALID = 0, + RESTORE = 1, + CLONE = 2, + NORMAL = 3, + }; +private: + int load_(); + + int common_env_check_(); + int normal_running_env_check_(); + int clone_running_env_check_(); + int get_tenant_status_(share::schema::ObTenantStatus& tenant_status); + int get_tenant_role_(share::ObTenantRole& tenant_role); + int decide_running_mode_(enum RUNNING_MODE& running_mode); + void run_in_normal_mode_(); + void run_in_clone_mode_(); + + int wait_(); + int schedule_create_tenant_snapshot_dag_(const share::ObTenantSnapshotID& tenant_snapshot_id, + const common::ObArray& creating_ls_id_arr, + const common::ObCurTraceId::TraceId& trace_id); + int schedule_gc_tenant_snapshot_dag_(const share::ObTenantSnapshotID &tenant_snapshot_id, + const common::ObArray &gc_ls_id_arr, + const bool gc_all_tenant_snapshot, + const common::ObCurTraceId::TraceId& trace_id); + int try_create_tenant_snapshot_(const share::ObTenantSnapshotID& tenant_snapshot_id); + int try_create_tenant_snapshot_in_meta_table_(); + int try_gc_tenant_snapshot_(); + uint64_t calculate_idle_time_(); + +private: + class TryGcTenantSnapshotFunctor { + public: + bool operator()(const share::ObTenantSnapshotID &tenant_snapshot_id, ObTenantSnapshot* tenant_snapshot); + }; + + class GetAllLSSnapshotMapKeyFunctor { + public: + GetAllLSSnapshotMapKeyFunctor(common::ObArray *ls_snapshot_key_arr) + : ls_snapshot_key_arr_(ls_snapshot_key_arr) {} + bool operator()(const ObLSSnapshotMapKey &ls_snap_map_key, ObLSSnapshot *ls_snapshot); + private: + common::ObArray *ls_snapshot_key_arr_; + }; +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapshotService); + + bool is_inited_; + bool is_running_; + bool meta_loaded_; + ObTenantSnapshotMgr tenant_snapshot_mgr_; + ObLSSnapshotMgr ls_snapshot_mgr_; + ObTenantMetaSnapshotHandler meta_handler_; + + common::ObThreadCond cond_; + int tg_id_; + + // record running_mode_ information in the ObTenantSnapshotService class, because the service + // will not switch to the CLONE state after confirming that it has reached the normal state, + RUNNING_MODE running_mode_; + ObTenantCloneService clone_service_; +}; + +} +} +#endif diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_task.cpp b/src/storage/tenant_snapshot/ob_tenant_snapshot_task.cpp new file mode 100644 index 0000000000..30e67c45bb --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_task.cpp @@ -0,0 +1,418 @@ +/** + * Copyright (c) 2021 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. + */ + +#define USING_LOG_PREFIX STORAGE + +#include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "storage/slog_ckpt/ob_server_checkpoint_slog_handler.h" +#include "storage/tx_storage/ob_ls_map.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_defs.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_task.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_service.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_mgr.h" +#include "storage/tenant_snapshot/ob_tenant_snapshot_meta_table.h" +namespace oceanbase +{ +namespace storage +{ + +bool ObTenantSnapshotCreateParam::is_valid() const +{ + int ret = OB_SUCCESS; + + bool bret = false; + if (!tenant_snapshot_id_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("the tenant_snapshot_id_ is invalid", KR(ret), KPC(this)); + } else if (creating_ls_id_arr_.empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("the creating_ls_id_arr_ is empty", KR(ret), KPC(this)); + } else if (!trace_id_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("the trace_id is not valid", KR(ret), KPC(this)); + } else if (OB_ISNULL(tenant_snapshot_mgr_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_mgr_ is nullptr", KR(ret), KPC(this)); + } else { + bret = true; + } + + return bret; +} + +int ObTenantSnapshotCreateDag::init_by_param(const share::ObIDagInitParam *param) +{ + int ret = OB_SUCCESS; + const ObTenantSnapshotCreateParam *create_param = nullptr; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTenantSnapshotCreateParam cannot init twice", KR(ret), KPC(this), K(param)); + } else if (OB_ISNULL(param)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObTenantSnapshotCreateParam input param is null", KR(ret), KPC(this), K(param)); + } else if (FALSE_IT(create_param = static_cast(param))) { + } else if (!create_param->is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObTenantSnapshotCreateParam input param is not valid", + KR(ret), KPC(this), KPC(create_param)); + } else if (OB_FAIL(this->set_dag_id(create_param->trace_id_))) { + LOG_WARN("fail to set dag id", KR(ret), KPC(create_param)); + } else { + tenant_snapshot_id_ = create_param->tenant_snapshot_id_; + creating_ls_id_arr_ = create_param->creating_ls_id_arr_; + tenant_snapshot_mgr_ = create_param->tenant_snapshot_mgr_; + is_inited_ = true; + } + + return ret; +} + +int ObTenantSnapshotCreateDag::create_first_task() +{ + int ret = OB_SUCCESS; + ObTenantSnapshotCreateTask *task = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotCreateDag has not been inited", KR(ret), KPC(this)); + } else if (OB_FAIL(alloc_task(task))) { + LOG_WARN("fail to alloc ObTenantSnapshotCreateTask", KR(ret), KPC(this)); + } else if (OB_FAIL(task->init(tenant_snapshot_id_, + &creating_ls_id_arr_, + tenant_snapshot_mgr_))) { + LOG_WARN("fail to init ObTenantSnapshotCreateTask", KR(ret), KPC(this), KPC(task)); + } else if (OB_FAIL(add_task(*task))) { + LOG_WARN("fail to add task", KR(ret), KPC(this), KPC(task)); + } else { + LOG_INFO("success to add ObTenantSnapshotCreateTask", KPC(this), KPC(task)); + } + return ret; +} + +bool ObTenantSnapshotCreateDag::operator==(const ObIDag &other) const +{ + bool bret = true; + const ObTenantSnapshotCreateDag &other_dag = static_cast(other); + if (this != &other) { + if (get_type() != other.get_type() || + tenant_snapshot_id_ != other_dag.tenant_snapshot_id_) { + bret = false; + } + } + return bret; +} + +int ObTenantSnapshotCreateDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, + ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotCreateDag has not been inited", KR(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + tenant_snapshot_id_.id()))) { + LOG_WARN("fail to fill info param", KR(ret), KPC(this)); + } + return ret; +} + +int ObTenantSnapshotCreateDag::fill_dag_key(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotCreateDag has not been inited", KR(ret), KPC(this)); + } else if (OB_ISNULL(buf) || buf_len <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fill_dag_key parameters are invalid", KR(ret), KPC(this), KP(buf), K(buf_len)); + } else if (!tenant_snapshot_id_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant_snapshot_id_ is invalid", KR(ret), KPC(this)); + } else if (OB_FAIL(databuff_printf(buf, buf_len, "tenant_snapshot_id=%s", + to_cstring(tenant_snapshot_id_)))) { + LOG_WARN("fail to fill dag_key", KR(ret), KPC(this)); + } + return ret; +} + +int64_t ObTenantSnapshotCreateDag::hash() const +{ + int64_t ptr = reinterpret_cast(this); + return common::murmurhash(&ptr, sizeof(ptr), 0); +} + +int ObTenantSnapshotCreateTask::init(const ObTenantSnapshotID& tenant_snapshot_id, + const ObArray* creating_ls_id_arr, + ObTenantSnapshotMgr* tenant_snapshot_mgr) +{ + int ret = OB_SUCCESS; + + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("cannot init twice", KR(ret)); + } else if (OB_ISNULL(dag_)) { + ret = OB_ERR_SYS; + LOG_WARN("dag must not null", KR(ret), K(tenant_snapshot_id)); + } else if (share::ObDagType::DAG_TYPE_TENANT_SNAPSHOT_CREATE != dag_->get_type()) { + ret = OB_ERR_SYS; + LOG_ERROR("dag type not match", KR(ret), KPC(dag_), K(tenant_snapshot_id)); + } else if (!tenant_snapshot_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_id is invalid", KR(ret), K(tenant_snapshot_id)); + } else if (OB_ISNULL(creating_ls_id_arr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("creating_ls_id_arr is unexpected null", KR(ret), K(tenant_snapshot_id)); + } else if (creating_ls_id_arr->empty()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("creating_ls_id_arr is empty array", KR(ret), K(tenant_snapshot_id)); + } else if (OB_ISNULL(tenant_snapshot_mgr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_mgr is unexpected null", KR(ret), K(tenant_snapshot_id)); + } else { + tenant_snapshot_id_ = tenant_snapshot_id; + creating_ls_id_arr_ = creating_ls_id_arr; + tenant_snapshot_mgr_ = tenant_snapshot_mgr; + is_inited_ = true; + } + return ret; +} + +int ObTenantSnapshotCreateTask::process() +{ + int ret = OB_SUCCESS; + ObTaskController::get().switch_task(share::ObTaskType::DATA_MAINTAIN); + ObTenantSnapshot* tenant_snapshot = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotCreateTask not inited", KR(ret)); + } else if (OB_ISNULL(creating_ls_id_arr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("creating_ls_id_arr_ is unexpected nullptr", KR(ret), KPC(this)); + } else if (OB_FAIL(tenant_snapshot_mgr_->get_tenant_snapshot(tenant_snapshot_id_, tenant_snapshot))) { + LOG_WARN("fail to get tenant_snapshot", KR(ret), K(tenant_snapshot_id_)); + } else if (OB_ISNULL(tenant_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tenant_snapshot is unexpected nullptr", KR(ret), K(tenant_snapshot_id_)); + } else { + if (OB_FAIL(tenant_snapshot->execute_create_tenant_snapshot_dag(*creating_ls_id_arr_))) { + LOG_WARN("fail to create tenant_snapshot", KR(ret), KPC(tenant_snapshot)); + } + tenant_snapshot->finish_create_tenant_snapshot_dag(); + tenant_snapshot_mgr_->revert_tenant_snapshot(tenant_snapshot); + } + + LOG_INFO("ObTenantSnapshotCreateTask process finished", KR(ret), K(tenant_snapshot_id_), KPC(this)); + return ret; +} + +//****** ObTenantSnapshotGCParam +bool ObTenantSnapshotGCParam::is_valid() const +{ + int ret = OB_SUCCESS; + bool bret = false; + + if (OB_UNLIKELY(!tenant_snapshot_id_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("the tenant_snapshot_id_ is invalid", KR(ret), KPC(this)); + } else if (!gc_all_tenant_snapshot_ && gc_ls_id_arr_.empty()) { // gc_all_tenant_snapshot_ == false means gc ls snap + ret = OB_INVALID_ARGUMENT; // therefore gc_ls_id_arr_ could not be empty + LOG_WARN("gc_ls_id_arr_ is empty", KR(ret), KPC(this)); + } else if (!trace_id_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("the trace_id is not valid", KR(ret), KPC(this)); + } else if (OB_ISNULL(tenant_snapshot_mgr_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_mgr_ is nullptr", KR(ret), KPC(this)); + } else { + bret = true; + } + + return bret; +} + +//****** ObTenantSnapshotGCDag +int ObTenantSnapshotGCDag::init_by_param(const share::ObIDagInitParam *param) +{ + int ret = OB_SUCCESS; + const ObTenantSnapshotGCParam *gc_param = nullptr; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTenantSnapshotGCDag cannot init twice", KR(ret), KPC(this), K(param)); + } else if (OB_ISNULL(param)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObTenantSnapshotGCDag input param is null", KR(ret), KPC(this)); + } else if (FALSE_IT(gc_param = static_cast(param))) { + } else if (OB_UNLIKELY(!gc_param->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("ObTenantSnapshotGCDag input param is not valid", + KR(ret), KPC(this), KPC(gc_param)); + } else if (OB_FAIL(this->set_dag_id(gc_param->trace_id_))) { + LOG_WARN("fail to set dag id", KR(ret), KPC(gc_param)); + } else { + tenant_snapshot_id_ = gc_param->tenant_snapshot_id_; + gc_ls_id_arr_ = gc_param->gc_ls_id_arr_; + gc_all_tenant_snapshot_ = gc_param->gc_all_tenant_snapshot_; + tenant_snapshot_mgr_ = gc_param->tenant_snapshot_mgr_; + is_inited_ = true; + } + + return ret; +} + +int ObTenantSnapshotGCDag::create_first_task() +{ + int ret = OB_SUCCESS; + ObTenantSnapshotGCTask *task = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", KR(ret), KPC(this)); + } else if (OB_FAIL(alloc_task(task))) { + LOG_WARN("fail to create ObTenantSnapshotGCDag", KR(ret)); + } else if (OB_FAIL(task->init(tenant_snapshot_id_, + &gc_ls_id_arr_, + gc_all_tenant_snapshot_, + tenant_snapshot_mgr_))) { + LOG_WARN("fail to init ObTenantSnapshotGCTask", KR(ret)); + } else if(OB_FAIL(add_task(*task))) { + LOG_WARN("fail to add task", KR(ret), KPC(this)); + } else { + LOG_INFO("success to add ObTenantSnapshotGCTask", KPC(this)); + } + return ret; +} + +bool ObTenantSnapshotGCDag::operator==(const ObIDag &other) const +{ + bool bret = true; + const ObTenantSnapshotGCDag &other_dag = static_cast(other); + if (this != &other) { + if (get_type() != other.get_type() || + tenant_snapshot_id_ != other_dag.tenant_snapshot_id_) { + bret = false; + } + } + return bret; +} + +int ObTenantSnapshotGCDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, + ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotGCDag has not been inited", KR(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + tenant_snapshot_id_.id()))) { + LOG_WARN("failed to fill info param", KR(ret), KPC(this)); + } + return ret; +} + +int ObTenantSnapshotGCDag::fill_dag_key(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotGCDag has not been inited", KR(ret), KPC(this)); + } else if (OB_ISNULL(buf) || buf_len <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fill_dag_key parameters are invalid", KR(ret), KPC(this), KP(buf), K(buf_len)); + } else if (OB_UNLIKELY(!tenant_snapshot_id_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant_snapshot_id_ is invalid", KR(ret), KPC(this)); + } else if (OB_FAIL(databuff_printf(buf, buf_len, "tenant_snapshot_id=%s", + to_cstring(tenant_snapshot_id_)))) { + LOG_WARN("failed to fill dag_key", KR(ret), KPC(this)); + } + return ret; +} + +int64_t ObTenantSnapshotGCDag::hash() const +{ + int64_t ptr = reinterpret_cast(this); + return common::murmurhash(&ptr, sizeof(ptr), 0); +} + +//****** ObTenantSnapshotGCTask +int ObTenantSnapshotGCTask::init(const ObTenantSnapshotID tenant_snapshot_id, + const ObArray *gc_ls_id_arr, + bool gc_all_tenant_snapshot, + ObTenantSnapshotMgr* tenant_snapshot_mgr) +{ + int ret = OB_SUCCESS; + if(is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTenantSnapshotGCTask can not init twice", KR(ret)); + } else if (OB_ISNULL(dag_)) { + ret = OB_ERR_SYS; + LOG_WARN("dag must be not null", KR(ret), K(tenant_snapshot_id)); + } else if (share::ObDagType::DAG_TYPE_TENANT_SNAPSHOT_GC != dag_->get_type()) { + ret = OB_ERR_SYS; + LOG_ERROR("dag type not match", KR(ret), KPC(dag_)); + } else if (OB_ISNULL(tenant_snapshot_mgr)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tenant_snapshot_mgr is null", KR(ret), K(tenant_snapshot_id)); + } else { + tenant_snapshot_id_ = tenant_snapshot_id; + gc_ls_id_arr_ = gc_ls_id_arr; + gc_all_tenant_snapshot_ = gc_all_tenant_snapshot; + tenant_snapshot_mgr_ = tenant_snapshot_mgr; + is_inited_ = true; + } + return ret; +} + +int ObTenantSnapshotGCTask::process() +{ + int ret = OB_SUCCESS; + ObTaskController::get().switch_task(share::ObTaskType::DATA_MAINTAIN); + ObTenantSnapshot* tenant_snapshot = nullptr; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObTenantSnapshotGCTask not inited", KR(ret)); + } else if (OB_ISNULL(gc_ls_id_arr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("gc_ls_id_arr_ is null", KR(ret)); + } else if (OB_UNLIKELY(OB_ISNULL(tenant_snapshot_mgr_))) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tenant_snapshot_mgr_ is null", KR(ret), K(tenant_snapshot_id_)); + } else if (OB_FAIL(tenant_snapshot_mgr_->get_tenant_snapshot(tenant_snapshot_id_, tenant_snapshot))) { + LOG_WARN("fail to get tenant_snapshot", KR(ret), K(tenant_snapshot_id_)); + } else if (OB_ISNULL(tenant_snapshot)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("tenant_snapshot has been deleted", KR(ret), K(tenant_snapshot_id_)); + } else { + if (OB_FAIL(tenant_snapshot->execute_gc_tenant_snapshot_dag(gc_all_tenant_snapshot_, *gc_ls_id_arr_))) { + LOG_WARN("fail to execute gc tenant snapshot dag", KR(ret)); + } else { + if (gc_all_tenant_snapshot_) { + if (OB_FAIL(tenant_snapshot_mgr_->del_tenant_snapshot(tenant_snapshot->get_tenant_snapshot_id()))) { + LOG_WARN("fail to delete tenant snapshot in tenant_snapshot_mgr_", + KR(ret), KPC(tenant_snapshot_mgr_), KPC(tenant_snapshot)); + } + } // if only gc ls snapshot, then no need to delete tenant_snapshot in tenant_snapshot_mgr_ + tenant_snapshot->finish_gc_tenant_snapshot_dag(); + tenant_snapshot_mgr_->revert_tenant_snapshot(tenant_snapshot); + LOG_INFO("execute gc tenant snapshot task success"); + } + } + + LOG_INFO("ObTenantSnapshotGCTask finished", + KR(ret), K(gc_all_tenant_snapshot_), K(tenant_snapshot_id_), KPC(gc_ls_id_arr_)); + return ret; +} + +} +} diff --git a/src/storage/tenant_snapshot/ob_tenant_snapshot_task.h b/src/storage/tenant_snapshot/ob_tenant_snapshot_task.h new file mode 100644 index 0000000000..119dc9df4e --- /dev/null +++ b/src/storage/tenant_snapshot/ob_tenant_snapshot_task.h @@ -0,0 +1,192 @@ +/** + * Copyright (c) 2021 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. + */ + +#ifndef OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_TASK_ +#define OCEANBASE_STORAGE_OB_TENANT_SNAPSHOT_TASK_ + +#include "share/scheduler/ob_tenant_dag_scheduler.h" +#include "share/scheduler/ob_dag_scheduler_config.h" + +namespace oceanbase +{ +namespace storage +{ +class ObTenantSnapshot; +class ObTenantSnapshotMgr; + +struct ObTenantSnapshotCreateParam : public share::ObIDagInitParam { + ObTenantSnapshotCreateParam(const share::ObTenantSnapshotID& tenant_snapshot_id, + const common::ObArray& creating_ls_id_arr, + const common::ObCurTraceId::TraceId& trace_id, + ObTenantSnapshotMgr* tenant_snapshot_mgr): + tenant_snapshot_id_(tenant_snapshot_id), + creating_ls_id_arr_(creating_ls_id_arr), + trace_id_(trace_id), + tenant_snapshot_mgr_(tenant_snapshot_mgr) { } + virtual ~ObTenantSnapshotCreateParam() {}; + virtual bool is_valid() const override; + + TO_STRING_KV(K(tenant_snapshot_id_), K(creating_ls_id_arr_), K(trace_id_), KP(tenant_snapshot_mgr_)); + + ObTenantSnapshotCreateParam& operator=(const ObTenantSnapshotCreateParam& other) = delete; + const share::ObTenantSnapshotID tenant_snapshot_id_; + const common::ObArray creating_ls_id_arr_; + const common::ObCurTraceId::TraceId trace_id_; + ObTenantSnapshotMgr* tenant_snapshot_mgr_; +}; + +class ObTenantSnapshotCreateDag : public share::ObIDag { +public: + ObTenantSnapshotCreateDag(): ObIDag(share::ObDagType::DAG_TYPE_TENANT_SNAPSHOT_CREATE), + is_inited_(false), + tenant_snapshot_id_(), + creating_ls_id_arr_(), + tenant_snapshot_mgr_(nullptr) {} + virtual ~ObTenantSnapshotCreateDag() {} + virtual int init_by_param(const share::ObIDagInitParam *param) override; + virtual int create_first_task() override; + virtual bool operator==(const share::ObIDag &other) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, + common::ObIAllocator &allocator) const override; + virtual bool is_ha_dag() const override { return false; } + virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; + virtual int64_t hash() const override; + virtual lib::Worker::CompatMode get_compat_mode() const override + { return lib::Worker::CompatMode::MYSQL; } + + virtual uint64_t get_consumer_group_id() const override { return consumer_group_id_; } + + TO_STRING_KV(K(is_inited_), + K(tenant_snapshot_id_), K(creating_ls_id_arr_), KP(tenant_snapshot_mgr_)); +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapshotCreateDag); + +private: + bool is_inited_; + share::ObTenantSnapshotID tenant_snapshot_id_; + common::ObArray creating_ls_id_arr_; + ObTenantSnapshotMgr* tenant_snapshot_mgr_; +}; + +class ObTenantSnapshotCreateTask: public share::ObITask +{ +public: + ObTenantSnapshotCreateTask(): ObITask(ObITask::TASK_TYPE_TENANT_SNAPSHOT_CREATE), + is_inited_(false), + tenant_snapshot_id_(), + creating_ls_id_arr_(nullptr), + tenant_snapshot_mgr_(nullptr) {}; + virtual ~ObTenantSnapshotCreateTask() {}; + int init(const share::ObTenantSnapshotID& tenant_snapshot_id, + const common::ObArray* creating_ls_id_arr, + ObTenantSnapshotMgr* tenant_snapshot_mgr); +protected: + virtual int process() override; + +protected: + bool is_inited_; + share::ObTenantSnapshotID tenant_snapshot_id_; + const common::ObArray* creating_ls_id_arr_; + ObTenantSnapshotMgr* tenant_snapshot_mgr_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapshotCreateTask); +}; + +struct ObTenantSnapshotGCParam : public share::ObIDagInitParam { + ObTenantSnapshotGCParam(const share::ObTenantSnapshotID tenant_snapshot_id, + const common::ObArray &gc_ls_id_arr, + const bool gc_all_tenant_snapshot, + const common::ObCurTraceId::TraceId& trace_id, + ObTenantSnapshotMgr *tenant_snapshot_mgr) + : tenant_snapshot_id_(tenant_snapshot_id), + gc_ls_id_arr_(gc_ls_id_arr), + gc_all_tenant_snapshot_(gc_all_tenant_snapshot), + trace_id_(trace_id), + tenant_snapshot_mgr_(tenant_snapshot_mgr){} + virtual ~ObTenantSnapshotGCParam(){} + virtual bool is_valid() const override; + + TO_STRING_KV(K(tenant_snapshot_id_), + K(gc_ls_id_arr_), K(gc_all_tenant_snapshot_), K(trace_id_), KP(tenant_snapshot_mgr_)); + + const share::ObTenantSnapshotID tenant_snapshot_id_; + const common::ObArray gc_ls_id_arr_; + const bool gc_all_tenant_snapshot_; // gc tenant snapshot or gc ls snapshot + const common::ObCurTraceId::TraceId trace_id_; + ObTenantSnapshotMgr *tenant_snapshot_mgr_; +}; + +class ObTenantSnapshotGCDag : public share::ObIDag { +public: + ObTenantSnapshotGCDag() : ObIDag(share::ObDagType::DAG_TYPE_TENANT_SNAPSHOT_GC), + is_inited_(false), + tenant_snapshot_id_(), + gc_ls_id_arr_(), + gc_all_tenant_snapshot_(false), + tenant_snapshot_mgr_() {} + virtual ~ObTenantSnapshotGCDag() {} + virtual int init_by_param(const share::ObIDagInitParam *param) override; + virtual int create_first_task() override; + virtual bool operator==(const ObIDag &other) const override; + virtual int fill_info_param(compaction::ObIBasicInfoParam *&out_param, + ObIAllocator &allocator) const override; + virtual bool is_ha_dag() const override { return false; } + virtual int fill_dag_key(char *buf, const int64_t buf_len) const override; + virtual int64_t hash() const override; + virtual lib::Worker::CompatMode get_compat_mode() const override + { return lib::Worker::CompatMode::MYSQL; } + + virtual uint64_t get_consumer_group_id() const override { return consumer_group_id_; } + + TO_STRING_KV(K(is_inited_), K(tenant_snapshot_id_), K(gc_ls_id_arr_), KP(tenant_snapshot_mgr_)); + +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapshotGCDag); + +private: + + bool is_inited_; + share::ObTenantSnapshotID tenant_snapshot_id_; + common::ObArray gc_ls_id_arr_; + bool gc_all_tenant_snapshot_; + ObTenantSnapshotMgr *tenant_snapshot_mgr_; +}; + +class ObTenantSnapshotGCTask : public share::ObITask { +public: + ObTenantSnapshotGCTask() : ObITask(ObITask::TASK_TYPE_TENANT_SNAPSHOT_GC), + is_inited_(false), + tenant_snapshot_id_(), + gc_ls_id_arr_(), + gc_all_tenant_snapshot_(false), + tenant_snapshot_mgr_(nullptr) {} + virtual ~ObTenantSnapshotGCTask() {} + int init(const share::ObTenantSnapshotID tenant_snapshot_id, + const common::ObArray *gc_ls_id_arr, + bool gc_all_tenant_snapshot, + ObTenantSnapshotMgr *tenant_snapshot_mgr); +protected: + virtual int process() override; + +private: + DISALLOW_COPY_AND_ASSIGN(ObTenantSnapshotGCTask); +protected: + bool is_inited_; + share::ObTenantSnapshotID tenant_snapshot_id_; + const common::ObArray *gc_ls_id_arr_; + bool gc_all_tenant_snapshot_; + ObTenantSnapshotMgr *tenant_snapshot_mgr_; +}; + +} +} +#endif diff --git a/src/storage/tx/ob_ts_mgr.cpp b/src/storage/tx/ob_ts_mgr.cpp index ab0e7487ff..2dddb0de77 100644 --- a/src/storage/tx/ob_ts_mgr.cpp +++ b/src/storage/tx/ob_ts_mgr.cpp @@ -679,6 +679,12 @@ int ObTsMgr::get_gts(const uint64_t tenant_id, return ret; } +int ObTsMgr::get_ts_sync(const uint64_t tenant_id, const int64_t timeout_us, share::SCN &scn) +{ + bool unused_is_external_consistent = false; + return get_ts_sync(tenant_id, timeout_us, scn, unused_is_external_consistent); +} + int ObTsMgr::get_ts_sync(const uint64_t tenant_id, const int64_t timeout_us, SCN &scn, diff --git a/src/storage/tx/ob_ts_mgr.h b/src/storage/tx/ob_ts_mgr.h index fc62dc4ea5..6a1247d366 100644 --- a/src/storage/tx/ob_ts_mgr.h +++ b/src/storage/tx/ob_ts_mgr.h @@ -89,6 +89,7 @@ public: virtual int get_gts(const uint64_t tenant_id, ObTsCbTask *task, share::SCN &scn) = 0; virtual int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_ts, share::SCN &scn, bool &is_external_consistent) = 0; + virtual int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_ts, share::SCN &scn) = 0; virtual int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn, ObTsCbTask *task, bool &need_wait) = 0; virtual int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn) = 0; @@ -318,8 +319,9 @@ public: //1. 如果task == NULL,说明调用者不需要异步回调,直接返回报错,由调用者处理 //2. 如果task != NULL,需要注册异步回调任务 int get_gts(const uint64_t tenant_id, ObTsCbTask *task, share::SCN &scn); - int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_ts, + int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_us, share::SCN &scn, bool &is_external_consistent); + int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_us, share::SCN &scn); int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn, ObTsCbTask *task, bool &need_wait); int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn); diff --git a/src/storage/tx_storage/ob_ls_service.cpp b/src/storage/tx_storage/ob_ls_service.cpp index d5b7cf9c30..d2433eb11d 100644 --- a/src/storage/tx_storage/ob_ls_service.cpp +++ b/src/storage/tx_storage/ob_ls_service.cpp @@ -457,11 +457,9 @@ int ObLSService::create_ls(const obrpc::ObCreateLSArg &arg) common_arg.tenant_role_ = arg.get_tenant_info().get_tenant_role(); common_arg.replica_type_ = arg.get_replica_type(); common_arg.compat_mode_ = arg.get_compat_mode(); - common_arg.create_type_ = is_ls_to_restore_(arg) ? ObLSCreateType::RESTORE : ObLSCreateType::NORMAL; common_arg.migration_status_ = ObMigrationStatus::OB_MIGRATION_STATUS_NONE; - common_arg.restore_status_ = (is_ls_to_restore_(arg) ? - ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_START) : - ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_NONE)); + common_arg.restore_status_ = get_restore_status_by_tenant_role_(arg.get_tenant_info().get_tenant_role()); + common_arg.create_type_ = get_create_type_by_tenant_role_(arg.get_tenant_info().get_tenant_role()); common_arg.need_create_inner_tablet_ = need_create_inner_tablets_(arg); if (OB_FAIL(create_ls_(common_arg, mig_arg))) { @@ -509,6 +507,15 @@ int ObLSService::post_create_ls_(const int64_t create_type, } break; } + case ObLSCreateType::CLONE: { + if (OB_FAIL(ls->get_log_handler()->enable_sync())) { + LOG_WARN("failed to enable sync", K(ret)); + } else if (OB_FAIL(ls->set_start_ha_state())) { + LOG_ERROR("ls set start ha state failed", KR(ret), KPC(ls)); + } else { + } + break; + } default: { ret = OB_ERR_UNEXPECTED; LOG_ERROR("should not be here.", KR(ret)); @@ -645,6 +652,12 @@ int ObLSService::replay_create_ls_commit(const share::ObLSID &ls_id, } break; } + case ObLSCreateType::CLONE: { + if (OB_FAIL(ls->set_start_ha_state())) { + LOG_ERROR("ls set start ha state failed", KR(ret), K(ls_id)); + } + break; + } default: { if (OB_FAIL(ls->set_start_work_state())) { LOG_ERROR("ls set start work state failed", KR(ret), K(ls_id)); @@ -1135,7 +1148,7 @@ int ObLSService::create_ls_for_ha( { int ret = OB_SUCCESS; ObMigrationStatus migration_status; - ObLSRestoreStatus restore_status = ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_NONE); + ObLSRestoreStatus restore_status = ObLSRestoreStatus(ObLSRestoreStatus::NONE); if (task_id.is_invalid() || !arg.is_valid()) { ret = OB_INVALID_ARGUMENT; @@ -1297,6 +1310,11 @@ bool ObLSService::is_ls_to_restore_(const obrpc::ObCreateLSArg &arg) const return arg.get_tenant_info().is_restore(); } +bool ObLSService::is_ls_to_clone_(const obrpc::ObCreateLSArg &arg) const +{ + return arg.get_tenant_info().is_clone(); +} + bool ObLSService::need_create_inner_tablets_(const obrpc::ObCreateLSArg &arg) const { return arg.need_create_inner_tablets(); @@ -1335,23 +1353,54 @@ int ObLSService::get_restore_status_( { int ret = OB_SUCCESS; const uint64_t tenant_id = MTL_ID(); - restore_status = ObLSRestoreStatus::RESTORE_NONE; + restore_status = ObLSRestoreStatus::NONE; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not init", K(ret)); - } else if (is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) { - restore_status = ObLSRestoreStatus::RESTORE_NONE; - } else if (share::ObTenantRole::INVALID_TENANT == MTL_GET_TENANT_ROLE_CACHE()) { - //tenant role not ready, need wait - ret = OB_NEED_WAIT; - LOG_WARN("tenant role is invalid now, need wait", KR(ret), K(tenant_id)); - } else if (FALSE_IT(restore_status = MTL_TENANT_ROLE_CACHE_IS_RESTORE() ? - ObLSRestoreStatus::RESTORE_START : ObLSRestoreStatus::RESTORE_NONE)) { + if (is_sys_tenant(tenant_id) || is_meta_tenant(tenant_id)) { + restore_status = ObLSRestoreStatus::NONE; + } else { + ObAllTenantInfo tenant_info; + if (OB_FAIL(ObAllTenantInfoProxy::load_tenant_info(tenant_id, + GCTX.sql_proxy_, + false, + tenant_info))) { + LOG_WARN("fail to load tenant info", KR(ret)); + } else { + restore_status = get_restore_status_by_tenant_role_(tenant_info.get_tenant_role()); + } } return ret; } +ObLSRestoreStatus ObLSService::get_restore_status_by_tenant_role_(const ObTenantRole& tenant_role) +{ + ObLSRestoreStatus restore_status = ObLSRestoreStatus(ObLSRestoreStatus::NONE); + + if (tenant_role.is_restore()) { + restore_status = ObLSRestoreStatus::RESTORE_START; + } else if (tenant_role.is_clone()) { + restore_status = ObLSRestoreStatus::CLONE_START; + } else { + restore_status = ObLSRestoreStatus::NONE; + } + + return restore_status; +} + +int64_t ObLSService::get_create_type_by_tenant_role_(const ObTenantRole& tenant_role) +{ + int64_t create_type = ObLSCreateType::NORMAL; + + if (tenant_role.is_restore()) { + create_type = ObLSCreateType::RESTORE; + } else if (tenant_role.is_clone()) { + create_type = ObLSCreateType::CLONE; + } else { + create_type = ObLSCreateType::NORMAL; + } + + return create_type; +} + int ObLSService::dump_ls_info() { int ret = OB_SUCCESS; diff --git a/src/storage/tx_storage/ob_ls_service.h b/src/storage/tx_storage/ob_ls_service.h index 5644ceb394..eb25d8dd59 100644 --- a/src/storage/tx_storage/ob_ls_service.h +++ b/src/storage/tx_storage/ob_ls_service.h @@ -200,9 +200,12 @@ private: int alloc_ls_(ObLS *&ls); bool is_ls_to_restore_(const obrpc::ObCreateLSArg &arg) const; + bool is_ls_to_clone_(const obrpc::ObCreateLSArg &arg) const; bool need_create_inner_tablets_(const obrpc::ObCreateLSArg &arg) const; int get_restore_status_( share::ObLSRestoreStatus &restore_status); + ObLSRestoreStatus get_restore_status_by_tenant_role_(const ObTenantRole& tenant_role); + int64_t get_create_type_by_tenant_role_(const ObTenantRole& tenant_role); private: bool is_inited_; diff --git a/src/storage/tx_table/ob_tx_data_table.cpp b/src/storage/tx_table/ob_tx_data_table.cpp index a4133c126e..273f4e649e 100644 --- a/src/storage/tx_table/ob_tx_data_table.cpp +++ b/src/storage/tx_table/ob_tx_data_table.cpp @@ -749,7 +749,7 @@ int ObTxDataTable::get_recycle_scn(SCN &recycle_scn) STORAGE_LOG(INFO, "logstream is in migration state. skip recycle tx data", "ls_id", ls_->get_ls_id()); } else if (OB_FAIL(ls_->get_restore_status(restore_status))) { STORAGE_LOG(WARN, "get restore status failed", KR(ret), "ls_id", ls_->get_ls_id()); - } else if (ObLSRestoreStatus::RESTORE_NONE != restore_status) { + } else if (ObLSRestoreStatus::NONE != restore_status) { recycle_scn.set_min(); STORAGE_LOG(INFO, "logstream is in restore state. skip recycle tx data", "ls_id", ls_->get_ls_id()); } else if (FALSE_IT(tg.click("iterate tablets start"))) { diff --git a/tools/deploy/mysql_test/r/mysql/information_schema.result b/tools/deploy/mysql_test/r/mysql/information_schema.result index 1337a1f134..99c3a2a58d 100644 --- a/tools/deploy/mysql_test/r/mysql/information_schema.result +++ b/tools/deploy/mysql_test/r/mysql/information_schema.result @@ -351,6 +351,7 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | GV$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | GV$OB_LS_SNAPSHOTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_MEMSTORE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -413,6 +414,7 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | V$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_LS_LOG_RESTORE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_LS_REPLICA_TASK_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | V$OB_LS_SNAPSHOTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_MEMSTORE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -654,6 +656,8 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | __all_virtual_backup_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_backup_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_clone_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_clone_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_compaction_diagnose_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_compaction_suggestion | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_core_all_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -699,6 +703,7 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | __all_virtual_ls_replica_task_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_ls_restore_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_ls_restore_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_ls_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_ls_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_ls_transfer_member_list_lock_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_malloc_sample_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -768,6 +773,11 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | __all_virtual_tenant_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_tenant_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_tenant_parameter_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot_ls | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot_ls_replica | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot_ls_replica_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_tenant_tablespace | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_tenant_user_failed_login_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_thread | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -1641,6 +1651,7 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | GV$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | GV$OB_LS_SNAPSHOTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | GV$OB_MEMSTORE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -1703,6 +1714,7 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | V$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_LS_LOG_RESTORE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_LS_REPLICA_TASK_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | V$OB_LS_SNAPSHOTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | V$OB_MEMSTORE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -1943,6 +1955,8 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | __all_virtual_backup_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_backup_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_clone_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_clone_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_compaction_diagnose_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_compaction_suggestion | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_core_all_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -1989,6 +2003,7 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | __all_virtual_ls_replica_task_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_ls_restore_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_ls_restore_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_ls_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_ls_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_ls_transfer_member_list_lock_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_malloc_sample_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -2058,6 +2073,11 @@ select * from information_schema.tables where table_schema in ('oceanbase', 'mys | def | oceanbase | __all_virtual_tenant_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_tenant_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_tenant_parameter_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot_ls | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot_ls_replica | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | +| def | oceanbase | __all_virtual_tenant_snapshot_ls_replica_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_tenant_tablespace | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_tenant_user_failed_login_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | | def | oceanbase | __all_virtual_thread | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | @@ -2239,6 +2259,10 @@ select * from information_schema.statistics where table_schema in ('oceanbase', | def | oceanbase | __all_balance_task_helper | 0 | oceanbase | PRIMARY | 2 | operation_scn | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_balance_task_history | 0 | oceanbase | PRIMARY | 1 | task_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_charset | 0 | oceanbase | PRIMARY | 1 | charset | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_clone_job | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_clone_job | 0 | oceanbase | PRIMARY | 2 | job_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_clone_job_history | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_clone_job_history | 0 | oceanbase | PRIMARY | 2 | job_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_cluster_event_history | 0 | oceanbase | PRIMARY | 1 | gmt_create | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_coll_type | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_coll_type | 0 | oceanbase | PRIMARY | 2 | coll_type_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | @@ -2951,6 +2975,25 @@ select * from information_schema.statistics where table_schema in ('oceanbase', | def | oceanbase | __all_tenant_security_audit_record | 0 | oceanbase | PRIMARY | 2 | record_timestamp_us | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_tenant_security_audit_record | 0 | oceanbase | PRIMARY | 3 | svr_ip | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_tenant_security_audit_record | 0 | oceanbase | PRIMARY | 4 | svr_port | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot | 0 | oceanbase | PRIMARY | 2 | snapshot_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot | 0 | oceanbase | idx_tenant_snapshot_name | 1 | snapshot_name | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_job | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_job | 0 | oceanbase | PRIMARY | 2 | snapshot_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_job | 0 | oceanbase | PRIMARY | 3 | operation | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls | 0 | oceanbase | PRIMARY | 2 | snapshot_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls | 0 | oceanbase | PRIMARY | 3 | ls_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica | 0 | oceanbase | PRIMARY | 2 | snapshot_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica | 0 | oceanbase | PRIMARY | 3 | ls_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica | 0 | oceanbase | PRIMARY | 4 | svr_ip | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica | 0 | oceanbase | PRIMARY | 5 | svr_port | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica_history | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica_history | 0 | oceanbase | PRIMARY | 2 | snapshot_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica_history | 0 | oceanbase | PRIMARY | 3 | ls_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica_history | 0 | oceanbase | PRIMARY | 4 | svr_ip | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | +| def | oceanbase | __all_tenant_snapshot_ls_replica_history | 0 | oceanbase | PRIMARY | 5 | svr_port | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_tenant_sysauth | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_tenant_sysauth | 0 | oceanbase | PRIMARY | 2 | grantee_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | | def | oceanbase | __all_tenant_sysauth | 0 | oceanbase | PRIMARY | 3 | priv_id | A | NULL | NULL | NULL | | BTREE | | | YES | NULL | diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_sys_views_in_mysql.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_sys_views_in_mysql.result index e6021dc6ab..26c81c68e4 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_sys_views_in_mysql.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_sys_views_in_mysql.result @@ -5592,3 +5592,45 @@ LAST_USED varchar(128) NO NULL select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.DBA_INDEX_USAGE limit 1); cnt 1 +desc oceanbase.GV$OB_LS_SNAPSHOTS; +Field Type Null Key Default Extra +TENANT_ID bigint(20) NO NULL +SNAPSHOT_ID bigint(20) NO NULL +LS_ID bigint(20) NO NULL +SVR_IP varchar(46) NO NULL +SVR_PORT bigint(20) NO NULL +META_EXISTED varchar(3) NO +BUILD_STATUS varchar(10) NO +REBUILD_SEQ_START bigint(20) YES NULL +REBUILD_SEQ_END bigint(20) YES NULL +END_INTERVAL_SCN bigint(20) YES NULL +LS_META_PACKAGE longtext YES NULL +TSNAP_IS_RUNNING varchar(3) NO +TSNAP_HAS_UNFINISHED_CREATE_DAG varchar(3) NO +TSNAP_HAS_UNFINISHED_GC_DAG varchar(3) NO +TSNAP_CLONE_REF bigint(20) YES NULL +TSNAP_META_EXISTED varchar(3) NO +select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.GV$OB_LS_SNAPSHOTS limit 1); +cnt +1 +desc oceanbase.V$OB_LS_SNAPSHOTS; +Field Type Null Key Default Extra +TENANT_ID bigint(20) NO +SNAPSHOT_ID bigint(20) NO +LS_ID bigint(20) NO +SVR_IP varchar(46) NO +SVR_PORT bigint(20) NO +META_EXISTED varchar(3) NO +BUILD_STATUS varchar(10) NO +REBUILD_SEQ_START bigint(20) NO +REBUILD_SEQ_END bigint(20) NO +END_INTERVAL_SCN bigint(20) NO +LS_META_PACKAGE longtext NO +TSNAP_IS_RUNNING varchar(3) NO +TSNAP_HAS_UNFINISHED_CREATE_DAG varchar(3) NO +TSNAP_HAS_UNFINISHED_GC_DAG varchar(3) NO +TSNAP_CLONE_REF bigint(20) NO +TSNAP_META_EXISTED varchar(3) NO +select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.V$OB_LS_SNAPSHOTS limit 1); +cnt +1 diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_sys_views_in_sys.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_sys_views_in_sys.result index 13e4c22988..b16d092bca 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_sys_views_in_sys.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_sys_views_in_sys.result @@ -8041,6 +8041,29 @@ CERT_EXPIRED_TIME timestamp(6) NO NULL select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.DBA_OB_TRUSTED_ROOT_CERTIFICATE limit 1); cnt 1 +desc oceanbase.DBA_OB_CLONE_PROGRESS; +Field Type Null Key Default Extra +CLONE_JOB_ID bigint(20) NO NULL +TRACE_ID varchar(64) NO NULL +SOURCE_TENANT_ID bigint(20) NO NULL +SOURCE_TENANT_NAME varchar(128) NO NULL +CLONE_TENANT_ID bigint(20) NO +CLONE_TENANT_NAME varchar(128) NO NULL +TENANT_SNAPSHOT_ID bigint(20) NO NULL +TENANT_SNAPSHOT_NAME varchar(128) NO NULL +RESOURCE_POOL_ID bigint(20) NO NULL +RESOURCE_POOL_NAME varchar(128) NO NULL +UNIT_CONFIG_NAME varchar(128) NO NULL +RESTORE_SCN bigint(20) unsigned NO +STATUS varchar(64) NO NULL +CLONE_JOB_TYPE varchar(16) NO NULL +CLONE_START_TIME timestamp(6) NO NULL +CLONE_FINISHED_TIME timestamp(6) YES NULL +RET_CODE bigint(20) YES NULL +ERROR_MESSAGE varchar(512) YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.DBA_OB_CLONE_PROGRESS limit 1); +cnt +1 desc oceanbase.CDB_INDEX_USAGE; Field Type Null Key Default Extra CON_ID bigint(20) NO NULL @@ -8064,3 +8087,68 @@ LAST_USED varchar(128) NO NULL select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.CDB_INDEX_USAGE limit 1); cnt 1 +desc oceanbase.GV$OB_LS_SNAPSHOTS; +Field Type Null Key Default Extra +TENANT_ID bigint(20) NO NULL +SNAPSHOT_ID bigint(20) NO NULL +LS_ID bigint(20) NO NULL +SVR_IP varchar(46) NO NULL +SVR_PORT bigint(20) NO NULL +META_EXISTED varchar(3) NO +BUILD_STATUS varchar(10) NO +REBUILD_SEQ_START bigint(20) YES NULL +REBUILD_SEQ_END bigint(20) YES NULL +END_INTERVAL_SCN bigint(20) YES NULL +LS_META_PACKAGE longtext YES NULL +TSNAP_IS_RUNNING varchar(3) NO +TSNAP_HAS_UNFINISHED_CREATE_DAG varchar(3) NO +TSNAP_HAS_UNFINISHED_GC_DAG varchar(3) NO +TSNAP_CLONE_REF bigint(20) YES NULL +TSNAP_META_EXISTED varchar(3) NO +select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.GV$OB_LS_SNAPSHOTS limit 1); +cnt +1 +desc oceanbase.V$OB_LS_SNAPSHOTS; +Field Type Null Key Default Extra +TENANT_ID bigint(20) NO +SNAPSHOT_ID bigint(20) NO +LS_ID bigint(20) NO +SVR_IP varchar(46) NO +SVR_PORT bigint(20) NO +META_EXISTED varchar(3) NO +BUILD_STATUS varchar(10) NO +REBUILD_SEQ_START bigint(20) NO +REBUILD_SEQ_END bigint(20) NO +END_INTERVAL_SCN bigint(20) NO +LS_META_PACKAGE longtext NO +TSNAP_IS_RUNNING varchar(3) NO +TSNAP_HAS_UNFINISHED_CREATE_DAG varchar(3) NO +TSNAP_HAS_UNFINISHED_GC_DAG varchar(3) NO +TSNAP_CLONE_REF bigint(20) NO +TSNAP_META_EXISTED varchar(3) NO +select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.V$OB_LS_SNAPSHOTS limit 1); +cnt +1 +desc oceanbase.DBA_OB_CLONE_HISTORY; +Field Type Null Key Default Extra +CLONE_JOB_ID bigint(20) NO NULL +TRACE_ID varchar(64) NO NULL +SOURCE_TENANT_ID bigint(20) NO NULL +SOURCE_TENANT_NAME varchar(128) NO NULL +CLONE_TENANT_ID bigint(20) NO +CLONE_TENANT_NAME varchar(128) NO NULL +TENANT_SNAPSHOT_ID bigint(20) NO NULL +TENANT_SNAPSHOT_NAME varchar(128) NO NULL +RESOURCE_POOL_ID bigint(20) NO NULL +RESOURCE_POOL_NAME varchar(128) NO NULL +UNIT_CONFIG_NAME varchar(128) NO NULL +RESTORE_SCN bigint(20) unsigned NO +STATUS varchar(64) NO NULL +CLONE_JOB_TYPE varchar(16) NO NULL +CLONE_START_TIME timestamp(6) NO NULL +CLONE_FINISHED_TIME timestamp(6) NO NULL +RET_CODE bigint(20) YES NULL +ERROR_MESSAGE varchar(512) YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.DBA_OB_CLONE_HISTORY limit 1); +cnt +1 diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_virtual_table_in_mysql.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_virtual_table_in_mysql.result index 2579ccbb66..1fd5ada007 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_virtual_table_in_mysql.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_virtual_table_in_mysql.result @@ -3973,6 +3973,55 @@ config_version bigint(20) NO NULL select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_parameter; IF(count(*) >= 0, 1, 0) 1 +desc oceanbase.__all_virtual_tenant_snapshot; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +snapshot_name varchar(128) NO NULL +status varchar(32) NO NULL +snapshot_scn bigint(20) unsigned NO NULL +clog_start_scn bigint(20) unsigned NO NULL +type varchar(16) NO NULL +create_time timestamp(6) NO NULL +data_version bigint(20) unsigned NO NULL +owner_job_id bigint(20) NO NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_tenant_snapshot_ls; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +ls_id bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +ls_group_id bigint(20) NO NULL +status varchar(100) NO NULL +flag varchar(2048) NO NULL +create_scn bigint(20) unsigned NO NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot_ls; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_tenant_snapshot_ls_replica; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +ls_id bigint(20) NO PRI NULL +svr_ip varchar(46) NO PRI NULL +svr_port bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +status varchar(64) NO NULL +zone varchar(128) NO NULL +unit_id bigint(20) NO NULL +begin_interval_scn bigint(20) unsigned NO NULL +end_interval_scn bigint(20) unsigned NO NULL +ls_meta_package longtext YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot_ls_replica; +IF(count(*) >= 0, 1, 0) +1 desc oceanbase.__all_virtual_wr_control; Field Type Null Key Default Extra tenant_id bigint(20) NO PRI NULL @@ -4287,3 +4336,110 @@ comment longtext YES select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_import_table_task_history; IF(count(*) >= 0, 1, 0) 1 +desc oceanbase.__all_virtual_clone_job; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +job_id bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +trace_id varchar(64) NO NULL +source_tenant_id bigint(20) NO NULL +source_tenant_name varchar(128) NO NULL +clone_tenant_id bigint(20) NO 0 +clone_tenant_name varchar(128) NO NULL +tenant_snapshot_id bigint(20) NO NULL +tenant_snapshot_name varchar(128) NO NULL +resource_pool_id bigint(20) NO NULL +resource_pool_name varchar(128) NO NULL +unit_config_name varchar(128) NO NULL +restore_scn bigint(20) unsigned NO 0 +status varchar(64) NO NULL +job_type varchar(16) NO NULL +clone_start_time timestamp(6) NO NULL +clone_finished_time timestamp(6) YES NULL +ret_code bigint(20) YES NULL +error_msg varchar(512) YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_clone_job; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_clone_job_history; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +job_id bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +trace_id varchar(64) NO NULL +source_tenant_id bigint(20) NO NULL +source_tenant_name varchar(128) NO NULL +clone_tenant_id bigint(20) NO 0 +clone_tenant_name varchar(128) NO NULL +tenant_snapshot_id bigint(20) NO NULL +tenant_snapshot_name varchar(128) NO NULL +resource_pool_id bigint(20) NO NULL +resource_pool_name varchar(128) NO NULL +unit_config_name varchar(128) NO NULL +restore_scn bigint(20) unsigned NO 0 +status varchar(64) NO NULL +job_type varchar(16) NO NULL +clone_start_time timestamp(6) NO NULL +clone_finished_time timestamp(6) NO NULL +ret_code bigint(20) YES NULL +error_msg varchar(512) YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_clone_job_history; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_tenant_snapshot_job; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +operation varchar(32) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +job_start_time timestamp(6) NO NULL +trace_id varchar(64) NO NULL +majority_succ_time timestamp(6) NO NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot_job; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_ls_snapshot; +Field Type Null Key Default Extra +tenant_id bigint(20) NO NULL +snapshot_id bigint(20) NO NULL +ls_id bigint(20) NO NULL +svr_ip varchar(46) NO NULL +svr_port bigint(20) NO NULL +meta_existed tinyint(4) NO NULL +build_status varchar(32) YES NULL +rebuild_seq_start bigint(20) YES NULL +rebuild_seq_end bigint(20) YES NULL +end_interval_scn bigint(20) YES NULL +ls_meta_package longtext YES NULL +tsnap_is_running tinyint(4) YES NULL +tsnap_has_unfinished_create_dag tinyint(4) YES NULL +tsnap_has_unfinished_gc_dag tinyint(4) YES NULL +tsnap_clone_ref bigint(20) YES NULL +tsnap_meta_existed tinyint(4) YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_ls_snapshot; +IF(count(*) >= 0, 1, 0) +1 +"oceanbase.__all_virtual_ls_snapshot runs in single server" +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_tenant_snapshot_ls_replica_history; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +ls_id bigint(20) NO PRI NULL +svr_ip varchar(46) NO PRI NULL +svr_port bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +status varchar(64) NO NULL +zone varchar(128) NO NULL +unit_id bigint(20) NO NULL +begin_interval_scn bigint(20) unsigned NO NULL +end_interval_scn bigint(20) unsigned NO NULL +ls_meta_package longtext YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot_ls_replica_history; +IF(count(*) >= 0, 1, 0) +1 diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_virtual_table_in_sys.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_virtual_table_in_sys.result index de346ce218..c3738ba814 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_virtual_table_in_sys.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/desc_virtual_table_in_sys.result @@ -8279,6 +8279,55 @@ config_version bigint(20) NO NULL select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_parameter; IF(count(*) >= 0, 1, 0) 1 +desc oceanbase.__all_virtual_tenant_snapshot; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +snapshot_name varchar(128) NO NULL +status varchar(32) NO NULL +snapshot_scn bigint(20) unsigned NO NULL +clog_start_scn bigint(20) unsigned NO NULL +type varchar(16) NO NULL +create_time timestamp(6) NO NULL +data_version bigint(20) unsigned NO NULL +owner_job_id bigint(20) NO NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_tenant_snapshot_ls; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +ls_id bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +ls_group_id bigint(20) NO NULL +status varchar(100) NO NULL +flag varchar(2048) NO NULL +create_scn bigint(20) unsigned NO NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot_ls; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_tenant_snapshot_ls_replica; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +ls_id bigint(20) NO PRI NULL +svr_ip varchar(46) NO PRI NULL +svr_port bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +status varchar(64) NO NULL +zone varchar(128) NO NULL +unit_id bigint(20) NO NULL +begin_interval_scn bigint(20) unsigned NO NULL +end_interval_scn bigint(20) unsigned NO NULL +ls_meta_package longtext YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot_ls_replica; +IF(count(*) >= 0, 1, 0) +1 desc oceanbase.__all_virtual_tablet_buffer_info; Field Type Null Key Default Extra svr_ip varchar(46) NO PRI NULL @@ -8648,6 +8697,58 @@ comment longtext YES select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_import_table_task_history; IF(count(*) >= 0, 1, 0) 1 +desc oceanbase.__all_virtual_clone_job; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +job_id bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +trace_id varchar(64) NO NULL +source_tenant_id bigint(20) NO NULL +source_tenant_name varchar(128) NO NULL +clone_tenant_id bigint(20) NO 0 +clone_tenant_name varchar(128) NO NULL +tenant_snapshot_id bigint(20) NO NULL +tenant_snapshot_name varchar(128) NO NULL +resource_pool_id bigint(20) NO NULL +resource_pool_name varchar(128) NO NULL +unit_config_name varchar(128) NO NULL +restore_scn bigint(20) unsigned NO 0 +status varchar(64) NO NULL +job_type varchar(16) NO NULL +clone_start_time timestamp(6) NO NULL +clone_finished_time timestamp(6) YES NULL +ret_code bigint(20) YES NULL +error_msg varchar(512) YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_clone_job; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_clone_job_history; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +job_id bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +trace_id varchar(64) NO NULL +source_tenant_id bigint(20) NO NULL +source_tenant_name varchar(128) NO NULL +clone_tenant_id bigint(20) NO 0 +clone_tenant_name varchar(128) NO NULL +tenant_snapshot_id bigint(20) NO NULL +tenant_snapshot_name varchar(128) NO NULL +resource_pool_id bigint(20) NO NULL +resource_pool_name varchar(128) NO NULL +unit_config_name varchar(128) NO NULL +restore_scn bigint(20) unsigned NO 0 +status varchar(64) NO NULL +job_type varchar(16) NO NULL +clone_start_time timestamp(6) NO NULL +clone_finished_time timestamp(6) NO NULL +ret_code bigint(20) YES NULL +error_msg varchar(512) YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_clone_job_history; +IF(count(*) >= 0, 1, 0) +1 desc oceanbase.__all_virtual_aux_stat; Field Type Null Key Default Extra tenant_id bigint(20) NO PRI NULL @@ -8661,6 +8762,43 @@ network_speed bigint(20) YES NULL select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_aux_stat; IF(count(*) >= 0, 1, 0) 1 +desc oceanbase.__all_virtual_tenant_snapshot_job; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +operation varchar(32) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +job_start_time timestamp(6) NO NULL +trace_id varchar(64) NO NULL +majority_succ_time timestamp(6) NO NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot_job; +IF(count(*) >= 0, 1, 0) +1 +desc oceanbase.__all_virtual_ls_snapshot; +Field Type Null Key Default Extra +tenant_id bigint(20) NO NULL +snapshot_id bigint(20) NO NULL +ls_id bigint(20) NO NULL +svr_ip varchar(46) NO NULL +svr_port bigint(20) NO NULL +meta_existed tinyint(4) NO NULL +build_status varchar(32) YES NULL +rebuild_seq_start bigint(20) YES NULL +rebuild_seq_end bigint(20) YES NULL +end_interval_scn bigint(20) YES NULL +ls_meta_package longtext YES NULL +tsnap_is_running tinyint(4) YES NULL +tsnap_has_unfinished_create_dag tinyint(4) YES NULL +tsnap_has_unfinished_gc_dag tinyint(4) YES NULL +tsnap_clone_ref bigint(20) YES NULL +tsnap_meta_existed tinyint(4) YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_ls_snapshot; +IF(count(*) >= 0, 1, 0) +1 +"oceanbase.__all_virtual_ls_snapshot runs in single server" +IF(count(*) >= 0, 1, 0) +1 desc oceanbase.__all_virtual_index_usage_info; Field Type Null Key Default Extra tenant_id bigint(20) NO PRI NULL @@ -8687,3 +8825,21 @@ last_flush_time timestamp(6) NO NULL select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_index_usage_info; IF(count(*) >= 0, 1, 0) 1 +desc oceanbase.__all_virtual_tenant_snapshot_ls_replica_history; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +snapshot_id bigint(20) NO PRI NULL +ls_id bigint(20) NO PRI NULL +svr_ip varchar(46) NO PRI NULL +svr_port bigint(20) NO PRI NULL +gmt_create timestamp(6) NO NULL +gmt_modified timestamp(6) NO NULL +status varchar(64) NO NULL +zone varchar(128) NO NULL +unit_id bigint(20) NO NULL +begin_interval_scn bigint(20) unsigned NO NULL +end_interval_scn bigint(20) unsigned NO NULL +ls_meta_package longtext YES NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tenant_snapshot_ls_replica_history; +IF(count(*) >= 0, 1, 0) +1 diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/inner_table_overall.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/inner_table_overall.result index 1755abaab6..3110c704cd 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/inner_table_overall.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/inner_table_overall.result @@ -254,6 +254,9 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 457 __wr_statname 0 201001 1 458 __wr_sysstat 0 201001 1 459 __all_balance_task_helper 0 201001 1 +460 __all_tenant_snapshot 0 201001 1 +461 __all_tenant_snapshot_ls 0 201001 1 +462 __all_tenant_snapshot_ls_replica 0 201001 1 471 __all_dbms_lock_allocated 0 201001 1 472 __wr_control 0 201001 1 473 __all_tenant_event_history 0 201001 1 @@ -264,9 +267,13 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 478 __all_import_table_job_history 0 201001 1 479 __all_import_table_task 0 201001 1 480 __all_import_table_task_history 0 201001 1 +485 __all_clone_job 0 201001 1 +486 __all_clone_job_history 0 201001 1 494 __all_aux_stat 0 201001 1 495 __all_index_usage_info 0 201001 1 +500 __all_tenant_snapshot_job 0 201001 1 502 __all_trusted_root_certificate 0 201001 1 +507 __all_tenant_snapshot_ls_replica_history 0 201001 1 10001 __tenant_virtual_all_table 2 201001 1 10002 __tenant_virtual_table_column 2 201001 1 10003 __tenant_virtual_table_index 2 201001 1 @@ -657,6 +664,9 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 12399 __all_virtual_storage_leak_info 2 201001 1 12400 __all_virtual_ls_log_restore_status 2 201001 1 12401 __all_virtual_tenant_parameter 2 201001 1 +12402 __all_virtual_tenant_snapshot 2 201001 1 +12403 __all_virtual_tenant_snapshot_ls 2 201001 1 +12404 __all_virtual_tenant_snapshot_ls_replica 2 201001 1 12405 __all_virtual_tablet_buffer_info 2 201001 1 12414 __all_virtual_wr_control 2 201001 1 12415 __all_virtual_tenant_event_history 2 201001 1 @@ -670,8 +680,13 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 12425 __all_virtual_import_table_job_history 2 201001 1 12426 __all_virtual_import_table_task 2 201001 1 12427 __all_virtual_import_table_task_history 2 201001 1 +12435 __all_virtual_clone_job 2 201001 1 +12436 __all_virtual_clone_job_history 2 201001 1 12447 __all_virtual_aux_stat 2 201001 1 +12453 __all_virtual_tenant_snapshot_job 2 201001 1 +12458 __all_virtual_ls_snapshot 2 201001 1 12459 __all_virtual_index_usage_info 2 201001 1 +12464 __all_virtual_tenant_snapshot_ls_replica_history 2 201001 1 20001 GV$OB_PLAN_CACHE_STAT 1 201001 1 20002 GV$OB_PLAN_CACHE_PLAN_STAT 1 201001 1 20003 SCHEMATA 1 201002 1 @@ -1043,7 +1058,11 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 21498 CDB_OB_AUX_STATISTICS 1 201001 1 21499 DBA_INDEX_USAGE 1 201001 1 21509 DBA_OB_TRUSTED_ROOT_CERTIFICATE 1 201001 1 +21510 DBA_OB_CLONE_PROGRESS 1 201001 1 21513 CDB_INDEX_USAGE 1 201001 1 +21517 GV$OB_LS_SNAPSHOTS 1 201001 1 +21518 V$OB_LS_SNAPSHOTS 1 201001 1 +21519 DBA_OB_CLONE_HISTORY 1 201001 1 check sys table count and table_id range success check count and table_id range for virtual table success select * from information_schema.CHARACTER_SETS limit 1; diff --git a/tools/ob_admin/dump_ckpt/ob_admin_dump_ckpt_executor.cpp b/tools/ob_admin/dump_ckpt/ob_admin_dump_ckpt_executor.cpp index c188bc35d6..c3a85fbd7e 100644 --- a/tools/ob_admin/dump_ckpt/ob_admin_dump_ckpt_executor.cpp +++ b/tools/ob_admin/dump_ckpt/ob_admin_dump_ckpt_executor.cpp @@ -201,16 +201,16 @@ int ObAdminDumpCkptExecutor::dump_all_ls_metas_from_ckpt(const blocksstable::Mac ObTenantStorageCheckpointReader tenant_storage_ckpt_reader; ObArray meta_block_list; - ObTenantStorageCheckpointReader::ObCheckpointMetaOp dump_ls_meta_op = + ObTenantStorageCheckpointReader::ObStorageMetaOp dump_ls_meta_op = std::bind(&ObAdminDumpCkptExecutor::dump_ls_meta, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, stream); if (fprintf(stream, "======================ls meta=====================\n") < 0) { ret = OB_ERR_SYS; LOG_WARN("fail to fprintf", K(ret)); - } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_checkpoint_item( + } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_meta_item( entry_block, dump_ls_meta_op, meta_block_list))) { - LOG_WARN("fail to iter_read_checkpoint_item", K(ret), K(entry_block)); + LOG_WARN("fail to iter_read_meta_item", K(ret), K(entry_block)); } else if (fprintf(stream, "checkpoint_block_id_list: [%s]\n", to_cstring(meta_block_list)) < 0) { ret = OB_ERR_SYS; LOG_WARN("fail to fprintf", K(ret)); @@ -245,16 +245,16 @@ int ObAdminDumpCkptExecutor::dump_all_tablets_from_ckpt(const blocksstable::Macr ObTenantStorageCheckpointReader tenant_storage_ckpt_reader; ObArray meta_block_list; - ObTenantStorageCheckpointReader::ObCheckpointMetaOp dump_tablet_op = + ObTenantStorageCheckpointReader::ObStorageMetaOp dump_tablet_op = std::bind(&ObAdminDumpCkptExecutor::dump_tablet, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, stream); if (fprintf(stream, "======================tablet=====================\n") < 0) { ret = OB_ERR_SYS; LOG_WARN("fail to fprintf", K(ret)); - } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_checkpoint_item( + } else if (OB_FAIL(tenant_storage_ckpt_reader.iter_read_meta_item( entry_block, dump_tablet_op, meta_block_list))) { - LOG_WARN("fail to iter_read_checkpoint_item", K(ret), K(entry_block)); + LOG_WARN("fail to iter_read_meta_item", K(ret), K(entry_block)); } else if (fprintf(stream, "checkpoint_block_id_list: %s\n", to_cstring(meta_block_list)) < 0) { ret = OB_ERR_SYS; LOG_WARN("fail to fprintf", K(ret)); diff --git a/tools/upgrade/upgrade_checker.py b/tools/upgrade/upgrade_checker.py index a0f23fc6cd..70374e92d8 100755 --- a/tools/upgrade/upgrade_checker.py +++ b/tools/upgrade/upgrade_checker.py @@ -608,6 +608,46 @@ def check_table_api_transport_compress_func(query_cur): fail_list.append('Table api connection is not allowed to use zlib as compression algorithm during the upgrade, please use other compression algorithms by setting table_api_transport_compress_func') logging.info('check table_api_transport_compress_func success') +# 17. 检查无租户克隆任务 +def check_tenant_clone_job_exist(query_cur): + min_cluster_version = 0 + sql = """select distinct value from GV$OB_PARAMETERS where name='min_observer_version'""" + (desc, results) = query_cur.exec_query(sql) + if len(results) != 1: + fail_list.append('min_observer_version is not sync') + elif len(results[0]) != 1: + fail_list.append('column cnt not match') + else: + min_cluster_version = get_version(results[0][0]) + if min_cluster_version >= get_version("4.3.0.0"): + (desc, results) = query_cur.exec_query("""select count(1) from __all_virtual_clone_job""") + if len(results) != 1 or len(results[0]) != 1: + fail_list.append('failed to tenant clone job cnt') + elif results[0][0] != 0: + fail_list.append("""still has tenant clone job, upgrade is not allowed temporarily""") + else: + logging.info('check tenant clone job success') + +# 18. 检查无租户快照任务 +def check_tenant_snapshot_task_exist(query_cur): + min_cluster_version = 0 + sql = """select distinct value from GV$OB_PARAMETERS where name='min_observer_version'""" + (desc, results) = query_cur.exec_query(sql) + if len(results) != 1: + fail_list.append('min_observer_version is not sync') + elif len(results[0]) != 1: + fail_list.append('column cnt not match') + else: + min_cluster_version = get_version(results[0][0]) + if min_cluster_version >= get_version("4.3.0.0"): + (desc, results) = query_cur.exec_query("""select count(1) from __all_virtual_tenant_snapshot where status!='NORMAL'""") + if len(results) != 1 or len(results[0]) != 1: + fail_list.append('failed to tenant snapshot task') + elif results[0][0] != 0: + fail_list.append("""still has tenant snapshot task, upgrade is not allowed temporarily""") + else: + logging.info('check tenant snapshot task success') + # 17. 检查是否有租户在升到4.3.0版本之前已将binlog_row_image设为MINIMAL def check_variable_binlog_row_image(query_cur): # 4.3.0.0之前的版本,MINIMAL模式生成的日志CDC无法正常消费(DELETE日志). @@ -670,6 +710,8 @@ def do_check(my_host, my_port, my_user, my_passwd, timeout, upgrade_params): check_schema_status(query_cur) check_server_version(query_cur) check_not_supported_tenant_name(query_cur) + check_tenant_clone_job_exist(query_cur) + check_tenant_snapshot_task_exist(query_cur) check_log_transport_compress_func(query_cur) check_table_compress_func(query_cur) check_table_api_transport_compress_func(query_cur) diff --git a/tools/upgrade/upgrade_post.py b/tools/upgrade/upgrade_post.py index e0bd668a22..ca38333d3c 100755 --- a/tools/upgrade/upgrade_post.py +++ b/tools/upgrade/upgrade_post.py @@ -2178,7 +2178,46 @@ # fail_list.append('Table api connection is not allowed to use zlib as compression algorithm during the upgrade, please use other compression algorithms by setting table_api_transport_compress_func') # logging.info('check table_api_transport_compress_func success') # -## 17. 检查是否有租户在升到4.3.0版本之前已将binlog_row_image设为MINIMAL +## 17. 检查无租户克隆任务 +#def check_tenant_clone_job_exist(query_cur): +# min_cluster_version = 0 +# sql = """select distinct value from GV$OB_PARAMETERS where name='min_observer_version'""" +# (desc, results) = query_cur.exec_query(sql) +# if len(results) != 1: +# fail_list.append('min_observer_version is not sync') +# elif len(results[0]) != 1: +# fail_list.append('column cnt not match') +# else: +# min_cluster_version = get_version(results[0][0]) +# if min_cluster_version >= get_version("4.3.0.0"): +# (desc, results) = query_cur.exec_query("""select count(1) from __all_virtual_clone_job""") +# if len(results) != 1 or len(results[0]) != 1: +# fail_list.append('failed to tenant clone job cnt') +# elif results[0][0] != 0: +# fail_list.append("""still has tenant clone job, upgrade is not allowed temporarily""") +# else: +# logging.info('check tenant clone job success') +# +## 18. 检查无租户快照任务 +#def check_tenant_snapshot_task_exist(query_cur): +# min_cluster_version = 0 +# sql = """select distinct value from GV$OB_PARAMETERS where name='min_observer_version'""" +# (desc, results) = query_cur.exec_query(sql) +# if len(results) != 1: +# fail_list.append('min_observer_version is not sync') +# elif len(results[0]) != 1: +# fail_list.append('column cnt not match') +# else: +# min_cluster_version = get_version(results[0][0]) +# if min_cluster_version >= get_version("4.3.0.0"): +# (desc, results) = query_cur.exec_query("""select count(1) from __all_virtual_tenant_snapshot where status!='NORMAL'""") +# if len(results) != 1 or len(results[0]) != 1: +# fail_list.append('failed to tenant snapshot task') +# elif results[0][0] != 0: +# fail_list.append("""still has tenant snapshot task, upgrade is not allowed temporarily""") +# else: +# logging.info('check tenant snapshot task success') +## 19. 检查是否有租户在升到4.3.0版本之前已将binlog_row_image设为MINIMAL #def check_variable_binlog_row_image(query_cur): ## 4.3.0.0之前的版本,MINIMAL模式生成的日志CDC无法正常消费(DELETE日志). ## 4.3.0版本开始,MINIMAL模式做了改进,支持CDC消费,需要在升级到4.3.0.0之后再打开. @@ -2240,6 +2279,8 @@ # check_schema_status(query_cur) # check_server_version(query_cur) # check_not_supported_tenant_name(query_cur) +# check_tenant_clone_job_exist(query_cur) +# check_tenant_snapshot_task_exist(query_cur) # check_log_transport_compress_func(query_cur) # check_table_compress_func(query_cur) # check_table_api_transport_compress_func(query_cur) diff --git a/tools/upgrade/upgrade_pre.py b/tools/upgrade/upgrade_pre.py index 1e7795ee47..6ce6108cd7 100755 --- a/tools/upgrade/upgrade_pre.py +++ b/tools/upgrade/upgrade_pre.py @@ -2178,7 +2178,46 @@ # fail_list.append('Table api connection is not allowed to use zlib as compression algorithm during the upgrade, please use other compression algorithms by setting table_api_transport_compress_func') # logging.info('check table_api_transport_compress_func success') # -## 17. 检查是否有租户在升到4.3.0版本之前已将binlog_row_image设为MINIMAL +## 17. 检查无租户克隆任务 +#def check_tenant_clone_job_exist(query_cur): +# min_cluster_version = 0 +# sql = """select distinct value from GV$OB_PARAMETERS where name='min_observer_version'""" +# (desc, results) = query_cur.exec_query(sql) +# if len(results) != 1: +# fail_list.append('min_observer_version is not sync') +# elif len(results[0]) != 1: +# fail_list.append('column cnt not match') +# else: +# min_cluster_version = get_version(results[0][0]) +# if min_cluster_version >= get_version("4.3.0.0"): +# (desc, results) = query_cur.exec_query("""select count(1) from __all_virtual_clone_job""") +# if len(results) != 1 or len(results[0]) != 1: +# fail_list.append('failed to tenant clone job cnt') +# elif results[0][0] != 0: +# fail_list.append("""still has tenant clone job, upgrade is not allowed temporarily""") +# else: +# logging.info('check tenant clone job success') +# +## 18. 检查无租户快照任务 +#def check_tenant_snapshot_task_exist(query_cur): +# min_cluster_version = 0 +# sql = """select distinct value from GV$OB_PARAMETERS where name='min_observer_version'""" +# (desc, results) = query_cur.exec_query(sql) +# if len(results) != 1: +# fail_list.append('min_observer_version is not sync') +# elif len(results[0]) != 1: +# fail_list.append('column cnt not match') +# else: +# min_cluster_version = get_version(results[0][0]) +# if min_cluster_version >= get_version("4.3.0.0"): +# (desc, results) = query_cur.exec_query("""select count(1) from __all_virtual_tenant_snapshot where status!='NORMAL'""") +# if len(results) != 1 or len(results[0]) != 1: +# fail_list.append('failed to tenant snapshot task') +# elif results[0][0] != 0: +# fail_list.append("""still has tenant snapshot task, upgrade is not allowed temporarily""") +# else: +# logging.info('check tenant snapshot task success') +## 19. 检查是否有租户在升到4.3.0版本之前已将binlog_row_image设为MINIMAL #def check_variable_binlog_row_image(query_cur): ## 4.3.0.0之前的版本,MINIMAL模式生成的日志CDC无法正常消费(DELETE日志). ## 4.3.0版本开始,MINIMAL模式做了改进,支持CDC消费,需要在升级到4.3.0.0之后再打开. @@ -2240,6 +2279,8 @@ # check_schema_status(query_cur) # check_server_version(query_cur) # check_not_supported_tenant_name(query_cur) +# check_tenant_clone_job_exist(query_cur) +# check_tenant_snapshot_task_exist(query_cur) # check_log_transport_compress_func(query_cur) # check_table_compress_func(query_cur) # check_table_api_transport_compress_func(query_cur) diff --git a/unittest/storage/backup/test_backup_extern_info_mgr.cpp b/unittest/storage/backup/test_backup_extern_info_mgr.cpp index 691736fccd..ae0ade0382 100644 --- a/unittest/storage/backup/test_backup_extern_info_mgr.cpp +++ b/unittest/storage/backup/test_backup_extern_info_mgr.cpp @@ -95,7 +95,7 @@ void TestBackupExternInfoMgr::make_ls_meta_package_(ObBackupLSMetaInfo &ls_meta_ ls_meta_info.ls_meta_package_.ls_meta_.ls_id_ = ls_id_; ls_meta_info.ls_meta_package_.ls_meta_.migration_status_ = ObMigrationStatus::OB_MIGRATION_STATUS_NONE; ls_meta_info.ls_meta_package_.ls_meta_.gc_state_ = LSGCState::NORMAL; - ls_meta_info.ls_meta_package_.ls_meta_.restore_status_ = ObLSRestoreStatus(ObLSRestoreStatus::RESTORE_NONE); + ls_meta_info.ls_meta_package_.ls_meta_.restore_status_ = ObLSRestoreStatus(ObLSRestoreStatus::Status::NONE); ls_meta_info.ls_meta_package_.palf_meta_.prev_log_info_.lsn_.val_ = 1; ls_meta_info.ls_meta_package_.palf_meta_.curr_lsn_.val_ = 2; } diff --git a/unittest/storage/test_tablet_pointer_map.cpp b/unittest/storage/test_tablet_pointer_map.cpp index f567c35b27..c02bbd6992 100644 --- a/unittest/storage/test_tablet_pointer_map.cpp +++ b/unittest/storage/test_tablet_pointer_map.cpp @@ -107,7 +107,7 @@ void TestMetaPointerMap::FakeLs(ObLS &ls) ls.ls_meta_.ls_id_.id_ = 1001; ls.ls_meta_.gc_state_ = logservice::LSGCState::NORMAL; ls.ls_meta_.migration_status_ = ObMigrationStatus::OB_MIGRATION_STATUS_NONE; - ls.ls_meta_.restore_status_ = ObLSRestoreStatus::RESTORE_NONE; + ls.ls_meta_.restore_status_ = ObLSRestoreStatus::NONE; ls.ls_meta_.rebuild_seq_ = 0; } diff --git a/unittest/storage/tx/mock_utils/basic_fake_define.h b/unittest/storage/tx/mock_utils/basic_fake_define.h index 94da7bb917..7e6becb37f 100644 --- a/unittest/storage/tx/mock_utils/basic_fake_define.h +++ b/unittest/storage/tx/mock_utils/basic_fake_define.h @@ -195,7 +195,7 @@ public: common::ObAddr leader; OZ(get_leader(cluster_id, tenant_id, ls_id, leader)); ObLSReplicaLocation rep_loc; - ObLSRestoreStatus restore_status(ObLSRestoreStatus::Status::RESTORE_NONE); + ObLSRestoreStatus restore_status(ObLSRestoreStatus::Status::NONE); auto p = ObReplicaProperty::create_property(100); OZ(rep_loc.init(leader, ObRole::LEADER, 10000, ObReplicaType::REPLICA_TYPE_FULL, p, restore_status, 1)); OZ(location.add_replica_location(rep_loc)); @@ -272,6 +272,8 @@ public: } int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_ts, share::SCN &scn, bool &is_external_consistent) { return OB_SUCCESS; } + int get_ts_sync(const uint64_t tenant_id, const int64_t timeout_ts, + share::SCN &scn) { return OB_SUCCESS; } int wait_gts_elapse(const uint64_t tenant_id, const share::SCN &scn, ObTsCbTask *task, bool &need_wait) {