diff --git a/deps/oblib/src/common/ob_common_types.h b/deps/oblib/src/common/ob_common_types.h index 90ace2ba5..609f69c7c 100644 --- a/deps/oblib/src/common/ob_common_types.h +++ b/deps/oblib/src/common/ob_common_types.h @@ -87,6 +87,7 @@ struct ObQueryFlag static const uint64_t OBSF_MASK_IS_MDS_QUERY = (0x1UL << OBSF_BIT_IS_MDS_QUERY) - 1; static const uint64_t OBSF_MASK_IS_SELECT_FOLLOWER = (0x1UL << OBSF_BIT_IS_SELECT_FOLLOWER) - 1; static const uint64_t OBSF_MASK_ENABLE_LOB_PREFETCH = (0x1UL << OBSF_BIT_ENABLE_LOB_PREFETCH) - 1; + static const uint64_t OBSF_MASK_IS_DIRECT_SCAN = (0x1UL << OBSF_BIT_IS_BARE_ROW_SCAN) - 1; enum ScanOrder @@ -242,6 +243,7 @@ struct ObQueryFlag inline bool is_for_foreign_key_check() const { return for_foreign_key_check_; } inline bool is_sstable_cut() const { return is_sstable_cut_; } inline bool is_skip_read_lob() const { return skip_read_lob_; } + inline bool is_bare_row_scan() const {return is_bare_row_scan_; } inline bool is_mds_query() const { return is_mds_query_; } inline void set_is_select_follower() { is_select_follower_ = true; } inline bool is_select_follower() const { return is_select_follower_; } @@ -279,6 +281,7 @@ struct ObQueryFlag "is_sstable_cut", is_sstable_cut_, "skip_read_lob", skip_read_lob_, "is_lookup_for_4377", is_lookup_for_4377_, + "is_bare_row_scan", is_bare_row_scan_, "enable_rich_format", enable_rich_format_, "is_for_foreign_key_check", for_foreign_key_check_, "is_mds_query", is_mds_query_, diff --git a/deps/oblib/src/common/object/ob_object.h b/deps/oblib/src/common/object/ob_object.h index 6389864b9..15aa376f1 100644 --- a/deps/oblib/src/common/object/ob_object.h +++ b/deps/oblib/src/common/object/ob_object.h @@ -554,7 +554,7 @@ struct ObLobDataOutRowCtx ERASE, EMPTY_SQL, // lob col not change in full sql update, out row ctx is empty DIFF, - EXT_INFO_LOG, + EXT_INFO_LOG, // only used in new row value VALID_OLD_VALUE_EXT_INFO_LOG, VALID_OLD_VALUE, DIFF_V2, // add lob id in ext info log, so deprecated old, use new diff type diff --git a/deps/oblib/src/common/storage/ob_device_common.h b/deps/oblib/src/common/storage/ob_device_common.h index afc08489c..306e60e53 100644 --- a/deps/oblib/src/common/storage/ob_device_common.h +++ b/deps/oblib/src/common/storage/ob_device_common.h @@ -180,7 +180,7 @@ struct ObStorageIdMod static const ObStorageIdMod get_default_id_mod() { - static const ObStorageIdMod storage_id_mod(0, ObStorageUsedMod::STORAGE_USED_OTHER);; + static const ObStorageIdMod storage_id_mod(0, ObStorageUsedMod::STORAGE_USED_OTHER); return storage_id_mod; } diff --git a/deps/oblib/src/lib/geo/ob_geo_mvt.cpp b/deps/oblib/src/lib/geo/ob_geo_mvt.cpp index fe6c42244..7a727a0d6 100644 --- a/deps/oblib/src/lib/geo/ob_geo_mvt.cpp +++ b/deps/oblib/src/lib/geo/ob_geo_mvt.cpp @@ -267,7 +267,7 @@ int mvt_agg_result::transform_json_column(ObObj &json) default: // ignore other type, do nothing ignore_type = true; - break;; + break; } if (OB_SUCC(ret) && !ignore_type) { tile_value.value_ = value; @@ -507,4 +507,4 @@ bool mvt_agg_result::is_upper_char_exist(const ObString &str) } } // namespace common -} // namespace oceanbase \ No newline at end of file +} // namespace oceanbase diff --git a/deps/oblib/src/lib/json_type/ob_json_bin.cpp b/deps/oblib/src/lib/json_type/ob_json_bin.cpp index 3e0b2922b..1f4a52468 100644 --- a/deps/oblib/src/lib/json_type/ob_json_bin.cpp +++ b/deps/oblib/src/lib/json_type/ob_json_bin.cpp @@ -4729,7 +4729,7 @@ int ObJsonBin::get_value(int index, ObJsonBin &value) const uint64_t value_offset = 0; uint8_t value_type = 0; if (OB_FAIL(get_value_entry(index, value_offset, value_type))) { - LOG_WARN("get_value_entry fail", K(ret), K(index));; + LOG_WARN("get_value_entry fail", K(ret), K(index)); } else if (OB_JSON_TYPE_IS_INLINE(value_type)) { offset += pos_; } else if (is_forward_v0(value_type)) { diff --git a/deps/oblib/src/lib/lock/ob_tc_rwlock.h b/deps/oblib/src/lib/lock/ob_tc_rwlock.h index e63c91239..a1ab7194c 100644 --- a/deps/oblib/src/lib/lock/ob_tc_rwlock.h +++ b/deps/oblib/src/lib/lock/ob_tc_rwlock.h @@ -60,7 +60,7 @@ public: }; struct RLockGuardWithTimeout { - [[nodiscard]] explicit RLockGuardWithTimeout(TCRWLock &lock, const int64_t abs_timeout_us, int &ret): lock_(lock), need_unlock_(true) + [[nodiscard]] explicit RLockGuardWithTimeout(const TCRWLock &lock, const int64_t abs_timeout_us, int &ret): lock_(const_cast(lock)), need_unlock_(true) { if (OB_FAIL(lock_.rdlock(abs_timeout_us))) { need_unlock_ = false; @@ -78,6 +78,7 @@ public: TCRWLock &lock_; bool need_unlock_; }; + struct WLockGuard { [[nodiscard]] explicit WLockGuard(TCRWLock& lock): lock_(lock) { lock_.wrlock(); } @@ -86,7 +87,7 @@ public: }; struct WLockGuardWithTimeout { - [[nodiscard]] explicit WLockGuardWithTimeout(TCRWLock &lock, const int64_t abs_timeout_us, int &ret): lock_(lock), need_unlock_(true) + [[nodiscard]] explicit WLockGuardWithTimeout(const TCRWLock &lock, const int64_t abs_timeout_us, int &ret): lock_(const_cast(lock)), need_unlock_(true) { if (OB_FAIL(lock_.wrlock(abs_timeout_us))) { need_unlock_ = false; diff --git a/deps/oblib/src/lib/mysqlclient/ob_dblink_error_trans.cpp b/deps/oblib/src/lib/mysqlclient/ob_dblink_error_trans.cpp index a456cce53..adf48c144 100644 --- a/deps/oblib/src/lib/mysqlclient/ob_dblink_error_trans.cpp +++ b/deps/oblib/src/lib/mysqlclient/ob_dblink_error_trans.cpp @@ -142,7 +142,7 @@ int ObTenantDblinkKeeper::clean_dblink_conn(uint32_t sessid, bool force_disconne connection = next; } if (OB_SUCC(ret) && OB_FAIL(dblink_conn_map_.erase_refactored(sessid))) { - LOG_WARN("failed to erase_refactored", K(tenant_id_), K(sessid), K(ret));; + LOG_WARN("failed to erase_refactored", K(tenant_id_), K(sessid), K(ret)); } } return ret; diff --git a/deps/oblib/src/lib/net/ob_addr.h b/deps/oblib/src/lib/net/ob_addr.h index 286126995..2de1ff4d0 100644 --- a/deps/oblib/src/lib/net/ob_addr.h +++ b/deps/oblib/src/lib/net/ob_addr.h @@ -243,7 +243,7 @@ inline int ObAddr::compare_refactored(const ObAddr &rv) const if (0 == ipcmp) { ipcmp = port_ - rv.port_; } - return 0 == ipcmp ? 0 : (ipcmp > 0 ? 1 : -1);; + return 0 == ipcmp ? 0 : (ipcmp > 0 ? 1 : -1); } // forward compatible diff --git a/deps/oblib/src/lib/xml/ob_multi_mode_interface.h b/deps/oblib/src/lib/xml/ob_multi_mode_interface.h index 021d89a5b..8b6f15171 100644 --- a/deps/oblib/src/lib/xml/ob_multi_mode_interface.h +++ b/deps/oblib/src/lib/xml/ob_multi_mode_interface.h @@ -211,7 +211,7 @@ public: new (dst_buf) T(*reinterpret_cast(src_buf)); } } else { - OB_LOG(WARN, "failed to construct ObStack", K(ret), K(length));; + OB_LOG(WARN, "failed to construct ObStack", K(ret), K(length)); } } @@ -611,4 +611,4 @@ protected: } // namespace common } // namespace oceanbase -#endif // OCEANBASE_SQL_OB_MULTI_MODE_INTERFACE \ No newline at end of file +#endif // OCEANBASE_SQL_OB_MULTI_MODE_INTERFACE 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 6a2b4c6aa..94a827326 100644 --- a/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h +++ b/deps/oblib/src/rpc/obrpc/ob_rpc_packet_list.h @@ -846,7 +846,7 @@ PCODE_DEF(OB_HIGH_PRIORITY_BATCH_TABLE_LOCK_TASK, 0x932) PCODE_DEF(OB_ARB_CLUSTER_OP, 0x933) #endif PCODE_DEF(OB_DETECT_SESSION_ALIVE, 0x934) -// PCODE_DEF(OB_BATCH_REPLACE_TABLE_LOCK_TASK, 0x935) +PCODE_DEF(OB_BATCH_REPLACE_TABLE_LOCK_TASK, 0x935) #ifdef OB_BUILD_ARBITRATION // PCODE_DEF(OB_LOG_PROBE_RS, 0x936) #endif @@ -865,20 +865,20 @@ PCODE_DEF(OB_CHECK_MEDIUM_INFO_LIST_CNT, 0x959) PCODE_DEF(OB_SPLIT_TABLET_DATA_FINISH_REQUEST, 0x960) PCODE_DEF(OB_MVIEW_COMPLETE_REFRESH, 0x961) PCODE_DEF(OB_CLEAR_TABLET_AUTOINC_SEQ_CACHE, 0x962) -//PCODE_DEF(OB_FREEZE_SPLIT_SRC_TABLET, 0x963) +PCODE_DEF(OB_FREEZE_SPLIT_SRC_TABLET, 0x963) PCODE_DEF(OB_CHECK_AND_CANCEL_DDL_COMPLEMENT_DAG, 0x964) -//PCODE_DEF(OB_CLEAN_SPLITTED_TABLET, 0x965) +PCODE_DEF(OB_CLEAN_SPLITTED_TABLET, 0x965) PCODE_DEF(OB_REMOTE_WRITE_DDL_FINISH_LOG, 0x966) PCODE_DEF(OB_REMOTE_WRITE_DDL_INC_COMMIT_LOG, 0x967) PCODE_DEF(OB_REMOTE_WRITE_DDL_INC_REDO_LOG, 0x968) -//PCODE_DEF(OB_AUTO_SPLIT_TABLET_TASK_REQUEST, 0x969) -//PCODE_DEF(OB_FETCH_SPLIT_TABLET_INFO, 0x96A) -//PCODE_DEF(OB_SPLIT_GLOBAL_INDEX_TABLET, 0x96B) -//PCODE_DEF(OB_PREPARE_TABLET_SPLIT_TASK_RANGES, 0x96C) +PCODE_DEF(OB_AUTO_SPLIT_TABLET_TASK_REQUEST, 0x969) +PCODE_DEF(OB_FETCH_SPLIT_TABLET_INFO, 0x96A) +PCODE_DEF(OB_SPLIT_GLOBAL_INDEX_TABLET, 0x96B) +PCODE_DEF(OB_PREPARE_TABLET_SPLIT_TASK_RANGES, 0x96C) PCODE_DEF(OB_BATCH_GET_TABLET_BINDING, 0x96D) //PCODE_DEF(OB_BATCH_UPGRADE_TABLE_SCHEMA, 0x96E) -//PCODE_DEF(OB_SPLIT_TABLET_DATA_START_REQUEST, 0x96F) -//PCODE_DEF(OB_BATCH_GET_TABLET_SPLIT, 0x970) +PCODE_DEF(OB_SPLIT_TABLET_DATA_START_REQUEST, 0x96F) +PCODE_DEF(OB_BATCH_GET_TABLET_SPLIT, 0x970) // Depedency Detector PCODE_DEF(OB_DETECTOR_LCL_MESSAGE, 0x9F0) diff --git a/deps/oblib/src/rpc/obrpc/ob_rpc_proxy.h b/deps/oblib/src/rpc/obrpc/ob_rpc_proxy.h index a96badee4..7dd7fc77a 100644 --- a/deps/oblib/src/rpc/obrpc/ob_rpc_proxy.h +++ b/deps/oblib/src/rpc/obrpc/ob_rpc_proxy.h @@ -163,7 +163,7 @@ public: || pcode == OB_OUT_TRANS_LOCK_TABLE || pcode == OB_OUT_TRANS_UNLOCK_TABLE || pcode == OB_TABLE_LOCK_TASK || pcode == OB_HIGH_PRIORITY_TABLE_LOCK_TASK || pcode == OB_BATCH_TABLE_LOCK_TASK - || pcode == OB_HIGH_PRIORITY_BATCH_TABLE_LOCK_TASK + || pcode == OB_HIGH_PRIORITY_BATCH_TABLE_LOCK_TASK || pcode == OB_BATCH_REPLACE_TABLE_LOCK_TASK || pcode == OB_REGISTER_TX_DATA || pcode == OB_REFRESH_SYNC_VALUE || pcode == OB_CLEAR_AUTOINC_CACHE || pcode == OB_CLEAN_SEQUENCE_CACHE || pcode == OB_FETCH_TABLET_AUTOINC_SEQ_CACHE diff --git a/mittest/mtlenv/storage/CMakeLists.txt b/mittest/mtlenv/storage/CMakeLists.txt index 6a0fa7ea8..ebf2a468d 100644 --- a/mittest/mtlenv/storage/CMakeLists.txt +++ b/mittest/mtlenv/storage/CMakeLists.txt @@ -34,6 +34,10 @@ storage_dml_unittest(test_tablet_aggregated_info test_tablet_aggregated_info.cpp # storage_unittest(test_speed_limit test_speed_limit.cpp) storage_dml_unittest(test_tablet_block_id_list test_tablet_block_id_list.cpp) storage_dml_unittest(test_ls_tablet_info_writer_and_reader test_ls_tablet_info_writer_and_reader.cpp) +storage_dml_unittest(test_auto_partition_split_range test_auto_partition_split_range.cpp) +#storage_dml_unittest(test_auto_partition_estimate) +#storage_dml_unittest(test_auto_partition_get_read_tables) +#storage_dml_unittest(test_auto_partition_scan_table) storage_dml_unittest(test_transfer_barrier test_transfer_barrier.cpp) add_subdirectory(checkpoint) diff --git a/mittest/mtlenv/storage/blocksstable/CMakeLists.txt b/mittest/mtlenv/storage/blocksstable/CMakeLists.txt index e83e16037..8cd21e91e 100644 --- a/mittest/mtlenv/storage/blocksstable/CMakeLists.txt +++ b/mittest/mtlenv/storage/blocksstable/CMakeLists.txt @@ -4,7 +4,7 @@ storage_dml_unittest(test_clustered_index_writer) storage_dml_unittest(test_index_block_row_struct) storage_dml_unittest(test_index_block_tree_cursor) storage_dml_unittest(test_index_block_row_scanner) -storage_unittest(test_index_tree) +storage_dml_unittest(test_index_tree) storage_dml_unittest(test_index_dumper) storage_dml_unittest(test_sstable_row_getter) storage_dml_unittest(test_sstable_row_multi_getter) diff --git a/mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h b/mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h index 320bafbd4..9a6322a59 100644 --- a/mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h +++ b/mittest/mtlenv/storage/blocksstable/ob_index_block_data_prepare.h @@ -256,6 +256,7 @@ int TestIndexBlockDataPrepare::gen_create_tablet_arg(const int64_t tenant_id, obrpc::ObCreateTabletInfo tablet_info; ObArray index_tablet_ids; ObArray index_tablet_schema_idxs; + ObArray create_commit_versions; arg.reset(); for(int64_t i = 0; OB_SUCC(ret) && i < count; i++) { @@ -273,6 +274,7 @@ int TestIndexBlockDataPrepare::gen_create_tablet_arg(const int64_t tenant_id, index_tablet_schema_idxs, lib::Worker::CompatMode::MYSQL, false, + create_commit_versions, false /*has_cs_replica*/))) { STORAGE_LOG(WARN, "failed to init tablet info", KR(ret), K(index_tablet_ids), K(tablet_id), K(index_tablet_schema_idxs)); diff --git a/mittest/mtlenv/storage/blocksstable/test_sstable_sec_meta_iterator.cpp b/mittest/mtlenv/storage/blocksstable/test_sstable_sec_meta_iterator.cpp index 4c9d624b4..eeae7b982 100644 --- a/mittest/mtlenv/storage/blocksstable/test_sstable_sec_meta_iterator.cpp +++ b/mittest/mtlenv/storage/blocksstable/test_sstable_sec_meta_iterator.cpp @@ -16,6 +16,7 @@ #include "storage/ob_partition_range_spliter.h" #include "storage/blocksstable/index_block/ob_sstable_sec_meta_iterator.h" +#include "storage/blocksstable/index_block/ob_index_block_macro_iterator.h" #include "storage/blocksstable/index_block/ob_index_block_dual_meta_iterator.h" #include "ob_index_block_data_prepare.h" diff --git a/mittest/mtlenv/storage/checkpoint/test_lock_memtable_checkpoint.cpp b/mittest/mtlenv/storage/checkpoint/test_lock_memtable_checkpoint.cpp index 05388d105..bf07bb871 100644 --- a/mittest/mtlenv/storage/checkpoint/test_lock_memtable_checkpoint.cpp +++ b/mittest/mtlenv/storage/checkpoint/test_lock_memtable_checkpoint.cpp @@ -105,24 +105,15 @@ TEST_F(TestLockMemtableCheckpoint, replay_disorder) commit_version.set_base(); commit_scn.set_base(); - // 1. get ls checkpoint + // 1.recover unlock op and lock op LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 1"); - ObCheckpointExecutor *checkpoint_executor = ls_->get_checkpoint_executor(); - ObCommonCheckpoint *checkpoint = - dynamic_cast( - checkpoint_executor - ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) - ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]; - - // 2.recover unlock op and lock op - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 2"); ret = memtable_->recover_obj_lock(DEFAULT_OUT_TRANS_UNLOCK_OP); ASSERT_EQ(OB_SUCCESS, ret); ret = memtable_->recover_obj_lock(DEFAULT_OUT_TRANS_LOCK_OP); ASSERT_EQ(OB_SUCCESS, ret); - // 3. update lock status disorder - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 3"); + // 2. update lock status disorder + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 2"); commit_version.val_ = 3; commit_scn.val_ = 3; ret = memtable_->update_lock_status(DEFAULT_OUT_TRANS_UNLOCK_OP, @@ -139,19 +130,17 @@ TEST_F(TestLockMemtableCheckpoint, replay_disorder) COMMIT_LOCK_OP_STATUS); ASSERT_EQ(OB_SUCCESS, ret); - // 4. check checkpoint + // 3. check checkpoint // The rec_scn should be equal with the smaller commit_scn - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 4"); + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 3"); ASSERT_EQ(commit_scn.val_, memtable_->get_rec_scn().val_); - share::SCN rec_scn = checkpoint->get_rec_scn(); - ASSERT_EQ(commit_scn.val_, rec_scn.val_); - // 5. flush and get a previous commit log + // 4. flush and get a previous commit log // You will find the log about disordered replay in the log file. - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 5"); + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 4"); ret = memtable_->recover_obj_lock(DEFAULT_OUT_TRANS_UNLOCK_OP); ASSERT_EQ(OB_SUCCESS, ret); - ASSERT_EQ(OB_SUCCESS, checkpoint->flush(share::SCN::max_scn(), 0)); + ASSERT_EQ(OB_SUCCESS, memtable_->flush(share::SCN::max_scn(), 0)); commit_version.val_ = 1; commit_scn.val_ = 1; ret = memtable_->update_lock_status(DEFAULT_OUT_TRANS_UNLOCK_OP, @@ -160,17 +149,15 @@ TEST_F(TestLockMemtableCheckpoint, replay_disorder) COMMIT_LOCK_OP_STATUS); ASSERT_EQ(OB_SUCCESS, ret); - // 6. check checkpoint + // 5. check checkpoint // The rec_scn should be equal with the smaller commit_scn // during flushing (i.e. it's get from pre_rec_scn) - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 6"); + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 5"); ASSERT_EQ(commit_scn.val_, memtable_->get_rec_scn().val_); - rec_scn = checkpoint->get_rec_scn(); - ASSERT_EQ(commit_scn.val_, rec_scn.val_); - // 7. get a commit log with a commit_scn which + // 6. get a commit log with a commit_scn which // is larger than freeze_scn during flushing - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 7"); + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 6"); ret = memtable_->recover_obj_lock(DEFAULT_OUT_TRANS_LOCK_OP); ASSERT_EQ(OB_SUCCESS, ret); commit_version.val_ = 4; @@ -180,29 +167,25 @@ TEST_F(TestLockMemtableCheckpoint, replay_disorder) commit_scn, COMMIT_LOCK_OP_STATUS); - // 8. check checkpoint + // 7. check checkpoint // The rec_scn should still be equal with the smaller // commit_scn during flushing (i.e. it's get from pre_rec_scn) - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 8"); + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 7"); ASSERT_EQ(1, memtable_->get_rec_scn().val_); - rec_scn = checkpoint->get_rec_scn(); - ASSERT_EQ(1, rec_scn.val_); - // 9. flush finish - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 9"); + // 8. flush finish + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 8"); ret = memtable_->on_memtable_flushed(); ASSERT_EQ(OB_SUCCESS, ret); - // 10. check checkpoint + // 9. check checkpoint // The rec_scn should be equal with the latest commit_scn // which got during previous flushing (i.e. it's get from rec_scn) - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 10"); + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 9"); ASSERT_EQ(commit_scn.val_, memtable_->get_rec_scn().val_); - rec_scn = checkpoint->get_rec_scn(); - ASSERT_EQ(commit_scn.val_, rec_scn.val_); - // 11. clean up - LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 11"); + // 10. clean up + LOG_INFO("TestLockMemtableCheckpoint::replay_disorder 10"); table_handle_.reset(); ls_handle_.reset(); ASSERT_EQ(OB_SUCCESS, MTL(ObLSService*)->remove_ls(ls_id_)); diff --git a/mittest/mtlenv/storage/test_auto_partition_estimate.cpp b/mittest/mtlenv/storage/test_auto_partition_estimate.cpp new file mode 100644 index 000000000..af7f84aee --- /dev/null +++ b/mittest/mtlenv/storage/test_auto_partition_estimate.cpp @@ -0,0 +1,566 @@ +/** + * 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 private public +#define protected public + +#include "share/schema/ob_table_param.h" +#include "share/schema/ob_table_dml_param.h" +#include "mtlenv/storage/blocksstable/ob_index_block_data_prepare.h" + +namespace oceanbase +{ +using namespace common; +using namespace storage; +using namespace share; + +namespace unittest +{ + +typedef ObSEArray ColDescArray; +static int64_t TEST_COLUMN_CNT=5; +static int64_t TEST_ROWKEY_COLUMN_CNT=1; + +class FakeObTabletEstimate : public ::testing::Test +{ +public: + FakeObTabletEstimate() : + tenant_id_(OB_SYS_TENANT_ID), + ls_id_(TestDmlCommon::TEST_LS_ID), + tablet_id_(TestDmlCommon::TEST_DATA_TABLE_ID), + access_service_(nullptr), + ls_service_(nullptr), + tx_desc_(nullptr), + table_param_(allocator_) + {} + + ~FakeObTabletEstimate(){} + + virtual void SetUp(); + virtual void TearDown(); + static void SetUpTestCase(); + static void TearDownTestCase(); + + int prepare_scan_range(); + int reset_scan_range(); + int prepare_scan_param(); + int insert_data(); + int set_tablet_split_info(ObTabletID &src_tablet_id, ObTabletID &origin_tablet_id, ObLSID &ls_id, ObTabletSplitType split_type, const int64_t split_cnt); + int estimate_row_count(int64_t &logical_row_count, int64_t &physical_row_count); + int estimate_block_count_and_row_count(ObTabletID &tablet_id, int64_t ¯o_block_count, int64_t µ_block_count, int64_t &sstable_row_count, int64_t &memtable_row_count); + ObLSTabletService *get_ls_service() { return ls_service_; } + int gen_datum_rowkey(const int64_t key_val, const int64_t key_cnt, ObDatumRowkey &rowkey); + ObDatumRowkey &get_start_key() { return start_key_; } + ObDatumRowkey &get_end_key() { return end_key_; } + +private: + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; + MockObAccessService *access_service_; + ObLSTabletService *ls_service_; + transaction::ObTxDesc *tx_desc_; + ColDescArray col_descs_; + ObTableScanRange scan_range_; + ObTableScanParam scan_param_; + ObTableParam table_param_; + ObTableSchema table_schema_; + ObTabletHandle tablet_handle_; + ObArenaAllocator allocator_; + ObDatumRowkey start_key_; + ObDatumRowkey end_key_; +}; + +void FakeObTabletEstimate::SetUpTestCase() +{ + ASSERT_EQ(OB_SUCCESS, MockTenantModuleEnv::get_instance().init()); + MTL(transaction::ObTransService*)->tx_desc_mgr_.tx_id_allocator_ = + [](transaction::ObTransID &tx_id) { tx_id = transaction::ObTransID(1001); return OB_SUCCESS; }; + ObServerCheckpointSlogHandler::get_instance().is_started_ = true; +} + +void FakeObTabletEstimate::TearDownTestCase() +{ + MockTenantModuleEnv::get_instance().destroy(); +} + +void FakeObTabletEstimate::SetUp() +{ + int ret = OB_SUCCESS; + + ObLSHandle ls_handle; + ret = TestDmlCommon::create_ls(tenant_id_, ls_id_, ls_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + // mock ls tablet service and access service + ret = TestDmlCommon::mock_ls_tablet_service(ls_id_, ls_service_); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, ls_service_); + + ret = TestDmlCommon::mock_access_service(ls_service_, access_service_); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, access_service_); + + ObTableSchema table_schema; + TestDmlCommon::build_data_table_schema(tenant_id_, table_schema); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id_, table_schema, allocator_)); + ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id_, tablet_handle_)); + + ASSERT_EQ(OB_SUCCESS, prepare_scan_param()); // prepare scan range (defaut whole range) + ret = col_descs_.assign(tablet_handle_.get_obj()->get_rowkey_read_info().get_columns_desc()); + ASSERT_EQ(OB_SUCCESS, ret); + + ASSERT_EQ(OB_SUCCESS, insert_data()); +} + +void FakeObTabletEstimate::TearDown() +{ + access_service_ = nullptr; + tx_desc_ = nullptr; + tablet_handle_.reset(); + col_descs_.reset(); + scan_range_.reset(); + table_param_.reset(); + start_key_.reset(); + end_key_.reset(); + + ASSERT_EQ(OB_SUCCESS, MTL(ObLSService*)->remove_ls(ls_id_, false)); + + TestDmlCommon::delete_mocked_access_service(access_service_); + TestDmlCommon::delete_mocked_ls_tablet_service(ls_service_); +} + +int FakeObTabletEstimate::set_tablet_split_info( + ObTabletID &src_tablet_id, + ObTabletID &origin_tablet_id, + ObLSID &ls_id, + ObTabletSplitType split_type, + const int64_t split_count) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTabletSplitTscInfo split_info; + ObLSHandle ls_handle; + ObLSID test_ls_id(ls_id_); + + if (OB_FAIL(MTL(ObLSService *)->get_ls(test_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + STORAGE_LOG(WARN, "fail to get log stream", K(ret), K(ls_handle)); + } else if (OB_UNLIKELY(nullptr == ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls is null", K(ret), K(ls_handle)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(src_tablet_id, tablet_handle))) { + STORAGE_LOG(WARN, "fail to get tablet", K(ret), K(src_tablet_id)); + } else if (OB_ISNULL(tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet handle obj is null", K(ret), K(tablet_handle)); + } else { + split_info.split_cnt_= split_count; + split_info.split_type_ = split_type; + split_info.start_key_ = start_key_; // not set is invalid + split_info.end_key_ = end_key_; // not set is invalid + split_info.src_tablet_handle_ = tablet_handle; + tablet_handle.get_obj()->set_split_info(split_info); + } + + return ret; +} + +int FakeObTabletEstimate::prepare_scan_range() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(scan_range_.init(scan_param_))) { + STORAGE_LOG(WARN, "fail to init scan range.", K(ret), K(scan_range_)); + } + return ret; +} + +int FakeObTabletEstimate::reset_scan_range() +{ + scan_range_.reset(); + return OB_SUCCESS; +} + +int FakeObTabletEstimate::estimate_row_count(int64_t &logical_row_count, int64_t &physical_row_count) +{ + int ret = OB_SUCCESS; + logical_row_count = 0; + physical_row_count = 0; + common::ObSEArray est_records; + ls_service_->enable_to_read(); + if (OB_ISNULL(ls_service_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "error unexpected.", K(ret), K(ls_service_)); + } else if (OB_FAIL(ls_service_->estimate_row_count( + scan_param_, scan_range_, est_records, logical_row_count, physical_row_count))) { + STORAGE_LOG(WARN, "fail to do estimate row count", K(ret), K(scan_param_), K(scan_range_)); + } + return ret; +} + +int FakeObTabletEstimate::insert_data() +{ + int ret = OB_SUCCESS; + if (nullptr == access_service_ || OB_ISNULL(tablet_handle_.get_obj()) || OB_ISNULL(tx_desc_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "null pointer, unexpected.", K(ret), K(access_service_), K(tablet_handle_), K(tx_desc_)); + } else { + // insert rows + ObMockNewRowIterator mock_iter; + ObSEArray column_ids; + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 0); // pk + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 1); // c1 + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 2); // c2 + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 3); // c3 + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 4); // c4 + + if (OB_FAIL(mock_iter.from(TestDmlCommon::data_row_str))) { + STORAGE_LOG(WARN, "mock iter from fail.", K(ret), K(mock_iter)); + } else { + ObTxParam tx_param; + int64_t savepoint = 0; + transaction::ObTransService *tx_service = MTL(transaction::ObTransService*); + if (FALSE_IT(TestDmlCommon::build_tx_param(tx_param))) { + } else if (OB_FAIL(tx_service->create_implicit_savepoint(*tx_desc_, tx_param, savepoint, true))) { + STORAGE_LOG(WARN, "fail to create implicit savepoint.", K(ret), K(tx_desc_), K(tx_param)); + } else { + ObTxReadSnapshot read_snapshot; + ObTxIsolationLevel isolation = ObTxIsolationLevel::RC; + int64_t expire_ts = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + if (OB_FAIL(tx_service->get_read_snapshot(*tx_desc_, isolation, expire_ts, read_snapshot))) { + STORAGE_LOG(WARN, "fail to get read snapshot.", K(ret), K(expire_ts)); + } else { + ObDMLBaseParam dml_param; + dml_param.timeout_ = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + dml_param.is_total_quantity_log_ = false; + dml_param.tz_info_ = NULL; + dml_param.sql_mode_ = SMO_DEFAULT; + dml_param.schema_version_ = share::OB_CORE_SCHEMA_VERSION + 1; + dml_param.tenant_schema_version_ = share::OB_CORE_SCHEMA_VERSION + 1; + dml_param.encrypt_meta_ = &dml_param.encrypt_meta_legacy_; + dml_param.snapshot_ = read_snapshot; + + share::schema::ObTableDMLParam table_dml_param(allocator_); + if (OB_FAIL(table_dml_param.convert(&table_schema_, 1, column_ids))) { + STORAGE_LOG(WARN, "fail to covert dml param.", K(ret), K(table_schema_)); + } else { + dml_param.table_param_ = &table_dml_param; + int64_t affected_rows = 0; + if (OB_FAIL(access_service_->insert_rows( + ls_id_, tablet_id_, *tx_desc_, dml_param, column_ids, &mock_iter, affected_rows))) { + STORAGE_LOG(WARN, "fail to insert rows.", K(ret)); + } else if (affected_rows != 12) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "affected rows not equal to insert rows(12).", K(affected_rows)); + } else { + expire_ts = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + if (OB_FAIL(tx_service->commit_tx(*tx_desc_, expire_ts))) { + STORAGE_LOG(WARN, "fail to commit tx.", K(ret), K(expire_ts)); + } else { + tx_service->release_tx(*tx_desc_); + } + } + } + } + } + } + } + return ret; +} + +int FakeObTabletEstimate::estimate_block_count_and_row_count( + ObTabletID &tablet_id, + int64_t ¯o_block_count, + int64_t µ_block_count, + int64_t &sstable_row_count, + int64_t &memtable_row_count) +{ + int ret = OB_SUCCESS; + macro_block_count = 0; + micro_block_count = 0; + + if (!tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid tablet id.", K(ret), K(tablet_id)); + } else if (OB_ISNULL(ls_service_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "error unexpected.", K(ret), K(ls_service_)); + } else if (OB_FAIL(ls_service_->estimate_block_count_and_row_count(tablet_id, macro_block_count, micro_block_count, sstable_row_count, memtable_row_count))) { + STORAGE_LOG(WARN, "fail to do estimate block count.", K(ret), K(tablet_id)); + } + + return ret; +} + +int FakeObTabletEstimate::prepare_scan_param() +{ + int ret = OB_SUCCESS; + // prepare table schema + if (OB_FALSE_IT(TestDmlCommon::build_data_table_schema(tenant_id_, table_schema_))) { + } else if (OB_FAIL(TestDmlCommon::build_tx_desc(tenant_id_, tx_desc_))) { // 1. get tx desc + STORAGE_LOG(WARN, "fail to build tx desc.", K(ret), K(tenant_id_)); + } else { + ObTxIsolationLevel isolation = ObTxIsolationLevel::RC; + int64_t expire_ts = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + ObTxReadSnapshot read_snapshot; + transaction::ObTransService *tx_service = MTL(transaction::ObTransService*); + if (OB_FAIL(tx_service->get_read_snapshot(*tx_desc_, isolation, expire_ts, read_snapshot))) { // 2. get read snapshot + STORAGE_LOG(WARN, "fail to get_read_snapshot.", K(ret)); + } else { + ObSArray colunm_ids; + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 0); + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 1); + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 2); + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 3); + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 4); + if (OB_FAIL(TestDmlCommon::build_table_param(table_schema_, colunm_ids, table_param_))) { // build table param + STORAGE_LOG(WARN, "fail to build table param.", K(ret), K(colunm_ids), K(table_schema_)); + } else if (OB_FAIL(TestDmlCommon::build_table_scan_param(tenant_id_, read_snapshot, table_param_, scan_param_))) { // 4. build scan param + STORAGE_LOG(WARN, "fail to build table scan param.", K(ret), K(tenant_id_), K(read_snapshot)); + } + } + } + return ret; +} + +int FakeObTabletEstimate::gen_datum_rowkey(const int64_t key_val, const int64_t key_cnt, ObDatumRowkey &datum_rowkey) +{ + int ret = OB_SUCCESS; + ObObj *key_val_obj = NULL; + ObRowkey rowkey; + if (NULL == (key_val_obj = static_cast(allocator_.alloc(sizeof(ObObj) * key_cnt)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "out of memory", K(ret)); + } else { + for (int64_t i = 0; i < key_cnt; ++i) { + key_val_obj[i].set_int(key_val); + // key_val_obj[i].set_min(); + } + rowkey.assign(key_val_obj, key_cnt); + if (OB_FAIL(datum_rowkey.from_rowkey(rowkey, allocator_))) { + STORAGE_LOG(WARN, "fail to from rowkey", K(ret)); + } + } + return ret; +} + +TEST_F(FakeObTabletEstimate, test_split_tablet_estimate) +{ +// =================================== not set split info =============================================== + int ret = OB_SUCCESS; + + int64_t macro_block_cnt = 0; + int64_t micro_block_cnt = 0; + int64_t sstable_row_cnt = 0; + int64_t memtable_row_cnt = 0; + int64_t logical_row_count = 0; + int64_t physical_row_count = 0; + int64_t split_cnt = 1; + + // 1. do not set split info + ObTabletID src_tablet_id(TestDmlCommon::TEST_DATA_TABLE_ID); + ObTabletID ori_tablet_id(TestDmlCommon::TEST_DATA_TABLE_ID); + + ObLSID ls_id(TestDmlCommon::TEST_LS_ID); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); // TestIndexBlockDataPrepare::12 + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + // TODO: local index table + + // ============================test_estimate_row_set_wrong_split_info=================================== + // 2. wrong ls_id; + ObLSID wrong_ls_id(111); + /* main table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, wrong_ls_id, ObTabletSplitType::RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + /* local index table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, wrong_ls_id, ObTabletSplitType::NONE_RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + // 3. wrong ori tablet_id; + ObTabletID wrong_ori_tablet_id(222); + /* main table */ + ret = set_tablet_split_info(src_tablet_id, wrong_ori_tablet_id, ls_id, ObTabletSplitType::RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + /* local index table */ + ret = set_tablet_split_info(src_tablet_id, wrong_ori_tablet_id, ls_id, ObTabletSplitType::NONE_RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + // 4. wrong split_cnt + split_cnt = 0; + /* main table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, ls_id, ObTabletSplitType::RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + /* local index table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, ls_id, ObTabletSplitType::NONE_RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + // // ==================================== test_estimate_row_right_set_split_info ====================================== + int64_t start_val = 0; + int64_t end_val = 0; + + // 1. do not split range + split_cnt = 1.0; + /* main table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, ls_id, ObTabletSplitType::RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); // not set split key, invalid spilt info. + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + /* local index table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, ls_id, ObTabletSplitType::NONE_RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(12, logical_row_count); + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + + // 2. do split range + split_cnt = 1.0; + start_val = 1; // include eage + end_val = 6; // not include eage + int64_t key_cnt = 1; + ret = gen_datum_rowkey(start_val, key_cnt, get_start_key()); + ASSERT_EQ(OB_SUCCESS, ret); + ret = gen_datum_rowkey(end_val, key_cnt, get_end_key()); + ASSERT_EQ(OB_SUCCESS, ret); + + /* main table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, ls_id, ObTabletSplitType::RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); // cut scan range using split info + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(10, logical_row_count); // two tablets + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + /* local index table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, ls_id, ObTabletSplitType::NONE_RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); // cut scan range using split info + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(24, logical_row_count); // two tablets total data + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + // ### because estimate block is calculate block metas count, has no relation with range + + // 3. set split ratio 0.5; + split_cnt = 2; + start_val = 1; // include edge + end_val = 6; // not include edge + int64_t key_cnt = 1; + ret = gen_datum_rowkey(start_val, key_cnt, get_start_key()); + ASSERT_EQ(OB_SUCCESS, ret); + ret = gen_datum_rowkey(end_val, key_cnt, get_end_key()); + ASSERT_EQ(OB_SUCCESS, ret); + + /* main table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, ls_id, ObTabletSplitType::RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); // cut scan range using split info + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(10, logical_row_count); // counts of two tablets in split range + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + + /* local index table */ + ret = set_tablet_split_info(src_tablet_id, ori_tablet_id, ls_id, ObTabletSplitType::NONE_RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, prepare_scan_range()); // cut scan range using split info + ret = estimate_row_count(logical_row_count, physical_row_count); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(24, logical_row_count); + ret = estimate_block_count_and_row_count(src_tablet_id, macro_block_cnt, micro_block_cnt, sstable_row_cnt, memtable_row_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + ASSERT_EQ(OB_SUCCESS, reset_scan_range()); + // ### because estimate block is calculate block metas count, has no relation with range +} + +} // namespace unittest +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -rf test_auto_partition_estimate.log"); + OB_LOGGER.set_file_name("test_auto_partition_estimate.log", true); + OB_LOGGER.set_log_level("WARN"); + CLOG_LOG(INFO, "begin unittest: test_auto_partition_estimate"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/mtlenv/storage/test_auto_partition_get_read_tables.cpp b/mittest/mtlenv/storage/test_auto_partition_get_read_tables.cpp new file mode 100644 index 000000000..7047d2b9d --- /dev/null +++ b/mittest/mtlenv/storage/test_auto_partition_get_read_tables.cpp @@ -0,0 +1,222 @@ +/** + * 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 private public +#define protected public + +#include "src/storage/ob_storage_struct.h" +#include "src/share/ob_rpc_struct.h" +#include "src/storage/meta_mem/ob_tablet_handle.h" +#include "src/storage/tx_storage/ob_ls_handle.h" +#include "src/storage/tx_storage/ob_ls_service.h" +#include "src/storage/tablet/ob_tablet.h" + + +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/test_tablet_helper.h" +#include "storage/init_basic_struct.h" +#include "mtlenv/mock_tenant_module_env.h" +#include "storage/test_dml_common.h" +#include "mtlenv/mock_tenant_module_env.h" +#include "observer/ob_safe_destroy_thread.h" + +namespace oceanbase +{ +using namespace common; +using namespace storage; +using namespace share; + +namespace unittest +{ + +static uint64_t TEST_TENANT_ID = 1001; +static int64_t TEST_LS_ID = 101; +static int64_t TEST_SRC_TABLET_ID = 10001; +static int64_t TEST_ORI_TABLET_ID = 10002; + +class FakeObGetReadTables : public ::testing::Test +{ +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + +public: + FakeObGetReadTables() : + snapshot_version_(0), + allow_not_ready_(false), + split_type_(ObTabletSplitType::MAX_TYPE) + {} + + ~FakeObGetReadTables() + {} + + int set_tablet_split_info(ObTabletID &src_tablet_id, ObTabletID &origin_tablet_id, ObLSID &ls_id); + int gen_datum_rowkey(const int64_t key_val, const int64_t key_cnt, ObDatumRowkey &datum_rowkey); + int64_t get_read_tables_count(ObTabletID &src_tablet_id); + + void set_snapshot_version(int64_t snapshot_version) { snapshot_version_ = snapshot_version; } + void set_split_type(ObTabletSplitType split_type) { split_type_ = split_type; } + void set_allow_not_ready(bool need) { allow_not_ready_ = need; } + +private: + ObTabletTableIterator iterator_; + static ObArenaAllocator allocator_; + int64_t snapshot_version_; + bool allow_not_ready_; + ObTabletSplitType split_type_; +}; + +ObArenaAllocator FakeObGetReadTables::allocator_; + +void FakeObGetReadTables::SetUpTestCase() +{ + int ret = OB_SUCCESS; + ret = MockTenantModuleEnv::get_instance().init(); + ASSERT_EQ(OB_SUCCESS, ret); + ObServerCheckpointSlogHandler::get_instance().is_started_ = true; + + // create ls + const ObLSID ls_id(TEST_LS_ID); + ObLSHandle ls_handle; + ret = TestDmlCommon::create_ls(TEST_TENANT_ID, ls_id, ls_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + const int64_t table_id = 12345; + share::schema::ObTableSchema table_schema; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + + // create tablet_1 + ObTabletID src_tablet_id(TEST_SRC_TABLET_ID); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, src_tablet_id, table_schema, allocator_)); + + // create tablet_2 + ObTabletID ori_tablet_id(TEST_ORI_TABLET_ID); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, ori_tablet_id, table_schema, allocator_)); +} + +void FakeObGetReadTables::TearDownTestCase() +{ + int ret = OB_SUCCESS; + ret = MTL(ObLSService*)->remove_ls(ObLSID(TEST_LS_ID), false); + ASSERT_EQ(OB_SUCCESS, ret); + MockTenantModuleEnv::get_instance().destroy(); +} + +// return tables count +int64_t FakeObGetReadTables::get_read_tables_count(ObTabletID &src_tablet_id) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + int64_t tables_count = 0; + ObLSID test_ls_id(TEST_LS_ID); + + if (OB_FAIL(MTL(ObLSService *)->get_ls(test_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + STORAGE_LOG(WARN, "fail to get log stream", K(ret), K(ls_handle)); + } else if (OB_UNLIKELY(nullptr == ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls is null", K(ret), K(ls_handle)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet_svr()->get_read_tables( + src_tablet_id, + snapshot_version_, + iterator_, + allow_not_ready_, + true /* get split src table if need */))) { + STORAGE_LOG(WARN, "fail to get tablet tables", K(ret), K(src_tablet_id)); + } else { + if (!iterator_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "invalid iterator.", K(ret), K(src_tablet_id)); + } else { + tables_count = iterator_.table_iter()->count(); + } + } + + return tables_count; +} + +int FakeObGetReadTables::gen_datum_rowkey(const int64_t key_val, const int64_t key_cnt, ObDatumRowkey &datum_rowkey) +{ + int ret = OB_SUCCESS; + ObObj *key_val_obj = NULL; + ObRowkey rowkey; + if (NULL == (key_val_obj = static_cast(allocator_.alloc(sizeof(ObObj) * key_cnt)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "out of memory", K(ret)); + } else { + for (int64_t i = 0; i < key_cnt; ++i) { + key_val_obj[i].set_int(key_val); + // key_val_obj[i].set_min(); + } + rowkey.assign(key_val_obj, key_cnt); + if (OB_FAIL(datum_rowkey.from_rowkey(rowkey, allocator_))) { + STORAGE_LOG(WARN, "fail to from rowkey", K(ret)); + } + } + return ret; +} + +int FakeObGetReadTables::set_tablet_split_info(ObTabletID &src_tablet_id) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTabletSplitTscInfo split_info; + ObLSHandle ls_handle; + ObLSID test_ls_id(TEST_LS_ID); + if (OB_FAIL(MTL(ObLSService *)->get_ls(test_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + STORAGE_LOG(WARN, "fail to get log stream", K(ret), K(ls_handle)); + } else if (OB_UNLIKELY(nullptr == ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls is null", K(ret), K(ls_handle)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(src_tablet_id, tablet_handle))) { + STORAGE_LOG(WARN, "fail to get tablet", K(ret), K(src_tablet_id)); + } else if (OB_ISNULL(tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet handle obj is null", K(ret), K(tablet_handle)); + } else if (OB_FAIL(gen_datum_rowkey(1, 1, split_info.start_key_))) { + STORAGE_LOG(WARN, "gen start key fail.", K(ret)); + } else if (OB_FAIL(gen_datum_rowkey(2, 1, split_info.end_key_))) { + STORAGE_LOG(WARN, "gen end key fail.", K(ret)); + } else { + split_info.split_cnt_= 1; + split_info.src_tablet_handle_ = tablet_handle; + split_info.split_type_ = ObTabletSplitType::RANGE; + } + return ret; +} + +TEST_F(FakeObGetReadTables, test_right_set_split_info) +{ + int ret = OB_SUCCESS; + set_snapshot_version(INT64_MAX); + set_allow_not_ready(false); + + ObTabletID src_tablet_id(TEST_SRC_TABLET_ID); + ret = set_tablet_split_info(src_tablet_id); + ASSERT_EQ(ret, OB_SUCCESS); + ret = get_read_tables_count(src_tablet_id); + ASSERT_EQ(ret, 2); // both src tablet and origin tables, major; +} + +} // namespace unittest +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -rf test_auto_partition_get_read_tables.log"); + OB_LOGGER.set_file_name("test_auto_partition_get_read_tables.log", true); + OB_LOGGER.set_log_level("WARN"); + CLOG_LOG(INFO, "begin unittest: test_auto_partition_get_read_tables"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/mtlenv/storage/test_auto_partition_scan_table.cpp b/mittest/mtlenv/storage/test_auto_partition_scan_table.cpp new file mode 100644 index 000000000..c6b198132 --- /dev/null +++ b/mittest/mtlenv/storage/test_auto_partition_scan_table.cpp @@ -0,0 +1,382 @@ +/** + * 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 private public +#define protected public + +#include "share/schema/ob_table_param.h" +#include "share/schema/ob_table_dml_param.h" +#include "mtlenv/storage/blocksstable/ob_index_block_data_prepare.h" + + +/* + 0. 用主表模拟局部索引表扫描,两者差别在于主表会进行范围切割,局部索引表会进行 行过滤 + 1. 创建分区 + 2. 设置分区为split状态,把自己设置为局部索引,并且把origin tablet id设置为自己 + 3. 启动table_scan + 4. 预期逻辑 + 1)同时获取origin table的tables ; + 2)不会cut range; + 3)根据当前tablet id 过滤数据,当然当前代码里分裂后的schema没有变更,计算分区方式也没有改变,因此数据全部符合 +*/ + +namespace oceanbase +{ +using namespace common; +using namespace storage; +using namespace share; + +namespace unittest +{ +class FakeObScanTable : public ::testing::Test +{ +public: + FakeObScanTable() : + tenant_id_(OB_SYS_TENANT_ID), + ls_id_(TestDmlCommon::TEST_LS_ID), + tablet_id_(TestDmlCommon::TEST_DATA_TABLE_ID), + orig_tablet_id_(51) + {} + + ~FakeObScanTable(){} + + static void SetUpTestCase(); + static void TearDownTestCase(); + + void table_scan(ObAccessService *access_service, ObNewRowIterator *&result); + void insert_data_to_tablet(MockObAccessService *access_service, ObTabletID &tablet_id, const char *data); + int set_tablet_split_info(ObTabletID &src_tablet_id, ObTabletSplitType split_type, const int64_t split_cnt); + int gen_datum_rowkey(const int64_t key_val, const int64_t key_cnt, ObDatumRowkey &datum_rowkey); + ObDatumRowkey &get_start_key() { return start_key_; } + ObDatumRowkey &get_end_key() { return end_key_; } + +protected: + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObTabletID tablet_id_; + common::ObTabletID orig_tablet_id_; + +private: + ObArenaAllocator allocator_; + ObRowkey start_key_; + ObRowkey end_key_; + +public: + static constexpr const char *data_row_str_01 = + "bigint bigint bigint var var dml \n" + "1 62 20 Houston Rockets T_DML_INSERT \n" + "2 65 17 SanAntonio Spurs T_DML_INSERT \n" + "3 58 24 Dallas Mavericks T_DML_INSERT \n" + "4 51 31 LosAngeles Lakers T_DML_INSERT \n" + "5 57 25 Phoenix Suns T_DML_INSERT \n" + "6 32 50 NewJersey Nets T_DML_INSERT \n" + "7 44 38 Miami Heats T_DML_INSERT \n" + "8 21 61 Chicago Bulls T_DML_INSERT \n" + "9 47 35 Cleveland Cavaliers T_DML_INSERT \n" + "10 59 23 Detroit Pistons T_DML_INSERT \n" + "11 40 42 Utah Jazz T_DML_INSERT \n" + "12 50 32 Boston Celtics T_DML_INSERT \n"; + + static constexpr const char *data_row_str_02 = + "bigint bigint bigint var var dml \n" + "13 62 20 Houston Rockets T_DML_INSERT \n" + "14 65 17 SanAntonio Spurs T_DML_INSERT \n" + "15 58 24 Dallas Mavericks T_DML_INSERT \n" + "16 51 31 LosAngeles Lakers T_DML_INSERT \n" + "17 57 25 Phoenix Suns T_DML_INSERT \n" + "18 32 50 NewJersey Nets T_DML_INSERT \n" + "19 44 38 Miami Heats T_DML_INSERT \n" + "20 21 61 Chicago Bulls T_DML_INSERT \n" + "21 47 35 Cleveland Cavaliers T_DML_INSERT \n" + "22 59 23 Detroit Pistons T_DML_INSERT \n" + "23 40 42 Utah Jazz T_DML_INSERT \n" + "24 50 32 Boston Celtics T_DML_INSERT \n"; + +}; + +void FakeObScanTable::SetUpTestCase() +{ + ASSERT_EQ(OB_SUCCESS, MockTenantModuleEnv::get_instance().init()); + MTL(transaction::ObTransService*)->tx_desc_mgr_.tx_id_allocator_ = + [](transaction::ObTransID &tx_id) { tx_id = transaction::ObTransID(1001); return OB_SUCCESS; }; + + ObServerCheckpointSlogHandler::get_instance().is_started_ = true; +} + +void FakeObScanTable::TearDownTestCase() +{ + MockTenantModuleEnv::get_instance().destroy(); +} + +int FakeObScanTable::set_tablet_split_info( + ObTabletID &src_tablet_id, + ObTabletSplitType split_type, + const int64_t split_cnt) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTabletSplitTscInfo split_info; + ObLSHandle ls_handle; + ObLSID test_ls_id(ls_id_); + + if (OB_FAIL(MTL(ObLSService *)->get_ls(test_ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + STORAGE_LOG(WARN, "fail to get log stream", K(ret), K(ls_handle)); + } else if (OB_UNLIKELY(nullptr == ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ls is null", K(ret), K(ls_handle)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(src_tablet_id, tablet_handle))) { + STORAGE_LOG(WARN, "fail to get tablet", K(ret), K(src_tablet_id)); + } else if (OB_ISNULL(tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "tablet handle obj is null", K(ret), K(tablet_handle)); + } else { + split_info.split_cnt_= split_cnt; + split_info.split_type_ = split_type; + split_info.start_key_ = start_key_; // not set is invalid + split_info.end_key_ = end_key_; // not set is invalid + split_info.src_tablet_handle_ = tablet_handle; + // tablet_handle.get_obj()->set_split_info(split_info); + } + return ret; +} + +int FakeObScanTable::gen_datum_rowkey(const int64_t key_val, const int64_t key_cnt, ObDatumRowkey &datum_rowkey) +{ + int ret = OB_SUCCESS; + ObObj *key_val_obj = NULL; + ObRowkey rowkey; + if (NULL == (key_val_obj = static_cast(allocator_.alloc(sizeof(ObObj) * key_cnt)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "out of memory", K(ret)); + } else { + for (int64_t i = 0; i < key_cnt; ++i) { + key_val_obj[i].set_int(key_val); + // key_val_obj[i].set_min(); + } + rowkey.assign(key_val_obj, key_cnt); + if (OB_FAIL(datum_rowkey.from_rowkey(rowkey, allocator_))) { + STORAGE_LOG(WARN, "fail to from rowkey", K(ret)); + } + } + return ret; +} + +void FakeObScanTable::insert_data_to_tablet(MockObAccessService *access_service, ObTabletID &tablet_id, const char *data) +{ + ASSERT_NE(nullptr, access_service); + ASSERT_NE(nullptr, data); + + 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)); + ObLS *ls = ls_handle.get_ls(); + ASSERT_NE(nullptr, ls); + ASSERT_EQ(OB_SUCCESS, ls->get_tablet(tablet_id, tablet_handle)); + ObTablet *tablet = tablet_handle.get_obj(); + ASSERT_NE(nullptr, tablet); + + // insert rows + ObMockNewRowIterator mock_iter; + ObSEArray column_ids; + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 0); // pk + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 1); // c1 + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 2); // c2 + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 3); // c3 + column_ids.push_back(OB_APP_MIN_COLUMN_ID + 4); // c4 + + ASSERT_EQ(OB_SUCCESS, mock_iter.from(data)); + + transaction::ObTransService *tx_service = MTL(transaction::ObTransService*); + // 1. get tx desc + transaction::ObTxDesc *tx_desc = nullptr; + ASSERT_EQ(OB_SUCCESS, TestDmlCommon::build_tx_desc(tenant_id_, tx_desc)); + + // 2. create savepoint (can be rollbacked) + ObTxParam tx_param; + TestDmlCommon::build_tx_param(tx_param); + int64_t savepoint = 0; + ASSERT_EQ(OB_SUCCESS, tx_service->create_implicit_savepoint(*tx_desc, tx_param, savepoint, true)); + // 3. acquire snapshot (write also need snapshot) + ObTxIsolationLevel isolation = ObTxIsolationLevel::RC; + int64_t expire_ts = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + ObTxReadSnapshot read_snapshot; + ASSERT_EQ(OB_SUCCESS, tx_service->get_read_snapshot(*tx_desc, isolation, expire_ts, read_snapshot)); + + // 4. storage dml + ObDMLBaseParam dml_param; + dml_param.timeout_ = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + dml_param.is_total_quantity_log_ = false; + dml_param.tz_info_ = NULL; + dml_param.sql_mode_ = SMO_DEFAULT; + dml_param.schema_version_ = share::OB_CORE_SCHEMA_VERSION + 1; + dml_param.tenant_schema_version_ = share::OB_CORE_SCHEMA_VERSION + 1; + dml_param.encrypt_meta_ = &dml_param.encrypt_meta_legacy_; + dml_param.snapshot_ = read_snapshot; + + ObArenaAllocator allocator; + share::schema::ObTableDMLParam table_dml_param(allocator); + + share::schema::ObTableSchema table_schema; + TestDmlCommon::build_data_table_schema(tenant_id_, table_schema); + + ASSERT_EQ(OB_SUCCESS, table_dml_param.convert(&table_schema, 1, column_ids)); + dml_param.table_param_ = &table_dml_param; + + int64_t affected_rows = 0; + ASSERT_EQ(OB_SUCCESS, access_service->insert_rows(ls_id_, tablet_id, + *tx_desc, dml_param, column_ids, &mock_iter, affected_rows)); + + ASSERT_EQ(12, affected_rows); + + // 5. submit transaction, or rollback + expire_ts = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + ASSERT_EQ(OB_SUCCESS, tx_service->commit_tx(*tx_desc, expire_ts)); + + // 6. release tx desc + tx_service->release_tx(*tx_desc); +} + +void FakeObScanTable::table_scan( + ObAccessService *access_service, + ObNewRowIterator *&result) +{ + // prepare table schema + share::schema::ObTableSchema table_schema; + TestDmlCommon::build_data_table_schema(tenant_id_, table_schema); + + // 1. get tx desc + transaction::ObTxDesc *tx_desc = nullptr; + ASSERT_EQ(OB_SUCCESS, TestDmlCommon::build_tx_desc(tenant_id_, tx_desc)); + + // 2. get read snapshot + ObTxIsolationLevel isolation = ObTxIsolationLevel::RC; + int64_t expire_ts = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + ObTxReadSnapshot read_snapshot; + transaction::ObTransService *tx_service = MTL(transaction::ObTransService*); + ASSERT_EQ(OB_SUCCESS, tx_service->get_read_snapshot(*tx_desc, isolation, expire_ts, read_snapshot)); + + // 3. storage dml + // build table param + ObArenaAllocator allocator; + share::schema::ObTableParam table_param(allocator); + ObSArray colunm_ids; + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 0); + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 1); + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 2); + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 3); + colunm_ids.push_back(OB_APP_MIN_COLUMN_ID + 4); + + ASSERT_EQ(OB_SUCCESS, TestDmlCommon::build_table_param(table_schema, colunm_ids, table_param)); + + ObTableScanParam scan_param; + ASSERT_EQ(OB_SUCCESS, TestDmlCommon::build_table_scan_param(tenant_id_, read_snapshot, table_param, scan_param)); + + const share::ObLSID ls_id(TestDmlCommon::TEST_LS_ID); + ASSERT_EQ(OB_SUCCESS, access_service->table_scan(scan_param, result)); + ASSERT_TRUE(nullptr != result); + + // print data + int ret = OB_SUCCESS; + int cnt = 0; + ObNewRow *row = nullptr; + while (OB_SUCC(ret)) { + ret = result->get_next_row(row); + if (OB_SUCCESS == ret) { + ++cnt; + } + STORAGE_LOG(WARN, "table scan row", KPC(row)); + } + ASSERT_EQ(24, cnt); + + // 4. submit transaction, or rollback + expire_ts = ObTimeUtility::current_time() + TestDmlCommon::TX_EXPIRE_TIME_US; + ASSERT_EQ(OB_SUCCESS, tx_service->commit_tx(*tx_desc, expire_ts)); + + // 5. release tx desc + tx_service->release_tx(*tx_desc); +} + +TEST_F(FakeObScanTable, table_scan_pure_data_table) +{ + int ret = OB_SUCCESS; + + ObLSHandle ls_handle; + ret = TestDmlCommon::create_ls(tenant_id_, ls_id_, ls_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + // mock ls tablet service and access service + ObLSTabletService *tablet_service = nullptr; + ret = TestDmlCommon::mock_ls_tablet_service(ls_id_, tablet_service); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, tablet_service); + + MockObAccessService *access_service = nullptr; + ret = TestDmlCommon::mock_access_service(tablet_service, access_service); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, access_service); + + ObTableSchema table_schema; + TestDmlCommon::build_data_table_schema(tenant_id_, table_schema); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id_, table_schema, allocator_)); + + TestDmlCommon::build_data_table_schema(tenant_id_, table_schema); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, orig_tablet_id_, table_schema, allocator_)); + + insert_data_to_tablet(access_service, tablet_id_, data_row_str_01); + insert_data_to_tablet(access_service, orig_tablet_id_, data_row_str_02); + + // set split info + ObTabletID src_tablet_id(TestDmlCommon::TEST_DATA_TABLE_ID); + ObTabletID ori_tablet_id(51); + int64_t split_cnt = 1.0; + int64_t start_val = 0; // not include eage + int64_t end_val = 26; // not include eage + int64_t key_cnt = 1; + ret = gen_datum_rowkey(start_val, key_cnt, get_start_key()); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = gen_datum_rowkey(end_val, key_cnt, get_end_key()); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = set_tablet_split_info(src_tablet_id, ObTabletSplitType::RANGE, split_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + // table scan + ObNewRowIterator *iter = nullptr; + table_scan(access_service, iter); + + // clean env + TestDmlCommon::delete_mocked_access_service(access_service); + TestDmlCommon::delete_mocked_ls_tablet_service(tablet_service); + + // for exist + // the iter has store ctx and store ctx has one ls handle. + iter->reset(); + ASSERT_EQ(OB_SUCCESS, MTL(ObLSService*)->remove_ls(ls_id_, false)); +} + +} // namespace unittest +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -rf test_auto_partition_scan_table.log"); + OB_LOGGER.set_file_name("test_auto_partition_scan_table.log", true); + OB_LOGGER.set_log_level("WARN"); + CLOG_LOG(INFO, "begin unittest: test_auto_partition_scan_table"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/mtlenv/storage/test_auto_partition_split_range.cpp b/mittest/mtlenv/storage/test_auto_partition_split_range.cpp new file mode 100644 index 000000000..53487fbeb --- /dev/null +++ b/mittest/mtlenv/storage/test_auto_partition_split_range.cpp @@ -0,0 +1,1059 @@ +/** + * 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 private public +#define protected public + +#include "src/storage/ob_storage_struct.h" +#include "src/storage/blocksstable/ob_datum_range.h" +#include "src/share/ob_ddl_common.h" +#include "src/storage/meta_mem/ob_tablet_handle.h" +#include "storage/init_basic_struct.h" +#include "storage/test_tablet_helper.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/test_dml_common.h" +#include "mtlenv/mock_tenant_module_env.h" +#include "src/share/ob_partition_split_query.h" + +namespace oceanbase +{ +using namespace common; +using namespace storage; +using namespace share; + +namespace unittest +{ + +enum TEST_RANGE_TYPE +{ + EMPTY_ORIGIN_RANGE = 0, + EMPTY_SPLIT_RANGE, + ONLY_SET_SPLIT_START_KEY, + ONLY_SET_SPLIT_END_KEY, + ORIGIN_INSIDE_SPLIT, + ORIGIN_OUTSIDE_SPLIT, + ORIGIN_INCLIDE_SPLIT_START, + ORIGIN_INCLUDE_SPLIT_END, + MAX_RANGE_TYPE +}; + +enum CHECK_DATUM_MIN_TYPE +{ + LEFT = 0, + RIGHT, + BOTH, + MAX_TYPE +}; + +typedef ObSEArray ColDescArray; + +class FakeObTableScanRange : public ::testing::Test +{ +public: + FakeObTableScanRange(); + ~FakeObTableScanRange() + {} + + virtual void SetUp(); + virtual void TearDown(); + static void SetUpTestCase(); + static void TearDownTestCase(); + + int do_split_store_range(const int64_t split_start_val, const int64_t split_end_val); + int do_split_datum_range(int64_t split_start_val, int64_t split_end_val); + int gen_datum_range(const int64_t start_val, const int64_t end_val, const int64_t key_cnt); + int check_datum_range_result(int64_t expected_start_val, int64_t expected_end_val, bool is_left_closed, bool is_right_closed, bool &is_equal); + int check_datum_min_column(const int64_t src_datum_cnt, const int64_t split_datum_cnt, const int64_t expected_left_val, const int64_t expected_right_val, int check_type); + int set_datum_key(const bool is_left, const bool is_right, int64_t value); + + void set_need_set_src_range(bool value) { need_set_src_range_ = value; } + void set_need_set_split_start_key(bool value) { need_set_split_start_key_ = value; } + void set_need_set_split_end_key(bool value) { need_set_split_end_key_ = value; } + void set_split_type(ObTabletSplitType type) { split_info_.split_type_ = type; } + void set_left_closed() { datum_range_.set_left_closed(); } + void set_right_closed() { datum_range_.set_right_closed(); } + void set_left_open() { datum_range_.set_left_open(); } + void set_right_open() { datum_range_.set_right_open(); } + +public: + static constexpr int64_t TEST_LS_ID = 100; + static constexpr int64_t TEST_TENANT_ID = 1; + +private: + int init_table_datum_desc(); + int init_table_col_descs(); + int gen_datum_rowkey(const int64_t key_val, const int64_t key_cnt, blocksstable::ObDatumRowkey &rowkey); + +private: + ObArenaAllocator allocator_; + static ObArenaAllocator static_allocator_; + ColDescArray col_descs_; + blocksstable::ObDatumRange datum_range_; // src datum range + blocksstable::ObStorageDatumUtils datum_utils_; + storage::ObTabletSplitTscInfo split_info_; + ObTabletHandle tablet_handle_; + ObPartitionSplitQuery split_query_; + bool need_set_src_range_; + bool need_set_split_start_key_; + bool need_set_split_end_key_; +}; + +ObArenaAllocator FakeObTableScanRange::static_allocator_; + +void FakeObTableScanRange::SetUpTestCase() +{ + int ret = OB_SUCCESS; + ret = MockTenantModuleEnv::get_instance().init(); + ASSERT_EQ(OB_SUCCESS, ret); + SERVER_STORAGE_META_SERVICE.is_started_ = true; + + // create ls + ObLSHandle ls_handle; + ret = TestDmlCommon::create_ls(TEST_TENANT_ID, ObLSID(TEST_LS_ID), ls_handle); + ASSERT_EQ(OB_SUCCESS, ret); + + // create tablet + ObTabletID tablet_id(1001); + share::schema::ObTableSchema table_schema; + uint64_t table_id = 12345; + ASSERT_EQ(OB_SUCCESS, build_test_schema(table_schema, table_id)); + ASSERT_EQ(OB_SUCCESS, TestTabletHelper::create_tablet(ls_handle, tablet_id, table_schema, static_allocator_)); +} + +void FakeObTableScanRange::TearDownTestCase() +{ + int ret = OB_SUCCESS; + ret = MTL(ObLSService*)->remove_ls(ObLSID(TEST_LS_ID)); + ASSERT_EQ(OB_SUCCESS, ret); + MockTenantModuleEnv::get_instance().destroy(); +} + +void FakeObTableScanRange::SetUp() +{ + int ret = OB_SUCCESS; + ret = init_table_col_descs(); + ASSERT_EQ(OB_SUCCESS, ret); + + ret = init_table_datum_desc(); + ASSERT_EQ(OB_SUCCESS, ret); + + // get ls + ObLSHandle handle; + const ObLSID ls_id(TEST_LS_ID); + ObLS *ls = NULL; + ObLSService *ls_svr = MTL(ObLSService*); + ASSERT_NE(nullptr, ls_svr); + EXPECT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, handle, ObLSGetMod::STORAGE_MOD)); + ls = handle.get_ls(); + ASSERT_NE(nullptr, ls); + + ObTabletID tablet_id(1001); + ASSERT_EQ(OB_SUCCESS, ls->get_tablet(tablet_id, tablet_handle_)); + + need_set_src_range_ = false; + need_set_split_start_key_ = false; + need_set_split_end_key_ = false; + split_info_.split_type_ = ObTabletSplitType::MAX_TYPE; + split_info_.split_cnt_ = 1; + split_info_.src_tablet_handle_ = tablet_handle_; + split_info_.partkey_is_rowkey_prefix_ = true; +} + +void FakeObTableScanRange::TearDown() +{ + col_descs_.reset(); + datum_utils_.reset(); +} + +FakeObTableScanRange::FakeObTableScanRange() +{ +} + +int FakeObTableScanRange::do_split_datum_range(int64_t split_start_val, int64_t split_end_val) +{ + int ret = OB_SUCCESS; + + int64_t key_cnt = 1; + if (need_set_split_start_key_) { + if (OB_FAIL(gen_datum_rowkey(split_start_val, key_cnt, split_info_.start_partkey_))) { + STORAGE_LOG(WARN, "fail to gen start rowkey", K(ret)); + } + } + + if (OB_SUCC(ret) && need_set_split_end_key_) { + if (OB_FAIL(gen_datum_rowkey(split_end_val, key_cnt, split_info_.end_partkey_))) { + STORAGE_LOG(WARN, "fail to gen end rowkey", K(ret)); + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(split_query_.get_tablet_split_range(*tablet_handle_.get_obj(), datum_utils_, split_info_, allocator_, datum_range_))) { + STORAGE_LOG(WARN, "fail to do split range", K(ret)); + } + } + + return ret; +} + +int FakeObTableScanRange::init_table_col_descs() +{ + int ret = OB_SUCCESS; + + share::schema::ObColDesc col_desc; + for (int64_t i = 0; i < 2; i++) { // two columns + col_desc.col_type_.set_int32(); + col_desc.col_id_ = OB_APP_MIN_COLUMN_ID + i; + // col_desc.col_type_.set_collation_type(CS_TYPE_UTF8MB4_BIN); + if (OB_FAIL(col_descs_.push_back(col_desc))) { + STORAGE_LOG(WARN, "fail to push back col_descs_", K(ret)); + } + } + return ret; +} + +int FakeObTableScanRange::init_table_datum_desc() +{ + int ret = OB_SUCCESS; + ObColDesc col_desc; + ObSEArray col_descs; + const bool is_oracle_mode = false; + // two columns + for (int64_t i = 0; i < 2; i++) { + col_desc.col_type_.set_int32(); + col_desc.col_id_ = OB_APP_MIN_COLUMN_ID + i; + if (OB_FAIL(col_descs.push_back(col_desc))) { + STORAGE_LOG(WARN, "fail to push back col_desc", K(ret)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(datum_utils_.init(col_descs, 2, is_oracle_mode, allocator_))) { + STORAGE_LOG(WARN, "fail to init datum_utils", K(ret)); + } + } + return ret; +} + +int FakeObTableScanRange::gen_datum_rowkey(const int64_t key_val, const int64_t key_cnt, blocksstable::ObDatumRowkey &datum_rowkey) +{ + int ret = OB_SUCCESS; + ObObj *key_val_obj = NULL; + ObRowkey rowkey; + if (NULL == (key_val_obj = static_cast(allocator_.alloc(sizeof(ObObj) * key_cnt)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "out of memory", K(ret)); + } else { + for (int64_t i = 0; i < key_cnt; ++i) { + key_val_obj[i].set_int(key_val); + // key_val_obj[i].set_min(); + } + rowkey.assign(key_val_obj, key_cnt); + if (OB_FAIL(datum_rowkey.from_rowkey(rowkey, allocator_))) { + STORAGE_LOG(WARN, "fail to from rowkey", K(ret)); + } + } + return ret; +} + + + +int FakeObTableScanRange::gen_datum_range(const int64_t start_val, const int64_t end_val, const int64_t key_cnt) +{ + int ret = OB_SUCCESS; + datum_range_.reset(); + if (start_val <= end_val && need_set_src_range_) { + blocksstable::ObDatumRowkey start_key; + blocksstable::ObDatumRowkey end_key; + if (OB_FAIL(gen_datum_rowkey(start_val, key_cnt, start_key))) { + STORAGE_LOG(WARN, "Failed to gen start rowkey", K(ret)); + } else if (OB_FAIL(gen_datum_rowkey(end_val, key_cnt, end_key))) { + STORAGE_LOG(WARN, "Failed to gen end rowkey", K(ret)); + } else { + datum_range_.set_start_key(start_key); + datum_range_.set_end_key(end_key); + } + } else { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "Invalid argument", K(ret), K(start_val), K(end_val), K(need_set_src_range_)); + } + return ret; +} + +int FakeObTableScanRange::set_datum_key(const bool is_left, const bool is_right, int64_t value) +{ + int ret = OB_SUCCESS; + int64_t key_cnt = 1; + blocksstable::ObDatumRowkey datum_key; + if (OB_FAIL(gen_datum_rowkey(value, key_cnt, datum_key))) { + STORAGE_LOG(WARN, "Failed to gen rowkey", K(ret)); + } else if (!datum_range_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "Invalid range", K(ret)); + } else if (is_left) { + datum_range_.set_start_key(datum_key); + } else if (is_right) { + datum_range_.set_end_key(datum_key); + } + return ret; +} + +int FakeObTableScanRange::check_datum_range_result( + int64_t expected_left_val, + int64_t expected_right_val, + bool is_left_closed, // 1: close; 0: open + bool is_right_closed, + bool &is_equal) +{ + int ret = OB_SUCCESS; + int64_t key_cnt = 1; + blocksstable::ObDatumRowkey datum_start_key; + blocksstable::ObDatumRowkey datum_end_key; + + if (OB_FAIL(gen_datum_rowkey(expected_left_val, key_cnt, datum_start_key))) { + STORAGE_LOG(WARN, "Failed to gen start rowkey", K(ret)); + } else if (OB_FAIL(gen_datum_rowkey(expected_right_val, key_cnt, datum_end_key))) { + STORAGE_LOG(WARN, "Failed to gen end rowkey", K(ret)); + } else if (!datum_range_.is_valid()) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "Invalid range", K(ret)); + } else { + const blocksstable::ObDatumRowkey &range_start_rowkey = datum_range_.get_start_key(); + const blocksstable::ObDatumRowkey &range_end_rowkey = datum_range_.get_end_key(); + + if (OB_FAIL(range_start_rowkey.equal(datum_start_key, datum_utils_, is_equal))) { + STORAGE_LOG(WARN, "Failed to compare start key", K(ret)); + } else if (is_left_closed != datum_range_.is_left_closed()) { + is_equal = false; + } else if (is_equal && OB_FAIL(range_end_rowkey.equal(datum_end_key, datum_utils_, is_equal))) { + STORAGE_LOG(WARN, "Failed to compare end rowkey", K(ret)); + } else if (is_right_closed != datum_range_.is_right_closed()) { + is_equal = false; + } + } + return ret; +} + +int FakeObTableScanRange::check_datum_min_column( + const int64_t src_datum_cnt, + const int64_t split_datum_cnt, + const int64_t expected_left_val, + const int64_t expected_right_val, + int check_type) +{ + int ret = OB_SUCCESS; + if (split_datum_cnt > src_datum_cnt) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "split datum cnt should not large than src datum cnt", K(ret)); + } else if (datum_range_.is_valid()) { + const blocksstable::ObDatumRowkey &range_start_rowkey = datum_range_.get_start_key(); + const blocksstable::ObDatumRowkey &range_end_rowkey = datum_range_.get_end_key(); + if (src_datum_cnt != range_start_rowkey.get_datum_cnt()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "datum cnt after split not equal to src datum", K(ret)); + } else if (src_datum_cnt != range_end_rowkey.get_datum_cnt()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "datum cnt after split not equal to src datum", K(ret)); + } + // start key + if (check_type == CHECK_DATUM_MIN_TYPE::BOTH || check_type == CHECK_DATUM_MIN_TYPE::LEFT) { + for (int64_t i = 0; OB_SUCC(ret) && i < range_start_rowkey.get_datum_cnt(); ++i) { + if (i < split_datum_cnt) { + int64_t datum_left = range_start_rowkey.get_datum(i).get_int(); + if (datum_left != expected_left_val) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "datum left value not as expected", K(ret), K(expected_left_val), K(datum_left)); + } + } else if (!range_start_rowkey.get_datum(i).is_min()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ext datum column not equal to min value.", K(ret), K(range_start_rowkey.get_datum(i).get_int())); + } + } + } + // end key + if (check_type == CHECK_DATUM_MIN_TYPE::BOTH || check_type == CHECK_DATUM_MIN_TYPE::RIGHT) { + for (int64_t i = 0; OB_SUCC(ret) && i < range_end_rowkey.get_datum_cnt(); ++i) { + if (i < split_datum_cnt) { + int64_t datum_right = range_end_rowkey.get_datum(i).get_int(); + if (datum_right != expected_right_val) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "datum right value not as expected", K(ret), K(expected_right_val), K(datum_right)); + } + } else if (!range_end_rowkey.get_datum(i).is_min()) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "ext datum column not equal to min value.", K(ret)); + } + } + } + } + return ret; +} + + +/* + ATENTION!!! + split range is left closed right open. like: [1, 10) +*/ + +// set empty origin key +TEST_F(FakeObTableScanRange, test_empty_origin_range) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set valid split start key + set_need_set_split_end_key(true); // set valid split end key + set_need_set_src_range(false); // set empty origin range + set_split_type(ObTabletSplitType::RANGE); + + // datum range + int64_t origin_start_val = 1; + int64_t origin_end_val = 5; + int64_t split_start_val = 2; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_NE(OB_SUCCESS, ret); + ret = do_split_datum_range(split_start_val, split_end_val); + // error + ASSERT_NE(OB_SUCCESS, ret); +} + +// set empty split range key +TEST_F(FakeObTableScanRange, test_empty_split_range) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(false); // set empty split start key + set_need_set_split_end_key(false); // set empty split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 5; + int64_t split_start_val = 2; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 1; + + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ret = do_split_datum_range(split_start_val, split_end_val); + // error + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); // empty key is invalid, return -4016 +} + +// only set split start key +TEST_F(FakeObTableScanRange, test_only_set_split_start_key) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set valid split start key + set_need_set_split_end_key(false); // set valid split end key + set_need_set_src_range(true); // set empty origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 5; + int64_t split_start_val = 2; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + ret = do_split_datum_range(split_start_val, split_end_val); + // error + ASSERT_NE(OB_SUCCESS, ret); +} + +// only set split end key +TEST_F(FakeObTableScanRange, test_only_set_split_end_key) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(false); // set empty split start key + set_need_set_split_end_key(false); // set empty split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 5; + int64_t split_start_val = 2; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + // error + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_NE(OB_SUCCESS, ret); +} + +// origin range = (1,5) +// split range = [2,4) +// result = [2,4) +TEST_F(FakeObTableScanRange, test_origin_range_outside_split_range) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 5; + int64_t split_start_val = 2; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 1; + + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_open(); + set_right_open(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + // check result + + // [2,4) + int64_t expected_left_val = 2; + int64_t expected_right_val = 4; + bool is_left_closed = true; + bool is_right_closed = false; + bool is_equal = false; + + ret = check_datum_range_result(expected_left_val, expected_right_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_equal); +} + +// origin range = (2,4) +// split range = [1,5) +// result = (2,4) +TEST_F(FakeObTableScanRange, test_origin_range_inside_split_range_01) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 4; + int64_t split_start_val = 1; + int64_t split_end_val = 5; + int64_t origin_key_cnt = 1; + + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_open(); + set_right_open(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + // (2,4) + int64_t expected_start_val = 2; + int64_t expected_end_val = 4; + bool is_left_closed = false; + bool is_right_closed = false; + bool is_equal = false; + + ret = check_datum_range_result(expected_start_val, expected_end_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_equal); +} + +// origin range = [2,4] +// split range = [1,5) +// result = [2,4] +TEST_F(FakeObTableScanRange, test_origin_range_inside_split_range_02) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 4; + int64_t split_start_val = 1; + int64_t split_end_val = 5; + int64_t origin_key_cnt = 1; + + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_closed(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + // [2,4] + int64_t expected_start_val = 2; + int64_t expected_end_val = 4; + bool is_left_closed = true; + bool is_right_closed = true; + bool is_equal = false; + + ret = check_datum_range_result(expected_start_val, expected_end_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_equal); +} + +// ori range = (2,4) +// split range = [1,3) +// result = (2,3) +TEST_F(FakeObTableScanRange, test_origin_range_include_split_end_key_01) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 4; + int64_t split_start_val = 1; + int64_t split_end_val = 3; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_open(); + set_right_open(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + // (2,3) + int64_t expected_start_val = 2; + int64_t expected_end_val = 3; + bool is_left_closed = false; + bool is_right_closed = false; + bool is_equal = false; + ret = check_datum_range_result(expected_start_val, expected_end_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_equal); +} + +// origin range = [2,4] +// split range = [1,3) +// result = [2,3) +TEST_F(FakeObTableScanRange, test_origin_range_include_split_end_key_02) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 4; + int64_t split_start_val = 1; + int64_t split_end_val = 3; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_closed(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + // [2,3) + int64_t expected_start_val = 2; + int64_t expected_end_val = 3; + bool is_left_closed = true; + bool is_right_closed = false; + bool is_equal = false; + ret = check_datum_range_result(expected_start_val, expected_end_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_equal); +} + +// origin range = (1,3) +// split range = [2,4) +// result = [2,3) +TEST_F(FakeObTableScanRange, test_origin_range_include_split_start_key_01) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 3; + int64_t split_start_val = 2; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 1; + + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_open(); + set_right_open(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t expected_start_val = 2; + int64_t expected_end_val = 3; + bool is_left_closed = true; + bool is_right_closed = false; + bool is_equal = false; + + ret = check_datum_range_result(expected_start_val, expected_end_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_equal); +} + +// origin range = [1,3] +// split range = [2,4) +// result = [2,3] +TEST_F(FakeObTableScanRange, test_origin_range_include_split_start_key_02) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 3; + int64_t split_start_val = 2; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 1; + + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_closed(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + // [2,3] + int64_t expected_start_val = 2; + int64_t expected_end_val = 3; + bool is_left_closed = true; + bool is_right_closed = true; + bool is_equal = false; + + ret = check_datum_range_result(expected_start_val, expected_end_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_equal); +} + +// src range = [2,5] +// split range = [5,6) +// result = [5] +TEST_F(FakeObTableScanRange, test_split_range_result_only_left_key) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 5; + int64_t split_start_val = 5; + int64_t split_end_val = 6; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_closed(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + // [5] + int64_t expected_left_val = 5; + int64_t expected_right_val = 5; + bool is_left_closed = true; + bool is_right_closed = true; + bool is_equal = false; + + ret = check_datum_range_result(expected_left_val, expected_right_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(true, is_equal); +} + +// src range = [2,5] +// split range = [1,2) +// result = [empty] +TEST_F(FakeObTableScanRange, test_split_range_result_only_right_key) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 5; + int64_t split_start_val = 1; + int64_t split_end_val = 2; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_closed(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t expected_left_val = 2; + int64_t expected_right_val = 2; + bool is_left_closed = true; + bool is_right_closed = true; + bool is_equal = false; + + ret = check_datum_range_result(expected_left_val, expected_right_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); // empty range +} + +// src range = (2,5) +// split range = [1,2) +// result = [] +TEST_F(FakeObTableScanRange, test_split_range_empty_case_01) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 5; + int64_t split_start_val = 1; + int64_t split_end_val = 2; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_open(); + set_right_open(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t expected_left_val = 2; + int64_t expected_right_val = 2; + bool is_left_closed = true; + bool is_right_closed = true; + bool is_equal = false; + + ret = check_datum_range_result(expected_left_val, expected_right_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); // empty range +} + +// src range = (2,5) +// split range = [5,6) +// result = [] +TEST_F(FakeObTableScanRange, test_split_range_empty_case_02) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 5; + int64_t split_start_val = 5; + int64_t split_end_val = 6; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_open(); + set_right_open(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t expected_left_val = 2; + int64_t expected_right_val = 2; + bool is_left_closed = true; + bool is_right_closed = true; + bool is_equal = false; + + ret = check_datum_range_result(expected_left_val, expected_right_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); +} + +// src range = (2,2] +// split range = [2,3) +// result = [] +TEST_F(FakeObTableScanRange, test_split_range_empty_case_03) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 2; + int64_t split_start_val = 2; + int64_t split_end_val = 3; + int64_t origin_key_cnt = 1; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + // attention !!! because ObNewRange need start key not equal to end key in (] case + // here modify start key to 2 + ret = set_datum_key(true, false, 2); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_open(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t expected_left_val = 2; + int64_t expected_right_val = 2; + bool is_left_closed = true; + bool is_right_closed = true; + bool is_equal = false; + + ret = check_datum_range_result(expected_left_val, expected_right_val, is_left_closed, is_right_closed, is_equal); + ASSERT_EQ(OB_INVALID_ARGUMENT, ret); +} + + +// src range = [(1,1), (5,5)] +// split range = [2,4) +// result = [(2,min),(3,min)] +TEST_F(FakeObTableScanRange, test_split_column_cnt_not_match_with_rowkey_cnt_both_min) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 5; + int64_t split_start_val = 2; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 2; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_closed(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t expected_left_val = 2; + int64_t expected_right_val = 4; + int64_t split_column_cnt = 1; + + ret = check_datum_min_column(origin_key_cnt, split_column_cnt, expected_left_val, expected_right_val, CHECK_DATUM_MIN_TYPE::BOTH); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(FakeObTableScanRange, test_split_column_cnt_not_match_with_rowkey_cnt_left_min) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 1; + int64_t origin_end_val = 4; + int64_t split_start_val = 2; + int64_t split_end_val = 5; + int64_t origin_key_cnt = 2; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_closed(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t expected_left_val = 2; + int64_t expected_right_val = 4; + int64_t split_column_cnt = 1; + ret = check_datum_min_column(origin_key_cnt, split_column_cnt, expected_left_val, expected_right_val, CHECK_DATUM_MIN_TYPE::LEFT); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(FakeObTableScanRange, test_split_column_cnt_not_match_with_rowkey_right_min) +{ + int ret = OB_SUCCESS; + set_need_set_split_start_key(true); // set split start key + set_need_set_split_end_key(true); // set split end key + set_need_set_src_range(true); // set valid origin range + set_split_type(ObTabletSplitType::RANGE); + + int64_t origin_start_val = 2; + int64_t origin_end_val = 5; + int64_t split_start_val = 1; + int64_t split_end_val = 4; + int64_t origin_key_cnt = 2; + // datum range + ret = gen_datum_range(origin_start_val, origin_end_val, origin_key_cnt); + ASSERT_EQ(OB_SUCCESS, ret); + + set_left_closed(); + set_right_closed(); + + ret = do_split_datum_range(split_start_val, split_end_val); + ASSERT_EQ(OB_SUCCESS, ret); + + int64_t expected_left_val = 2; + int64_t expected_right_val = 4; + int64_t split_column_cnt = 1; + + ret = check_datum_min_column(origin_key_cnt, split_column_cnt, expected_left_val, expected_right_val, CHECK_DATUM_MIN_TYPE::RIGHT); + ASSERT_EQ(OB_SUCCESS, ret); +} + +} // namespace unittest +} // namespace oceanbase + +int main(int argc, char **argv) +{ + system("rm -rf test_auto_partition_split_range.log"); + OB_LOGGER.set_file_name("test_auto_partition_split_range.log", true); + OB_LOGGER.set_log_level("WARN"); + CLOG_LOG(INFO, "begin unittest: test_auto_partition_split_range"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/mittest/mtlenv/storage/test_ddl_create_tablet.cpp b/mittest/mtlenv/storage/test_ddl_create_tablet.cpp index 7f1955878..c2a0dc75b 100644 --- a/mittest/mtlenv/storage/test_ddl_create_tablet.cpp +++ b/mittest/mtlenv/storage/test_ddl_create_tablet.cpp @@ -298,13 +298,14 @@ int TestDDLCreateTablet::build_create_tablet_arg( obrpc::ObCreateTabletInfo tablet_info; ObArray tablet_id_array; ObArray tablet_schema_index_array; + ObArray create_commit_versions; TestSchemaUtils::prepare_data_schema(data_table_schema); if (OB_FAIL(tablet_id_array.push_back(data_tablet_id))) { STORAGE_LOG(WARN, "failed to push tablet id into array", K(ret), K(data_tablet_id)); } else if (OB_FAIL(tablet_schema_index_array.push_back(0))) { STORAGE_LOG(WARN, "failed to push index into array", K(ret)); } else if (OB_FAIL(tablet_info.init(tablet_id_array, data_tablet_id, tablet_schema_index_array, - lib::get_compat_mode(), false/*is_create_bind_hidden_tablets*/, false /*has_cs_replica*/))) { + lib::get_compat_mode(), false/*is_create_bind_hidden_tablets*/, create_commit_versions, false /*has_cs_replica*/))) { STORAGE_LOG(WARN, "failed to init tablet info", K(ret), K(tablet_id_array), K(data_tablet_id), K(tablet_schema_index_array)); } else if (OB_FAIL(arg.tablets_.push_back(tablet_info))) { diff --git a/mittest/mtlenv/storage/test_ls_migration_param.cpp b/mittest/mtlenv/storage/test_ls_migration_param.cpp index 686277c88..54a138592 100644 --- a/mittest/mtlenv/storage/test_ls_migration_param.cpp +++ b/mittest/mtlenv/storage/test_ls_migration_param.cpp @@ -253,8 +253,7 @@ TEST_F(TestLSMigrationParam, test_migrate_tablet_param) SCN scn; scn.convert_from_ts(ObTimeUtility::current_time()); ret = src_handle.get_obj()->init_for_first_time_creation(allocator_, src_key.ls_id_, src_key.tablet_id_, src_key.tablet_id_, - scn, 2022, create_tablet_schema, true/*need_create_empty_major_sstable*/, - true/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, ls_handle.get_ls()->get_freezer()); + scn, 2022, create_tablet_schema, true/*need_create_empty_major_sstable*/, SCN::invalid_scn(), true/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, ls_handle.get_ls()->get_freezer()); ASSERT_EQ(common::OB_SUCCESS, ret); share::SCN create_commit_scn; @@ -338,8 +337,7 @@ TEST_F(TestLSMigrationParam, test_migration_param_compat) SCN scn; scn.convert_from_ts(ObTimeUtility::current_time()); ret = src_handle.get_obj()->init_for_first_time_creation(allocator_, src_key.ls_id_, src_key.tablet_id_, src_key.tablet_id_, - scn, 2022, create_tablet_schema, true/*need_create_empty_major_sstable*/, - true/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, ls_handle.get_ls()->get_freezer()); + scn, 2022, create_tablet_schema, true/*need_create_empty_major_sstable*/, SCN::invalid_scn(), true/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, ls_handle.get_ls()->get_freezer()); ASSERT_EQ(common::OB_SUCCESS, ret); share::SCN create_commit_scn; diff --git a/mittest/mtlenv/storage/test_ls_tablet_info_writer_and_reader.cpp b/mittest/mtlenv/storage/test_ls_tablet_info_writer_and_reader.cpp index 1a1177ebb..3814f4e89 100644 --- a/mittest/mtlenv/storage/test_ls_tablet_info_writer_and_reader.cpp +++ b/mittest/mtlenv/storage/test_ls_tablet_info_writer_and_reader.cpp @@ -170,8 +170,7 @@ void TestLSTabletInfoWR::fill_tablet_meta() SCN scn; scn.convert_from_ts(ObTimeUtility::current_time()); ret = src_handle.get_obj()->init_for_first_time_creation(arena_allocator_, src_key.ls_id_, src_key.tablet_id_, src_key.tablet_id_, - scn, 2022, create_tablet_schema, true/*need_create_empty_major_sstable*/, - false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, ls_handle.get_ls()->get_freezer()); + scn, 2022, create_tablet_schema, true/*need_create_empty_major_sstable*/, share::SCN::invalid_scn(), false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, ls_handle.get_ls()->get_freezer()); ASSERT_EQ(common::OB_SUCCESS, ret); share::SCN create_commit_scn; diff --git a/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp b/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp index 95b10bc97..dbd0be0f4 100644 --- a/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp +++ b/mittest/mtlenv/storage/test_tenant_meta_mem_mgr.cpp @@ -728,8 +728,7 @@ TEST_F(TestTenantMetaMemMgr, test_wash_tablet) ObTabletID empty_tablet_id; ret = tablet->init_for_first_time_creation(allocator_, ls_id_, tablet_id, tablet_id, - create_scn, create_scn.get_val_for_tx(), create_tablet_schema, true/*need_create_empty_major_sstable*/, - false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); + create_scn, create_scn.get_val_for_tx(), create_tablet_schema, true/*need_create_empty_major_sstable*/, SCN::invalid_scn(), false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); const ObTabletPersisterParam persist_param(ls_id_, ls_handle.get_ls()->get_ls_epoch(), tablet_id, tablet->get_transfer_seq()); @@ -830,8 +829,7 @@ TEST_F(TestTenantMetaMemMgr, test_wash_inner_tablet) bool make_empty_co_sstable = true; ret = tablet->init_for_first_time_creation(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), create_tablet_schema, - make_empty_co_sstable/*need_create_empty_major_sstable*/, - false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); + make_empty_co_sstable/*need_create_empty_major_sstable*/, share::SCN::invalid_scn(), false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); @@ -944,8 +942,7 @@ TEST_F(TestTenantMetaMemMgr, test_wash_no_sstable_tablet) bool make_empty_co_sstable = false; ret = tablet->init_for_first_time_creation(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), create_tablet_schema, - make_empty_co_sstable/*need_create_empty_major_sstable*/, - false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); + make_empty_co_sstable/*need_create_empty_major_sstable*/, share::SCN::invalid_scn(), false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); @@ -1044,8 +1041,7 @@ TEST_F(TestTenantMetaMemMgr, test_get_tablet_with_allocator) bool make_empty_co_sstable = true; ret = tablet->init_for_first_time_creation(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), create_tablet_schema, - make_empty_co_sstable/*need_create_empty_major_sstable*/, - false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); + make_empty_co_sstable/*need_create_empty_major_sstable*/, share::SCN::invalid_scn(), false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); @@ -1177,8 +1173,7 @@ TEST_F(TestTenantMetaMemMgr, test_wash_mem_tablet) bool make_empty_co_sstable = false; ret = tablet->init_for_first_time_creation(allocator_, ls_id_, tablet_id, tablet_id, create_scn, create_scn.get_val_for_tx(), create_tablet_schema, - make_empty_co_sstable/*need_create_empty_major_sstable*/, - false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); + make_empty_co_sstable/*need_create_empty_major_sstable*/, share::SCN::invalid_scn(), false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, &freezer); ASSERT_EQ(common::OB_SUCCESS, ret); ASSERT_EQ(1, tablet->get_ref()); diff --git a/mittest/mtlenv/tablelock/table_lock_common_env.h b/mittest/mtlenv/tablelock/table_lock_common_env.h index e1fb491c0..c7a02b7ea 100644 --- a/mittest/mtlenv/tablelock/table_lock_common_env.h +++ b/mittest/mtlenv/tablelock/table_lock_common_env.h @@ -35,7 +35,7 @@ ObLockID DEFAULT_TABLE_LOCK_ID; ObLockID TABLE_LOCK_ID2; ObLockID TABLE_LOCK_ID3; ObTableLockMode DEFAULT_LOCK_MODE = ROW_EXCLUSIVE; -ObTableLockMode DEFAULT_COFLICT_LOCK_MODE = EXCLUSIVE; +ObTableLockMode DEFAULT_CONFLICT_LOCK_MODE = EXCLUSIVE; ObTableLockOwnerID DEFAULT_IN_TRANS_OWNER_ID(ObTableLockOwnerID::default_owner()); ObTableLockOwnerID DEFAULT_OUT_TRANS_OWNER_ID(ObTableLockOwnerID::get_owner_by_value(100)); ObTableLockOwnerID CONFLICT_OWNER_ID(ObTableLockOwnerID::get_owner_by_value(1)); @@ -55,6 +55,7 @@ ObTableLockOp DEFAULT_OUT_TRANS_LOCK_OP; ObTableLockOp DEFAULT_OUT_TRANS_UNLOCK_OP; ObTableLockOp DEFAULT_CONFLICT_OUT_TRANS_LOCK_OP; +ObTableLockOp DEFAULT_OUT_TRANS_REPLACE_LOCK_OP; void init_default_lock_test_value() { @@ -108,7 +109,7 @@ void init_default_lock_test_value() create_schema_version); DEFAULT_CONFLICT_OUT_TRANS_LOCK_OP.set(DEFAULT_TABLET_LOCK_ID, - DEFAULT_COFLICT_LOCK_MODE, + DEFAULT_CONFLICT_LOCK_MODE, CONFLICT_OWNER_ID, TRANS_ID2, OUT_TRANS_LOCK_OP_TYPE, diff --git a/mittest/mtlenv/tablelock/test_lock_memtable.cpp b/mittest/mtlenv/tablelock/test_lock_memtable.cpp index ce5303c25..0a01f305d 100644 --- a/mittest/mtlenv/tablelock/test_lock_memtable.cpp +++ b/mittest/mtlenv/tablelock/test_lock_memtable.cpp @@ -561,7 +561,8 @@ TEST_F(TestLockMemtable, pre_check_lock) LOG_INFO("TestLockMemtable::pre_check_lock 1.2"); ret = memtable_.check_lock_conflict(mem_ctx, DEFAULT_IN_TRANS_LOCK_OP, - conflict_tx_set); + conflict_tx_set, + expired_time); ASSERT_EQ(OB_SUCCESS, ret); // 1.3 lock LOG_INFO("TestLockMemtable::pre_check_lock 1.3"); @@ -575,7 +576,8 @@ TEST_F(TestLockMemtable, pre_check_lock) LOG_INFO("TestLockMemtable::pre_check_lock 1.4"); ret = memtable_.check_lock_conflict(mem_ctx, DEFAULT_IN_TRANS_LOCK_OP, - conflict_tx_set); + conflict_tx_set, + expired_time); ASSERT_EQ(OB_SUCCESS, ret); // 1.5 check allow lock LOG_INFO("TestLockMemtable::pre_check_lock 1.5"); @@ -583,7 +585,8 @@ TEST_F(TestLockMemtable, pre_check_lock) lock_op.lock_mode_ = ROW_SHARE; ret = memtable_.check_lock_conflict(mem_ctx, lock_op, - conflict_tx_set); + conflict_tx_set, + expired_time); ASSERT_EQ(OB_SUCCESS, ret); // 1.6 remove lock op at memtable. LOG_INFO("TestLockMemtable::pre_check_lock 1.6"); @@ -1161,7 +1164,7 @@ TEST_F(TestLockMemtable, test_lock_retry_lock_conflict) ObTableLockOp lock_first = DEFAULT_OUT_TRANS_LOCK_OP; // RX, owner 0 ObTableLockOp lock_second = DEFAULT_OUT_TRANS_LOCK_OP; - lock_second.lock_mode_ = DEFAULT_COFLICT_LOCK_MODE; // X + lock_second.lock_mode_ = DEFAULT_CONFLICT_LOCK_MODE; // X lock_second.owner_id_ = CONFLICT_OWNER_ID; // owner 1 MyTxCtx default_ctx; @@ -1298,6 +1301,157 @@ TEST_F(TestLockMemtable, test_lock_retry_lock_conflict) ASSERT_EQ(min_commited_scn, share::SCN::max_scn()); } +TEST_F(TestLockMemtable, test_replace) +{ + LOG_INFO("TestLockMemtable::test_replace"); + int ret = OB_SUCCESS; + bool is_try_lock = false; + int64_t expired_time = ObClockGenerator::getClock() + 10 * 1000 * 1000; + ObReplaceLockParam param; + ObMemtableCtx *mem_ctx = nullptr; + bool lock_exist = false; + share::SCN min_commited_scn; + share::SCN flushed_scn; + uint64_t lock_mode_cnt_in_same_trans[TABLE_LOCK_MODE_COUNT] = {0, 0, 0, 0, 0}; + + ObTableLockOp lock_first = DEFAULT_OUT_TRANS_LOCK_OP; // RX, owner 0 + ObTableLockOp lock_second = DEFAULT_OUT_TRANS_LOCK_OP; + lock_second.lock_mode_ = DEFAULT_CONFLICT_LOCK_MODE; // X + lock_second.owner_id_ = CONFLICT_OWNER_ID; // owner 1 + + ObTableLockOp unlock_first = DEFAULT_OUT_TRANS_UNLOCK_OP; + ObTableLockOp unlock_second = DEFAULT_OUT_TRANS_UNLOCK_OP; + unlock_second.lock_mode_ = DEFAULT_CONFLICT_LOCK_MODE; + unlock_second.owner_id_ = CONFLICT_OWNER_ID; + + MyTxCtx ctx1; + ObStoreCtx store_ctx1; + MyTxCtx ctx2; + ObStoreCtx store_ctx2; + + start_tx(DEFAULT_TRANS_ID, ctx1); + get_store_ctx(ctx1, store_ctx1); + ctx1.tx_ctx_.change_to_leader(); + start_tx(TRANS_ID2, ctx2); + get_store_ctx(ctx2, store_ctx2); + ctx2.tx_ctx_.change_to_leader(); + + LOG_INFO("TestLockMemtable::test_replace 1"); + // 1.1 lock first + LOG_INFO("TestLockMemtable::test_replace 1.1"); + param.is_try_lock_ = is_try_lock; + param.expired_time_ = expired_time; + ret = memtable_.lock(param, + store_ctx1, + lock_first); + ASSERT_EQ(OB_SUCCESS, ret); + + // 1.2 check lock exist at memctx. + LOG_INFO("TestLockMemtable::test_replace 1.2"); + mem_ctx = store_ctx1.mvcc_acc_ctx_.mem_ctx_; + ret = mem_ctx->check_lock_exist(lock_first.lock_id_, + lock_first.owner_id_, + lock_first.lock_mode_, + lock_first.op_type_, + lock_exist, + lock_mode_cnt_in_same_trans); + ASSERT_EQ(lock_exist, true); + + // 1.3 commit out trans lock + LOG_INFO("TestLockMemtable::test_replace 1.3"); + share::SCN commit_version; + share::SCN commit_scn; + commit_version.set_base(); + commit_scn.set_base(); + ret = memtable_.update_lock_status(lock_first, + commit_version, + commit_scn, + COMMIT_LOCK_OP_STATUS); + ASSERT_EQ(OB_SUCCESS, ret); + min_commited_scn = memtable_.obj_lock_map_.get_min_ddl_committed_scn( + flushed_scn); + ASSERT_EQ(min_commited_scn, commit_scn); + memtable_.obj_lock_map_.print(); + + // 2. replace lock_first with lock_second + LOG_INFO("TestLockMemtable::test_replace 2"); + // 2.1 replace to owner 1 + LOG_INFO("TestLockMemtable::test_replace 2.1"); + param.is_for_replace_ = true; + ret = memtable_.replace(store_ctx2, param, unlock_first, lock_second); + ASSERT_EQ(OB_SUCCESS, ret); + memtable_.obj_lock_map_.print(); + + // 2.2 check lock exist at memctx + LOG_INFO("TestLockMemtable::test_replace 2.2"); + mem_ctx = store_ctx2.mvcc_acc_ctx_.mem_ctx_; + ret = mem_ctx->check_lock_exist(lock_second.lock_id_, + lock_second.owner_id_, + lock_second.lock_mode_, + lock_second.op_type_, + lock_exist, + lock_mode_cnt_in_same_trans); + ASSERT_EQ(lock_exist, true); + + // 2.3 commit replace lock + // We should commit all lock_ops in the same tx, + // so we commit unlock_op and lock_op together here + LOG_INFO("TestLockMemtable::test_replace 2.3"); + commit_version.set_base(); + commit_scn.set_base(); + ret = memtable_.update_lock_status(unlock_first, + commit_version, + commit_scn, + COMMIT_LOCK_OP_STATUS); + ASSERT_EQ(OB_SUCCESS, ret); + ret = memtable_.update_lock_status(lock_second, + commit_version, + commit_scn, + COMMIT_LOCK_OP_STATUS); + ASSERT_EQ(OB_SUCCESS, ret); + min_commited_scn = memtable_.obj_lock_map_.get_min_ddl_committed_scn( + flushed_scn); + ASSERT_EQ(min_commited_scn, commit_scn); + memtable_.obj_lock_map_.print(); + + // 3. unlock + LOG_INFO("TestLockMemtable::test_replace 3"); + MyTxCtx ctx3; + ObStoreCtx unlock_store_ctx3; + start_tx(TRANS_ID3, ctx3); + get_store_ctx(ctx3, unlock_store_ctx3); + ctx3.tx_ctx_.change_to_leader(); + // 3.1 unlock with owner 0: should be OB_OBJ_LOCK_NOT_EXIST. + LOG_INFO("TestLockMemtable::test_replace 3.1"); + ret = memtable_.unlock(unlock_store_ctx3, + unlock_first, + is_try_lock, + expired_time); + ASSERT_EQ(OB_OBJ_LOCK_NOT_EXIST, ret); + + // 3.2 unlock with owner 1: should be success + LOG_INFO("TestLockMemtable::test_replace 3.2"); + ret = memtable_.unlock(unlock_store_ctx3, + unlock_second, + is_try_lock, + expired_time); + ASSERT_EQ(OB_SUCCESS, ret); + + // 3.3 commit unlock + LOG_INFO("TestLockMemtable::test_replace 3.3"); + commit_version.set_base(); + commit_scn.set_base(); + ret = memtable_.update_lock_status(unlock_second, + commit_version, + commit_scn, + COMMIT_LOCK_OP_STATUS); + ASSERT_EQ(OB_SUCCESS, ret); + min_commited_scn = memtable_.obj_lock_map_.get_min_ddl_committed_scn( + flushed_scn); + ASSERT_EQ(min_commited_scn, share::SCN::max_scn()); + memtable_.obj_lock_map_.print(); +} + } // tablelock } // transaction } // oceanbase diff --git a/mittest/mtlenv/tablelock/test_lock_table_callback.cpp b/mittest/mtlenv/tablelock/test_lock_table_callback.cpp index c7e993911..a0638128f 100644 --- a/mittest/mtlenv/tablelock/test_lock_table_callback.cpp +++ b/mittest/mtlenv/tablelock/test_lock_table_callback.cpp @@ -140,7 +140,7 @@ TEST_F(TestLockTableCallback, callback) bool lock_exist = false; uint64_t lock_mode_cnt_in_same_trans[TABLE_LOCK_MODE_COUNT] = {0, 0, 0, 0, 0}; const bool for_replay = false; - ObIMemtable *memtable = nullptr; + storage::ObIMemtable *memtable = nullptr; ObOBJLockCallback *cb = nullptr; // 1. UNNSED CALLBACK TYPE LOG_INFO("TestLockTableCallback::callback 1."); diff --git a/mittest/simple_server/CMakeLists.txt b/mittest/simple_server/CMakeLists.txt index ac942f597..19ecb1230 100644 --- a/mittest/simple_server/CMakeLists.txt +++ b/mittest/simple_server/CMakeLists.txt @@ -77,6 +77,7 @@ ob_unittest_observer(test_ob_obj_lock_garbage_collector test_ob_obj_lock_garbage ob_unittest_observer(test_observer_expand_shrink test_observer_expand_shrink.cpp) ob_unittest_observer(test_replay_from_middle test_replay_from_middle.cpp) ob_unittest_observer(test_special_tablet_flush test_special_tablet_flush.cpp) +ob_unittest_observer(test_table_lock_split test_table_lock_split.cpp) ob_unittest_observer(test_tx_data_table_mit test_tx_data_table_mit.cpp) ob_unittest_observer(test_tx_ctx_table_mit test_tx_ctx_table_mit.cpp) ob_unittest_observer(test_lock_table_persistence test_lock_table_persistence.cpp) @@ -106,6 +107,7 @@ ob_unittest_observer(test_get_stopped_zone_list test_get_stopped_zone_list.cpp) ob_unittest_observer(test_lock_table_with_tx test_lock_table_with_tx.cpp) ob_unittest_observer(test_ob_detect_manager_in_simple_server test_ob_detect_manager_in_simple_server.cpp) ob_unittest_observer(test_transfer_lock_info_operator storage_ha/test_transfer_lock_info_operator.cpp) +ob_unittest_observer(test_tablet_reorganize_history_table_operator storage_ha/test_backup_tablet_reorganize_helper.cpp) 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) diff --git a/mittest/simple_server/test_callbacks_with_reverse_order.cpp b/mittest/simple_server/test_callbacks_with_reverse_order.cpp index aef6a21d8..1dbe62a2b 100644 --- a/mittest/simple_server/test_callbacks_with_reverse_order.cpp +++ b/mittest/simple_server/test_callbacks_with_reverse_order.cpp @@ -135,7 +135,9 @@ int ObStorageTableGuard::refresh_and_protect_memtable_for_write(ObRelativeTable store_ctx_.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), store_ctx_.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), iter, - relative_table.allow_not_ready()))) { + relative_table.allow_not_ready(), + true/*need_split_src_table*/, + false/*need_split_dst_table*/))) { TRANS_LOG(WARN, "fail to get", K(store_ctx_.mvcc_acc_ctx_.tx_id_), K(ret)); } else { // no worry. iter will hold tablet reference and its life cycle is longer than guard diff --git a/mittest/simple_server/test_lock_table_persistence.cpp b/mittest/simple_server/test_lock_table_persistence.cpp index 3c53ccdd6..4cab1531b 100644 --- a/mittest/simple_server/test_lock_table_persistence.cpp +++ b/mittest/simple_server/test_lock_table_persistence.cpp @@ -140,8 +140,10 @@ TEST_F(ObLockTableBeforeRestartTest, test_lock_table_flush) share::ObLSID ls_id = share::LOCK_SERVICE_LS; ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, handle, ObLSGetMod::STORAGE_MOD)); ASSERT_NE(nullptr, ls = handle.get_ls()); - ObCheckpointExecutor *checkpoint_executor = ls->get_checkpoint_executor(); - ASSERT_NE(nullptr, checkpoint_executor); + ObTableHandleV2 table_handle; + ObLockMemtable *lock_memtable = nullptr; + ASSERT_EQ(OB_SUCCESS, ls->lock_table_.get_lock_memtable(table_handle)); + ASSERT_EQ(OB_SUCCESS, table_handle.get_lock_memtable(lock_memtable)); ObSchemaGetterGuard guard; ASSERT_EQ(OB_SUCCESS, GCTX.schema_service_->get_tenant_schema_guard(RunCtx.tenant_id_, guard)); @@ -155,11 +157,6 @@ TEST_F(ObLockTableBeforeRestartTest, test_lock_table_flush) ASSERT_EQ(OB_SUCCESS, table_lock_ser->lock_table(table_id, EXCLUSIVE, owner_id, 0)); usleep(1000 * 1000); - ObLockMemtable *lock_memtable - = dynamic_cast(dynamic_cast(checkpoint_executor - ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) - ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]); - SCN rec_scn = lock_memtable->get_rec_scn(); ASSERT_NE(rec_scn, SCN::max_scn()); lock_scn = rec_scn; @@ -251,17 +248,14 @@ TEST_F(ObLockTableAfterRestartTest, test_recover_lock_table) share::ObLSID ls_id = share::LOCK_SERVICE_LS; ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, handle, ObLSGetMod::STORAGE_MOD)); ASSERT_NE(nullptr, ls = handle.get_ls()); - ObCheckpointExecutor *checkpoint_executor = ls->get_checkpoint_executor(); - ASSERT_NE(nullptr, checkpoint_executor); // get lock_scn from table select_existed_data(lock_scn, unlock_scn); - // check lock_memtable scn - ObLockMemtable *lock_memtable - = dynamic_cast(dynamic_cast(checkpoint_executor - ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) - ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]); + ObTableHandleV2 table_handle; + ObLockMemtable *lock_memtable = nullptr; + ASSERT_EQ(OB_SUCCESS, ls->lock_table_.get_lock_memtable(table_handle)); + ASSERT_EQ(OB_SUCCESS, table_handle.get_lock_memtable(lock_memtable)); ASSERT_EQ(lock_memtable->get_rec_scn(), unlock_scn); ASSERT_EQ(lock_memtable->flushed_scn_, lock_scn); ASSERT_EQ(lock_memtable->max_committed_scn_, unlock_scn); diff --git a/mittest/simple_server/test_lock_table_with_tx.cpp b/mittest/simple_server/test_lock_table_with_tx.cpp index a42d13e2b..98a81416c 100644 --- a/mittest/simple_server/test_lock_table_with_tx.cpp +++ b/mittest/simple_server/test_lock_table_with_tx.cpp @@ -184,9 +184,12 @@ TEST_F(ObLockTableBeforeRestartTest, test_commit_log) checkpoint_executor = ls->get_checkpoint_executor(); ASSERT_NE(nullptr, checkpoint_executor); - lock_memtable = dynamic_cast(dynamic_cast(checkpoint_executor - ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) - ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]); + // lock_memtable = dynamic_cast(dynamic_cast(checkpoint_executor + // ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) + // ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]); + ObTableHandleV2 table_handle; + ASSERT_EQ(OB_SUCCESS, ls->lock_table_.get_lock_memtable(table_handle)); + ASSERT_EQ(OB_SUCCESS, table_handle.get_lock_memtable(lock_memtable)); lock_memtable->obj_lock_map_.print(); LOG_INFO("ObLockTableBeforeRestartTest::test_commit_log 1.2 wait tablelock committed"); @@ -310,10 +313,15 @@ TEST_F(ObLockTableAfterRestartTest, test_recover_lock_table) select_existed_data(lock_scn, ls_checkpoint_scn); // check lock_memtable scn - ObLockMemtable *lock_memtable - = dynamic_cast(dynamic_cast(checkpoint_executor - ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) - ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]); + // ObLockMemtable *lock_memtable + // = dynamic_cast(dynamic_cast(checkpoint_executor + // ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) + // ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]); + ObTableHandleV2 table_handle; + ObLockMemtable *lock_memtable; + ASSERT_EQ(OB_SUCCESS, ls->lock_table_.get_lock_memtable(table_handle)); + ASSERT_EQ(OB_SUCCESS, table_handle.get_lock_memtable(lock_memtable)); + lock_memtable->obj_lock_map_.print(); ASSERT_EQ(lock_memtable->get_rec_scn(), lock_scn); ASSERT_EQ(lock_memtable->max_committed_scn_, lock_scn); diff --git a/mittest/simple_server/test_memtable_new_safe_to_destroy.cpp b/mittest/simple_server/test_memtable_new_safe_to_destroy.cpp index 7a68fde86..091386249 100644 --- a/mittest/simple_server/test_memtable_new_safe_to_destroy.cpp +++ b/mittest/simple_server/test_memtable_new_safe_to_destroy.cpp @@ -222,13 +222,13 @@ TEST_F(ObTestMemtableNewSafeToDestroy, test_safe_to_destroy) storage::ObTabletMemtableMgr *memtable_mgr = memtable->get_memtable_mgr(); EXPECT_EQ(OB_SUCCESS, memtable_mgr->release_memtables()); - TRANS_LOG(INFO, "qcc print2", KPC(memtable));; + TRANS_LOG(INFO, "qcc print2", KPC(memtable)); ObTabletHandle tablet_handle; get_tablet(tenant_id, share::ObLSID(1001), tablet_id, tablet_handle); tablet_handle.get_obj()->reset_memtable(); - TRANS_LOG(INFO, "qcc print3", KPC(memtable));; + TRANS_LOG(INFO, "qcc print3", KPC(memtable)); usleep(5 * 1000 * 1000); diff --git a/mittest/simple_server/test_ob_table_lock_service.cpp b/mittest/simple_server/test_ob_table_lock_service.cpp index ac6df7ffa..b5c5e0366 100644 --- a/mittest/simple_server/test_ob_table_lock_service.cpp +++ b/mittest/simple_server/test_ob_table_lock_service.cpp @@ -37,6 +37,7 @@ public: // 指定case运行目录前缀 test_ob_simple_cluster_ ObTableLockServiceTest() : ObSimpleClusterTestBase("test_ob_lock_service_") {} void get_table_id(const char* tname, uint64_t &table_id); + void get_lock_owner(const char* where_cond, int64_t &raw_owner_id); void get_table_part_ids(const uint64_t table_id, ObIArray &part_ids); void get_table_tablets(const uint64_t table_id, ObTabletIDArray &tablet_list); }; @@ -64,6 +65,28 @@ void ObTableLockServiceTest::get_table_id(const char* tname, uint64_t &table_id) } } +void ObTableLockServiceTest::get_lock_owner(const char* where_cond, int64_t &raw_owner_id) +{ + int ret = OB_SUCCESS; + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy(); + ObSqlString sql; + raw_owner_id = -1; + ASSERT_EQ(OB_SUCCESS, + sql.assign_fmt( + "select owner_id from %s.%s where %s", OB_SYS_DATABASE_NAME, OB_ALL_VIRTUAL_OBJ_LOCK_TNAME, where_cond)); + 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); + if (OB_SUCC(result->next())) { + ASSERT_EQ(OB_SUCCESS, result->get_int("owner_id", raw_owner_id)); + } else { + raw_owner_id = -2; + } + } +} + void ObTableLockServiceTest::get_table_part_ids(const uint64_t table_id, ObIArray &part_ids) { @@ -161,21 +184,35 @@ TEST_F(ObTableLockServiceTest, test_ctx) int64_t retry_timeout_us = 0; // 1. TRY LOCK && NOT DEAD LOCK AVOID - ObTableLockService::ObTableLockCtx ctx_try_lock(ObTableLockTaskType::LOCK_TABLE, table_id, timeout_us, retry_timeout_us); + ObTableLockService::ObTableLockCtx ctx_try_lock; + ctx_try_lock.task_type_ = ObTableLockTaskType::LOCK_TABLE; + ctx_try_lock.table_id_ = table_id; + ctx_try_lock.origin_timeout_us_ = timeout_us; + ctx_try_lock.timeout_us_ = retry_timeout_us; ASSERT_TRUE(ctx_try_lock.is_try_lock()); ASSERT_FALSE(ctx_try_lock.is_deadlock_avoid_enabled()); // 2. TIMEOUT && NOT DEAD LOCK AVOID timeout_us = 15; retry_timeout_us = 15; - ObTableLockService::ObTableLockCtx ctx_no_try_lock(ObTableLockTaskType::LOCK_TABLE, table_id, timeout_us, retry_timeout_us); + ObTableLockService::ObTableLockCtx ctx_no_try_lock; + ctx_no_try_lock.task_type_ = ObTableLockTaskType::LOCK_TABLE; + ctx_no_try_lock.table_id_ = table_id; + ctx_no_try_lock.origin_timeout_us_ = timeout_us; + ctx_no_try_lock.timeout_us_ = retry_timeout_us; + ASSERT_FALSE(ctx_no_try_lock.is_try_lock()); ASSERT_FALSE(ctx_no_try_lock.is_deadlock_avoid_enabled()); // 3. TIMEOUT && DEAD LOCK AVOID timeout_us = 60 * 1000 * 1000; retry_timeout_us = 15; - ObTableLockService::ObTableLockCtx ctx_deadlock_avoid(ObTableLockTaskType::LOCK_TABLE, table_id, timeout_us, retry_timeout_us); + ObTableLockService::ObTableLockCtx ctx_deadlock_avoid; + ctx_deadlock_avoid.task_type_ = ObTableLockTaskType::LOCK_TABLE; + ctx_deadlock_avoid.table_id_ = table_id; + ctx_deadlock_avoid.origin_timeout_us_ = timeout_us; + ctx_deadlock_avoid.timeout_us_ = retry_timeout_us; + LOG_INFO("ObTableLockServiceTest::test_ctx", K(ctx_deadlock_avoid)); ASSERT_FALSE(ctx_deadlock_avoid.is_try_lock()); ASSERT_TRUE(ctx_deadlock_avoid.is_deadlock_avoid_enabled()); @@ -423,7 +460,7 @@ TEST_F(ObTableLockServiceTest, lock_part) lock_arg.part_object_id_ = part_ids[0]; lock_arg.is_from_sql_ = true; - ret = MTL(ObTableLockService*)->lock_partition(*tx_desc, + ret = MTL(ObTableLockService*)->lock(*tx_desc, tx_param, lock_arg); ASSERT_EQ(OB_SUCCESS, ret); @@ -468,9 +505,9 @@ TEST_F(ObTableLockServiceTest, lock_part) unlock_arg.table_id_ = table_id; unlock_arg.part_object_id_ = part_ids[0]; - ret = MTL(ObTableLockService*)->unlock_partition(*tx_desc, - tx_param, - unlock_arg); + ret = MTL(ObTableLockService*)->unlock(*tx_desc, + tx_param, + unlock_arg); ASSERT_EQ(OB_SUCCESS, ret); // commit LOG_INFO("ObTableLockServiceTest::lock_part 4.2"); @@ -639,9 +676,9 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_table) lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; lock_arg.timeout_us_ = 0; lock_arg.is_from_sql_ = true; - ret = MTL(ObTableLockService*)->lock_table(*tx_desc, - tx_param, - lock_arg); + ret = MTL(ObTableLockService*)->lock(*tx_desc, + tx_param, + lock_arg); ASSERT_EQ(OB_SUCCESS, ret); // 1.2 check lock lock_mode = SHARE; @@ -662,9 +699,9 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_table) lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; lock_arg.timeout_us_ = 0; lock_arg.is_from_sql_ = true; - ret = MTL(ObTableLockService*)->lock_table(*tx_desc, - tx_param, - lock_arg); + ret = MTL(ObTableLockService*)->lock(*tx_desc, + tx_param, + lock_arg); ASSERT_EQ(OB_SUCCESS, ret); // 2.2 check lock LOG_INFO("ObTableLockServiceTest::in_trans_lock_table 2.2"); @@ -724,9 +761,9 @@ TEST_F(ObTableLockServiceTest, lock_out_trans_after_in_trans) lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; lock_arg.timeout_us_ = 0; lock_arg.is_from_sql_ = true; - ret = MTL(ObTableLockService*)->lock_table(*tx_desc, - tx_param, - lock_arg); + ret = MTL(ObTableLockService*)->lock(*tx_desc, + tx_param, + lock_arg); ASSERT_EQ(OB_SUCCESS, ret); // 1.2 check lock lock_mode = SHARE; @@ -772,9 +809,9 @@ TEST_F(ObTableLockServiceTest, lock_out_trans_after_in_trans) lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; lock_arg.timeout_us_ = 0; lock_arg.is_from_sql_ = true; - ret = MTL(ObTableLockService*)->lock_table(*tx_desc, - tx_param, - lock_arg); + ret = MTL(ObTableLockService*)->lock(*tx_desc, + tx_param, + lock_arg); ASSERT_EQ(OB_SUCCESS, ret); // 2.2 lock out_trans lock @@ -786,9 +823,9 @@ TEST_F(ObTableLockServiceTest, lock_out_trans_after_in_trans) lock_arg.op_type_ = OUT_TRANS_LOCK; lock_arg.timeout_us_ = 0; lock_arg.is_from_sql_ = true; - ret = MTL(ObTableLockService*)->lock_table(*tx_desc, - tx_param, - lock_arg); + ret = MTL(ObTableLockService*)->lock(*tx_desc, + tx_param, + lock_arg); ASSERT_EQ(OB_SUCCESS, ret); // 2.3 check lock @@ -852,8 +889,9 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_obj) uint64_t obj_id1 = 1010; ObTableLockMode lock_mode1 = SHARE; ObTableLockOwnerID OWNER_ONE; - ObLockObjRequest lock_arg; OWNER_ONE.convert_from_value(1); + ObLockObjsRequest lock_arg; + ObLockID lock_id; tx_param.access_mode_ = ObTxAccessMode::RW; tx_param.isolation_ = ObTxIsolationLevel::RC; @@ -873,28 +911,21 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_obj) lock_arg.lock_mode_ = lock_mode1; lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; lock_arg.timeout_us_ = 0; - lock_arg.obj_type_ = ObLockOBJType::OBJ_TYPE_COMMON_OBJ; - lock_arg.obj_id_ = obj_id1; + lock_id.set(ObLockOBJType::OBJ_TYPE_COMMON_OBJ, obj_id1); + lock_arg.objs_.push_back(lock_id); lock_arg.is_from_sql_ = true; - ret = MTL(ObTableLockService*)->lock_obj(*tx_desc1, - tx_param, - lock_arg); + ret = MTL(ObTableLockService*)->lock(*tx_desc1, + tx_param, + lock_arg); ASSERT_EQ(OB_SUCCESS, ret); LOG_INFO("ObTableLockServiceTest::in_trans_lock_obj 1.2"); ObTxDesc *tx_desc2 = nullptr; ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc2)); - lock_arg.lock_mode_ = lock_mode1; - lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; - lock_arg.timeout_us_ = 0; - lock_arg.obj_type_ = ObLockOBJType::OBJ_TYPE_COMMON_OBJ; - lock_arg.obj_id_ = obj_id1; - lock_arg.is_from_sql_ = true; - - ret = MTL(ObTableLockService*)->lock_obj(*tx_desc2, - tx_param, - lock_arg); + ret = MTL(ObTableLockService*)->lock(*tx_desc2, + tx_param, + lock_arg); ASSERT_EQ(OB_SUCCESS, ret); LOG_INFO("ObTableLockServiceTest::in_trans_lock_obj 1.3"); @@ -902,15 +933,9 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_obj) ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc3)); ObTableLockMode lock_mode2 = EXCLUSIVE; lock_arg.lock_mode_ = lock_mode2; - lock_arg.op_type_ = IN_TRANS_COMMON_LOCK; - lock_arg.timeout_us_ = 0; - lock_arg.obj_type_ = ObLockOBJType::OBJ_TYPE_COMMON_OBJ; - lock_arg.obj_id_ = obj_id1; - lock_arg.is_from_sql_ = true; - - ret = MTL(ObTableLockService*)->lock_obj(*tx_desc3, - tx_param, - lock_arg); + ret = MTL(ObTableLockService*)->lock(*tx_desc3, + tx_param, + lock_arg); ASSERT_EQ(OB_ERR_EXCLUSIVE_LOCK_CONFLICT, ret); LOG_INFO("ObTableLockServiceTest::in_trans_lock_obj 1.4"); @@ -929,6 +954,945 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_obj) ASSERT_EQ(OB_SUCCESS, ret); } +TEST_F(ObTableLockServiceTest, replace_lock_table_from_x_to_rx) +{ + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx"); + int ret = OB_SUCCESS; + // 1. LOCK TABLE + // 1.1 lock one part table + ObTxParam tx_param; + share::ObTenantSwitchGuard tenant_guard; + ObTxDesc *tx_desc1 = nullptr; + ObTxDesc *tx_desc2= nullptr; + ObTxDesc *tx_desc3= nullptr; + ObTransService *txs = nullptr; + uint64_t table_id = 0; + ObTabletIDArray tablet_list; + ObTableLockMode ori_lock_mode = EXCLUSIVE; + ObTableLockMode check_lock_mode = EXCLUSIVE; + ObTableLockMode new_lock_mode = ROW_EXCLUSIVE; + ObTableLockOwnerID owner_one(ObTableLockOwnerID::get_owner_by_value(1)); + ObTableLockOwnerID owner_two(ObTableLockOwnerID::get_owner_by_value(2)); + ObLockTableRequest lock_arg; + ObUnLockTableRequest unlock_arg; + int64_t stmt_timeout_ts = -1; + char where_cond[512] = {0}; + int64_t raw_owner_id = -1; + + tx_param.access_mode_ = ObTxAccessMode::RW; + tx_param.isolation_ = ObTxIsolationLevel::RC; + tx_param.timeout_us_ = 6000 * 1000L; + tx_param.lock_timeout_us_ = -1; + tx_param.cluster_id_ = GCONF.cluster_id; + + ret = tenant_guard.switch_to(OB_SYS_TENANT_ID); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, MTL(ObTableLockService*)); + + txs = MTL(ObTransService*); + ASSERT_NE(nullptr, txs); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc1)); + + // 1. lock table + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 1"); + get_table_id("t_one_part", table_id); + get_table_tablets(table_id, tablet_list); + lock_arg.table_id_ = table_id; + lock_arg.owner_id_ = owner_one; + lock_arg.lock_mode_ = ori_lock_mode; + lock_arg.op_type_ = OUT_TRANS_LOCK; + lock_arg.timeout_us_ = 0; + + unlock_arg.table_id_ = table_id; + unlock_arg.owner_id_ = owner_one; + unlock_arg.lock_mode_ = ori_lock_mode; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + unlock_arg.timeout_us_ = 0; + + ret = MTL(ObTableLockService*)->lock(*tx_desc1, + tx_param, + lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + // 2. check lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 2"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 3. commit lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 3"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc1, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc1); + ASSERT_EQ(OB_SUCCESS, ret); + + // 4. replace lock + // check before commit replace + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", table_id)); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(1, raw_owner_id); + + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", tablet_list[0].id())); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(1, raw_owner_id); + + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 4"); + ObReplaceLockRequest replace_lock_arg; + replace_lock_arg.unlock_req_ = &unlock_arg; + replace_lock_arg.new_lock_mode_ = new_lock_mode; + replace_lock_arg.new_lock_owner_ = owner_two; + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc2)); + + ret = MTL(ObTableLockService*)->replace_lock(*tx_desc2, + tx_param, + replace_lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 5. commit rplace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 5"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc2, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc2); + ASSERT_EQ(OB_SUCCESS, ret); + + // check after commit replace + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", table_id)); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(2, raw_owner_id); + + // there's no lock on tablet, so owner is -2 + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", tablet_list[0].id())); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(-2, raw_owner_id); + + // 6. try to lock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 6"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_EAGAIN, ret); + + // 7. check new owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 7"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + new_lock_mode, + owner_two); + ASSERT_EQ(OB_SUCCESS, ret); + + // 8. unlock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 8"); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc3)); + unlock_arg.owner_id_ = owner_two; + unlock_arg.lock_mode_ = new_lock_mode; + ret = MTL(ObTableLockService *)->unlock(*tx_desc3, tx_param, unlock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc3, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc3); + ASSERT_EQ(OB_SUCCESS, ret); + + // 9. try to lock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 9"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_SUCCESS, ret); + + // 10. check new owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 10"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 11. unlock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_rx 11"); + ret = MTL(ObTableLockService*)->unlock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(ObTableLockServiceTest, replace_lock_table_from_rx_to_x) +{ + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x"); + int ret = OB_SUCCESS; + // 1. LOCK TABLE + // 1.1 lock one part table + ObTxParam tx_param; + share::ObTenantSwitchGuard tenant_guard; + ObTxDesc *tx_desc1 = nullptr; + ObTxDesc *tx_desc2= nullptr; + ObTxDesc *tx_desc3= nullptr; + ObTransService *txs = nullptr; + uint64_t table_id = 0; + ObTabletIDArray tablet_list; + ObTableLockMode ori_lock_mode = ROW_EXCLUSIVE; + ObTableLockMode check_lock_mode = EXCLUSIVE; + ObTableLockMode new_lock_mode = EXCLUSIVE; + ObTableLockOwnerID owner_one(ObTableLockOwnerID::get_owner_by_value(1)); + ObTableLockOwnerID owner_two(ObTableLockOwnerID::get_owner_by_value(2)); + ObLockTableRequest lock_arg; + ObUnLockTableRequest unlock_arg; + int64_t stmt_timeout_ts = -1; + char where_cond[512] = {0}; + int64_t raw_owner_id = -1; + + tx_param.access_mode_ = ObTxAccessMode::RW; + tx_param.isolation_ = ObTxIsolationLevel::RC; + tx_param.timeout_us_ = 6000 * 1000L; + tx_param.lock_timeout_us_ = -1; + tx_param.cluster_id_ = GCONF.cluster_id; + + ret = tenant_guard.switch_to(OB_SYS_TENANT_ID); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, MTL(ObTableLockService*)); + + txs = MTL(ObTransService*); + ASSERT_NE(nullptr, txs); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc1)); + + // 1. lock table + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 1"); + get_table_id("t_one_part", table_id); + get_table_tablets(table_id, tablet_list); + lock_arg.table_id_ = table_id; + lock_arg.owner_id_ = owner_one; + lock_arg.lock_mode_ = ori_lock_mode; + lock_arg.op_type_ = OUT_TRANS_LOCK; + lock_arg.timeout_us_ = 0; + + unlock_arg.table_id_ = table_id; + unlock_arg.owner_id_ = owner_one; + unlock_arg.lock_mode_ = ori_lock_mode; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + unlock_arg.timeout_us_ = 0; + + ret = MTL(ObTableLockService*)->lock(*tx_desc1, + tx_param, + lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + // 2. check lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 2"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 3. commit lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 3"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc1, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc1); + ASSERT_EQ(OB_SUCCESS, ret); + + // 4. replace lock + // check before commit replace + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", table_id)); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(1, raw_owner_id); + + // there's no lock on tablet, so owner is -2 + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", tablet_list[0].id())); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(-2, raw_owner_id); + + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 4"); + ObReplaceLockRequest replace_lock_arg; + replace_lock_arg.unlock_req_ = &unlock_arg; + replace_lock_arg.new_lock_mode_ = new_lock_mode; + replace_lock_arg.new_lock_owner_ = owner_two; + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc2)); + + ret = MTL(ObTableLockService*)->replace_lock(*tx_desc2, + tx_param, + replace_lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 5. commit rplace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 5"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc2, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc2); + ASSERT_EQ(OB_SUCCESS, ret); + + // check after commit replace + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", table_id)); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(2, raw_owner_id); + + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", tablet_list[0].id())); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(2, raw_owner_id); + + // 6. try to lock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 6"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_EAGAIN, ret); + + // 7. unlock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 7"); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc3)); + unlock_arg.owner_id_ = owner_two; + unlock_arg.lock_mode_ = new_lock_mode; + ret = MTL(ObTableLockService *)->unlock(*tx_desc3, tx_param, unlock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc3, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc3); + ASSERT_EQ(OB_SUCCESS, ret); + + // 8. try to lock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 8"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_SUCCESS, ret); + + // 9. check new owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 9"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 10. unlock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_rx_to_x 10"); + ret = MTL(ObTableLockService*)->unlock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(ObTableLockServiceTest, replace_lock_table_from_x_to_s) +{ + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s"); + int ret = OB_SUCCESS; + // 1. LOCK TABLE + // 1.1 lock one part table + ObTxParam tx_param; + share::ObTenantSwitchGuard tenant_guard; + ObTxDesc *tx_desc1 = nullptr; + ObTxDesc *tx_desc2= nullptr; + ObTxDesc *tx_desc3= nullptr; + ObTransService *txs = nullptr; + uint64_t table_id = 0; + ObTabletIDArray tablet_list; + ObTableLockMode ori_lock_mode = EXCLUSIVE; + ObTableLockMode check_lock_mode = EXCLUSIVE; + ObTableLockMode new_lock_mode = SHARE; + ObTableLockOwnerID owner_one(ObTableLockOwnerID::get_owner_by_value(1)); + ObTableLockOwnerID owner_two(ObTableLockOwnerID::get_owner_by_value(2)); + ObLockTableRequest lock_arg; + ObUnLockTableRequest unlock_arg; + int64_t stmt_timeout_ts = -1; + char where_cond[512] = {0}; + int64_t raw_owner_id = -1; + + tx_param.access_mode_ = ObTxAccessMode::RW; + tx_param.isolation_ = ObTxIsolationLevel::RC; + tx_param.timeout_us_ = 6000 * 1000L; + tx_param.lock_timeout_us_ = -1; + tx_param.cluster_id_ = GCONF.cluster_id; + + ret = tenant_guard.switch_to(OB_SYS_TENANT_ID); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, MTL(ObTableLockService*)); + + txs = MTL(ObTransService*); + ASSERT_NE(nullptr, txs); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc1)); + + // 1. lock table + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 1"); + get_table_id("t_one_part", table_id); + get_table_tablets(table_id, tablet_list); + lock_arg.table_id_ = table_id; + lock_arg.owner_id_ = owner_one; + lock_arg.lock_mode_ = ori_lock_mode; + lock_arg.op_type_ = OUT_TRANS_LOCK; + lock_arg.timeout_us_ = 0; + + unlock_arg.table_id_ = table_id; + unlock_arg.owner_id_ = owner_one; + unlock_arg.lock_mode_ = ori_lock_mode; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + unlock_arg.timeout_us_ = 0; + + ret = MTL(ObTableLockService*)->lock(*tx_desc1, + tx_param, + lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + // 2. check lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 2"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 3. commit lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 3"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc1, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc1); + ASSERT_EQ(OB_SUCCESS, ret); + + // 4. replace lock + // check before commit replace + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", table_id)); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(1, raw_owner_id); + + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", tablet_list[0].id())); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(1, raw_owner_id); + + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 4"); + ObReplaceLockRequest replace_lock_arg; + replace_lock_arg.unlock_req_ = &unlock_arg; + replace_lock_arg.new_lock_mode_ = new_lock_mode; + replace_lock_arg.new_lock_owner_ = owner_two; + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc2)); + + ret = MTL(ObTableLockService*)->replace_lock(*tx_desc2, + tx_param, + replace_lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 5. commit rplace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 5"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc2, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc2); + ASSERT_EQ(OB_SUCCESS, ret); + + // check after commit replace + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", table_id)); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(2, raw_owner_id); + + ASSERT_EQ(OB_SUCCESS, databuff_printf(where_cond, 512, "obj_id = %lu LIMIT 1", tablet_list[0].id())); + get_lock_owner(where_cond, raw_owner_id); + ASSERT_EQ(2, raw_owner_id); + + // 6. try to lock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 6"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_EAGAIN, ret); + + // 7. check new owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 7"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + new_lock_mode, + owner_two); + ASSERT_EQ(OB_SUCCESS, ret); + + // 8. unlock + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 8"); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc3)); + unlock_arg.owner_id_ = owner_two; + unlock_arg.lock_mode_ = new_lock_mode; + ret = MTL(ObTableLockService *)->unlock(*tx_desc3, tx_param, unlock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc3, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc3); + ASSERT_EQ(OB_SUCCESS, ret); + + // 9. try to lock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 9"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_SUCCESS, ret); + + // 10. check new owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 10"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 11. unlock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_table_from_x_to_s 11"); + ret = MTL(ObTableLockService*)->unlock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(ObTableLockServiceTest, replace_lock_part) +{ + LOG_INFO("ObTableLockServiceTest::replace_lock_part"); + int ret = OB_SUCCESS; + // 1.1 lock one part table + ObTxParam tx_param; + share::ObTenantSwitchGuard tenant_guard; + ObTxDesc *tx_desc1 = nullptr; + ObTxDesc *tx_desc3 = nullptr; + ObTxDesc *tx_desc2 = nullptr; + ObTxDesc *tx_desc4 = nullptr; + ObTransService *txs = nullptr; + uint64_t table_id = 0; + ObSEArray part_ids; + ObTableLockMode ori_lock_mode = EXCLUSIVE; + ObTableLockMode check_lock_mode = EXCLUSIVE; + ObTableLockMode new_lock_mode = ROW_SHARE; + ObTableLockOwnerID owner_one(ObTableLockOwnerID::get_owner_by_value(1)); + ObTableLockOwnerID owner_two(ObTableLockOwnerID::get_owner_by_value(2)); + ObLockPartitionRequest lock_arg; + ObUnLockPartitionRequest unlock_arg; + int64_t stmt_timeout_ts = -1; + + tx_param.access_mode_ = ObTxAccessMode::RW; + tx_param.isolation_ = ObTxIsolationLevel::RC; + tx_param.timeout_us_ = 6000 * 1000L; + tx_param.lock_timeout_us_ = -1; + tx_param.cluster_id_ = GCONF.cluster_id; + + ret = tenant_guard.switch_to(OB_SYS_TENANT_ID); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, MTL(ObTableLockService*)); + + txs = MTL(ObTransService*); + ASSERT_NE(nullptr, txs); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc1)); + + // 1. lock partition + LOG_INFO("ObTableLockServiceTest::replace_lock_part 1"); + part_ids.reset(); + get_table_id("t_multi_part", table_id); + get_table_part_ids(table_id, part_ids); + + lock_arg.owner_id_ = owner_one; + lock_arg.lock_mode_ = ori_lock_mode; + lock_arg.op_type_ = OUT_TRANS_LOCK; + lock_arg.timeout_us_ = 0; + lock_arg.table_id_ = table_id; + lock_arg.part_object_id_ = part_ids[0]; + + unlock_arg.owner_id_ = owner_one; + unlock_arg.lock_mode_ = ori_lock_mode; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + unlock_arg.timeout_us_ = 0; + unlock_arg.table_id_ = table_id; + unlock_arg.part_object_id_ = part_ids[0]; + + ret = MTL(ObTableLockService*)->lock(*tx_desc1, + tx_param, + lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 2. check lock + LOG_INFO("ObTableLockServiceTest::replace_lock_part 2"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 3. commit lock + LOG_INFO("ObTableLockServiceTest::replace_lock_part 3"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc1, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc1); + ASSERT_EQ(OB_SUCCESS, ret); + + // 4. replace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_part 4"); + ObReplaceLockRequest replace_lock_arg; + replace_lock_arg.unlock_req_ = &unlock_arg; + replace_lock_arg.new_lock_mode_ = new_lock_mode; + replace_lock_arg.new_lock_owner_ = owner_two; + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc2)); + + ret = MTL(ObTableLockService*)->replace_lock(*tx_desc2, + tx_param, + replace_lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 5. check lock + LOG_INFO("ObTableLockServiceTest::replace_lock_part 5"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_EAGAIN, ret); + + ret = MTL(ObTableLockService*)->lock(*tx_desc2, + tx_param, + lock_arg); + ASSERT_EQ(OB_EAGAIN, ret); + + lock_arg.lock_mode_ = new_lock_mode; + lock_arg.owner_id_ = owner_two; + ret = MTL(ObTableLockService*)->lock(*tx_desc2, + tx_param, + lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 6. commit rplace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_part 6"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc2, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc2); + ASSERT_EQ(OB_SUCCESS, ret); + + // 7. check lock again + LOG_INFO("ObTableLockServiceTest::replace_lock_part 7"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_EAGAIN, ret); + ret = MTL(ObTableLockService*)->lock_table(table_id, + new_lock_mode, + owner_two); + ASSERT_EQ(OB_SUCCESS, ret); + ret = MTL(ObTableLockService*)->unlock_table(table_id, + new_lock_mode, + owner_two); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc3)); + ret = MTL(ObTableLockService *)->lock(*tx_desc3, tx_param, lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->commit_tx(*tx_desc3, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc3); + ASSERT_EQ(OB_SUCCESS, ret); + + // 8. unlock and commit + LOG_INFO("ObTableLockServiceTest::replace_lock_part 8"); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc4)); + unlock_arg.lock_mode_ = new_lock_mode; + unlock_arg.owner_id_ = owner_two; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + ret = MTL(ObTableLockService *)->unlock(*tx_desc4, tx_param, unlock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc4, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc4); + ASSERT_EQ(OB_SUCCESS, ret); + + // 9. check lock + LOG_INFO("ObTableLockServiceTest::replace_lock_part 9"); + ret = MTL(ObTableLockService *)->lock_table(table_id, check_lock_mode, owner_one); + ASSERT_EQ(OB_SUCCESS, ret); + ret = MTL(ObTableLockService *)->unlock_table(table_id, check_lock_mode, owner_one); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(ObTableLockServiceTest, replace_lock_obj) +{ + LOG_INFO("ObTableLockServiceTest::replace_lock_obj"); + int ret = OB_SUCCESS; + ObTxParam tx_param; + share::ObTenantSwitchGuard tenant_guard; + ObTxDesc *tx_desc1 = nullptr; + ObTxDesc *tx_desc3 = nullptr; + ObTxDesc *tx_desc2 = nullptr; + ObTxDesc *tx_desc4 = nullptr; + ObTransService *txs = nullptr; + uint64_t table_id; + ObTableLockMode ori_lock_mode = EXCLUSIVE; + ObTableLockMode check_lock_mode = EXCLUSIVE; + ObTableLockMode new_lock_mode = ROW_SHARE; + ObTableLockOwnerID owner_one(ObTableLockOwnerID::get_owner_by_value(1)); + ObTableLockOwnerID owner_two(ObTableLockOwnerID::get_owner_by_value(2)); + ObLockObjsRequest lock_arg; + ObUnLockObjsRequest unlock_arg; + int64_t stmt_timeout_ts = -1; + int64_t obj_id1 = 1001; + int64_t obj_id2 = 1002; + int64_t obj_id3 = 1003; + + tx_param.access_mode_ = ObTxAccessMode::RW; + tx_param.isolation_ = ObTxIsolationLevel::RC; + tx_param.timeout_us_ = 6000 * 1000L; + tx_param.lock_timeout_us_ = -1; + tx_param.cluster_id_ = GCONF.cluster_id; + + ret = tenant_guard.switch_to(OB_SYS_TENANT_ID); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, MTL(ObTableLockService*)); + + txs = MTL(ObTransService*); + ASSERT_NE(nullptr, txs); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc1)); + + // 1. lock obj + LOG_INFO("ObTableLockServiceTest::replace_lock_obj 1"); + get_table_id("t_one_part", table_id); + lock_arg.owner_id_ = owner_one; + lock_arg.lock_mode_ = ori_lock_mode; + lock_arg.op_type_ = OUT_TRANS_LOCK; + lock_arg.timeout_us_ = 0; + ObLockID lock_id1; + ObLockID lock_id2; + ObLockID lock_id3; + lock_id1.set(ObLockOBJType::OBJ_TYPE_COMMON_OBJ, obj_id1); + lock_arg.objs_.push_back(lock_id1); + lock_id2.set(ObLockOBJType::OBJ_TYPE_COMMON_OBJ, obj_id2); + lock_arg.objs_.push_back(lock_id2); + lock_id3.set(ObLockOBJType::OBJ_TYPE_COMMON_OBJ, obj_id3); + lock_arg.objs_.push_back(lock_id3); + + unlock_arg.owner_id_ = owner_one; + unlock_arg.lock_mode_ = ori_lock_mode; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + unlock_arg.timeout_us_ = 0; + unlock_arg.objs_.push_back(lock_id1); + unlock_arg.objs_.push_back(lock_id2); + unlock_arg.objs_.push_back(lock_id3); + + ret = MTL(ObTableLockService*)->lock(*tx_desc1, + tx_param, + lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 2. commit lock + LOG_INFO("ObTableLockServiceTest::replace_lock_obj 2"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc1, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc1); + ASSERT_EQ(OB_SUCCESS, ret); + + // 3. replace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_obj 3"); + ObReplaceLockRequest replace_lock_arg; + replace_lock_arg.unlock_req_ = &unlock_arg; + replace_lock_arg.new_lock_mode_ = new_lock_mode; + replace_lock_arg.new_lock_owner_ = owner_two; + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc2)); + + ret = MTL(ObTableLockService*)->replace_lock(*tx_desc2, + tx_param, + replace_lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 4. check lock + LOG_INFO("ObTableLockServiceTest::replace_lock_obj 4"); + ret = MTL(ObTableLockService*)->lock(*tx_desc2, + tx_param, + lock_arg); + ASSERT_EQ(OB_EAGAIN, ret); + + lock_arg.lock_mode_ = new_lock_mode; + lock_arg.owner_id_ = owner_two; + ret = MTL(ObTableLockService*)->lock(*tx_desc2, + tx_param, + lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 5. commit rplace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_obj 5"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc2, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc2); + ASSERT_EQ(OB_SUCCESS, ret); + + // 6. check lock again + LOG_INFO("ObTableLockServiceTest::replace_lock_obj 6"); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc3)); + ret = MTL(ObTableLockService *)->lock(*tx_desc3, tx_param, lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->commit_tx(*tx_desc3, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc3); + ASSERT_EQ(OB_SUCCESS, ret); + + // 7. unlock and commit + LOG_INFO("ObTableLockServiceTest::replace_lock_obj 7"); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc4)); + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + unlock_arg.lock_mode_ = new_lock_mode; + unlock_arg.owner_id_ = owner_two; + ret = MTL(ObTableLockService *)->unlock(*tx_desc4, tx_param, unlock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc4, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc4); + ASSERT_EQ(OB_SUCCESS, ret); +} + +TEST_F(ObTableLockServiceTest, replace_lock_and_unlock_concurrency) +{ + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency"); + int ret = OB_SUCCESS; + ObTxParam tx_param; + share::ObTenantSwitchGuard tenant_guard; + ObTxDesc *tx_desc1 = nullptr; + ObTxDesc *tx_desc2= nullptr; + ObTxDesc *tx_desc3= nullptr; + ObTransService *txs = nullptr; + uint64_t table_id = 0; + ObTableLockMode ori_lock_mode = EXCLUSIVE; + ObTableLockMode check_lock_mode = EXCLUSIVE; + ObTableLockMode new_lock_mode = SHARE; + ObTableLockOwnerID owner_one(ObTableLockOwnerID::get_owner_by_value(1)); + ObTableLockOwnerID owner_two(ObTableLockOwnerID::get_owner_by_value(2)); + ObLockTableRequest lock_arg; + ObUnLockTableRequest unlock_arg; + int64_t stmt_timeout_ts = -1; + + tx_param.access_mode_ = ObTxAccessMode::RW; + tx_param.isolation_ = ObTxIsolationLevel::RC; + tx_param.timeout_us_ = 6000 * 1000L; + tx_param.lock_timeout_us_ = -1; + tx_param.cluster_id_ = GCONF.cluster_id; + + ret = tenant_guard.switch_to(OB_SYS_TENANT_ID); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_NE(nullptr, MTL(ObTableLockService*)); + + txs = MTL(ObTransService*); + ASSERT_NE(nullptr, txs); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc1)); + + // 1. lock in_trans + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 1"); + get_table_id("t_one_part", table_id); + lock_arg.table_id_ = table_id; + lock_arg.owner_id_ = owner_one; + lock_arg.lock_mode_ = ori_lock_mode; + lock_arg.op_type_ = OUT_TRANS_LOCK; + lock_arg.timeout_us_ = 0; + + unlock_arg.table_id_ = table_id; + unlock_arg.owner_id_ = owner_one; + unlock_arg.lock_mode_ = ori_lock_mode; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + unlock_arg.timeout_us_ = 0; + + ret = MTL(ObTableLockService*)->lock(*tx_desc1, + tx_param, + lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + // 2. check lock + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 2"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 3. commit lock + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 3"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc1, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc1); + ASSERT_EQ(OB_SUCCESS, ret); + + // 3. unlock and not commit + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc2)); + ret = MTL(ObTableLockService*)->unlock(*tx_desc2, + tx_param, + unlock_arg); + + // 4. replace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 4"); + ObReplaceLockRequest replace_lock_arg; + replace_lock_arg.unlock_req_ = &unlock_arg; + replace_lock_arg.new_lock_mode_ = new_lock_mode; + replace_lock_arg.new_lock_owner_ = owner_two; + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc3)); + + ret = MTL(ObTableLockService*)->replace_lock(*tx_desc3, + tx_param, + replace_lock_arg); + ASSERT_EQ(OB_EAGAIN, ret); + + // 5. rollback unlock + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 5"); + ret = txs->rollback_tx(*tx_desc2); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc2); + ASSERT_EQ(OB_SUCCESS, ret); + + // 6. replace again + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 6"); + ret = MTL(ObTableLockService*)->replace_lock(*tx_desc3, + tx_param, + replace_lock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + // 7. commit rplace lock + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 7"); + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc3, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc3); + ASSERT_EQ(OB_SUCCESS, ret); + + // 8. try to lock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 8"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_EAGAIN, ret); + + // 9. check new owner + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 9"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + new_lock_mode, + owner_two); + ASSERT_EQ(OB_SUCCESS, ret); + + // 10. unlock + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 10"); + ASSERT_EQ(OB_SUCCESS, txs->acquire_tx(tx_desc3)); + unlock_arg.owner_id_ = owner_two; + unlock_arg.lock_mode_ = new_lock_mode; + ret = MTL(ObTableLockService *)->unlock(*tx_desc3, tx_param, unlock_arg); + ASSERT_EQ(OB_SUCCESS, ret); + + stmt_timeout_ts = ObTimeUtility::current_time() + 1000 * 1000; + ret = txs->commit_tx(*tx_desc3, stmt_timeout_ts); + ASSERT_EQ(OB_SUCCESS, ret); + ret = txs->release_tx(*tx_desc3); + ASSERT_EQ(OB_SUCCESS, ret); + + // 11. try to lock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 11"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_SUCCESS, ret); + + // 12. check new owner + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 12"); + ret = MTL(ObTableLockService*)->lock_table(table_id, + check_lock_mode, + owner_two); + ASSERT_EQ(OB_EAGAIN, ret); + + // 13. unlock by origin owner + LOG_INFO("ObTableLockServiceTest::replace_lock_and_unlock_concurrency 13"); + ret = MTL(ObTableLockService*)->unlock_table(table_id, + check_lock_mode, + owner_one); + ASSERT_EQ(OB_SUCCESS, ret); +} }// end unittest } // end oceanbase @@ -936,8 +1900,8 @@ TEST_F(ObTableLockServiceTest, in_trans_lock_obj) int main(int argc, char **argv) { oceanbase::unittest::init_log_and_gtest(argc, argv); - OB_LOGGER.set_log_level("info"); - OB_LOGGER.set_mod_log_levels("storage.tablelock:debug"); + OB_LOGGER.set_log_level(OB_LOG_LEVEL_ERROR); + OB_LOGGER.set_mod_log_levels("STORAGE.TABLELOCK:DEBUG"); OB_LOGGER.set_enable_async_log(false); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/mittest/simple_server/test_special_tablet_flush.cpp b/mittest/simple_server/test_special_tablet_flush.cpp index f17776520..6c9a5043a 100644 --- a/mittest/simple_server/test_special_tablet_flush.cpp +++ b/mittest/simple_server/test_special_tablet_flush.cpp @@ -228,10 +228,10 @@ TEST_F(ObTabletFlushTest, test_special_tablet_flush) ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) ->common_checkpoints_[ObCommonCheckpointType::TX_CTX_MEMTABLE_TYPE]); - ObLockMemtable *lock_memtable - = dynamic_cast(dynamic_cast(checkpoint_executor - ->handlers_[logservice::TRANS_SERVICE_LOG_BASE_TYPE]) - ->common_checkpoints_[ObCommonCheckpointType::LOCK_MEMTABLE_TYPE]); + ObTableHandleV2 table_handle; + ObLockMemtable *lock_memtable = nullptr; + ASSERT_EQ(OB_SUCCESS, ls->lock_table_.get_lock_memtable(table_handle)); + ASSERT_EQ(OB_SUCCESS, table_handle.get_lock_memtable(lock_memtable)); ObTxDataMemtableMgr *tx_data_mgr = dynamic_cast(dynamic_cast(checkpoint_executor diff --git a/mittest/simple_server/test_table_lock_split.cpp b/mittest/simple_server/test_table_lock_split.cpp new file mode 100644 index 000000000..9df93772f --- /dev/null +++ b/mittest/simple_server/test_table_lock_split.cpp @@ -0,0 +1,284 @@ +/** + * 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 +#define USING_LOG_PREFIX TABLELOCK +#define protected public +#define private public + +#include "env/ob_simple_cluster_test_base.h" +#include "env/ob_simple_server_restart_helper.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tablelock/ob_lock_memtable.h" +#include "logservice/ob_log_base_type.h" +#include "mtlenv/tablelock/table_lock_tx_common_env.h" +#include "storage/tx_storage/ob_ls_handle.h" //ObLSHandle + +static const char *TEST_FILE_NAME = "test_table_lock_split"; +static const char *BORN_CASE_NAME = "ObLockTableSplitBeforeRestartTest"; +static const char *RESTART_CASE_NAME = "ObLockTableSplitAfterRestartTest"; + +namespace oceanbase +{ +namespace unittest +{ + +using namespace oceanbase::transaction; +using namespace oceanbase::storage; +using namespace oceanbase::storage::checkpoint; + +class TestRunCtx +{ +public: + uint64_t tenant_id_ = 0; + int time_sec_ = 0; +}; + +TestRunCtx RunCtx; + +class ObLockTableSplitBeforeRestartTest : public ObSimpleClusterTestBase +{ +public: + ObLockTableSplitBeforeRestartTest() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} + void add_rx_in_trans_lock(sqlclient::ObISQLConnection *&connection); + void commit_tx(sqlclient::ObISQLConnection *&connection); +}; + +#define EXE_SQL(sql_str) \ + ASSERT_EQ(OB_SUCCESS, sql.assign(sql_str)); \ + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + +#define EXE_SQL_FMT(...) \ + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt(__VA_ARGS__)); \ + ASSERT_EQ(OB_SUCCESS, sql_proxy.write(sql.ptr(), affected_rows)); + +#define WRITE_SQL_BY_CONN(conn, sql_str) \ + ASSERT_EQ(OB_SUCCESS, sql.assign(sql_str)); \ + ASSERT_EQ(OB_SUCCESS, conn->execute_write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + +#define WRITE_SQL_FMT_BY_CONN(conn, ...) \ + ASSERT_EQ(OB_SUCCESS, sql.assign_fmt(__VA_ARGS__)); \ + ASSERT_EQ(OB_SUCCESS, conn->execute_write(OB_SYS_TENANT_ID, sql.ptr(), affected_rows)); + +void ObLockTableSplitBeforeRestartTest::add_rx_in_trans_lock(sqlclient::ObISQLConnection *&connection) +{ + LOG_INFO("insert data start"); + // common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + int64_t affected_rows = 0; + ObSqlString sql; + // sqlclient::ObISQLConnection *connection = nullptr; + // ASSERT_EQ(OB_SUCCESS, sql_proxy.acquire(connection)); + ASSERT_NE(nullptr, connection); + WRITE_SQL_BY_CONN(connection, "set ob_trx_timeout = 3000000000"); + WRITE_SQL_BY_CONN(connection, "set ob_trx_idle_timeout = 3000000000"); + WRITE_SQL_BY_CONN(connection, "set ob_query_timeout = 3000000000"); + WRITE_SQL_BY_CONN(connection, "set autocommit=0"); + + // start and commit transaction + // create data in tx data table. + WRITE_SQL_BY_CONN(connection, "begin;"); + WRITE_SQL_FMT_BY_CONN(connection, "insert into test_table_lock_split_t values(1, 1);"); +} + +void ObLockTableSplitBeforeRestartTest::commit_tx(sqlclient::ObISQLConnection *&connection) +{ + int64_t affected_rows = 0; + ObSqlString sql; + ASSERT_NE(nullptr, connection); + WRITE_SQL_BY_CONN(connection, "commit;"); + + ObTransService *txs = MTL(ObTransService*); + share::ObLSID ls_id(1001); + ASSERT_EQ(OB_SUCCESS, txs->get_tx_ctx_mgr().clear_all_tx(ls_id)); +} + +TEST_F(ObLockTableSplitBeforeRestartTest, add_tenant) +{ + // create tenant + LOG_INFO("step 1: 创建普通租户tt1"); + ASSERT_EQ(OB_SUCCESS, create_tenant()); + LOG_INFO("step 2: 获取租户tt1的tenant_id"); + ASSERT_EQ(OB_SUCCESS, get_tenant_id(RunCtx.tenant_id_)); + LOG_INFO("step 3: 初始化普通租户tt1的sql proxy"); + ASSERT_NE(0, RunCtx.tenant_id_); + ASSERT_EQ(OB_SUCCESS, get_curr_simple_server().init_sql_proxy2()); +} + +TEST_F(ObLockTableSplitBeforeRestartTest, create_table) +{ + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + { + OB_LOG(INFO, "create_table start"); + ObSqlString sql; + int64_t affected_rows = 0; + EXE_SQL("create table test_table_lock_split_t (c1 int, c2 int, primary key(c1))"); + OB_LOG(INFO, "create_table succ"); + } +} + +TEST_F(ObLockTableSplitBeforeRestartTest, test_table_lock_split) +{ + // switch tenant + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(RunCtx.tenant_id_)); + + common::ObMySQLProxy &sql_proxy = get_curr_simple_server().get_sql_proxy2(); + sqlclient::ObISQLConnection *connection = nullptr; + ASSERT_EQ(OB_SUCCESS, sql_proxy.acquire(connection)); + add_rx_in_trans_lock(connection); + + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLSService *ls_svr = MTL(ObLSService*); + ASSERT_NE(nullptr, ls_svr); + ObLS *ls = nullptr; + ObLSHandle handle; + share::ObLSID ls_id(1001); + ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, handle, ObLSGetMod::STORAGE_MOD)); + ASSERT_NE(nullptr, ls = handle.get_ls()); + ObTableHandleV2 table_handle; + ObLockMemtable *lock_memtable = nullptr; + ASSERT_EQ(OB_SUCCESS, ls->lock_table_.get_lock_memtable(table_handle)); + ASSERT_EQ(OB_SUCCESS, table_handle.get_lock_memtable(lock_memtable)); + + // table_lock split + ObTabletID src_tablet_id(200001); + ObSArray dst_tablet_ids; + ObTabletID dst_tablet_id1(300000); + dst_tablet_ids.push_back(dst_tablet_id1); + ObTabletID dst_tablet_id2(400000); + dst_tablet_ids.push_back(dst_tablet_id2); + + ObTransID trans_id(1000); + ObOBJLock *obj_lock = NULL; + ObLockID lock_id; + ASSERT_EQ(OB_SUCCESS, get_lock_id(dst_tablet_id1, lock_id)); + ASSERT_EQ(OB_SUCCESS, lock_memtable->table_lock_split(src_tablet_id, dst_tablet_ids, trans_id)); + int retry_time = 0; + + while (OB_FAIL(lock_memtable->obj_lock_map_.get_obj_lock_with_ref_(lock_id, obj_lock))) { + usleep(1000 * 1000); + retry_time++; + if (retry_time % 5 == 0) { + OB_LOG(WARN, "wait log callback use too much time", K(retry_time)); + } + } + ASSERT_NE(share::SCN::min_scn(), obj_lock->max_split_epoch_); + // share::SCN split_scn = obj_lock->max_split_epoch_; + // ASSERT_EQ(lock_memtable->get_rec_scn(), split_scn); + // ASSERT_EQ(OB_SUCCESS, lock_memtable->flush(share::SCN::max_scn(), true)); + // ASSERT_EQ(lock_memtable->freeze_scn_, split_scn); + // int retry_time = 0; + // while (lock_memtable->is_frozen_memtable()) { + // usleep(1000 * 1000); + // retry_time++; + // if (retry_time % 5 == 0) { + // OB_LOG(WARN, "wait lock memtable flush finish use too much time", + // K(retry_time), KPC(lock_memtable)); + // } + // } + // ASSERT_EQ(lock_memtable->get_rec_scn(), share::SCN::max_scn()); + // ASSERT_EQ(lock_memtable->flushed_scn_, lock_memtable->freeze_scn_); + + // // conflict with split lock + // ObStoreCtx store_ctx; + // store_ctx.ls_id_ = ls_id; + // transaction::tablelock::ObTableLockOp out_trans_lock_op; + // out_trans_lock_op.lock_id_ = lock_id; + // out_trans_lock_op.lock_mode_ = SHARE; + // out_trans_lock_op.op_type_ = OUT_TRANS_LOCK; + // out_trans_lock_op.lock_op_status_ = LOCK_OP_DOING; + // ASSERT_EQ(OB_TRY_LOCK_ROW_CONFLICT, obj_lock->eliminate_conflict_caused_by_split_if_need_(out_trans_lock_op, store_ctx)); + + // commit_tx(connection); + // ASSERT_EQ(OB_SUCCESS, obj_lock->eliminate_conflict_caused_by_split_if_need_(out_trans_lock_op, store_ctx)); + // ASSERT_EQ(share::SCN::min_scn(), obj_lock->max_split_epoch_); + + // ASSERT_EQ(OB_SUCCESS, ls->lock_table_.offline()); + // ASSERT_EQ(OB_SUCCESS, ls->lock_table_.load_lock()); + // ASSERT_EQ(OB_SUCCESS, get_lock_id(dst_tablet_id1, lock_id)); + // ASSERT_EQ(OB_SUCCESS, ls->lock_table_.get_lock_memtable(table_handle)); + // ASSERT_EQ(OB_SUCCESS, table_handle.get_lock_memtable(lock_memtable)); + // ASSERT_EQ(OB_SUCCESS, lock_memtable->obj_lock_map_.get_obj_lock_with_ref_(lock_id, obj_lock)); + // ASSERT_EQ(split_scn, obj_lock->max_split_epoch_); +} + +class ObLockTableSplitAfterRestartTest : public ObSimpleClusterTestBase +{ +public: + ObLockTableSplitAfterRestartTest() : ObSimpleClusterTestBase(TEST_FILE_NAME) {} +}; + +TEST_F(ObLockTableSplitAfterRestartTest, test_recover) +{ + // ============================== restart successfully ============================== + //switch tenant + uint64_t tenant_id = 0; + ASSERT_EQ(OB_SUCCESS, get_tenant_id(tenant_id)); + share::ObTenantSwitchGuard tenant_guard; + ASSERT_EQ(OB_SUCCESS, tenant_guard.switch_to(tenant_id)); + + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObLSService *ls_svr = MTL(ObLSService*); + ASSERT_NE(nullptr, ls_svr); + ObLS *ls = nullptr; + ObLSHandle handle; + share::ObLSID ls_id(1001); + ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, handle, ObLSGetMod::STORAGE_MOD)); + ASSERT_NE(nullptr, ls = handle.get_ls()); + + // check lock_memtable scn + ObTableHandleV2 table_handle; + ObLockMemtable *lock_memtable = nullptr; + ASSERT_EQ(OB_SUCCESS, ls->lock_table_.get_lock_memtable(table_handle)); + ASSERT_EQ(OB_SUCCESS, table_handle.get_lock_memtable(lock_memtable)); + ObOBJLock *obj_lock = NULL; + ObLockID lock_id; + ObTabletID dst_tablet_id1(300000); + ASSERT_EQ(OB_SUCCESS, get_lock_id(dst_tablet_id1, lock_id)); + ASSERT_EQ(OB_SUCCESS, lock_memtable->obj_lock_map_.get_obj_lock_with_ref_(lock_id, obj_lock)); + ASSERT_NE(share::SCN::min_scn(), obj_lock->max_split_epoch_); +} + +} //unitest +} //oceanbase + +int main(int argc, char **argv) +{ + int c = 0; + int time_sec = 0; + char *log_level = (char *)"INFO"; + while (EOF != (c = getopt(argc, argv, "t:l:"))) { + switch (c) { + case 't': + time_sec = atoi(optarg); + break; + case 'l': + log_level = optarg; + oceanbase::unittest::ObSimpleClusterTestBase::enable_env_warn_log_ = false; + break; + default: + break; + } + } + + std::string gtest_file_name = std::string(TEST_FILE_NAME) + "_gtest.log"; + oceanbase::unittest::init_gtest_output(gtest_file_name); + int ret = 0; + ObSimpleServerRestartHelper restart_helper(argc, argv, TEST_FILE_NAME, BORN_CASE_NAME, + RESTART_CASE_NAME); + restart_helper.set_sleep_sec(time_sec + 10); // sleep 10s for schema restore + restart_helper.run(); + + return ret; +} diff --git a/src/logservice/libobcdc/src/ob_cdc_lob_ctx.cpp b/src/logservice/libobcdc/src/ob_cdc_lob_ctx.cpp index 1961b9492..fd47a51a0 100644 --- a/src/logservice/libobcdc/src/ob_cdc_lob_ctx.cpp +++ b/src/logservice/libobcdc/src/ob_cdc_lob_ctx.cpp @@ -104,6 +104,9 @@ void ObLobDataGetCtx::reset( } else if (lob_data_out_row_ctx->is_diff()) { type_ = ObLobDataGetTaskType::EXT_INFO_LOG; LOG_DEBUG("lob_data_out_row_ctx is diff", K(column_id), KPC(new_lob_data_), KPC(lob_data_out_row_ctx)); + } else if (ObLobDataOutRowCtx::OpType::EXT_INFO_LOG == lob_data_out_row_ctx->op_) { + type_ = ObLobDataGetTaskType::EXT_INFO_LOG; + LOG_DEBUG("lob_data_out_row_ctx is outrow ext", K(column_id), KPC(new_lob_data_), KPC(lob_data_out_row_ctx)); } } diff --git a/src/logservice/libobcdc/src/ob_cdc_lob_data_merger.cpp b/src/logservice/libobcdc/src/ob_cdc_lob_data_merger.cpp index 8fcac7fd9..6fc55cbec 100644 --- a/src/logservice/libobcdc/src/ob_cdc_lob_data_merger.cpp +++ b/src/logservice/libobcdc/src/ob_cdc_lob_data_merger.cpp @@ -480,14 +480,21 @@ int ObCDCLobDataMerger::handle_when_outrow_log_fragment_progress_done_( if (OB_FAIL(merge_fragments_(task, lob_data_get_ctx, lob_data_out_row_ctx_list, src_data))) { LOG_ERROR("merge_fragments_ fail", KR(ret), K(task), K(lob_data_get_ctx), K(lob_data_out_row_ctx_list)); } else { + // if is_progress_done is false, it means that after_fragment_progress_done_ cannot be called to push task info formatter + // if task_type is FULL_LOB, current src_data is the final data, so is_progress_done always is true + // if task_type is EXT_INFO_LOG, there is further judgment based on the ext info log type + // for OB_JSON_DIFF_EXT_INFO_LOG, is_progress_done is true after handling + // for OB_OUTROW_DISK_LOB_LOCATOR_EXT_INFO_LOG, it is not final data, and the merge task will be generated, so is_progress_done is false + bool is_progress_done = false; ObLobDataGetTaskType task_type = lob_data_get_ctx.get_type(); LOG_DEBUG("handle", K(task_type), K(task), K(lob_data_get_ctx), K(lob_data_out_row_ctx_list), K(src_data)); switch (task_type) { case ObLobDataGetTaskType::FULL_LOB: output_data = src_data; + is_progress_done = true; break; case ObLobDataGetTaskType::EXT_INFO_LOG: - if (OB_FAIL(handle_ext_info_log_(lob_data_get_ctx, lob_data_out_row_ctx_list, src_data, output_data))) { + if (OB_FAIL(handle_ext_info_log_(lob_data_get_ctx, lob_data_out_row_ctx_list, src_data, output_data, is_progress_done, stop_flag))) { LOG_ERROR("handle ext info log fail", KR(ret), K(task_type), K(task), K(lob_data_get_ctx), K(lob_data_out_row_ctx_list)); } break; @@ -497,6 +504,8 @@ int ObCDCLobDataMerger::handle_when_outrow_log_fragment_progress_done_( break; } if (OB_FAIL(ret)) { + } else if (! is_progress_done) { + LOG_DEBUG("progress not done", K(task_type), "src_data_length", src_data.length()); } else if (OB_FAIL(lob_data_get_ctx.set_col_value(is_new_col, output_data.ptr(), output_data.length()))) { LOG_ERROR("lob_data_get_ctx set_col_value failed", KR(ret), K(src_data), K(output_data)); } else if (OB_FAIL(after_fragment_progress_done_(lob_data_get_ctx, lob_data_out_row_ctx_list, stop_flag))) { @@ -555,7 +564,7 @@ int ObCDCLobDataMerger::merge_fragments_( if (pos + len > data_len) { ret = OB_BUF_NOT_ENOUGH; - LOG_ERROR("buf not enough, not expected", KR(ret), K(pos), K(len), K(data_len)); + LOG_ERROR("buf not enough, not expected", KR(ret), K(pos), K(len), K(data_len), K(seq_no_cnt), K(idx)); } else { MEMCPY(buf + pos, ptr, len); pos += len; @@ -644,7 +653,9 @@ int ObCDCLobDataMerger::handle_ext_info_log_( ObLobDataGetCtx &lob_data_get_ctx, ObLobDataOutRowCtxList &lob_data_out_row_ctx_list, const ObString &src_data, - ObString &output_data) + ObString &output_data, + bool &is_progress_done, + volatile bool &stop_flag) { int ret = OB_SUCCESS; storage::ObExtInfoLogHeader ext_info_log_header; @@ -663,6 +674,16 @@ int ObCDCLobDataMerger::handle_ext_info_log_( case storage::OB_JSON_DIFF_EXT_INFO_LOG: if (OB_FAIL(handle_json_diff_ext_info_log_(allocator, src_data.ptr(), src_data.length(), pos, output_data))) { LOG_ERROR("handle_json_diff_ext_info_log_ fail", KR(ret), K(src_data), K(ext_info_log_header), K(lob_data_get_ctx), K(lob_data_out_row_ctx_list)); + } else { + is_progress_done = true; + } + break; + case storage::OB_OUTROW_DISK_LOB_LOCATOR_EXT_INFO_LOG: + if (OB_FAIL(handle_outrow_lob_locator_ext_info_log_(allocator, src_data.ptr(), src_data.length(), pos, lob_data_get_ctx, lob_data_out_row_ctx_list, stop_flag))) { + LOG_ERROR("handle_outrow_lob_locator_ext_info_log_ fail", KR(ret), K(src_data), K(ext_info_log_header), K(lob_data_get_ctx), K(lob_data_out_row_ctx_list)); + } else { + // it is not final data, and the new merge task is generated, so is_progress_done is false + is_progress_done = false; } break; default: @@ -674,6 +695,41 @@ int ObCDCLobDataMerger::handle_ext_info_log_( return ret; } +int ObCDCLobDataMerger::handle_outrow_lob_locator_ext_info_log_( + ObIAllocator &allocator, + const char *buf, uint64_t len, int64_t pos, + ObLobDataGetCtx &lob_data_get_ctx, + ObLobDataOutRowCtxList &lob_data_out_row_ctx_list, + volatile bool &stop_flag) +{ + int ret = OB_SUCCESS; + if (len - pos != ObLobLocatorV2::DISK_LOB_OUTROW_FULL_SIZE) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("size is incorrect", KR(ret), K(len), K(pos)); + } else { + const ObLobCommon *lob_common = reinterpret_cast(buf + pos); + const ObLobData *lob_data = reinterpret_cast(lob_common->buffer_); + const ObLobDataOutRowCtx *lob_data_out_row_ctx = reinterpret_cast(lob_data->buffer_); + const ObLobData *pre_lob_data = lob_data_get_ctx.new_lob_data_; + + LOG_DEBUG("push lob merge task suscces", KPC(lob_common), KPC(lob_data), KPC(lob_data_out_row_ctx), KPC(pre_lob_data), K(lob_data_get_ctx), K(lob_data_out_row_ctx_list)); + + // check and set lob_data in ext info log + if (OB_ISNULL(pre_lob_data)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("pre lob data for ext info log is null", K(ret), K(lob_data_get_ctx), KPC(lob_data), KPC(lob_data_out_row_ctx)); + } else if (lob_data_out_row_ctx->op_ != ObLobDataOutRowCtx::OpType::SQL || pre_lob_data->id_ != lob_data->id_ || pre_lob_data->byte_size_ != lob_data->byte_size_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("lob data is not match", K(ret), KPC(lob_data), KPC(pre_lob_data), KPC(lob_data_out_row_ctx), K(lob_data_get_ctx)); + } else if (OB_FALSE_IT(lob_data_get_ctx.new_lob_data_ = lob_data)) { + } else if (OB_FALSE_IT(lob_data_get_ctx.set_type(ObLobDataGetTaskType::FULL_LOB))) { + } else if (OB_FAIL(push_lob_column_(allocator, lob_data_out_row_ctx_list, lob_data_get_ctx, stop_flag))) { + LOG_ERROR("push_lob_column_ fail", KR(ret), KPC(lob_data), KPC(pre_lob_data), KPC(lob_data_out_row_ctx), K(lob_data_get_ctx)); + } + } + return ret; +} + int ObCDCLobDataMerger::handle_json_diff_ext_info_log_( ObIAllocator &allocator, const char *buf, uint64_t len, int64_t pos, diff --git a/src/logservice/libobcdc/src/ob_cdc_lob_data_merger.h b/src/logservice/libobcdc/src/ob_cdc_lob_data_merger.h index ee190805b..b02651530 100644 --- a/src/logservice/libobcdc/src/ob_cdc_lob_data_merger.h +++ b/src/logservice/libobcdc/src/ob_cdc_lob_data_merger.h @@ -122,11 +122,19 @@ private: ObLobDataGetCtx &lob_data_get_ctx, ObLobDataOutRowCtxList &lob_data_out_row_ctx_list, const ObString &src_data, - ObString &format_data); + ObString &format_data, + bool &is_progress_done, + volatile bool &stop_flag); int handle_json_diff_ext_info_log_( ObIAllocator &allocator, const char *buf, uint64_t len, int64_t pos, ObString &format_data); + int handle_outrow_lob_locator_ext_info_log_( + ObIAllocator &allocator, + const char *buf, uint64_t len, int64_t pos, + ObLobDataGetCtx &lob_data_get_ctx, + ObLobDataOutRowCtxList &lob_data_out_row_ctx_list, + volatile bool &stop_flag); bool is_in_stop_status(volatile bool stop_flag) const { return stop_flag || LobDataMergerThread::is_stoped(); } // TODO diff --git a/src/logservice/ob_log_base_type.h b/src/logservice/ob_log_base_type.h index 1654c5d21..4830e8211 100644 --- a/src/logservice/ob_log_base_type.h +++ b/src/logservice/ob_log_base_type.h @@ -124,6 +124,7 @@ enum ObLogBaseType // for workload repository service WORKLOAD_REPOSITORY_SERVICE_LOG_BASE_TYPE = 38, + TTL_LOG_BASE_TYPE = 39, // for table load resource manager @@ -266,6 +267,8 @@ int log_base_type_to_string(const ObLogBaseType log_type, strncpy(str, "MVIEW_MAINTENANCE_SERVICE_LOG_BASE_TYPE", str_len); } else if (log_type == SHARE_STORAGE_NRT_THROT_LOG_BASE_TYPE) { strncpy(str ,"SHARE_STORAGE_NRT_THROT_SERVICE", str_len); + } else if (log_type == TABLE_LOCK_LOG_BASE_TYPE) { + strncpy(str ,"TABLE_LOCK", str_len); } else if (log_type == SHARED_STORAGE_PRE_WARM_LOG_BASE_TYPE) { strncpy(str ,"SHARED_STORAGE_PRE_WARM_LOG_BASE_TYPE", str_len); #ifdef OB_BUILD_SHARED_STORAGE diff --git a/src/observer/ob_inner_sql_rpc_processor.cpp b/src/observer/ob_inner_sql_rpc_processor.cpp index 917bc47ca..e2873efee 100644 --- a/src/observer/ob_inner_sql_rpc_processor.cpp +++ b/src/observer/ob_inner_sql_rpc_processor.cpp @@ -419,8 +419,8 @@ int ObInnerSqlRpcP::process() case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_ALONE_TABLET: case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_ALONE_TABLET: case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJS: - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJS: { - + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJS: + case ObInnerSQLTransmitArg::OPERATION_TYPE_REPLACE_LOCK: { if (OB_FAIL(ObInnerConnectionLockUtil::process_lock_rpc(transmit_arg, conn))) { LOG_WARN("process lock rpc failed", K(ret), K(transmit_arg.get_operation_type())); } diff --git a/src/observer/ob_rpc_processor_simple.cpp b/src/observer/ob_rpc_processor_simple.cpp index 14f24fd7c..402948017 100644 --- a/src/observer/ob_rpc_processor_simple.cpp +++ b/src/observer/ob_rpc_processor_simple.cpp @@ -556,7 +556,7 @@ int ObRpcCheckandCancelDDLComplementDagP::process() int ret = OB_SUCCESS; if (OB_ISNULL(gctx_.ob_service_)) { ret = OB_INVALID_ARGUMENT; - LOG_ERROR("invalid argument", K(ret), K(gctx_.ob_service_)); + LOG_ERROR("invalid arguments", K(ret), KP(gctx_.ob_service_)); } else { bool is_dag_exist = true; ret = gctx_.ob_service_->check_and_cancel_ddl_complement_data_dag(arg_, is_dag_exist); @@ -579,6 +579,56 @@ int ObRpcCheckandCancelDeleteLobMetaRowDagP::process() return ret; } +int ObRpcBuildSplitTabletDataStartRequestP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid arguments", K(ret), KP(gctx_.ob_service_)); + } else { + ret = gctx_.ob_service_->build_split_tablet_data_start_request(arg_, result_); + } + return ret; +} + +int ObRpcBuildSplitTabletDataFinishRequestP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid arguments", K(ret), KP(gctx_.ob_service_)); + } else { + ret = gctx_.ob_service_->build_split_tablet_data_finish_request(arg_, result_); + } + return ret; +} + +int ObRpcFreezeSplitSrcTabletP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid arguments", K(ret), KP(gctx_.ob_service_)); + } else { + const int64_t abs_timeout_us = nullptr == rpc_pkt_ ? 0 : get_receive_timestamp() + rpc_pkt_->get_timeout(); + ret = gctx_.ob_service_->freeze_split_src_tablet(arg_, result_, abs_timeout_us); + } + return ret; +} + +int ObRpcFetchSplitTabletInfoP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid arguments", K(ret), KP(gctx_.ob_service_)); + } else { + const int64_t abs_timeout_us = nullptr == rpc_pkt_ ? 0 : get_receive_timestamp() + rpc_pkt_->get_timeout(); + ret = gctx_.ob_service_->fetch_split_tablet_info(arg_, result_, abs_timeout_us); + } + return ret; +} + int ObRpcFetchSysLSP::process() { int ret = OB_SUCCESS; @@ -749,6 +799,42 @@ int ObRpcCheckSchemaVersionElapsedP::process() return ret; } +int ObRpcCheckMemtableCntP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid argument", K(ret), K(gctx_.ob_service_)); + } else { + ret = gctx_.ob_service_->check_memtable_cnt(arg_, result_); + } + return ret; +} + +int ObRpcCheckMediumCompactionInfoListP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid argument", K(ret), K(gctx_.ob_service_)); + } else { + ret = gctx_.ob_service_->check_medium_compaction_info_list_cnt(arg_, result_); + } + return ret; +} + +int ObRpcPrepareTabletSplitTaskRangesP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(gctx_.ob_service_)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid argument", K(ret), K(gctx_.ob_service_)); + } else { + ret = gctx_.ob_service_->prepare_tablet_split_task_ranges(arg_, result_); + } + return ret; +} + int ObRpcCheckCtxCreateTimestampElapsedP::process() { int ret = OB_SUCCESS; @@ -2316,6 +2402,19 @@ int ObRpcBatchGetTabletBindingP::process() return ret; } +int ObRpcBatchGetTabletSplitP::process() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(rpc_pkt_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid rpc pkt", K(ret)); + } else { + const int64_t abs_timeout_us = get_send_timestamp() + rpc_pkt_->get_timeout(); + ret = ObTabletSplitMdsHelper::batch_get_tablet_split(abs_timeout_us, arg_, result_); + } + return ret; +} + #ifdef OB_BUILD_TDE_SECURITY int ObDumpTenantCacheMasterKeyP::process() { diff --git a/src/observer/ob_rpc_processor_simple.h b/src/observer/ob_rpc_processor_simple.h index f3d650fae..aca399ab1 100644 --- a/src/observer/ob_rpc_processor_simple.h +++ b/src/observer/ob_rpc_processor_simple.h @@ -116,13 +116,21 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_FETCH_SYS_LS, ObRpcFetchSysLSP); OB_DEFINE_PROCESSOR_S(Srv, OB_BROADCAST_RS_LIST, ObRpcBroadcastRsListP); OB_DEFINE_PROCESSOR_S(Srv, OB_MINOR_FREEZE, ObRpcMinorFreezeP); OB_DEFINE_PROCESSOR_S(Srv, OB_CHECK_SCHEMA_VERSION_ELAPSED, ObRpcCheckSchemaVersionElapsedP); +OB_DEFINE_PROCESSOR_S(Srv, OB_CHECK_MEMTABLE_CNT, ObRpcCheckMemtableCntP); +OB_DEFINE_PROCESSOR_S(Srv, OB_CHECK_MEDIUM_INFO_LIST_CNT, ObRpcCheckMediumCompactionInfoListP); OB_DEFINE_PROCESSOR_S(Srv, OB_DDL_BUILD_SINGLE_REPLICA_REQUEST, ObRpcBuildDDLSingleReplicaRequestP); +OB_DEFINE_PROCESSOR_S(Srv, OB_SPLIT_TABLET_DATA_START_REQUEST, ObRpcBuildSplitTabletDataStartRequestP); +OB_DEFINE_PROCESSOR_S(Srv, OB_SPLIT_TABLET_DATA_FINISH_REQUEST, ObRpcBuildSplitTabletDataFinishRequestP); +OB_DEFINE_PROCESSOR_S(Srv, OB_PREPARE_TABLET_SPLIT_TASK_RANGES, ObRpcPrepareTabletSplitTaskRangesP); +OB_DEFINE_PROCESSOR_S(Srv, OB_FREEZE_SPLIT_SRC_TABLET, ObRpcFreezeSplitSrcTabletP); +OB_DEFINE_PROCESSOR_S(Srv, OB_FETCH_SPLIT_TABLET_INFO, ObRpcFetchSplitTabletInfoP); OB_DEFINE_PROCESSOR_S(Srv, OB_FETCH_TABLET_AUTOINC_SEQ_CACHE, ObRpcFetchTabletAutoincSeqCacheP); OB_DEFINE_PROCESSOR_S(Srv, OB_BATCH_GET_TABLET_AUTOINC_SEQ, ObRpcBatchGetTabletAutoincSeqP); OB_DEFINE_PROCESSOR_S(Srv, OB_BATCH_SET_TABLET_AUTOINC_SEQ, ObRpcBatchSetTabletAutoincSeqP); OB_DEFINE_PROCESSOR_S(Srv, OB_SET_TABLET_AUTOINC_SEQ, ObRpcSetTabletAutoincSeqP); OB_DEFINE_PROCESSOR_S(Srv, OB_CLEAR_TABLET_AUTOINC_SEQ_CACHE, ObRpcClearTabletAutoincSeqCacheP); OB_DEFINE_PROCESSOR_S(Srv, OB_BATCH_GET_TABLET_BINDING, ObRpcBatchGetTabletBindingP); +OB_DEFINE_PROCESSOR_S(Srv, OB_BATCH_GET_TABLET_SPLIT, ObRpcBatchGetTabletSplitP); OB_DEFINE_PROCESSOR_S(Srv, OB_CHECK_MODIFY_TIME_ELAPSED, ObRpcCheckCtxCreateTimestampElapsedP); OB_DEFINE_PROCESSOR_S(Srv, OB_UPDATE_BASELINE_SCHEMA_VERSION, ObRpcUpdateBaselineSchemaVersionP); OB_DEFINE_PROCESSOR_S(Srv, OB_SWITCH_LEADER, ObRpcSwitchLeaderP); diff --git a/src/observer/ob_server.cpp b/src/observer/ob_server.cpp index 12220db41..241e4b694 100644 --- a/src/observer/ob_server.cpp +++ b/src/observer/ob_server.cpp @@ -110,6 +110,7 @@ #include "share/ob_server_blacklist.h" #include "rootserver/standby/ob_standby_service.h" // ObStandbyService #include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "share/scheduler/ob_partition_auto_split_helper.h" #include "share/longops_mgr/ob_longops_mgr.h" #include "logservice/palf/election/interface/election.h" #include "share/ob_ddl_sim_point.h" @@ -518,6 +519,8 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg) LOG_ERROR("set sys task status self addr failed", KR(ret)); } else if (OB_FAIL(ObTableStoreStatMgr::get_instance().init())) { LOG_ERROR("init table store stat mgr failed", KR(ret)); + } else if (OB_FAIL(ObServerAutoSplitScheduler::get_instance().init())) { + LOG_ERROR("init auto split scheduler failed", KR(ret)); } else if (OB_FAIL(ObCompatModeGetter::instance().init(&sql_proxy_))) { LOG_ERROR("init get compat mode server failed",KR(ret)); } else if (OB_FAIL(table_service_.init())) { diff --git a/src/observer/ob_server_schema_updater.cpp b/src/observer/ob_server_schema_updater.cpp index 42ffcff27..cdf50e573 100644 --- a/src/observer/ob_server_schema_updater.cpp +++ b/src/observer/ob_server_schema_updater.cpp @@ -436,6 +436,7 @@ int ObServerSchemaUpdater::try_reload_schema( LOG_WARN("fail to set tenant received broadcast version", K(tmp_ret), K(schema_info)); } + DEBUG_SYNC(BEFORE_ADD_REFRESH_SCHEMA_TASK); const bool did_retry = true; ObServerSchemaTask refresh_task(ObServerSchemaTask::REFRESH, did_retry, schema_info); if (OB_FAIL(task_queue_.add(refresh_task))) { @@ -471,6 +472,7 @@ int ObServerSchemaUpdater::async_refresh_schema( const int64_t schema_version) { int ret = OB_SUCCESS; + DEBUG_SYNC(BEFORE_ADD_ASYNC_REFRESH_SCHEMA_TASK); ObServerSchemaTask refresh_task(ObServerSchemaTask::ASYNC_REFRESH, tenant_id, schema_version); if (!inited_) { diff --git a/src/observer/ob_service.cpp b/src/observer/ob_service.cpp index 741680a45..afd337625 100644 --- a/src/observer/ob_service.cpp +++ b/src/observer/ob_service.cpp @@ -32,6 +32,7 @@ #include "common/ob_tenant_data_version_mgr.h" #include "share/ob_version.h" +#include "share/ob_ddl_common.h" #include "share/ob_version.h" #include "share/inner_table/ob_inner_table_schema.h" #include "share/deadlock/ob_deadlock_inner_table_service.h" @@ -54,10 +55,14 @@ #include "observer/ob_server_schema_updater.h" #include "ob_server_event_history_table_operator.h" #include "share/ob_alive_server_tracer.h" +#include "storage/ddl/ob_tablet_split_task.h" +#include "storage/ddl/ob_tablet_lob_split_task.h" #include "storage/ddl/ob_complement_data_task.h" // complement data for drop column +#include "storage/ddl/ob_ddl_clog.h" #include "storage/ddl/ob_delete_lob_meta_row_task.h" // delete lob meta row for drop vec index #include "storage/ddl/ob_ddl_merge_task.h" #include "storage/ddl/ob_build_index_task.h" +#include "storage/ddl/ob_ddl_redo_log_writer.h" #include "storage/tablet/ob_tablet_multi_source_data.h" #include "storage/tx_storage/ob_tenant_freezer.h" #include "storage/tx_storage/ob_ls_map.h" @@ -84,6 +89,7 @@ #ifdef OB_BUILD_TDE_SECURITY #include "share/ob_master_key_getter.h" #endif +#include "storage/compaction/ob_schedule_dag_func.h" #include "storage/compaction/ob_tenant_tablet_scheduler.h" #include "share/ob_cluster_event_history_table_operator.h"//CLUSTER_EVENT_INSTANCE #include "storage/ddl/ob_tablet_ddl_kv_mgr.h" @@ -1266,7 +1272,10 @@ int ObService::check_schema_version_elapsed( LOG_WARN("ddl sim failure: check schema version elapsed slow", K(tmp_ret), K(arg)); } else if (OB_TMP_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { LOG_WARN("get ls failed", K(tmp_ret), K(i), K(ls_id)); - } else if (OB_TMP_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle))) { + } else if (OB_TMP_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, + tablet_handle, + ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, + ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("fail to get tablet", K(tmp_ret), K(i), K(ls_id), K(tablet_id)); } else if (OB_TMP_FAIL(tablet_handle.get_obj()->check_schema_version_elapsed(arg.schema_version_, arg.need_wait_trans_end_, @@ -1286,6 +1295,108 @@ int ObService::check_schema_version_elapsed( return ret; } +// 1. minor freeze +// 2. get memtable cnt +int ObService::check_memtable_cnt( + const obrpc::ObCheckMemtableCntArg &arg, + obrpc::ObCheckMemtableCntResult &result) +{ + int ret = OB_SUCCESS; + LOG_INFO("receive check memtable cnt request", K(arg)); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(arg)); + } else { + ObMinorFreezeArg minor_freeze_arg; + minor_freeze_arg.tablet_id_ = arg.tablet_id_; + if (OB_FAIL(minor_freeze_arg.tenant_ids_.push_back(arg.tenant_id_))) { + LOG_WARN("failed to push back tenant id", K(ret)); + } else if (OB_FAIL(handle_ls_freeze_req_(minor_freeze_arg))) { + LOG_WARN("failed to handle tablet freeze", K(ret)); + } else { + MTL_SWITCH(arg.tenant_id_) { + bool freeze_finished = false; + ObTabletID tablet_id = arg.tablet_id_; + const int64_t expire_renew_time = INT64_MAX; + bool is_cache_hit = false; + ObLSID ls_id = arg.ls_id_; + ObLSService *ls_srv = MTL(ObLSService *); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObLSTabletService *ls_tablet_service = nullptr; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObArray memtable_handles; + if (OB_FAIL(ls_srv->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("fail to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls is null", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls_tablet_service = ls->get_tablet_svr())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet service should not be null", K(ret), K(ls_id)); + } else if (OB_FAIL(ls_tablet_service->get_tablet(tablet_id, + tablet_handle, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get tablet handle failed", K(ret), K(tablet_id)); + } else if (FALSE_IT(tablet = tablet_handle.get_obj())) { + } else if (OB_FAIL(tablet->get_all_memtables(memtable_handles))) { + LOG_WARN("failed to get_memtable_mgr for get all memtable", K(ret), KPC(tablet)); + } else { + result.memtable_cnt_ = memtable_handles.count(); + freeze_finished = result.memtable_cnt_ == 0 ? true : false; + if (freeze_finished) { + ObTabletFreezeLog freeze_log; + freeze_log.tablet_id_ = tablet_id; + if (OB_FAIL(storage::ObDDLRedoLogWriter:: + write_auto_split_log(ls_id, + ObDDLClogType::DDL_TABLET_FREEZE_LOG, + logservice::ObReplayBarrierType::STRICT_BARRIER, + freeze_log))) { + LOG_WARN("write tablet freeze log failed", K(ret), K(freeze_log)); + } + } + } + } // MTL_SWITCH + } + } + LOG_INFO("finish check memtable cnt request", K(ret), K(arg)); + return ret; +} + +// possible results: +// 1. ret != OB_SUCCESS +// 2. ret == OB_SUCCESS && info_list_cnt_ > 0 && invalid compaction_scn +// 3. ret == OB_SUCCESS && info_list_cnt_ == 0 && valid primary_compaction_scn_ +int ObService::check_medium_compaction_info_list_cnt( + const obrpc::ObCheckMediumCompactionInfoListArg &arg, + obrpc::ObCheckMediumCompactionInfoListResult &result) +{ + return ObTabletSplitUtil::check_medium_compaction_info_list_cnt(arg, result); +} + +int ObService::prepare_tablet_split_task_ranges( + const obrpc::ObPrepareSplitRangesArg &arg, + obrpc::ObPrepareSplitRangesRes &result) +{ + int ret = OB_SUCCESS; + result.parallel_datum_rowkey_list_.reset(); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(arg)); + } else if (OB_FAIL(ObTabletSplitUtil::split_task_ranges(result.rowkey_allocator_, arg.ls_id_, + arg.tablet_id_, arg.user_parallelism_, arg.schema_tablet_size_, result.parallel_datum_rowkey_list_))) { + LOG_WARN("split task ranges failed", K(ret)); + } + return ret; +} + int ObService::check_ddl_tablet_merge_status( const obrpc::ObDDLCheckTabletMergeStatusArg &arg, obrpc::ObDDLCheckTabletMergeStatusResult &result) @@ -2721,23 +2832,181 @@ int ObService::broadcast_rs_list(const ObRsListArg &arg) return ret; } +int ObService::build_split_tablet_data_start_request(const obrpc::ObTabletSplitStartArg &arg, obrpc::ObTabletSplitStartResult &res) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg.split_info_array_.count(); i++) { + const ObTabletSplitArg &each_arg = arg.split_info_array_.at(i); + if (OB_FAIL(ObTabletLobSplitUtil::process_write_split_start_log_request(each_arg))) { + LOG_WARN("process write split start log failed", K(ret), K(tmp_ret), K(arg)); + } + if (OB_TMP_FAIL(res.ret_codes_.push_back(ret))) { + LOG_WARN("push back result failed", K(ret), K(tmp_ret)); + } + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + LOG_INFO("process write split start log finished", K(ret), K(arg)); + return ret; +} + +int ObService::build_split_tablet_data_finish_request(const obrpc::ObTabletSplitFinishArg &arg, obrpc::ObTabletSplitFinishResult &res) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg.split_info_array_.count(); i++) { + ObTabletSplitFinishResult unused_res; + const ObTabletSplitArg &each_arg = arg.split_info_array_.at(i); + if (OB_FAIL(ObTabletLobSplitUtil::process_tablet_split_request( + each_arg.lob_col_idxs_.count() > 0/*is_lob_tablet*/, + false/*is_start_request*/, + static_cast(&each_arg), + static_cast(&unused_res)))) { + LOG_WARN("process split finish request failed", K(ret), K(arg)); + } + if (OB_TMP_FAIL(res.ret_codes_.push_back(ret))) { + LOG_WARN("push back failed", K(ret), K(tmp_ret)); + } + ret = OB_SUCC(ret) ? tmp_ret : ret; + } + } + LOG_INFO("process split finish request succ", K(ret), K(arg)); + return ret; +} + +int ObService::freeze_split_src_tablet(const ObFreezeSplitSrcTabletArg &arg, + ObFreezeSplitSrcTabletRes &res, + const int64_t abs_timeout_us) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("service not inited", K(ret)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else { + MTL_SWITCH(arg.tenant_id_) { + ObLSService *ls_service = MTL(ObLSService *); + logservice::ObLogService *log_service = MTL(logservice::ObLogService*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObRole role = INVALID_ROLE; + int64_t proposal_id = -1; + bool has_active_memtable = false; + if (OB_ISNULL(ls_service) || OB_ISNULL(log_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected ls_service or log_service", K(ret)); + } else if (OB_FAIL(ls_service->get_ls(arg.ls_id_, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("get ls failed", K(ret), K(arg)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls", K(ret), K(arg.ls_id_)); + } else if (OB_FAIL(ls->get_ls_role(role))) { + LOG_WARN("get role failed", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else if (OB_UNLIKELY(ObRole::LEADER != role)) { + ret = OB_NOT_MASTER; + LOG_WARN("ls not leader", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else if (OB_FAIL(ls->tablet_freeze(checkpoint::INVALID_TRACE_ID, arg.tablet_ids_, true/*is_sync*/, abs_timeout_us, + false/*need_rewrite_meta*/, ObFreezeSourceFlag::TABLET_SPLIT))) { + LOG_WARN("batch tablet freeze failed", K(ret), K(arg)); + } else if (OB_FAIL(ls->check_tablet_no_active_memtable(arg.tablet_ids_, has_active_memtable))) { + // safer with this check, non-mandatory + LOG_WARN("check tablet has active memtable failed", K(ret), K(arg)); + } else if (has_active_memtable) { + ret = OB_EAGAIN; + LOG_WARN("tablet has active memtable need retry", K(ret), K(arg)); + } else if (OB_FAIL(ls->get_log_handler()->get_max_scn(res.data_end_scn_))) { + LOG_WARN("log_handler get_max_scn failed", K(ret), K(arg)); + } + } + } + return ret; +} + +int ObService::fetch_split_tablet_info(const ObFetchSplitTabletInfoArg &arg, + ObFetchSplitTabletInfoRes &res, + const int64_t abs_timeout_us) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("service not inited", K(ret)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else { + MTL_SWITCH(arg.tenant_id_) { + ObLSService *ls_service = MTL(ObLSService *); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObRole role = INVALID_ROLE; + if (OB_ISNULL(ls_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected ls_service or log_service", K(ret)); + } else if (OB_FAIL(ls_service->get_ls(arg.ls_id_, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("get ls failed", K(ret), K(arg)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls", K(ret), K(arg.ls_id_)); + } else if (OB_FAIL(ls->get_ls_role(role))) { + LOG_WARN("get role failed", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else if (OB_UNLIKELY(ObRole::LEADER != role)) { + ret = OB_NOT_MASTER; + LOG_WARN("ls not leader", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); i++) { + const ObTabletID &tablet_id = arg.tablet_ids_.at(i); + ObTabletHandle tablet_handle; + ObTabletCreateDeleteMdsUserData user_data; + if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_tablet_status( + share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet status", K(ret), K(arg.ls_id_), K(tablet_id)); + } else if (OB_FAIL(res.create_commit_versions_.push_back(user_data.create_commit_version_))) { + LOG_WARN("failed to push back", K(ret)); + } + } + } + } + } + return ret; +} + int ObService::build_ddl_single_replica_request(const ObDDLBuildSingleReplicaRequestArg &arg, ObDDLBuildSingleReplicaRequestResult &res) { int ret = OB_SUCCESS; - LOG_INFO("receive build single replica request", K(arg)); + ObTenantDagScheduler *dag_scheduler = nullptr; if (OB_UNLIKELY(!arg.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), K(arg)); + } else if (OB_ISNULL(dag_scheduler = MTL(ObTenantDagScheduler *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag scheduler is null", K(ret)); } else { - if (is_complement_data_relying_on_dag(ObDDLType(arg.ddl_type_))) { + if (share::is_tablet_split(ObDDLType(arg.ddl_type_))) { + if (OB_FAIL(ObTabletLobSplitUtil::process_tablet_split_request( + arg.lob_col_idxs_.count() > 0/*is_lob_tablet*/, + true/*is_start_request*/, + static_cast(&arg), + static_cast(&res)))) { + LOG_WARN("process split start request failed", K(ret), K(arg)); + } + } else if (is_complement_data_relying_on_dag(ObDDLType(arg.ddl_type_))) { int saved_ret = OB_SUCCESS; - ObTenantDagScheduler *dag_scheduler = nullptr; ObComplementDataDag *dag = nullptr; - if (OB_ISNULL(dag_scheduler = MTL(ObTenantDagScheduler *))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("dag scheduler is null", K(ret)); - } else if (OB_FAIL(dag_scheduler->alloc_dag(dag))) { + if (OB_FAIL(dag_scheduler->alloc_dag(dag))) { LOG_WARN("fail to alloc dag", K(ret)); } else if (OB_ISNULL(dag)) { ret = OB_ERR_UNEXPECTED; @@ -2746,17 +3015,21 @@ int ObService::build_ddl_single_replica_request(const ObDDLBuildSingleReplicaReq LOG_WARN("fail to init complement data dag", K(ret), K(arg)); } else if (OB_FAIL(dag->create_first_task())) { LOG_WARN("create first task failed", K(ret)); - } else if (OB_FAIL(dag_scheduler->add_dag(dag))) { + } else if (OB_FAIL(add_dag_and_get_progress(dag, res.row_inserted_, res.physical_row_count_))) { saved_ret = ret; - LOG_WARN("add dag failed", K(ret), K(arg)); - if (OB_EAGAIN == saved_ret) { - dag_scheduler->get_complement_data_dag_progress(dag, res.row_scanned_, res.row_inserted_); + if (OB_EAGAIN == ret) { + ret = OB_SUCCESS; + } else if (OB_SIZE_OVERFLOW == ret) { + ret = OB_EAGAIN; + } else { + LOG_WARN("add dag and get progress failed", K(ret)); } } else { dag = nullptr; } + if (OB_NOT_NULL(dag)) { - (void) dag->handle_init_failed_ret_code(ret); + // to free dag. dag_scheduler->free_dag(*dag); dag = nullptr; } @@ -2800,11 +3073,11 @@ int ObService::build_ddl_single_replica_request(const ObDDLBuildSingleReplicaReq dag = nullptr; } } else { - ret = OB_NOT_SUPPORTED; - LOG_WARN("not supported ddl type", K(ret), K(arg)); + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ddl type request", K(ret), K(arg)); } - } + LOG_INFO("receive build single replica request", K(ret), K(arg)); return ret; } @@ -2879,7 +3152,6 @@ int ObService::check_and_cancel_delete_lob_meta_row_dag(const obrpc::ObDDLBuildS LOG_WARN("cancel dag failed", K(ret)); } if (OB_NOT_NULL(dag)) { - (void) dag->handle_init_failed_ret_code(ret); dag_scheduler->free_dag(*dag); dag = nullptr; } diff --git a/src/observer/ob_service.h b/src/observer/ob_service.h index fed3ebfe6..bf47d392e 100644 --- a/src/observer/ob_service.h +++ b/src/observer/ob_service.h @@ -32,6 +32,8 @@ namespace share { class ObIAliveServerTracer; struct ObTabletReplicaChecksumItem; +class ObTenantDagScheduler; +class ObIDag; } namespace storage { @@ -124,6 +126,11 @@ public: // ObRpcSwitchSchemaP @RS DDL int switch_schema(const obrpc::ObSwitchSchemaArg &arg, obrpc::ObSwitchSchemaResult &result); int calc_column_checksum_request(const obrpc::ObCalcColumnChecksumRequestArg &arg, obrpc::ObCalcColumnChecksumRequestRes &res); + int build_split_tablet_data_start_request(const obrpc::ObTabletSplitStartArg &arg, obrpc::ObTabletSplitStartResult &res); + int build_split_tablet_data_finish_request(const obrpc::ObTabletSplitFinishArg &arg, obrpc::ObTabletSplitFinishResult &res); + int freeze_split_src_tablet(const obrpc::ObFreezeSplitSrcTabletArg &arg, obrpc::ObFreezeSplitSrcTabletRes &res, const int64_t abs_timeout_us); + int fetch_split_tablet_info(const obrpc::ObFetchSplitTabletInfoArg &arg, obrpc::ObFetchSplitTabletInfoRes &res, const int64_t abs_timeout_us); + int build_ddl_single_replica_request(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg); int build_ddl_single_replica_request(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg, obrpc::ObDDLBuildSingleReplicaRequestResult &res); int check_and_cancel_ddl_complement_data_dag(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg, bool &is_dag_exist); int check_and_cancel_delete_lob_meta_row_dag(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg, bool &is_dag_exist); @@ -177,6 +184,19 @@ public: const obrpc::ObCheckSchemaVersionElapsedArg &arg, obrpc::ObCheckSchemaVersionElapsedResult &result); // ObRpcGetChecksumCalSnapshotP + + // ObRpcCheckMemtableCntP + int check_memtable_cnt( + const obrpc::ObCheckMemtableCntArg &arg, + obrpc::ObCheckMemtableCntResult &result); + // ObRpcCheckMediumCompactionInfoListP + int check_medium_compaction_info_list_cnt( + const obrpc::ObCheckMediumCompactionInfoListArg &arg, + obrpc::ObCheckMediumCompactionInfoListResult &result); + int prepare_tablet_split_task_ranges( + const obrpc::ObPrepareSplitRangesArg &arg, + obrpc::ObPrepareSplitRangesRes &result); + int check_modify_time_elapsed( const obrpc::ObCheckModifyTimeElapsedArg &arg, obrpc::ObCheckModifyTimeElapsedResult &result); @@ -184,7 +204,6 @@ public: int check_ddl_tablet_merge_status( const obrpc::ObDDLCheckTabletMergeStatusArg &arg, obrpc::ObDDLCheckTabletMergeStatusResult &result); - //////////////////////////////////////////////////////////////// // ObRpcBatchSwitchRsLeaderP @RS leader coordinator & admin int batch_switch_rs_leader(const ObAddr &arg); diff --git a/src/observer/ob_srv_xlator_partition.cpp b/src/observer/ob_srv_xlator_partition.cpp index 27d4578ca..a38cd1f99 100644 --- a/src/observer/ob_srv_xlator_partition.cpp +++ b/src/observer/ob_srv_xlator_partition.cpp @@ -255,6 +255,7 @@ void oceanbase::observer::init_srv_xlator_for_others(ObSrvRpcXlator *xlator) { RPC_PROCESSOR(ObOutTransLockTableP, gctx_); RPC_PROCESSOR(ObOutTransUnlockTableP, gctx_); RPC_PROCESSOR(ObBatchLockTaskP, gctx_); + RPC_PROCESSOR(ObBatchReplaceLockTaskP, gctx_); RPC_PROCESSOR(ObHighPriorityBatchLockTaskP, gctx_); RPC_PROCESSOR(ObAdminRemoveLockP); RPC_PROCESSOR(ObAdminUpdateLockP); diff --git a/src/observer/ob_srv_xlator_rootserver.cpp b/src/observer/ob_srv_xlator_rootserver.cpp index 9507199a5..e54e278fb 100644 --- a/src/observer/ob_srv_xlator_rootserver.cpp +++ b/src/observer/ob_srv_xlator_rootserver.cpp @@ -275,7 +275,9 @@ void oceanbase::observer::init_srv_xlator_for_rootserver(ObSrvRpcXlator *xlator) RPC_PROCESSOR(rootserver::ObRpcCloneTenantP, *gctx_.root_service_); // auto part ddl - + RPC_PROCESSOR(rootserver::ObRpcCleanSplittedTabletP, *gctx_.root_service_); + RPC_PROCESSOR(rootserver::ObAutoSplitTabletTaskP, *gctx_.root_service_); + RPC_PROCESSOR(rootserver::ObSplitGlobalIndexTabletTaskP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObRpcFlushOptStatMonitoringInfoP, *gctx_.root_service_); RPC_PROCESSOR(rootserver::ObRpcCreateDirectoryP, *gctx_.root_service_); diff --git a/src/observer/ob_srv_xlator_storage.cpp b/src/observer/ob_srv_xlator_storage.cpp index 18c3c4237..37ac1b3f0 100644 --- a/src/observer/ob_srv_xlator_storage.cpp +++ b/src/observer/ob_srv_xlator_storage.cpp @@ -58,6 +58,8 @@ void oceanbase::observer::init_srv_xlator_for_storage(ObSrvRpcXlator *xlator) { //RPC_PROCESSOR(ObRpcRemoveReplicaP, gctx_); RPC_PROCESSOR(ObRpcMinorFreezeP, gctx_); RPC_PROCESSOR(ObRpcCheckSchemaVersionElapsedP, gctx_); + RPC_PROCESSOR(ObRpcCheckMemtableCntP, gctx_); + RPC_PROCESSOR(ObRpcCheckMediumCompactionInfoListP, gctx_); RPC_PROCESSOR(ObRpcCheckCtxCreateTimestampElapsedP, gctx_); RPC_PROCESSOR(ObRpcUpdateBaselineSchemaVersionP, gctx_); RPC_PROCESSOR(ObRpcSwitchLeaderP, gctx_); @@ -101,11 +103,16 @@ void oceanbase::observer::init_srv_xlator_for_storage(ObSrvRpcXlator *xlator) { RPC_PROCESSOR(ObPreProcessServerP, gctx_); RPC_PROCESSOR(ObRpcBroadcastRsListP, gctx_); RPC_PROCESSOR(ObRpcBuildDDLSingleReplicaRequestP, gctx_); + RPC_PROCESSOR(ObRpcBuildSplitTabletDataStartRequestP, gctx_); + RPC_PROCESSOR(ObRpcBuildSplitTabletDataFinishRequestP, gctx_); + RPC_PROCESSOR(ObRpcFreezeSplitSrcTabletP, gctx_); + RPC_PROCESSOR(ObRpcFetchSplitTabletInfoP, gctx_); RPC_PROCESSOR(ObRpcFetchTabletAutoincSeqCacheP, gctx_); RPC_PROCESSOR(ObRpcBatchGetTabletAutoincSeqP, gctx_); RPC_PROCESSOR(ObRpcBatchSetTabletAutoincSeqP, gctx_); RPC_PROCESSOR(ObRpcClearTabletAutoincSeqCacheP, gctx_); RPC_PROCESSOR(ObRpcBatchGetTabletBindingP, gctx_); + RPC_PROCESSOR(ObRpcBatchGetTabletSplitP, gctx_); RPC_PROCESSOR(ObRpcRemoteWriteDDLRedoLogP, gctx_); RPC_PROCESSOR(ObRpcRemoteWriteDDLCommitLogP, gctx_); RPC_PROCESSOR(ObRpcSetTabletAutoincSeqP, gctx_); @@ -138,6 +145,7 @@ void oceanbase::observer::init_srv_xlator_for_storage(ObSrvRpcXlator *xlator) { RPC_PROCESSOR(ObRpcTabletMajorFreezeP, gctx_); RPC_PROCESSOR(ObRpcDetectSessionAliveP, gctx_); RPC_PROCESSOR(ObCancelGatherStatsP, gctx_); + RPC_PROCESSOR(ObRpcPrepareTabletSplitTaskRangesP, gctx_); RPC_PROCESSOR(ObRpcCheckStorageOperationStatusP, gctx_); #ifdef OB_BUILD_SHARED_STORAGE RPC_PROCESSOR(ObRpcRemoteWriteDDLFinishLogP, gctx_); diff --git a/src/observer/omt/ob_multi_tenant.cpp b/src/observer/omt/ob_multi_tenant.cpp index 7b6432ad2..a29953265 100644 --- a/src/observer/omt/ob_multi_tenant.cpp +++ b/src/observer/omt/ob_multi_tenant.cpp @@ -172,6 +172,7 @@ #include "storage/tenant_snapshot/ob_tenant_snapshot_service.h" #include "share/index_usage/ob_index_usage_info_mgr.h" #include "rootserver/mview/ob_mview_maintenance_service.h" +#include "storage/restore/ob_tenant_restore_info_mgr.h" #include "share/io/ob_storage_io_usage_reporter.h" #include "share/resource_limit_calculator/ob_resource_limit_calculator.h" #include "storage/checkpoint/ob_checkpoint_diagnose.h" @@ -179,6 +180,7 @@ #include "lib/roaringbitmap/ob_rb_memory_mgr.h" #include "storage/tmp_file/ob_tmp_file_manager.h" // ObTenantTmpFileManager #include "storage/restore/ob_tenant_restore_info_mgr.h" +#include "share/scheduler/ob_partition_auto_split_helper.h" #ifdef OB_BUILD_AUDIT_SECURITY #include "sql/audit/ob_audit_logger.h" #include "sql/audit/ob_audit_log_mgr.h" @@ -618,6 +620,7 @@ int ObMultiTenant::init(ObAddr myaddr, 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); MTL_BIND2(mtl_new_default, rootserver::ObMViewMaintenanceService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, storage::ObTenantRestoreInfoMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObStorageIOUsageRepoter::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); #ifdef OB_BUILD_SHARED_STORAGE MTL_BIND2(mtl_new_default, ObPublicBlockGCService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); @@ -638,6 +641,7 @@ int ObMultiTenant::init(ObAddr myaddr, MTL_BIND2(mtl_new_default, table::ObTableClientInfoMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, observer::ObTableQueryASyncMgr::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); MTL_BIND2(mtl_new_default, ObPluginVectorIndexService::mtl_init, mtl_start_default, mtl_stop_default, mtl_wait_default, mtl_destroy_default); + MTL_BIND2(mtl_new_default, ObAutoSplitTaskCache::mtl_init, nullptr, nullptr, nullptr, mtl_destroy_default); } if (OB_SUCC(ret)) { diff --git a/src/observer/table_load/ob_table_load_instance.cpp b/src/observer/table_load/ob_table_load_instance.cpp index 600935956..c73725449 100644 --- a/src/observer/table_load/ob_table_load_instance.cpp +++ b/src/observer/table_load/ob_table_load_instance.cpp @@ -374,7 +374,7 @@ int ObTableLoadInstance::lock_table_in_tx() while (OB_SUCC(ret) && !lock_succeed) { if (OB_FAIL(execute_ctx_->check_status())) { LOG_WARN("failed to check status", KR(ret)); - } else if (OB_FAIL(table_lock_service->lock_table(*tx_desc, stmt_ctx_.tx_param_, lock_table_arg))) { + } else if (OB_FAIL(table_lock_service->lock(*tx_desc, stmt_ctx_.tx_param_, lock_table_arg))) { if (OB_EAGAIN == ret) { ob_usleep(sleep_time); ret = OB_SUCCESS; diff --git a/src/observer/table_load/ob_table_load_redef_table.cpp b/src/observer/table_load/ob_table_load_redef_table.cpp index 7020fae94..1b95d74a8 100644 --- a/src/observer/table_load/ob_table_load_redef_table.cpp +++ b/src/observer/table_load/ob_table_load_redef_table.cpp @@ -118,6 +118,7 @@ int ObTableLoadRedefTable::finish(const ObTableLoadRedefTableFinishArg &arg, finish_redef_table_arg.task_id_ = arg.task_id_; finish_redef_table_arg.tenant_id_ = arg.tenant_id_; + ObAddr rs_addr; ObDDLBuildSingleReplicaResponseArg build_single_replica_response_arg; build_single_replica_response_arg.task_id_ = arg.task_id_; build_single_replica_response_arg.tenant_id_ = arg.tenant_id_; @@ -132,6 +133,7 @@ int ObTableLoadRedefTable::finish(const ObTableLoadRedefTableFinishArg &arg, build_single_replica_response_arg.snapshot_version_ = 1; build_single_replica_response_arg.execution_id_ = 1; build_single_replica_response_arg.ret_code_ = ret; + build_single_replica_response_arg.server_addr_ = GCTX.self_addr(); if (OB_FAIL(ObDDLServerClient::finish_redef_table( finish_redef_table_arg, build_single_replica_response_arg, session_info))) { LOG_WARN("failed to finish redef table", KR(ret), K(finish_redef_table_arg)); diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_encrypt_info.h b/src/observer/virtual_table/ob_all_virtual_tablet_encrypt_info.h index 1b24b9331..ecab9d74a 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_encrypt_info.h +++ b/src/observer/virtual_table/ob_all_virtual_tablet_encrypt_info.h @@ -20,6 +20,7 @@ #include "share/ob_scanner.h" #include "share/ob_virtual_table_scanner_iterator.h" #include "share/rc/ob_tenant_base.h" +#include "storage/blocksstable/index_block/ob_index_block_macro_iterator.h" #include "storage/blocksstable/index_block/ob_index_block_dual_meta_iterator.h" #include "storage/blocksstable/ob_sstable_meta.h" #include "storage/meta_mem/ob_tablet_handle.h" diff --git a/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.h b/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.h index 16b65cc9e..3fe0311bb 100644 --- a/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.h +++ b/src/observer/virtual_table/ob_all_virtual_tablet_sstable_macro_info.h @@ -18,6 +18,7 @@ #include "share/ob_scanner.h" #include "share/ob_virtual_table_scanner_iterator.h" #include "share/rc/ob_tenant_base.h" +#include "storage/blocksstable/index_block/ob_index_block_macro_iterator.h" #include "storage/blocksstable/index_block/ob_index_block_dual_meta_iterator.h" #include "storage/blocksstable/ob_sstable_meta.h" #include "storage/ob_i_table.h" diff --git a/src/pl/CMakeLists.txt b/src/pl/CMakeLists.txt index 5ea646433..b2a1fbb92 100644 --- a/src/pl/CMakeLists.txt +++ b/src/pl/CMakeLists.txt @@ -84,6 +84,7 @@ ob_set_subtarget(ob_pl sys_package sys_package/ob_dbms_sql.cpp sys_package/ob_dbms_xplan.cpp sys_package/ob_dbms_user_define_rule.cpp + sys_package/ob_dbms_space.cpp sys_package/ob_dbms_mview_mysql.cpp sys_package/ob_dbms_mview_stats_mysql.cpp sys_package/ob_dbms_workload_repository.cpp diff --git a/src/pl/ob_pl_interface_pragma.h b/src/pl/ob_pl_interface_pragma.h index c89623e3e..e8e93aa76 100644 --- a/src/pl/ob_pl_interface_pragma.h +++ b/src/pl/ob_pl_interface_pragma.h @@ -69,6 +69,7 @@ #include "pl/sys_package/ob_dbms_xplan.h" #include "pl/sys_package/ob_pl_dbms_resource_manager.h" #include "pl/sys_package/ob_dbms_session.h" +#include "pl/sys_package/ob_dbms_space.h" #include "pl/sys_package/ob_dbms_workload_repository.h" #include "pl/sys_package/ob_dbms_mview_mysql.h" #include "pl/sys_package/ob_dbms_mview_stats_mysql.h" @@ -620,6 +621,10 @@ INTERFACE_DEF(INTERFACE_DBMS_SESSION_RESET_PACKAGE, "RESET_PACKAGE", (ObDBMSSession::reset_package)) // end of dbms_session + // start of dbms_space + INTERFACE_DEF(INTERFACE_DBMS_SPACE_CREATE_INDEX_COST, "CREATE_INDEX_COST", (ObDbmsSpace::create_index_cost)) + // end of dbms_space + #ifdef OB_BUILD_ORACLE_PL // start of dbms_rls INTERFACE_DEF(INTERFACE_RLS_ADD_GROUPED_POLICY, "RLS_ADD_GROUPED_POLICY", (ObDBMSRls::add_grouped_policy)) diff --git a/src/pl/ob_pl_package_manager.cpp b/src/pl/ob_pl_package_manager.cpp index e5788402e..207c6d848 100644 --- a/src/pl/ob_pl_package_manager.cpp +++ b/src/pl/ob_pl_package_manager.cpp @@ -475,6 +475,7 @@ static const ObSysPackageFile oracle_syspack_file_list[] = { {"json_object_t", "json_object_type.sql", "json_object_type_body.sql"}, {"dbms_mview", "dbms_mview.sql", "dbms_mview_body.sql"}, {"dbms_mview_stats", "dbms_mview_stats.sql", "dbms_mview_stats_body.sql"}, + {"dbms_space", "dbms_space.sql", "dbms_space_body.sql"}, {"json_array_t", "json_array_type.sql", "json_array_type_body.sql"}, {"xmlsequence", "xml_sequence_type.sql", nullptr}, {"utl_recomp", "utl_recomp.sql", "utl_recomp_body.sql"}, @@ -504,7 +505,8 @@ static const ObSysPackageFile mysql_syspack_file_list[] = { {"dbms_ob_limit_calculator", "dbms_ob_limit_calculator_mysql.sql", "dbms_ob_limit_calculator_body_mysql.sql"}, {"dbms_external_table", "dbms_external_table_mysql.sql", "dbms_external_table_body_mysql.sql"}, {"external_table_alert_log", "external_table_alert_log.sql", nullptr}, - {"dbms_vector", "dbms_vector_mysql.sql", "dbms_vector_body_mysql.sql"} + {"dbms_vector", "dbms_vector_mysql.sql", "dbms_vector_body_mysql.sql"}, + {"dbms_space", "dbms_space_mysql.sql", "dbms_space_body_mysql.sql"} }; // for now! we only have one special system package "__DBMS_UPGRADE" diff --git a/src/pl/ob_pl_resolver.cpp b/src/pl/ob_pl_resolver.cpp index 4134474af..4d9dff7e1 100644 --- a/src/pl/ob_pl_resolver.cpp +++ b/src/pl/ob_pl_resolver.cpp @@ -14189,7 +14189,7 @@ int ObPLResolver::resolve_routine(ObObjAccessIdent &access_ident, ObObjAccessIdx access_idx; if (expr_params.count() != 2 && expr_params.count() != 3) { ret = OB_ERR_WRONG_TYPE_FOR_VAR; - LOG_WARN("PLS-00306: wrong number or types of arguments in call to 'RAISE_APPLICATION_ERROR'", K(ret));; + LOG_WARN("PLS-00306: wrong number or types of arguments in call to 'RAISE_APPLICATION_ERROR'", K(ret)); LOG_USER_ERROR(OB_ERR_WRONG_TYPE_FOR_VAR, routine_name.length(), routine_name.ptr()); } else { ObPLDataType invalid_pl_data_type; diff --git a/src/pl/sys_package/ob_dbms_space.cpp b/src/pl/sys_package/ob_dbms_space.cpp new file mode 100644 index 000000000..24e0ad920 --- /dev/null +++ b/src/pl/sys_package/ob_dbms_space.cpp @@ -0,0 +1,1052 @@ +/** + * 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 DDL +#include "pl/sys_package/ob_dbms_space.h" +#include "sql/parser/ob_parser.h" +#include "sql/ob_sql_context.h" +#include "sql/resolver/ddl/ob_create_index_resolver.h" +#include "share/stat/ob_opt_stat_manager.h" +#include "lib/mysqlclient/ob_mysql_proxy.h" +#include "lib/mysqlclient/ob_mysql_result.h" +#include "share/stat/ob_dbms_stats_utils.h" +#include "pl/sys_package/ob_dbms_stats.h" +#include "sql/ob_sql_define.h" +#include "lib/utility/utility.h" +#include "share/ob_ddl_common.h" +#include "observer/ob_server_struct.h" + +#define GET_COMPRESSED_INFO_SQL "select sum(occupy_size)/sum(original_size) as compression_ratio from oceanbase.__all_virtual_tablet_sstable_macro_info "\ + "where tablet_id in (%.*s) and (svr_ip, svr_port) in (%.*s) and tenant_id = %lu;"\ + +#define GET_TABLET_INFO_SQL "select case when tablet_id is null then 0 else tablet_id end as tablet_id,"\ + " sum(original_size)/sum(row_count) as row_len,"\ + " sum(row_count) as row_count, "\ + " sum(occupy_size)/sum(original_size) as compression_ratio "\ + "from __all_virtual_tablet_sstable_macro_info "\ + "where tablet_id in (%.*s) and (svr_ip, svr_port) in (%.*s) and tenant_id = %lu "\ + "group by __all_virtual_tablet_sstable_macro_info.tablet_id with rollup;" + +#define GET_TABLET_SIZE_SQL "select case when tablet_id is null then 0 else tablet_id end as tablet_id,"\ + " sum(occupy_size) as tablet_size "\ + "from __all_virtual_tablet_sstable_macro_info "\ + "where tablet_id in (%.*s) and (svr_ip, svr_port) in (%.*s) and tenant_id = %lu "\ + "group by __all_virtual_tablet_sstable_macro_info.tablet_id;" + +namespace oceanbase +{ +using namespace sql; +using namespace common; +namespace pl +{ + +/** + * @brief ObDbmsSpace::create_index_cost + * @param ctx + * @param params + * 0. ddl VARCHAR2, // the create index sql + * 1. used_bytes NUMBER, // the real size + * 2. alloc_bytes NUMBER, // the store size. + * 3. plan_table VARCHAR2, // the data table, default NULL + * @param result + * @return + */ +int ObDbmsSpace::create_index_cost(sql::ObExecContext &ctx, + sql::ParamStore ¶ms, + common::ObObj &result) +{ + int ret = OB_SUCCESS; + ObCreateIndexStmt *stmt = nullptr; + IndexCostInfo info; + OptStats opt_stats; + ObString ddl_str; + + if (params.count() != 4) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "param count do not match", K(ret), K(params)); + } else if (OB_FAIL(params.at(0).get_string(ddl_str))) { + SQL_ENG_LOG(WARN, "fail to get string", K(ret)); + } else if (OB_FAIL(parse_ddl_sql(ctx, ddl_str, stmt))) { + SQL_ENG_LOG(WARN, "fail to parse_ddl_SQL", K(ret)); + } else if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "get unexpected null pointer", K(ret)); + } else if (OB_FAIL(extract_info_from_stmt(ctx, + stmt, + info))) { + SQL_ENG_LOG(WARN, "fail extract info from stmt", K(ret)); + } else if (OB_FAIL(get_compressed_ratio(ctx, info))) { + SQL_ENG_LOG(WARN, "fail to get compression ratio", K(ret)); + } else if (OB_FAIL(get_optimizer_stats(info, + opt_stats))) { + SQL_ENG_LOG(WARN, "fail to get opt stats", K(ret)); + } else if (OB_FAIL(calc_index_size(opt_stats, + info, + params.at(1), + params.at(2)))) { + SQL_ENG_LOG(WARN, "fail to calc index size", K(ret)); + } + + return ret; +} + +// parser sql_string to statement +int ObDbmsSpace::parse_ddl_sql(ObExecContext &ctx, + const ObString &ddl_sql, + ObCreateIndexStmt *&stmt) +{ + int ret = OB_SUCCESS; + ObSQLSessionInfo *session = nullptr; + ObSchemaChecker schema_checker; + stmt = nullptr; + + if (OB_ISNULL(session = ctx.get_my_session())) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(session)); + } else if (OB_FAIL(schema_checker.init(*(ctx.get_sql_ctx()->schema_guard_)))) { + SQL_ENG_LOG(WARN, "fail to init schema checker", K(ret)); + } else { + ObParser parser(ctx.get_allocator(), session->get_sql_mode()); + ParseResult parse_result; + SMART_VAR(ObResolverParams, resolver_ctx) { + resolver_ctx.allocator_ = &ctx.get_allocator(); + resolver_ctx.schema_checker_ = &schema_checker; + resolver_ctx.session_info_ = session; + resolver_ctx.expr_factory_ = ctx.get_expr_factory(); + resolver_ctx.stmt_factory_ = ctx.get_stmt_factory(); + if (OB_ISNULL(ctx.get_stmt_factory())) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "stmt factory is NULL", K(ret)); + } else if (FALSE_IT(resolver_ctx.query_ctx_ = + ctx.get_stmt_factory()->get_query_ctx())) { + } else if (OB_ISNULL(ctx.get_physical_plan_ctx())) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "phy plan ctx is NULL", K(ret)); + } else { + resolver_ctx.param_list_ = &ctx.get_physical_plan_ctx()->get_param_store(); + resolver_ctx.query_ctx_->sql_schema_guard_.set_schema_guard(ctx.get_sql_ctx()->schema_guard_); + } + + if (OB_SUCC(ret)) { + HEAP_VAR(ObCreateIndexResolver, resolver, resolver_ctx) { + ParseNode *tree = nullptr; + if (OB_FAIL(parser.parse(ddl_sql, parse_result))) { + SQL_ENG_LOG(WARN, "fail to parse stmt", K(ret)); + } else if (OB_ISNULL(tree = parse_result.result_tree_->children_[0])) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "result tree is null", K(ret)); + } else if (OB_FAIL(resolver.resolve(*tree))) { + SQL_ENG_LOG(WARN, "fail to resove parse tree", K(ret)); + } else { + stmt = resolver.get_create_index_stmt(); + } + } + } + } + } + + return ret; +} + +// get table_id, index column's column_id, partition_id +// the count of column that have statistics +int ObDbmsSpace::extract_info_from_stmt(ObExecContext &ctx, + ObCreateIndexStmt *stmt, + IndexCostInfo &info) +{ + int ret = OB_SUCCESS; + share::schema::ObSchemaGetterGuard* schema_guard = nullptr; + const share::schema::ObTableSchema* table_schema = nullptr; + ObSQLSessionInfo *session = nullptr; + int64_t partition_id = OB_INVALID_PARTITION_ID; + + if (OB_ISNULL(stmt) || OB_ISNULL(schema_guard = ctx.get_sql_ctx()->schema_guard_) + || OB_ISNULL(session = ctx.get_my_session())) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(stmt), KP(schema_guard)); + } else if (OB_FAIL(schema_guard->get_table_schema(session->get_effective_tenant_id(), + stmt->get_table_id(), + table_schema))) { + SQL_ENG_LOG(WARN, "fail to get table_schema", K(ret)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_TABLE_NOT_EXIST; + SQL_ENG_LOG(WARN, "can't find table_schema", K(ret)); + } else if (OB_FAIL(get_svr_info_from_schema(table_schema, info.svr_addr_, info.tablet_ids_, info.table_tenant_id_))) { + SQL_ENG_LOG(WARN, "fail to get info from schema", K(ret)); + } else if (OB_FAIL(get_index_column_ids(table_schema, stmt->get_create_index_arg(), info))) { + SQL_ENG_LOG(WARN, "fail to get index column ids", K(ret)); + } else { + info.tenant_id_ = session->get_effective_tenant_id(); + info.table_id_ = ObSchemaUtils::get_extract_schema_id(info.tenant_id_, stmt->get_table_id()); + if (table_schema->is_partitioned_table()) { + partition_id = -1; + } else { + partition_id = ObSchemaUtils::get_extract_schema_id(info.tenant_id_, info.table_id_); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(info.part_ids_.push_back(partition_id))) { + SQL_ENG_LOG(WARN, "fail to push back partition_id", K(ret)); + } else { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: finial info is ", K(info)); + } + } + } + + return ret; +} + +int ObDbmsSpace::get_index_column_ids(const share::schema::ObTableSchema *table_schema, + const obrpc::ObCreateIndexArg &arg, + IndexCostInfo &info) + +{ + int ret = OB_SUCCESS; + const ObColumnSchemaV2 *tmp_col = nullptr; + ObIArray &column_ids = info.column_ids_; + ObString tmp_col_name; + bool is_tmp_match = true; + bool is_match = false; + bool is_oracle_mode = false; + + if (OB_ISNULL(table_schema)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(table_schema)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg.index_columns_.count(); ++i) { + // get index column ids; + const ObColumnSchemaV2 *tmp_col = nullptr; + tmp_col_name = arg.index_columns_.at(i).column_name_; + if (OB_ISNULL(tmp_col = table_schema->get_column_schema(tmp_col_name))) { + ret = OB_ERR_COLUMN_NOT_FOUND; + SQL_ENG_LOG(WARN, "fail to get column schema", K(ret), K(tmp_col_name)); + } else if (OB_FAIL(column_ids.push_back(tmp_col->get_column_id()))) { + SQL_ENG_LOG(WARN, "fail to push back column id", K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: final column ids are", K(column_ids)); + } + + return ret; +} + +int ObDbmsSpace::get_optimizer_stats(const IndexCostInfo &info, + OptStats &opt_stats) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(ObOptStatManager::get_instance().get_table_stat(info.table_tenant_id_, + info.table_id_, + info.part_ids_, + opt_stats.table_stats_))) { + SQL_ENG_LOG(WARN, "fail to get table stat", K(ret)); + } else if (OB_FAIL(ObOptStatManager::get_instance().get_column_stat(info.table_tenant_id_, + info.table_id_, + info.part_ids_, + info.column_ids_, + opt_stats.column_stats_))) { + SQL_ENG_LOG(WARN, "fail to get column stats", K(ret)); + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: get optimizer statistics", K(opt_stats.table_stats_), K(opt_stats.column_stats_)); + } + + return ret; +} + + +int ObDbmsSpace::get_compressed_ratio(ObExecContext &ctx, + IndexCostInfo &info) +{ + int ret = OB_SUCCESS; + ObMySQLProxy *sql_proxy = nullptr; + ObSQLSessionInfo *session = nullptr; + + if (OB_ISNULL(sql_proxy = ctx.get_sql_proxy()) || OB_ISNULL(session = ctx.get_my_session())) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(sql_proxy), KP(session)); + } else if (OB_FAIL(inner_get_compressed_ratio(sql_proxy, info))){ + SQL_ENG_LOG(WARN, "fail to calc compression ratio", K(ret)); + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: get compression ratio", K(info.compression_ratio_)); + } + + return ret; +} + +int ObDbmsSpace::inner_get_compressed_ratio(ObMySQLProxy *sql_proxy, + IndexCostInfo &info) +{ + int ret = OB_SUCCESS; + ObSqlString compression_ratio_sql; + ObSqlString svr_addr_predicate; + ObSqlString tablet_predicate; + + if (OB_ISNULL(sql_proxy)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(sql_proxy)); + } else if (OB_FAIL(generate_part_key_str(svr_addr_predicate, info.svr_addr_))) { + SQL_ENG_LOG(WARN, "fail to get svr_addr_predicate", K(ret)); + } else if (OB_FAIL(generate_tablet_predicate_str(tablet_predicate, info.tablet_ids_))) { + SQL_ENG_LOG(WARN, "fail to get tablet_predicate", K(ret)); + } else if (svr_addr_predicate.length() == 0 || tablet_predicate.length() == 0) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "the predicate id unexpected", K(ret)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_FAIL(compression_ratio_sql.assign_fmt(GET_COMPRESSED_INFO_SQL, + static_cast(tablet_predicate.length()), + tablet_predicate.ptr(), + static_cast(svr_addr_predicate.length()), + svr_addr_predicate.ptr(), + info.table_tenant_id_))) { + SQL_ENG_LOG(WARN, "fail to construct inner sql", K(ret)); + } else if (OB_FAIL(sql_proxy->read(result, OB_SYS_TENANT_ID, compression_ratio_sql.ptr()))) { + SQL_ENG_LOG(WARN, "exec query fail", K(ret)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "get result fail", K(ret)); + } else { + while (OB_SUCC(ret) && OB_SUCC(result.get_result()->next())) { + if (OB_FAIL(extract_total_compression_ratio(result.get_result(), info.compression_ratio_))) { + SQL_ENG_LOG(WARN, "fail to extract result", K(ret)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + } + } + + return ret; +} + +int ObDbmsSpace::extract_total_compression_ratio(const sqlclient::ObMySQLResult *result, + double &compression_ratio) +{ + int ret = OB_SUCCESS; + int64_t col_idx = 0; + compression_ratio = 0; + number::ObNumber tmp_comp_ratio; + if (OB_ISNULL(result)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(result)); + } else if (OB_FAIL(result->get_number(col_idx++, tmp_comp_ratio))) { + if (ret == OB_ERR_NULL_VALUE) { + // may not have macro blocks. use the default compression_ratio + ret = OB_SUCCESS; + } else { + SQL_ENG_LOG(WARN, "fail to get double from result", K(ret)); + } + } else if (OB_FAIL(ObDbmsStatsUtils::cast_number_to_double(tmp_comp_ratio, compression_ratio))) { + SQL_ENG_LOG(WARN, "fail to cat number to double", K(ret)); + } + + return ret; +} + +int ObDbmsSpace::calc_index_size(OptStats &opt_stats, + IndexCostInfo &info, + ObObjParam &actual_size, + ObObjParam &alloc_size) +{ + int ret = OB_SUCCESS; + actual_size.set_uint64(0); + alloc_size.set_uint64(0); + uint64_t dummy_actual_size = 0; + uint64_t dummy_alloc_size = 0; + + if (info.part_ids_.count() != 1) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "fail to get table stats", K(ret)); + } else if (OB_FAIL(inner_calc_index_size(opt_stats.table_stats_.at(0), + opt_stats.column_stats_, + info, + dummy_actual_size, + dummy_alloc_size))) { + SQL_ENG_LOG(WARN, "fail to calc stat", K(ret)); + } else { + actual_size.set_uint64(dummy_actual_size); + alloc_size.set_uint64(dummy_alloc_size); + } + + return ret; +} + +int ObDbmsSpace::inner_calc_index_size(const ObOptTableStat &table_stat, + const ObIArray &column_stats, + const IndexCostInfo &info, + uint64_t &actual_size, + uint64_t &alloc_size) +{ + int ret = OB_SUCCESS; + uint64_t row_count = 0; + uint64_t block_count = 0; + uint64_t index_column_len = 0; + uint64_t actual_store_size = 0; + int64_t target_part_id = OB_INVALID_PARTITION_ID; + const uint64_t block_size = OB_DEFAULT_MACRO_BLOCK_SIZE; + actual_size = 0; + alloc_size = 0; + if (table_stat.get_last_analyzed() > 0) { + row_count = table_stat.get_row_count(); + target_part_id = table_stat.get_partition_id(); + } else { + SQL_ENG_LOG(WARN, "the table stat is default", K(ret), K(table_stat)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < column_stats.count(); i++) { + if (OB_ISNULL(column_stats.at(i).stat_)) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "fail to get column stat", K(ret), K(column_stats.at(i).stat_)); + } else if (column_stats.at(i).stat_->get_last_analyzed() < 0) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the stat is default", K(ret)); + } else if (column_stats.at(i).stat_->get_partition_id() == target_part_id) { + uint64_t col_len = column_stats.at(i).stat_->get_avg_len(); + if (col_len > sizeof(ObDatum)) { + col_len = col_len - sizeof(ObDatum); + } + index_column_len += col_len; + } + } + + if (OB_SUCC(ret)) { + actual_store_size = row_count * index_column_len * info.compression_ratio_; + actual_store_size = actual_store_size == 0 ? 1 : actual_store_size; + if (actual_store_size % block_size != 0) { + block_count = actual_store_size / block_size + 1; + } else { + block_count = actual_store_size / block_size; + } + actual_size = actual_store_size; + alloc_size = block_count * block_size; + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: result", K(target_part_id), + K(row_count), + K(block_count), + K(index_column_len), + K(actual_size)); + } + return ret; +} + + +int ObDbmsSpace::fill_tablet_infos(const ObTableSchema *table_schema, + TabletInfoList &tablet_infos) +{ + int ret = OB_SUCCESS; + ObSEArray tmp_partition_id; + ObSEArray tmp_tablet_id; + tablet_infos.reset(); + + if (OB_ISNULL(table_schema)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(table_schema)); + } else if (OB_FAIL(table_schema->get_all_tablet_and_object_ids(tmp_tablet_id, tmp_partition_id))) { + SQL_ENG_LOG(WARN, "fail to get tablet and partition id", K(ret)); + } else if (tmp_tablet_id.count() != tmp_partition_id.count()) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "tablet id and partition id not match", K(ret), K(tmp_tablet_id), K(tmp_partition_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tmp_tablet_id.count(); i++) { + TabletInfo tmp_tablet_info(tmp_tablet_id.at(i), tmp_partition_id.at(i)); + if (OB_FAIL(tablet_infos.push_back(tmp_tablet_info))) { + SQL_ENG_LOG(WARN, "tablet id and partition id not match", K(ret), K(tmp_tablet_id), K(tmp_partition_id)); + } + } + if (OB_SUCC(ret)) { + // for partitioned table, we need an item to indicate the global information. The item's tablet_id is 0 and part_id is -1 + // this item is redundant for non-part table. + if (OB_FAIL(tablet_infos.push_back(TabletInfo(ObTabletID(0), -1)))) { + SQL_ENG_LOG(WARN, "fail to push back to tablet info", K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: tablet_info", K(tablet_infos)); + } + + return ret; +} + +const ObDbmsSpace::TabletInfo* ObDbmsSpace::get_tablet_info_by_tablet_id(const TabletInfoList &tablet_infos, + const ObTabletID tablet_id) +{ + const TabletInfo *res = nullptr; + for (int64_t i = 0; i < tablet_infos.count(); i++) { + if (tablet_infos.at(i).tablet_id_ == tablet_id) { + res = &tablet_infos.at(i); + break; + } + } + return res; +} + +const ObDbmsSpace::TabletInfo* ObDbmsSpace::get_tablet_info_by_part_id(const TabletInfoList &tablet_infos, + const ObObjectID partition_id) +{ + const TabletInfo *res = nullptr; + for (int64_t i = 0; i < tablet_infos.count(); i++) { + if (tablet_infos.at(i).partition_id_ == partition_id) { + res = &tablet_infos.at(i); + break; + } + } + return res; +} + +int ObDbmsSpace::get_each_tablet_size(ObMySQLProxy *sql_proxy, + TabletInfoList &tablet_infos, + IndexCostInfo &info) +{ + int ret = OB_SUCCESS; + ObSqlString get_tablet_size_sql; + ObSqlString svr_addr_predicate; + ObSqlString tablet_predicate; + + if (OB_ISNULL(sql_proxy)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(sql_proxy)); + } else if (OB_FAIL(generate_part_key_str(svr_addr_predicate, info.svr_addr_))) { + SQL_ENG_LOG(WARN, "fail to get svr_addr_predicate", K(ret)); + } else if (OB_FAIL(generate_tablet_predicate_str(tablet_predicate, info.tablet_ids_))) { + SQL_ENG_LOG(WARN, "fail to get tablet_predicate", K(ret)); + } else if (svr_addr_predicate.length() == 0 || tablet_predicate.length() == 0) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "the predicate id unexpected", K(ret)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_FAIL(get_tablet_size_sql.assign_fmt(GET_TABLET_INFO_SQL, + static_cast(tablet_predicate.length()), + tablet_predicate.ptr(), + static_cast(svr_addr_predicate.length()), + svr_addr_predicate.ptr(), + info.table_tenant_id_))) { + SQL_ENG_LOG(WARN, "fail to construct inner sql", K(ret)); + } else if (OB_FAIL(sql_proxy->read(result, OB_SYS_TENANT_ID, get_tablet_size_sql.ptr()))) { + SQL_ENG_LOG(WARN, "exec query fail", K(ret)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "get result fail", K(ret)); + } else { + while (OB_SUCC(ret) && OB_SUCC(result.get_result()->next())) { + if (OB_FAIL(extract_tablet_size(result.get_result(), tablet_infos))) { + SQL_ENG_LOG(WARN, "fail to extract result", K(ret)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + } + } + + return ret; +} + +int ObDbmsSpace::get_each_tablet_size(ObMySQLProxy *sql_proxy, + const ObTableSchema *table_schema, + ObIArray> &tablet_size) +{ + int ret = OB_SUCCESS; + ObSqlString get_tablet_size_sql; + ObSqlString svr_addr_predicate; + ObSqlString tablet_predicate; + ObSEArray svr_addr; + ObSEArray tablet_ids; + uint64_t table_tenant_id = OB_INVALID_TENANT_ID; + tablet_size.reset(); + + if (OB_ISNULL(sql_proxy) || OB_ISNULL(table_schema)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(sql_proxy), KP(table_schema)); + } else if (OB_FAIL(get_svr_info_from_schema(table_schema, svr_addr, tablet_ids, table_tenant_id))) { + SQL_ENG_LOG(WARN, "fail to get svr_info", K(ret)); + } else if (OB_FAIL(generate_part_key_str(svr_addr_predicate, svr_addr))) { + SQL_ENG_LOG(WARN, "fail to get svr_addr_predicate", K(ret)); + } else if (OB_FAIL(generate_tablet_predicate_str(tablet_predicate, tablet_ids))) { + SQL_ENG_LOG(WARN, "fail to get tablet_predicate", K(ret)); + } else if (svr_addr_predicate.length() == 0 || tablet_predicate.length() == 0) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "the predicate id unexpected", K(ret)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, result) { + if (OB_FAIL(get_tablet_size_sql.assign_fmt(GET_TABLET_SIZE_SQL, + static_cast(tablet_predicate.length()), + tablet_predicate.ptr(), + static_cast(svr_addr_predicate.length()), + svr_addr_predicate.ptr(), + table_tenant_id))) { + SQL_ENG_LOG(WARN, "fail to construct inner sql", K(ret)); + } else if (OB_FAIL(sql_proxy->read(result, OB_SYS_TENANT_ID, get_tablet_size_sql.ptr()))) { + SQL_ENG_LOG(WARN, "exec query fail", K(ret)); + } else if (OB_ISNULL(result.get_result())) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "get result fail", K(ret)); + } else { + while (OB_SUCC(ret) && OB_SUCC(result.get_result()->next())) { + if (OB_FAIL(extract_tablet_size(result.get_result(), tablet_size))) { + SQL_ENG_LOG(WARN, "fail to extract result", K(ret)); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + } + } + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: get each tablet size", K(tablet_size)); + } + + return ret; +} + +int ObDbmsSpace::extract_tablet_size(const sqlclient::ObMySQLResult *result, + ObIArray> &tablet_size) +{ + int ret = OB_SUCCESS; + int64_t col_idx = 0; + int64_t tablet_id = 0; + int64_t tmp_tablet_size_int = 0; + number::ObNumber tmp_tablet_size; + if (OB_ISNULL(result)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(result)); + } else if (OB_FAIL(result->get_int(col_idx++, tablet_id))) { + if (ret == OB_ERR_NULL_VALUE) { + ret = OB_SUCCESS; + } else { + SQL_ENG_LOG(WARN, "fail to get int from result", K(ret)); + } + } else if (OB_FAIL(result->get_number(col_idx++, tmp_tablet_size))) { + if (ret == OB_ERR_NULL_VALUE) { + ret = OB_SUCCESS; + } else { + SQL_ENG_LOG(WARN, "fail to get number from result", K(ret)); + } + } else if (OB_FAIL(tmp_tablet_size.cast_to_int64(tmp_tablet_size_int))) { + SQL_ENG_LOG(WARN, "fail to cast number to int", K(ret)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(tablet_size.push_back(std::pair(ObTabletID(tablet_id), tmp_tablet_size_int)))) { + SQL_ENG_LOG(WARN, "fail to push back tablet size", K(ret)); + } + } + + return ret; +} + + +int ObDbmsSpace::extract_tablet_size(const sqlclient::ObMySQLResult *result, + TabletInfoList &tablet_infos) +{ + int ret = OB_SUCCESS; + int64_t col_idx = 0; + int64_t tablet_id = 0; + int64_t tmp_row_count_int = 0; + double tmp_row_len = 0; + double tmp_compression_ratio = 0; + number::ObNumber tmp_row_count; + number::ObNumber row_len; + number::ObNumber compression_ratio; + if (OB_ISNULL(result)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(result)); + } else if (OB_FAIL(result->get_int(col_idx++, tablet_id))) { + if (ret == OB_ERR_NULL_VALUE) { + // may not have macro blocks. use the default compression_ratio + ret = OB_SUCCESS; + } else { + SQL_ENG_LOG(WARN, "fail to get int from result", K(ret)); + } + } else if (OB_FAIL(result->get_number(col_idx++, row_len))) { + if (ret == OB_ERR_NULL_VALUE) { + ret = OB_SUCCESS; + } else { + SQL_ENG_LOG(WARN, "fail to get double from result", K(ret)); + } + } else if (OB_FAIL(result->get_number(col_idx++, tmp_row_count))) { + if (ret == OB_ERR_NULL_VALUE) { + ret = OB_SUCCESS; + } else { + SQL_ENG_LOG(WARN, "fail to get double from result", K(ret)); + } + } else if (OB_FAIL(result->get_number(col_idx++, compression_ratio))) { + if (ret == OB_ERR_NULL_VALUE) { + ret = OB_SUCCESS; + } else { + SQL_ENG_LOG(WARN, "fail to get double from result", K(ret)); + } + } else if (OB_FAIL(ObDbmsStatsUtils::cast_number_to_double(row_len, tmp_row_len))) { + SQL_ENG_LOG(WARN, "fail to cast number to double", K(ret)); + } else if (OB_FAIL(ObDbmsStatsUtils::cast_number_to_double(compression_ratio, tmp_compression_ratio))) { + SQL_ENG_LOG(WARN, "fail to cast number to double", K(ret)); + } else if (OB_FAIL(tmp_row_count.cast_to_int64(tmp_row_count_int))) { + SQL_ENG_LOG(WARN, "fail to cast number int", K(ret)); + } else if (OB_FAIL(set_tablet_info_by_tablet_id(ObTabletID(tablet_id), tmp_row_len, tmp_row_count_int, tmp_compression_ratio, + tablet_infos))) { + SQL_ENG_LOG(WARN, "fail to set tablet info", K(ret)); + } + return ret; +} + +int ObDbmsSpace::set_tablet_info_by_tablet_id(const ObTabletID tablet_id, + const double row_len, + const uint64_t row_count, + const double compression_ratio, + TabletInfoList &tablet_infos) +{ + int ret = OB_SUCCESS; + + TabletInfo *tablet_info = nullptr; + if (row_len < 0 || compression_ratio < 0) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "get invalid argument", K(ret), K(row_len), K(compression_ratio)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_infos.count(); i++) { + if (tablet_infos.at(i).tablet_id_ == tablet_id) { + tablet_info = &tablet_infos.at(i); + break; + } + } + + if (OB_SUCC(ret)) { + if (OB_ISNULL(tablet_info)) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "fail to get tablet info", K(ret), KP(tablet_info)); + } else { + tablet_info->row_count_ = row_count; + tablet_info->row_len_ = row_len; + tablet_info->compression_ratio_ = compression_ratio; + } + } + + return ret; +} + +int ObDbmsSpace::estimate_index_table_size(ObMySQLProxy *sql_proxy, + const ObTableSchema *table_schema, + IndexCostInfo &info, + ObIArray &table_size) +{ + int ret = OB_SUCCESS; + OptStats opt_stats; + bool is_valid = false; + table_size.reset(); + + if (OB_ISNULL(sql_proxy)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(sql_proxy)); + } else if (OB_FAIL(get_optimizer_stats(info, opt_stats))) { + SQL_ENG_LOG(WARN, "fail to get opt stats", K(ret)); + } else if (OB_FAIL(check_stats_valid(opt_stats, is_valid))) { + SQL_ENG_LOG(WARN, "fail to check opt stats", K(ret)); + } else if (is_valid) { + if (OB_FAIL(estimate_index_table_size_by_opt_stats(sql_proxy, opt_stats, info, table_size))) { + SQL_ENG_LOG(WARN, "fail to estimate index table size", K(ret)); + } + } else if (OB_FAIL(estimate_index_table_size_default(sql_proxy, table_schema, info, table_size))) { + SQL_ENG_LOG(WARN, "fail to estimate index table size by default", K(ret)); + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: table_size", K(table_size)); + } + + return ret; +} + +int ObDbmsSpace::check_stats_valid(const OptStats &opt_stats, bool &is_valid) +{ + int ret = OB_SUCCESS; + is_valid = true; + for (int64_t i = 0; is_valid && i < opt_stats.table_stats_.count(); i++) { + if (opt_stats.table_stats_.at(i).get_last_analyzed() > 0) { + } else { + is_valid = false; + } + } + for (int64_t i = 0; OB_SUCC(ret) && is_valid && i < opt_stats.column_stats_.count(); i++) { + const ObOptColumnStat *col_stat = nullptr; + if (OB_ISNULL(col_stat = opt_stats.column_stats_.at(i).stat_)) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "get unexpected null pointer", K(ret)); + } else if (col_stat->get_last_analyzed() > 0) { + } else { + is_valid = false; + } + } + + return ret; +} + +int ObDbmsSpace::estimate_index_table_size_by_opt_stats(ObMySQLProxy *sql_proxy, + const OptStats &opt_stats, + IndexCostInfo &info, + ObIArray &table_size) +{ + int ret = OB_SUCCESS; + table_size.reset(); + + if (OB_ISNULL(sql_proxy)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(sql_proxy)); + } else if (OB_FAIL(inner_get_compressed_ratio(sql_proxy, info))) { + SQL_ENG_LOG(WARN, "fail to get compression ratio", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < info.part_ids_.count(); i++) { + uint64_t dummy_alloc_size = 0; + uint64_t actual_size = 0; + if (OB_FAIL(inner_calc_index_size(opt_stats.table_stats_.at(i), opt_stats.column_stats_, info, + actual_size, dummy_alloc_size))) { + SQL_ENG_LOG(WARN, "fail to calc index size", K(ret)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(table_size.push_back(actual_size))) { + SQL_ENG_LOG(WARN, "fail to push back table_size", K(ret), K(actual_size)); + } + } + } + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE: get_tablet info by opt_stats", K(opt_stats), K(table_size), K(info)); + } + return ret; +} + +int ObDbmsSpace::estimate_index_table_size_default(ObMySQLProxy *sql_proxy, + const ObTableSchema *table_schema, + IndexCostInfo &info, + ObIArray &table_size) +{ + int ret = OB_SUCCESS; + // 1. get each partition's data size; + TabletInfoList tablet_infos; + table_size.reset(); + if (OB_ISNULL(table_schema) || OB_ISNULL(sql_proxy)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(table_schema), KP(sql_proxy)); + } else if (OB_FAIL(fill_tablet_infos(table_schema, tablet_infos))) { + SQL_ENG_LOG(WARN, "fail to fill tablet info", K(ret)); + } else if (OB_FAIL(get_svr_info_from_schema(table_schema, + info.svr_addr_, + info.tablet_ids_, + info.table_tenant_id_))) { + SQL_ENG_LOG(WARN, "fail to get info from schema", K(ret)); + } else if (OB_FAIL(get_each_tablet_size(sql_proxy, tablet_infos, info))) { + SQL_ENG_LOG(WARN, "fail to get tablet size", K(ret)); + } else if (OB_FAIL(get_default_index_column_len(table_schema, + tablet_infos, + info))) { + SQL_ENG_LOG(WARN, "fail to get default index column len", K(ret)); + } else if (OB_FAIL(inner_calc_index_size_by_default(info, tablet_infos, table_size))) { + SQL_ENG_LOG(WARN, "fail to calc index size", K(ret)); + } + + if (OB_SUCC(ret)) { + SQL_ENG_LOG(TRACE, "DBMS_SPACE by default", K(tablet_infos), K(info)); + } + + return ret; +} + +int ObDbmsSpace::inner_calc_index_size_by_default(IndexCostInfo &info, + TabletInfoList &tablet_infos, + ObIArray &table_size) +{ + int ret = OB_SUCCESS; + + const TabletInfo *tablet_info = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < info.part_ids_.count(); i++) { + if (OB_ISNULL(tablet_info = get_tablet_info_by_part_id(tablet_infos, info.part_ids_.at(i)))) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "get unexpected null pointer", K(ret)); + } else { + uint64_t partition_size = info.default_index_len_ * tablet_info->row_count_ * tablet_info->compression_ratio_; + if (OB_FAIL(table_size.push_back(partition_size))) { + SQL_ENG_LOG(WARN, "fail to push back partition size", K(ret)); + } + } + } + + return ret; +} + +// TODO if no optimizer_stats should use the infomation in macro info to calc the size. +int ObDbmsSpace::get_default_index_column_len(const ObTableSchema *table_schema, + const TabletInfoList &tablet_infos, + IndexCostInfo &info) +{ + int ret = OB_SUCCESS; + // get row_len from macro_info + const TabletInfo *global_tablet_info = nullptr; + info.default_index_len_ = 0; + + if (OB_ISNULL(table_schema)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the args is null", K(ret), KP(table_schema)); + } else if (OB_ISNULL(global_tablet_info = get_tablet_info_by_tablet_id(tablet_infos, ObTabletID(0)))) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "get unexpected null pointer", K(ret)); + } else { + uint64_t index_var_column_cnt = 0; + uint64_t index_fix_column_len = 0; + uint64_t fix_column_len = 0; + uint64_t var_column_cnt = 0; + const ObColumnSchemaV2 *tmp_col = nullptr; + + for (int64_t i = 0; OB_SUCC(ret) && i < table_schema->get_column_count(); i++) { + if (OB_ISNULL(tmp_col = table_schema->get_column_schema_by_idx(i))) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "get unexpected null pointer", K(ret)); + } else { + bool is_index_column = has_exist_in_array(info.column_ids_, tmp_col->get_column_id()); + bool is_fix_column = is_fixed_length_storage(tmp_col->get_meta_type().get_type()); + if (is_fix_column) { + int16_t len = get_type_fixed_length(tmp_col->get_meta_type().get_type()); + fix_column_len += len; + if (is_index_column) { + index_fix_column_len += len; + } + } else if (tmp_col->get_meta_type().is_binary()) { + int16_t len = tmp_col->get_data_length(); + fix_column_len += len; + if (is_index_column) { + index_fix_column_len += len; + } + } else { + if (is_index_column) { + index_var_column_cnt++; + } + var_column_cnt++; + } + } + } + if (OB_SUCC(ret)) { + if (global_tablet_info->row_len_ > 0) { + if (var_column_cnt != 0) { + if (global_tablet_info->row_len_ - fix_column_len > 0) { + uint64_t avg_var_column_len = (global_tablet_info->row_len_ - fix_column_len) / var_column_cnt; + info.default_index_len_ = index_fix_column_len + avg_var_column_len * index_var_column_cnt; + } else { + info.default_index_len_ = 0; + SQL_ENG_LOG(INFO, "the var column len is less than 0", K(global_tablet_info->row_len_), K(fix_column_len)); + } + } else { + info.default_index_len_ = index_fix_column_len; + } + } else { + info.default_index_len_ = 0; + } + } + } + return ret; +} + +int ObDbmsSpace::get_svr_info_from_schema(const ObTableSchema *table_schema, + ObIArray &addr_list, + ObIArray &tablet_list, + uint64_t &tenant_id) +{ + int ret = OB_SUCCESS; + tenant_id = OB_INVALID_TENANT_ID; + addr_list.reset(); + tablet_list.reset(); + + tablet_list.reset(); + if (OB_ISNULL(table_schema)) { + ret = OB_INVALID_ARGUMENT; + SQL_ENG_LOG(WARN, "the arg is null", K(ret), KP(table_schema)); + } else if (OB_FAIL(table_schema->get_tablet_ids(tablet_list))) { + SQL_ENG_LOG(WARN, "fail to get tablet_ids", K(ret)); + } else if (tablet_list.count() <= 0) { + ret = OB_ERR_UNEXPECTED; + SQL_ENG_LOG(WARN, "can't find tablet", K(ret)); + } else { + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + ObLSID dummy_ls_id; + ObAddr leader_addr; + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_list.count(); i++) { + if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(GCTX.location_service_, + table_schema->get_tenant_id(), + tablet_list.at(i), + rpc_timeout, + dummy_ls_id, + leader_addr + ))) { + SQL_ENG_LOG(WARN, "fail to get tablet's leader_addr", K(ret)); + } else if (OB_FAIL(add_var_to_array_no_dup(addr_list, leader_addr))) { + SQL_ENG_LOG(WARN, "fail to add add to addr_list", K(ret)); + } + } + if (OB_SUCC(ret)) { + tenant_id = table_schema->get_tenant_id(); + } + } + + return ret; +} + + +int ObDbmsSpace::generate_part_key_str(ObSqlString &target_str, + const ObIArray &addr_list) +{ + int ret = OB_SUCCESS; + target_str.reset(); + const static int MAX_IP_BUFFER_LEN = 32; + char host[MAX_IP_BUFFER_LEN]; + for (int64_t i = 0; OB_SUCC(ret) && i < addr_list.count(); i++) { + host[0] = '\0'; + if (!addr_list.at(i).ip_to_string(host, MAX_IP_BUFFER_LEN)) { + ret = OB_BUF_NOT_ENOUGH; + SQL_ENG_LOG(WARN, "fail to get host.", K(ret)); + } else if (OB_FAIL(target_str.append_fmt((i == addr_list.count() - 1) ? "('%.*s', %d)" : "('%.*s', %d),", + (int)strlen(host), + host, + addr_list.at(i).get_port()))) { + SQL_ENG_LOG(WARN, "fail to append fmt.", K(ret)); + } + } + + return ret; +} + +int ObDbmsSpace::generate_tablet_predicate_str(ObSqlString &target_str, + const ObIArray &tablet_list) +{ + int ret = OB_SUCCESS; + target_str.reset(); + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_list.count(); i++) { + if (OB_FAIL(target_str.append_fmt((i == tablet_list.count() - 1) ? "%lu" : "%lu,", + tablet_list.at(i).id()))) { + SQL_ENG_LOG(WARN, "fail to generate tablet predicate", K(ret)); + } + } + + return ret; +} + +} +} diff --git a/src/pl/sys_package/ob_dbms_space.h b/src/pl/sys_package/ob_dbms_space.h new file mode 100644 index 000000000..b56730122 --- /dev/null +++ b/src/pl/sys_package/ob_dbms_space.h @@ -0,0 +1,220 @@ +/** + * 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_SRC_PL_SYS_PACKAGE_OB_DBMS_SPACE_H_ +#define OCEANBASE_SRC_PL_SYS_PACKAGE_OB_DBMS_SPACE_H_ + +#include "sql/engine/ob_exec_context.h" +#include "pl/ob_pl_type.h" +#include "lib/ob_define.h" +#include "share/stat/ob_opt_table_stat.h" +#include "share/stat/ob_opt_column_stat.h" +#include "share/stat/ob_opt_column_stat_cache.h" +#include "sql/resolver/ddl/ob_create_index_stmt.h" + +namespace oceanbase +{ +using namespace sql; +namespace pl +{ +class ObDbmsSpace +{ +public: + struct IndexCostInfo final { + public: + IndexCostInfo(): tenant_id_(OB_SYS_TENANT_ID), + table_id_(common::OB_INVALID_ID), + part_ids_(), + column_ids_(), + compression_ratio_(1.0), + default_index_len_(0), + svr_addr_(), + tablet_ids_(), + table_tenant_id_(OB_INVALID_TENANT_ID) {} + ~IndexCostInfo() = default; + TO_STRING_KV(K_(tenant_id), K_(table_id), K_(part_ids), K_(column_ids), + K_(compression_ratio), K_(default_index_len), K_(svr_addr), + K_(tablet_ids), K_(table_tenant_id)); + public: + uint64_t tenant_id_; + uint64_t table_id_; + ObSEArray part_ids_; + ObSEArray column_ids_; + double compression_ratio_; + uint64_t default_index_len_; + ObSEArray svr_addr_; + ObSEArray tablet_ids_; + uint64_t table_tenant_id_; + }; + + struct OptStats final { + public: + OptStats(): table_stats_(), column_stats_() {}; + ~OptStats() = default; + TO_STRING_KV(K_(table_stats), K_(column_stats)); + public: + ObSEArray table_stats_; + ObSEArray column_stats_; + }; + + struct TabletInfo final { + public: + TabletInfo(): tablet_id_(OB_INVALID_ID), partition_id_(OB_INVALID_PARTITION_ID), row_len_(0), row_count_(0), compression_ratio_(0) {} + TabletInfo(ObTabletID tablet_id, ObObjectID partition_id): tablet_id_(tablet_id), partition_id_(partition_id), row_len_(0), row_count_(0), compression_ratio_(0) {} + ~TabletInfo() = default; + int assign(const TabletInfo &other) { + int ret = OB_SUCCESS; + tablet_id_ = other.tablet_id_; + partition_id_ = other.partition_id_; + row_len_ = other.row_len_; + row_count_ = other.row_count_; + compression_ratio_ = other.compression_ratio_; + return ret; + } + TO_STRING_KV(K_(tablet_id), K_(partition_id), K_(row_len), K_(row_count), K_(compression_ratio)); + public: + ObTabletID tablet_id_; + ObObjectID partition_id_; + double row_len_; + uint64_t row_count_; + double compression_ratio_; + }; + typedef ObSEArray TabletInfoList; + +public: + static int create_index_cost(sql::ObExecContext &ctx, + sql::ParamStore ¶ms, + common::ObObj &result); + + // interface for auto_split + /* in param: + * info tenant_id_; // default set to OB_SYS_TENANT_ID + * info table_id_; // data table's table id; + * info.part_ids_; // the part id(data table) we need to calc. + * info.column_ids_; // index columns' column id (in data table schema). + * out param: + * the table_size in info.part_ids_'s order + */ + static int estimate_index_table_size(ObMySQLProxy *sql_proxy, + const ObTableSchema *table_schema, + IndexCostInfo &info, + ObIArray &table_size); + + // interface to get each tablet_size in the table + /* + * in param: + * table_schema -- the target table we need to calc size. + * out param: + * each tablet's size. + */ + static int get_each_tablet_size(ObMySQLProxy *sql_proxy, + const ObTableSchema *table_schema, + ObIArray> &tablet_size); +private: + + static int parse_ddl_sql(ObExecContext &ctx, + const ObString &ddl_sql, + ObCreateIndexStmt *&stmt); + + static int extract_info_from_stmt(ObExecContext &ctx, + ObCreateIndexStmt *stmt, + IndexCostInfo &info); + + static int get_index_column_ids(const share::schema::ObTableSchema *table_schema, + const obrpc::ObCreateIndexArg &arg, + IndexCostInfo &info); + + static int get_optimizer_stats(const IndexCostInfo &info, + OptStats &opt_stats); + + static int calc_index_size(OptStats &opt_stats, + IndexCostInfo &info, + ObObjParam &actual_size, + ObObjParam &alloc_size); + + static int get_compressed_ratio(ObExecContext &ctx, + IndexCostInfo &info); + + static int inner_get_compressed_ratio(ObMySQLProxy *sql_proxy, + IndexCostInfo &info); + + static int extract_total_compression_ratio(const sqlclient::ObMySQLResult *result, + double &compression_ratio); + + static int inner_calc_index_size(const ObOptTableStat &table_stat, + const ObIArray &column_stats, + const IndexCostInfo &info, + uint64_t &actual_size, + uint64_t &alloc_size); + + static int estimate_index_table_size_by_opt_stats(ObMySQLProxy *sql_proxy, + const OptStats &opt_stats, + IndexCostInfo &info, + ObIArray &table_size); + + static int estimate_index_table_size_default(ObMySQLProxy *sql_proxy, + const ObTableSchema *table_schema, + IndexCostInfo &info, + ObIArray &table_size); + + static int inner_calc_index_size_by_default(IndexCostInfo &info, + TabletInfoList &tablet_infos, + ObIArray &table_size); + + static int fill_tablet_infos(const ObTableSchema *table_schema, + TabletInfoList &tablet_infos); + + static int extract_tablet_size(const sqlclient::ObMySQLResult *result, + TabletInfoList &tablet_infos); + + static int extract_tablet_size(const sqlclient::ObMySQLResult *result, + ObIArray> &tablet_size); + + static int get_each_tablet_size(ObMySQLProxy *sql_proxy, + TabletInfoList &tablet_infos, + IndexCostInfo &info); + + static const TabletInfo* get_tablet_info_by_tablet_id(const TabletInfoList &tablet_infos, + const ObTabletID tablet_id); + + static const TabletInfo* get_tablet_info_by_part_id(const TabletInfoList &tablet_infos, + const ObObjectID partition_id); + + static int set_tablet_info_by_tablet_id(const ObTabletID tablet_id, + const double row_len, + const uint64_t row_count, + const double compression_ratio, + TabletInfoList &tablet_infos); + + static int get_default_index_column_len(const ObTableSchema *table_schema, + const TabletInfoList &table_infos, + IndexCostInfo &info); + + static int check_stats_valid(const OptStats &opt_stats, bool &is_valid); + + static int get_svr_info_from_schema(const ObTableSchema *table_schema, + ObIArray &addr_list, + ObIArray &tablet_list, + uint64_t &tenant_id); + + static int generate_part_key_str(ObSqlString &target_str, + const ObIArray &addr_list); + + static int generate_tablet_predicate_str(ObSqlString &target_str, + const ObIArray &tablet_list); + +}; + +} +} + +#endif \ No newline at end of file diff --git a/src/rootserver/CMakeLists.txt b/src/rootserver/CMakeLists.txt index 765ae5bbb..9ce81d214 100644 --- a/src/rootserver/CMakeLists.txt +++ b/src/rootserver/CMakeLists.txt @@ -101,6 +101,7 @@ ob_set_subtarget(ob_rootserver common ob_lob_meta_builder.cpp ob_ls_recovery_stat_handler.cpp ob_shrink_expand_resource_pool_checker.cpp + ob_split_partition_helper.cpp ob_transfer_partition_command.cpp ob_partition_exchange.cpp ob_service_name_command.cpp @@ -131,6 +132,7 @@ ob_set_subtarget(ob_rootserver ddl_task ddl_task/ob_fts_index_build_task.cpp ddl_task/ob_modify_autoinc_task.cpp ddl_task/ob_table_redefinition_task.cpp + ddl_task/ob_partition_split_task.cpp ddl_task/ob_recover_restore_table_task.cpp ddl_task/ob_ddl_tablet_scheduler.cpp ddl_task/ob_rebuild_index_task.cpp diff --git a/src/rootserver/backup/ob_backup_data_set_task_mgr.cpp b/src/rootserver/backup/ob_backup_data_set_task_mgr.cpp index ea074bc1f..81ef136b3 100644 --- a/src/rootserver/backup/ob_backup_data_set_task_mgr.cpp +++ b/src/rootserver/backup/ob_backup_data_set_task_mgr.cpp @@ -36,7 +36,6 @@ #include "share/ob_tenant_info_proxy.h" #include "observer/ob_inner_sql_connection.h" #include "share/backup/ob_backup_server_mgr.h" -#include "share/backup/ob_backup_tablet_reorganize_helper.h" #include "rootserver/backup/ob_backup_table_list_mgr.h" using namespace oceanbase; @@ -1189,6 +1188,10 @@ int ObBackupSetTaskMgr::change_turn_( ObIArray &tablets_to_ls) { int ret = OB_SUCCESS; + ROOTSERVICE_EVENT_INSTANCE.sync_add_event("rs_backup", "rs_before_change_turn", + "tenant_id", set_task_attr_.tenant_id_, + "task_id", set_task_attr_.task_id_); + DEBUG_SYNC(RS_CHANGE_TURN_DEBUG_SYNC); ObTimeoutCtx ctx; const int64_t DEFAULT_TIMEOUT = 60_s; const int64_t INNER_SQL_TIMEOUT = GCONF.internal_sql_execute_timeout; @@ -1558,10 +1561,7 @@ int ObBackupSetTaskMgr::do_get_change_turn_tablets_( ObHashMap> tablet_reorganize_ls_map; ObHashSet ls_id_set; ObHashSet new_ls_id_set; - ObLSID transfer_ls_id; - ObLSID split_ls_id; ObLSID final_ls_id; - int64_t transfer_seq = 0; const int64_t OB_BACKUP_MAX_LS_BUCKET = 1024; if (OB_ISNULL(job_attr_)) { ret = OB_ERR_UNEXPECTED; @@ -1584,35 +1584,8 @@ int ObBackupSetTaskMgr::do_get_change_turn_tablets_( for (auto iter = skipped_tablets.begin(); OB_SUCC(ret) && iter != skipped_tablets.end(); ++iter) { const ObBackupSkipTabletAttr &skip_tablet = iter->first; descendent_list.reset(); - if (OB_FAIL(ObBackupTabletToLSOperator::get_ls_of_tablet(*sql_proxy_, job_attr_->tenant_id_, skip_tablet.tablet_id_, transfer_ls_id, transfer_seq))) { - if (OB_ENTRY_NOT_EXIST == ret) { - ret = OB_SUCCESS; - bool has_reorganized = false; - ObArray *tablet_reorganize_array = NULL; - if (OB_FAIL(ObBackupTabletReorganizeHelper::check_tablet_has_reorganized( - *sql_proxy_, job_attr_->tenant_id_, skip_tablet.tablet_id_, split_ls_id, has_reorganized))) { - LOG_WARN("failed to check tablet has reorganized", K(ret), K(skip_tablet)); - } else if (!has_reorganized) { - LOG_WARN("[DATA_BACKUP]deleted tablet", K(skip_tablet)); - } else if (OB_ISNULL(tablet_reorganize_array = tablet_reorganize_ls_map.get(split_ls_id))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("do not exist", K(ret), K(split_ls_id)); - } else if (OB_FAIL(ObBackupTabletReorganizeHelper::get_leaf_children_from_history( - job_attr_->tenant_id_, *tablet_reorganize_array, skip_tablet.tablet_id_, descendent_list))) { - LOG_WARN("failed to get lead children from history", K(ret)); - } else { - final_ls_id = split_ls_id; - } - } else { - LOG_WARN("[DATA_BACKUP]failed to get tablet", K(ret), K(skip_tablet)); - } - } else if (OB_FAIL(descendent_list.push_back(skip_tablet.tablet_id_))) { - LOG_WARN("failed to push back", K(ret)); - } else { - final_ls_id = transfer_ls_id; - } - if (OB_FAIL(ret)) { - // do nothing + if (OB_FAIL(decide_tablet_final_ls_(skip_tablet, tablet_reorganize_ls_map, descendent_list, final_ls_id))) { + LOG_WARN("failed to decide tablet final ls", K(ret), K(skip_tablet), K(descendent_list)); } else if (!final_ls_id.is_valid()) { // do nothing } else { @@ -1670,6 +1643,68 @@ int ObBackupSetTaskMgr::do_get_change_turn_tablets_( return ret; } +int ObBackupSetTaskMgr::decide_tablet_final_ls_(const share::ObBackupSkipTabletAttr &skip_tablet, + common::hash::ObHashMap> &tablet_reorganize_ls_map, + common::ObArray &descendent_list, + share::ObLSID &final_ls_id) +{ + int ret = OB_SUCCESS; + final_ls_id.reset(); + ObLSID transfer_ls_id; + ObLSID split_ls_id; + int64_t transfer_seq = 0; + const int64_t OB_BACKUP_MAX_LS_BUCKET = 1024; + if (!skip_tablet.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("get invalid args", K(ret), K(skip_tablet)); + } else if (OB_ISNULL(sql_proxy_) || OB_ISNULL(job_attr_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sql proxy or job attr should not be null", K(ret), KP_(sql_proxy), KP_(job_attr)); + } else if (OB_FAIL(ObBackupTabletToLSOperator::get_ls_of_tablet(*sql_proxy_, job_attr_->tenant_id_, skip_tablet.tablet_id_, transfer_ls_id, transfer_seq))) { + if (OB_ENTRY_NOT_EXIST != ret) { + LOG_WARN("[DATA_BACKUP]failed to get tablet", K(ret), K(skip_tablet)); + } else { + ret = OB_SUCCESS; + bool has_reorganized = false; + ObArray *tablet_reorganize_array = NULL; + if (OB_FAIL(ObBackupTabletReorganizeHelper::check_tablet_has_reorganized( + *sql_proxy_, job_attr_->tenant_id_, skip_tablet.tablet_id_, split_ls_id, has_reorganized))) { + LOG_WARN("failed to check tablet has reorganized", K(ret), K(skip_tablet)); + } else if (!has_reorganized) { + LOG_INFO("[DATA_BACKUP]deleted tablet", K(skip_tablet)); + } else if (OB_ISNULL(tablet_reorganize_array = tablet_reorganize_ls_map.get(split_ls_id))) { + ObHashSet split_ls_id_set; + if (OB_FAIL(split_ls_id_set.create(OB_BACKUP_MAX_LS_BUCKET))) { + LOG_WARN("[DATA_BACKUP]failed to create set", K(ret)); + } else if (OB_FAIL(split_ls_id_set.set_refactored(split_ls_id))) { + LOG_WARN("failed to set ls id", K(ret), K(split_ls_id)); + } else if (OB_FAIL(ObBackupTabletReorganizeHelper::get_ls_to_tablet_reorganize_info_map( + *sql_proxy_, job_attr_->tenant_id_, split_ls_id_set, tablet_reorganize_ls_map))) { + LOG_WARN("failed to get tablet reorganize hash map", K(ret), KPC_(job_attr)); + } else if (OB_ISNULL(tablet_reorganize_array = tablet_reorganize_ls_map.get(split_ls_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("split ls id has no tablet reoragnize array", K(ret), K(split_ls_id)); + } else { + LOG_INFO("get ls to tablet reorganize info map", K(split_ls_id)); + } + } + if (!has_reorganized) { + // do nothing + } else if (FAILEDx(ObBackupTabletReorganizeHelper::get_leaf_children_from_history( + job_attr_->tenant_id_, *tablet_reorganize_array, skip_tablet.tablet_id_, descendent_list))) { + LOG_WARN("failed to get lead children from history", K(ret)); + } else { + final_ls_id = split_ls_id; + } + } + } else if (OB_FAIL(descendent_list.push_back(skip_tablet.tablet_id_))) { + LOG_WARN("failed to push back", K(ret)); + } else { + final_ls_id = transfer_ls_id; + } + return ret; +} + int ObBackupSetTaskMgr::deduplicate_array_(const common::ObIArray &tablet_ids, common::ObIArray &deduplicated_ids) { diff --git a/src/rootserver/backup/ob_backup_data_set_task_mgr.h b/src/rootserver/backup/ob_backup_data_set_task_mgr.h index ec7a658c5..4829538e4 100644 --- a/src/rootserver/backup/ob_backup_data_set_task_mgr.h +++ b/src/rootserver/backup/ob_backup_data_set_task_mgr.h @@ -14,6 +14,7 @@ #define OCEANBASE_SHARE_OB_BACKUP_DATA_SET_TASK_MGR_H_ #include "ob_backup_data_scheduler.h" +#include "share/backup/ob_backup_tablet_reorganize_helper.h" namespace oceanbase { @@ -99,6 +100,10 @@ private: int do_get_change_turn_tablets_(const ObIArray &ls_tasks, const common::hash::ObHashSet &skip_tablets, ObIArray &tablet_to_ls); + int decide_tablet_final_ls_(const share::ObBackupSkipTabletAttr &skip_tablet, + common::hash::ObHashMap> &tablet_reorganize_ls_map, + common::ObArray &descendent_list, + share::ObLSID &final_ls_id); int deduplicate_array_(const common::ObIArray &tablet_ids, common::ObIArray &deduplicated_ids); int construct_cur_ls_set_(const ObIArray &ls_tasks, diff --git a/src/rootserver/ddl_task/ob_column_redefinition_task.cpp b/src/rootserver/ddl_task/ob_column_redefinition_task.cpp index 269e850b5..cb232ddc0 100644 --- a/src/rootserver/ddl_task/ob_column_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_column_redefinition_task.cpp @@ -22,6 +22,7 @@ #include "rootserver/ob_root_service.h" #include "rootserver/ddl_task/ob_ddl_redefinition_task.h" #include "storage/tablelock/ob_table_lock_service.h" +#include "storage/ob_partition_pre_split.h" using namespace oceanbase::lib; using namespace oceanbase::common; @@ -152,6 +153,7 @@ int ObColumnRedefinitionTask::init(const ObDDLTaskRecord &task_record) // update sstable complement status for all leaders int ObColumnRedefinitionTask::update_complete_sstable_job_status(const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, @@ -167,14 +169,16 @@ int ObColumnRedefinitionTask::update_complete_sstable_job_status(const common::O // by pass, may be network delay } else if (snapshot_version != snapshot_version_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("snapshot version not match", K(ret), K(snapshot_version), K(snapshot_version_)); + LOG_WARN("snapshot version not match", K(ret), K(addr), K(snapshot_version), K(snapshot_version_)); } else if (execution_id < execution_id_) { - LOG_INFO("receive a mismatch execution result, ignore", K(ret_code), K(execution_id), K(execution_id_)); - } else if (OB_FAIL(replica_builder_.set_partition_task_status(tablet_id, - ret_code, - addition_info.row_scanned_, - addition_info.row_inserted_))) { - LOG_WARN("fail to set partition task status", K(ret)); + LOG_INFO("receive a mismatch execution result, ignore", K(addr), K(ret_code), K(execution_id), K(execution_id_)); + } else if (OB_FAIL(replica_builder_.update_build_progress(tablet_id, + addr, + ret_code, + addition_info.row_scanned_, + addition_info.row_inserted_, + addition_info.physical_row_count_))) { + LOG_WARN("fail to set update replica build progress", K(ret), K(addr)); } return ret; } @@ -227,10 +231,11 @@ int ObColumnRedefinitionTask::copy_table_indexes() } LOG_INFO("indexes schema are already built", K(index_ids)); } else { - // if there is no indexes in new tables, we need to rebuild indexes in new table int64_t rpc_timeout = 0; int64_t all_tablet_count = 0; - if (OB_FAIL(get_orig_all_index_tablet_count(schema_guard, all_tablet_count))) { + if (OB_FAIL(generate_rebuild_index_arg_list(tenant_id_, object_id_, schema_guard, alter_table_arg_))) { // for pre split index + LOG_WARN("fail to generate rebuild index arg list", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_FAIL(get_orig_all_index_tablet_count(schema_guard, all_tablet_count))) { LOG_WARN("get all tablet count failed", K(ret)); } else if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(all_tablet_count, rpc_timeout))) { LOG_WARN("get ddl rpc timeout failed", K(ret)); @@ -721,17 +726,32 @@ int ObColumnRedefinitionTask::collect_longops_stat(ObLongopsValue &value) break; } case ObDDLTaskStatus::REDEFINITION: { - int64_t row_scanned = 0; int64_t row_inserted = 0; - if (OB_FAIL(replica_builder_.get_progress(row_scanned, row_inserted))) { + int64_t physical_row_count_ = 0; + double percent = 0.0; + bool initializing = false; + { + TCRLockGuard guard(lock_); + initializing = !is_sstable_complete_task_submitted_; + } + if (initializing) { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: REPLICA BUILD, PARALLELISM: %ld, INITIALIZING", + ObDDLUtil::get_real_parallelism(parallelism_, false/*is mv refresh*/)))) { + LOG_WARN("failed to print", K(ret)); + } + } else if (OB_FAIL(replica_builder_.get_progress(row_inserted, physical_row_count_, percent))) { LOG_WARN("failed to gather redefinition stats", K(ret)); } else if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, - "STATUS: REPLICA BUILD, PARALLELISM: %ld, ROW_SCANNED: %ld, ROW_INSERTED: %ld", + "STATUS: REPLICA BUILD, PARALLELISM: %ld, ESTIMATED_TOTAL_ROWS: %ld, ROW_PROCESSED: %ld, PROGRESS: %0.2lf%%", ObDDLUtil::get_real_parallelism(parallelism_, false/*is mv refresh*/), - row_scanned, - row_inserted))) { + physical_row_count_, + row_inserted, + percent))) { LOG_WARN("failed to print", K(ret)); } break; diff --git a/src/rootserver/ddl_task/ob_column_redefinition_task.h b/src/rootserver/ddl_task/ob_column_redefinition_task.h index 13f7abc2e..d389f42ff 100644 --- a/src/rootserver/ddl_task/ob_column_redefinition_task.h +++ b/src/rootserver/ddl_task/ob_column_redefinition_task.h @@ -46,6 +46,7 @@ public: virtual int process() override; virtual int update_complete_sstable_job_status( const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, diff --git a/src/rootserver/ddl_task/ob_constraint_task.cpp b/src/rootserver/ddl_task/ob_constraint_task.cpp index 365149222..9490f23c9 100755 --- a/src/rootserver/ddl_task/ob_constraint_task.cpp +++ b/src/rootserver/ddl_task/ob_constraint_task.cpp @@ -57,6 +57,7 @@ int ObCheckConstraintValidationTask::process() const ObDatabaseSchema *database_schema = nullptr; int tmp_ret = OB_SUCCESS; ObTabletID unused_tablet_id; + ObAddr unused_addr; ObDDLTaskKey task_key(tenant_id_, target_object_id_, schema_version_); if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(tenant_id_, schema_guard))) { LOG_WARN("get tenant schema guard failed", K(ret), K(tenant_id_)); @@ -160,7 +161,7 @@ int ObCheckConstraintValidationTask::process() } } ObDDLTaskInfo info; - if (OB_SUCCESS != (tmp_ret = root_service->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, 1L/*unused snapshot version*/, 1L/*unused execution id*/, ret, info))) { + if (OB_SUCCESS != (tmp_ret = root_service->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, unused_addr, task_key, 1L/*unused snapshot version*/, 1L/*unused execution id*/, ret, info))) { LOG_WARN("fail to finish check constraint task", K(ret), K(tmp_ret)); } char table_id_buffer[256]; @@ -215,13 +216,14 @@ int ObForeignKeyConstraintValidationTask::process() LOG_WARN("ddl sim failure", K(ret), K(tenant_id_), K(task_id_)); } else { ObTabletID unused_tablet_id; + ObAddr unused_addr; ObDDLTaskKey task_key(tenant_id_, foregin_key_id_, schema_version_); ObDDLTaskInfo info; int tmp_ret = OB_SUCCESS; if (OB_FAIL(check_fk_by_send_sql())) { LOG_WARN("failed to check fk", K(ret)); } - if (OB_SUCCESS != (tmp_ret = root_service->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, 1L/*unused snapshot version*/, 1L/*unused execution id*/, ret, info))) { + if (OB_SUCCESS != (tmp_ret = root_service->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, unused_addr, task_key, 1L/*unused snapshot version*/, 1L/*unused execution id*/, ret, info))) { LOG_WARN("fail to finish check constraint task", K(ret)); } LOG_INFO("execute check foreign key task finish", K(ret), "ddl_event_info", ObDDLEventInfo(), K(task_key), K(data_table_id_), K(foregin_key_id_)); diff --git a/src/rootserver/ddl_task/ob_constraint_task.h b/src/rootserver/ddl_task/ob_constraint_task.h index 5d431b4e9..0a0e5c361 100644 --- a/src/rootserver/ddl_task/ob_constraint_task.h +++ b/src/rootserver/ddl_task/ob_constraint_task.h @@ -108,7 +108,6 @@ public: virtual int serialize_params_to_message(char *buf, const int64_t buf_size, int64_t &pos) const override; virtual int deserialize_params_from_message(const uint64_t tenant_id, const char *buf, const int64_t buf_size, int64_t &pos) override; virtual int64_t get_serialize_param_size() const override; - virtual int cleanup_impl() override; private: int hold_snapshot(const int64_t snapshot_version); int release_snapshot(const int64_t snapshot_version); @@ -116,6 +115,7 @@ private: int validate_constraint_valid(); int fail(); int succ(); + virtual int cleanup_impl() override; int send_check_constraint_request(); int send_fk_constraint_request(); int set_foreign_key_constraint_validated(); diff --git a/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp b/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp index 746f8b3fd..05a3eb03c 100644 --- a/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_ddl_redefinition_task.cpp @@ -26,6 +26,7 @@ #include "storage/tablelock/ob_table_lock_rpc_client.h" #include "share/scn.h" #include "pl/sys_package/ob_dbms_stats.h" +#include "storage/ob_partition_pre_split.h" using namespace oceanbase::lib; using namespace oceanbase::common; @@ -94,6 +95,7 @@ int ObDDLRedefinitionSSTableBuildTask::process() int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; ObTabletID unused_tablet_id; + ObAddr unused_addr; ObTraceIdGuard trace_id_guard(trace_id_); ObSqlString sql_string; ObSchemaGetterGuard schema_guard; @@ -216,7 +218,7 @@ int ObDDLRedefinitionSSTableBuildTask::process() } } } - if (OB_SUCCESS != (tmp_ret = root_service_->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, task_key, snapshot_version_, execution_id_, ret, info))) { + if (OB_SUCCESS != (tmp_ret = root_service_->get_ddl_scheduler().on_sstable_complement_job_reply(unused_tablet_id, unused_addr, task_key, snapshot_version_, execution_id_, ret, info))) { LOG_WARN("fail to finish sstable complement", K(ret), "ddl_event_info", ObDDLEventInfo()); } add_event_info(ret, "ddl redefinition sstable build task finish"); @@ -545,31 +547,48 @@ int ObDDLRedefinitionTask::send_build_single_replica_request() ret = OB_NOT_INIT; LOG_WARN("ObColumnRedefinitionTask has not been inited", K(ret)); } else { - ObDDLSingleReplicaExecutorParam param; - param.tenant_id_ = tenant_id_; - param.dest_tenant_id_ = dst_tenant_id_; - param.type_ = task_type_; - param.source_table_id_ = object_id_; - param.dest_table_id_ = target_object_id_; - param.schema_version_ = schema_version_; - param.dest_schema_version_ = dst_schema_version_; - param.snapshot_version_ = snapshot_version_; - param.task_id_ = task_id_; - param.parallelism_ = std::max(alter_table_arg_.parallelism_, 1L); - param.execution_id_ = execution_id_; - param.data_format_version_ = data_format_version_; - param.consumer_group_id_ = alter_table_arg_.consumer_group_id_; - if (OB_FAIL(ObDDLUtil::get_tablets(tenant_id_, object_id_, param.source_tablet_ids_))) { - LOG_WARN("fail to get tablets", K(ret), K(tenant_id_), K(object_id_)); - } else if (OB_FAIL(ObDDLUtil::get_tablets(dst_tenant_id_, target_object_id_, param.dest_tablet_ids_))) { - LOG_WARN("fail to get tablets", K(ret), K(tenant_id_), K(target_object_id_)); - } else if (OB_FAIL(replica_builder_.build(param))) { - LOG_WARN("fail to send build single replica", K(ret)); - } else { - LOG_INFO("start to build single replica", K(target_object_id_)); - is_sstable_complete_task_submitted_ = true; - sstable_complete_request_time_ = ObTimeUtility::current_time(); - } + SMART_VAR(ObDDLReplicaBuildExecutorParam, param) { + param.tenant_id_ = tenant_id_; + param.dest_tenant_id_ = dst_tenant_id_; + param.ddl_type_ = task_type_; + param.snapshot_version_ = snapshot_version_; + param.task_id_ = task_id_; + param.parallelism_ = std::max(alter_table_arg_.parallelism_, 1L); + param.execution_id_ = execution_id_; + param.data_format_version_ = data_format_version_; + param.consumer_group_id_ = alter_table_arg_.consumer_group_id_; + if (OB_FAIL(ObDDLUtil::get_tablets(tenant_id_, object_id_, param.source_tablet_ids_))) { + LOG_WARN("fail to get tablets", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_FAIL(ObDDLUtil::get_tablets(dst_tenant_id_, target_object_id_, param.dest_tablet_ids_))) { + LOG_WARN("fail to get tablets", K(ret), K(dst_tenant_id_), K(target_object_id_)); + } + const int64_t src_tablet_cnt = param.source_tablet_ids_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < src_tablet_cnt; ++i) { + if (OB_FAIL(param.source_table_ids_.push_back(object_id_))) { + LOG_WARN("failed to push back src table id", K(ret)); + } else if (OB_FAIL(param.source_schema_versions_.push_back(schema_version_))) { + LOG_WARN("failed to push back src schema version", K(ret)); + } + } + const int64_t dest_tablet_cnt = param.dest_tablet_ids_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < dest_tablet_cnt; ++i) { + if (OB_FAIL(param.dest_table_ids_.push_back(target_object_id_))) { + LOG_WARN("failed to push back dest table id", K(ret)); + } else if (OB_FAIL(param.dest_schema_versions_.push_back(dst_schema_version_))) { + LOG_WARN("failed to push back dest schema version", K(ret)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(replica_builder_.build(param))) { + LOG_WARN("fail to send build single replica", K(ret)); + } else { + TCWLockGuard guard(lock_); + is_sstable_complete_task_submitted_ = true; + sstable_complete_request_time_ = ObTimeUtility::current_time(); + LOG_INFO("start to build single replica", K(target_object_id_)); + } + } + } // smart_var } return ret; } @@ -586,6 +605,7 @@ int ObDDLRedefinitionTask::check_build_single_replica(bool &is_end) LOG_WARN("fail to check build end", K(ret)); } else if (!is_end) { if (sstable_complete_request_time_ + ObDDLUtil::calc_inner_sql_execute_timeout() < ObTimeUtility::current_time()) { // timeout, retry + TCWLockGuard guard(lock_); is_sstable_complete_task_submitted_ = false; sstable_complete_request_time_ = 0; } @@ -1203,7 +1223,11 @@ int ObDDLRedefinitionTask::finish() ObSArray objs; int64_t rpc_timeout = 0; int64_t all_orig_index_tablet_count = 0; - alter_table_arg_.ddl_task_type_ = share::CLEANUP_GARBAGE_TASK; + if (ObDDLType::DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION == task_type_) { + alter_table_arg_.ddl_task_type_ = share::PARTITION_SPLIT_RECOVERY_CLEANUP_GARBAGE_TASK; + } else { + alter_table_arg_.ddl_task_type_ = share::CLEANUP_GARBAGE_TASK; + } alter_table_arg_.table_id_ = object_id_; alter_table_arg_.hidden_table_id_ = target_object_id_; alter_table_arg_.task_id_ = task_id_; @@ -2293,6 +2317,55 @@ int ObDDLRedefinitionTask::check_need_check_table_empty(bool &need_check_table_e return ret; } +int ObDDLRedefinitionTask::generate_rebuild_index_arg_list( + const int64_t tenant_id, + const int64_t table_id, + ObSchemaGetterGuard &schema_guard, + obrpc::ObAlterTableArg &alter_table_arg) +{ + int ret = OB_SUCCESS; + const ObTableSchema *table_schema = nullptr; + ObRootService *root_service = GCTX.root_service_; + if (tenant_id == OB_INVALID_TENANT_ID || table_id == OB_INVALID_ID) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(tenant_id), K(table_id)); + } else if (OB_ISNULL(root_service)) { + ret = OB_ERR_SYS; + LOG_WARN("error sys, root service must not be nullptr", K(ret)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_id, table_schema))) { + LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(table_id)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, table schema must not be nullptr", K(ret), K(table_id)); + } else { + const common::ObIArray &index_infos = table_schema->get_simple_index_infos(); + if (index_infos.count() > 0) { + AlterTableSchema &alter_table_schema = const_cast(alter_table_arg.alter_table_schema_); + const ObString database_name = alter_table_schema.get_origin_database_name(); + ObPartitionPreSplit pre_split(root_service->get_ddl_service()); + for (int64_t i = 0; OB_SUCC(ret) && i < index_infos.count(); ++i) { + const ObTableSchema *index_schema = nullptr; + ObTableSchema new_index_schema; + const int64_t index_id = index_infos.at(i).table_id_; + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, index_id, index_schema))) { + LOG_WARN("fail to get index table schema", K(ret), K(tenant_id), K(index_id)); + } else if (OB_ISNULL(index_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected schema nullptr", K(ret), KP(index_schema)); + } else if (!index_schema->is_global_index_table()) { // skip + } else if (OB_FAIL(new_index_schema.assign(*index_schema))) { + LOG_WARN("fail to assign schema", K(ret)); + } else if (OB_FAIL(pre_split.do_table_pre_split_if_need(database_name, ObDDLType::DDL_CREATE_INDEX, false, *table_schema, *index_schema, new_index_schema))) { + LOG_WARN("fail to pre split index partition", K(ret), K(index_id)); + } else if (OB_FAIL(alter_table_arg.rebuild_index_arg_list_.push_back(new_index_schema))) { + LOG_WARN("fail to push back index schema", K(ret)); + } + } + } + } + return ret; +} + int ObDDLRedefinitionTask::get_child_task_ids(char *buf, int64_t len) { int ret = OB_SUCCESS; @@ -2666,7 +2739,8 @@ int ObDDLRedefinitionTask::reap_old_replica_build_task(bool &need_exec_new_inner LOG_WARN("failed to check and wait old complement task", K(ret)); } } else if (!need_exec_new_inner_sql) { - if (OB_FAIL(update_complete_sstable_job_status(unused_tablet_id, snapshot_version_, old_execution_id, old_ret_code, unused_addition_info))) { + ObAddr unused_addr; + if (OB_FAIL(update_complete_sstable_job_status(unused_tablet_id, unused_addr, snapshot_version_, old_execution_id, old_ret_code, unused_addition_info))) { LOG_WARN("failed to wait and complete old task finished!", K(ret)); } } diff --git a/src/rootserver/ddl_task/ob_ddl_redefinition_task.h b/src/rootserver/ddl_task/ob_ddl_redefinition_task.h index ce517a62a..4cd669b07 100644 --- a/src/rootserver/ddl_task/ob_ddl_redefinition_task.h +++ b/src/rootserver/ddl_task/ob_ddl_redefinition_task.h @@ -140,6 +140,7 @@ public: virtual int process() = 0; virtual int update_complete_sstable_job_status( const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, @@ -148,7 +149,6 @@ public: const uint64_t child_task_key, const int ret_code) override; int notify_update_autoinc_finish(const uint64_t autoinc_val, const int ret_code); - virtual int cleanup_impl() override; int reap_old_replica_build_task(bool &need_exec_new_inner_sql); INHERIT_TO_STRING_KV("ObDDLTask", ObDDLTask, K(wait_trans_ctx_), K(sync_tablet_autoinc_seq_ctx_), K(build_replica_request_time_), @@ -258,7 +258,14 @@ protected: int get_child_task_ids(char *buf, int64_t len); int get_estimated_timeout(const share::schema::ObTableSchema *dst_table_schema, int64_t &estimated_timeout); int get_orig_all_index_tablet_count(ObSchemaGetterGuard &schema_guard, int64_t &all_tablet_count); + + int generate_rebuild_index_arg_list(const int64_t tenant_id, + const int64_t table_id, + ObSchemaGetterGuard &schema_guard, + obrpc::ObAlterTableArg &alter_table_arg); int64_t get_build_replica_request_time(); +private: + virtual int cleanup_impl() override; protected: static const int64_t MAP_BUCKET_NUM = 1024; struct DependTaskStatus final @@ -291,7 +298,7 @@ protected: int64_t check_table_empty_job_time_; bool is_sstable_complete_task_submitted_; int64_t sstable_complete_request_time_; - ObDDLSingleReplicaExecutor replica_builder_; + ObDDLReplicaBuildExecutor replica_builder_; common::hash::ObHashMap check_dag_exit_tablets_map_; // for dag complement data ddl only. int64_t check_dag_exit_retry_cnt_; }; diff --git a/src/rootserver/ddl_task/ob_ddl_retry_task.h b/src/rootserver/ddl_task/ob_ddl_retry_task.h index 922746c4a..e8a8af891 100644 --- a/src/rootserver/ddl_task/ob_ddl_retry_task.h +++ b/src/rootserver/ddl_task/ob_ddl_retry_task.h @@ -47,7 +47,6 @@ public: common::ObMySQLTransaction &trans, const uint64_t tenant_id, const int64_t task_id); - virtual int cleanup_impl() override; private: int check_health(); int prepare(const share::ObDDLTaskStatus next_task_status); @@ -55,6 +54,7 @@ private: int wait_alter_table(const share::ObDDLTaskStatus next_task_status); int succ(); int fail(); + virtual int cleanup_impl() override; int deep_copy_ddl_arg(common::ObIAllocator &allocator, const share::ObDDLType &ddl_type, const obrpc::ObDDLArg *source_arg); int init_compat_mode(const share::ObDDLType &ddl_type, const obrpc::ObDDLArg *source_arg); int get_forward_user_message(const obrpc::ObRpcResultCode &rcode); diff --git a/src/rootserver/ddl_task/ob_ddl_scheduler.cpp b/src/rootserver/ddl_task/ob_ddl_scheduler.cpp index 965f27691..920f81f36 100755 --- a/src/rootserver/ddl_task/ob_ddl_scheduler.cpp +++ b/src/rootserver/ddl_task/ob_ddl_scheduler.cpp @@ -40,6 +40,7 @@ #include "share/scheduler/ob_sys_task_stat.h" #include "share/ob_ddl_sim_point.h" #include "share/restore/ob_import_util.h" +#include "share/scheduler/ob_partition_auto_split_helper.h" namespace oceanbase { @@ -359,10 +360,12 @@ int ObDDLTaskQueue::update_task_ret_code(const ObDDLTaskID &task_id, const int r LOG_WARN("ddl_task is null", K(ret)); } else { const ObTabletID unused_tablet_id; + const ObAddr unused_addr; const int64_t unused_snapshot_version = 0; const int64_t unused_execution_id = 0; const ObDDLTaskInfo unused_task_info; - ret = table_redefinition_task->update_complete_sstable_job_status(unused_tablet_id, unused_snapshot_version, + ret = table_redefinition_task->update_complete_sstable_job_status( + unused_tablet_id, unused_addr, unused_snapshot_version, unused_execution_id, ret_code, unused_task_info); } return ret; @@ -665,10 +668,12 @@ int ObUpdateSSTableCompleteStatusCallback::update_redef_task_info(ObTableRedefin { int ret = OB_SUCCESS; const ObTabletID unused_tablet_id; + const ObAddr unused_addr; const int64_t unused_snapshot_version = 0; const int64_t unused_execution_id = 0; const ObDDLTaskInfo unused_task_info; - ret = redef_task.update_complete_sstable_job_status(unused_tablet_id, unused_snapshot_version, + ret = redef_task.update_complete_sstable_job_status( + unused_tablet_id, unused_addr, unused_snapshot_version, unused_execution_id, ret_code_, unused_task_info); return ret; } @@ -976,6 +981,7 @@ int ObDDLScheduler::create_ddl_task(const ObCreateDDLTaskParam ¶m, const obrpc::ObAlterTableArg *alter_table_arg = nullptr; const obrpc::ObCreateIndexArg *create_index_arg = nullptr; const obrpc::ObDropIndexArg *drop_index_arg = nullptr; + const obrpc::ObPartitionSplitArg *partition_split_arg = nullptr; const obrpc::ObRebuildIndexArg *rebuild_index_arg = nullptr; const obrpc::ObMViewCompleteRefreshArg *mview_complete_refresh_arg = nullptr; ObRootService *root_service = GCTX.root_service_; @@ -1115,6 +1121,7 @@ int ObDDLScheduler::create_ddl_task(const ObCreateDDLTaskParam ¶m, case DDL_ALTER_COLUMN_GROUP: case DDL_MVIEW_COMPLETE_REFRESH: case DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION: + case DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION: if (OB_FAIL(create_table_redefinition_task(proxy, param.type_, param.src_table_schema_, @@ -1243,6 +1250,22 @@ int ObDDLScheduler::create_ddl_task(const ObCreateDDLTaskParam ¶m, LOG_WARN("fail to create modify autoinc task", K(ret)); } break; + case DDL_AUTO_SPLIT_BY_RANGE: + case DDL_AUTO_SPLIT_NON_RANGE: + case DDL_MANUAL_SPLIT_BY_RANGE: + case DDL_MANUAL_SPLIT_NON_RANGE: + partition_split_arg = static_cast(param.ddl_arg_); + if (OB_FAIL(create_partition_split_task(proxy, + param.src_table_schema_, + param.parallelism_, + param.parent_task_id_, + param.task_id_, + partition_split_arg, + *param.allocator_, + task_record))) { + LOG_WARN("fail to create partition split task", K(ret)); + } + break; case DDL_DROP_DATABASE: case DDL_DROP_TABLE: case DDL_TRUNCATE_TABLE: @@ -1361,6 +1384,109 @@ int ObDDLScheduler::prepare_alter_table_arg(const ObPrepareAlterTableArgParam &p return ret; } +int ObDDLScheduler::cache_auto_split_task(const obrpc::ObAutoSplitTabletBatchArg &arg, + obrpc::ObAutoSplitTabletBatchRes &res) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(arg)); + } else { + ObRsAutoSplitScheduler &split_task_scheduler = ObRsAutoSplitScheduler::get_instance(); + ObArray task_array; + ObAutoSplitTask task; + const ObSArray &single_arg_array = arg.args_; + res.suggested_next_valid_time_ = OB_INVALID_TIMESTAMP; + res.rets_.reuse(); + for (int64_t i = 0; OB_SUCC(ret) && i < single_arg_array.size(); ++i) { + const obrpc::ObAutoSplitTabletArg &single_arg = single_arg_array.at(i); + task.reset(); + task.auto_split_tablet_size_ = single_arg.auto_split_tablet_size_; + task.ls_id_ = single_arg.ls_id_; + task.tablet_id_ = single_arg.tablet_id_; + task.tenant_id_ = single_arg.tenant_id_; + task.used_disk_space_ = single_arg.used_disk_space_; + task.retry_times_ = 0; + if (OB_FAIL(task_array.push_back(task))) { + LOG_WARN("fail to push back task", K(ret) ,K(task), K(task_array)); + } else if (OB_FAIL(res.rets_.push_back(OB_SUCCESS))) { + LOG_WARN("fail to push back ret", K(ret)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(split_task_scheduler.push_tasks(task_array))) { + LOG_WARN("fail to push tasks into auto_split_task_tree_", K(ret), K(task_array)); + } else { + int64_t cur_time = ObTimeUtility::current_time(); + bool is_busy = split_task_scheduler.is_busy(); + res.suggested_next_valid_time_ = cur_time + (is_busy ? ObServerAutoSplitScheduler::OB_SERVER_DELAYED_TIME : 0); + } + } + } + return ret; +} + +int ObDDLScheduler::schedule_auto_split_task() +{ + int ret = OB_SUCCESS; + ObRsAutoSplitScheduler &split_task_scheduler = ObRsAutoSplitScheduler::get_instance(); + ObArray task_array; + if (OB_FAIL(split_task_scheduler.pop_tasks(task_array))) { + LOG_WARN("fail to pop tasks from auto_split_task_tree"); + } else if (task_array.count() == 0) { + //do nothing + } else { + ObAutoSplitArgBuilder split_helper; + ObArray failed_task; + obrpc::ObAlterTableRes unused_res; + common::ObMalloc allocator(common::ObMemAttr(OB_SERVER_TENANT_ID, "split_sched")); + for (int64_t i = 0; OB_SUCC(ret) && i < task_array.count(); ++i) { + int tmp_ret = OB_SUCCESS; + unused_res.reset(); + ObAutoSplitTask &task = task_array.at(i); + void *buf = nullptr; + obrpc::ObAlterTableArg *single_arg = nullptr; + bool is_ls_migrating = false; + if (OB_FAIL(ObRsAutoSplitScheduler::check_ls_migrating(task.tenant_id_, task.tablet_id_, is_ls_migrating))) { + LOG_WARN("check ls migrating failed", K(ret), K(task)); + } else if (is_ls_migrating) { + LOG_TRACE("ls migrating, delay auto split", K(task)); + } else if (OB_ISNULL(buf = allocator.alloc(sizeof(obrpc::ObAlterTableArg)))) { + //ignore ret + tmp_ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(tmp_ret), K(task)); + } else if (FALSE_IT(single_arg = new (buf) obrpc::ObAlterTableArg())) { + } else if (OB_TMP_FAIL(split_helper.build_arg(task.tenant_id_, task.ls_id_, task.tablet_id_, + task.auto_split_tablet_size_, task.used_disk_space_, *single_arg))) { + LOG_WARN("fail to build arg", K(tmp_ret), K(task)); + } else if (!single_arg->is_auto_split_partition()) { + //do nothing + } else if (single_arg->alter_table_schema_.is_global_index_table() + && OB_TMP_FAIL(root_service_->get_common_rpc_proxy().to(GCTX.self_addr()).timeout(GCONF._ob_ddl_timeout).split_global_index_tablet(*single_arg))) { + LOG_WARN("split global index failed", K(tmp_ret), K(single_arg)); + } else if (!single_arg->alter_table_schema_.is_global_index_table() + && OB_TMP_FAIL(root_service_->get_common_rpc_proxy().to(GCTX.self_addr()).timeout(GCONF._ob_ddl_timeout).alter_table(*single_arg, unused_res))) { + LOG_WARN("alter table failed", K(tmp_ret), K(single_arg), K(unused_res)); + } + if (OB_TMP_FAIL(tmp_ret) && split_task_scheduler.can_retry(task, tmp_ret)) { + failed_task.reuse(); + task.increment_retry_times(); + if (OB_TMP_FAIL(failed_task.push_back(task))) { + LOG_WARN("fail to push back into failed task", K(tmp_ret), K(task)); + } else if (OB_TMP_FAIL(split_task_scheduler.push_tasks(failed_task))) { + LOG_WARN("fail to push tasks", K(tmp_ret), K(failed_task)); + } + } + if (OB_NOT_NULL(single_arg)) { + single_arg->~ObAlterTableArg(); + allocator.free(single_arg); + single_arg = nullptr; + } + } + } + return ret; +} + int ObDDLScheduler::get_task_record(const ObDDLTaskID &task_id, ObISQLClient &trans, ObDDLTaskRecord &task_record, @@ -2021,7 +2147,7 @@ int ObDDLScheduler::create_constraint_task( } else if (OB_UNLIKELY(nullptr == table_schema || OB_INVALID_ID == constraint_id || schema_version <= 0 || nullptr == arg || !arg->is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(table_schema), K(constraint_id), K(schema_version), K(arg)); + LOG_WARN("invalid argument", K(ret), KPC(table_schema), K(constraint_id), K(schema_version), K(arg)); } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service_->get_sql_proxy(), table_schema->get_tenant_id(), task_id))) { LOG_WARN("fetch new task id failed", K(ret)); } else if (OB_FAIL(constraint_task.init(task_id, table_schema, constraint_id, ddl_type, schema_version, *arg, consumer_group_id, sub_task_trace_id, parent_task_id))) { @@ -2246,6 +2372,44 @@ int ObDDLScheduler::create_ddl_retry_task( return ret; } +int ObDDLScheduler::create_partition_split_task( + common::ObISQLClient &proxy, + const share::schema::ObTableSchema *table_schema, + const int64_t parallelism, + const int64_t parent_task_id, + const int64_t task_id, + const obrpc::ObPartitionSplitArg *partition_split_arg, + ObIAllocator &allocator, + ObDDLTaskRecord &task_record) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObPartitionSplitTask, split_task) { + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(partition_split_arg) || OB_ISNULL(table_schema) || OB_UNLIKELY(0 == task_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(task_id), KPC(partition_split_arg), KPC(table_schema)); + } else if (OB_FAIL(split_task.init(table_schema->get_tenant_id(), + task_id, + table_schema->get_table_id(), + table_schema->get_schema_version(), + parallelism, + *partition_split_arg, + table_schema->get_tablet_size(), + parent_task_id))) { + LOG_WARN("init global index task failed", K(ret), KPC(table_schema)); + } else if (OB_FAIL(split_task.set_trace_id(*ObCurTraceId::get_trace_id()))) { + LOG_WARN("set trace id failed", K(ret)); + } else if (OB_FAIL(insert_task_record(proxy, split_task, allocator, task_record))) { + LOG_WARN("fail to insert task record", K(ret)); + } + + LOG_INFO("ddl_scheduler create partition split task finished", K(ret), K(split_task)); + } + return ret; +} + int ObDDLScheduler::create_recover_restore_table_task( common::ObISQLClient &proxy, const share::ObDDLType &type, @@ -2340,6 +2504,7 @@ int ObDDLScheduler::recover_task() ret = OB_NOT_INIT; LOG_WARN("not init", K(ret)); } else { + schedule_auto_split_task(); //ignore schedule auto split task error ObSqlString sql_string; ObArray task_records; ObArray primary_tenant_ids; @@ -2498,6 +2663,7 @@ int ObDDLScheduler::schedule_ddl_task(const ObDDLTaskRecord &record) case DDL_ALTER_COLUMN_GROUP: case DDL_MVIEW_COMPLETE_REFRESH: case DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION: + case DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION: ret = schedule_table_redefinition_task(record); break; case DDL_CREATE_MVIEW: @@ -2527,6 +2693,14 @@ int ObDDLScheduler::schedule_ddl_task(const ObDDLTaskRecord &record) case DDL_TRUNCATE_SUB_PARTITION: ret = schedule_ddl_retry_task(record); break; + case DDL_AUTO_SPLIT_BY_RANGE: + case DDL_AUTO_SPLIT_NON_RANGE: + case DDL_MANUAL_SPLIT_BY_RANGE: + case DDL_MANUAL_SPLIT_NON_RANGE: + if (OB_FAIL(schedule_partition_split_task(record))) { + LOG_WARN("schedule partition split task failed", K(ret)); + } + break; case DDL_TABLE_RESTORE: ret = schedule_recover_restore_table_task(record); break; @@ -2805,6 +2979,40 @@ int ObDDLScheduler::schedule_ddl_retry_task(const ObDDLTaskRecord &task_record) return ret; } +int ObDDLScheduler::schedule_partition_split_task( + const ObDDLTaskRecord &task_record) +{ + int ret = OB_SUCCESS; + ObPartitionSplitTask *split_task = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(alloc_ddl_task(split_task))) { + LOG_WARN("alloc ddl task failed", K(ret)); + } else { + if (OB_FAIL(split_task->init(task_record))) { + LOG_WARN("init partition split task failed", K(ret), K(task_record)); + } else if (OB_FAIL(split_task->set_trace_id(task_record.trace_id_))) { + LOG_WARN("set trace id failed", K(ret)); + } else if (OB_FAIL(inner_schedule_ddl_task(split_task, task_record))) { + if (OB_ENTRY_EXIST != ret) { + LOG_WARN("inner schedule task failed", K(ret), K(*split_task)); + } + } else { + LOG_INFO("scheduler partition split task successfully", K(*split_task)); + } + } + if (OB_FAIL(ret) && nullptr != split_task) { + split_task->~ObPartitionSplitTask(); + allocator_.free(split_task); + split_task = nullptr; + } + if (OB_ENTRY_EXIST == ret) { + ret = OB_SUCCESS; + } + return ret; +} + int ObDDLScheduler::schedule_constraint_task(const ObDDLTaskRecord &task_record) { int ret = OB_SUCCESS; @@ -3222,6 +3430,7 @@ int ObDDLScheduler::on_column_checksum_calc_reply( int ObDDLScheduler::on_sstable_complement_job_reply( const common::ObTabletID &tablet_id, + const ObAddr &svr, const ObDDLTaskKey &task_key, const int64_t snapshot_version, const int64_t execution_id, @@ -3249,18 +3458,18 @@ int ObDDLScheduler::on_sstable_complement_job_reply( if (OB_FAIL(modify_redef_task(task_id, callback))) { LOG_WARN("fail to modify redef task", K(ret), K(task_id)); } - } else if (OB_FAIL(task_queue_.modify_task(task_key, [&tablet_id, &snapshot_version, &execution_id, &ret_code, &addition_info](ObDDLTask &task) -> int { + } else if (OB_FAIL(task_queue_.modify_task(task_key, [&tablet_id, &svr, &snapshot_version, &execution_id, &ret_code, &addition_info](ObDDLTask &task) -> int { int ret = OB_SUCCESS; const int64_t task_type = task.get_task_type(); switch (task_type) { case ObDDLType::DDL_CREATE_INDEX: case ObDDLType::DDL_CREATE_PARTITIONED_LOCAL_INDEX: - if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { + if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, svr, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status failed", K(ret)); } break; case ObDDLType::DDL_DROP_PRIMARY_KEY: - if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { + if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, svr, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status", K(ret)); } break; @@ -3273,12 +3482,13 @@ int ObDDLScheduler::on_sstable_complement_job_reply( case ObDDLType::DDL_ALTER_COLUMN_GROUP: case ObDDLType::DDL_MVIEW_COMPLETE_REFRESH: case ObDDLType::DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION: - if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { + case ObDDLType::DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION: + if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, svr, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status", K(ret)); } break; case ObDDLType::DDL_TABLE_RESTORE: - if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { + if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, svr, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status", K(ret)); } break; @@ -3292,12 +3502,24 @@ int ObDDLScheduler::on_sstable_complement_job_reply( case ObDDLType::DDL_DROP_COLUMN: case ObDDLType::DDL_ADD_COLUMN_OFFLINE: case ObDDLType::DDL_COLUMN_REDEFINITION: - if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { + if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, svr, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status", K(ret), K(tablet_id), K(snapshot_version), K(ret_code)); } break; + case DDL_AUTO_SPLIT_BY_RANGE: + case DDL_AUTO_SPLIT_NON_RANGE: + case DDL_MANUAL_SPLIT_BY_RANGE: + case DDL_MANUAL_SPLIT_NON_RANGE: + if (OB_FAIL(static_cast(&task)->update_complete_sstable_job_status(tablet_id, + svr, + execution_id, + ret_code, + addition_info))) { + LOG_WARN("update partition split task tastus", K(ret)); + } + break; case ObDDLType::DDL_DROP_VEC_INDEX: - if (OB_FAIL(static_cast(&task)->update_drop_lob_meta_row_job_status(tablet_id, snapshot_version, execution_id, ret_code, addition_info))) { + if (OB_FAIL(static_cast(&task)->update_drop_lob_meta_row_job_status(tablet_id, svr, snapshot_version, execution_id, ret_code, addition_info))) { LOG_WARN("update complete sstable job status", K(ret), K(tablet_id), K(snapshot_version), K(ret_code)); } break; diff --git a/src/rootserver/ddl_task/ob_ddl_scheduler.h b/src/rootserver/ddl_task/ob_ddl_scheduler.h index 24897fe45..77baa14aa 100755 --- a/src/rootserver/ddl_task/ob_ddl_scheduler.h +++ b/src/rootserver/ddl_task/ob_ddl_scheduler.h @@ -24,6 +24,7 @@ #include "rootserver/ddl_task/ob_index_build_task.h" #include "rootserver/ddl_task/ob_modify_autoinc_task.h" #include "rootserver/ddl_task/ob_table_redefinition_task.h" +#include "rootserver/ddl_task//ob_partition_split_task.h" #include "rootserver/ob_thread_idling.h" #include "lib/hash/ob_hashmap.h" #include "lib/profile/ob_trace_id.h" @@ -260,6 +261,7 @@ public: int on_sstable_complement_job_reply( const common::ObTabletID &tablet_id, + const ObAddr &svr, const ObDDLTaskKey &task_key, const int64_t snapshot_version, const int64_t execution_id, @@ -300,6 +302,9 @@ public: int prepare_alter_table_arg(const ObPrepareAlterTableArgParam ¶m, const ObTableSchema *target_table_schema, obrpc::ObAlterTableArg &alter_table_arg); + int cache_auto_split_task(const obrpc::ObAutoSplitTabletBatchArg &arg, + obrpc::ObAutoSplitTabletBatchRes &res); + int schedule_auto_split_task(); private: class DDLIdling : public ObThreadIdling { @@ -530,6 +535,16 @@ private: ObIAllocator &allocator, ObDDLTaskRecord &task_record); +int create_partition_split_task( + common::ObISQLClient &proxy, + const share::schema::ObTableSchema *table_schema, + const int64_t parallelism, + const int64_t parent_task_id, + const int64_t task_id, + const obrpc::ObPartitionSplitArg *partition_split_arg, + ObIAllocator &allocator, + ObDDLTaskRecord &task_record); + int create_recover_restore_table_task( common::ObISQLClient &proxy, const share::ObDDLType &type, @@ -561,6 +576,7 @@ private: int schedule_rebuild_index_task(const ObDDLTaskRecord &task_record); int schedule_drop_fts_index_task(const ObDDLTaskRecord &task_record); int schedule_ddl_retry_task(const ObDDLTaskRecord &task_record); + int schedule_partition_split_task(const ObDDLTaskRecord &task_record); int schedule_recover_restore_table_task(const ObDDLTaskRecord &task_record); int add_sys_task(ObDDLTask *task); int remove_sys_task(ObDDLTask *task); diff --git a/src/rootserver/ddl_task/ob_ddl_single_replica_executor.cpp b/src/rootserver/ddl_task/ob_ddl_single_replica_executor.cpp index 1a93e8c85..a8cbf9cad 100644 --- a/src/rootserver/ddl_task/ob_ddl_single_replica_executor.cpp +++ b/src/rootserver/ddl_task/ob_ddl_single_replica_executor.cpp @@ -25,7 +25,125 @@ using namespace oceanbase::common; using namespace oceanbase::rootserver; using namespace oceanbase::storage; -int ObDDLSingleReplicaExecutor::build(const ObDDLSingleReplicaExecutorParam ¶m) +int ObSingleReplicaBuildCtx::init( + const ObAddr& addr, + const share::ObDDLType ddl_type, + const int64_t src_table_id, + const int64_t dest_table_id, + const int64_t src_schema_version, + const int64_t dest_schema_version, + const int64_t tablet_task_id, + const int64_t compaction_scn, + const ObTabletID &src_tablet_id, + const ObTabletID &dest_tablet_id, + const bool can_reuse_macro_block, + const ObIArray ¶llel_datum_rowkey_list) +{ + int ret = OB_SUCCESS; + if (is_inited_) { + ret = OB_INIT_TWICE; + LOG_WARN("already inited", K(ret)); + } else if (!addr.is_valid() || + src_table_id == OB_INVALID_ID || + dest_table_id == OB_INVALID_ID || + tablet_task_id == 0 || + !src_tablet_id.is_valid() || + !dest_tablet_id.is_valid() || + (is_tablet_split(ddl_type) && (compaction_scn == 0 || parallel_datum_rowkey_list.empty()))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(addr), K(src_table_id), K(dest_table_id), + K(tablet_task_id), K(src_tablet_id), K(dest_tablet_id), + K(ddl_type), K(compaction_scn), K(parallel_datum_rowkey_list)); + } else if (OB_FAIL(parallel_datum_rowkey_list_.assign(parallel_datum_rowkey_list))) { // shallow copy. + LOG_WARN("assign failed", K(ret), K(parallel_datum_rowkey_list)); + } else { + addr_ = addr; + ddl_type_ = ddl_type; + src_table_id_ = src_table_id; + dest_table_id_ = dest_table_id; + src_schema_version_ = src_schema_version; + dest_schema_version_ = dest_schema_version; + tablet_task_id_ = tablet_task_id; + compaction_scn_ = compaction_scn; + src_tablet_id_ = src_tablet_id; + dest_tablet_id_ = dest_tablet_id; + can_reuse_macro_block_ = can_reuse_macro_block; + reset_build_stat(); + is_inited_ = true; + } + return ret; +} + +void ObSingleReplicaBuildCtx::reset_build_stat() +{ + stat_ = ObReplicaBuildStat::BUILD_INIT; + ret_code_ = OB_SUCCESS; + heart_beat_time_ = 0; + row_inserted_ = 0; + row_scanned_ = 0; + physical_row_count_ = 0; +} + +bool ObSingleReplicaBuildCtx::is_valid() const +{ + bool valid = is_inited_ && addr_.is_valid() && src_table_id_ != OB_INVALID_ID && + dest_table_id_ != OB_INVALID_ID && src_schema_version_ != 0 && + dest_schema_version_ != 0 && tablet_task_id_ != 0 && + src_tablet_id_.is_valid() && dest_tablet_id_.is_valid(); + if (is_tablet_split(ddl_type_)) { + valid &= (compaction_scn_ != 0 && !parallel_datum_rowkey_list_.empty()); + } + return valid; +} + +int ObSingleReplicaBuildCtx::assign(const ObSingleReplicaBuildCtx &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(parallel_datum_rowkey_list_.assign(other.parallel_datum_rowkey_list_))) { + LOG_WARN("assign failed", K(ret)); + } else { + is_inited_ = other.is_inited_; + addr_ = other.addr_; + ddl_type_ = other.ddl_type_; + src_table_id_ = other.src_table_id_; + dest_table_id_ = other.dest_table_id_; + src_schema_version_ = other.src_schema_version_; + dest_schema_version_ = other.dest_schema_version_; + tablet_task_id_ = other.tablet_task_id_; + compaction_scn_ = other.compaction_scn_; + src_tablet_id_ = other.src_tablet_id_; + can_reuse_macro_block_ = other.can_reuse_macro_block_; + stat_ = other.stat_; + ret_code_ = other.ret_code_; + heart_beat_time_ = other.heart_beat_time_; + row_inserted_ = other.row_inserted_; + row_scanned_ = other.row_scanned_; + physical_row_count_ = other.physical_row_count_; + dest_tablet_id_ = other.dest_tablet_id_; + } + return ret; +} + +int ObSingleReplicaBuildCtx::check_need_schedule(bool &need_schedule) const +{ + int ret = OB_SUCCESS; + need_schedule = false; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret)); + } else { + const int64_t elapsed_time = ObTimeUtility::current_time() - heart_beat_time_; + const bool timeout = (elapsed_time > REPLICA_BUILD_HEART_BEAT_TIME); + if (stat_ == ObReplicaBuildStat::BUILD_INIT || + stat_ == ObReplicaBuildStat::BUILD_RETRY || + (stat_ == ObReplicaBuildStat::BUILD_REQUESTED && timeout)) { + need_schedule = true; + } + } + return ret; +} + +int ObDDLReplicaBuildExecutor::build(const ObDDLReplicaBuildExecutorParam ¶m) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!param.is_valid())) { @@ -33,212 +151,549 @@ int ObDDLSingleReplicaExecutor::build(const ObDDLSingleReplicaExecutorParam &par LOG_WARN("invalid arguments", K(ret), K(param)); } else if (OB_FAIL(DDL_SIM(param.tenant_id_, param.task_id_, SINGLE_REPLICA_EXECUTOR_BUILD_FAILED))) { LOG_WARN("ddl sim failure", K(ret), K(param.tenant_id_), K(param.task_id_)); - } else { + } else { // lock scope, keep construct_replica_build_ctxs() out of scope ObSpinLockGuard guard(lock_); tenant_id_ = param.tenant_id_; dest_tenant_id_ = param.dest_tenant_id_; - type_ = param.type_; - source_table_id_ = param.source_table_id_; - dest_table_id_ = param.dest_table_id_; - schema_version_ = param.schema_version_; - dest_schema_version_ = param.dest_schema_version_; + ddl_type_ = param.ddl_type_; + ddl_task_id_ = param.task_id_; snapshot_version_ = param.snapshot_version_; - task_id_ = param.task_id_; - execution_id_ = param.execution_id_; parallelism_ = param.parallelism_; + execution_id_ = param.execution_id_; data_format_version_ = param.data_format_version_; consumer_group_id_ = param.consumer_group_id_; - - common::ObIArray &build_infos = partition_build_stat_; - const common::ObIArray &tablet_ids = param.source_tablet_ids_; - if (0 == build_infos.count()) { // first time init - for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { - ObPartitionBuildInfo build_info_tmp; - build_info_tmp.stat_ = ObPartitionBuildStat::BUILD_INIT; - if (OB_FAIL(build_infos.push_back(build_info_tmp))) { - LOG_WARN("fail to push back build info", K(ret)); - } else if (OB_FAIL(tablet_task_ids_.push_back(i + 1))) { - LOG_WARN("fail to push tablet task id", K(ret)); - } - } - if (OB_FAIL(ret)) { - } else if (OB_FAIL(source_tablet_ids_.assign(param.source_tablet_ids_))) { - LOG_WARN("fail to assign tablet ids", K(ret)); - } else if (OB_FAIL(dest_tablet_ids_.assign(param.dest_tablet_ids_))) { - LOG_WARN("fail to assign tablet ids", K(ret)); - } - if (OB_FAIL(ret)) { - source_tablet_ids_.reset(); - dest_tablet_ids_.reset(); - build_infos.reset(); - tablet_task_ids_.reset(); - } - } else { // timeout, need reset task status - for (int64_t i = 0; OB_SUCC(ret) && i < build_infos.count(); ++i) { - ObPartitionBuildInfo &build_info = build_infos.at(i); - if (ObPartitionBuildStat::BUILD_REQUESTED == build_info.stat_) { - build_info.stat_ = ObPartitionBuildStat::BUILD_INIT; - } - } + ObArray replica_build_ctxs; + if (OB_FAIL(construct_replica_build_ctxs(param, replica_build_ctxs))) { + LOG_WARN("failed to construct replica build ctxs", K(ret)); + } else if (OB_FAIL(lob_col_idxs_.assign(param.lob_col_idxs_))) { + LOG_WARN("failed to assign to lob col idxs", K(ret)); + } else if (OB_FAIL(src_tablet_ids_.assign(param.source_tablet_ids_))) { + LOG_WARN("failed to assign to tablet ids", K(ret)); + } else if (OB_FAIL(dest_tablet_ids_.assign(param.dest_tablet_ids_))) { + LOG_WARN("failed to assign to dest tablet ids", K(ret)); + } else if (OB_FAIL(replica_build_ctxs_.assign(replica_build_ctxs))) { + LOG_WARN("failed to setup replica build ctxs", K(ret)); + } else { + is_inited_ = true; } - } - char table_id_buffer[256]; - snprintf(table_id_buffer, sizeof(table_id_buffer), "dest_table_id:%ld, source_table_id:%ld", dest_table_id_, source_table_id_); - ROOTSERVICE_EVENT_ADD("ddl scheduler", "build single replica", - "tenant_id",tenant_id_, - "ret", ret, - "trace_id", *ObCurTraceId::get_trace_id(), - K_(task_id), - "type", type_, - K_(schema_version), - table_id_buffer); + if (OB_FAIL(ret)) { + is_inited_ = false; + } + } // lock scope, keep schedule_task() out of lock scope + + // TODO(lihongqin.lhq) + // char table_id_buffer[256]; + // snprintf(table_id_buffer, sizeof(table_id_buffer), "dest_table_id:%ld, source_table_id:%ld", dest_table_id_, source_table_id_); + // ROOTSERVICE_EVENT_ADD("ddl scheduler", "build single replica", + // "tenant_id",tenant_id_, + // "ret", ret, + // "trace_id", *ObCurTraceId::get_trace_id(), + // K_(task_id), + // "type", type_, + // K_(schema_version), + // table_id_buffer); + if (OB_SUCC(ret)) { - LOG_INFO("start to schedule task", K(source_tablet_ids_.count()), K(dest_table_id_), "ddl_event_info", ObDDLEventInfo()); + LOG_INFO("start to schedule task", K(src_tablet_ids_.count()), "ddl_event_info", ObDDLEventInfo()); if (OB_FAIL(schedule_task())) { LOG_WARN("fail to schedule tasks", K(ret)); + } else { + LOG_INFO("start to schedule task", K(param.source_tablet_ids_)); } } else { - LOG_INFO("fail to build single replica task", K(ret), K(dest_table_id_), "ddl_event_info", ObDDLEventInfo()); + LOG_INFO("fail to build single replica task", K(ret), "ddl_event_info", ObDDLEventInfo()); } return ret; } -int ObDDLSingleReplicaExecutor::schedule_task() +int ObDDLReplicaBuildExecutor::schedule_task() { int ret = OB_SUCCESS; obrpc::ObSrvRpcProxy *rpc_proxy = GCTX.srv_rpc_proxy_; - share::ObLocationService *location_service = GCTX.location_service_; - if (OB_ISNULL(rpc_proxy) || OB_ISNULL(location_service)) { + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (OB_ISNULL(rpc_proxy)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), KP(rpc_proxy), KP(location_service)); - } else if (OB_FAIL(DDL_SIM(tenant_id_, task_id_, SINGLE_REPLICA_EXECUTOR_SCHEDULE_TASK_FAILED))) { - LOG_WARN("ddl sim failure", K(ret), K(tenant_id_), K(task_id_)); + LOG_WARN("invalid arguments", K(ret), KP(rpc_proxy)); + } else if (OB_FAIL(DDL_SIM(dest_tenant_id_, ddl_task_id_, SINGLE_REPLICA_EXECUTOR_SCHEDULE_TASK_FAILED))) { + LOG_WARN("ddl sim failure", K(ret), K(dest_tenant_id_), K(ddl_task_id_)); } else { ObDDLBuildSingleReplicaRequestProxy proxy(*rpc_proxy, &obrpc::ObSrvRpcProxy::build_ddl_single_replica_request); - common::ObIArray &build_infos = partition_build_stat_; - ObArray idxs; // to record the tablets position in build_infos that need to be scheduled. - const int64_t current_time = ObTimeUtility::current_time(); - int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); - const bool force_renew = true; - bool is_cache_hit = false; - const int64_t expire_renew_time = force_renew ? INT64_MAX : 0; - ObLSID orig_ls_id; - ObLSID dest_ls_id; - common::ObArray ret_array; - ObArray request_source_tablet_ids; - ObArray request_dest_tablet_ids; - ObArray request_tablet_task_ids; + ObArray args; + ObArray addrs; + ObArray tablet_ids; + { // lock scope + ObSpinLockGuard guard(lock_); // ensure build ctxs will not change + for (int64_t i = 0; OB_SUCC(ret) && i < replica_build_ctxs_.count(); ++i) { + ObSingleReplicaBuildCtx &replica_build_ctx = replica_build_ctxs_.at(i); + bool need_schedule = false; + if (OB_FAIL(replica_build_ctx.check_need_schedule(need_schedule))) { + LOG_WARN("failed to check need schedule", K(ret)); + } else if (need_schedule) { + obrpc::ObDDLBuildSingleReplicaRequestArg arg; + if (OB_FAIL(construct_rpc_arg(replica_build_ctx, arg))) { + LOG_WARN("failed to construct single replica request arg", K(ret)); + } else if (OB_FAIL(args.push_back(arg))) { + LOG_WARN("failed to push back arg", K(ret)); + } else if (OB_FAIL(addrs.push_back(replica_build_ctx.addr_))) { + LOG_WARN("failed to push back addr", K(ret)); + } else if (OB_FAIL(tablet_ids.push_back(replica_build_ctx.src_tablet_id_))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } + } + } + } // lock scope + // keep send rpc out of lock scope + for (int64_t i = 0; OB_SUCC(ret) && i < args.count(); ++i) { + const ObAddr &addr = addrs.at(i); + if (OB_FAIL(proxy.call(addr, rpc_timeout, dest_tenant_id_, args.at(i)))) { + LOG_WARN("failed to send rpc", K(ret), K(addr), K(rpc_timeout), + K(args.at(i))); + } else { + LOG_INFO("send build single replica request", K(addr), K(args.at(i))); + } + } int tmp_ret = OB_SUCCESS; - { - ObSpinLockGuard guard(lock_); - // send rpc request may cost too much time, thus set some status before rpc request under lock. - for (int64_t i = 0; OB_SUCC(ret) && i < build_infos.count(); i++) { - ObPartitionBuildInfo &build_info = build_infos.at(i); - if (build_info.need_schedule()) { - if (OB_FAIL(request_source_tablet_ids.push_back(source_tablet_ids_.at(i)))) { - LOG_WARN("push backed failed", K(ret)); - } else if (OB_FAIL(request_dest_tablet_ids.push_back(dest_tablet_ids_.at(i)))) { - LOG_WARN("push back failed", K(ret)); - } else if (OB_FAIL(request_tablet_task_ids.push_back(tablet_task_ids_.at(i)))) { - LOG_WARN("push back failed", K(ret)); - } else if (OB_FAIL(idxs.push_back(i))) { - LOG_WARN("fail to push back idx", K(ret)); + common::ObArray ret_array; + if (OB_SUCCESS != (tmp_ret = proxy.wait_all(ret_array))) { + LOG_WARN("rpc_proxy wait failed", K(ret), K(tmp_ret)); + ret = (OB_SUCCESS == ret) ? tmp_ret : ret; + } else if (OB_SUCC(ret)) { + const ObIArray + &result_array = proxy.get_results(); + if (OB_FAIL(process_rpc_results(tablet_ids, addrs, result_array, ret_array))) { + LOG_WARN("failed to process result", K(ret)); + } + } + } + return ret; +} + +/* before check if build is finished, get refreshed replica addrs for all tablets, + * after that, refresh replica build ctxs, finally check each replica build status + */ +int ObDDLReplicaBuildExecutor::check_build_end(const bool need_checksum, bool &is_end, int64_t &ret_code) +{ + int ret = OB_SUCCESS; + is_end = false; + ret_code = OB_SUCCESS; + ObArray replica_tablet_ids; + ObArray replica_addrs; + int64_t succ_cnt = 0; + int64_t failed_cnt = 0; + int64_t reschedule_cnt = 0; + int64_t waiting_cnt = 0; + int64_t total_cnt = 0; + int64_t dest_table_id = OB_INVALID_ID; + const bool send_to_all_replicas = is_tablet_split(ddl_type_); + // keep get replica addr out of lock scope + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (OB_FAIL(get_refreshed_replica_addrs(send_to_all_replicas, + replica_tablet_ids, replica_addrs))) { + LOG_WARN("failed to get refreshed replica addrs", K(ret)); + } + { // lock scope + ObSpinLockGuard guard(lock_); + // first use refresh addrs to refresh build ctxs + if (OB_FAIL(ret)) { + } else if (OB_FAIL(refresh_replica_build_ctxs(replica_tablet_ids, replica_addrs))) { + LOG_WARN("failed to refresh replica build ctxs", K(ret)); + } else if (!replica_build_ctxs_.empty()) { + dest_table_id = replica_build_ctxs_.at(0).dest_table_id_; + } + total_cnt = replica_build_ctxs_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < total_cnt; ++i) { + const ObSingleReplicaBuildCtx &replica_build_ctx = replica_build_ctxs_.at(i); + bool need_schedule = false; + if (replica_build_ctx.stat_ == ObReplicaBuildStat::BUILD_FAILED) { + ++failed_cnt; + LOG_WARN("check build end, task has failed", K(replica_build_ctx.ret_code_), + K(replica_build_ctx)); + if (ret_code == OB_SUCCESS) { + ret_code = replica_build_ctx.ret_code_; + } + } else if (replica_build_ctx.stat_ == ObReplicaBuildStat::BUILD_SUCCEED) { + ++succ_cnt; + } else if (OB_FAIL(replica_build_ctx.check_need_schedule(need_schedule))) { + LOG_WARN("failed to check need schedule", K(ret)); + } else if (need_schedule) { + ++reschedule_cnt; + LOG_INFO("replica build need reschedule", K(replica_build_ctx)); + } else { // rpc requested, waiting for report + ++waiting_cnt; + } + } + } // lock scope, keep schedule task out of lock scope + if (OB_FAIL(ret)) { + } else if (failed_cnt != 0) { + // ret_code already set in for loop + is_end = true; + LOG_INFO("exist replica build task failed", K(failed_cnt), K(total_cnt)); + } else if (reschedule_cnt != 0) { + if (OB_FAIL(schedule_task())) { + LOG_WARN("fail to schedule task", K(ret)); + } else { + LOG_INFO("replica build task schedule again", K(reschedule_cnt), K(total_cnt)); + } + } else if (succ_cnt == total_cnt) { + is_end = true; + ret_code = ret; + LOG_INFO("all replica build finished", K(succ_cnt), K(total_cnt)); + if (!share::is_tablet_split(ddl_type_) && need_checksum) { + if (OB_FAIL(ObCheckTabletDataComplementOp::check_finish_report_checksum( + dest_tenant_id_, dest_table_id, execution_id_, ddl_task_id_))) { + LOG_WARN("fail to check sstable checksum_report_finish", + K(ret), K(dest_tenant_id_), K(dest_table_id), K(execution_id_), K(ddl_task_id_)); + } + } + } + LOG_INFO("check build end:", K(succ_cnt), K(failed_cnt), K(reschedule_cnt), + K(waiting_cnt), K(total_cnt)); + return ret; +} + +// update replica build ctx if tablet_id && addr is matched +// do nothing if no one matches +int ObDDLReplicaBuildExecutor::update_build_progress( + const common::ObTabletID &tablet_id, + const ObAddr &addr, + const int ret_code, + const int64_t row_scanned, + const int64_t row_inserted, + const int64_t physical_row_count) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!tablet_id.is_valid() || !addr.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(addr)); + } else { // lock scope + ObSpinLockGuard guard(lock_); + if (!is_inited_) { // hold lock before access is_inited_ + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else { + bool is_found = false; + ObSingleReplicaBuildCtx *replica_build_ctx = nullptr; + if (OB_FAIL(get_replica_build_ctx(tablet_id, addr, + replica_build_ctx, is_found))) { + LOG_WARN("failed to get replica build ctx", K(ret), K(tablet_id), K(addr)); + } else if (is_found) { + if (OB_FAIL(update_replica_build_ctx(*replica_build_ctx, + ret_code, row_scanned, row_inserted, physical_row_count, false/*is_rpc_request*/, + true/*is_observer_report*/))) { + LOG_WARN("failed to update replica build ctx", K(ret), K(tablet_id), K(addr), K(ret_code)); + } + LOG_INFO("receive build progress report from replica", K(tablet_id), K(addr), K(ret_code)); + } else { // not found + LOG_INFO("ignore build progress report from expired replica", K(tablet_id), K(addr), K(ret_code)); + } + } + } // lock scope + return ret; +} + +int ObDDLReplicaBuildExecutor::get_progress(int64_t &row_inserted, int64_t &physical_row_count, double &percent) +{ + int ret = OB_SUCCESS; + bool all_done = true; + row_inserted = 0; + physical_row_count = 0; + percent = 0; + // lock scope + ObSpinLockGuard guard(lock_); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < replica_build_ctxs_.count(); ++i) { + row_inserted += replica_build_ctxs_.at(i).row_inserted_; + physical_row_count += replica_build_ctxs_.at(i).physical_row_count_; + if (ObReplicaBuildStat::BUILD_SUCCEED != replica_build_ctxs_.at(i).stat_) { + all_done = false; + } + } + // 100% if all replica_build_ctxs_.at(i).stat_ == BUILD_SUCCEED + if (OB_FAIL(ret)){ + // error occurred + } else if (all_done) { // lob meta maybe 0 rows, percent should be 0; (in row storing) + percent = 100.0; + } else if (physical_row_count == 0) { + percent = 0.0; + } else { + percent = row_inserted * 100.0 / physical_row_count; + } + return ret; +} + +// as caller, schedule_task() will hold lock +int ObDDLReplicaBuildExecutor::construct_rpc_arg( + const ObSingleReplicaBuildCtx &replica_build_ctx, + obrpc::ObDDLBuildSingleReplicaRequestArg &arg) const +{ + int ret = OB_SUCCESS; + ObLSID ls_id; + ObLSID dest_ls_id; + share::ObLocationService *location_service = GCTX.location_service_; + bool is_cache_hit = false; + const bool force_renew = true; + const int64_t expire_renew_time = force_renew ? INT64_MAX : 0; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (!replica_build_ctx.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(replica_build_ctx)); + } else { + arg.tenant_id_ = tenant_id_; + arg.dest_tenant_id_ = dest_tenant_id_; + arg.source_tablet_id_ = replica_build_ctx.src_tablet_id_; + arg.dest_tablet_id_ = replica_build_ctx.dest_tablet_id_; + arg.source_table_id_ = replica_build_ctx.src_table_id_; + arg.dest_schema_id_ = replica_build_ctx.dest_table_id_; + arg.schema_version_ = replica_build_ctx.src_schema_version_; + arg.dest_schema_version_ = replica_build_ctx.dest_schema_version_; + arg.snapshot_version_ = snapshot_version_; + arg.ddl_type_ = ddl_type_; + arg.task_id_ = ddl_task_id_; + arg.parallelism_ = parallelism_; + arg.execution_id_ = execution_id_; + arg.tablet_task_id_ = replica_build_ctx.tablet_task_id_; + arg.data_format_version_ = data_format_version_; + arg.consumer_group_id_ = consumer_group_id_; + arg.compaction_scn_ = replica_build_ctx.compaction_scn_; + arg.can_reuse_macro_block_ = replica_build_ctx.can_reuse_macro_block_; + if (OB_FAIL(arg.lob_col_idxs_.assign(lob_col_idxs_))) { + LOG_WARN("failed to assign to lob col idxs", K(ret)); + } else if (OB_FAIL(arg.parallel_datum_rowkey_list_.assign(replica_build_ctx.parallel_datum_rowkey_list_))) { + LOG_WARN("failed to assign split ranges", K(ret)); + } else if (OB_ISNULL(location_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("location service is nullptr", K(ret)); + } else if (OB_FAIL(location_service->get(tenant_id_, arg.source_tablet_id_, + expire_renew_time, is_cache_hit, ls_id))) { + LOG_WARN("get ls failed", K(ret), K(arg.source_tablet_id_)); + } else if (OB_FAIL(location_service->get(dest_tenant_id_, arg.dest_tablet_id_, + expire_renew_time, is_cache_hit, dest_ls_id))) { + LOG_WARN("get dest ls failed", K(ret), K(arg)); + } else { + arg.ls_id_ = ls_id; + arg.dest_ls_id_ = dest_ls_id; + } + } + return ret; +} + +int ObDDLReplicaBuildExecutor::process_rpc_results( + const ObArray &tablet_ids, + const ObArray addrs, + const ObIArray &result_array, + const ObArray &ret_array) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (tablet_ids.count() != addrs.count() || + ret_array.count() != addrs.count() || + result_array.count() != addrs.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, rets count is not equal to request count", K(ret), + K(tablet_ids.count()), K(addrs.count()), K(ret_array.count()), + K(result_array.count())); + } + { // lock scope + ObSpinLockGuard guard(lock_); + for (int64_t i = 0; OB_SUCC(ret) && i < result_array.count(); ++i) { + const ObTabletID &tablet_id = tablet_ids.at(i); + const ObAddr &addr = addrs.at(i); + bool is_found = false; + ObSingleReplicaBuildCtx *replica_build_ctx = nullptr; + if (OB_FAIL(get_replica_build_ctx(tablet_id, addr, replica_build_ctx, + is_found))) { + LOG_WARN("failed to get replica build ctx", K(ret)); + } else if (is_found) { + if (replica_build_ctx->stat_ != ObReplicaBuildStat::BUILD_INIT) { + continue; // already handle respone rpc + } else if (OB_FAIL(update_build_ctx(*replica_build_ctx, + result_array.at(i), ret_array.at(i)))) { + LOG_WARN("failed to update build progress", K(ret)); + } + } else { // not found, replica addr refreshed, ignore result + LOG_INFO("replica addr refreshed, ignore rpc result from ", + K(tablet_id), K(addr)); + } + } + } // lock scope + return ret; +} + +// as caller, process_rpc_result() will hold lock +int ObDDLReplicaBuildExecutor::update_build_ctx( + ObSingleReplicaBuildCtx &build_ctx, + const oceanbase::obrpc::ObDDLBuildSingleReplicaRequestResult *result, + const int ret_code) +{ + int ret = OB_SUCCESS; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (OB_FAIL(update_replica_build_ctx(build_ctx, ret_code, + result->row_scanned_, result->row_inserted_, result->physical_row_count_, true/*is_rpc_request*/, + false/*is_observer_report*/))) { + LOG_WARN("failed to update replica build ctx", K(ret)); + } + return ret; +} + +// as caller, build() will hold lock +int ObDDLReplicaBuildExecutor::construct_replica_build_ctxs( + const ObDDLReplicaBuildExecutorParam ¶m, + ObArray &replica_build_ctxs) const +{ + int ret = OB_SUCCESS; + ObArray split_replica_addrs; + replica_build_ctxs.reuse(); + const bool send_to_all_replicas = is_tablet_split(param.ddl_type_); + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + if (!param.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(param)); + } else if (send_to_all_replicas) { + ObLSID ls_id; + ObAddr unused_addr; + const ObTabletID &any_tablet_id = param.source_tablet_ids_.at(0); + if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr( + GCTX.location_service_, param.tenant_id_, any_tablet_id, rpc_timeout, ls_id, unused_addr))) { + LOG_WARN("get ls id failed", K(ret), K(param.tenant_id_), K(any_tablet_id)); + } else if (OB_FAIL(ObDDLUtil::get_split_replicas_addrs(param.tenant_id_, ls_id, split_replica_addrs))) { + LOG_WARN("get split replica addrs failed", K(ret), K(param.tenant_id_), K(ls_id)); + } + } + if (OB_SUCC(ret)) { + for (int64_t i = 0; OB_SUCC(ret) && i < param.source_tablet_ids_.count(); ++i) { + const ObTabletID &src_tablet_id = param.source_tablet_ids_.at(i); + const ObTabletID &dest_tablet_id = param.dest_tablet_ids_.at(i); + const int64_t src_table_id = param.source_table_ids_.at(i); + const int64_t dest_table_id = param.dest_table_ids_.at(i); + const int64_t src_schema_version = param.source_schema_versions_.at(i); + const int64_t dest_schema_version = param.dest_schema_versions_.at(i); + int64_t tablet_task_id = i + 1; + int64_t compaction_scn = send_to_all_replicas ? param.compaction_scns_.at(i) : 0; + const bool can_reuse_macro_block = send_to_all_replicas ? param.can_reuse_macro_blocks_.at(i) : false; + ObSEArray unused_empty_rowkey_list; // placeholder only. + const ObIArray ¶llel_datum_rowkey_list = send_to_all_replicas ? + param.parallel_datum_rowkey_list_.at(i) : unused_empty_rowkey_list; + if (send_to_all_replicas) { + for (int64_t j = 0; OB_SUCC(ret) && j < split_replica_addrs.count(); ++j) { + ObSingleReplicaBuildCtx replica_build_ctx; + if (OB_FAIL(replica_build_ctx.init(split_replica_addrs.at(j), ddl_type_, + src_table_id, dest_table_id, src_schema_version, + dest_schema_version, tablet_task_id, compaction_scn, + src_tablet_id, dest_tablet_id, can_reuse_macro_block, parallel_datum_rowkey_list))) { + LOG_WARN("failed to init replica build ctx", K(ret)); + } else if (OB_FAIL(replica_build_ctxs.push_back(replica_build_ctx))) { + LOG_WARN("failed to push back replica build ctx", K(ret)); + } + } + } else { // send to all leader only + ObLSID unused_ls_id; + ObAddr orig_leader_addr; + ObAddr dest_leader_addr; + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + ObSingleReplicaBuildCtx replica_build_ctx; + if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(GCTX.location_service_, + param.tenant_id_, src_tablet_id, rpc_timeout, unused_ls_id, orig_leader_addr))) { + LOG_WARN("failed to get orig leader addr", K(ret), K(src_tablet_id)); + } else if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(GCTX.location_service_, + param.dest_tenant_id_, dest_tablet_id, rpc_timeout, unused_ls_id, + dest_leader_addr))) { + LOG_WARN("failed to get dest leader addr", K(ret), K(dest_tablet_id)); + } else if (ObDDLType::DDL_TABLE_RESTORE != ddl_type_ && + orig_leader_addr != dest_leader_addr) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("orig leader addr not equal dest leader addr", K(ret), K(orig_leader_addr), + K(dest_leader_addr)); + } else if (OB_FAIL(replica_build_ctx.init(dest_leader_addr, ddl_type_, + src_table_id, dest_table_id, src_schema_version, dest_schema_version, + tablet_task_id, compaction_scn, src_tablet_id, dest_tablet_id, can_reuse_macro_block, parallel_datum_rowkey_list))) { + LOG_WARN("failed to init replica build ctx", K(ret), K(src_tablet_id)); + } else if (OB_FAIL(replica_build_ctxs.push_back(replica_build_ctx))) { + LOG_WARN("failed to push back replica build ctx", K(ret)); + } + } + } + } + return ret; +} + +int ObDDLReplicaBuildExecutor::get_refreshed_replica_addrs( + const bool send_to_all_replicas, + ObArray &replica_tablet_ids, + ObArray &replica_addrs) const +{ + int ret = OB_SUCCESS; + // TODO hanxuan optimization hold lock before refresh addrs (ObMemberListLockUtils) + replica_tablet_ids.reuse(); + replica_addrs.reuse(); + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (OB_UNLIKELY(src_tablet_ids_.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KPC(this)); + } else if (send_to_all_replicas) { + ObLSID ls_id; + ObAddr unused_addr; + ObArray split_replica_addrs; + const ObTabletID &any_tablet_id = src_tablet_ids_.at(0); + if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr( + GCTX.location_service_, tenant_id_, any_tablet_id, rpc_timeout, ls_id, unused_addr))) { + LOG_WARN("get ls id failed", K(ret), K(tenant_id_), K(any_tablet_id)); + } else if (OB_FAIL(ObDDLUtil::get_split_replicas_addrs(tenant_id_, ls_id, split_replica_addrs))) { + LOG_WARN("get split replica addrs failed", K(ret), K(tenant_id_), K(ls_id)); + } else { // send to all replicas. + for (int64_t i = 0; OB_SUCC(ret) && i < src_tablet_ids_.count(); ++i) { + const ObTabletID &src_tablet_id = src_tablet_ids_.at(i); + for (int64_t j = 0; OB_SUCC(ret) && j < split_replica_addrs.count(); ++j) { + const ObAddr &addr = split_replica_addrs.at(j); + if (OB_FAIL(replica_tablet_ids.push_back(src_tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } else if (OB_FAIL(replica_addrs.push_back(addr))) { + LOG_WARN("failed to push back addr", K(ret)); } } } } - for (int64_t i = 0; OB_SUCC(ret) && i < request_source_tablet_ids.count(); ++i) { - // get leader of partition + } else { // send to leader only. + for (int64_t i = 0; OB_SUCC(ret) && i < src_tablet_ids_.count(); ++i) { + ObLSID ls_id; ObAddr orig_leader_addr; ObAddr dest_leader_addr; - obrpc::ObDDLBuildSingleReplicaRequestArg arg; - arg.ls_id_ = share::ObLSID::INVALID_LS_ID; - arg.dest_ls_id_ = share::ObLSID::INVALID_LS_ID; - arg.tenant_id_ = tenant_id_; - arg.dest_tenant_id_ = dest_tenant_id_; - arg.source_tablet_id_ = request_source_tablet_ids.at(i); - arg.dest_tablet_id_ = request_dest_tablet_ids.at(i); - arg.source_table_id_ = source_table_id_; - arg.dest_schema_id_ = dest_table_id_; - arg.schema_version_ = schema_version_; - arg.dest_schema_version_ = dest_schema_version_; - arg.snapshot_version_ = snapshot_version_; - arg.ddl_type_ = type_; - arg.task_id_ = task_id_; - arg.parallelism_ = parallelism_; - arg.execution_id_ = execution_id_; - arg.data_format_version_ = data_format_version_; - arg.tablet_task_id_ = request_tablet_task_ids.at(i); - arg.consumer_group_id_ = consumer_group_id_; - if (OB_FAIL(location_service->get(tenant_id_, arg.source_tablet_id_, - expire_renew_time, is_cache_hit, orig_ls_id))) { - LOG_WARN("get ls failed", K(ret), K(arg.source_tablet_id_)); - } else if (OB_FAIL(location_service->get_leader(GCONF.cluster_id, tenant_id_, orig_ls_id, force_renew, orig_leader_addr))) { - LOG_WARN("get leader failed", K(ret), K(tenant_id_), K(orig_ls_id)); - } else if (FALSE_IT(arg.ls_id_ = orig_ls_id)) { - } else if (OB_FAIL(location_service->get(dest_tenant_id_, arg.dest_tablet_id_, - expire_renew_time, is_cache_hit, dest_ls_id))) { - LOG_WARN("get ls failed", K(ret), K(arg.dest_tablet_id_)); - } else if (OB_FAIL(location_service->get_leader(GCONF.cluster_id, dest_tenant_id_, dest_ls_id, force_renew, dest_leader_addr))) { - LOG_WARN("get leader failed", K(ret), K(dest_tenant_id_), K(dest_ls_id)); - } else if (ObDDLType::DDL_TABLE_RESTORE != arg.ddl_type_ && orig_leader_addr != dest_leader_addr) { + const ObTabletID &src_tablet_id = src_tablet_ids_.at(i); + const ObTabletID &dest_tablet_id = dest_tablet_ids_.at(i); + if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(GCTX.location_service_, + tenant_id_, src_tablet_id, rpc_timeout, ls_id, orig_leader_addr))) { + LOG_WARN("failed to get orig leader addr", K(ret), K(src_tablet_id)); + } else if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(GCTX.location_service_, + dest_tenant_id_, dest_tablet_id, rpc_timeout, ls_id, + dest_leader_addr))) { + LOG_WARN("failed to get dest leader addr", K(ret), K(dest_tablet_id)); + } else if (ObDDLType::DDL_TABLE_RESTORE != ddl_type_ && + orig_leader_addr != dest_leader_addr) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("orig leader addr not equal dest leader addr", K(ret), K(orig_leader_addr), K(dest_leader_addr), K(arg)); - } else if (FALSE_IT(arg.dest_ls_id_ = dest_ls_id)) { - } else if (OB_FAIL(proxy.call(dest_leader_addr, rpc_timeout, dest_tenant_id_, arg))) { - LOG_WARN("fail to send rpc", K(ret), K(rpc_timeout)); + LOG_WARN("orig leader addr not equal dest leader addr", K(ret), + K(orig_leader_addr), K(dest_leader_addr)); } else { - LOG_INFO("send build single replica request", K(arg), K(dest_leader_addr), "ddl_event_info", ObDDLEventInfo()); - char table_id_buffer[256]; - snprintf(table_id_buffer, sizeof(table_id_buffer), "data_table_id:%ld, dest_table_id:%ld", - source_table_id_, dest_table_id_); - ROOTSERVICE_EVENT_ADD("ddl scheduler", "schedule single replica task", - "tenant_id", dest_tenant_id_, - "ret", ret, - "trace_id", *ObCurTraceId::get_trace_id(), - K_(task_id), - "table_id", table_id_buffer, - "dest_leader_addr", dest_leader_addr, - orig_leader_addr); - } - } - if (OB_TMP_FAIL(proxy.wait_all(ret_array))) { - LOG_WARN("rpc_pRoxy wait failed", KR(ret), KR(tmp_ret)); - ret = (OB_SUCCESS == ret) ? tmp_ret : ret; - } else if (OB_FAIL(ret)) { - } else if (OB_FAIL(proxy.check_return_cnt(ret_array.count()))) { - LOG_WARN("return cnt not match", KR(ret), "return_cnt", ret_array.count()); - } else { - if (ret_array.count() != idxs.count()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("error unexpected, ret array count is not equal to request count", - KR(ret), "return_cnt", ret_array.count(), "idxs_cnt", idxs.count()); - } - ObSpinLockGuard guard(lock_); - const ObIArray &result_array = proxy.get_results(); - for (int64_t i = 0; OB_SUCC(ret) && i < ret_array.count(); ++i) { - const int64_t idx = idxs.at(i); - if (!build_infos.at(idx).need_schedule()) { // already handle respone rpc - continue; - } else if (OB_SUCCESS == ret_array.at(i)) { - build_infos.at(idx).stat_ = ObPartitionBuildStat::BUILD_REQUESTED; - build_infos.at(idx).heart_beat_time_ = ObTimeUtility::current_time(); - build_infos.at(idx).row_inserted_ = MAX(build_infos.at(idx).row_inserted_, result_array.at(i)->row_inserted_); - build_infos.at(idx).row_scanned_ = MAX(build_infos.at(idx).row_scanned_, result_array.at(i)->row_scanned_); - LOG_INFO("rpc send successfully", K(source_tablet_ids_.at(idx)), K(dest_tablet_ids_.at(idx))); - } else if (ObIDDLTask::in_ddl_retry_white_list(ret_array.at(i))) { - build_infos.at(idx).stat_ = ObPartitionBuildStat::BUILD_RETRY; - build_infos.at(idx).row_inserted_ = 0; - build_infos.at(idx).row_scanned_ = 0; - LOG_INFO("task need retry", K(ret_array.at(i)), K(source_tablet_ids_.at(idx)), K(dest_tablet_ids_.at(idx))); - } else { - build_infos.at(idx).stat_ = ObPartitionBuildStat::BUILD_FAILED; - build_infos.at(idx).ret_code_ = ret_array.at(i); - build_infos.at(idx).heart_beat_time_ = ObTimeUtility::current_time(); - build_infos.at(idx).row_inserted_ = 0; - build_infos.at(idx).row_scanned_ = 0; - LOG_INFO("task is failed", K(build_infos.at(idx)), K(source_tablet_ids_.at(idx)), K(dest_tablet_ids_.at(idx))); + if (OB_FAIL(replica_tablet_ids.push_back(src_tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } else if (OB_FAIL(replica_addrs.push_back(dest_leader_addr))) { + LOG_WARN("failed to push back addr", K(ret)); } } } @@ -246,99 +701,166 @@ int ObDDLSingleReplicaExecutor::schedule_task() return ret; } -int ObDDLSingleReplicaExecutor::check_build_end(const bool need_checksum, bool &is_end, int64_t &ret_code) +/* for each replica, check if there exists build ctx whose tablet id && addr matches + * - if exists, copy it to new replica build ctx with its build stat + * - otherwise, init a new build ctx whose build stat is BUILD_INIT + * NOTE as caller, check_build_end() will hold lock_ + */ +int ObDDLReplicaBuildExecutor::refresh_replica_build_ctxs( + const ObArray &replica_tablet_ids, + const ObArray &replica_addrs) { int ret = OB_SUCCESS; - is_end = false; - bool has_fail = false; - bool need_schedule = false; - int64_t succ_cnt = 0; - { - ObSpinLockGuard guard(lock_); - const common::ObIArray &build_infos = partition_build_stat_; - for (int64_t i = 0; OB_SUCC(ret) && i < build_infos.count() && !has_fail; ++i) { - has_fail = (ObPartitionBuildStat::BUILD_FAILED == build_infos.at(i).stat_); - if (has_fail) { - is_end = true; - ret_code = build_infos.at(i).ret_code_; - LOG_WARN("check build end, task has failed", K(ret_code)); - } - } - if (OB_SUCC(ret) && !is_end) { - for (int64_t i = 0; OB_SUCC(ret) && i < build_infos.count(); ++i) { - succ_cnt += ObPartitionBuildStat::BUILD_SUCCEED == build_infos.at(i).stat_; - need_schedule |= build_infos.at(i).need_schedule(); - } - if (OB_SUCC(ret) && build_infos.count() == succ_cnt && need_checksum) { - if (OB_FAIL(ObCheckTabletDataComplementOp::check_finish_report_checksum( - dest_tenant_id_, dest_table_id_, execution_id_, task_id_))) { - LOG_WARN("fail to check sstable checksum_report_finish", - K(ret), K(dest_tenant_id_), K(dest_table_id_), K(execution_id_), K(task_id_)); - } - } - if (OB_SUCC(ret) && build_infos.count() == succ_cnt) { - is_end = true; - ret_code = ret; - } - } - } - if (OB_SUCC(ret) && need_schedule) { - if (OB_FAIL(schedule_task())) { - LOG_WARN("fail to schedule task", K(ret)); - } else { - LOG_INFO("need schedule again", K(succ_cnt)); - } - } - return ret; -} - -int ObDDLSingleReplicaExecutor::set_partition_task_status(const common::ObTabletID &tablet_id, - const int ret_code, - const int64_t row_scanned, - const int64_t row_inserted) -{ - LOG_INFO("ObDDLSingleReplicaExecutor::set_partition_task_status", K(ret_code)); - int ret = OB_SUCCESS; - common::ObIArray &build_infos = partition_build_stat_; - if (OB_UNLIKELY(!tablet_id.is_valid())) { + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (replica_tablet_ids.empty() || replica_addrs.empty() || + replica_tablet_ids.count() != replica_addrs.count()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", K(ret), K(tablet_id)); - } else { - ObSpinLockGuard guard(lock_); - for (int64_t i = 0; OB_SUCC(ret) && i < source_tablet_ids_.count(); ++i) { - if (tablet_id == source_tablet_ids_.at(i)) { - if (OB_SUCCESS == ret_code) { - build_infos.at(i).ret_code_ = OB_SUCCESS; - build_infos.at(i).stat_ = ObPartitionBuildStat::BUILD_SUCCEED; - build_infos.at(i).row_inserted_ = row_inserted; - build_infos.at(i).row_scanned_ = row_scanned; - } else if (ObIDDLTask::in_ddl_retry_white_list(ret_code)) { - build_infos.at(i).ret_code_ = OB_SUCCESS; - build_infos.at(i).stat_ = ObPartitionBuildStat::BUILD_RETRY; - build_infos.at(i).row_inserted_ = 0; - build_infos.at(i).row_scanned_ = 0; - } else { - build_infos.at(i).ret_code_ = ret_code; - build_infos.at(i).stat_ = ObPartitionBuildStat::BUILD_FAILED; - build_infos.at(i).row_inserted_ = 0; - build_infos.at(i).row_scanned_ = 0; + LOG_WARN("invalid argument", K(replica_tablet_ids.count()), K(replica_addrs.count())); + } + ObArray new_replica_build_ctxs; + for (int64_t i = 0; OB_SUCC(ret) && i < replica_addrs.count(); ++i) { + const ObTabletID &tablet_id = replica_tablet_ids.at(i); + const ObAddr &replica_addr = replica_addrs.at(i); + bool is_found = false; + ObSingleReplicaBuildCtx *existing_ctx = nullptr; + if (OB_FAIL(get_replica_build_ctx(tablet_id, replica_addr, + existing_ctx, is_found))) { + LOG_WARN("failed to get replica build ctx", K(ret), + K(tablet_id), K(replica_addr)); + } else if (is_found) { + if (OB_FAIL(new_replica_build_ctxs.push_back(*existing_ctx))) { + LOG_WARN("failed to push back replica build ctx", K(ret)); + } + } else { // not found + ObSingleReplicaBuildCtx new_build_ctx; + bool ctx_partial_inited = false; + // 1. use existing replica build ctx to init new build ctx + // NOTE currently new build ctx's addr is an unrelated addr + for (int64_t j = 0; OB_SUCC(ret) && !ctx_partial_inited && + j < replica_build_ctxs_.count(); ++j) { + // find corresponding tablet + if (replica_build_ctxs_.at(j).src_tablet_id_ == tablet_id) { + if (OB_FAIL(new_build_ctx.assign(replica_build_ctxs_.at(j)))) { + LOG_WARN("failed to assign to replica build ctx", K(ret)); + } else { + // use correspoinding tablet's old replica ctx to init + ctx_partial_inited = true; + } } } + // 2. overwrite with correct addr && reset build stat + if (OB_FAIL(ret)) { + } else if (!ctx_partial_inited) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to setup new replica build ctx for refreshed replica addr", + K(ret), K(tablet_id), K(replica_addr)); + } else if (FALSE_IT(new_build_ctx.addr_ = replica_addr)) { + } else if (FALSE_IT(new_build_ctx.reset_build_stat())) { + } else if (OB_FAIL(new_replica_build_ctxs.push_back(new_build_ctx))) { + LOG_WARN("failed to push back replica build ctx", K(ret)); + } + if (OB_FAIL(ret)) { + LOG_WARN("failed to setup new replica build ctx for refreshed replica addr", + K(ret), K(tablet_id), K(replica_addr), K(new_build_ctx)); + } else { + LOG_INFO("setup new replica build ctx for refreshed replica addr", + K(tablet_id), K(replica_addr), K(new_build_ctx)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(replica_build_ctxs_.assign(new_replica_build_ctxs))) { + LOG_WARN("failed to assign to replica build ctxs", K(ret)); + } else if (new_replica_build_ctxs.count() != replica_tablet_ids.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the size of replica build ctxs doesn't equal to the size of replica_tablet_ids", K(ret), K(replica_build_ctxs_.count()), K(replica_tablet_ids.count())); + } + return ret; +} + +// look up repica build ctx by tablet id && addr +// NOTE as caller, update_build_progress() process_rpc_results() +// refresh_replica_build_ctxs() will hold lock +int ObDDLReplicaBuildExecutor::get_replica_build_ctx( + const ObTabletID &tablet_id, + const ObAddr &addr, + ObSingleReplicaBuildCtx *&replica_build_ctx, + bool &is_found) +{ + int ret = OB_SUCCESS; + replica_build_ctx = nullptr; + is_found = false; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (!tablet_id.is_valid() || !addr.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tablet_id), K(addr)); + } + for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < replica_build_ctxs_.count(); ++i) { + if (replica_build_ctxs_.at(i).src_tablet_id_ == tablet_id && + replica_build_ctxs_.at(i).addr_ == addr) { + replica_build_ctx = &replica_build_ctxs_.at(i); + is_found = true; } } return ret; } -int ObDDLSingleReplicaExecutor::get_progress(int64_t &row_scanned, int64_t &row_inserted) +// NOTE as caller, update_build_progress(), update_build_ctx() will hold lock +int ObDDLReplicaBuildExecutor::update_replica_build_ctx( + ObSingleReplicaBuildCtx &build_ctx, + const int64_t ret_code, + const int64_t row_scanned, + const int64_t row_inserted, + const int64_t physical_row_count, + const bool is_rpc_request, + const bool is_observer_report) { int ret = OB_SUCCESS; - row_scanned = 0; - row_inserted = 0; - ObSpinLockGuard guard(lock_); - const common::ObIArray &build_infos = partition_build_stat_; - for (int64_t i = 0; OB_SUCC(ret) && i < build_infos.count(); ++i) { - row_scanned += build_infos.at(i).row_scanned_; - row_inserted += build_infos.at(i).row_inserted_; + if (!is_inited_) { + ret = OB_NOT_INIT; + LOG_WARN("replica build executor not init", K(ret)); + } else if (ret_code == OB_SUCCESS) { + build_ctx.ret_code_ = OB_SUCCESS; + if (is_rpc_request) { + build_ctx.row_inserted_ = MAX(build_ctx.row_inserted_, row_inserted); + build_ctx.row_scanned_ = MAX(build_ctx.row_scanned_, row_scanned); + build_ctx.physical_row_count_ = MAX(build_ctx.physical_row_count_, physical_row_count); + build_ctx.stat_ = ObReplicaBuildStat::BUILD_REQUESTED; + LOG_INFO("rpc send successfully", K(build_ctx.addr_), + K(build_ctx.src_tablet_id_), K(build_ctx.dest_tablet_id_)); + } else if (is_observer_report) { + build_ctx.row_inserted_ = row_inserted; + build_ctx.row_scanned_ = row_scanned; + build_ctx.physical_row_count_ = physical_row_count; + build_ctx.stat_ = ObReplicaBuildStat::BUILD_SUCCEED; + LOG_INFO("receive observer build success report", K(build_ctx.addr_), + K(build_ctx.src_tablet_id_), K(build_ctx.dest_tablet_id_)); + } + } else if (ObIDDLTask::in_ddl_retry_white_list(ret_code)) { + build_ctx.ret_code_ = OB_SUCCESS; + build_ctx.row_inserted_ = 0; + build_ctx.row_scanned_ = 0; + build_ctx.physical_row_count_ = 0; + build_ctx.stat_ = ObReplicaBuildStat::BUILD_RETRY; + LOG_INFO("task need retry", K(ret_code), K(build_ctx.addr_), + K(build_ctx.src_tablet_id_), K(build_ctx.dest_tablet_id_), + K(is_rpc_request), K(is_observer_report)); + } else { // other error ret_code + build_ctx.ret_code_ = ret_code; + build_ctx.row_inserted_ = 0; + build_ctx.row_scanned_ = 0; + build_ctx.physical_row_count_ = 0; + build_ctx.stat_ = ObReplicaBuildStat::BUILD_FAILED; + LOG_INFO("task is failed", K(build_ctx.addr_), K(build_ctx.src_tablet_id_), + K(build_ctx.dest_tablet_id_), K(is_rpc_request), K(is_observer_report), K(build_ctx)); + } + if (OB_FAIL(ret)) { + } else if (is_rpc_request) { + build_ctx.heart_beat_time_ = ObTimeUtility::current_time(); } return ret; } diff --git a/src/rootserver/ddl_task/ob_ddl_single_replica_executor.h b/src/rootserver/ddl_task/ob_ddl_single_replica_executor.h index c1ba70bd7..6e93c66c4 100644 --- a/src/rootserver/ddl_task/ob_ddl_single_replica_executor.h +++ b/src/rootserver/ddl_task/ob_ddl_single_replica_executor.h @@ -16,125 +16,259 @@ #include "lib/container/ob_array.h" #include "common/ob_tablet_id.h" #include "share/ob_ddl_common.h" +#include "share/ob_rpc_struct.h" namespace oceanbase { namespace rootserver { -struct ObDDLSingleReplicaExecutorParam final +struct ObDDLReplicaBuildExecutorParam final { public: - ObDDLSingleReplicaExecutorParam() - : tenant_id_(common::OB_INVALID_TENANT_ID), - dest_tenant_id_(common::OB_INVALID_TENANT_ID), - type_(share::DDL_INVALID), + ObDDLReplicaBuildExecutorParam () + : tenant_id_(OB_INVALID_TENANT_ID), + dest_tenant_id_(OB_INVALID_TENANT_ID), + ddl_type_(share::DDL_INVALID), source_tablet_ids_(), dest_tablet_ids_(), - source_table_id_(common::OB_INVALID_ID), - dest_table_id_(common::OB_INVALID_ID), - schema_version_(0), - dest_schema_version_(0), + source_table_ids_(OB_INVALID_ID), + dest_table_ids_(OB_INVALID_ID), + source_schema_versions_(0), + dest_schema_versions_(0), snapshot_version_(0), task_id_(0), parallelism_(0), execution_id_(-1), data_format_version_(0), - consumer_group_id_(0) + consumer_group_id_(0), + compaction_scns_(), + lob_col_idxs_(), + can_reuse_macro_blocks_(), + parallel_datum_rowkey_list_() {} - ~ObDDLSingleReplicaExecutorParam() = default; + ~ObDDLReplicaBuildExecutorParam () = default; bool is_valid() const { - return common::OB_INVALID_TENANT_ID != tenant_id_ && common::OB_INVALID_TENANT_ID != dest_tenant_id_ - && share::DDL_INVALID != type_ && source_tablet_ids_.count() > 0 && dest_tablet_ids_.count() > 0 - && common::OB_INVALID_ID != source_table_id_ && common::OB_INVALID_ID != dest_table_id_ - && schema_version_ > 0 && dest_schema_version_ > 0 && snapshot_version_ > 0 && task_id_ > 0 - && execution_id_ >= 0 && data_format_version_ > 0 && consumer_group_id_ >= 0; + bool is_valid = tenant_id_ != OB_INVALID_TENANT_ID && + dest_tenant_id_ != OB_INVALID_TENANT_ID && + ddl_type_ != share::DDL_INVALID && + source_tablet_ids_.count() > 0 && + dest_tablet_ids_.count() == source_tablet_ids_.count() && + source_table_ids_.count() == source_tablet_ids_.count() && + dest_table_ids_.count() == source_tablet_ids_.count() && + source_schema_versions_.count() == source_tablet_ids_.count() && + dest_schema_versions_.count() == source_tablet_ids_.count() && + snapshot_version_ > 0 && + task_id_ > 0 && + execution_id_ >= 0 && + data_format_version_ > 0 && + consumer_group_id_ >= 0; + if (is_tablet_split(ddl_type_)) { + is_valid = is_valid && compaction_scns_.count() == source_tablet_ids_.count() + && can_reuse_macro_blocks_.count() == source_tablet_ids_.count(); + } else { + is_valid = (is_valid && compaction_scns_.count() == 0); + } + return is_valid; } - TO_STRING_KV(K_(tenant_id), K_(dest_tenant_id), K_(type), K_(source_tablet_ids), K_(dest_tablet_ids), - K_(source_table_id), K_(dest_table_id), K_(schema_version), K_(dest_schema_version), - K_(snapshot_version), K_(task_id), K_(parallelism), K_(execution_id), - K_(data_format_version), K_(consumer_group_id)); + TO_STRING_KV(K_(tenant_id), K_(dest_tenant_id), K_(ddl_type), K_(source_tablet_ids), + K_(dest_tablet_ids), K_(source_table_ids), K_(dest_table_ids), + K_(source_schema_versions), K_(dest_schema_versions), K_(snapshot_version), + K_(task_id), K_(parallelism), K_(execution_id), + K_(data_format_version), K_(consumer_group_id), K_(can_reuse_macro_blocks), + K_(parallel_datum_rowkey_list)); public: uint64_t tenant_id_; uint64_t dest_tenant_id_; - share::ObDDLType type_; - common::ObArray source_tablet_ids_; - common::ObArray dest_tablet_ids_; - int64_t source_table_id_; - int64_t dest_table_id_; - int64_t schema_version_; - int64_t dest_schema_version_; + share::ObDDLType ddl_type_; + ObArray source_tablet_ids_; + ObSArray dest_tablet_ids_; + ObSArray source_table_ids_; + ObSArray dest_table_ids_; + ObSArray source_schema_versions_; + ObSArray dest_schema_versions_; int64_t snapshot_version_; int64_t task_id_; int64_t parallelism_; int64_t execution_id_; int64_t data_format_version_; int64_t consumer_group_id_; + ObSArray compaction_scns_; + ObSArray lob_col_idxs_; + ObSArray can_reuse_macro_blocks_; + common::ObSEArray, 8> parallel_datum_rowkey_list_; }; -class ObDDLSingleReplicaExecutor +enum class ObReplicaBuildStat +{ + BUILD_INIT = 0, + BUILD_REQUESTED = 1, + BUILD_SUCCEED = 2, + BUILD_RETRY = 3, + BUILD_FAILED = 4 +}; + +struct ObSingleReplicaBuildCtx final { public: - int build(const ObDDLSingleReplicaExecutorParam ¶m); + static const int64_t REPLICA_BUILD_HEART_BEAT_TIME = 10 * 1000 * 1000; + ObSingleReplicaBuildCtx() + : is_inited_(false), + addr_(), + ddl_type_(share::DDL_INVALID), + src_table_id_(OB_INVALID_ID), + dest_table_id_(OB_INVALID_ID), + src_schema_version_(0), + dest_schema_version_(0), + tablet_task_id_(0), + compaction_scn_(0), + src_tablet_id_(ObTabletID::INVALID_TABLET_ID), + dest_tablet_id_(), + can_reuse_macro_block_(false), + parallel_datum_rowkey_list_(), + stat_(ObReplicaBuildStat::BUILD_INIT), + ret_code_(OB_SUCCESS), + heart_beat_time_(0), + row_inserted_(0), + row_scanned_(0), + physical_row_count_(0) + { } + ~ObSingleReplicaBuildCtx() = default; + int init(const ObAddr& addr, + const share::ObDDLType ddl_type, + const int64_t src_table_id, + const int64_t dest_table_id, + const int64_t src_schema_version, + const int64_t dest_schema_version, + const int64_t tablet_task_id, + const int64_t compaction_scn, + const ObTabletID &src_tablet_id, + const ObTabletID &dest_tablet_ids, + const bool can_reuse_macro_block, + const ObIArray ¶llel_datum_rowkey_list); + void reset_build_stat(); + bool is_valid() const; + int assign(const ObSingleReplicaBuildCtx &other); + int check_need_schedule(bool &need_schedule) const; + TO_STRING_KV(K(is_inited_), K(addr_), K(ddl_type_), K(src_table_id_), + K(src_schema_version_), K(dest_schema_version_), + K(dest_table_id_), K(tablet_task_id_), K(compaction_scn_), + K(src_tablet_id_), K(dest_tablet_id_), K_(can_reuse_macro_block), + K(parallel_datum_rowkey_list_), K(stat_), K(ret_code_), + K(heart_beat_time_), K(row_inserted_), K(row_scanned_), K(physical_row_count_)); + +public: + bool is_inited_; + ObAddr addr_; + share::ObDDLType ddl_type_; + int64_t src_table_id_; + int64_t dest_table_id_; + int64_t src_schema_version_; + int64_t dest_schema_version_; + int64_t tablet_task_id_; + int64_t compaction_scn_; + ObTabletID src_tablet_id_; + ObTabletID dest_tablet_id_; + bool can_reuse_macro_block_; + common::ObSEArray parallel_datum_rowkey_list_; + ObReplicaBuildStat stat_; + int64_t ret_code_; + int64_t heart_beat_time_; + int64_t row_inserted_; + int64_t row_scanned_; + int64_t physical_row_count_; +}; + +class ObDDLReplicaBuildExecutor +{ +public: + ObDDLReplicaBuildExecutor() + : is_inited_(false), + tenant_id_(OB_INVALID_TENANT_ID), + dest_tenant_id_(OB_INVALID_TENANT_ID), + ddl_type_(share::ObDDLType::DDL_INVALID), + ddl_task_id_(0), + snapshot_version_(0), + parallelism_(0), + execution_id_(0), + data_format_version_(0), + consumer_group_id_(0), + lob_col_idxs_(), + src_tablet_ids_(), + dest_tablet_ids_(), + replica_build_ctxs_(), + lock_() + {} + ~ObDDLReplicaBuildExecutor() = default; + int build(const ObDDLReplicaBuildExecutorParam ¶m); int check_build_end(const bool need_checksum, bool &is_end, int64_t &ret_code); - int set_partition_task_status(const common::ObTabletID &tablet_id, - const int ret_code, - const int64_t row_scanned, - const int64_t row_inserted); - int get_progress(int64_t &row_scanned, int64_t &row_inserted); + int update_build_progress(const ObTabletID &tablet_id, + const ObAddr &addr, + const int ret_code, + const int64_t row_scanned, + const int64_t row_inserted, + const int64_t physical_row_count); + int get_progress(int64_t &row_inserted, int64_t &physical_row_count_, double& percent); + + TO_STRING_KV(K(is_inited_), K(tenant_id_), K(dest_tenant_id_), K(ddl_type_), + K(ddl_task_id_), K(snapshot_version_), K(parallelism_), + K(execution_id_), K(data_format_version_), K(consumer_group_id_), + K(lob_col_idxs_), K(src_tablet_ids_), K(dest_tablet_ids_), + K(replica_build_ctxs_)); private: int schedule_task(); + int process_rpc_results( + const ObArray &tablet_ids, + const ObArray addrs, + const ObIArray &result_array, + const ObArray &ret_array); + int construct_rpc_arg( + const ObSingleReplicaBuildCtx &replica_build_ctx, + obrpc::ObDDLBuildSingleReplicaRequestArg &arg) const; + int construct_replica_build_ctxs( + const ObDDLReplicaBuildExecutorParam ¶m, + ObArray &replica_build_ctxs) const; + int get_refreshed_replica_addrs( + const bool send_to_all_replicas, + ObArray &replica_tablet_ids, + ObArray &replica_addrs) const; + int refresh_replica_build_ctxs( + const ObArray &replica_tablet_ids, + const ObArray &replica_addrs); + int update_build_ctx( + ObSingleReplicaBuildCtx &build_ctx, + const obrpc::ObDDLBuildSingleReplicaRequestResult *result, + const int ret_code); + int update_replica_build_ctx( + ObSingleReplicaBuildCtx &build_ctx, + const int64_t ret_code, + const int64_t row_scanned, + const int64_t row_inserted, + const int64_t row_count, + const bool is_rpc_request, + const bool is_observer_report); + int get_replica_build_ctx( + const ObTabletID &tablet_id, + const ObAddr &addr, + ObSingleReplicaBuildCtx *&replica_build_ctx, + bool &is_found); + private: - enum class ObPartitionBuildStat - { - BUILD_INIT = 0, - BUILD_REQUESTED = 1, - BUILD_SUCCEED = 2, - BUILD_RETRY = 3, - BUILD_FAILED = 4 - }; - struct ObPartitionBuildInfo final - { - public: - static const int64_t PARTITION_BUILD_HEART_BEAT_TIME = 10 * 1000 * 1000; - ObPartitionBuildInfo() - : ret_code_(common::OB_SUCCESS), stat_(ObPartitionBuildStat::BUILD_INIT), heart_beat_time_(0), - row_inserted_(0), row_scanned_(0) - {} - ~ObPartitionBuildInfo() = default; - bool need_schedule() const { - return ObPartitionBuildStat::BUILD_INIT == stat_ - || ObPartitionBuildStat::BUILD_RETRY == stat_ - || (ObPartitionBuildStat::BUILD_REQUESTED == stat_ - && ObTimeUtility::current_time() - heart_beat_time_ > PARTITION_BUILD_HEART_BEAT_TIME); - } - TO_STRING_KV(K_(ret_code), K_(stat), K_(heart_beat_time), K_(row_inserted), K_(row_scanned)); - public: - int64_t ret_code_; - ObPartitionBuildStat stat_; - int64_t heart_beat_time_; - int64_t row_inserted_; - int64_t row_scanned_; - }; -private: + bool is_inited_; uint64_t tenant_id_; uint64_t dest_tenant_id_; - share::ObDDLType type_; - common::ObArray source_tablet_ids_; - common::ObArray dest_tablet_ids_; - common::ObArray tablet_task_ids_; - int64_t source_table_id_; - int64_t dest_table_id_; - int64_t schema_version_; - int64_t dest_schema_version_; + share::ObDDLType ddl_type_; + int64_t ddl_task_id_; int64_t snapshot_version_; - int64_t task_id_; int64_t parallelism_; int64_t execution_id_; int64_t data_format_version_; int64_t consumer_group_id_; - common::ObArray partition_build_stat_; - common::ObSpinLock lock_; + ObSArray lob_col_idxs_; + ObArray src_tablet_ids_; + ObSArray dest_tablet_ids_; + ObArray replica_build_ctxs_; // NOTE hold lock before access + ObSpinLock lock_; // NOTE keep rpc send out of lock scope }; } // end namespace rootserver diff --git a/src/rootserver/ddl_task/ob_ddl_task.cpp b/src/rootserver/ddl_task/ob_ddl_task.cpp index 2c1b2e8ee..1bfb49e17 100644 --- a/src/rootserver/ddl_task/ob_ddl_task.cpp +++ b/src/rootserver/ddl_task/ob_ddl_task.cpp @@ -337,6 +337,7 @@ trace::ObSpanCtx* ObDDLTracing::begin_task_span() case DDL_CONVERT_TO_CHARACTER: case DDL_TABLE_REDEFINITION: case DDL_ALTER_COLUMN_GROUP: + case DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION: span = FLT_BEGIN_SPAN(ddl_table_redefinition); break; case DDL_DROP_PRIMARY_KEY: @@ -421,6 +422,7 @@ trace::ObSpanCtx* ObDDLTracing::restore_task_span() case DDL_CONVERT_TO_CHARACTER: case DDL_TABLE_REDEFINITION: case DDL_ALTER_COLUMN_GROUP: + case DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION: span = FLT_RESTORE_DDL_SPAN(ddl_table_redefinition, task_span_id_, task_start_ts_); break; case DDL_DROP_PRIMARY_KEY: @@ -927,6 +929,9 @@ int ObDDLTask::get_ddl_type_str(const int64_t ddl_type, const char *&ddl_type_st case DDL_MODIFY_AUTO_INCREMENT_WITH_REDEFINITION: ddl_type_str = "modify auto increment column with redefinition"; break; + case DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION: + ddl_type_str = "partition split recovery table redefinition"; + break; default: ret = OB_ERR_UNEXPECTED; } @@ -1169,7 +1174,7 @@ int ObDDLTask::switch_status(const ObDDLTaskStatus new_status, const bool enable ObDDLTaskStatus real_new_status = new_status; const ObDDLTaskStatus old_status = task_status_; const bool error_need_retry = OB_SUCCESS != ret_code && is_error_need_retry(ret_code); - if (OB_TMP_FAIL(check_ddl_task_is_cancel(trace_id_, is_cancel))) { + if (!is_partition_split_recovery_table_redefinition(task_type_) && OB_TMP_FAIL(check_ddl_task_is_cancel(trace_id_, is_cancel))) { LOG_WARN("check ddl task is cancel failed", K(tmp_ret), K(task_id_), K(parent_task_id_), K_(trace_id)); } if (is_cancel) { @@ -1183,7 +1188,11 @@ int ObDDLTask::switch_status(const ObDDLTaskStatus new_status, const bool enable real_ret_code = OB_SUCCESS; } ret_code_ = OB_SUCCESS == ret_code_ ? real_ret_code : ret_code_; - real_new_status = OB_SUCCESS != real_ret_code ? FAIL : real_new_status; + if (is_tablet_split(task_type_)) { + real_new_status = OB_SUCCESS != real_ret_code ? WAIT_PARTITION_SPLIT_RECOVERY_TASK_FINISH : real_new_status; + } else { + real_new_status = OB_SUCCESS != real_ret_code ? FAIL : real_new_status; + } ObMySQLTransaction trans; ObRootService *root_service = nullptr; if (OB_ISNULL(root_service = GCTX.root_service_)) { @@ -1945,6 +1954,41 @@ int ObDDLWaitTransEndCtx::init( return ret; } +int ObDDLWaitTransEndCtx::init( + const uint64_t tenant_id, + const int64_t ddl_task_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const WaitTransType wait_trans_type, + const int64_t wait_version) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K(is_inited_)); + } else if (OB_UNLIKELY(OB_INVALID_ID == tenant_id + || ddl_task_id <= 0 + || table_id <= 0 + || tablet_ids.count() <= 0 + || !is_wait_trans_type_valid(wait_trans_type) + || wait_version <= 0)) { + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(ddl_task_id), K(table_id), K(tablet_ids.count()), K(wait_trans_type), K(wait_version)); + } else if (OB_FAIL(tablet_ids_.assign(tablet_ids))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(snapshot_array_.prepare_allocate(tablet_ids_.count()))) { + LOG_WARN("failed to prepare allocate", K(ret)); + } else { + tenant_id_ = tenant_id; + ddl_task_id_ = ddl_task_id; + table_id_ = table_id; + wait_type_ = wait_trans_type; + wait_version_ = wait_version; + is_trans_end_ = false; + is_inited_ = true; + } + return ret; +} + void ObDDLWaitTransEndCtx::reset() { is_inited_ = false; @@ -3627,6 +3671,7 @@ int ObDDLTaskRecordOperator::check_has_conflict_ddl( case ObDDLType::DDL_DIRECT_LOAD_INSERT: case ObDDLType::DDL_ALTER_COLUMN_GROUP: case ObDDLType::DDL_MVIEW_COMPLETE_REFRESH: + case ObDDLType::DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION: has_conflict_ddl = true; break; default: @@ -4204,6 +4249,58 @@ int ObDDLTaskRecordOperator::kill_inner_sql( return ret; } +int ObDDLTaskRecordOperator::get_partition_split_task_ids( + common::ObISQLClient &proxy, + const uint64_t tenant_id, + const ObIArray &table_ids, + ObIArray &task_ids) +{ + int ret = OB_SUCCESS; + ObSqlString sql_table_ids; + ObSqlString sql_string; + task_ids.reset(); + if (OB_UNLIKELY(tenant_id <= 0 || table_ids.count() < 1)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(table_ids.count())); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + sqlclient::ObMySQLResult *result = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < table_ids.count(); i++) { + if (OB_FAIL(sql_table_ids.append_fmt("%s %lu", 0 == i ? "" : ", ", table_ids.at(i)))) { + LOG_WARN("append sql failed", K(ret)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(sql_string.assign_fmt("SELECT task_id FROM %s WHERE object_id in (%.*s) AND ddl_type >= %u AND ddl_type <= %u ", + OB_ALL_DDL_TASK_STATUS_TNAME, static_cast(sql_table_ids.length()), sql_table_ids.ptr(), ObDDLType::DDL_AUTO_SPLIT_BY_RANGE, ObDDLType::DDL_MANUAL_SPLIT_NON_RANGE))) { + LOG_WARN("assign sql string failed", K(ret)); + } else if (OB_FAIL(proxy.read(res, tenant_id, sql_string.ptr()))) { + LOG_WARN("query task_ids task failed", K(ret), K(sql_string)); + } else if (OB_UNLIKELY(NULL == (result = res.get_result()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get sql result", K(ret)); + } else { + while (OB_SUCC(ret) && OB_SUCC(result->next())) { + uint64_t task_id = OB_INVALID_ID; + EXTRACT_INT_FIELD_MYSQL(*result, "task_id", task_id, uint64_t); + if (OB_SUCC(ret)) { + if (OB_FAIL(task_ids.push_back(task_id))) { + LOG_WARN("fail to push back task id", K(ret), K(task_id)); + } + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to iter result", K(ret)); + } + } + } + } + } + return ret; +} + int ObDDLTaskRecordOperator::kill_task_inner_sql( common::ObMySQLProxy &proxy, const common::ObCurTraceId::TraceId &trace_id, diff --git a/src/rootserver/ddl_task/ob_ddl_task.h b/src/rootserver/ddl_task/ob_ddl_task.h index bcdce50ce..0e733c3d0 100755 --- a/src/rootserver/ddl_task/ob_ddl_task.h +++ b/src/rootserver/ddl_task/ob_ddl_task.h @@ -106,12 +106,13 @@ public: struct ObDDLTaskInfo final { public: - ObDDLTaskInfo() : row_scanned_(0), row_inserted_(0) {} + ObDDLTaskInfo() : row_scanned_(0), row_inserted_(0), physical_row_count_(0) {} ~ObDDLTaskInfo() {} - TO_STRING_KV(K_(row_scanned), K_(row_inserted), K_(ls_id), K_(ls_leader_addr), K_(partition_ids)); + TO_STRING_KV(K_(row_scanned), K_(row_inserted), K_(physical_row_count), K_(ls_id), K_(ls_leader_addr), K_(partition_ids)); public: int64_t row_scanned_; int64_t row_inserted_; + int64_t physical_row_count_; share::ObLSID ls_id_; common::ObAddr ls_leader_addr_; ObArray partition_ids_; @@ -467,6 +468,11 @@ public: common::ObIAllocator &allocator, common::ObIArray &records); + static int get_partition_split_task_ids( + common::ObISQLClient &proxy, + const uint64_t tenant_id, + const ObIArray &table_ids, + ObIArray &task_ids); static int check_rebuild_vec_index_task_exist( const uint64_t tenant_id, const uint64_t data_table_id, @@ -515,6 +521,13 @@ public: const uint64_t table_id, const WaitTransType wait_trans_type, const int64_t wait_version); + int init( + const uint64_t tenant_id, + const int64_t ddl_task_id, + const uint64_t table_id, + const common::ObIArray &tablet_ids, + const WaitTransType wait_trans_type, + const int64_t wait_version); void reset(); bool is_inited() const { return is_inited_; } int try_wait(bool &is_trans_end, int64_t &snapshot_version, const bool need_wait_trans_end = true); @@ -758,7 +771,6 @@ public: static bool check_is_load_data(share::ObDDLType task_type); virtual bool support_longops_monitoring() const { return false; } int cleanup(); - virtual int cleanup_impl() { return OB_NOT_SUPPORTED; } int update_task_record_status_and_msg(common::ObISQLClient &proxy, const share::ObDDLTaskStatus real_new_status); #ifdef ERRSIM @@ -806,10 +818,12 @@ protected: || MAX_ERR_TOLERANCE_CNT > ++err_code_occurence_cnt_)); } int init_ddl_task_monitor_info(const uint64_t target_table_id); - virtual bool task_can_retry() const { return true; } virtual bool is_ddl_retryable() const { return true; } private: - void clear_old_status_context(); + virtual int cleanup_impl() { return OB_NOT_SUPPORTED; } + virtual bool task_can_retry() const { return true; } +protected: + virtual void clear_old_status_context(); protected: static const int64_t TASK_EXECUTE_TIME_THRESHOLD = 3 * 24 * 60 * 60 * 1000000L; // 3 days common::TCRWLock lock_; diff --git a/src/rootserver/ddl_task/ob_drop_index_task.h b/src/rootserver/ddl_task/ob_drop_index_task.h index 4fa1da4b9..cf1be5aac 100644 --- a/src/rootserver/ddl_task/ob_drop_index_task.h +++ b/src/rootserver/ddl_task/ob_drop_index_task.h @@ -43,7 +43,6 @@ public: virtual int deserialize_params_from_message(const uint64_t tenant_id, const char *buf, const int64_t buf_size, int64_t &pos) override; virtual int64_t get_serialize_param_size() const override; INHERIT_TO_STRING_KV("ObDDLTask", ObDDLTask, KP_(root_service)); - virtual int cleanup_impl() override; private: int check_switch_succ(); @@ -55,6 +54,7 @@ private: int drop_index(const share::ObDDLTaskStatus new_status); int succ(); int fail(); + virtual int cleanup_impl() override; int deep_copy_index_arg(common::ObIAllocator &allocator, const obrpc::ObDropIndexArg &src_index_arg, obrpc::ObDropIndexArg &dst_index_arg); diff --git a/src/rootserver/ddl_task/ob_drop_vec_index_task.cpp b/src/rootserver/ddl_task/ob_drop_vec_index_task.cpp index cab122fd4..b89559962 100644 --- a/src/rootserver/ddl_task/ob_drop_vec_index_task.cpp +++ b/src/rootserver/ddl_task/ob_drop_vec_index_task.cpp @@ -925,14 +925,10 @@ int ObDropVecIndexTask::send_build_single_replica_request() ret = OB_NOT_INIT; LOG_WARN("ObColumnRedefinitionTask has not been inited", K(ret)); } else { - ObDDLSingleReplicaExecutorParam param; + ObDDLReplicaBuildExecutorParam param; param.tenant_id_ = tenant_id_; param.dest_tenant_id_ = dst_tenant_id_; - param.type_ = task_type_; - param.source_table_id_ = vec_index_snapshot_data_.table_id_; - param.dest_table_id_ = target_object_id_; - param.schema_version_ = schema_version_; - param.dest_schema_version_ = dst_schema_version_; + param.ddl_type_ = task_type_; param.snapshot_version_ = snapshot_version_; // should > 0, but = 0 param.task_id_ = task_id_; param.parallelism_ = std::max(parallelism_, 1L); @@ -944,6 +940,26 @@ int ObDropVecIndexTask::send_build_single_replica_request() LOG_WARN("fail to get tablets", K(ret), K(tenant_id_), K(object_id_)); } else if (OB_FAIL(ObDDLUtil::get_tablets(dst_tenant_id_, vec_index_snapshot_data_.table_id_, param.dest_tablet_ids_))) { LOG_WARN("fail to get tablets", K(ret), K(tenant_id_), K(target_object_id_)); + } + + const int64_t src_tablet_cnt = param.source_tablet_ids_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < src_tablet_cnt; ++i) { + if (OB_FAIL(param.source_table_ids_.push_back(vec_index_snapshot_data_.table_id_))) { + LOG_WARN("failed to push back src table id", K(ret)); + } else if (OB_FAIL(param.source_schema_versions_.push_back(schema_version_))) { + LOG_WARN("failed to push back src schema version", K(ret)); + } + } + const int64_t dest_tablet_cnt = param.dest_tablet_ids_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < dest_tablet_cnt; ++i) { + if (OB_FAIL(param.dest_table_ids_.push_back(target_object_id_))) { + LOG_WARN("failed to push back dest table id", K(ret)); + } else if (OB_FAIL(param.dest_schema_versions_.push_back(dst_schema_version_))) { + LOG_WARN("failed to push back dest schema version", K(ret)); + } + } + + if (OB_FAIL(ret)) { } else if (OB_FAIL(replica_builder_.build(param))) { LOG_WARN("fail to send build single replica", K(ret), K(param)); } else { @@ -975,6 +991,7 @@ int ObDropVecIndexTask::check_build_single_replica(bool &is_end) // update sstable complement status for all leaders int ObDropVecIndexTask::update_drop_lob_meta_row_job_status(const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, @@ -991,10 +1008,12 @@ int ObDropVecIndexTask::update_drop_lob_meta_row_job_status(const common::ObTabl LOG_WARN("snapshot version not match", K(ret), K(snapshot_version), K(snapshot_version_)); } else if (execution_id < execution_id_) { LOG_INFO("receive a mismatch execution result, ignore", K(ret_code), K(execution_id), K(execution_id_)); - } else if (OB_FAIL(replica_builder_.set_partition_task_status(tablet_id, - ret_code, - addition_info.row_scanned_, - addition_info.row_inserted_))) { + } else if (OB_FAIL(replica_builder_.update_build_progress(tablet_id, + addr, + ret_code, + addition_info.row_scanned_, + addition_info.row_inserted_, + addition_info.physical_row_count_))) { LOG_WARN("fail to set partition task status", K(ret)); } return ret; diff --git a/src/rootserver/ddl_task/ob_drop_vec_index_task.h b/src/rootserver/ddl_task/ob_drop_vec_index_task.h index 159a1073a..1fd59100a 100644 --- a/src/rootserver/ddl_task/ob_drop_vec_index_task.h +++ b/src/rootserver/ddl_task/ob_drop_vec_index_task.h @@ -54,6 +54,7 @@ public: virtual int64_t get_serialize_param_size() const override; virtual int on_child_task_finish(const uint64_t child_task_key, const int ret_code) override { return OB_SUCCESS; } int update_drop_lob_meta_row_job_status(const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, @@ -109,7 +110,7 @@ private: ObVecIndexDDLChildTaskInfo vec_index_id_; ObVecIndexDDLChildTaskInfo vec_index_snapshot_data_; obrpc::ObDropIndexArg drop_index_arg_; - ObDDLSingleReplicaExecutor replica_builder_; + ObDDLReplicaBuildExecutor replica_builder_; common::hash::ObHashMap check_dag_exit_tablets_map_; // for delete lob meta row data ddl only. ObDDLWaitTransEndCtx wait_trans_ctx_; int64_t delte_lob_meta_request_time_; diff --git a/src/rootserver/ddl_task/ob_index_build_task.cpp b/src/rootserver/ddl_task/ob_index_build_task.cpp index b8806c9c2..4ce82ebed 100755 --- a/src/rootserver/ddl_task/ob_index_build_task.cpp +++ b/src/rootserver/ddl_task/ob_index_build_task.cpp @@ -81,6 +81,7 @@ int ObIndexSSTableBuildTask::process() const ObSysVariableSchema *sys_variable_schema = NULL; bool oracle_mode = false; ObTabletID unused_tablet_id; + ObAddr unused_addr; const ObTableSchema *data_schema = nullptr; const ObTableSchema *index_schema = nullptr; bool need_padding = false; @@ -196,9 +197,9 @@ int ObIndexSSTableBuildTask::process() } } ObDDLTaskKey task_key(tenant_id_, dest_table_id_, schema_version_); - int tmp_ret = 0; - tmp_ret = root_service_->get_ddl_scheduler().on_sstable_complement_job_reply( - unused_tablet_id, task_key, snapshot_version_, execution_id_, ret, addition_info_); + ObDDLTaskInfo info; + int tmp_ret = root_service_->get_ddl_scheduler().on_sstable_complement_job_reply( + unused_tablet_id, unused_addr, task_key, snapshot_version_, execution_id_, ret, addition_info_); if (OB_SUCCESS != tmp_ret) { LOG_WARN("report build finish failed", K(ret), K(tmp_ret)); ret = OB_SUCCESS == ret ? tmp_ret : ret; @@ -851,7 +852,8 @@ int ObIndexBuildTask::reap_old_replica_build_task(bool &need_exec_new_inner_sql) LOG_WARN("failed to check and wait old complement task", K(ret)); } } else if (!need_exec_new_inner_sql) { - if (OB_FAIL(update_complete_sstable_job_status(unused_tablet_id, snapshot_version_, old_execution_id, old_ret_code, unused_addition_info))) { + ObAddr unused_addr; + if (OB_FAIL(update_complete_sstable_job_status(unused_tablet_id, unused_addr, snapshot_version_, old_execution_id, old_ret_code, unused_addition_info))) { LOG_INFO("succ to wait and complete old task finished!", K(ret)); } } @@ -1387,6 +1389,7 @@ int ObIndexBuildTask::update_column_checksum_calc_status( int ObIndexBuildTask::update_complete_sstable_job_status( const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, @@ -1399,7 +1402,7 @@ int ObIndexBuildTask::update_complete_sstable_job_status( LOG_WARN("not init", K(ret)); } else if (OB_UNLIKELY(snapshot_version <= 0)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(snapshot_version), K(ret_code)); + LOG_WARN("invalid argument", K(ret), K(snapshot_version), K(addr), K(ret_code)); } else if (OB_FAIL(DDL_SIM(tenant_id_, task_id_, UPDATE_COMPLETE_SSTABLE_FAILED))) { LOG_WARN("ddl sim failure", K(tenant_id_), K(task_id_)); } else if (ObDDLTaskStatus::REDEFINITION != task_status_) { @@ -1407,7 +1410,7 @@ int ObIndexBuildTask::update_complete_sstable_job_status( LOG_INFO("not waiting data complete, may finished", K(task_status_)); } else if (snapshot_version != snapshot_version_) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("snapshot version not match", K(ret), K(snapshot_version), K(snapshot_version_)); + LOG_WARN("snapshot version not match", K(ret), K(addr), K(snapshot_version), K(snapshot_version_)); } else { if (is_create_partitioned_local_index()) { if (OB_UNLIKELY(addition_info.partition_ids_.count() < 1 || !addition_info.ls_id_.is_valid() || !addition_info.ls_leader_addr_.is_valid())) { @@ -1426,9 +1429,9 @@ int ObIndexBuildTask::update_complete_sstable_job_status( complete_sstable_job_ret_code_ = ret_code; sstable_complete_ts_ = ObTimeUtility::current_time(); execution_id_ = execution_id; - LOG_INFO("update complete sstable job return code", K(ret), K(target_object_id_), K(tablet_id), K(snapshot_version), K(ret_code), K(execution_id_), K(addition_info)); } } + LOG_INFO("update complete sstable job return code", K(ret), K(addr), K(target_object_id_), K(tablet_id), K(snapshot_version), K(ret_code), K(execution_id_)); return ret; } diff --git a/src/rootserver/ddl_task/ob_index_build_task.h b/src/rootserver/ddl_task/ob_index_build_task.h index 3179eaaa4..2e24df9a8 100644 --- a/src/rootserver/ddl_task/ob_index_build_task.h +++ b/src/rootserver/ddl_task/ob_index_build_task.h @@ -111,12 +111,12 @@ public: const int ret_code); int update_complete_sstable_job_status( const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, const ObDDLTaskInfo &addition_info); virtual int process() override; - virtual int cleanup_impl() override; virtual bool is_valid() const override; virtual int collect_longops_stat(share::ObLongopsValue &value) override; virtual int serialize_params_to_message(char *buf, const int64_t buf_size, int64_t &pos) const override; @@ -136,6 +136,7 @@ private: int enable_index(); int clean_on_failed(); int succ(); + virtual int cleanup_impl() override; int hold_snapshot(const int64_t snapshot); int release_snapshot(const int64_t snapshot); int update_index_status_in_schema( diff --git a/src/rootserver/ddl_task/ob_modify_autoinc_task.cpp b/src/rootserver/ddl_task/ob_modify_autoinc_task.cpp index 324b2a33f..ae6a00325 100644 --- a/src/rootserver/ddl_task/ob_modify_autoinc_task.cpp +++ b/src/rootserver/ddl_task/ob_modify_autoinc_task.cpp @@ -313,7 +313,7 @@ int ObModifyAutoincTask::unlock_table() } else if (OB_FAIL(owner_id.convert_from_value(ObLockOwnerType::DEFAULT_OWNER_TYPE, task_id_))) { LOG_WARN("convert owner id failed", K(ret), K(task_id_)); - } else if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id_, object_id_, owner_id, trans))) { + } else if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id_, object_id_, nullptr/*hidden_tablet_ids_alone*/, owner_id, trans))) { LOG_WARN("failed to unlock table", K(ret)); } diff --git a/src/rootserver/ddl_task/ob_modify_autoinc_task.h b/src/rootserver/ddl_task/ob_modify_autoinc_task.h index f810e495e..a46dcb7de 100644 --- a/src/rootserver/ddl_task/ob_modify_autoinc_task.h +++ b/src/rootserver/ddl_task/ob_modify_autoinc_task.h @@ -69,13 +69,13 @@ public: virtual int deserialize_params_from_message(const uint64_t tenant_id, const char *buf, const int64_t buf_size, int64_t &pos) override; virtual int64_t get_serialize_param_size() const override; int notify_update_autoinc_finish(const uint64_t autoinc_val, const int ret_code); - virtual int cleanup_impl() override; private: int unlock_table(); int modify_autoinc(); int wait_trans_end(); int fail(); int success(); + virtual int cleanup_impl() override; int set_schema_available(); int rollback_schema(); int check_update_autoinc_end(bool &is_end); diff --git a/src/rootserver/ddl_task/ob_partition_split_task.cpp b/src/rootserver/ddl_task/ob_partition_split_task.cpp new file mode 100644 index 000000000..277256463 --- /dev/null +++ b/src/rootserver/ddl_task/ob_partition_split_task.cpp @@ -0,0 +1,2626 @@ +/** + * 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_partition_split_task.h" +#include "observer/omt/ob_tenant_timezone_mgr.h" +#include "common/ob_tablet_id.h" +#include "share/ob_ddl_checksum.h" +#include "share/ob_ddl_common.h" +#include "rootserver/ob_root_service.h" +#include "storage/ls/ob_ls.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "share/ob_freeze_info_proxy.h" +#include "share/ob_tablet_reorganize_history_table_operator.h" + +using namespace oceanbase::rootserver; +using namespace oceanbase::share; + +template +ObCheckProgressKey::ObCheckProgressKey( + const T &field, + const ObTabletID &tablet_id) + : field_(field), + tablet_id_(tablet_id) +{} + +template +uint64_t ObCheckProgressKey::hash() const +{ + uint64_t hash_val = murmurhash(&field_, sizeof(field_), 0); + hash_val = murmurhash(&tablet_id_, sizeof(tablet_id_), hash_val); + return hash_val; +} + +template +bool ObCheckProgressKey::operator==(const ObCheckProgressKey &other) const +{ + return field_ == other.field_ && + tablet_id_ == other.tablet_id_; +} + +template +bool ObCheckProgressKey::operator!=(const ObCheckProgressKey &other) const +{ + return !(*this == other); +} + +template +int ObCheckProgressKey::assign(const ObCheckProgressKey &other) +{ + int ret = OB_SUCCESS; + if (!other.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(other)); + } else { + field_ = other.field_; + tablet_id_ = other.tablet_id_; + } + return ret; +} + +ObPartitionSplitTask::ObPartitionSplitTask() + : ObDDLTask(DDL_INVALID), + root_service_(nullptr), + partition_split_arg_(), + has_synced_stats_info_(false), + replica_build_task_submit_(false), + replica_build_request_time_(0), + replica_build_ret_code_(OB_SUCCESS), + all_src_tablet_ids_(), + data_tablet_compaction_scn_(0), + index_tablet_compaction_scns_(), + lob_tablet_compaction_scns_(), + tablet_compaction_scn_map_(), + freeze_progress_map_(), + compaction_progress_map_(), + send_finish_map_(), + freeze_progress_status_inited_(false), + compact_progress_status_inited_(false), + write_split_log_status_inited_(false), + replica_builder_(), + wait_trans_ctx_(), + tablet_size_(0), + data_tablet_parallel_rowkey_list_(), + index_tablet_parallel_rowkey_list_() + +{ + ObMemAttr attr(OB_SERVER_TENANT_ID, "RSSplitRange", ObCtxIds::DEFAULT_CTX_ID); + data_tablet_parallel_rowkey_list_.set_attr(attr); + index_tablet_parallel_rowkey_list_.set_attr(attr); +} + +ObPartitionSplitTask::~ObPartitionSplitTask() +{ + data_tablet_parallel_rowkey_list_.reset(); + index_tablet_parallel_rowkey_list_.reset(); +} + +int ObPartitionSplitTask::setup_src_tablet_ids_array() +{ + int ret = OB_SUCCESS; + if (all_src_tablet_ids_.empty()) { + const ObTabletID &data_tablet_id = partition_split_arg_.src_tablet_id_; + const ObSArray &index_tablet_ids = partition_split_arg_.src_local_index_tablet_ids_; + const ObSArray &lob_tablet_ids = partition_split_arg_.src_lob_tablet_ids_; + if (OB_FAIL(all_src_tablet_ids_.push_back(data_tablet_id))) { + LOG_WARN("failed to push back data tablet id", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < index_tablet_ids.count(); ++i) { + if (OB_FAIL(all_src_tablet_ids_.push_back(index_tablet_ids.at(i)))) { + LOG_WARN("failed to push back local index tablet id", K(ret)); + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < lob_tablet_ids.count(); ++i) { + if (OB_FAIL(all_src_tablet_ids_.push_back(lob_tablet_ids.at(i)))) { + LOG_WARN("failed to push back lob tablet id", K(ret)); + } + } + } + if (OB_FAIL(ret)) { + } else if (all_src_tablet_ids_.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to set up all src tablet ids", K(ret)); + } + return ret; +} + +int ObPartitionSplitTask::init_freeze_progress_map() +{ + int ret = OB_SUCCESS; + if (!freeze_progress_status_inited_) { + if (all_src_tablet_ids_.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("all src tablet ids array is empty", K(ret)); + } else if (!freeze_progress_map_.created() && + OB_FAIL(freeze_progress_map_.create(all_src_tablet_ids_.count(), + lib::ObLabel("DDLSplitTask")))) { + LOG_WARN("failed to create freeze progress map", K(ret)); + } + TCWLockGuard guard(lock_); + for (int64_t i = 0; OB_SUCC(ret) && i < all_src_tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = all_src_tablet_ids_.at(i); + ObCheckProgressKey check_progress_key(tenant_id_, tablet_id); + if (OB_FAIL(freeze_progress_map_.set_refactored( + check_progress_key, ObCheckProgressStatus::NOT_STARTED, true /*override*/))) { + LOG_WARN("failed to set freeze progress", K(ret)); + } + } + if (OB_FAIL(ret)) { + (void)freeze_progress_map_.destroy(); + } + } + return ret; +} + +int ObPartitionSplitTask::init_send_finish_map() +{ + int ret = OB_SUCCESS; + if (!write_split_log_status_inited_) { + if (all_src_tablet_ids_.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("all src tablet ids array is empty", K(ret)); + } else if (!send_finish_map_.created() && + OB_FAIL(send_finish_map_.create(all_src_tablet_ids_.count(), + lib::ObLabel("DDLSplitTask")))) { + LOG_WARN("failed to create send finish map", K(ret)); + } + TCWLockGuard guard(lock_); + for (int64_t i = 0; OB_SUCC(ret) && i < all_src_tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = all_src_tablet_ids_.at(i); + ObCheckProgressKey check_progress_key(tenant_id_, tablet_id); + if (OB_FAIL(send_finish_map_.set_refactored( + check_progress_key, ObCheckProgressStatus::NOT_STARTED))) { + LOG_WARN("failed to set finish map", K(ret), K(tablet_id)); + } + } + } + if (OB_FAIL(ret)) { + (void)send_finish_map_.destroy(); + } + return ret; +} + +int ObPartitionSplitTask::init_compaction_scn_map() +{ + int ret = OB_SUCCESS; + if (!tablet_compaction_scn_map_.created() && + OB_FAIL(tablet_compaction_scn_map_.create(10, lib::ObLabel("DDLSplitTask")))) { + LOG_WARN("failed to create tablet compaction scn map", K(ret)); + } + if (OB_FAIL(ret)) { + (void)tablet_compaction_scn_map_.destroy(); + } + return ret; +} + +// restore from deserialization +int ObPartitionSplitTask::restore_compaction_scn_map() +{ + int ret = OB_SUCCESS; + const ObTabletID &data_tablet_id = partition_split_arg_.src_tablet_id_; + const ObSArray &index_tablet_ids = partition_split_arg_.src_local_index_tablet_ids_; + const ObSArray &lob_tablet_ids = partition_split_arg_.src_lob_tablet_ids_; + if (data_tablet_compaction_scn_ == 0 && + index_tablet_compaction_scns_.empty() && + lob_tablet_compaction_scns_.empty()) { + // do nothing + } else if (index_tablet_ids.count() != index_tablet_compaction_scns_.count() || + lob_tablet_ids.count() != lob_tablet_compaction_scns_.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet ids' count != tablet compaction scns' count", K(ret), + K(index_tablet_ids.count()), K(index_tablet_compaction_scns_.count()), + K(lob_tablet_ids.count()), K(lob_tablet_compaction_scns_.count())); + } else { + if (data_tablet_compaction_scn_ != 0) { + if (OB_FAIL(tablet_compaction_scn_map_.set_refactored( + data_tablet_id, data_tablet_compaction_scn_))) { + LOG_WARN("failed to set compaction scn for tablet id in map", K(ret), + K(data_tablet_id), K(data_tablet_compaction_scn_)); + } + } + for (int64_t i = 0; OB_SUCC(ret) && + i < index_tablet_compaction_scns_.count(); ++i) { + const ObTabletID &tablet_id = index_tablet_ids.at(i); + int64_t compaction_scn = index_tablet_compaction_scns_.at(i); + if (compaction_scn != 0) { + if (OB_FAIL(tablet_compaction_scn_map_.set_refactored( + tablet_id, compaction_scn))) { + LOG_WARN("failed to set compaction scn for tablet id in map", K(ret), + K(tablet_id), K(compaction_scn)); + } + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < lob_tablet_compaction_scns_.count(); ++i) { + const ObTabletID &tablet_id = lob_tablet_ids.at(i); + int64_t compaction_scn = lob_tablet_compaction_scns_.at(i); + if (compaction_scn != 0) { + if (OB_FAIL(tablet_compaction_scn_map_.set_refactored( + tablet_id, compaction_scn))) { + LOG_WARN("failed to set compaction scn for tablet id in map", K(ret), + K(tablet_id), K(compaction_scn)); + } + } + } + } + return ret; +} + +int ObPartitionSplitTask::serialize_compaction_scn_to_task_record() +{ + int ret = OB_SUCCESS; + char *buf = nullptr; + int64_t pos = 0; + ObString msg; + ObMySQLTransaction trans; + const int64_t serialize_param_size = get_serialize_param_size(); + ObArenaAllocator allocator(lib::ObLabel("DDLTask")); + if (OB_ISNULL(root_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("root service is null", K(ret), KP(root_service_)); + } else if (OB_ISNULL(buf = + static_cast(allocator.alloc(serialize_param_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret), K(serialize_param_size)); + } else if (OB_FAIL(serialize_params_to_message(buf, serialize_param_size, pos))) { + LOG_WARN("serialize params to message failed", K(ret)); + } else if (FALSE_IT(msg.assign(buf, serialize_param_size))) { + } else if (OB_FAIL(trans.start(&root_service_->get_sql_proxy(), tenant_id_))) { + LOG_WARN("start transaction failed", K(ret)); + } else if (OB_FAIL(ObDDLTaskRecordOperator::update_message(trans, + tenant_id_, task_id_, msg))) { + LOG_WARN("faied to serialize message to task record", K(ret)); + } + bool commit = (OB_SUCCESS == ret); + int tmp_ret = trans.end(commit); + if (OB_SUCCESS != tmp_ret) { + ret = (OB_SUCCESS == ret) ? tmp_ret : ret; + } + return ret; +} + +int ObPartitionSplitTask::init_tablet_compaction_scn_array() +{ + int ret = OB_SUCCESS; + const ObSArray &index_tablet_ids = partition_split_arg_.src_local_index_tablet_ids_; + const ObSArray &lob_tablet_ids = partition_split_arg_.src_lob_tablet_ids_; + if (index_tablet_compaction_scns_.empty()) { + for (int64_t i = 0; OB_SUCC(ret) && i < index_tablet_ids.count(); ++i) { + if (OB_FAIL(index_tablet_compaction_scns_.push_back(0))) { + LOG_WARN("failed to push back to tablet compaction scn", K(ret)); + } + } + } + if (lob_tablet_compaction_scns_.empty()) { + for (int64_t i = 0; OB_SUCC(ret) && i < lob_tablet_ids.count(); ++i) { + if (OB_FAIL(lob_tablet_compaction_scns_.push_back(0))) { + LOG_WARN("failed to push back to tablet compaction scn", K(ret)); + } + } + } + return ret; +} + +// update compaction scn array for serialization +int ObPartitionSplitTask::update_tablet_compaction_scn_array() +{ + int ret = OB_SUCCESS; + const ObTabletID &data_tablet_id = partition_split_arg_.src_tablet_id_; + const ObSArray &index_tablet_ids = partition_split_arg_.src_local_index_tablet_ids_; + const ObSArray &lob_tablet_ids = partition_split_arg_.src_lob_tablet_ids_; + if (index_tablet_ids.count() != index_tablet_compaction_scns_.count() || + lob_tablet_ids.count() != lob_tablet_compaction_scns_.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet ids count != tablet compaction scns count", K(ret), + K(index_tablet_ids.count()), K(index_tablet_compaction_scns_.count()), + K(lob_tablet_ids.count()), K(lob_tablet_compaction_scns_.count())); + } else { + if (OB_FAIL(tablet_compaction_scn_map_.get_refactored( + data_tablet_id, data_tablet_compaction_scn_))) { + if (OB_HASH_NOT_EXIST != ret) { + LOG_WARN("failed to get compaction scn from tablet compaction scn map", + K(ret), K(data_tablet_id)); + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < index_tablet_ids.count(); ++i) { + const ObTabletID tablet_id = index_tablet_ids.at(i); + int64_t compaction_scn = 0l; + if (OB_FAIL(tablet_compaction_scn_map_.get_refactored( + tablet_id, compaction_scn))) { + if (OB_HASH_NOT_EXIST != ret) { + LOG_WARN("failed to get compaction scn from tablet compaction scn map", + K(ret), K(tablet_id)); + } + } else { // update compaction scn + index_tablet_compaction_scns_[i] = compaction_scn; + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < lob_tablet_ids.count(); ++i) { + const ObTabletID tablet_id = lob_tablet_ids.at(i); + int64_t compaction_scn = 0l; + if (OB_FAIL(tablet_compaction_scn_map_.get_refactored( + tablet_id, compaction_scn))) { + if (OB_HASH_NOT_EXIST != ret) { + LOG_WARN("failed to get compaction scn from tablet compaction scn map", + K(ret), K(tablet_id)); + } + } else { // update compaction scn + lob_tablet_compaction_scns_[i] = compaction_scn; + } + } + } + return ret; +} + +int ObPartitionSplitTask::init( + const uint64_t tenant_id, + const int64_t task_id, + const int64_t table_id, + const int64_t schema_version, + const int64_t parallelism, + const obrpc::ObPartitionSplitArg &partition_split_arg, + const int64_t tablet_size, + const int64_t parent_task_id, /* = 0 */ + const int64_t task_status) /* = TaskStatus::PREPARE */ +{ + int ret = OB_SUCCESS; + uint64_t tenant_data_format_version = 0; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_ISNULL(root_service_ = GCTX.root_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("root service is null", K(ret), KP(root_service_)); + } else if (!root_service_->in_service()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("root service not in service", K(ret)); + } else if (OB_UNLIKELY(!(OB_INVALID_ID != tenant_id && + schema_version > 0 && + OB_INVALID_ID != table_id && + (task_status >= ObDDLTaskStatus::PREPARE && + task_status <= ObDDLTaskStatus::SUCCESS) && + task_id > 0))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(schema_version), K(table_id), + K(task_status), K(task_id)); + } else if (OB_UNLIKELY( + (partition_split_arg.local_index_table_ids_.count() != + partition_split_arg.src_local_index_tablet_ids_.count()) && + (partition_split_arg.lob_table_ids_.count() != + partition_split_arg.src_lob_tablet_ids_.count()))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(partition_split_arg), + K(task_status), K(task_id)); + } else if (OB_FAIL(deep_copy_table_arg( + allocator_, partition_split_arg, partition_split_arg_))) { + LOG_WARN("failed to copy partition split arg", K(ret), K(partition_split_arg)); + } else if (OB_FAIL(ObShareUtil::fetch_current_data_version( + *GCTX.sql_proxy_, tenant_id, tenant_data_format_version))) { + LOG_WARN("failed to get min data version", K(ret), K(tenant_id)); + } else { + set_gmt_create(ObTimeUtility::current_time()); + start_time_ = ObTimeUtility::current_time(); + tenant_id_ = tenant_id; + dst_tenant_id_ = tenant_id_; + object_id_ = table_id; + target_object_id_ = partition_split_arg_.src_tablet_id_.id(); + schema_version_ = schema_version; + dst_schema_version_ = schema_version_; + parallelism_ = parallelism; + task_type_ = partition_split_arg_.task_type_; + task_id_ = task_id; + tablet_size_ = tablet_size; + parent_task_id_ = parent_task_id; + task_version_ = OB_PARTITION_SPLIT_TASK_VERSION; + task_status_ = static_cast(task_status); + execution_id_ = 1L; + data_format_version_ = tenant_data_format_version; + if (OB_FAIL(init_ddl_task_monitor_info(table_id))) { + LOG_WARN("init ddl task monitor info failed", K(ret)); + } else { + is_inited_ = true; + } + } + return ret; +} + +int ObPartitionSplitTask::init(const ObDDLTaskRecord &task_record) +{ + int ret = OB_SUCCESS; + const uint64_t table_id = task_record.object_id_; + const int64_t schema_version = task_record.schema_version_; + int64_t pos = 0; + if (!task_record.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(task_record)); + } else if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_ISNULL(root_service_ = GCTX.root_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("root_service is null", K(ret), KP(root_service_)); + } else if (!root_service_->in_service()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("root service not in service", K(ret)); + } else if (OB_FAIL(deserialize_params_from_message( + task_record.tenant_id_, + task_record.message_.ptr(), + task_record.message_.length(), + pos))) { + LOG_WARN("deserialize params from message failed", K(ret)); + } else { + tenant_id_ = task_record.tenant_id_; + dst_tenant_id_ = tenant_id_; + object_id_ = table_id; + target_object_id_ = partition_split_arg_.src_tablet_id_.id(); + schema_version_ = schema_version; + dst_schema_version_ = schema_version_; + task_type_ = task_record.ddl_type_; + execution_id_ = task_record.execution_id_; + task_id_ = task_record.task_id_; + parent_task_id_ = task_record.parent_task_id_; + task_status_ = static_cast(task_record.task_status_); + start_time_ = ObTimeUtility::current_time(); + if (OB_FAIL(init_ddl_task_monitor_info(object_id_))) { + LOG_WARN("init ddl task monitor info failed", K(ret), K(object_id_), K(task_record)); + } else { + is_inited_ = true; + } + } + return ret; +} + +int ObPartitionSplitTask::process() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObPartitionSplitTask has not been inited", K(ret)); + } else if (OB_FAIL(check_health())) { + LOG_WARN("check health failed", K(ret)); + } else if (!need_retry()) { + // bypass + } else { + const ObDDLTaskStatus status = static_cast(task_status_); + switch (status) { + case ObDDLTaskStatus::PREPARE: { + DEBUG_SYNC(PARTITION_SPLIT_PREPARE); + if (OB_FAIL(prepare(WAIT_FROZE_END))) { + LOG_WARN("prepare failed", K(ret), K(*this)); + } + break; + } + case ObDDLTaskStatus::WAIT_FROZE_END: { + if (OB_FAIL(wait_freeze_end(WAIT_COMPACTION_END))) { + LOG_WARN("wait memtable freeze end failed", K(ret), K(*this)); + } + break; + } + case ObDDLTaskStatus::WAIT_COMPACTION_END: { + if (OB_FAIL(wait_compaction_end(WRITE_SPLIT_START_LOG))) { + LOG_WARN("wait compaction end failed", K(ret), K(*this)); + } + break; + } + case ObDDLTaskStatus::WRITE_SPLIT_START_LOG: { + if (OB_FAIL(write_split_start_log(WAIT_DATA_TABLE_SPLIT_END))) { + LOG_WARN("write split start log failed", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_DATA_TABLE_SPLIT_END: { + if (OB_FAIL(wait_data_tablet_split_end(WAIT_LOCAL_INDEX_SPLIT_END))) { + LOG_WARN("wait data table split end failed", K(ret), K(*this)); + } + break; + } + case ObDDLTaskStatus::WAIT_LOCAL_INDEX_SPLIT_END: { + if (OB_FAIL(wait_local_index_tablet_split_end(WAIT_LOB_TABLE_SPLIT_END))) { + LOG_WARN("wait local index split end failed", K(ret), K(*this)); + } + break; + } + case ObDDLTaskStatus::WAIT_LOB_TABLE_SPLIT_END: { + if (OB_FAIL(wait_lob_tablet_split_end(WAIT_TRANS_END))) { + LOG_WARN("wait lob table split end failed", K(ret), K(*this)); + } + break; + } + case ObDDLTaskStatus::WAIT_TRANS_END: { + if (OB_FAIL(wait_trans_end(TAKE_EFFECT))) { + LOG_WARN("failed to wait trans end", K(ret)); + } + break; + } + case ObDDLTaskStatus::TAKE_EFFECT: { + if (OB_FAIL(take_effect(SUCCESS))) { + LOG_WARN("take effect failed", K(ret), K(*this)); + } + break; + } + case ObDDLTaskStatus::SUCCESS: { + if (OB_FAIL(succ())) { + LOG_WARN("clean task on finish failed", K(ret), K(*this)); + } + break; + } + case ObDDLTaskStatus::WAIT_PARTITION_SPLIT_RECOVERY_TASK_FINISH: { + if (OB_FAIL(wait_recovery_task_finish(SUCCESS))) { + LOG_WARN("fail to wait recovery task finish", K(ret), K(*this)); + } + break; + } + default: { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not expected status", K(ret), K(status), K(*this)); + break; + } + } // end switch + } + return ret; +} + +int ObPartitionSplitTask::prepare(const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + bool state_finished = false; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (ObDDLTaskStatus::PREPARE != task_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status not match", K(ret), K(task_status_)); + } else { + state_finished = true; + } + + if (state_finished) { + if (OB_FAIL(switch_status(next_task_status, true, ret))) { + LOG_WARN("failed to switch task status", K(ret)); + } + LOG_INFO("prepare finished", K(ret), K(*this)); + } + return ret; +} + +int ObPartitionSplitTask::wait_freeze_end( + const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + bool freeze_finished = false; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (ObDDLTaskStatus::WAIT_FROZE_END != task_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status not match", K(ret), K(task_status_)); + } else if (all_src_tablet_ids_.empty() && OB_FAIL(setup_src_tablet_ids_array())) { + LOG_WARN("failed to setup all src tablet ids array", K(ret)); + } else if (OB_FAIL(init_freeze_progress_map())) { + LOG_WARN("failed to setup freeze progress map", K(ret)); + } else { // check tablet freeze progress + if (OB_FAIL(check_freeze_progress(all_src_tablet_ids_, + freeze_finished))) { + LOG_WARN("check freeze end failed", K(ret)); + } else { + TCWLockGuard guard(lock_); + freeze_progress_status_inited_ = true; + } + } + if (OB_FAIL(ret)) { + } else if (freeze_finished) { + DEBUG_SYNC(PARTITION_SPLIT_WAIT_FREEZE_END); + if (OB_FAIL(switch_status(next_task_status, true, ret))) { + LOG_WARN("failed to switch task status", K(ret)); + } + LOG_INFO("wait freeze end finished", K(ret), K(*this)); + } + return ret; +} + +// check freeze progess of all replicas of this tablet +int ObPartitionSplitTask::check_freeze_progress( + const ObSArray &tablet_ids, + bool &is_end) +{ + int ret = OB_SUCCESS; + is_end = false; + int64_t num_tablet_finished = 0; + ObLocationService *location_service = nullptr; + ObArray request_tablet_ids; + const int64_t rpc_timeout = max(GCONF.rpc_timeout, 1000L * 1000L * 9L); + obrpc::ObSrvRpcProxy *rpc_proxy = GCTX.srv_rpc_proxy_; + ObCheckMemtableCntProxy check_memtable_cnt_proxy(*rpc_proxy, + &obrpc::ObSrvRpcProxy::check_memtable_cnt); + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); ++i) { + const ObTabletID &tablet_id = tablet_ids.at(i); + share::ObLSID ls_id; + ObAddr leader_addr; + if (OB_ISNULL(location_service = GCTX.location_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("location_cache is null", K(ret)); + } else if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(location_service, + tenant_id_, tablet_id, rpc_timeout, ls_id, leader_addr))) { + LOG_WARN("get tablet leader addr failed", K(ret)); + } else { + const ObCheckProgressKey check_progress_key(tenant_id_, tablet_id); + ObCheckProgressStatus freeze_status; + if (OB_FAIL(freeze_progress_map_.get_refactored( + check_progress_key, freeze_status))) { + LOG_WARN("failed to get addr freeze status", K(ret), K(leader_addr)); + } else if (freeze_status == ObCheckProgressStatus::NOT_STARTED || + freeze_status == ObCheckProgressStatus::ONGOING) { + // 1. send rpc to check freeze progress + obrpc::ObCheckMemtableCntArg arg; + arg.tenant_id_ = tenant_id_; + arg.ls_id_ = ls_id; + arg.tablet_id_ = tablet_id; + if (OB_FAIL(check_memtable_cnt_proxy.call(leader_addr, + rpc_timeout, tenant_id_, arg))) { + LOG_WARN("send rpc failed", K(ret), K(arg), K(leader_addr), K(tenant_id_)); + } else { + TCWLockGuard guard(lock_); + if (OB_FAIL(freeze_progress_map_.set_refactored(check_progress_key, + ObCheckProgressStatus::ONGOING, true/*overwrite*/))) { + LOG_WARN("failed to update addr freeze status", K(ret), K(leader_addr)); + } else if (OB_FAIL(request_tablet_ids.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret)); + } + } + } else if (freeze_status == ObCheckProgressStatus::DONE) { + ++num_tablet_finished; + } + } + } + // 2. collect rpc results + int tmp_ret = OB_SUCCESS; + common::ObArray ret_array; + if (OB_SUCCESS != (tmp_ret = check_memtable_cnt_proxy.wait_all(ret_array))) { + LOG_WARN("rpc proxy wait failed", K(tmp_ret)); + ret = OB_SUCCESS == ret ? tmp_ret : ret; + } else if (OB_SUCC(ret)) { + const ObIArray &result_array = + check_memtable_cnt_proxy.get_results(); + const int64_t num_rpc_requested = request_tablet_ids.count(); + if (ret_array.count() != num_rpc_requested || + result_array.count() != num_rpc_requested) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result count not match", K(ret), K(num_rpc_requested), + K(ret_array.count()), K(result_array.count())); + } else { + TCWLockGuard guard(lock_); + for (int64_t i = 0; OB_SUCC(ret) && i < result_array.count(); ++i) { + const obrpc::ObCheckMemtableCntResult *cur_result = result_array.at(i); + if (OB_FAIL(ret_array.at(i))) { + } else if (cur_result->memtable_cnt_ > 0) { + // NOT finished + } else if (cur_result->memtable_cnt_ == 0) { + const ObTabletID &tablet_id = request_tablet_ids.at(i); + const ObCheckProgressKey check_progress_key(tenant_id_, tablet_id); + if (OB_FAIL(freeze_progress_map_.set_refactored( + check_progress_key, ObCheckProgressStatus::DONE, true/*overwrite*/))) { + LOG_WARN("failed to update freeze status", K(ret)); + } else { + ++num_tablet_finished; + } + } + } + } + } + is_end = num_tablet_finished == tablet_ids.count() ? true : false; + return ret; +} + +int ObPartitionSplitTask::wait_compaction_end( + const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + int64_t num_tablet_finished = 0; + // TODO hanxuan grab mem lock + ObLSID ls_id; + ObAddr unused_addr; + ObArray split_replica_addrs; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (ObDDLTaskStatus::WAIT_COMPACTION_END != task_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status not match", K(ret), K(task_status_)); + } else if (all_src_tablet_ids_.empty() && OB_FAIL(setup_src_tablet_ids_array())) { + LOG_WARN("failed to setup all src tablet ids array", K(ret)); + } else if (OB_FAIL(init_tablet_compaction_scn_array())) { + LOG_WARN("failed to setup all src tablet compaction scn array", K(ret)); + } else if (OB_FAIL(init_compaction_scn_map())) { + LOG_WARN("failed to setup compaction scn map", K(ret)); + } else { // check tablet compaction progress + const ObTabletID &any_tablet_id = all_src_tablet_ids_.at(0); + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr( + GCTX.location_service_, tenant_id_, any_tablet_id, rpc_timeout, ls_id, unused_addr))) { + LOG_WARN("get ls id failed", K(ret), K(tenant_id_), K(any_tablet_id)); + } else if (OB_FAIL(ObDDLUtil::get_split_replicas_addrs(tenant_id_, ls_id, split_replica_addrs))) { + LOG_WARN("get split replica addrs failed", K(ret), K(tenant_id_), K(ls_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < all_src_tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = all_src_tablet_ids_.at(i); + bool current_tablet_finished = false; + if (OB_FAIL(check_compaction_progress(ls_id, tablet_id, split_replica_addrs, current_tablet_finished))) { + LOG_WARN("failed to check compaction progress", K(ret)); + } else if (current_tablet_finished) { + ++num_tablet_finished; + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(update_tablet_compaction_scn_array())) { + LOG_WARN("failed to update tablet compaction scn", K(ret)); + } else { + TCWLockGuard guard(lock_); + compact_progress_status_inited_ = true; + } + } + if (OB_FAIL(ret)) { + } else if (num_tablet_finished == all_src_tablet_ids_.count()) { + DEBUG_SYNC(PARTITION_SPLIT_WAIT_COMPACTION_END); + ObArray double_check_replica_addrs; + ObArray different_replica_addrs; + // double check. + if (OB_FAIL(ObDDLUtil::get_split_replicas_addrs(tenant_id_, ls_id, double_check_replica_addrs))) { + LOG_WARN("get split replica addrs failed", K(ret), K(tenant_id_), K(ls_id)); + } else if (double_check_replica_addrs.count() != split_replica_addrs.count()) { + ret = OB_EAGAIN; + LOG_INFO("need retry when double check failed", K(ret), K(split_replica_addrs), K(double_check_replica_addrs)); + } else if OB_FAIL(get_difference(split_replica_addrs, double_check_replica_addrs, different_replica_addrs)) { + LOG_WARN("get difference failed", K(ret)); + } else if (!different_replica_addrs.empty()) { + ret = OB_EAGAIN; + LOG_INFO("different replica addrs occur, need retry", K(ret), K(split_replica_addrs), K(double_check_replica_addrs)); + } else if (OB_FAIL(serialize_compaction_scn_to_task_record())) { + LOG_WARN("failed to serialize compaction scn to ddl task record", K(ret)); + } else if (OB_FAIL(switch_status(next_task_status, true, ret))) { + LOG_WARN("failed to switch task status", K(ret)); + } + LOG_INFO("wait compaction end finished", K(ret), K(*this)); + } + return ret; +} + +int ObPartitionSplitTask::check_compaction_progress( + const ObLSID &ls_id, + const ObTabletID &tablet_id, + const ObIArray &split_replica_addrs, + bool& is_end) +{ + int ret = OB_SUCCESS; + is_end = false; + obrpc::ObSrvRpcProxy *rpc_proxy = GCTX.srv_rpc_proxy_; + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + ObCheckMediumCompactionInfoListProxy compaction_check_proxy( + *rpc_proxy, &obrpc::ObSrvRpcProxy::check_medium_compaction_info_list_cnt); + if (OB_UNLIKELY(!ls_id.is_valid() || !tablet_id.is_valid() || split_replica_addrs.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_id), K(tablet_id), K(split_replica_addrs)); + } else if (OB_UNLIKELY(all_src_tablet_ids_.empty())) { + ret = OB_ERR_SYS; + LOG_WARN("unexpected null tablet ids", K(ret), KPC(this)); + } else if (!compaction_progress_map_.created() && OB_FAIL(compaction_progress_map_.create(all_src_tablet_ids_.count(), lib::ObLabel("DDLWaitCompact")))) { + LOG_WARN("failed to create compaction progress map", K(ret)); + } else { + int64_t compaction_end_number = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < split_replica_addrs.count(); i++) { + ObCheckProgressStatus compaction_status; + const common::ObAddr &replica_addr = split_replica_addrs.at(i); + const ObCheckProgressKey check_progress_key(replica_addr, tablet_id); + if (OB_FAIL(compaction_progress_map_.get_refactored(check_progress_key, compaction_status))) { + if (OB_HASH_NOT_EXIST == ret) { + // override ret. + TCWLockGuard guard(lock_); + if (OB_FAIL(compaction_progress_map_.set_refactored(check_progress_key, ObCheckProgressStatus::NOT_STARTED))) { + LOG_WARN("failed to set compaction progress", K(ret)); + } else { + compaction_status = ObCheckProgressStatus::NOT_STARTED; + } + } else { + LOG_WARN("failed to get from map", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (ObCheckProgressStatus::DONE != compaction_status) { + // check compaction status + obrpc::ObCheckMediumCompactionInfoListArg arg; + arg.tenant_id_ = tenant_id_; + arg.ls_id_ = ls_id; + arg.tablet_id_ = tablet_id; + int tmp_ret = OB_SUCCESS; + if (OB_FAIL(compaction_check_proxy.call(replica_addr, rpc_timeout, tenant_id_, arg))) { + LOG_WARN("send rpc failed", K(ret), K(tenant_id_), K(replica_addr), K(arg)); + } else if (OB_TMP_FAIL(compaction_check_proxy.wait())) { + LOG_WARN("rpc proxy wait failed", K(tmp_ret), K(arg)); + ret = tmp_ret; + } else { + const ObIArray &result_array = compaction_check_proxy.get_results(); + const obrpc::ObCheckMediumCompactionInfoListResult *result = result_array.at(0); + TCWLockGuard guard(lock_); + if (result->info_list_cnt_ > 0) { + if (OB_FAIL(compaction_progress_map_.set_refactored(check_progress_key, ObCheckProgressStatus::ONGOING, true/*overwrite*/))) { + LOG_WARN("failed to update compaction progress", K(ret), K(replica_addr)); + } + } else if (result->info_list_cnt_ == 0) { + int64_t existed_compaction_scn; + if (OB_FAIL(tablet_compaction_scn_map_.get_refactored(tablet_id, existed_compaction_scn))) { + if (OB_HASH_NOT_EXIST == ret) { + // override ret is expected. + if (OB_FAIL(tablet_compaction_scn_map_.set_refactored(tablet_id, result->primary_compaction_scn_))) { + LOG_WARN("failed to set tablet tablet's primary compaction scn", K(ret), K(tablet_id)); + } + } else { + LOG_WARN("get compaction scn from map failed", K(ret), K(tablet_id)); + } + } else if (OB_UNLIKELY(existed_compaction_scn != result->primary_compaction_scn_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unequal compaction scn between replicas", K(ret), K(tablet_id), K(replica_addr), K(existed_compaction_scn), K(result->primary_compaction_scn_)); + } else if (OB_FAIL(compaction_progress_map_.set_refactored(check_progress_key, ObCheckProgressStatus::DONE, true/*overwrite*/))) { + LOG_WARN("failed to update compaction progress", K(ret), K(replica_addr)); + } else { + compaction_end_number++; + } + } + } + } else { + compaction_end_number++; // compact done. + } + } + is_end = OB_SUCC(ret) && (compaction_end_number == split_replica_addrs.count()) ? true : false; + } + return ret; +} + +int ObPartitionSplitTask::write_split_start_log(const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + ObSEArray, 8> unused_rowkey_list; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(prepare_tablet_split_ranges(unused_rowkey_list))) { + LOG_WARN("prepare tablet split ranges failed", K(ret)); + } else if (all_src_tablet_ids_.empty() && OB_FAIL(setup_src_tablet_ids_array())) { + LOG_WARN("failed to setup all src tablet ids array", K(ret)); + } else if (OB_FAIL(init_send_finish_map())) { + LOG_WARN("failed to setup send finish map", K(ret)); + } else if (OB_FAIL(send_split_rpc(true/*is_split_start*/))) { + LOG_WARN("failed to send split start request", K(ret)); + } else { + { + TCWLockGuard guard(lock_); + write_split_log_status_inited_ = true; + } + ObArray not_finished_tablets; + hash::ObHashMap, ObCheckProgressStatus>::const_iterator iter = send_finish_map_.begin(); + for (; OB_SUCC(ret) && iter != send_finish_map_.end(); iter++) { + const ObCheckProgressKey &key = iter->first; + const ObCheckProgressStatus &status = iter->second; + if (ObCheckProgressStatus::DONE != status && OB_FAIL(not_finished_tablets.push_back(key.tablet_id_))) { + LOG_WARN("failed to push back", K(ret)); + } + } + if (OB_SUCC(ret)) { + if (not_finished_tablets.empty()) { + if (OB_FAIL(switch_status(next_task_status, true/*enable_flt_tracing*/, ret))) { + LOG_WARN("fail to switch task status", K(ret)); + } + } else { + LOG_INFO("dump not finished tablets", K(ret), K(not_finished_tablets)); + } + } + } + return ret; +} + +int ObPartitionSplitTask::wait_data_tablet_split_end( + const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + bool data_split_finished = false; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (ObDDLTaskStatus::WAIT_DATA_TABLE_SPLIT_END != task_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status not match", K(ret), K(task_status_)); + } else if (!replica_build_task_submit_) { + if (OB_FAIL(send_split_request( + ObPartitionSplitReplicaType::DATA_TABLET_REPLICA))) { + LOG_WARN("failed to send tablet split requeset", K(ret), + K(partition_split_arg_.src_tablet_id_)); + } + } else { + if (OB_FAIL(check_split_finished(data_split_finished))) { + LOG_WARN("failed to check tablet split progress", K(ret), + K(partition_split_arg_.src_tablet_id_)); + } + } + + if (OB_FAIL(ret)) { + } else if (data_split_finished) { + DEBUG_SYNC(PARTITION_SPLIT_WAIT_DATA_TABLET_SPLIT_END); + ret = replica_build_ret_code_; + reset_replica_build_stat(); + if (OB_FAIL(switch_status(next_task_status, true, ret))) { + LOG_WARN("fail to switch task status", K(ret)); + } + LOG_INFO("wait data tablet split end finished", K(ret), KPC(this)); + } + return ret; +} + +int ObPartitionSplitTask::send_split_request( + const ObPartitionSplitReplicaType replica_type) +{ + int ret = OB_SUCCESS; + SMART_VAR(ObDDLReplicaBuildExecutorParam, param) { + ObSchemaGetterGuard schema_guard; + param.tenant_id_ = tenant_id_; + param.dest_tenant_id_ = dst_tenant_id_; + param.ddl_type_ = task_type_; + param.snapshot_version_ = 1L; + param.task_id_ = task_id_; + param.parallelism_ = parallelism_; + param.execution_id_ = execution_id_; + param.data_format_version_ = data_format_version_; + param.consumer_group_id_ = partition_split_arg_.consumer_group_id_; + if (OB_ISNULL(root_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("error sys", K(ret)); + } else if (OB_FAIL(root_service_->get_ddl_service(). + get_tenant_schema_guard_with_version_in_inner_table(dst_tenant_id_, schema_guard))) { + LOG_WARN("get schema guard failed", K(ret)); + } else if (replica_type == ObPartitionSplitReplicaType::DATA_TABLET_REPLICA) { + if (OB_FAIL(param.source_table_ids_.push_back(object_id_))) { + LOG_WARN("fail to set src table id", K(ret)); + } else if (OB_FAIL(param.dest_table_ids_.push_back(object_id_))) { + LOG_WARN("fail to set dest table id", K(ret)); + } else if (OB_FAIL(param.source_schema_versions_.push_back(schema_version_))) { + LOG_WARN("fail to set src schema versions", K(ret)); + } else if (OB_FAIL(param.dest_schema_versions_.push_back(schema_version_))) { + LOG_WARN("fail to set dest schema versions", K(ret)); + } else if (OB_FAIL(param.source_tablet_ids_.push_back( + partition_split_arg_.src_tablet_id_))) { + LOG_WARN("failed to push_back tablet id array", K(ret)); + } else if (OB_FAIL(param.dest_tablet_ids_.push_back( + ObTabletID(ObTabletID::MIN_VALID_TABLET_ID)/*to make sure valid only*/))) { + LOG_WARN("failed to push_back tablet id array", K(ret)); + } else if (OB_FAIL(param.compaction_scns_.push_back( + data_tablet_compaction_scn_))) { + LOG_WARN("failed to push_back compaction scns", K(ret)); + } + } else if (replica_type == ObPartitionSplitReplicaType::LOCAL_INDEX_TABLET_REPLICA) { + ObSArray data_table_schema_versions; + for (int64_t i = 0; OB_SUCC(ret) && + i < partition_split_arg_.local_index_table_ids_.count(); ++i) { + if (OB_FAIL(data_table_schema_versions.push_back(schema_version_))) { + LOG_WARN("failed to push back data table schema version", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(param.source_table_ids_.assign( + partition_split_arg_.local_index_table_ids_))) { + LOG_WARN("fail to set src table id", K(ret)); + } else if (OB_FAIL(param.dest_table_ids_.assign( + partition_split_arg_.local_index_table_ids_))) { + LOG_WARN("fail to set dest table id", K(ret)); + } else if (OB_FAIL(param.source_schema_versions_.assign( + data_table_schema_versions))) { + LOG_WARN("fail to set src schema versions", K(ret)); + } else if (OB_FAIL(param.dest_schema_versions_.assign( + data_table_schema_versions))) { + LOG_WARN("fail to set dest schema versions", K(ret)); + } else if (OB_FAIL(param.source_tablet_ids_.assign( + partition_split_arg_.src_local_index_tablet_ids_))) { + LOG_WARN("failed to assign tablet id array", K(ret)); + } else if (OB_FAIL(param.dest_tablet_ids_.assign( + partition_split_arg_.src_local_index_tablet_ids_/*to make sure valid only*/))) { + LOG_WARN("failed to assign tablet id array", K(ret)); + } else if (OB_FAIL(param.compaction_scns_.assign( + index_tablet_compaction_scns_))) { + LOG_WARN("failed to assign compaction scns", K(ret)); + } + } else if (replica_type == ObPartitionSplitReplicaType::LOB_TABLET_REPLICA) { + ObSArray data_table_ids; + ObSArray data_table_schema_versions; + for (int64_t i = 0; OB_SUCC(ret) && + i < partition_split_arg_.lob_table_ids_.count(); ++i) { + if (OB_FAIL(data_table_ids.push_back(object_id_))) { + LOG_WARN("failed to push back data table id", K(ret)); + } else if (OB_FAIL(data_table_schema_versions.push_back(schema_version_))) { + LOG_WARN("failed to push back data table schema version", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(param.source_table_ids_.assign(data_table_ids))) { + LOG_WARN("fail to set src table id", K(ret)); + } else if (OB_FAIL(param.dest_table_ids_.assign( + partition_split_arg_.lob_table_ids_))) { + LOG_WARN("fail to set dest table id", K(ret)); + } else if (OB_FAIL(param.source_schema_versions_.assign( + data_table_schema_versions))) { + LOG_WARN("fail to set src schema versions", K(ret)); + } else if (OB_FAIL(param.dest_schema_versions_.assign( + partition_split_arg_.lob_schema_versions_))) { + LOG_WARN("fail to set dest schema versions", K(ret)); + } else if (OB_FAIL(param.source_tablet_ids_.assign( + partition_split_arg_.src_lob_tablet_ids_))) { + LOG_WARN("failed to assign tablet id array", K(ret)); + } else if (OB_FAIL(param.dest_tablet_ids_.assign( + partition_split_arg_.src_lob_tablet_ids_/*to make sure valid only*/))) { + LOG_WARN("failed to assign tablet id array", K(ret)); + } else if (OB_FAIL(param.compaction_scns_.assign( + lob_tablet_compaction_scns_))) { + LOG_WARN("failed to assign compaction scns", K(ret)); + } else if (OB_FAIL(setup_lob_idxs_arr(param.lob_col_idxs_))) { + LOG_WARN("failed to setup lob col idxs array", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(prepare_tablet_split_ranges(param.parallel_datum_rowkey_list_))) { + LOG_WARN("prepare tablet split ranges failed", K(ret)); + } else if (OB_FAIL(check_can_reuse_macro_block(schema_guard, + dst_tenant_id_, param.source_table_ids_, param.can_reuse_macro_blocks_))) { + LOG_WARN("check can reuse macro block failed", K(ret)); + } else if (OB_FAIL(replica_builder_.build(param))) { + LOG_WARN("fail to send build single replica", K(ret)); + } else { + LOG_INFO("start to build single replica", K(param)); + TCWLockGuard guard(lock_); + replica_build_task_submit_ = true; + replica_build_request_time_ = ObTimeUtility::current_time(); + } + } // smart_var + return ret; +} + +int ObPartitionSplitTask::update_complete_sstable_job_status( + const ObTabletID &tablet_id, + const ObAddr &svr, + const int64_t execution_id, + const int ret_code, + const ObDDLTaskInfo &addition_info) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObPartitionSplitTask has not been inited", K(ret)); + } else if (!tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tablet_id)); + } else if (!(ObDDLTaskStatus::WAIT_DATA_TABLE_SPLIT_END <= task_status_ + && ObDDLTaskStatus::WAIT_LOB_TABLE_SPLIT_END >= task_status_)) { + // by pass, may be network delay + } else if (execution_id < execution_id_) { + LOG_INFO("receive a mismatch execution result, ignore", K(ret_code), + K(execution_id), K(execution_id_)); + } else if (OB_FAIL(replica_builder_.update_build_progress(tablet_id, svr, + ret_code, addition_info.row_scanned_, addition_info.row_inserted_, addition_info.physical_row_count_))) { + LOG_WARN("fail to update replica build status", K(ret)); + } + return ret; +} + +int ObPartitionSplitTask::check_split_finished(bool &is_end) +{ + int ret = OB_SUCCESS; + is_end = false; + if (OB_FAIL(replica_builder_.check_build_end(false/*need checksum*/, is_end, replica_build_ret_code_))) { + LOG_WARN("failed to check build end", K(ret)); + } else if (!is_end) { + if (replica_build_request_time_ + OB_MAX_DDL_SINGLE_REPLICA_BUILD_TIMEOUT < + ObTimeUtility::current_time()) { + // timeout, retry + TCWLockGuard guard(lock_); + replica_build_task_submit_ = false; + replica_build_request_time_ = 0; + } + } + return ret; +} + +int ObPartitionSplitTask::wait_local_index_tablet_split_end( + const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + bool local_index_split_finished = false; + const uint64_t data_table_id = object_id_; + const ObSArray &index_tablet_ids = partition_split_arg_.src_local_index_tablet_ids_; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (ObDDLTaskStatus::WAIT_LOCAL_INDEX_SPLIT_END != task_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status not match", K(ret), K(task_status_)); + } else if (index_tablet_compaction_scns_.count() != index_tablet_ids.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("compaction scn array count mismatch index tablet array", + K(index_tablet_compaction_scns_.count()), K(index_tablet_ids.count())); + } else if (index_tablet_ids.count() == 0) { + local_index_split_finished = true; + } else if (!replica_build_task_submit_) { + if (OB_FAIL(send_split_request( + ObPartitionSplitReplicaType::LOCAL_INDEX_TABLET_REPLICA))) { + LOG_WARN("failed to send tablet split requeset", K(ret), + K(partition_split_arg_.src_local_index_tablet_ids_)); + } + } else { + if (OB_FAIL(check_split_finished(local_index_split_finished))) { + LOG_WARN("failed to check tablet split progress", K(ret), + K(partition_split_arg_.src_local_index_tablet_ids_)); + } + } + + if (OB_FAIL(ret)) { + } else if (local_index_split_finished) { + DEBUG_SYNC(PARTITION_SPLIT_WAIT_LOCAL_INDEX_SPLIT_END); + ret = replica_build_ret_code_; + reset_replica_build_stat(); + /* if (OB_SUCC(ret) && OB_FAIL(check_local_index_checksum())) { */ + /* LOG_WARN("checksum failed", K(ret), K(*this)); */ + /* } */ + if (OB_FAIL(switch_status(next_task_status, true, ret))) { + LOG_WARN("failed to switch task status", K(ret)); + } + LOG_INFO("wait local index split end finished", K(ret), K(*this)); + } + return ret; +} + +int ObPartitionSplitTask::check_local_index_checksum() +{ + int ret = OB_SUCCESS; + const uint64_t data_table_id = object_id_; + ObSchemaGetterGuard schema_guard; + const ObTableSchema *table_schema = nullptr; + bool checksum_passed = false; + int64_t index_checksum_pass_cnt = 0; + if (partition_split_arg_.src_local_index_tablet_ids_.empty()) { + // do nothing + } else if (OB_FAIL(root_service_->get_ddl_service(). + get_tenant_schema_guard_with_version_in_inner_table( + tenant_id_, schema_guard))) { + LOG_WARN("get schema guard failed", K(ret)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, data_table_id, + table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("error unexpected, table schema must not be nullptr", K(ret), + K(data_table_id)); + } else { + const common::ObIArray &index_infos = + table_schema->get_simple_index_infos(); + ObArray ignore_col_ids; + for (int64_t i = 0; OB_SUCC(ret) && i < index_infos.count(); ++i) { + const ObAuxTableMetaInfo &index_info = index_infos.at(i); + const uint64_t index_table_id = index_info.table_id_; + bool dummy_equal = false; + if (OB_FAIL(ObDDLChecksumOperator::check_column_checksum( + tenant_id_, + get_execution_id(), + data_table_id, + index_table_id, + task_id_, + true/*check unique index*/, + ignore_col_ids, + dummy_equal, + root_service_->get_sql_proxy()))) { + LOG_WARN("checksum check failed", K(ret), K(data_table_id), K(index_table_id)); + } + } + } + return ret; +} + +int ObPartitionSplitTask::setup_lob_idxs_arr(ObSArray &lob_col_idxs) +{ + int ret = OB_SUCCESS; + lob_col_idxs.reuse(); + const uint64_t table_id = object_id_; + ObSchemaGetterGuard schema_guard; + const ObTableSchema *table_schema = nullptr; + ObArray all_column_ids; + ObMultiVersionSchemaService &schema_service = ObMultiVersionSchemaService::get_instance(); + if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id_, schema_guard))) { + LOG_WARN("get tenant schema guard failed", K(ret)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, table_id, + table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("error unexpected, table schema must not be nullptr", K(ret), + K(table_id)); + } else if (OB_FAIL(table_schema->get_store_column_ids(all_column_ids))) { + LOG_WARN("failed to get column ids", K(ret), K(table_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < all_column_ids.count(); ++i) { + if (all_column_ids.at(i).col_type_.is_lob_storage() && + OB_FAIL(lob_col_idxs.push_back(i))) { + LOG_WARN("failed to push back lob idx", K(ret)); + } + } + return ret; +} + +int ObPartitionSplitTask::wait_lob_tablet_split_end( + const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + bool is_lob_split_finished = false; + const uint64_t data_table_id = object_id_; + ObSArray &lob_tablet_ids = partition_split_arg_.src_lob_tablet_ids_; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (ObDDLTaskStatus::WAIT_LOB_TABLE_SPLIT_END != task_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status not match", K(ret), K(task_status_)); + } else if (lob_tablet_compaction_scns_.count() != lob_tablet_ids.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob tablet compaction scn array count mismatch lob tablet ids array", + K(ret), K(lob_tablet_compaction_scns_.count()), K(lob_tablet_ids.count())); + } else if (lob_tablet_ids.count() == 0) { + is_lob_split_finished = true; + } else if (!replica_build_task_submit_) { + if (OB_FAIL(send_split_request( + ObPartitionSplitReplicaType::LOB_TABLET_REPLICA))) { + LOG_WARN("failed to send tablet split requeset", K(ret), + K(partition_split_arg_.src_lob_tablet_ids_)); + } + } else { + if (OB_FAIL(check_split_finished(is_lob_split_finished))) { + LOG_WARN("failed to check tablet split progress", K(ret), + K(partition_split_arg_.src_lob_tablet_ids_)); + } + } + + if (OB_FAIL(ret)) { + } else if (is_lob_split_finished) { + DEBUG_SYNC(PARTITION_SPLIT_WAIT_LOB_TABLET_SPLIT_END); + ret = replica_build_ret_code_; + reset_replica_build_stat(); + if (OB_FAIL(switch_status(next_task_status, true, ret))) { + LOG_WARN("failed to switch task status", K(ret)); + } + LOG_INFO("wait lob split end finished", K(ret), K(*this)); + } + return ret; +} + +int ObPartitionSplitTask::wait_trans_end(const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + ObDDLTaskStatus new_status = task_status_; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObConstraintTask has not been inited", K(ret)); + } else if (ObDDLTaskStatus::WAIT_TRANS_END != task_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status not match", K(ret), K(task_status_)); + } else if (snapshot_version_ > 0) { + new_status = next_task_status; + } + + if (OB_SUCC(ret) && new_status != next_task_status && !wait_trans_ctx_.is_inited()) { + if (OB_FAIL(wait_trans_ctx_.init(tenant_id_, task_id_, object_id_, all_src_tablet_ids_, ObDDLWaitTransEndCtx::WaitTransType::WAIT_SCHEMA_TRANS, schema_version_))) { + LOG_WARN("init wait trans ctx failed", K(ret)); + } + } + + if (OB_SUCC(ret) && new_status != next_task_status && snapshot_version_ <= 0) { + bool is_trans_end = false; + if (OB_FAIL(wait_trans_ctx_.try_wait(is_trans_end, snapshot_version_))) { + LOG_WARN("try wait transaction failed", K(ret)); + } + } + + if (OB_SUCC(ret) && new_status != next_task_status && snapshot_version_ > 0) { + if (OB_FAIL(ObDDLTaskRecordOperator::update_snapshot_version(root_service_->get_sql_proxy(), + tenant_id_, + task_id_, + snapshot_version_))) { + LOG_WARN("update snapshot version failed", K(ret), K(task_id_)); + } else { + new_status = next_task_status; + } + } + DEBUG_SYNC(PARTITION_SPLIT_WAIT_TRANS_END); + if (OB_FAIL(switch_status(new_status, true, ret))) { + // overwrite ret. + LOG_WARN("switch status failed", K(ret)); + } + return ret; +} + +int ObPartitionSplitTask::take_effect( + const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (ObDDLTaskStatus::TAKE_EFFECT != task_status_) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("task status not match", K(ret), K(task_status_)); + } else if (all_src_tablet_ids_.empty() && OB_FAIL(setup_src_tablet_ids_array())) { + LOG_WARN("failed to setup all src tablet ids array", K(ret)); + } else if (OB_FAIL(init_send_finish_map())) { + LOG_WARN("failed to setup send finish map", K(ret)); + } else if (OB_FAIL(send_split_rpc(false/*is_split_start*/))) { + LOG_WARN("failed to send split finish to all tablets", K(ret)); + } else if (OB_FAIL(sync_stats_info())) { + LOG_WARN("failed to update stat", K(ret), K(*this)); + } else { + DEBUG_SYNC(PARTITION_SPLIT_TAKE_EFFECT); + if (OB_FAIL(switch_status(next_task_status, true, ret))) { + LOG_WARN("failed to switch task status", K(ret)); + } + LOG_INFO("take effect finished", K(ret), K(*this)); + } + return ret; +} + +int ObPartitionSplitTask::get_src_tablet_ids(ObIArray &src_ids) +{ + int ret = OB_SUCCESS; + src_ids.reset(); + if (OB_FAIL(src_ids.push_back(partition_split_arg_.src_tablet_id_))) { + LOG_WARN("failed to push back tablet id", K(ret), K(partition_split_arg_.src_tablet_id_)); + } + return ret; +} + +int ObPartitionSplitTask::get_dest_tablet_ids(ObIArray &dest_ids) +{ + int ret = OB_SUCCESS; + dest_ids.reset(); + for (int64_t i = 0; OB_SUCC(ret) && i < partition_split_arg_.dest_tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = partition_split_arg_.dest_tablet_ids_.at(i); + if (OB_FAIL(dest_ids.push_back(tablet_id))) { + LOG_WARN("failed to push back tablet id", K(ret), K(tablet_id)); + } + } + return ret; +} + +int ObPartitionSplitTask::get_all_dest_tablet_ids( + const ObTabletID &source_tablet_id, + ObArray &dest_ids) +{ + int ret = OB_SUCCESS; + dest_ids.reset(); + if (source_tablet_id == partition_split_arg_.src_tablet_id_) { + if (OB_FAIL(dest_ids.push_back(partition_split_arg_.dest_tablet_ids_))) { + LOG_WARN("push back failed", K(ret)); + } + } + if (OB_SUCC(ret)) { + const ObSArray &index_tablet_ids = partition_split_arg_.src_local_index_tablet_ids_; + for (int64_t i = 0; OB_SUCC(ret) && dest_ids.empty() && i < index_tablet_ids.count(); ++i) { + if (source_tablet_id == index_tablet_ids.at(i)) { + if (OB_FAIL(dest_ids.push_back(partition_split_arg_.dest_local_index_tablet_ids_.at(i)))) { + LOG_WARN("push back failed", K(ret)); + } + } + } + } + + if (OB_SUCC(ret)) { + const ObSArray &lob_tablet_ids = partition_split_arg_.src_lob_tablet_ids_; + for (int64_t i = 0; OB_SUCC(ret) && dest_ids.empty() && i < lob_tablet_ids.count(); ++i) { + if (source_tablet_id == lob_tablet_ids.at(i)) { + if (OB_FAIL(dest_ids.push_back(partition_split_arg_.dest_lob_tablet_ids_.at(i)))) { + LOG_WARN("push back failed", K(ret)); + } + } + } + } + + if (OB_SUCC(ret) && OB_UNLIKELY(dest_ids.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err, can not find dest tablet ids", K(ret), K(source_tablet_id), K(partition_split_arg_)); + } + return ret; +} + +int ObPartitionSplitTask::setup_split_finish_items( + ObAddr &leader_addr, + ObIArray &split_info_array) +{ + int ret = OB_SUCCESS; + leader_addr.reset(); + split_info_array.reset(); + ObLSID ls_id; + ObArray tmp_split_info_array; + ObLocationService *location_service = nullptr; + const int64_t rpc_timeout = max(GCONF.rpc_timeout, 1000L * 1000L * 9L); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(location_service = GCTX.location_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("location_cache is null", K(ret)); + } else if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(location_service, + tenant_id_, partition_split_arg_.src_tablet_id_, rpc_timeout, ls_id, leader_addr))) { + LOG_WARN("get tablet leader addr failed", K(ret), "tablet_id", partition_split_arg_.src_tablet_id_); + } else if (OB_FAIL(prepare_tablet_split_infos(ls_id, leader_addr, tmp_split_info_array))) { + LOG_WARN("prepare tablet split infos failed", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tmp_split_info_array.count(); ++i) { + ObCheckProgressStatus send_status; + const obrpc::ObTabletSplitArg &each_arg = tmp_split_info_array.at(i); + const ObTabletID &tablet_id = each_arg.source_tablet_id_; + ObCheckProgressKey check_progress_key(tenant_id_, tablet_id); + if (OB_FAIL(send_finish_map_.get_refactored(check_progress_key, send_status))) { + LOG_WARN("failed to get progress", K(ret)); + } else if (send_status == ObCheckProgressStatus::NOT_STARTED || + send_status == ObCheckProgressStatus::ONGOING) { // need call rpc. + if (OB_FAIL(split_info_array.push_back(each_arg))) { + LOG_WARN("push back failed", K(ret)); + } + } else if (send_status == ObCheckProgressStatus::DONE) { // already call rpc. + // do nothing. + } + } + } + return ret; +} + +int ObPartitionSplitTask::send_split_rpc( + const bool is_split_start) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObAddr leader_addr; + const int64_t rpc_timeout = max(GCONF.rpc_timeout, 1000L * 1000L * 30L); + ObTabletSplitStartArg start_arg; + ObTabletSplitStartResult start_result; + ObTabletSplitFinishArg finish_arg; + ObTabletSplitFinishResult finish_result; + obrpc::ObSrvRpcProxy *rpc_proxy = GCTX.srv_rpc_proxy_; + ObIArray &target_split_info_array = is_split_start ? start_arg.split_info_array_ : finish_arg.split_info_array_; + if (OB_FAIL(setup_split_finish_items(leader_addr, target_split_info_array))) { + LOG_WARN("failed to setup split finish items", K(ret)); + } else if (target_split_info_array.empty()) { // already all sent. + LOG_TRACE("already all sent", K(ret)); // do nothing. + } else if (OB_ISNULL(rpc_proxy)) { + ret = OB_ERR_SYS; + LOG_WARN("srv_rpc_proxy is null", K(ret)); + } else if (is_split_start) { + if (OB_TMP_FAIL(rpc_proxy->to(leader_addr).by(tenant_id_).timeout(rpc_timeout) + .build_split_tablet_data_start_request(start_arg, start_result))) { + LOG_WARN("failed to freeze src tablet", K(ret), K(tmp_ret), K(leader_addr)); + } + } else { + if (OB_TMP_FAIL(rpc_proxy->to(leader_addr).by(tenant_id_).timeout(rpc_timeout) + .build_split_tablet_data_finish_request(finish_arg, finish_result))) { + LOG_WARN("failed to freeze src tablet", K(ret), K(tmp_ret), K(leader_addr)); + } + } + + // overwrite ret of rpc call function is expected. + const ObIArray &resp_ret_codes = is_split_start ? start_result.ret_codes_ : finish_result.ret_codes_; + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(target_split_info_array.count() < resp_ret_codes.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mismatched rpc request and response count", K(ret), K(target_split_info_array), K(resp_ret_codes)); + } else if (!resp_ret_codes.empty()) { + if (OB_UNLIKELY(resp_ret_codes.count() > target_split_info_array.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(target_split_info_array), K(resp_ret_codes)); + } else { + TCWLockGuard guard(lock_); + for (int64_t i = 0; OB_SUCC(ret) && i < resp_ret_codes.count(); i++) { + const ObTabletID &tablet_id = target_split_info_array.at(i).source_tablet_id_; + if (OB_SUCCESS == resp_ret_codes.at(i)) { + ObCheckProgressKey check_progress_key(tenant_id_, tablet_id); + if (OB_FAIL(send_finish_map_.set_refactored(check_progress_key, ObCheckProgressStatus::DONE, true /*overwrite*/))) { + LOG_WARN("failed to set finish map for tablet", K(ret), K(tablet_id)); + } + } else { + LOG_WARN("process split finish request failed, need retry", "resp_ret", resp_ret_codes.at(i), K(tablet_id)); + } + } + } + } + return ret; +} + +bool ObPartitionSplitTask::check_need_sync_stats() +{ + return !has_synced_stats_info_; +} + + +int ObPartitionSplitTask::delete_stat_info(common::ObMySQLTransaction &trans, + const char *table_name, + const uint64_t table_id, + const uint64_t src_part_id) +{ + int ret = OB_SUCCESS; + int64_t affected_rows = 0; + ObSqlString sql_string; + // pre-check + if (OB_ISNULL(table_name) || OB_INVALID_ID == table_id || OB_INVALID_PARTITION_ID == src_part_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("parameter invalid", K(ret), KP(table_name), K(table_id), K(src_part_id)); + } else if (OB_FAIL(sql_string.assign_fmt("DELETE FROM %s " + " WHERE tenant_id = %ld and table_id = %ld and partition_id = %ld;", + table_name, 0l /*tenant_id*/, table_id, src_part_id))) { + LOG_WARN("failed to assign sql string", K(ret), K(table_name), K(table_id), K(src_part_id)); + } else if (OB_FAIL(trans.write(tenant_id_, sql_string.ptr(), affected_rows))) { + LOG_WARN("failed to delete source_partition information from ", K(ret), K(sql_string)); + } else if (OB_UNLIKELY(affected_rows < 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected affected_rows", K(ret), K(affected_rows)); + } + return ret; +} + +int ObPartitionSplitTask::delete_src_part_stat_info(const uint64_t table_id, + const int64_t src_part_id, + const ObIArray &local_index_table_ids, + const ObIArray &src_local_index_part_ids) +{ + int ret = OB_SUCCESS; + if (local_index_table_ids.count() != src_local_index_part_ids.count()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("size mismatch of local_index_table_ids and src_local_index_part_ids", K(ret), K(local_index_table_ids), K(local_index_table_ids)); + } else if (OB_INVALID_ID == table_id || OB_INVALID_ID == src_part_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("parameter invalid", K(ret), K(table_id), K(src_part_id)); + } else { + common::ObMySQLTransaction trans; + if (OB_FAIL(trans.start(&root_service_->get_sql_proxy(), tenant_id_))) { + LOG_WARN("fail to start transaction", K(ret)); + } else if (OB_FAIL(delete_stat_info(trans, OB_ALL_TABLE_STAT_TNAME, table_id, src_part_id))) { + LOG_WARN("failed to delete the data of source partition from ", K(ret), K(OB_ALL_TABLE_STAT_TNAME)); + } else if (OB_FAIL(delete_stat_info(trans, OB_ALL_COLUMN_STAT_TNAME, table_id, src_part_id))) { + LOG_WARN("failed to delete the data of source partition from ", K(ret), K(OB_ALL_COLUMN_STAT_TNAME)); + } else if (OB_FAIL(delete_stat_info(trans, OB_ALL_HISTOGRAM_STAT_TNAME, table_id, src_part_id))) { + LOG_WARN("failed to delete the data of source partition from ", K(ret), K(OB_ALL_HISTOGRAM_STAT_TNAME)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < src_local_index_part_ids.count(); i++) { + if (OB_INVALID_ID == local_index_table_ids.at(i) || OB_INVALID_ID == src_local_index_part_ids.at(i)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("parameter invalid", K(ret), K(local_index_table_ids.at(i)), K(src_local_index_part_ids.at(i))); + } else if (OB_FAIL(delete_stat_info(trans, OB_ALL_TABLE_STAT_TNAME, local_index_table_ids.at(i), src_local_index_part_ids.at(i)))) { + LOG_WARN("failed to delete the data of source local index partition from ", K(ret), K(OB_ALL_TABLE_STAT_TNAME)); + } + } + } + // commit the transaction + if (trans.is_started()) { + bool is_commit = (ret == OB_SUCCESS); + int tmp_ret = trans.end(is_commit); + if (OB_SUCCESS != tmp_ret) { + LOG_WARN("fail to end trans", K(ret), K(is_commit)); + if (OB_SUCC(ret)) { + ret = tmp_ret; + } + } else { + has_synced_stats_info_ = (ret == OB_SUCCESS); + } + } + } + + return ret; +} + +int ObPartitionSplitTask::init_sync_stats_info(const ObTableSchema* const table_schema, + ObSchemaGetterGuard &schema_guard, + int64_t &src_partition_id, /* OUTPUT */ + ObSArray &src_local_index_partition_ids /* OUTPUT */) +{ + // get necessary information: src_partition_id and src_local_index_partition_ids + int ret = OB_SUCCESS; + if (OB_ISNULL(table_schema)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("table_schema is nullptr", K(ret)); + } else if (OB_FAIL(table_schema->get_hidden_part_id_by_tablet_id(partition_split_arg_.src_tablet_id_, src_partition_id))) { + LOG_WARN("fail to get partition info by src tablet id", K(ret)); + } else if (OB_INVALID_PARTITION_ID == src_partition_id) { + /* + during clean_splitted_tablet or after clean_splitted_tablet, a follower become the leader, this task maybe restart. + But all/part of the involving src tablets had been cleaned before, thus the hidden partition id maybe OB_INVALID_PARTITION_ID. + It is not unexpected. + If one hidden part'id is OB_INVALID_PARTITION_ID, it means we had finished the stats_info_sync job. + Therefore we set has_synced_stats_info_ as true. + */ + ret = OB_ENTRY_NOT_EXIST; + has_synced_stats_info_ = true; + LOG_WARN("src local data partition id is invalid, due to the partition_split_task had been processed before", + K(ret), K(partition_split_arg_.src_tablet_id_.id()), KPC(this)); + } else if (OB_UNLIKELY(partition_split_arg_.src_local_index_tablet_ids_.count() != partition_split_arg_.local_index_table_ids_.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("src_local_index_tablet_ids_.count != local_index_table_ids_.count", K(ret), + K(partition_split_arg_.src_local_index_tablet_ids_.count()), K(partition_split_arg_.local_index_table_ids_.count())); + } else if (OB_FAIL(src_local_index_partition_ids.prepare_allocate(partition_split_arg_.src_local_index_tablet_ids_.count()))) { + LOG_WARN("fail to prepare_allocate src_local_index_partition_ids", K(ret), K(partition_split_arg_.src_local_index_tablet_ids_.count())); + } else { + // get info of the src_local_index_partition_ids + for (int64_t i = 0; OB_SUCC(ret) && i < partition_split_arg_.local_index_table_ids_.count(); i++) { + uint64_t index_table_id = partition_split_arg_.local_index_table_ids_.at(i); + const ObTableSchema *index_table_schema = nullptr; + // get the index_table_schema and get the src_local_index_part_id + if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, index_table_id, index_table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_ISNULL(index_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("error unexpected, table schema must not be nullptr", K(ret), K(index_table_id)); + } else if (OB_FAIL(index_table_schema->get_hidden_part_id_by_tablet_id(partition_split_arg_.src_local_index_tablet_ids_.at(i), + src_local_index_partition_ids.at(i)))) { + LOG_WARN("fail to get partition info via tablet id", K(ret), K(i), K(partition_split_arg_.src_local_index_tablet_ids_.at(i).id())); + } else if (OB_INVALID_PARTITION_ID == src_local_index_partition_ids.at(i)) { + ret = OB_ERR_UNEXPECTED; // get the hidden_part_id of src data tablet success, but failed at local index, thus unexpected. + LOG_WARN("unexpected: src local index partition id is invalid", + K(ret), K(i), K(partition_split_arg_.src_local_index_tablet_ids_.at(i).id()), KPC(this)); + } + } + } + return ret; +} + +int ObPartitionSplitTask::sync_stats_info() +{ + int ret = OB_SUCCESS; + if (check_need_sync_stats()) { + const uint64_t data_table_id = object_id_; + int64_t src_partition_id = 0; + ObSArray src_local_index_partition_ids; + src_local_index_partition_ids.reset(); + { + const ObTableSchema *data_table_schema = nullptr; + ObSchemaGetterGuard schema_guard; + if (OB_FAIL(root_service_->get_schema_service().get_tenant_schema_guard(tenant_id_, schema_guard))) { + LOG_WARN("get schema guard failed", K(ret)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, data_table_id, data_table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_ISNULL(data_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("error unexpected, table schema must not be nullptr", K(ret), K(data_table_id)); + } else if (OB_FAIL(init_sync_stats_info(data_table_schema, schema_guard, src_partition_id, src_local_index_partition_ids))) { + LOG_WARN("failed to init the necessary info, like part_ids", K(ret)); + } + } + if (OB_FAIL(ret)) { + if (has_synced_stats_info_ && OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } + } else if (OB_FAIL(delete_src_part_stat_info(data_table_id, src_partition_id, partition_split_arg_.local_index_table_ids_, src_local_index_partition_ids))) { + LOG_WARN("failed to delete the info of source partition from tables ", K(ret)); + } + } + return ret; +} + +int ObPartitionSplitTask::succ() +{ + int ret = OB_SUCCESS; + return cleanup(); +} + +int ObPartitionSplitTask::wait_recovery_task_finish(const share::ObDDLTaskStatus next_task_status) +{ + int ret = OB_SUCCESS; + ObSchemaGetterGuard schema_guard; + const ObTableSchema *orig_table_schema = nullptr; + const ObTableSchema *orig_data_table_schema = nullptr; + const ObDatabaseSchema *database_schema = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObPartitionSplitTask has not been inited", K(ret)); + } else if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(tenant_id_, schema_guard))) { + LOG_WARN("get schema guard failed", K(ret), K(tenant_id_)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, object_id_, orig_table_schema))) { + LOG_WARN("get data table schema failed", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_ISNULL(orig_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, orig table schema is nullptr", K(ret)); + } else if (OB_FAIL(schema_guard.get_database_schema(tenant_id_, orig_table_schema->get_database_id(), database_schema))) { + LOG_WARN("get database schema failed", K(ret), K(tenant_id_)); + } else if (OB_ISNULL(database_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, database schema is nullptr", K(ret)); + } else if (orig_table_schema->is_global_index_table()) { + if (OB_FAIL(schema_guard.get_table_schema(tenant_id_, orig_table_schema->get_data_table_id(), orig_data_table_schema))) { + LOG_WARN("get data table schema failed", K(ret), K(tenant_id_), K(orig_table_schema->get_data_table_id())); + } else if (OB_ISNULL(orig_data_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, orig data table schema is nullptr", K(ret)); + } + } else { + orig_data_table_schema = orig_table_schema; + } + if (OB_SUCC(ret)) { + if (OB_INVALID_ID == orig_data_table_schema->get_association_table_id()) { + SMART_VAR(obrpc::ObAlterTableArg, alter_table_arg) { + int64_t ddl_rpc_timeout = 0; + ObSArray unused_ids; + ObRootService *root_service = GCTX.root_service_; + alter_table_arg.ddl_task_type_ = share::PARTITION_SPLIT_RECOVERY_TASK; + alter_table_arg.exec_tenant_id_ = tenant_id_; + alter_table_arg.table_id_ = orig_data_table_schema->get_table_id(); + alter_table_arg.task_id_ = task_id_; + alter_table_arg.is_inner_ = true; + alter_table_arg.parallelism_ = parallelism_; + alter_table_arg.consumer_group_id_ = partition_split_arg_.consumer_group_id_; + alter_table_arg.tz_info_wrap_.set_tz_info_offset(0); + alter_table_arg.nls_formats_[ObNLSFormatEnum::NLS_DATE] = ObTimeConverter::COMPAT_OLD_NLS_DATE_FORMAT; + alter_table_arg.nls_formats_[ObNLSFormatEnum::NLS_TIMESTAMP] = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_FORMAT; + alter_table_arg.nls_formats_[ObNLSFormatEnum::NLS_TIMESTAMP_TZ] = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_TZ_FORMAT; + AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; + if (OB_FAIL(alter_table_schema.assign(*orig_data_table_schema))) { + LOG_WARN("assign table schema failed", K(ret)); + } else { + alter_table_schema.set_tenant_id(tenant_id_); + alter_table_schema.set_origin_database_name(database_schema->get_database_name_str()); + alter_table_schema.set_origin_table_name(orig_data_table_schema->get_table_name_str()); + ObTZMapWrap tz_map_wrap; + if (OB_FAIL(OTTZ_MGR.get_tenant_tz(tenant_id_, tz_map_wrap))) { + LOG_WARN("get tenant timezone map failed", K(ret), K(tenant_id_)); + } else if (FALSE_IT(alter_table_arg.set_tz_info_map(tz_map_wrap.get_tz_map()))) { + } else if (OB_ISNULL(root_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, root service must not be nullptr", K(ret)); + } else if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(tenant_id_, object_id_, ddl_rpc_timeout))) { + LOG_WARN("fail to get ddl rpc timeout", K(ret), K(tenant_id_), K(object_id_)); + } else if (OB_FAIL(root_service->get_ddl_service().get_common_rpc()->to(obrpc::ObRpcProxy::myaddr_).timeout(ddl_rpc_timeout).execute_ddl_task(alter_table_arg, unused_ids))) { + LOG_WARN("fail to execute ddl task", K(ret), K(obrpc::ObRpcProxy::myaddr_), K(ddl_rpc_timeout), K(alter_table_arg)); + } + } + } + } + } + return ret; +} + +int ObPartitionSplitTask::check_health() +{ + int ret = OB_SUCCESS; + const uint64_t table_id = object_id_; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(root_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("error sys", K(ret)); + } else if (!root_service_->in_service()) { + ret = OB_STATE_NOT_MATCH; + LOG_WARN("root service not in service, not need retry", K(ret), K(table_id)); + need_retry_ = false; // only stop run the task, no need to clean up task context + } else if (OB_FAIL(refresh_status())) { + LOG_WARN("refresh status failed", K(ret)); + } else if (OB_FAIL(refresh_schema_version())) { + LOG_WARN("refresh schema version failed", K(ret)); + } else { + ObMultiVersionSchemaService &schema_service = root_service_->get_schema_service(); + ObSchemaGetterGuard schema_guard; + const ObTableSchema *index_schema = nullptr; + bool is_data_table_exist = false; + if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id_, schema_guard))) { + LOG_WARN("get tanant schema guard failed", K(ret), K(tenant_id_)); + } else if (OB_FAIL(schema_guard.check_table_exist(tenant_id_, table_id, + is_data_table_exist))) { + LOG_WARN("check data table exist failed", K(ret), K_(tenant_id), K(table_id)); + } else if (!is_data_table_exist) { + ret = OB_TABLE_NOT_EXIST; + const ObDDLTaskStatus status = static_cast(task_status_); + if (ObDDLTaskStatus::WAIT_PARTITION_SPLIT_RECOVERY_TASK_FINISH == status) { + ret = OB_SUCCESS; + ObString unused_str; + if (OB_FAIL(batch_insert_reorganize_history())) { + LOG_WARN("failed to batch insert reorganize history", K(ret)); + } else if (OB_FAIL(report_error_code(unused_str))) { + LOG_WARN("report error code failed", K(ret)); + } else if (OB_FAIL(remove_task_record())) { + LOG_WARN("remove task record failed", K(ret)); + } else { + need_retry_ = false; // clean succ, stop the task + } + } + LOG_WARN("data table or dest table not exist", K(ret), K(is_data_table_exist), K(table_id)); + } + } + if (ObDDLTaskStatus::FAIL == static_cast(task_status_) + || ObDDLTaskStatus::SUCCESS == static_cast(task_status_)) { + ret = OB_SUCCESS; // allow clean up + } + check_ddl_task_execute_too_long(); + return ret; +} + +int ObPartitionSplitTask::serialize_params_to_message( + char *buf, + const int64_t buf_len, + int64_t &pos) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(nullptr == buf || buf_len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(buf), K(buf_len)); + } else if (OB_FAIL(ObDDLTask::serialize_params_to_message(buf, buf_len, pos))) { + LOG_WARN("ObDDLTask serialize failed", K(ret)); + } else { + LST_DO_CODE(OB_UNIS_ENCODE, all_src_tablet_ids_, data_tablet_compaction_scn_, + index_tablet_compaction_scns_, lob_tablet_compaction_scns_, partition_split_arg_, + tablet_size_, data_tablet_parallel_rowkey_list_, index_tablet_parallel_rowkey_list_); + } + return ret; +} + +int ObPartitionSplitTask::deserialize_params_from_message( + const uint64_t tenant_id, + const char *buf, + const int64_t data_len, + int64_t &pos) +{ + int ret = OB_SUCCESS; + ObPartitionSplitArg tmp_arg; + int64_t split_index_tablets_cnt = 0; + if (OB_UNLIKELY(!is_valid_tenant_id(tenant_id) || nullptr == buf || data_len <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tenant_id), KP(buf), K(data_len)); + } else if (OB_FAIL(ObDDLTask::deserialize_params_from_message( + tenant_id, buf, data_len, pos))) { + LOG_WARN("ObDDLTask deserlize failed", K(ret)); + } else { + LST_DO_CODE(OB_UNIS_DECODE, all_src_tablet_ids_, data_tablet_compaction_scn_, + index_tablet_compaction_scns_, lob_tablet_compaction_scns_, tmp_arg, + tablet_size_); + if (FAILEDx(ObSplitUtil::deserializ_parallel_datum_rowkey( + allocator_, buf, data_len, pos, data_tablet_parallel_rowkey_list_))) { + LOG_WARN("deserialize parallel info failed", K(ret)); + } else { + LST_DO_CODE(OB_UNIS_DECODE, split_index_tablets_cnt); + if (FAILEDx(index_tablet_parallel_rowkey_list_.prepare_allocate(split_index_tablets_cnt))) { + LOG_WARN("prepare alloc failed", K(ret), K(split_index_tablets_cnt)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < split_index_tablets_cnt; i++) { + if (OB_FAIL(ObSplitUtil::deserializ_parallel_datum_rowkey( + allocator_, buf, data_len, pos, index_tablet_parallel_rowkey_list_.at(i)))) { + LOG_WARN("deserialize parallel info failed", K(ret)); + } + } + LOG_TRACE("parallel datum rowkey info", K(ret), K(data_tablet_parallel_rowkey_list_), K(index_tablet_parallel_rowkey_list_)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(ObDDLUtil::replace_user_tenant_id(tenant_id, tmp_arg))) { + LOG_WARN("replace user tenant id failed", K(ret), K(tenant_id), K(tmp_arg)); + } else if (OB_FAIL(deep_copy_table_arg(allocator_, tmp_arg, partition_split_arg_))) { + LOG_WARN("deep copy partition split arg failed", K(ret)); + } else if (OB_FAIL(init_compaction_scn_map())) { + LOG_WARN("failed to init compaction scn map", K(ret)); + } else if (OB_FAIL(restore_compaction_scn_map())) { + LOG_WARN("failed to restore comaction scn map from tablet compaction array", K(ret)); + } + } + return ret; +} + +int64_t ObPartitionSplitTask::get_serialize_param_size() const +{ + int len = ObDDLTask::get_serialize_param_size(); + LST_DO_CODE(OB_UNIS_ADD_LEN, all_src_tablet_ids_, data_tablet_compaction_scn_, + index_tablet_compaction_scns_, lob_tablet_compaction_scns_, partition_split_arg_, + tablet_size_, data_tablet_parallel_rowkey_list_, index_tablet_parallel_rowkey_list_); + return len; +} + +int ObPartitionSplitTask::check_src_tablet_exist( + const uint64_t tenant_id, + const int64_t table_id, + const ObTabletID &src_tablet_id, + bool &is_src_tablet_exist) +{ + int ret = OB_SUCCESS; + ObMultiVersionSchemaService &schema_service = root_service_->get_schema_service(); + ObSchemaGetterGuard schema_guard; + const ObTableSchema *table_schema = nullptr; + int64_t src_part_id = OB_INVALID_PARTITION_ID; + is_src_tablet_exist = false; + if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id, schema_guard))) { + LOG_WARN("get tanant schema guard failed", K(ret), K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_id, table_schema))) { + LOG_WARN("failed to get table schema", K(ret), K(tenant_id), K(table_id)); + } else if (nullptr != table_schema) { + if (OB_FAIL(table_schema->get_hidden_part_id_by_tablet_id(src_tablet_id, src_part_id))) { + if (OB_TABLET_NOT_EXIST == ret) { + ret = OB_SUCCESS; + LOG_INFO("src tablet deleted", K(ret), K(tenant_id), K(table_id), K(src_tablet_id), K(task_id_)); + } else { + LOG_WARN("failed to get hidden part id", K(ret)); + } + } else { + is_src_tablet_exist = true; + } + } else { + LOG_INFO("table deleted", K(ret), K(tenant_id), K(table_id), K(task_id_)); + } + return ret; +} + +int ObPartitionSplitTask::cleanup_impl() +{ + int ret = OB_SUCCESS; + ObString unused_str; + bool is_src_tablet_exist = false; + + ROOTSERVICE_EVENT_ADD("ddl", "partition_split_task_cleanup"); + DEBUG_SYNC(BEFORE_PARTITION_SPLIT_TASK_CLEANUP); + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(check_src_tablet_exist(tenant_id_, object_id_, partition_split_arg_.src_tablet_id_, is_src_tablet_exist))) { + LOG_WARN("failed to check src tablet exist", K(ret)); + } else if (is_src_tablet_exist) { + if (OB_FAIL(batch_insert_reorganize_history())) { + LOG_WARN("failed to batch insert reorganize history", K(ret)); + } else if (OB_FAIL(clean_splitted_tablet())) { + LOG_WARN("fail to clean splitted tablet", K(ret)); + } + } else { + LOG_INFO("already clean splitted tablet, skip", K(ret), K(tenant_id_), K(task_id_), K(object_id_), K(partition_split_arg_.src_tablet_id_)); + } + DEBUG_SYNC(PARTITION_SPLIT_SUCCESS); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(report_error_code(unused_str))) { + LOG_WARN("report error code failed", K(ret)); + } else if (OB_FAIL(remove_task_record())) { + LOG_WARN("remove task record failed", K(ret)); + } else { + need_retry_ = false; // clean succ, stop the task + } + LOG_INFO("clean task finished", K(ret), K(*this)); + return ret; +} + +int ObPartitionSplitTask::clean_splitted_tablet() +{ + int ret = OB_SUCCESS; + ObCleanSplittedTabletArg clean_arg; + obrpc::ObCommonRpcProxy *rpc_proxy = GCTX.rs_rpc_proxy_; + if (OB_ISNULL(rpc_proxy)){ + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rpc_proxy is null", KR(ret)); + } else if (FALSE_IT(clean_arg.tenant_id_ = tenant_id_)) { + } else if (FALSE_IT(clean_arg.table_id_ = object_id_)) { + } else if (FALSE_IT(clean_arg.task_id_ = task_id_)) { + } else if (FALSE_IT(clean_arg.is_auto_split_ = is_auto_split(partition_split_arg_.task_type_))) { + } else if (FALSE_IT(clean_arg.src_table_tablet_id_ = partition_split_arg_.src_tablet_id_)) { + } else if (OB_FAIL(clean_arg.dest_tablet_ids_.assign(partition_split_arg_.dest_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret)); + } else if (OB_FAIL(clean_arg.local_index_table_ids_.assign(partition_split_arg_.local_index_table_ids_))) { + LOG_WARN("fail to assign array", KR(ret)); + } else if (OB_FAIL(clean_arg.src_local_index_tablet_ids_.assign(partition_split_arg_.src_local_index_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret)); + } else if (OB_FAIL(clean_arg.dest_local_index_tablet_ids_.assign(partition_split_arg_.dest_local_index_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret)); + } else if (OB_FAIL(clean_arg.lob_table_ids_.assign(partition_split_arg_.lob_table_ids_))) { + LOG_WARN("fail to assign array", KR(ret)); + } else if (OB_FAIL(clean_arg.src_lob_tablet_ids_.assign(partition_split_arg_.src_lob_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret)); + } else if (OB_FAIL(clean_arg.dest_lob_tablet_ids_.assign(partition_split_arg_.dest_lob_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret)); + } else if (OB_FAIL(rpc_proxy->timeout(GCONF._ob_ddl_timeout).clean_splitted_tablet(clean_arg))) { + LOG_WARN("failed to clean splitted tablet", KR(ret), K(clean_arg)); + } + + return ret; +} + +void ObPartitionSplitTask::reset_replica_build_stat() +{ + TCWLockGuard guard(lock_); + replica_build_task_submit_ = false; + replica_build_request_time_ = 0; + replica_build_ret_code_ = OB_SUCCESS; +} + +int ObPartitionSplitTask::update_message_row_progress_(const oceanbase::share::ObDDLTaskStatus status, + const bool task_submitted, + int64_t &pos) +{ + int ret = OB_SUCCESS; + if (!task_submitted) { + ObString str; + if (ObDDLTaskStatus::WAIT_DATA_TABLE_SPLIT_END == status) { + str = "STATUS: SUBMITTING DATA TABLET SPLIT TASK"; + } else if (ObDDLTaskStatus::WAIT_LOCAL_INDEX_SPLIT_END == status) { + str = "STATUS: SUBMITTING LOCAL INDEX TABLET SPLIT TASK"; + } else if (ObDDLTaskStatus::WAIT_LOB_TABLE_SPLIT_END == status) { + str = "STATUS: SUBMITTING LOB TABLE TABLET SPLIT TASK"; + } + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "%s", + str.ptr()))) { + LOG_WARN("failed to print", K(ret)); + } + } else { + ObString str; + int64_t row_inserted = 0; + int64_t physical_row_count_ = 0; + double percent = 0.0; + replica_builder_.get_progress(row_inserted, physical_row_count_, percent); + if (ObDDLTaskStatus::WAIT_DATA_TABLE_SPLIT_END == status + && OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: DATA TABLET SPLITTING, TOTAL_ROWS: %ld, ROW_PROCESSED: %ld, ROW_PROGRESS: %0.1lf%%; LOCAL INDEX TABLET 0.0%%; LOB TEBLET 0.0%%;", + physical_row_count_, row_inserted, percent))) { + LOG_WARN("failed to print", K(ret)); + } else if (ObDDLTaskStatus::WAIT_LOCAL_INDEX_SPLIT_END == status + && OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: DATA TABLET SPLITTED 100.0%%; LOCAL INDEX TABLET SPLITTING, TOTAL_ROWS: %ld, ROW_PROCESSED: %ld, ROW_PROGRESS: %0.1lf%%; LOB TEBLET 0.0%%;", + physical_row_count_, row_inserted, percent))) { + LOG_WARN("failed to print", K(ret)); + } else if (ObDDLTaskStatus::WAIT_LOB_TABLE_SPLIT_END == status + && OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: DATA TABLET SPLITTED 100.0%%; LOCAL INDEX TABLET SPLITTED 100.0%%; LOB TABLET SPLITTING, TOTAL_ROWS: %ld, ROW_PROCESSED: %ld, ROW_PROGRESS: %0.1lf%%", + physical_row_count_, row_inserted, percent))) { + LOG_WARN("failed to print", K(ret)); + } + } + return ret; +} + +int ObPartitionSplitTask::get_waiting_tablet_ids_( + const hash::ObHashMap, ObCheckProgressStatus> &tablet_hash, + ObIArray &waiting_tablets /* OUT */) +{ + int ret = OB_SUCCESS; + waiting_tablets.reset(); + for (hash::ObHashMap, ObCheckProgressStatus>::const_iterator it = tablet_hash.begin(); OB_SUCC(ret) && it != tablet_hash.end(); it++) { + if (ObCheckProgressStatus::DONE != it->second && OB_FAIL(waiting_tablets.push_back(it->first.tablet_id_.id()))) { + LOG_WARN("failed to push back", K(ret)); + } + } + return ret; +} + +int ObPartitionSplitTask::get_waiting_tablet_ids_( + const hash::ObHashMap, ObCheckProgressStatus> &tablet_hash, + ObIArray &waiting_tablets /* OUT */) +{ + int ret = OB_SUCCESS; + waiting_tablets.reset(); + for (hash::ObHashMap, ObCheckProgressStatus>::const_iterator it = tablet_hash.begin(); OB_SUCC(ret) && it != tablet_hash.end(); it++) { + if (ObCheckProgressStatus::DONE != it->second && OB_FAIL(waiting_tablets.push_back(it->first.tablet_id_.id()))) { + LOG_WARN("failed to push back", K(ret)); + } + } + return ret; +} + +int ObPartitionSplitTask::update_message_tablet_progress_(const oceanbase::share::ObDDLTaskStatus status, + int64_t &pos) +{ + int ret = OB_SUCCESS; + ObSArray waiting_tablets; + { + TCRLockGuard guard(lock_); + if (ObDDLTaskStatus::WAIT_FROZE_END == status) { + if (!freeze_progress_status_inited_) { + if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "STATUS: WAIT FROZE at INITIALIZING"))) { // total + LOG_WARN("failed to print", K(ret)); + } + } else if (OB_FAIL(get_waiting_tablet_ids_(freeze_progress_map_, waiting_tablets))) { + LOG_WARN("failed to get waiting tablet of freeze progressing", K(ret)); + } else if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "STATUS: WAIT FROZE %ld/%ld", + freeze_progress_map_.size() - waiting_tablets.size(), freeze_progress_map_.size()))) { // total + LOG_WARN("failed to print", K(ret)); + } + } else if (ObDDLTaskStatus::WAIT_COMPACTION_END == status) { + if (!compact_progress_status_inited_) { + if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "STATUS: WAIT COMPACTION at INITIALIZING"))) { // total + LOG_WARN("failed to print", K(ret)); + } + } else if (OB_FAIL(get_waiting_tablet_ids_(compaction_progress_map_, waiting_tablets))) { + LOG_WARN("failed to get waiting tablet of freeze progressing", K(ret)); + } else if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "STATUS: WAIT COMPACTION %ld/%ld", + compaction_progress_map_.size() - waiting_tablets.size(), compaction_progress_map_.size()))) { // total + LOG_WARN("failed to print", K(ret)); + } + } else if (ObDDLTaskStatus::WRITE_SPLIT_START_LOG == status) { + if (!write_split_log_status_inited_) { + if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "STATUS: WRITE START LOG at INITIALIZING"))) { // total + LOG_WARN("failed to print", K(ret)); + } + } else if (OB_FAIL(get_waiting_tablet_ids_(send_finish_map_, waiting_tablets))) { + LOG_WARN("failed to get waiting tablet of freeze progressing", K(ret)); + } else if (OB_FAIL(databuff_printf(stat_info_.message_, MAX_LONG_OPS_MESSAGE_LENGTH, pos, "STATUS: WRITE START LOG %ld/%ld", + send_finish_map_.size() - waiting_tablets.size(), send_finish_map_.size()))) { // total + LOG_WARN("failed to print", K(ret)); + } + } + } + + if (OB_SUCC(ret) && waiting_tablets.count() != 0) { // show the processing tablet_ids; + int64_t tmp_pos = 0; + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH - 2, // "]\0" at the end + pos, + ", WAITING TABLET: ["))) { + LOG_WARN("failed to print", K(ret)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < waiting_tablets.count(); i++) { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH - 2, // "]\0" at the end + pos, + "%ld", + waiting_tablets.at(i)))) { + LOG_WARN("failed to print", K(ret)); + } else if (OB_FALSE_IT(tmp_pos = pos)) { + // [123 + // ^ + // | + // tmp_pos, re-orientate pos when OB_SIZE_OVERFLOW + LOG_WARN("failed to assign tmp_pos", K(ret)); + } else if (i != waiting_tablets.count() - 1 + && OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH - 2, // "]\0" at the end + pos, + ", "))) { + LOG_WARN("failed to print", K(ret)); + } else if (i == waiting_tablets.count() - 1 + && OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "]"))) { + LOG_WARN("failed to print", K(ret)); + } + } + if (ret == OB_SIZE_OVERFLOW) { // cut down when length of tablet_ids longer than MAX_LONG_OPS_MESSAGE_LENGTH. + ret = OB_SUCCESS; + stat_info_.message_[tmp_pos] = ']'; + stat_info_.message_[tmp_pos + 1] = '\0'; + } else { + LOG_WARN("failed to print", K(ret)); + } + } + return ret; +} + +int ObPartitionSplitTask::collect_longops_stat(ObLongopsValue &value) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + const ObDDLTaskStatus status = static_cast(task_status_); + bool replica_build_task_submit = false; + { + TCRLockGuard guard(lock_); + replica_build_task_submit = replica_build_task_submit_; + } + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "TENANT_ID: %ld, TASK_ID: %ld, ", + tenant_id_, task_id_))) { + LOG_WARN("failed to print", K(ret)); + } + else { + switch (status) { + case ObDDLTaskStatus::PREPARE: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: PREPARE"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_FROZE_END: { + if (OB_FAIL(update_message_tablet_progress_(status, pos))) { + LOG_WARN("failed to update message for showing freezing progress", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_COMPACTION_END: { + if (OB_FAIL(update_message_tablet_progress_(status, pos))) { + LOG_WARN("failed to update message for showing compaction progress", K(ret)); + } + break; + } + case ObDDLTaskStatus::WRITE_SPLIT_START_LOG: { + if (OB_FAIL(update_message_tablet_progress_(status, pos))) { + LOG_WARN("failed to update message for showing compaction progress", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_DATA_TABLE_SPLIT_END: { + if (OB_FAIL(update_message_row_progress_(status, + replica_build_task_submit, + pos))) { + LOG_WARN("failed to update message", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_LOCAL_INDEX_SPLIT_END: { + if (OB_FAIL(update_message_row_progress_(status, + replica_build_task_submit, + pos))) { + LOG_WARN("failed to update message", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_LOB_TABLE_SPLIT_END: { + if (OB_FAIL(update_message_row_progress_(status, + replica_build_task_submit, + pos))) { + LOG_WARN("failed to update message", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_TRANS_END: { + if (snapshot_version_ > 0) { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: WAIT TRANS END: SNAPSHOT_VERSION: %ld", + snapshot_version_))) { + LOG_WARN("failed to print", K(ret)); + } + } else { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: WAIT TRANS END, PENDING_TX_ID: %ld", + wait_trans_ctx_.get_pending_tx_id().get_id()))) { + LOG_WARN("failed to print", K(ret)); + } + } + break; + } + case ObDDLTaskStatus::TAKE_EFFECT: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: TAKE EFFECT"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::SUCCESS: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: PARTITION SPLIT SUCCESS"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + case ObDDLTaskStatus::WAIT_PARTITION_SPLIT_RECOVERY_TASK_FINISH: { + if (OB_FAIL(databuff_printf(stat_info_.message_, + MAX_LONG_OPS_MESSAGE_LENGTH, + pos, + "STATUS: WAIT RECOVERY SPLIT TASK CREATED"))) { + LOG_WARN("failed to print", K(ret)); + } + break; + } + default: { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not expected status", K(ret), K(status), K(*this)); + break; + } + } // end switch + } + + if (OB_FAIL(ret)) { + // error occur + } else if (OB_FAIL(copy_longops_stat(value))) { + LOG_WARN("failed to collect common longops stat", K(ret)); + } + return ret; +} +int ObPartitionSplitTask::batch_insert_reorganize_history() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(root_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("root service should not be null", K(ret)); + } else if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::batch_insert( + root_service_->get_sql_proxy(), tenant_id_, partition_split_arg_, stat_info_.start_time_, ObTimeUtility::current_time()))) { + LOG_WARN("failed to batch insert reorganize history", K(ret)); + } + return ret; +} + +int ObPartitionSplitTask::check_can_reuse_macro_block( + ObSchemaGetterGuard &schema_guard, + const uint64_t tenant_id, + const ObIArray &table_ids, + ObSArray &can_reuse_macro_blocks) +{ + int ret = OB_SUCCESS; + can_reuse_macro_blocks.reset(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || table_ids.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init twice", K(ret), K(tenant_id), K(table_ids)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < table_ids.count(); i++) { + const ObTableSchema *table_schema = nullptr; + const uint64_t table_id = table_ids.at(i); + const ObTableSchema *fetch_part_key_schema = nullptr; // used to fetch partition key info. + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_id, table_schema))) { + LOG_WARN("get schema failed", K(ret), K(tenant_id), K(table_id)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table not exist", K(ret), K(tenant_id), K(table_id)); + } else if (is_aux_lob_table(table_schema->get_table_type())) { + if (OB_FAIL(can_reuse_macro_blocks.push_back(false))) { + LOG_WARN("push back failed", K(ret)); + } + } else if (!table_schema->is_index_local_storage() && + FALSE_IT(fetch_part_key_schema = table_schema)) { + // fetch partition key info from itself for data table and global index table. + // fetch partition key info from data table for local index table. + } else if (table_schema->is_index_local_storage() + && OB_FAIL(schema_guard.get_table_schema(tenant_id, table_schema->get_data_table_id(), fetch_part_key_schema))) { + LOG_WARN("get data table schema failed", K(ret), K(tenant_id), "data_table_id", table_schema->get_data_table_id()); + } else if (OB_ISNULL(fetch_part_key_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table does not exist", K(ret), KPC(table_schema)); + } else { + ObArray rowkey_cols; + ObArray part_key_cols; + const common::ObRowkeyInfo &rowkey_info = table_schema->get_rowkey_info(); + const common::ObPartitionKeyInfo &part_key_info = fetch_part_key_schema->get_partition_key_info(); + if (OB_FAIL(rowkey_info.get_column_ids(rowkey_cols))) { + LOG_WARN("get rowkey columns failed", K(ret), K(rowkey_info)); + } else if (OB_FAIL(part_key_info.get_column_ids(part_key_cols))) { + LOG_WARN("get part key columns failed", K(ret), K(part_key_info)); + } else if (OB_UNLIKELY(rowkey_cols.count() < part_key_cols.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(rowkey_cols), K(part_key_cols), KPC(fetch_part_key_schema)); + } else { + bool can_reuse = true; + for (int64_t col_idx = 0; OB_SUCC(ret) && can_reuse && col_idx < rowkey_cols.count() && col_idx < part_key_cols.count(); col_idx++) { + const ObColumnSchemaV2 *part_col_chema = fetch_part_key_schema->get_column_schema(part_key_cols.at(col_idx)); + const ObColumnSchemaV2 *rowkey_col_schema = table_schema->get_column_schema(rowkey_cols.at(col_idx)); + if (OB_UNLIKELY(nullptr == part_col_chema || nullptr == rowkey_col_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(col_idx), KPC(fetch_part_key_schema)); + } else if (rowkey_col_schema->is_shadow_column()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", K(ret), K(col_idx), K(rowkey_cols), K(part_key_cols), KPC(fetch_part_key_schema)); + } else { + can_reuse &= rowkey_cols.at(col_idx) == part_key_cols.at(col_idx); + } + } + if (FAILEDx(can_reuse_macro_blocks.push_back(can_reuse))) { + LOG_WARN("push back failed", K(ret)); + } + } + } + } + } + return ret; +} + +int ObPartitionSplitTask::prepare_tablet_split_ranges( + ObSEArray, 8> ¶llel_datum_rowkey_list) +{ + int ret = OB_SUCCESS; + parallel_datum_rowkey_list.reset(); + ObLSID ls_id; + ObAddr leader_addr; + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + const int64_t source_index_tablets_cnt = partition_split_arg_.src_local_index_tablet_ids_.count(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(root_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("error sys", K(ret)); + } else if (!data_tablet_parallel_rowkey_list_.empty()) { + if (OB_UNLIKELY(source_index_tablets_cnt != index_tablet_parallel_rowkey_list_.count())) { + ret = OB_ERR_UNEXPECTED; // defensive check. + LOG_WARN("unexpected err, mismatched parallel rowkey list count", + K(ret), K(task_status_), K(source_index_tablets_cnt), K(index_tablet_parallel_rowkey_list_)); + } + } else if (OB_UNLIKELY(!index_tablet_parallel_rowkey_list_.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err, empty parallel rowkey list for the data tablet, but non-empty ones for the index tablets", + K(ret), K(task_status_), K(data_tablet_parallel_rowkey_list_), K(index_tablet_parallel_rowkey_list_)); + } else if (WRITE_SPLIT_START_LOG != task_status_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err, empty parallel rowkey list under a mismatched status", K(ret), K(task_status_)); + } else if (OB_FAIL(index_tablet_parallel_rowkey_list_.prepare_allocate(source_index_tablets_cnt))) { + LOG_WARN("prepare alloc failed", K(ret)); + } else if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(GCTX.location_service_, + tenant_id_, partition_split_arg_.src_tablet_id_, rpc_timeout, ls_id, leader_addr))) { + LOG_WARN("failed to get orig leader addr", K(ret), "tablet_id", partition_split_arg_.src_tablet_id_); + } else { + for (int64_t tablet_idx = 0; OB_SUCC(ret) && tablet_idx < 1 /*data_tablet*/ + source_index_tablets_cnt; tablet_idx++) { + const ObTabletID &src_tablet_id = tablet_idx == 0 ? partition_split_arg_.src_tablet_id_ : partition_split_arg_.src_local_index_tablet_ids_.at(tablet_idx - 1); + ObIArray &target_parallel_rowkey_list = tablet_idx == 0 ? + data_tablet_parallel_rowkey_list_ : index_tablet_parallel_rowkey_list_.at(tablet_idx - 1); + obrpc::ObPrepareSplitRangesArg arg; + obrpc::ObPrepareSplitRangesRes result; + arg.ls_id_ = ls_id; + arg.tablet_id_ = src_tablet_id; + arg.user_parallelism_ = parallelism_; // parallelism_; + arg.schema_tablet_size_ = tablet_size_; + if (OB_FAIL(root_service_->get_rpc_proxy().to(leader_addr) + .by(tenant_id_).timeout(rpc_timeout).prepare_tablet_split_task_ranges(arg, result))) { + LOG_WARN("prepare tablet split task ranges failed", K(ret), K(arg)); + } else if (OB_UNLIKELY(result.parallel_datum_rowkey_list_.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected parallel info", K(ret), K(result)); + } else if (OB_FAIL(target_parallel_rowkey_list.prepare_allocate(result.parallel_datum_rowkey_list_.count()))) { + LOG_WARN("prepare allocate failed", K(ret), K(result)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < result.parallel_datum_rowkey_list_.count(); i++) { + if (OB_FAIL(result.parallel_datum_rowkey_list_.at(i).deep_copy(target_parallel_rowkey_list.at(i), allocator_))) { + LOG_WARN("deep copy range failed", K(ret)); + } + } + } + if (OB_FAIL(ret)) { + data_tablet_parallel_rowkey_list_.reset(); // reset. + index_tablet_parallel_rowkey_list_.reset(); // reset. + } else if (OB_FAIL(update_task_message())) { + LOG_WARN("update parallel split info failed", K(ret)); + } + LOG_INFO("split datum rowkey", K(ret), K(arg), K(result)); + } + } + if (OB_SUCC(ret)) { + if (ObDDLTaskStatus::WRITE_SPLIT_START_LOG == task_status_) { + // do nothing. + } else if (ObDDLTaskStatus::WAIT_DATA_TABLE_SPLIT_END == task_status_) { + if (OB_FAIL(parallel_datum_rowkey_list.push_back(data_tablet_parallel_rowkey_list_))) { + LOG_WARN("push back failed", K(ret)); + } + } else if (ObDDLTaskStatus::WAIT_LOB_TABLE_SPLIT_END == task_status_) { + if (OB_FAIL(parallel_datum_rowkey_list.push_back(data_tablet_parallel_rowkey_list_))) { // lob meta. + LOG_WARN("push back failed", K(ret)); + } else if (OB_FAIL(parallel_datum_rowkey_list.push_back(data_tablet_parallel_rowkey_list_))) { // lob piece. + LOG_WARN("push back failed", K(ret)); + } + } else if (ObDDLTaskStatus::WAIT_LOCAL_INDEX_SPLIT_END == task_status_) { + if (OB_UNLIKELY(source_index_tablets_cnt != index_tablet_parallel_rowkey_list_.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mismatched datum rowkey list", K(ret), K(source_index_tablets_cnt), K(index_tablet_parallel_rowkey_list_)); + } else if (OB_FAIL(parallel_datum_rowkey_list.assign(index_tablet_parallel_rowkey_list_))) { + LOG_WARN("assign failed", K(ret)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected status", K(ret), K(task_status_), K(data_tablet_parallel_rowkey_list_), K(index_tablet_parallel_rowkey_list_)); + } + } + return ret; +} + +int ObPartitionSplitTask::prepare_tablet_split_infos( + const share::ObLSID &ls_id, + const ObAddr &leader_addr, + ObIArray &split_info_array) +{ + int ret = OB_SUCCESS; + split_info_array.reset(); + ObSArray lob_col_idxs; + ObArray table_ids; + ObSArray can_reuse_macro_blocks; + ObSchemaGetterGuard schema_guard; + ObMultiVersionSchemaService &schema_service = ObMultiVersionSchemaService::get_instance(); + const int64_t rpc_timeout = max(GCONF.rpc_timeout, 1000L * 1000L * 9L); + if (all_src_tablet_ids_.empty() && OB_FAIL(setup_src_tablet_ids_array())) { + LOG_WARN("failed to setup all src tablet ids", K(ret)); + } else if (OB_FAIL(setup_lob_idxs_arr(lob_col_idxs))) { + LOG_WARN("failed to setup lob idxs array", K(ret)); + } else if (OB_FAIL(schema_service.get_tenant_schema_guard(tenant_id_, schema_guard))) { + LOG_WARN("get tenant schema guard failed", K(ret)); + } else if (OB_FAIL(table_ids.push_back(object_id_))) { + LOG_WARN("push back failed", K(ret)); + } else if (OB_FAIL(table_ids.push_back(partition_split_arg_.local_index_table_ids_))) { + LOG_WARN("push back failed", K(ret)); + } else if (OB_FAIL(table_ids.push_back(partition_split_arg_.lob_table_ids_))) { + LOG_WARN("push back failed", K(ret)); + } else if (OB_FAIL(check_can_reuse_macro_block(schema_guard, + tenant_id_, table_ids, can_reuse_macro_blocks))) { + LOG_WARN("check can reuse macro block failed", K(ret)); + } else if (OB_UNLIKELY(all_src_tablet_ids_.count() != table_ids.count() || all_src_tablet_ids_.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(all_src_tablet_ids_), K(table_ids), K(partition_split_arg_)); + } + const int64_t lob_tablet_start_idx = 1 /*data_tablet*/ + partition_split_arg_.src_local_index_tablet_ids_.count(); + const ObSArray &lob_tablet_ids = partition_split_arg_.src_lob_tablet_ids_; + for (int64_t i = 0; OB_SUCC(ret) && i < all_src_tablet_ids_.count(); ++i) { + const ObTabletID &tablet_id = all_src_tablet_ids_.at(i); + int64_t primary_compaction_scn = 0; + if (OB_FAIL(tablet_compaction_scn_map_.get_refactored(tablet_id, primary_compaction_scn))) { + LOG_WARN("failed to get compaction scn for tablet", K(ret), K(tablet_id)); + } else { + ObTabletSplitArg split_info; + split_info.ls_id_ = ls_id; + split_info.table_id_ = i < lob_tablet_start_idx ? table_ids.at(i) : object_id_; + split_info.lob_table_id_ = i < lob_tablet_start_idx ? OB_INVALID_ID : table_ids.at(i); + split_info.schema_version_ = schema_version_; + split_info.task_id_ = task_id_; + split_info.source_tablet_id_ = tablet_id; + split_info.compaction_scn_ = primary_compaction_scn; + split_info.data_format_version_ = data_format_version_; + split_info.consumer_group_id_ = partition_split_arg_.consumer_group_id_; + split_info.can_reuse_macro_block_ = can_reuse_macro_blocks.at(i); + split_info.split_sstable_type_ = share::ObSplitSSTableType::SPLIT_BOTH; + const ObIArray ¶llel_datum_rowkey_list = i > 0 && i < lob_tablet_start_idx ? + index_tablet_parallel_rowkey_list_.at(i - 1) : data_tablet_parallel_rowkey_list_; + int64_t index = 0; + ObArray dst_tablet_ids; + if (OB_FAIL(get_all_dest_tablet_ids(tablet_id, dst_tablet_ids))) { + LOG_WARN("failed to get all dest tablet ids", K(ret)); + } else if (OB_FAIL(split_info.dest_tablets_id_.assign(dst_tablet_ids))) { + LOG_WARN("assign failed", K(ret)); + } else if (i >= lob_tablet_start_idx && OB_FAIL(split_info.lob_col_idxs_.assign(lob_col_idxs))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(split_info.parallel_datum_rowkey_list_.assign(parallel_datum_rowkey_list))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(split_info_array.push_back(split_info))) { + LOG_WARN("push back failed", K(ret)); + } + } + } + return ret; +} + +int ObPartitionSplitTask::update_task_message() +{ + int ret = OB_SUCCESS; + char *buf = nullptr; + int64_t pos = 0; + ObString msg; + common::ObArenaAllocator allocator("SplitUpdMsg"); + const int64_t serialize_param_size = get_serialize_param_size(); + if (OB_ISNULL(root_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("root service is null", K(ret), KP(root_service_)); + } else if (OB_ISNULL(buf = static_cast(allocator.alloc(serialize_param_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate memory", K(ret), K(serialize_param_size)); + } else if (OB_FAIL(serialize_params_to_message(buf, serialize_param_size, pos))) { + LOG_WARN("failed to serialize params to message", KR(ret)); + } else { + msg.assign(buf, serialize_param_size); + if (OB_FAIL(ObDDLTaskRecordOperator::update_message(root_service_->get_sql_proxy(), tenant_id_, task_id_, msg))) { + LOG_WARN("failed to update message", KR(ret)); + } + } + return ret; +} + +void ObPartitionSplitTask::clear_old_status_context() +{ + TCWLockGuard guard(lock_); + wait_trans_ctx_.reset(); + (void)send_finish_map_.destroy(); + write_split_log_status_inited_ = false; +} diff --git a/src/rootserver/ddl_task/ob_partition_split_task.h b/src/rootserver/ddl_task/ob_partition_split_task.h new file mode 100644 index 000000000..2c7a1553d --- /dev/null +++ b/src/rootserver/ddl_task/ob_partition_split_task.h @@ -0,0 +1,258 @@ +/** + * 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_PARTITION_SPLIT_TASK_H +#define OCEANBASE_ROOTSERVER_OB_PARTITION_SPLIT_TASK_H + +#include "lib/net/ob_addr.h" +#include "rootserver/ddl_task/ob_ddl_task.h" +#include "share/ob_rpc_struct.h" + +namespace oceanbase +{ +namespace rootserver +{ + +enum ObCheckProgressStatus +{ + NOT_STARTED = 0, + ONGOING = 1, + DONE, +}; + +enum ObPartitionSplitReplicaType +{ + DATA_TABLET_REPLICA = 0, + LOCAL_INDEX_TABLET_REPLICA = 1, + LOB_TABLET_REPLICA = 2 +}; + +template +class ObCheckProgressKey final +{ +public: + ObCheckProgressKey() = default; + ObCheckProgressKey( + const T &field, + const ObTabletID &tablet_id); + ~ObCheckProgressKey() = default; + uint64_t hash() const; + int hash(uint64_t &hash_val) const + { + hash_val = hash(); return OB_SUCCESS; + } + bool operator==(const ObCheckProgressKey &other) const; + bool operator!=(const ObCheckProgressKey &other) const; + bool is_valid() const + { + return tablet_id_.is_valid(); + } + int assign(const ObCheckProgressKey&other); + TO_STRING_KV(K(field_), K(tablet_id_)); + +public: + T field_; + ObTabletID tablet_id_; +}; + +class ObSplitFinishItem final +{ +public: + ObSplitFinishItem() + : leader_addr_(), finish_arg_() + {} + ~ObSplitFinishItem() {} + TO_STRING_KV(K(leader_addr_), K(finish_arg_)); +public: + ObAddr leader_addr_; + obrpc::ObTabletSplitFinishArg finish_arg_; +}; + +// the process of partition split +class ObPartitionSplitTask final : public ObDDLTask +{ +public: + ObPartitionSplitTask(); + int init( + const uint64_t tenant_id, + const int64_t task_id, + const int64_t table_id, + const int64_t schema_version, + const int64_t parallelism, + const obrpc::ObPartitionSplitArg &partition_split_arg, + const int64_t tablet_size, + const int64_t parent_task_id = 0, + const int64_t task_status = share::ObDDLTaskStatus::PREPARE); + int init(const ObDDLTaskRecord &task_record); + virtual ~ObPartitionSplitTask(); + virtual int process() override; + virtual int collect_longops_stat(share::ObLongopsValue &value) override; + virtual bool support_longops_monitoring() const { return true; } + int update_complete_sstable_job_status( + const ObTabletID &tablet_id, + const ObAddr &svr, + const int64_t execution_id, + const int ret_code, + const ObDDLTaskInfo &addition_info); + virtual int serialize_params_to_message( + char *buf, + const int64_t buf_size, + int64_t &pos) const override; + virtual int deserialize_params_from_message( + const uint64_t tenant_id, + const char *buf, + const int64_t buf_size, + int64_t &pos) override; + virtual int64_t get_serialize_param_size() const override; + virtual bool is_error_need_retry(const int ret_code) override + { + UNUSED(ret_code); + // we should always retry on partition split task + return true; + } + int get_src_tablet_ids(ObIArray &src_ids); + int get_dest_tablet_ids(ObIArray &dest_ids); + INHERIT_TO_STRING_KV("ObDDLTask", ObDDLTask, + K(partition_split_arg_), K(has_synced_stats_info_), + K(replica_build_task_submit_), K(replica_build_request_time_), + K(replica_build_ret_code_), K(all_src_tablet_ids_), + K(data_tablet_compaction_scn_), K(index_tablet_compaction_scns_), + K(lob_tablet_compaction_scns_), K(freeze_progress_status_inited_), + K(compact_progress_status_inited_), K(write_split_log_status_inited_), + K_(data_tablet_parallel_rowkey_list), K_(index_tablet_parallel_rowkey_list)); +protected: + virtual void clear_old_status_context() override; +private: + int prepare(const share::ObDDLTaskStatus next_task_status); + int wait_freeze_end(const share::ObDDLTaskStatus next_task_status); + int wait_compaction_end(const share::ObDDLTaskStatus next_task_status); + int write_split_start_log(const share::ObDDLTaskStatus next_task_status); + int wait_data_tablet_split_end(const share::ObDDLTaskStatus next_task_status); + int wait_local_index_tablet_split_end(const share::ObDDLTaskStatus next_task_status); + int wait_lob_tablet_split_end(const share::ObDDLTaskStatus next_task_status); + int wait_trans_end(const share::ObDDLTaskStatus next_task_status); + int delete_stat_info(common::ObMySQLTransaction &trans, + const char *table_name, + const uint64_t table_id, + const uint64_t src_part_id); + int delete_src_part_stat_info(const uint64_t table_id, + const int64_t src_part_id, + const ObIArray &local_index_table_ids, + const ObIArray &src_local_index_part_ids); + int take_effect(const share::ObDDLTaskStatus next_task_status); + int succ(); + int wait_recovery_task_finish(const share::ObDDLTaskStatus next_task_status); + virtual int cleanup_impl() override; + virtual int clean_splitted_tablet(); + int check_health(); + int setup_src_tablet_ids_array(); + int init_freeze_progress_map(); + int init_compaction_scn_map(); + int init_tablet_compaction_scn_array(); + int update_tablet_compaction_scn_array(); + int restore_compaction_scn_map(); + int serialize_compaction_scn_to_task_record(); + int init_data_complement_progress_map(); + int init_send_finish_map(); + int get_all_dest_tablet_ids( + const ObTabletID &source_tablet_id, + ObArray &dest_ids); + int setup_split_finish_items( + ObAddr &leader_addr, + ObIArray &split_info_array); + int setup_lob_idxs_arr(ObSArray &lob_col_idxs_); + int check_freeze_progress( + const ObSArray &tablet_ids, + bool &is_end); + int check_compaction_progress( + const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const ObIArray &split_replica_addrs, + bool &is_end); + int send_split_request( + const ObPartitionSplitReplicaType replica_type); + int check_split_finished(bool &is_end); + int check_local_index_checksum(); + int send_split_rpc(const bool is_split_start); + bool check_need_sync_stats(); + int sync_stats_info(); + void reset_replica_build_stat(); + int init_sync_stats_info(const ObTableSchema* const table_schema, + ObSchemaGetterGuard &schema_guard, + int64_t &src_partition_id, /* OUTPUT */ + ObSArray &src_local_index_partition_ids /* OUTPUT */); + int update_message_row_progress_(const oceanbase::share::ObDDLTaskStatus status, + const bool task_submitted, + int64_t &pos); + int update_message_tablet_progress_(const oceanbase::share::ObDDLTaskStatus status, + int64_t &pos); + int get_waiting_tablet_ids_(const hash::ObHashMap, ObCheckProgressStatus> &tablet_hash, + ObIArray &waiting_tablets /* OUT */); + int get_waiting_tablet_ids_(const hash::ObHashMap, ObCheckProgressStatus> &tablet_hash, + ObIArray &waiting_tablets /* OUT */); + int batch_insert_reorganize_history(); + int check_can_reuse_macro_block( + ObSchemaGetterGuard &schema_guard, + const uint64_t tenant_id, + const ObIArray &table_ids, + ObSArray &can_reuse_macro_blocks); + int check_src_tablet_exist( + const uint64_t tenant_id, + const int64_t table_id, + const ObTabletID &src_tablet_id, + bool &is_src_tablet_exist); + int prepare_tablet_split_ranges( + ObSEArray, 8> ¶llel_datum_rowkey_list); + int prepare_tablet_split_infos( + const share::ObLSID &ls_id, + const ObAddr &leader_addr, + ObIArray &split_info_array); + int update_task_message(); +private: + static const int64_t OB_PARTITION_SPLIT_TASK_VERSION = 1; + using ObDDLTask::is_inited_; + using ObDDLTask::task_status_; + using ObDDLTask::snapshot_version_; + using ObDDLTask::tenant_id_; + using ObDDLTask::dst_tenant_id_; + using ObDDLTask::object_id_; + using ObDDLTask::schema_version_; + using ObDDLTask::dst_schema_version_; + using ObDDLTask::task_type_; + ObRootService *root_service_; + obrpc::ObPartitionSplitArg partition_split_arg_; + bool has_synced_stats_info_; + bool replica_build_task_submit_; + int64_t replica_build_request_time_; + int64_t replica_build_ret_code_; + ObSArray all_src_tablet_ids_; // src data tablet, src local index tablet, src lob tablet + int64_t data_tablet_compaction_scn_; + ObSArray index_tablet_compaction_scns_; + ObSArray lob_tablet_compaction_scns_; + hash::ObHashMap tablet_compaction_scn_map_; + hash::ObHashMap, ObCheckProgressStatus> freeze_progress_map_; + hash::ObHashMap, ObCheckProgressStatus> compaction_progress_map_; + hash::ObHashMap, ObCheckProgressStatus> send_finish_map_; + bool freeze_progress_status_inited_; + bool compact_progress_status_inited_; + bool write_split_log_status_inited_; + ObDDLReplicaBuildExecutor replica_builder_; + ObDDLWaitTransEndCtx wait_trans_ctx_; + int64_t tablet_size_; + common::ObSEArray data_tablet_parallel_rowkey_list_; // data table + common::ObSEArray, 8> index_tablet_parallel_rowkey_list_; // index table. +}; + +} // end namespace rootserver +} // end namespace oceanbase + +#endif // OCEANBASE_ROOTSERVER_OB_PARTITION_SPLIT_TASK_H diff --git a/src/rootserver/ddl_task/ob_recover_restore_table_task.cpp b/src/rootserver/ddl_task/ob_recover_restore_table_task.cpp index 697c054a5..dd8110820 100755 --- a/src/rootserver/ddl_task/ob_recover_restore_table_task.cpp +++ b/src/rootserver/ddl_task/ob_recover_restore_table_task.cpp @@ -131,6 +131,7 @@ int ObRecoverRestoreTableTask::obtain_snapshot(const ObDDLTaskStatus next_task_s // update sstable complement status for all leaders int ObRecoverRestoreTableTask::update_complete_sstable_job_status(const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, @@ -147,10 +148,12 @@ int ObRecoverRestoreTableTask::update_complete_sstable_job_status(const common:: LOG_WARN("snapshot version not match", K(ret), K(snapshot_version), K(snapshot_version_)); } else if (execution_id < execution_id_) { LOG_INFO("receive a mismatch execution result, ignore", K(ret_code), K(execution_id), K(execution_id_)); - } else if (OB_FAIL(replica_builder_.set_partition_task_status(tablet_id, - ret_code, - addition_info.row_scanned_, - addition_info.row_inserted_))) { + } else if (OB_FAIL(replica_builder_.update_build_progress(tablet_id, + addr, + ret_code, + addition_info.row_scanned_, + addition_info.row_inserted_, + addition_info.physical_row_count_))) { LOG_WARN("fail to set partition task status", K(ret)); } return ret; diff --git a/src/rootserver/ddl_task/ob_recover_restore_table_task.h b/src/rootserver/ddl_task/ob_recover_restore_table_task.h index a3118cd85..f57279c9a 100644 --- a/src/rootserver/ddl_task/ob_recover_restore_table_task.h +++ b/src/rootserver/ddl_task/ob_recover_restore_table_task.h @@ -47,6 +47,7 @@ public: virtual int process() override; virtual int update_complete_sstable_job_status( const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, diff --git a/src/rootserver/ddl_task/ob_table_redefinition_task.cpp b/src/rootserver/ddl_task/ob_table_redefinition_task.cpp index 5235515eb..76488e7d3 100755 --- a/src/rootserver/ddl_task/ob_table_redefinition_task.cpp +++ b/src/rootserver/ddl_task/ob_table_redefinition_task.cpp @@ -196,6 +196,7 @@ int ObTableRedefinitionTask::init(const ObDDLTaskRecord &task_record) } int ObTableRedefinitionTask::update_complete_sstable_job_status(const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, @@ -218,20 +219,20 @@ int ObTableRedefinitionTask::update_complete_sstable_job_status(const common::Ob case ObDDLType::DDL_DIRECT_LOAD_INSERT: { complete_sstable_job_ret_code_ = ret_code; ret_code_ = ret_code; - LOG_INFO("table redefinition task callback", K(complete_sstable_job_ret_code_)); + LOG_INFO("table redefinition task callback", K(addr), K(complete_sstable_job_ret_code_)); break; } default : { if (OB_UNLIKELY(snapshot_version_ != snapshot_version)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("error unexpected, snapshot version is not equal", K(ret), K(snapshot_version_), K(snapshot_version)); + LOG_WARN("error unexpected, snapshot version is not equal", K(addr), K(ret), K(snapshot_version_), K(snapshot_version)); } else if (execution_id < execution_id_) { ret = OB_TASK_EXPIRED; - LOG_WARN("receive a mismatch execution result, ignore", K(ret_code), K(execution_id), K(execution_id_)); + LOG_WARN("receive a mismatch execution result, ignore", K(addr), K(ret_code), K(execution_id), K(execution_id_)); } else { complete_sstable_job_ret_code_ = ret_code; execution_id_ = execution_id; // update ObTableRedefinitionTask::execution_id_ from ObDDLRedefinitionSSTableBuildTask::execution_id_ - LOG_INFO("table redefinition task callback", K(complete_sstable_job_ret_code_), K(execution_id_)); + LOG_INFO("table redefinition task callback", K(addr), K(complete_sstable_job_ret_code_), K(execution_id_)); } break; } @@ -515,12 +516,13 @@ int ObTableRedefinitionTask::copy_table_indexes() } LOG_INFO("indexes schema are already built", K(index_ids)); } else { - // if there is no indexes in new tables, we need to rebuild indexes in new table int64_t ddl_rpc_timeout = 0; int64_t all_tablet_count = 0; ObSchemaGetterGuard orig_schema_guard; if (OB_FAIL(root_service->get_ddl_service().get_tenant_schema_guard_with_version_in_inner_table(tenant_id_, orig_schema_guard))) { LOG_WARN("get schema guard failed", K(ret), K(tenant_id_)); + } else if (OB_FAIL(generate_rebuild_index_arg_list(tenant_id_, object_id_, orig_schema_guard, alter_table_arg_))) { + LOG_WARN("fail to generate rebuild index arg list", K(ret), K(tenant_id_), K(object_id_)); } else if (OB_FAIL(get_orig_all_index_tablet_count(orig_schema_guard, all_tablet_count))) { LOG_WARN("get all tablet count failed", K(ret)); } else if (OB_FAIL(ObDDLUtil::get_ddl_rpc_timeout(all_tablet_count, ddl_rpc_timeout))) { diff --git a/src/rootserver/ddl_task/ob_table_redefinition_task.h b/src/rootserver/ddl_task/ob_table_redefinition_task.h index d3361c665..a59b47f12 100644 --- a/src/rootserver/ddl_task/ob_table_redefinition_task.h +++ b/src/rootserver/ddl_task/ob_table_redefinition_task.h @@ -49,6 +49,7 @@ public: virtual int process() override; virtual int update_complete_sstable_job_status( const common::ObTabletID &tablet_id, + const ObAddr &addr, const int64_t snapshot_version, const int64_t execution_id, const int ret_code, diff --git a/src/rootserver/ob_ddl_help.cpp b/src/rootserver/ob_ddl_help.cpp index 6b757fbe5..b9ac0f752 100644 --- a/src/rootserver/ob_ddl_help.cpp +++ b/src/rootserver/ob_ddl_help.cpp @@ -102,6 +102,10 @@ int ObTableGroupHelp::add_tables_to_tablegroup(ObMySQLTransaction &trans, ret = OB_NOT_SUPPORTED; LOG_WARN("alter tablegroup of materialized view log is not supported", KR(ret)); LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter tablegroup of materialized view log is"); + } else if (table_schema->is_auto_partitioned_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to add auto-partitioned table to tablegroup", KR(ret), K(arg), KPC(table_schema)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "add auto-partitioned table to tablegroup"); } else if (table_schema->is_external_table()) { ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter tablegroup of external table is"); @@ -225,6 +229,10 @@ int ObTableGroupHelp::check_table_partition_in_tablegroup(const ObTableSchema *f } else if (is_sys_tablegroup_id(tablegroup_id)) { ret = OB_OP_NOT_ALLOW; LOG_WARN("can not handle with sys tablegroup", KR(ret), K(tablegroup_id)); + } else if (table.is_auto_partitioned_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to add auto-partitioned table to tablegroup", KR(ret), K(table)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "add auto-partitioned table to tablegroup"); } else if (OB_FAIL(schema_guard.get_tablegroup_schema(tenant_id, tablegroup_id, tablegroup))) { LOG_WARN("fail to get tablegroup schema", KR(ret), K(tenant_id), KT(tablegroup_id)); } else if (OB_ISNULL(tablegroup)) { diff --git a/src/rootserver/ob_ddl_operator.cpp b/src/rootserver/ob_ddl_operator.cpp index 198bd50fd..babbd742c 100644 --- a/src/rootserver/ob_ddl_operator.cpp +++ b/src/rootserver/ob_ddl_operator.cpp @@ -2577,6 +2577,120 @@ int ObDDLOperator::update_boundary_schema_version(const uint64_t &tenant_id, return ret; } +int ObDDLOperator::inc_table_schema_version(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const uint64_t table_id) +{ + int ret = OB_SUCCESS; + ObSchemaService *schema_service = schema_service_.get_schema_service(); + + if (OB_INVALID_ID == table_id || OB_INVALID_ID == tenant_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(table_id), K(tenant_id)); + } else if (OB_ISNULL(schema_service)) { + ret = OB_ERR_SYS; + LOG_WARN("schema service should not be NULL", K(ret)); + } else if (OB_FAIL(schema_service->get_table_sql_service(). + update_data_table_schema_version(trans, + tenant_id, + table_id, + false))) { + LOG_WARN("fail to update schema version", K(ret)); + } + return ret; +} + +// split_table_partitions() will modify __all_part and __all_table: +// 1. add split partitions' information into __all_part based on inc_table_schema +// which records the setting of split partitions +// 2. modify part_idx, partition_type of origin partition in __all_part +// based on upd_table_schema which records the setting of changed origin partitions +// 3. modify part_num of table in __all_table based on new_table_schema +// which records the setting of table +int ObDDLOperator::split_table_partitions(const ObTableSchema &orig_table_schema, + ObTableSchema &inc_table_schema, + ObTableSchema &new_table_schema, + ObTableSchema &upd_table_schema, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = new_table_schema.get_tenant_id(); + int64_t new_schema_version = OB_INVALID_VERSION; + ObSchemaService *schema_service = schema_service_.get_schema_service(); + + if (OB_ISNULL(schema_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_service is NULL", KR(ret)); + } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) { + LOG_WARN("fail to gen new schema_version", KR(ret), K(tenant_id)); + } else if (OB_FAIL(schema_service->get_table_sql_service().add_split_inc_part_info(trans, + orig_table_schema, + inc_table_schema, + new_schema_version))) { + LOG_WARN("add split inc part info failed", KR(ret), + K(new_table_schema), + K(inc_table_schema), + K(new_schema_version)); + } else if (orig_table_schema.is_partitioned_table()) { + if (OB_FAIL(schema_service->get_table_sql_service().update_part_info(trans, + orig_table_schema, + upd_table_schema, + new_schema_version))) { + LOG_WARN("update split part info failed", KR(ret), + K(orig_table_schema), + K(upd_table_schema), + K(new_schema_version)); + } + } else { // !orig_table_schema.is_partitioned_table() + if (orig_table_schema.is_user_table() || orig_table_schema.is_global_index_table()) { + const ObRowkeyInfo& partition_key_info = new_table_schema.get_partition_key_info(); + if (partition_key_info.get_size() == 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid partition key numbers", KR(ret), K(orig_table_schema), K(new_table_schema)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < partition_key_info.get_size(); i++) { + const ObRowkeyColumn* partition_key_column = partition_key_info.get_column(i); + if (OB_ISNULL(partition_key_column)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("partition_key_column is null", KR(ret), K(new_table_schema)); + } else { + ObColumnSchemaV2* column_schema = new_table_schema.get_column_schema( + partition_key_column->column_id_); + + if (OB_ISNULL(column_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), K(orig_table_schema), K(new_table_schema), + KPC(partition_key_column)); + } else if (FALSE_IT(column_schema->set_schema_version(new_schema_version))) { + } else if (OB_FAIL(schema_service->get_table_sql_service() + .update_single_column(trans, orig_table_schema, new_table_schema, + *column_schema, false /* record_ddl_operation */))) { + LOG_WARN("update single column failed", KR(ret), K(orig_table_schema), + K(new_table_schema), KPC(column_schema)); + } + } + } // end for + } + } else if (!orig_table_schema.is_index_local_storage() && + !orig_table_schema.is_aux_lob_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not supported table type", KR(ret), K(orig_table_schema)); + } else { + // do nothing + } + } + + if (OB_SUCC(ret)){ + new_table_schema.set_schema_version(new_schema_version); + if (OB_FAIL(schema_service->get_table_sql_service() + .update_splitting_partition_option(trans, new_table_schema))) { + LOG_WARN("update splitting partition option failed", KR(ret), K(new_table_schema)); + } + } + + return ret; +} + int ObDDLOperator::truncate_table_partitions(const share::schema::ObTableSchema &orig_table_schema, share::schema::ObTableSchema &inc_table_schema, share::schema::ObTableSchema &del_table_schema, @@ -2862,6 +2976,40 @@ int ObDDLOperator::drop_table_partitions(const ObTableSchema &orig_table_schema, return ret; } +int ObDDLOperator::drop_table_splitted_partitions(const ObTableSchema &orig_table_schema, + ObTableSchema &inc_table_schema, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + bool is_truncate_table = false; + bool is_truncate_partition = true; // in order to avoid logging operation in drop_inc_part_info() + const uint64_t tenant_id = orig_table_schema.get_tenant_id(); + int64_t new_schema_version = OB_INVALID_VERSION; + ObSchemaService *schema_service = schema_service_.get_schema_service(); + + if (OB_ISNULL(schema_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_service is NULL", K(ret)); + } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) { + LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id)); + } else if (OB_FAIL(schema_service->get_table_sql_service().drop_inc_part_info(trans, + orig_table_schema, + inc_table_schema, + new_schema_version, + is_truncate_partition, + is_truncate_table))) { + LOG_WARN("delete inc part info failed", K(ret)); + } else if (OB_FAIL(schema_service->get_table_sql_service(). + update_data_table_schema_version(trans, + tenant_id, + orig_table_schema.get_table_id(), + false, + new_schema_version))) { + LOG_WARN("fail to update schema version", K(ret)); + } + return ret; +} + int ObDDLOperator::drop_table_subpartitions(const ObTableSchema &orig_table_schema, ObTableSchema &inc_table_schema, ObTableSchema &new_table_schema, @@ -4421,6 +4569,87 @@ int ObDDLOperator::update_index_status( return ret; } +// "alter table ... partition by" clause need to call this function to modify index type +// when enable auto partitioning feature for non-partitioned table and it has global local index +int ObDDLOperator::update_index_type(const ObTableSchema &data_table_schema, + const uint64_t index_table_id, + const share::schema::ObIndexType index_type, + const common::ObString *ddl_stmt_str, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObArray index_table_ids; + ObArray index_types; + + if (!data_table_schema.is_valid() || + OB_INVALID_ID == index_table_id || index_type >= INDEX_TYPE_MAX) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", + K(ret), K(data_table_schema), K(index_table_id), K(INDEX_TYPE_MAX)); + } else if (OB_FAIL(index_table_ids.push_back(index_table_id))) { + LOG_WARN("fail to push back", K(ret), K(index_table_id)); + } else if (OB_FAIL(index_types.push_back(index_type))) { + LOG_WARN("fail to push back", K(ret), K(index_type)); + } else if (OB_FAIL(update_indexes_type(data_table_schema, + index_table_ids, index_types, + ddl_stmt_str, + trans))) { + LOG_WARN("update index type failed", K(ret), K(data_table_schema)); + } + + return ret; +} + +int ObDDLOperator::update_indexes_type(const ObTableSchema &data_table_schema, + const ObIArray &index_table_ids, + const ObIArray &index_types, + const common::ObString *ddl_stmt_str, + common::ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + int64_t new_schema_version = OB_INVALID_VERSION; + ObSchemaService *schema_service = schema_service_.get_schema_service(); + uint64_t tenant_id = data_table_schema.get_tenant_id(); + uint64_t data_table_id = data_table_schema.get_table_id(); + + if (OB_INVALID_TENANT_ID == tenant_id || OB_INVALID_ID == data_table_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(data_table_id)); + } else if (index_table_ids.count() != index_types.count()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(index_table_ids), K(index_types), K(data_table_schema)); + } else if (OB_ISNULL(schema_service)) { + ret = OB_ERR_SYS; + LOG_WARN("schema service should not be NULL", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < index_table_ids.count(); i++) { + uint64_t index_table_id = index_table_ids.at(i); + ObIndexType index_type = index_types.at(i); + if (OB_INVALID_ID == data_table_id || OB_INVALID_ID == index_table_id + || index_type <= INDEX_TYPE_IS_NOT || index_type >= INDEX_TYPE_MAX) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(data_table_id), K(index_table_id), K(index_type)); + } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) { + LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id)); + } else if (OB_FAIL(schema_service->get_table_sql_service().update_index_type( + data_table_schema, index_table_id, + index_type, new_schema_version, + ddl_stmt_str, + trans))) { + LOG_WARN("update index type failed", K(ret), K(data_table_schema)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(schema_service->get_table_sql_service().update_data_table_schema_version( + trans, tenant_id, + data_table_id, + data_table_schema.get_in_offline_ddl_white_list()))) { + LOG_WARN("update data table schema version failed", K(ret)); + } + return ret; +} + int ObDDLOperator::update_table_attribute(ObTableSchema &new_table_schema, common::ObMySQLTransaction &trans, const ObSchemaOperationType operation_type, @@ -4610,6 +4839,29 @@ int ObDDLOperator::update_partition_option(common::ObMySQLTransaction &trans, return ret; } +int ObDDLOperator::update_partition_option(common::ObMySQLTransaction &trans, + ObTableSchema &table_schema, + const ObString &ddl_stmt_str) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + int64_t new_schema_version = OB_INVALID_VERSION; + ObSchemaService *schema_service_impl = schema_service_.get_schema_service(); + if (OB_ISNULL(schema_service_impl)) { + ret = OB_ERR_SYS; + RS_LOG(WARN, "schema_service_impl must not null", K(ret)); + } else if (OB_FAIL(schema_service_.gen_new_schema_version(tenant_id, new_schema_version))) { + LOG_WARN("fail to gen new schema_version", K(ret), K(tenant_id)); + } else { + table_schema.set_schema_version(new_schema_version); + if (OB_FAIL(schema_service_impl->get_table_sql_service().update_partition_option( + trans, table_schema, &ddl_stmt_str))) { + RS_LOG(WARN, "failed to update partition option", K(table_schema), K(ret)); + } + } + return ret; +} + int ObDDLOperator::update_check_constraint_state(common::ObMySQLTransaction &trans, const ObTableSchema &table_schema, ObConstraint &cst) diff --git a/src/rootserver/ob_ddl_operator.h b/src/rootserver/ob_ddl_operator.h index 3bdf5ce51..25e6600ac 100644 --- a/src/rootserver/ob_ddl_operator.h +++ b/src/rootserver/ob_ddl_operator.h @@ -259,6 +259,9 @@ public: int update_boundary_schema_version(const uint64_t &tenant_id, const uint64_t &boundary_schema_version, common::ObMySQLTransaction &trans); + int inc_table_schema_version(ObMySQLTransaction &trans, + const uint64_t tenant_id, + const uint64_t table_id); int truncate_table_partitions(const share::schema::ObTableSchema &orig_table_schema, share::schema::ObTableSchema &inc_table_schema, share::schema::ObTableSchema &del_table_schema, @@ -275,6 +278,14 @@ public: share::schema::ObTableSchema &inc_table_schema, share::schema::ObTableSchema &new_table_schema, common::ObMySQLTransaction &trans); + int split_table_partitions(const share::schema::ObTableSchema &orig_table_schema, + share::schema::ObTableSchema &inc_table_schema, + share::schema::ObTableSchema &new_table_schema, + share::schema::ObTableSchema &upd_table_schema, + common::ObMySQLTransaction &trans); + int drop_table_splitted_partitions(const share::schema::ObTableSchema &orig_table_schema, + share::schema::ObTableSchema &inc_table_schema, + common::ObMySQLTransaction &trans); int drop_table_partitions(const share::schema::ObTableSchema &orig_table_schema, share::schema::ObTableSchema &inc_table_schema, share::schema::ObTableSchema &new_table_schema, @@ -552,6 +563,16 @@ public: const bool in_offline_ddl_white_list, common::ObMySQLTransaction &trans, const common::ObString *ddl_stmt_str); + virtual int update_index_type(const ObTableSchema &data_table_schema, + const uint64_t index_table_id, + const share::schema::ObIndexType index_type, + const common::ObString *ddl_stmt_str, + common::ObMySQLTransaction &trans); + virtual int update_indexes_type(const ObTableSchema &data_table_schema, + const ObIArray &index_table_ids, + const ObIArray &index_types, + const common::ObString *ddl_stmt_str, + common::ObMySQLTransaction &trans); // tablespace virtual int create_tablespace(share::schema::ObTablespaceSchema &tablespace_schema, @@ -1028,6 +1049,9 @@ public: const ObColumnSchemaV2 &new_column_schema); int update_partition_option(common::ObMySQLTransaction &trans, share::schema::ObTableSchema &table_schema); + int update_partition_option(common::ObMySQLTransaction &trans, + share::schema::ObTableSchema &table_schema, + const common::ObString &ddl_stmt_str); int update_check_constraint_state(common::ObMySQLTransaction &trans, const share::schema::ObTableSchema &table, share::schema::ObConstraint &cst); diff --git a/src/rootserver/ob_ddl_service.cpp b/src/rootserver/ob_ddl_service.cpp index c2339af33..1227086b1 100755 --- a/src/rootserver/ob_ddl_service.cpp +++ b/src/rootserver/ob_ddl_service.cpp @@ -123,7 +123,11 @@ #include "storage/mview/ob_mview_sched_job_utils.h" #include "storage/vector_index/ob_vector_index_sched_job_utils.h" #include "rootserver/restore/ob_tenant_clone_util.h" +#include "rootserver/ob_split_partition_helper.h" #include "rootserver/mview/ob_mview_dependency_service.h" +#include "storage/ddl/ob_ddl_alter_auto_part_attr.h" +#include "share/tablet/ob_tablet_to_ls_operator.h" +#include "share/tablet/ob_tablet_to_table_history_operator.h" #include "src/share/ob_vec_index_builder_util.h" #include "share/vector_index/ob_vector_index_util.h" #include "rootserver/direct_load/ob_direct_load_partition_exchange.h" @@ -600,6 +604,7 @@ int ObDDLService::create_index_table( ObSchemaService *schema_service = NULL; const ObDatabaseSchema *database_schema = NULL; ObSchemaGetterGuard schema_guard; + if (OB_FAIL(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { LOG_WARN("fail to get schema guard with version in inner table", K(ret), K(tenant_id)); } else if (OB_FAIL(check_inner_stat())) { @@ -1136,7 +1141,6 @@ int ObDDLService::generate_object_id_for_partition_schema( } } // end for } - // 2. generate object_id for subpartitions if (OB_SUCC(ret) && PARTITION_LEVEL_TWO == part_level) { for (int64_t i = 0; OB_SUCC(ret) && i < partition_num; i++) { @@ -1563,6 +1567,12 @@ int ObDDLService::generate_schema( } } + // check auto_partition validity + if (OB_FAIL(ret)) { + } else if (OB_FAIL(schema.check_validity_for_auto_partition())) { + LOG_WARN("fail to check auto partition setting", KR(ret), K(schema), K(arg)); + } + if (OB_SUCC(ret)) { schema.set_micro_index_clustered(arg.schema_.get_micro_index_clustered()); } @@ -3215,12 +3225,16 @@ int ObDDLService::set_raw_table_options( case ObAlterTableArg::TABLEGROUP_NAME: { const ObString &tablegroup_name = alter_table_schema.get_tablegroup_name(); if (!tablegroup_name.empty()) { - uint64_t tablegroup_id = OB_INVALID_ID; - uint64_t tenant_id = alter_table_schema.get_tenant_id(); + uint64_t tablegroup_id = OB_INVALID_ID; + uint64_t tenant_id = alter_table_schema.get_tenant_id(); //tablegroup_id not set in resolver, only record tablegroup name - if (OB_FAIL(schema_guard.get_tablegroup_id(tenant_id, - tablegroup_name, - tablegroup_id))) { + if (new_table_schema.is_auto_partitioned_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to add auto-partitioned table to tablegroup", KR(ret), K(new_table_schema)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "add auto-partitioned table to tablegroup is"); + } else if (OB_FAIL(schema_guard.get_tablegroup_id(tenant_id, + tablegroup_name, + tablegroup_id))) { LOG_WARN("failed to get tablegroup id", K(ret), K(tablegroup_name)); } else if (OB_INVALID_ID == tablegroup_id) { ret = OB_TABLEGROUP_NOT_EXIST; @@ -3755,6 +3769,52 @@ int ObDDLService::create_hidden_table_with_pk_changed( LOG_WARN("invalid argument", K(ret), K(index_action_type), K(index_columns)); } else if (is_add_or_alter_pk && OB_FAIL(add_primary_key(index_columns, new_table_schema))) { LOG_WARN("failed to add pk", K(ret), K(index_columns), K(new_table_schema)); + } + + if (OB_FAIL(ret)) { + } else if (new_table_schema.is_auto_partitioned_table()) { + bool is_match_rowkey_prefix = true; + if (is_drop_pk) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to drop primary keys of auto-partitioned table", KR(ret), K(index_action_type), + K(new_table_schema)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "drop primary keys of auto-partitioning table is"); + } else if (new_table_schema.get_part_level() == PARTITION_LEVEL_ZERO) { + if (OB_FAIL(new_table_schema.is_presetting_partition_key_match_rowkey_prefix(is_match_rowkey_prefix))){ + LOG_WARN("fail to check whether presetting partition key matches rowkey prefix", KR(ret), K(new_table_schema)); + } + } else if (OB_FAIL(new_table_schema.is_partition_key_match_rowkey_prefix(is_match_rowkey_prefix))) { + LOG_WARN("fail to check whether partition key matches rowkey prefix", KR(ret), K(new_table_schema)); + } + + if (OB_FAIL(ret)) { + } else if (!is_match_rowkey_prefix) { + // auto-partitioning require that partition key must be equal to primary key prefix. + ret = OB_NOT_SUPPORTED; + LOG_WARN("mismatching between primary key prefix and partition key", KR(ret), K(index_action_type), + K(new_table_schema)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "mismatching between primary key prefix and partition key is"); + } else if (!new_table_schema.is_partitioned_table() && + origin_table_schema.get_part_option().get_part_func_expr_str().empty()) { + // for auto-partitioned non-partitioned table, empty part_func_expr means the presetting partition key + // of the data_table will always be "current" primary key. + // thus, when modify primary key, we need to check whether the part_func_type is need to be modified + const bool is_single_pk_column_new = new_table_schema.get_rowkey_column_num() == 1; + ObPartitionFuncType part_func_type = PARTITION_FUNC_TYPE_MAX; + if (is_single_pk_column_new) { + if (OB_FAIL(new_table_schema.detect_part_func_type(part_func_type))) { + LOG_WARN("check part func type failed", K(ret), K(new_table_schema)); + } + } else { + part_func_type = PARTITION_FUNC_TYPE_RANGE_COLUMNS; + } + if (OB_SUCC(ret)) { + new_table_schema.get_part_option().set_part_func_type(part_func_type); + } + } + } + + if (OB_FAIL(ret)) { } else if (is_drop_pk && OB_FAIL(drop_primary_key(new_table_schema))) { LOG_WARN("failed to add hidden pk column for heap table", K(ret)); } else if (!create_user_hidden_table_now) { @@ -4809,6 +4869,7 @@ int ObDDLService::adjust_cg_for_offline(ObTableSchema &new_table_schema) } int ObDDLService::gen_alter_partition_new_table_schema_offline( + obrpc::ObAlterTableArg &alter_table_arg, const AlterTableSchema & alter_table_schema, const ObTableSchema &orig_table_schema, ObTableSchema &new_table_schema) @@ -4835,6 +4896,11 @@ int ObDDLService::gen_alter_partition_new_table_schema_offline( } } OZ (fill_interval_info_for_offline(alter_table_schema, new_table_schema), new_table_schema); + if (OB_SUCC(ret) && alter_table_arg.is_alter_partitions_) { + // In the alter table partition by range(xxx) (partitions...) case, + // it is necessary to reset attributes of old table related to automatic partitioning here + new_table_schema.get_part_option().assign_auto_partition_attr(orig_table_schema.get_part_option()); + } return ret; } @@ -4868,7 +4934,10 @@ int ObDDLService::alter_table_partition_by( const bool bind_tablets = false; AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; OZ (gen_alter_partition_new_table_schema_offline( - alter_table_schema, orig_table_schema, new_table_schema)); + alter_table_arg, alter_table_schema, orig_table_schema, new_table_schema)); + if (FAILEDx(new_table_schema.check_validity_for_auto_partition())) { + LOG_WARN("fail to check enable auto partitioning", KR(ret), K(new_table_schema)); + } OZ (create_user_hidden_table(orig_table_schema, new_table_schema, &alter_table_arg.sequence_ddl_arg_, @@ -5362,6 +5431,7 @@ int ObDDLService::check_can_drop_column( { int ret = OB_SUCCESS; int64_t column_count = new_table_cols_cnt; + bool is_tbl_partition_key = false; if (OB_ISNULL(orig_column_schema) || OB_ISNULL(new_table_schema.get_column_schema(orig_column_name))) { ret = OB_ERR_CANT_DROP_FIELD_OR_KEY; LOG_USER_ERROR(OB_ERR_CANT_DROP_FIELD_OR_KEY, orig_column_name.length(), orig_column_name.ptr()); @@ -5387,7 +5457,10 @@ int ObDDLService::check_can_drop_column( LOG_USER_ERROR(OB_ERR_DEPENDENT_BY_FUNCTIONAL_INDEX, orig_column_name.length(), orig_column_name.ptr()); LOG_WARN("Dropping column has functional index column deps", K(ret), K(orig_column_name)); } - } else if (orig_column_schema->is_tbl_part_key_column()) { + } else if (OB_FAIL(new_table_schema.is_tbl_partition_key(*orig_column_schema, is_tbl_partition_key, + false /* ignore_presetting_key */))) { + LOG_WARN("fail to check tbl partition key", KR(ret), KPC(orig_column_schema), K(new_table_schema)); + } else if (is_tbl_partition_key) { ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "drop partitioning column is"); LOG_WARN("partitioning column is not allowed to be dropped", K(ret), K(orig_column_schema->get_column_name_str())); @@ -6894,6 +6967,7 @@ int ObDDLService::alter_table_index(obrpc::ObAlterTableArg &alter_table_arg, LOG_WARN("too many index for table!", K(index_count), K(OB_MAX_INDEX_PER_TABLE)); } if (!new_table_schema.is_partitioned_table() + && !new_table_schema.is_auto_partitioned_table() && !create_index_arg->index_schema_.is_partitioned_table()) { if (INDEX_TYPE_NORMAL_GLOBAL == create_index_arg->index_type_) { create_index_arg->index_type_ = INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE; @@ -6948,7 +7022,6 @@ int ObDDLService::alter_table_index(obrpc::ObAlterTableArg &alter_table_arg, //alter table t1 rename index ori_idx to new_idx, add index new_idx // MySQL supports this behavior is_exist = true; } - } else { if (OB_HASH_EXIST == drop_index_name_set.exist_refactored(index_key)) { //alter table t1 drop index c1, add index c1 @@ -6990,7 +7063,9 @@ int ObDDLService::alter_table_index(obrpc::ObAlterTableArg &alter_table_arg, } else if (FALSE_IT(index_schema.set_tenant_id(origin_table_schema.get_tenant_id()))) { } } - bool global_index_without_column_info = create_index_arg->index_schema_.is_partitioned_table() ? false : true; + bool global_index_without_column_info = (create_index_arg->index_schema_.is_partitioned_table() || + create_index_arg->index_schema_.is_auto_partitioned_table()) ? + false : true; bool rowkey_doc_exist = false; if (OB_FAIL(ret)) { } else if (OB_FAIL(my_arg.assign(*create_index_arg))) { @@ -8920,6 +8995,41 @@ int ObDDLService::modify_depend_column_type(sql::ObRawExpr *expr, return ret; } +int ObDDLService::modify_part_func_expr(const share::schema::ObTableSchema &orig_table_schema, + const share::schema::ObColumnSchemaV2 &orig_column_schema, + const share::schema::AlterColumnSchema &alter_column_schema, + share::schema::ObTableSchema &new_table_schema, + const common::ObTimeZoneInfo &tz_info, + common::ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + bool is_partition_key = false; + if (OB_FAIL(orig_table_schema.is_tbl_partition_key(orig_column_schema, + is_partition_key, + false /* ignore_presetting_key */))) { + LOG_WARN("fail to check is tbl partition key", KR(ret), K(orig_table_schema), K(orig_column_schema)); + } else if (is_partition_key) { + if (share::schema::PARTITION_FUNC_TYPE_KEY_IMPLICIT != orig_table_schema.get_part_option().get_part_func_type() + && orig_table_schema.get_part_option().get_part_func_expr_str().empty()) { + if (orig_table_schema.is_auto_partitioned_table()) { + // when part_func_expr is empty, + // auto-partitioned non-partitioned table will choose rowkey for data table and + // choose index columns for global index as presetting partition key. + // in this case, it is no need to modify part_func_expr + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("a partitioned table doesn't have part_fun_expr", KR(ret), K(orig_table_schema)); + } + } else if (OB_FAIL(modify_part_func_expr(orig_column_schema.get_column_name_str(), + alter_column_schema.get_column_name_str(), + new_table_schema, tz_info, allocator))) { + LOG_WARN("modify part func expr failed", KR(ret)); + } + } + + return ret; +} + int ObDDLService::modify_part_func_expr( const ObString &orig_column_name, const ObString &alter_column_name, @@ -8929,10 +9039,16 @@ int ObDDLService::modify_part_func_expr( { int ret = OB_SUCCESS; - if (!table_schema.is_partitioned_table()) { + if (!table_schema.is_partitioned_table() && !table_schema.is_auto_partitioned_table()) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid part level", K(ret), K(table_schema.get_part_level())); - } else if (PARTITION_LEVEL_ONE == table_schema.get_part_level()) { + LOG_WARN("invalid part level", KR(ret), K(table_schema.get_part_level()), + K(table_schema.get_part_option())); + } else if (share::schema::PARTITION_FUNC_TYPE_KEY_IMPLICIT != table_schema.get_part_option().get_part_func_type() + && table_schema.get_part_option().get_part_func_expr_str().empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid argument", KR(ret), K(table_schema)); + } else if (PARTITION_LEVEL_ZERO == table_schema.get_part_level() + || PARTITION_LEVEL_ONE == table_schema.get_part_level()) { if (OB_FAIL(modify_func_expr_column_name( orig_column_name, alter_column_name, table_schema, tz_info, allocator, false))) { LOG_WARN("fail to modify func expr column name", @@ -12261,6 +12377,8 @@ const char* ObDDLService::ddl_type_str(const ObDDLType ddl_type) str = "manual split by range"; } else if (DDL_MANUAL_SPLIT_NON_RANGE == ddl_type) { str = "manual split non range"; + } else if (DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION == ddl_type) { + str = "partition split recovery table redefinition"; } return str; @@ -12683,11 +12801,14 @@ int ObDDLService::fill_interval_info_for_offline(const ObTableSchema &orig_table //For truncate part/subpart, inc_table_schema and del_table_schema should be different in the later process. //For other situations, del_table_schema is useless and equal to inc_table_schema. +//For split partition, upd_table_schema records the partition information which need to be changed. +//For other situations, upd_table_schema is useless and equal to new_table_schema. int ObDDLService::generate_tables_array(const ObAlterTableArg::AlterPartitionType op_type, ObIArray &orig_table_schemas, ObIArray &new_table_schemas, ObIArray &inc_table_schemas, ObIArray &del_table_schemas, + common::ObIArray &upd_table_schemas, const ObTableSchema &orig_table_schema, ObTableSchema &new_table_schema, AlterTableSchema &inc_table_schema, @@ -12804,7 +12925,7 @@ int ObDDLService::generate_tables_array(const ObAlterTableArg::AlterPartitionTyp && FALSE_IT(new_aux_table_schema->unset_sub_part_template_def_valid())) { } else if (OB_FAIL(inc_aux_table_schema->assign(*new_aux_table_schema))) { LOG_WARN("failed to push back table_schema", KR(ret), KPC(new_aux_table_schema)); - } else if (OB_FAIL(inc_aux_table_schema->assign_partition_schema(inc_table_schema))) { + } else if (OB_FAIL(inc_aux_table_schema->assign_partition_schema_without_auto_part_attr(inc_table_schema))) { LOG_WARN("fail to assign partition schema", K(inc_table_schema), KR(ret)); } else if (OB_FAIL(inc_aux_table_schema->set_transition_point(inc_table_schema.get_transition_point()))) { LOG_WARN("fail to set transition point", K(ret)); @@ -12819,6 +12940,37 @@ int ObDDLService::generate_tables_array(const ObAlterTableArg::AlterPartitionTyp } } } + + if (OB_FAIL(ret)) { + } else if (obrpc::ObAlterTableArg::REORGANIZE_PARTITION == op_type || + obrpc::ObAlterTableArg::SPLIT_PARTITION == op_type || + obrpc::ObAlterTableArg::AUTO_SPLIT_PARTITION == op_type) { + for (int64_t i = 0; OB_SUCC(ret) && i < new_table_schemas.count(); i++) { + ObTableSchema *upd_table_schema = NULL; + void *upd_schema_ptr = allocator.alloc(sizeof(ObTableSchema)); + if (OB_ISNULL(upd_schema_ptr)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail alloc memory", KR(ret)); + } else if (FALSE_IT(upd_table_schema = new (upd_schema_ptr)ObTableSchema(&allocator))) { + } else if (OB_FAIL(upd_table_schema->assign(*new_table_schemas.at(i)))) { + LOG_WARN("fail to assign partition schema", K(new_table_schemas), KR(ret)); + } else if (FALSE_IT(upd_table_schema->reset_partition_array())) { + } else if (FALSE_IT(upd_table_schema->reset_hidden_partition_array())) { + } else if (OB_FAIL(upd_table_schemas.push_back(upd_table_schema))) { + LOG_WARN("failed to push back table_schema", KR(ret), KPC(upd_table_schema)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(generate_split_info_for_schemas_(op_type, + orig_table_schemas, inc_table_schemas, + new_table_schemas, upd_table_schemas))) { + LOG_WARN("fail to generate split info for schema", KR(ret)); + } + } else if (OB_FAIL(upd_table_schemas.assign(new_table_schemas))) { + LOG_WARN("failed to assign new_table_schemas", KR(ret), K(new_table_schemas)); + } + if (OB_FAIL(ret)) { } else if (obrpc::ObAlterTableArg::TRUNCATE_PARTITION == op_type || obrpc::ObAlterTableArg::TRUNCATE_SUB_PARTITION == op_type) { @@ -12861,11 +13013,155 @@ int ObDDLService::reset_interval_info_for_interval_to_range(ObTableSchema &new_t return ret; } +int ObDDLService::split_global_index_partitions(obrpc::ObAlterTableArg &arg, obrpc::ObAlterTableRes &res) +{ + int ret = OB_SUCCESS; + AlterTableSchema &alter_table_schema = arg.alter_table_schema_; + const uint64_t tenant_id = alter_table_schema.get_tenant_id(); + const ObTableSchema *orig_index_schema = NULL; + int64_t refreshed_schema_version = 0; + uint64_t tenant_data_version = 0; + ObDDLSQLTransaction trans(schema_service_); + ObSchemaGetterGuard schema_guard; + schema_guard.set_session_id(arg.session_id_); + + if (OB_FAIL(check_inner_stat())) { + LOG_WARN("variable is not init", KR(ret)); + } else if (OB_ISNULL(GCTX.root_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("root service is null", KR(ret)); + } else if (!arg.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", KR(ret), K(arg)); + } else if (OB_UNLIKELY(obrpc::ObAlterTableArg::AlterPartitionType::AUTO_SPLIT_PARTITION != arg.alter_part_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid alter partition type", KR(ret), K(arg.alter_part_type_), K(arg)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, tenant_data_version))) { + LOG_WARN("get min data version failed", K(ret), K(tenant_id)); + } else if (OB_FAIL(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, + schema_guard))) { + LOG_WARN("fail to get schema guard with version in inner table", KR(ret), K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_schema_version(tenant_id, refreshed_schema_version))) { + LOG_WARN("failed to get tenant schema version", KR(ret), K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, + alter_table_schema.get_origin_database_name(), + alter_table_schema.get_origin_table_name(), + true /*is_index*/, + orig_index_schema))) { + LOG_WARN("fail to get table schema", KR(ret), K(tenant_id), K(alter_table_schema)); + } else if (OB_ISNULL(orig_index_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("NULL ptr", KR(ret), K(alter_table_schema)); + } else if (OB_UNLIKELY(!orig_index_schema->is_global_index_table() || + is_sys_index_table(orig_index_schema->get_table_id()))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid index type", KR(ret), KPC(orig_index_schema)); + } else if (OB_FAIL(fill_part_name(*orig_index_schema, arg.alter_table_schema_))) { + LOG_WARN("failed to fill part name", KR(ret), K(orig_index_schema), K(arg)); + } else if (OB_FAIL(check_split_global_index_partition_(schema_guard, arg, *orig_index_schema))) { + LOG_WARN("fail to check split global idnex partition", KR(ret), KPC(orig_index_schema), K(arg)); + } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { + LOG_WARN("start transaction failed", KR(ret), K(tenant_id), K(refreshed_schema_version)); + } else { + ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); + ObArray orig_index_schemas; + ObArray new_index_schemas; + ObArray inc_index_schemas; + ObArray inc_index_schema_ptrs; + ObArray del_index_schemas; + ObArray upd_index_schemas; + ObArenaAllocator allocator("ModifyPart"); + obrpc::ObAlterTableRes res; + + HEAP_VAR(ObArray, ddl_tasks) { + HEAP_VAR(ObTableSchema, new_table_schema) { + if (OB_FAIL(new_table_schema.assign(*orig_index_schema))) { + LOG_WARN("fail to assign schema", KR(ret)); + } else if (OB_FAIL(generate_tables_array(arg.alter_part_type_, + orig_index_schemas, + new_index_schemas, + inc_index_schemas, + del_index_schemas, + upd_index_schemas, + *orig_index_schema, + new_table_schema, + alter_table_schema, + schema_guard, + allocator))) { + LOG_WARN("generate tables array failed", KR(ret), K(arg)); + } else if (OB_FAIL(alter_tables_partitions(arg, + orig_index_schemas, + new_index_schemas, + inc_index_schemas, + del_index_schemas, + upd_index_schemas, + ddl_operator, + schema_guard, + trans))) { + LOG_WARN("alter table partitions failed", KR(ret), K(arg)); + } else if (OB_FAIL(ddl_operator.inc_table_schema_version(trans, tenant_id, + orig_index_schema->get_data_table_id()))) { + LOG_WARN("fail to inc data table schema version", KR(ret), KPC(orig_index_schema)); + } else if (OB_UNLIKELY(inc_index_schemas.count() != 1) || + OB_UNLIKELY(new_index_schemas.count() != 1) || + OB_ISNULL(inc_index_schemas.at(0)) || + OB_ISNULL(new_index_schemas.at(0))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid schema arr", KR(ret), K(inc_index_schemas.count()), KP(inc_index_schemas.at(0)), + K(new_index_schemas.count()), KP(new_index_schemas.at(0))); + } else if (FALSE_IT(inc_index_schemas.at(0)->set_schema_version( + new_index_schemas.at(0)->get_schema_version()))) { + } else if (OB_FAIL(inc_index_schema_ptrs.push_back(inc_index_schemas.at(0)))) { + LOG_WARN("failed to push back", K(ret)); + } else { + const ObDDLType ddl_type = ObDDLType::DDL_AUTO_SPLIT_BY_RANGE; + ObSplitPartitionHelper split_partition_helper(trans, schema_guard, arg.allocator_, tenant_id, + tenant_data_version, ddl_type, new_index_schemas, upd_index_schemas, inc_index_schema_ptrs, arg.parallelism_); + ObDDLTaskRecord task_record; + if (OB_FAIL(split_partition_helper.execute(task_record))) { + LOG_WARN("failed to execute split partition helper", KR(ret)); + } else if (OB_FAIL(ddl_tasks.push_back(task_record))) { + LOG_WARN("failed to push back", KR(ret)); + } else { + res.ddl_type_ = ddl_type; + res.task_id_ = task_record.task_id_; + } + } + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(ddl_tasks.count() != 1)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid task number", KR(ret), K(arg), K(ddl_tasks)); + } + + const bool is_commit = OB_SUCC(ret); + if (trans.is_started()) { + int temp_ret = OB_SUCCESS; + if (OB_SUCCESS != (temp_ret = trans.end(is_commit))) { + LOG_WARN("trans end failed", K(is_commit), K(temp_ret)); + ret = is_commit ? temp_ret : ret; + } + } + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_FAIL(publish_schema(tenant_id))) { + LOG_WARN("publish_schema failed", KR(ret)); + } else if (OB_TMP_FAIL(GCTX.root_service_->get_ddl_scheduler().schedule_ddl_task(ddl_tasks.at(0)))) { + LOG_WARN("fail to schedule ddl task", K(tmp_ret), K(ddl_tasks.at(0))); + } + } + } // end HEAP_VAR(ObTableSchema, new_table_schema) + } // end HEAP_VAR(ObArray, ddl_tasks) + } + + return ret; +} + int ObDDLService::alter_tables_partitions(const obrpc::ObAlterTableArg &alter_table_arg, ObIArray &orig_table_schemas, ObIArray &new_table_schemas, ObIArray &inc_table_schemas, ObIArray &del_table_schemas, + ObIArray &upd_table_schemas, ObDDLOperator &ddl_operator, ObSchemaGetterGuard &schema_guard, ObMySQLTransaction &trans) @@ -12897,6 +13193,7 @@ int ObDDLService::alter_tables_partitions(const obrpc::ObAlterTableArg &alter_ta *orig_table_schemas.at(i), *inc_table_schemas.at(i), *del_table_schemas.at(i), + *upd_table_schemas.at(i), *new_table_schemas.at(i), ddl_operator, schema_guard, @@ -12922,6 +13219,7 @@ int ObDDLService::alter_table_partitions(const obrpc::ObAlterTableArg &alter_tab const ObTableSchema &orig_table_schema, AlterTableSchema &inc_table_schema, AlterTableSchema &del_table_schema, + ObTableSchema &upd_table_schema, ObTableSchema &new_table_schema, ObDDLOperator &ddl_operator, ObSchemaGetterGuard &schema_guard, @@ -12937,12 +13235,18 @@ int ObDDLService::alter_table_partitions(const obrpc::ObAlterTableArg &alter_tab if (OB_ISNULL(schema_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("valid schema service", K(ret)); - } else if (obrpc::ObAlterTableArg::PARTITIONED_TABLE == op_type - || obrpc::ObAlterTableArg::REORGANIZE_PARTITION == op_type - || obrpc::ObAlterTableArg::SPLIT_PARTITION == op_type) { + } else if (obrpc::ObAlterTableArg::PARTITIONED_TABLE == op_type) { ret = OB_NOT_SUPPORTED; LOG_WARN("split table partitions is not supported", KR(ret), K(orig_table_schema)); LOG_USER_ERROR(OB_NOT_SUPPORTED, "split table partitions is"); + } else if (alter_table_arg.is_split_partition()) { + if (OB_FAIL(ddl_operator.split_table_partitions(orig_table_schema, + inc_table_schema, + new_table_schema, + upd_table_schema, + trans))) { + LOG_WARN("failed to add table partitions", KR(ret)); + } } else if (obrpc::ObAlterTableArg::ADD_PARTITION == op_type) { if (OB_FAIL(ObDDLLock::lock_for_add_partition_in_trans(orig_table_schema, trans))) { LOG_WARN("failed to lock for add drop partition", K(ret)); @@ -13481,8 +13785,8 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, //table columns if (OB_SUCC(ret) && alter_table_arg.is_alter_columns_) { if (OB_FAIL(check_can_alter_column(tenant_id, - alter_table_schema, - *orig_table_schema))) { + alter_table_schema, + *orig_table_schema))) { LOG_WARN("fail to can alter column", K(ret), K(alter_table_arg)); } else if (OB_FAIL(alter_table_column(*orig_table_schema, alter_table_schema, @@ -13577,6 +13881,21 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, LOG_WARN("alter table constraints failed", K(ret)); } } + // alter auto table attr + if (OB_SUCC(ret) && alter_table_arg.alter_auto_partition_attr_) { + ObAlterAutoPartAttrOp alter_auto_part(*this); + if (OB_FAIL(check_restore_point_allow(tenant_id, *orig_table_schema))) { + LOG_WARN("check restore point allow failed,", K(ret), K(tenant_id), K(orig_table_schema->get_table_id())); + } else if (OB_FAIL(alter_auto_part.alter_table_auto_part_attr_if_need( + alter_table_arg, + ddl_type, + schema_guard, + new_table_schema, + ddl_operator, + trans))) { + LOG_WARN("fail to alter table part attr.", K(ret)); + } + } //table partitions // the first element is data_table_schema // the others element are local_index_schemas @@ -13584,8 +13903,11 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, ObArray new_table_schemas; // 1. truncate part/subpart: del_table_schemas will be deleted and inc_table_schemas will be added // 2. others: inc_table_schemas and del_table_schemas is pointed same partitions + // 3. split partition: upd_table_schemas record the partition information which need to be changed. + // 4. other situations, upd_table_schemas are useless and point to same partition with new_table_schemas. ObArray inc_table_schemas; ObArray del_table_schemas; + ObArray upd_table_schemas; ObArenaAllocator allocator("ModifyPart"); //table partitions ObArray new_partition_ids; @@ -13606,16 +13928,19 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, new_table_schemas, inc_table_schemas, del_table_schemas, + upd_table_schemas, *orig_table_schema, new_table_schema, alter_table_schema, schema_guard, allocator))) { + LOG_WARN("failed to generate tables array", KR(ret)); } else if (OB_FAIL(alter_tables_partitions(alter_table_arg, orig_table_schemas, new_table_schemas, inc_table_schemas, del_table_schemas, + upd_table_schemas, ddl_operator, schema_guard, trans))) { @@ -13672,8 +13997,7 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, ObSchemaOperationType operation_type = OB_DDL_ALTER_TABLE; if (obrpc::ObAlterTableArg::PARTITIONED_TABLE == alter_table_arg.alter_part_type_) { operation_type = OB_DDL_PARTITIONED_TABLE; - } else if (obrpc::ObAlterTableArg::SPLIT_PARTITION == alter_table_arg.alter_part_type_ - || obrpc::ObAlterTableArg::REORGANIZE_PARTITION == alter_table_arg.alter_part_type_) { + } else if (alter_table_arg.is_split_partition()) { operation_type = OB_DDL_SPLIT_PARTITION; } else if (obrpc::ObAlterTableArg::TRUNCATE_PARTITION == alter_table_arg.alter_part_type_) { operation_type = OB_DDL_TRUNCATE_PARTITION; @@ -13694,7 +14018,9 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, } if (!alter_table_arg.is_alter_partitions_) { - if (OB_FAIL(ddl_operator.update_table_attribute( + if (alter_table_arg.alter_auto_partition_attr_) { + // do nothing + } else if (OB_FAIL(ddl_operator.update_table_attribute( new_table_schema, trans, operation_type, @@ -13785,6 +14111,7 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, } if (OB_SUCC(ret)) { + const bool need_create_empty_major_sstable = !alter_table_arg.is_split_partition(); common::ObArray need_create_empty_majors; common::ObArray inc_table_schema_ptrs; common::ObArray del_table_schema_ptrs; @@ -13795,7 +14122,7 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, LOG_WARN("table_schemas is NULL", KR(ret), K(i), K(tmp_table_schema)); } else if (FALSE_IT(inc_table_schemas.at(i)->set_schema_version(new_table_schemas.at(i)->get_schema_version()))) { } else if (OB_FAIL(inc_table_schema_ptrs.push_back(tmp_table_schema)) - || OB_FAIL(need_create_empty_majors.push_back(true))) { + || OB_FAIL(need_create_empty_majors.push_back(need_create_empty_major_sstable))) { LOG_WARN("fail to push back", KR(ret), KPC(tmp_table_schema)); } } @@ -13853,7 +14180,7 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, ObNewTableTabletAllocator new_table_tablet_allocator(tenant_id, schema_guard, sql_proxy_); if (OB_ISNULL(tmp_table_schema)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("table schem is null", KR(ret), K(inc_table_schema_ptrs)); + LOG_WARN("table schema is null", KR(ret), K(inc_table_schema_ptrs)); } else if (OB_FAIL(table_creator.init(need_check_tablet_cnt))) { LOG_WARN("fail to init table creator", KR(ret)); } else if (OB_FAIL(new_table_tablet_allocator.init())) { @@ -13866,24 +14193,39 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, inc_table_schema_ptrs, ls_id_array, tenant_data_version, - need_create_empty_majors/*need_create_empty_major_sstable*/))) { + need_create_empty_majors/*need_create_empty_majors*/))) { LOG_WARN("create table partitions failed", KR(ret), K(alter_table_schema), - K(inc_table_schema_ptrs)); + K(inc_table_schema_ptrs)); } else if (OB_FAIL(table_creator.execute())) { LOG_WARN("execute create partition failed", KR(ret)); } } } + + if (OB_SUCC(ret) && alter_table_arg.is_split_partition()) { + // TODO(zhenhan.gzh): modify ddl_type based on split type(auto/manual) and part_type + const ObDDLType ddl_type = alter_table_arg.is_auto_split_partition() ? ObDDLType::DDL_AUTO_SPLIT_BY_RANGE : ObDDLType::DDL_MANUAL_SPLIT_BY_RANGE; + ObSplitPartitionHelper split_partition_helper(trans, schema_guard, alter_table_arg.allocator_, tenant_id, + tenant_data_version, ddl_type, new_table_schemas, upd_table_schemas, inc_table_schema_ptrs, alter_table_arg.parallelism_); + ObDDLTaskRecord task_record; + if (OB_FAIL(split_partition_helper.execute(task_record))) { + LOG_WARN("failed to execute split partition helper", KR(ret)); + } else if (OB_FAIL(ddl_tasks.push_back(task_record))) { + LOG_WARN("failed to push back", KR(ret)); + } else { + res.ddl_type_ = ddl_type; + res.task_id_ = task_record.task_id_; + } + } } if (OB_FAIL(ret)) { - } else if (obrpc::ObAlterTableArg::PARTITIONED_TABLE == alter_table_arg.alter_part_type_ - || obrpc::ObAlterTableArg::REORGANIZE_PARTITION == alter_table_arg.alter_part_type_ - || obrpc::ObAlterTableArg::SPLIT_PARTITION == alter_table_arg.alter_part_type_) { + } else if (obrpc::ObAlterTableArg::PARTITIONED_TABLE == alter_table_arg.alter_part_type_) { ret = OB_NOT_SUPPORTED; LOG_WARN("split partition is not supported", KR(ret), K(alter_table_schema)); LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition is"); } + if (OB_SUCC(ret) && alter_table_schema.alter_option_bitset_.has_member(ObAlterTableArg::INCREMENT_MODE) && 0 != orig_table_schema->get_autoinc_column_id()) { @@ -14116,6 +14458,9 @@ int ObDDLService::alter_table_in_trans(obrpc::ObAlterTableArg &alter_table_arg, ret = is_commit ? temp_ret : ret; } } + + DEBUG_SYNC(AFTER_CREATE_SPLIT_TASK); + if (OB_SUCC(ret)) { int tmp_ret = OB_SUCCESS; if (OB_FAIL(publish_schema(tenant_id))) { @@ -14212,6 +14557,15 @@ int ObDDLService::check_is_offline_ddl(ObAlterTableArg &alter_table_arg, ddl_type))) { LOG_WARN("fail to check alter table partition", K(ret)); } + if (OB_SUCC(ret) && alter_table_arg.alter_auto_partition_attr_) { + ObAlterAutoPartAttrOp alter_auto_table(*this); + if (OB_FAIL(alter_auto_table.check_alter_table_partition_attr(alter_table_arg, + *orig_table_schema, + is_oracle_mode, + ddl_type))) { + LOG_WARN("fail to check alter table partition", K(ret)); + } + } if (OB_SUCC(ret)) { if (OB_FAIL(check_alter_column_group(alter_table_arg, ddl_type))) { LOG_WARN("fail to check alter column gorup", K(ret), K(alter_table_arg.alter_table_schema_), K(ddl_type)); @@ -14731,6 +15085,30 @@ int ObDDLService::do_offline_ddl_in_trans(obrpc::ObAlterTableArg &alter_table_ar LOG_WARN("failed to alter table partition by", K(ret)); } } + if (OB_SUCC(ret) && alter_table_arg.alter_auto_partition_attr_) { + const bool bind_tablets = false; + ObAlterAutoPartAttrOp alter_auto_part(*this); + // In the alter table partition by range(xxx) size(xxx) (partitions...) case, + // it is necessary to modify attributes related to automatic partitioning here. + if (OB_FAIL(check_restore_point_allow(tenant_id, *orig_table_schema))) { + LOG_WARN("check restore point allow failed,", K(ret), K(tenant_id), + K(orig_table_schema->get_table_id())); + } else if (OB_FAIL(alter_auto_part.alter_table_partition_attr( + alter_table_arg, *orig_table_schema, new_table_schema))) { + LOG_WARN("failed to alter table partition by", K(ret)); + } else if (OB_FAIL(create_user_hidden_table(*orig_table_schema, + new_table_schema, + &alter_table_arg.sequence_ddl_arg_, + bind_tablets, + schema_guard, + schema_guard, + ddl_operator, + trans, + alter_table_arg.allocator_, + tenant_data_version))) { + LOG_WARN("fail to create user_hidden table", K(ret)); + } + } // table constraints if (OB_SUCC(ret) && alter_table_arg.alter_constraint_type_ != obrpc::ObAlterTableArg::CONSTRAINT_NO_OPERATION) { @@ -15904,7 +16282,6 @@ int ObDDLService::check_alter_partitions(const ObTableSchema &orig_table_schema, } else if (OB_FAIL(orig_table_schema.check_has_local_index(schema_guard, has_local_index))) { LOG_WARN("fail to check_has_local_index", K(ret), K(has_local_index)); } else if (obrpc::ObAlterTableArg::PARTITIONED_TABLE == alter_part_type - && obrpc::ObAlterTableArg::SPLIT_PARTITION == alter_part_type && obrpc::ObAlterTableArg::REPARTITION_TABLE == alter_part_type && obrpc::ObAlterTableArg::PARTITIONED_PARTITION == alter_part_type) { ret = OB_OP_NOT_ALLOW; @@ -15950,6 +16327,10 @@ int ObDDLService::check_alter_partitions(const ObTableSchema &orig_table_schema, LOG_WARN("failed to check drop partition", K(ret), K(orig_table_schema), K(alter_table_arg)); } is_drop_or_truncate = true; + } else if (alter_table_arg.is_split_partition()) { + if (OB_FAIL(check_alter_split_partitions(orig_table_schema, alter_table_arg))) { + LOG_WARN("failed to check split paritions", K(ret), K(orig_table_schema), K(alter_table_arg)); + } } else if (obrpc::ObAlterTableArg::RENAME_PARTITION == alter_part_type) { if (OB_FAIL(check_alter_rename_partitions_(orig_table_schema, alter_table_arg))) { LOG_WARN("failed to check rename partition", KR(ret), K(orig_table_schema), K(alter_table_arg)); @@ -16442,6 +16823,379 @@ int ObDDLService::check_alter_add_partitions(const share::schema::ObTableSchema return ret; } +int ObDDLService::check_alter_split_partitions(const share::schema::ObTableSchema &orig_table_schema, + obrpc::ObAlterTableArg &alter_table_arg) +{ + int ret = OB_SUCCESS; + AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; + const uint64_t tenant_id = orig_table_schema.get_tenant_id(); + ObPartitionLevel target_part_level = alter_table_arg.is_auto_split_partition() ? + orig_table_schema.get_target_part_level_for_auto_partitioned_table() : + orig_table_schema.get_part_level(); + + if (alter_table_arg.is_auto_split_partition() && !orig_table_schema.is_auto_partitioned_table()) { + // the table might be disabled auto-partition after trigger auto splitting partition + ret = OB_OP_NOT_ALLOW; + LOG_WARN("attempt to auto split partition for non-auto-partitioned table", KR(ret), + K(alter_table_arg), + K(orig_table_schema)); + } else if (OB_FAIL(orig_table_schema.check_enable_split_partition(alter_table_arg.is_auto_split_partition()))) { + LOG_WARN("fail to check enable split partition", KR(ret), K(orig_table_schema)); + } else if (OB_FAIL(check_split_partition_val_(orig_table_schema, alter_table_schema, + target_part_level, alter_table_arg.alter_part_type_))) { + LOG_WARN("fail to check split partition val", KR(ret), K(orig_table_schema), K(alter_table_arg)); + } else if (OB_FAIL(check_split_partition_name_(orig_table_schema, alter_table_schema, target_part_level))) { + LOG_WARN("fail to check split partition name", KR(ret), K(orig_table_schema), K(alter_table_arg)); + } + + return ret; +} + +int ObDDLService::check_split_partition_val_(const share::schema::ObTableSchema &orig_table_schema, + const AlterTableSchema &alter_table_schema, + const ObPartitionLevel target_part_level, + const obrpc::ObAlterTableArg::AlterPartitionType type) +{ + int ret = OB_SUCCESS; + const ObPartitionLevel ori_part_level = orig_table_schema.get_part_level(); + ObPartition **split_part_array = alter_table_schema.get_part_array(); + const int64_t split_part_num = alter_table_schema.get_partition_num(); + + if (OB_ISNULL(split_part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("split_part_array is null", KR(ret), K(orig_table_schema), K(alter_table_schema)); + } else if (PARTITION_LEVEL_ONE == target_part_level) { + if (PARTITION_LEVEL_ZERO == ori_part_level) { + // only auto partitioning could run here, user could not manual split non-partitioned table + if (obrpc::ObAlterTableArg::AUTO_SPLIT_PARTITION != type) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("invalid operate", KR(ret), K(orig_table_schema), K(alter_table_schema), K(type)); + } else if (OB_FAIL(check_split_partitions_from_same_source_(split_part_array, split_part_num, + 0, split_part_num, + orig_table_schema, + target_part_level, + type))) { + LOG_WARN("fail to check split partitions from same source partition", KR(ret), + K(target_part_level), + K(orig_table_schema), + K(alter_table_schema)); + } + } else if (PARTITION_LEVEL_ONE == ori_part_level) { + // in future, we need to support to split multiple partitions, which means the split_part_array + // might include various set of split partitions from different source partitions. + // thus, we need to: + // 1. divide split partitions into different sets based on split_source_tablet_id + // 2. check whether each set is valid. + // moreover, we assume that the split partitions from same source is continued in the split_part_array. + common::hash::ObHashSet traversed_source_ids; + + if (OB_ISNULL(split_part_array[0])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", KR(ret)); + } else if (OB_FAIL(traversed_source_ids.create(hash::cal_next_prime(split_part_num)))) { + LOG_WARN("fail to create hashset", KR(ret)); + } else if (OB_FAIL(traversed_source_ids.set_refactored(split_part_array[0]->get_split_source_tablet_id().id(), 0 /*flag*/))) { + LOG_WARN("fail to set tablet_id", KR(ret), KPC(split_part_array[0])); + } else { + int64_t start_idx = 0; // the first idx of a set of same source splitting partitions + bool traverse_same_source_over = false; // traverse a set of same source splitting partitions over + + for (int64_t i = 0; OB_SUCC(ret) && i < split_part_num; ++i) { + ObPartition *split_part = split_part_array[i]; + if (!split_part->get_split_source_tablet_id().is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid source_tablet_id", KR(ret), KPC(split_part)); + } else if (i == split_part_num - 1) { + traverse_same_source_over = true; + } else if (OB_ISNULL(split_part_array[i+1])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", KR(ret), K(alter_table_schema)); + } else if (split_part_array[i+1]->get_split_source_tablet_id() != split_part->get_split_source_tablet_id()) { + traverse_same_source_over = true; + // TODO: + // we don't support to split multiple source partitions from same table in the meanwhile now. + // when we support the online ddl lock, we need to delete the following error code + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split multiple source partitions", KR(ret), K(alter_table_schema)); + } + + if (OB_FAIL(ret)) { + } else if (traverse_same_source_over) { + if (OB_FAIL(check_split_partitions_from_same_source_(split_part_array, split_part_num, + start_idx, i+1, + orig_table_schema, + target_part_level, + type))) { + LOG_WARN("fail to check split partitions from same source partition", KR(ret), + K(target_part_level), + K(orig_table_schema), + K(alter_table_schema)); + } else if (i != split_part_num - 1) { + ObTabletID curr_source_tablet_id = split_part_array[i+1]->get_split_source_tablet_id(); + start_idx = i + 1; + traverse_same_source_over = false; + if (OB_FAIL(traversed_source_ids.set_refactored(curr_source_tablet_id.id(), 0 /*flag*/))) { + // it means the split parts from same source part are not continuous in array + if (ret == OB_HASH_EXIST) { + LOG_WARN("split part array should be sorted by source_tablet_id", KR(ret), K(curr_source_tablet_id.id()), + K(alter_table_schema)); + } else { + LOG_WARN("fail to set tablet_id", KR(ret), K(curr_source_tablet_id)); + } + } + } + } // end if (traverse_same_source_over) + } // end for + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(ori_part_level), K(target_part_level), + K(alter_table_schema), K(orig_table_schema)); + } + } else if (PARTITION_LEVEL_TWO == target_part_level) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split subpartition", KR(ret), K(alter_table_schema), K(orig_table_schema)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(ori_part_level), + K(alter_table_schema), K(orig_table_schema)); + } + + return ret; +} + +// 1. the number of a set of split partition must be between [2, SPLIT_NUM_LIMIT] +// 2. source_tablet_id must exist in origin table schema +// 3. split partition array should be sorted by high_bound_val +// 4. if the table is range partition, the high_bound_val range of split partitions should be equal to that of source partition +int ObDDLService::check_split_partitions_from_same_source_(ObPartition **split_part_array, + const int64_t part_array_size, + const int64_t start, const int64_t end, + const share::schema::ObTableSchema &orig_table_schema, + const ObPartitionLevel target_part_level, + const obrpc::ObAlterTableArg::AlterPartitionType type) +{ + int ret = OB_SUCCESS; + const ObPartitionLevel ori_part_level = orig_table_schema.get_part_level(); + const ObPartitionOption &part_option = orig_table_schema.get_part_option(); + ObPartition **orig_part_array = orig_table_schema.get_part_array(); + const int64_t orig_part_num = orig_table_schema.get_partition_num(); + const int64_t split_part_num = end - start; + static const int64_t MANUAL_SPLIT_NUM_LIMIT = INT64_MAX; // not limit the number of manual splitting partition + static const int64_t AUTO_SPLIT_NUM_LIMIT = 2; + const int64_t SPLIT_NUM_LIMIT = obrpc::ObAlterTableArg::AUTO_SPLIT_PARTITION == type ? + AUTO_SPLIT_NUM_LIMIT : MANUAL_SPLIT_NUM_LIMIT; + + if (end > part_array_size || end <= start || start < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid interval", KR(ret), K(start), K(end), K(part_array_size)); + } else if (split_part_num < 2) { + ret = OB_ERR_SPLIT_INTO_ONE_PARTITION; + LOG_WARN("split partition number is invalid", KR(ret), K(split_part_num)); + } else if (split_part_num > SPLIT_NUM_LIMIT) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("invalid splitting partition number", KR(ret), K(split_part_num), K(SPLIT_NUM_LIMIT), K(type)); + char buffer[number::ObNumber::MAX_PRINTABLE_SIZE] = {0}; + (void)snprintf(buffer, sizeof(buffer), "%s splitting partition number more than %ld is", + obrpc::ObAlterTableArg::AUTO_SPLIT_PARTITION == type ? "auto" : "manual", + SPLIT_NUM_LIMIT); + LOG_USER_ERROR(OB_NOT_SUPPORTED, buffer); + } else if (orig_table_schema.is_partitioned_table() + && !orig_table_schema.is_valid_split_part_type()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("only support to split range part", KR(ret), K(orig_table_schema)); + } else { + // check sorting by value + for (int64_t i = start; OB_SUCC(ret) && i < end; ++i) { + ObPartition *split_part = split_part_array[i]; + if (OB_ISNULL(split_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", KR(ret)); + } else if (i > 0 && !ObBasePartition::range_like_func_less_than(split_part_array[i-1], split_part)) { + ret = OB_ERR_RANGE_NOT_INCREASING_ERROR; + LOG_WARN("range values should increasing", KR(ret), K(split_part_array[i-1]->get_high_bound_val()), + K(split_part_array[i]->get_high_bound_val())); + } + } + } + + // check existence of source_tablet_id and value validity of split partitions + if (OB_FAIL(ret)) { + } else if (PARTITION_LEVEL_ONE == target_part_level) { + if (PARTITION_LEVEL_ZERO == ori_part_level) { + for (int64_t i = start; OB_SUCC(ret) && i < end; ++i) { + const ObPartition *split_part = split_part_array[i]; + if (split_part->get_split_source_tablet_id() != orig_table_schema.get_tablet_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("source_tablet_id is invalid", KR(ret), K(split_part->get_split_source_tablet_id()), + K(orig_table_schema.get_table_id())); + } + } + } else if (PARTITION_LEVEL_ONE == ori_part_level) { + const ObTabletID source_tablet_id = split_part_array[start]->get_split_source_tablet_id(); + const ObPartition *part = NULL; + bool find = false; + + for (int64_t j = 0; !find && OB_SUCC(ret) && j < orig_part_num; ++j) { + part = orig_part_array[j]; + if (OB_ISNULL(part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", KR(ret)); + } else if (part->get_tablet_id() == source_tablet_id) { // check existence + find = true; + // check boundary + const ObRowkey& min_val = split_part_array[start]->get_high_bound_val(); + const ObRowkey& max_val = split_part_array[end - 1]->get_high_bound_val(); + if (max_val != part->get_high_bound_val()) { + ret = OB_ERR_RANGE_NOT_INCREASING_ERROR; + LOG_WARN("the value of last partition is not equal the origin range", KR(ret), K(max_val), KPC(part)); + } else if (j != 0 && min_val <= orig_part_array[j - 1]->get_high_bound_val()) { + ret = OB_ERR_RANGE_NOT_INCREASING_ERROR; + LOG_WARN("the value of split partition conflicts with existent partition", KR(ret), K(min_val), + KPC(orig_part_array[j - 1])); + } + } + } // end for + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(!find)) { + ret = OB_UNKNOWN_PARTITION; + LOG_WARN("source_tablet_id not exists in origin table", KR(ret), K(source_tablet_id), K(orig_table_schema)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(target_part_level), K(ori_part_level)); + } + } else if (PARTITION_LEVEL_TWO == target_part_level) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported the part level", KR(ret), K(target_part_level), K(ori_part_level)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(target_part_level), K(ori_part_level)); + } + + return ret; +} + +// the name of split patitions should be different with other partitions' name +// except that of its source partition +int ObDDLService::check_split_partition_name_(const share::schema::ObTableSchema &orig_table_schema, + const AlterTableSchema &alter_table_schema, + const ObPartitionLevel target_part_level) +{ + int ret = OB_SUCCESS; + const ObPartitionLevel ori_part_level = orig_table_schema.get_part_level(); + ObPartition **split_part_array = alter_table_schema.get_part_array(); + const int64_t split_part_num = alter_table_schema.get_partition_num(); + + if (OB_ISNULL(split_part_array)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(alter_table_schema)); + } else if (split_part_num < 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(split_part_num)); + } else { + ObArenaAllocator allocator; + ObPartition** sorted_part_array; + if (OB_ISNULL(sorted_part_array = static_cast(allocator.alloc( + sizeof(ObPartition*) * (split_part_num))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc", KR(ret), K(split_part_num)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < split_part_num; ++i) { + sorted_part_array[i] = split_part_array[i]; + } + ob_sort(sorted_part_array, sorted_part_array + split_part_num, ObPartitionNameCmp(CS_TYPE_UTF8MB4_GENERAL_CI)); + } + + ObString last_split_part_name; + const ObPartition *ori_part = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < split_part_num; ++i) { + ObPartition *split_part = sorted_part_array[i]; + if (OB_ISNULL(split_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", KR(ret)); + } else if (split_part->is_empty_partition_name()) { + // will be generated part name in fill_part_name() of ObDDLService + } else if (!last_split_part_name.empty() + && ObCharset::case_insensitive_equal(split_part->get_part_name(), + last_split_part_name)) { + ret = OB_ERR_SAME_NAME_PARTITION; + LOG_WARN("duplicate partition name in split part array", KR(ret), "part name", split_part->get_part_name()); + LOG_USER_ERROR(OB_ERR_SAME_NAME_PARTITION, split_part->get_part_name().length(), + split_part->get_part_name().ptr()); + } else if (PARTITION_LEVEL_ONE == target_part_level) { + if (PARTITION_LEVEL_ZERO == ori_part_level) { + } else if (PARTITION_LEVEL_ONE != ori_part_level) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(ori_part_level), K(target_part_level)); + } else if (OB_FAIL(orig_table_schema.get_partition_by_name(split_part->get_part_name(), + ori_part))) { + if (OB_UNLIKELY(ret != OB_UNKNOWN_PARTITION)) { + LOG_WARN("fail to get partition by name", KR(ret), KPC(split_part)); + } else { + ret = OB_SUCCESS; + } + } else if (OB_ISNULL(ori_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", KR(ret)); + } else if (ori_part->get_tablet_id() != split_part->get_split_source_tablet_id()) { + ret = OB_ERR_SAME_NAME_PARTITION; + LOG_WARN("duplicate partition name with orign part array", KR(ret), + "part name", split_part->get_part_name()); + LOG_USER_ERROR(OB_ERR_SAME_NAME_PARTITION, split_part->get_part_name().length(), + split_part->get_part_name().ptr()); + } + if (OB_SUCC(ret)) { + last_split_part_name = split_part->get_part_name(); + } + } else if (PARTITION_LEVEL_TWO == target_part_level) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split subpartition", KR(ret), K(ori_part_level), K(target_part_level), + K(orig_table_schema), K(alter_table_schema)); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(ori_part_level), K(target_part_level), + K(orig_table_schema), K(alter_table_schema)); + } + } // end for + } + + return ret; +} + +int ObDDLService::check_split_global_index_partition_(ObSchemaGetterGuard &schema_guard, + obrpc::ObAlterTableArg &arg, + const share::schema::ObTableSchema &orig_index_schema) +{ + int ret = OB_SUCCESS; + bool is_db_in_recyclebin = false; + uint64_t tenant_id = orig_index_schema.get_tenant_id(); + + if (OB_FAIL(schema_guard.check_database_in_recyclebin( + tenant_id, + orig_index_schema.get_database_id(), + is_db_in_recyclebin))) { + LOG_WARN("check database in recyclebin failed", KR(ret), K(tenant_id), K(orig_index_schema)); + } else if (OB_UNLIKELY(is_db_in_recyclebin)) { + ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT; + LOG_WARN("database is in recyclebin", KR(ret), K(orig_index_schema)); + } else if (OB_UNLIKELY(orig_index_schema.is_in_recyclebin())) { + // when drop data table, the related index of it will be moved to recyclebin; + // when drop index, the index will be removed directly + ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT; + LOG_WARN("index table is in recyclebin", KR(ret), K(orig_index_schema)); + } else if (!orig_index_schema.check_can_do_ddl()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("offline ddl is being executed, other ddl operations are not allowed", KR(ret), K(orig_index_schema)); + } else if (OB_FAIL(check_restore_point_allow(tenant_id, orig_index_schema))) { + LOG_WARN("check restore point allow failed,", KR(ret), K(tenant_id), K(orig_index_schema.get_table_id())); + } else if (OB_FAIL(check_alter_partitions(orig_index_schema, arg))) { + LOG_WARN("check alter partitions failed", KR(ret), K(orig_index_schema), K(arg)); + } + return ret; +} + int ObDDLService::check_alter_add_subpartitions(const share::schema::ObTableSchema &orig_table_schema, const obrpc::ObAlterTableArg &alter_table_arg) { @@ -16744,9 +17498,11 @@ int ObDDLService::alter_table(obrpc::ObAlterTableArg &alter_table_arg, ObDDLType &ddl_type = res.ddl_type_; bool &ddl_need_retry_at_executor = res.ddl_need_retry_at_executor_; ddl_type = DDL_INVALID; + if (OB_FAIL(check_inner_stat())) { LOG_WARN("variable is not init", K(ret)); } + ObSimpleTableSchemaV2 orig_table; if (OB_SUCC(ret)) { AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; @@ -18863,6 +19619,7 @@ int ObDDLService::add_new_index_schema(obrpc::ObAlterTableArg &alter_table_arg, } ObCreateIndexArg *create_index_arg = static_cast(index_arg); if (!new_table_schema.is_partitioned_table() + && !new_table_schema.is_auto_partitioned_table() && !create_index_arg->index_schema_.is_partitioned_table()) { if (INDEX_TYPE_NORMAL_GLOBAL == create_index_arg->index_type_) { create_index_arg->index_type_ = INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE; @@ -18913,7 +19670,6 @@ int ObDDLService::add_new_index_schema(obrpc::ObAlterTableArg &alter_table_arg, //alter table t1 add index c1, add index c1 is_exist = true; } - } else { if (OB_HASH_EXIST == drop_index_name_set.exist_refactored(index_key)) { //alter table t1 drop index c1, add index c1 @@ -19109,6 +19865,7 @@ int ObDDLService::reconstruct_index_schema(obrpc::ObAlterTableArg &alter_table_a const uint64_t dst_tenant_id = hidden_table_schema.get_tenant_id(); bool is_oracle_mode = false; ObSchemaService *schema_service = schema_service_->get_schema_service(); + if (OB_FAIL(check_inner_stat())) { LOG_WARN("variable is not init", K(ret)); } else if (OB_ISNULL(schema_service)) { @@ -19160,9 +19917,29 @@ int ObDDLService::reconstruct_index_schema(obrpc::ObAlterTableArg &alter_table_a } else if (need_rebuild) { ObString new_index_table_name; HEAP_VAR(ObTableSchema, new_index_schema) { + int64_t rebuild_index_arg_schema_id = OB_INVALID_ID; // No need to convert hidden table column id since indexes are rebuilt based on column names. - if (OB_FAIL(new_index_schema.assign(*index_table_schema))) { - LOG_WARN("fail to assign schema", K(ret)); + for (int64_t i = 0; OB_SUCC(ret) && rebuild_index_arg_schema_id == OB_INVALID_ID + && i < alter_table_arg.rebuild_index_arg_list_.count(); ++i) { + const int64_t tmp_index_id = alter_table_arg.rebuild_index_arg_list_.at(i).get_table_id(); + if (tmp_index_id == index_table_schema->get_table_id()) { + rebuild_index_arg_schema_id = i; + } + } + if (OB_FAIL(ret)) { + } else if (rebuild_index_arg_schema_id != OB_INVALID_ID) { + if (OB_FAIL(new_index_schema.assign(alter_table_arg.rebuild_index_arg_list_.at(rebuild_index_arg_schema_id)))) { + LOG_WARN("fail to assign schema", K(ret)); + } else { + // set rebuild index arg schema as old index_table_schema + index_table_schema = &alter_table_arg.rebuild_index_arg_list_.at(rebuild_index_arg_schema_id); + } + } else { + if (OB_FAIL(new_index_schema.assign(*index_table_schema))) { + LOG_WARN("fail to assign schema", K(ret)); + } + } + if (OB_FAIL(ret)) { } else if (FALSE_IT(new_index_schema.set_tenant_id(hidden_table_schema.get_tenant_id()))) { } else if (OB_FAIL(gen_new_index_table_name( index_table_schema->get_table_name_str(), @@ -19209,12 +19986,17 @@ int ObDDLService::reconstruct_index_schema(obrpc::ObAlterTableArg &alter_table_a } else if (OB_FAIL(gen_hidden_index_schema_columns( *index_table_schema, drop_cols_id_arr, col_name_map, new_table_schema, new_index_schema))) { LOG_WARN("failed to gen hidden index schema", K(ret)); - } else if (hidden_table_schema.get_part_level() > 0 && new_index_schema.is_index_local_storage() - && OB_FAIL(new_index_schema.assign_partition_schema(hidden_table_schema))) { + } else if ((hidden_table_schema.get_part_level() > 0 || hidden_table_schema.is_auto_partitioned_table()) + && new_index_schema.is_index_local_storage() + && OB_FAIL(new_index_schema.assign_partition_schema_without_auto_part_attr(hidden_table_schema))) { LOG_WARN("fail to assign partition schema", K(ret), K(new_index_schema)); } else { uint64_t new_idx_tid = OB_INVALID_ID; - if (OB_FAIL(schema_service->fetch_new_table_id( + ObAlterAutoPartAttrOp alter_auto_part(*this); + if (new_index_schema.is_global_index_table() + && OB_FAIL(alter_auto_part.alter_global_indexes_auto_part_attribute_offline(alter_table_arg, new_index_schema))) { + LOG_WARN("fail to alter global index auto split perproty", K(ret), K(new_index_schema)); + } else if (OB_FAIL(schema_service->fetch_new_table_id( dst_tenant_id, new_idx_tid))) { LOG_WARN("failed to fetch_new_table_id", K(ret)); } else if (OB_FAIL(generate_object_id_for_partition_schema(new_index_schema))) { @@ -19903,7 +20685,7 @@ int ObDDLService::swap_all_child_table_fk_name( ddl_operator, trans, allocator))) { - LOG_WARN("fail to swap child table fk name", K(ret));; + LOG_WARN("fail to swap child table fk name", K(ret)); } } } @@ -20792,9 +21574,10 @@ int ObDDLService::swap_orig_and_hidden_table_state(obrpc::ObAlterTableArg &alter if (OB_FAIL(owner_id.convert_from_value(ObLockOwnerType::DEFAULT_OWNER_TYPE, alter_table_arg.task_id_))) { LOG_WARN("failed to get owner id", K(ret), K(alter_table_arg.task_id_)); } else if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id, - orig_table_schema->get_table_id(), - owner_id, - trans))) { + orig_table_schema->get_table_id(), + nullptr/*hidden_tablet_ids_alone*/, + owner_id, + trans))) { LOG_WARN("failed to unlock ddl", K(ret)); } } @@ -20926,6 +21709,7 @@ int ObDDLService::swap_orig_and_hidden_table_partitions(obrpc::ObAlterTableArg & LOG_WARN("failed to get owner id", K(ret), K(alter_table_arg.task_id_)); } else if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id, orig_table_schema->get_table_id(), + nullptr/*hidden_tablet_ids_alone*/, owner_id, trans))) { LOG_WARN("failed to unlock ddl", K(ret)); @@ -21505,8 +22289,8 @@ int ObDDLService::modify_hidden_table_fk_state(obrpc::ObAlterTableArg &alter_tab return ret; } - int ObDDLService::modify_hidden_table_not_null_column_state(const obrpc::ObAlterTableArg &alter_table_arg) - { +int ObDDLService::modify_hidden_table_not_null_column_state(const obrpc::ObAlterTableArg &alter_table_arg) +{ int ret = OB_SUCCESS; const AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; const uint64_t tenant_id = alter_table_schema.get_tenant_id(); @@ -21613,6 +22397,181 @@ int ObDDLService::modify_hidden_table_fk_state(obrpc::ObAlterTableArg &alter_tab return ret; } +int ObDDLService::restore_the_table_to_split_completed_state(obrpc::ObAlterTableArg &alter_table_arg) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = alter_table_arg.alter_table_schema_.get_tenant_id(); + const uint64_t dest_tenant_id = alter_table_arg.alter_table_schema_.get_tenant_id(); + const int64_t data_table_id = alter_table_arg.table_id_; + int64_t new_task_id = 0; + uint64_t tenant_data_version = 0; + int64_t refreshed_schema_version = 0; + ObDDLTaskRecord task_record; + ObRootService *root_service = GCTX.root_service_; + ObSchemaGetterGuard schema_guard; + const ObTableSchema *orig_data_table_schema = nullptr; + const ObDatabaseSchema *orig_database_schema = nullptr; + ObArray task_ids; + ObArray table_ids; + ObTableLockOwnerID new_owner_id; + ObDDLSQLTransaction trans(schema_service_); + if (OB_UNLIKELY(!alter_table_arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("alter_table_arg is invalid", K(ret), K(alter_table_arg)); + } else if (OB_ISNULL(root_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, root service must not be nullptr", K(ret)); + } else if (OB_FAIL(check_inner_stat())) { + LOG_WARN("variable is not init", K(ret)); + } else if (OB_FAIL(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { + LOG_WARN("fail to get schema guard with version in inner table", K(ret), K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, data_table_id, orig_data_table_schema))) { + LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(data_table_id)); + } else if (OB_ISNULL(orig_data_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("orig data table schema is null", K(ret), K(tenant_id), K(data_table_id)); + } else if (OB_UNLIKELY(orig_data_table_schema->is_aux_table())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("orig data table schema is aux table", K(ret), K(tenant_id), K(data_table_id)); + } else if (OB_INVALID_ID != orig_data_table_schema->get_association_table_id()) { + LOG_INFO("the two tables offline ddl are being executed.", K(ret), K(orig_data_table_schema->get_association_table_id()), K(orig_data_table_schema->get_table_id())); + } else if (OB_FAIL(schema_guard.get_database_schema(tenant_id, orig_data_table_schema->get_database_id(), orig_database_schema))) { + LOG_WARN("fail to get orig database schema", K(ret), K(tenant_id), K(orig_data_table_schema->get_database_id())); + } else if (OB_ISNULL(orig_database_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("orig_database_schema is null", K(ret)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, tenant_data_version))) { + LOG_WARN("get min data version failed", K(ret), K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_schema_version(tenant_id, refreshed_schema_version))) { + LOG_WARN("failed to get tenant schema version", K(ret), K(tenant_id)); + } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { + LOG_WARN("start transaction failed", K(ret), K(tenant_id), K(refreshed_schema_version)); + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service->get_sql_proxy(), tenant_id, new_task_id))) { + LOG_WARN("fetch new task id failed", K(ret), K(tenant_id)); + } else if (OB_FAIL(new_owner_id.convert_from_value(ObLockOwnerType::DEFAULT_OWNER_TYPE, new_task_id))) { + LOG_WARN("failed to get new owner id", K(ret), K(new_task_id)); + } else if (OB_FAIL(ObDDLUtil::get_global_index_table_ids(*orig_data_table_schema, table_ids, schema_guard))) { + LOG_WARN("fail to get global index table ids", K(ret), K(orig_data_table_schema)); + } else if (OB_FAIL(table_ids.push_back(orig_data_table_schema->get_table_id()))) { + LOG_WARN("fail to push back", K(ret), K(orig_data_table_schema->get_table_id())); + } else if (OB_FAIL(ObDDLTaskRecordOperator::get_partition_split_task_ids(trans, tenant_id, table_ids, task_ids))) { + LOG_WARN("failed to get partition split task ids", K(ret), K(tenant_id), K(table_ids)); + } else { + //1、设置当前table的处于DDL_PARTITION_SPLIT状态的task任务状态设置为WAIT_PARTITION_SPLIT_RECOVERY_TASK_FINISH, 等待新表完成补数据任务 + //2、依次根据task_id获取task_record, 根据record在ObPartitionSplitTask中初始化, 解除相应ddl锁, 并且替换掉表级锁 + common::ObArenaAllocator allocator; + for (int64_t i = 0; OB_SUCC(ret) && i < task_ids.count(); i++) { + ObDDLTaskStatus new_status = WAIT_PARTITION_SPLIT_RECOVERY_TASK_FINISH; + if (OB_FAIL(ObDDLTaskRecordOperator::update_task_status(trans, dest_tenant_id, task_ids.at(i), static_cast(new_status)))) { + LOG_WARN("update task status failed", K(ret), K(dest_tenant_id), K(task_ids.at(i)), K(new_status)); + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < task_ids.count(); i++) { + const ObTableSchema *table_schema = nullptr; + ObDDLTaskRecord old_split_task_record; + ObArray src_tablet_ids; + ObArray dst_tablet_ids; + ObTableLockOwnerID old_owner_id; + HEAP_VAR(ObPartitionSplitTask, split_task) { + if (OB_FAIL(ObDDLTaskRecordOperator::get_ddl_task_record(tenant_id, + task_ids.at(i), + root_service->get_sql_proxy(), + allocator, + old_split_task_record))) { + LOG_WARN("get ddl task record failed", K(ret), K(tenant_id), K(task_ids.at(i))); + } else if (OB_FAIL(split_task.init(old_split_task_record))) { + LOG_WARN("init partition split task failed", K(ret), K(old_split_task_record)); + } else if (OB_FAIL(split_task.get_src_tablet_ids(src_tablet_ids))) { + LOG_WARN("fail to get all src tablet ids", K(ret)); + } else if (OB_FAIL(split_task.get_dest_tablet_ids(dst_tablet_ids))) { + LOG_WARN("fail to get all dest tablet ids", K(ret)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, split_task.get_object_id(), table_schema))) { + LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(split_task.get_object_id())); + } else if (OB_ISNULL(table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table schema is null", K(ret), K(tenant_id), K(table_schema)); + } else if (OB_FAIL(old_owner_id.convert_from_value(ObLockOwnerType::DEFAULT_OWNER_TYPE, task_ids.at(i)))) { + LOG_WARN("failed to get old owner id", K(ret), K(task_ids.at(i))); + } else if (OB_FAIL(ObDDLLock::replace_lock_for_split_partition(*table_schema, + src_tablet_ids, + dst_tablet_ids, + old_owner_id, + new_owner_id, + trans))) { + LOG_WARN("fail to replace lock for split partition", K(ret)); + } + } + } + if (OB_SUCC(ret)) { + HEAP_VAR(ObTableSchema, new_table_schema) { + if (OB_FAIL(new_table_schema.assign(*orig_data_table_schema))) { + LOG_WARN("fail to assign schema", K(ret)); + } else { + new_table_schema.set_tenant_id(dest_tenant_id); + new_table_schema.set_table_state_flag(ObTableStateFlag::TABLE_STATE_OFFLINE_DDL); + new_table_schema.reset_hidden_partition_array(); + bool bind_tablets = true; + ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); + if (OB_FAIL(create_user_hidden_table( + *orig_data_table_schema, + new_table_schema, + nullptr, + bind_tablets, + schema_guard, + schema_guard, + ddl_operator, + trans, + allocator, + tenant_data_version))) { + LOG_WARN("fail to create hidden table", K(ret)); + } else { + LOG_INFO("create hidden table success!", K(ret)); + common::ObArenaAllocator allocator_for_restore(lib::ObLabel("RestoreSplit")); + alter_table_arg.task_id_ = new_task_id; + ObCreateDDLTaskParam param(tenant_id, + ObDDLType::DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION, + orig_data_table_schema, + &new_table_schema, + data_table_id, + new_table_schema.get_schema_version(), + alter_table_arg.parallelism_, + alter_table_arg.consumer_group_id_, + &allocator_for_restore, + &alter_table_arg, + 0, + new_task_id); + param.tenant_data_version_ = tenant_data_version; + if (OB_FAIL(root_service->get_ddl_scheduler().create_ddl_task(param, trans, task_record))) { + LOG_WARN("submit ddl task failed", K(ret)); + } else if (ObTableStateFlag::TABLE_STATE_OFFLINE_DDL == orig_data_table_schema->get_table_state_flag()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("offline ddl is being executed, other ddl operations are not allowed, create hidden table fail", K(ret), K(alter_table_arg)); + } + } + } + } + } + } + if (trans.is_started()) { + int temp_ret = OB_SUCCESS; + if (OB_SUCCESS != (temp_ret = trans.end(OB_SUCC(ret)))) { + LOG_WARN("trans end failed", "is_commit", OB_SUCCESS == ret, K(temp_ret)); + ret = (OB_SUCC(ret)) ? temp_ret : ret; + } + } + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_FAIL(publish_schema(tenant_id))) { + LOG_WARN("publish_schema failed", K(ret)); + } else if (OB_TMP_FAIL(root_service->get_ddl_scheduler().schedule_ddl_task(task_record))) { + LOG_WARN("fail to schedule ddl task", K(tmp_ret), K(task_record)); + } else { + LOG_INFO("schedule ddl task success"); + } + } + return ret; +} + int ObDDLService::cleanup_garbage(ObAlterTableArg &alter_table_arg) { int ret = OB_SUCCESS; @@ -21684,7 +22643,9 @@ int ObDDLService::cleanup_garbage(ObAlterTableArg &alter_table_arg) // if the previous step fails, the newly created hidden table should be deleted. // if the previous steps are successful, the original table is changed to a hidden table // so regardless of success or failure, only need to delete the hidden table - new_hidden_table_schema.set_association_table_id(OB_INVALID_ID); + if (share::PARTITION_SPLIT_RECOVERY_CLEANUP_GARBAGE_TASK != alter_table_arg.ddl_task_type_) { + new_hidden_table_schema.set_association_table_id(OB_INVALID_ID); + } new_hidden_table_schema.set_in_offline_ddl_white_list(true); if (!ddl_succ) { if (OB_FAIL(unbind_hidden_tablets(*orig_table_schema, *hidden_table_schema, @@ -21725,10 +22686,56 @@ int ObDDLService::cleanup_garbage(ObAlterTableArg &alter_table_arg) if (OB_FAIL(owner_id.convert_from_value(ObLockOwnerType::DEFAULT_OWNER_TYPE, alter_table_arg.task_id_))) { LOG_WARN("failed to get owner id", K(ret), K(alter_table_arg.task_id_)); + } else if (share::PARTITION_SPLIT_RECOVERY_CLEANUP_GARBAGE_TASK == alter_table_arg.ddl_task_type_) { + ObArray tablet_ids; + const ObPartitionLevel part_level = orig_table_schema->get_part_level(); + const int64_t part_num = orig_table_schema->get_hidden_partition_num(); + ObPartition **part_array = orig_table_schema->get_hidden_part_array(); + if (OB_ISNULL(part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", K(ret), KPC(orig_table_schema)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < part_num; ++i) { + if (OB_ISNULL(part_array[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", K(ret), K(i), KPC(orig_table_schema)); + } else if (PARTITION_LEVEL_ONE == part_level) { + if (OB_FAIL(tablet_ids.push_back(part_array[i]->get_tablet_id()))) { + LOG_WARN("fail to push back tablet id", K(ret), K(i), K(part_array[i]->get_tablet_id())); + } + } else if (PARTITION_LEVEL_TWO == part_level) { + ObSubPartition **sub_part_array = part_array[i]->get_hidden_subpart_array(); + int64_t sub_part_num = part_array[i]->get_hidden_subpartition_num(); + if (OB_ISNULL(sub_part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", K(ret), KPC(orig_table_schema)); + } else { + for (int64_t j = 0; OB_SUCC(ret) && j < sub_part_num; j++) { + if (OB_ISNULL(sub_part_array[j])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", K(ret), K(j), KPC(orig_table_schema)); + } else if (OB_FAIL(tablet_ids.push_back(sub_part_array[j]->get_tablet_id()))) { + LOG_WARN("fail to push back tablet id", K(ret), K(j), K(sub_part_array[j]->get_tablet_id())); + } + } + } + } + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id, + orig_table_schema->get_table_id(), + &tablet_ids, + owner_id, + trans))) { + LOG_WARN("failed to unlock ddl", K(ret)); + } + } } else if (OB_FAIL(ObDDLLock::unlock_for_offline_ddl(tenant_id, - orig_table_schema->get_table_id(), - owner_id, - trans))) { + orig_table_schema->get_table_id(), + nullptr/*hidden_tablet_ids_alone*/, + owner_id, + trans))) { LOG_WARN("failed to unlock ddl", K(ret)); } } @@ -22141,7 +23148,7 @@ int ObDDLService::new_truncate_table_in_trans(const ObIArrayget_tenant_id(); table_name = orig_table_schemas.at(0)->get_table_name(); @@ -25738,6 +26745,7 @@ int ObDDLService::rebuild_index(const ObRebuildIndexArg &arg, obrpc::ObAlterTabl bool is_db_in_recyclebin = false; int64_t refreshed_schema_version = 0; schema_guard.set_session_id(arg.session_id_); + if (check_inner_stat()) { ret = OB_INNER_STAT_ERROR; LOG_WARN("check_inner_stat error", K(is_inited()), KR(ret)); @@ -25855,6 +26863,272 @@ int ObDDLService::rebuild_index(const ObRebuildIndexArg &arg, obrpc::ObAlterTabl return ret; } +int ObDDLService::clean_splitted_tablet(const obrpc::ObCleanSplittedTabletArg &arg) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg.tenant_id_; + ObArenaAllocator allocator; + ObArray splitting_table_schemas; + ObArray del_table_schemas; + ObDDLSQLTransaction trans(schema_service_); + ObDDLOperator ddl_operator(*schema_service_, *sql_proxy_); + int64_t refreshed_schema_version = 0; + ObSEArray src_data_tablet_id; + + if (check_inner_stat()) { + ret = OB_INNER_STAT_ERROR; + LOG_WARN("check_inner_stat error", K(is_inited()), KR(ret)); + } else if (OB_FAIL(generate_splitted_schema_array(arg, allocator, + splitting_table_schemas, + del_table_schemas, + refreshed_schema_version))) { + LOG_WARN("fail to generate splitted schema array", KR(ret), K(arg)); + } else if (OB_UNLIKELY(splitting_table_schemas.count() != del_table_schemas.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema's number is different", KR(ret), + K(splitting_table_schemas.count()), + K(del_table_schemas.count())); + } else if (OB_FAIL(trans.start(sql_proxy_, tenant_id, refreshed_schema_version))) { + LOG_WARN("start transaction failed", KR(ret), K(tenant_id), K(refreshed_schema_version)); + } else { + // modify schema + for (int64_t i = 0; OB_SUCC(ret) && i < splitting_table_schemas.count(); i++) { + if (OB_ISNULL(splitting_table_schemas.at(i)) || OB_ISNULL(del_table_schemas.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), KPC(splitting_table_schemas.at(i)), + KPC(del_table_schemas.at(i))); + } else if (OB_FAIL(ddl_operator.drop_table_splitted_partitions(*splitting_table_schemas.at(i), + *del_table_schemas.at(i), + trans))) { + LOG_WARN("failed to drop split source partitions", KR(ret), + KPC(splitting_table_schemas.at(i)), + KPC(del_table_schemas.at(i))); + } + } + // inc data_table's schema version when index or lob schema has been updated + if (OB_SUCC(ret)) { + if (splitting_table_schemas.empty() || OB_ISNULL(splitting_table_schemas.at(0))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid array", K(splitting_table_schemas.count()), KPC(splitting_table_schemas.at(0))); + } else if (splitting_table_schemas.count() > 1 || splitting_table_schemas.at(0)->is_global_index_table()) { + uint64_t data_table_id = splitting_table_schemas.at(0)->is_global_index_table() ? + splitting_table_schemas.at(0)->get_data_table_id() : + splitting_table_schemas.at(0)->get_table_id(); + if (OB_FAIL(ddl_operator.inc_table_schema_version(trans, tenant_id, data_table_id))) { + LOG_WARN("fail to inc data table schema version", KR(ret), K(arg), K(data_table_id), + KPC(splitting_table_schemas.at(0))); + } + } + } + } + + if (OB_SUCC(ret)) { + ObTableLockOwnerID owner_id; + owner_id.convert_from_value(arg.task_id_); + if (OB_FAIL(src_data_tablet_id.push_back(arg.src_table_tablet_id_))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(ObDDLLock::unlock_for_split_partition(*splitting_table_schemas.at(0), src_data_tablet_id, arg.dest_tablet_ids_, owner_id, trans))) { + LOG_WARN("failed to unlock for split partition", K(ret)); + } + } + + // drop tablets + if (OB_SUCC(ret)) { + int64_t new_schema_version = 0; + if (OB_FAIL(schema_service_->get_new_schema_version(tenant_id, new_schema_version))) { + LOG_WARN("failed to get new schema_version", KR(ret), K(tenant_id)); + } else if (OB_FAIL(ObSplitPartitionHelper::clean_split_src_and_dst_tablet(arg, splitting_table_schemas.at(0)->get_auto_part_size(), new_schema_version, trans))) { + LOG_WARN("failed to clean split dst tablet mds", K(ret)); + } + } + + const bool is_commit = OB_SUCC(ret); + if (trans.is_started()) { + int temp_ret = OB_SUCCESS; + if (OB_SUCCESS != (temp_ret = trans.end(is_commit))) { + LOG_WARN("trans end failed", K(is_commit), K(temp_ret)); + ret = is_commit ? temp_ret : ret; + } + } + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + if (OB_FAIL(publish_schema(tenant_id))) { + LOG_WARN("publish_schema failed", K(ret)); + } + } + return ret; +} + +// "splitting_table_schemas" records the current table_schema. +// the first table_schema in the array is of data_table/global_index and the others are local_index schema or lob schema. +// "del_table_schemas" records the deleting partition of table_schemas. +int ObDDLService::generate_splitted_schema_array( + const obrpc::ObCleanSplittedTabletArg &arg, + ObArenaAllocator& allocator, + common::ObIArray &splitting_table_schemas, + common::ObIArray &del_table_schemas, + int64_t &refreshed_schema_version) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg.tenant_id_; + uint64_t table_id = arg.table_id_; + ObSchemaGetterGuard schema_guard; + const ObTableSchema *splitting_table_schema = NULL; + bool is_db_in_recyclebin = false; + bool is_index = false; + int64_t del_table_schema_num = 1 + arg.local_index_table_ids_.count() + arg.lob_table_ids_.count(); + splitting_table_schemas.reset(); + del_table_schemas.reset(); + refreshed_schema_version = 0; + + if (OB_FAIL(get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { + LOG_WARN("get_schema_guard failed", KR(ret)); + } else if (OB_FAIL(schema_guard.get_schema_version(tenant_id, refreshed_schema_version))) { + LOG_WARN("failed to get tenant schema version", KR(ret), K(tenant_id)); + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, table_id, splitting_table_schema))) { + LOG_WARN("failed to get table schema", K(arg), KR(ret)); + } else if (OB_ISNULL(splitting_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table not found", K(arg), KR(ret)); + } else if (splitting_table_schema->is_in_recyclebin()) { + ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT; + LOG_WARN("the table is in recyclebin.", KR(ret), K(arg), KPC(splitting_table_schema)); + } else if (OB_FAIL(schema_guard.check_database_in_recyclebin(tenant_id, + splitting_table_schema->get_database_id(), + is_db_in_recyclebin))) { + LOG_WARN("check database in recyclebin failed", KR(ret), K(tenant_id), KPC(splitting_table_schema)); + } else if (is_db_in_recyclebin) { + ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT; + LOG_WARN("the database in recyclebin", KR(ret), K(arg), KPC(splitting_table_schema)); + } else if (OB_UNLIKELY(splitting_table_schema->get_part_level() == PARTITION_LEVEL_TWO)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("split subpartition is not supported", KR(ret), KPC(splitting_table_schema)); + } else if (OB_UNLIKELY(splitting_table_schema->get_part_level() == PARTITION_LEVEL_ZERO)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the splitting table is non-partitioned", KR(ret), KPC(splitting_table_schema)); + } else if (!splitting_table_schema->is_user_table() && !splitting_table_schema->is_global_index_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table type", K(ret), KPC(splitting_table_schema)); + } else if (splitting_table_schema->is_global_index_table() && del_table_schema_num > 1 ) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("global index should not have aux tables", KR(ret), K(arg), KPC(splitting_table_schema)); + } + + if (OB_SUCC(ret)) { + for (int64_t i = 0; OB_SUCC(ret) && i < del_table_schema_num; ++i) { + int64_t index = 0; + ObTabletID splitted_tablet_id; + const ObTableSchema *splitting_schema = nullptr; + + if (i == 0) { + // data table or global index + splitting_schema = splitting_table_schema; + splitted_tablet_id = arg.src_table_tablet_id_; + } else if (i < arg.local_index_table_ids_.count() + 1) { + index = i - 1; + splitted_tablet_id = arg.src_local_index_tablet_ids_.at(index); + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, + arg.local_index_table_ids_.at(index), + splitting_schema))) { + LOG_WARN("get_table_schema failed", K(tenant_id), K(splitted_tablet_id), KR(ret)); + } + } else { + index = i - arg.local_index_table_ids_.count() - 1; + splitted_tablet_id = arg.src_lob_tablet_ids_.at(index); + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, + arg.lob_table_ids_.at(index), + splitting_schema))) { + LOG_WARN("get_table_schema failed", K(tenant_id), K(splitted_tablet_id), KR(ret)); + } + } + + ObTableSchema *del_schema = nullptr; + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(splitting_schema) || !splitted_tablet_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid argument", KR(ret), K(splitted_tablet_id), KPC(splitting_schema)); + } else if (OB_FAIL(splitting_table_schemas.push_back(splitting_schema))) { + LOG_WARN("fail to push back", KR(ret), KPC(splitting_schema)); + } else if (OB_FAIL(generate_splitted_schema_from_partitioned_table( + allocator, splitted_tablet_id, + *splitting_schema, del_schema))) { + LOG_WARN("fail to generate splitted schema from partitioned table", KR(ret), K(splitted_tablet_id), + KPC(splitting_schema)); + } else if (OB_ISNULL(del_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), K(splitted_tablet_id), KPC(splitting_schema)); + } else if (OB_FAIL(del_table_schemas.push_back(del_schema))) { + LOG_WARN("fail to push back", KR(ret)); + } + } + } + return ret; +} + +int ObDDLService::generate_splitted_schema_from_partitioned_table( + ObArenaAllocator& allocator, + const ObTabletID splitted_tablet_id, + const share::schema::ObTableSchema &splitting_table_schema, + share::schema::ObTableSchema *&del_table_schema) +{ + int ret = OB_SUCCESS; + del_table_schema = NULL; + ObPartition** hidden_part_array = splitting_table_schema.get_hidden_part_array(); + const ObPartition* splitted_part = nullptr; + + if (OB_UNLIKELY(splitting_table_schema.get_part_level() != PARTITION_LEVEL_ONE)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the splitting table is not partitioned table", KR(ret), K(splitting_table_schema)); + } else if (OB_ISNULL(hidden_part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && splitted_part == nullptr + && i < splitting_table_schema.get_hidden_partition_num(); i++) { + if (OB_ISNULL(hidden_part_array[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret)); + } else if (hidden_part_array[i]->get_tablet_id() == splitted_tablet_id) { + splitted_part = hidden_part_array[i]; + } + } + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(splitted_part)) { + ret = OB_UNKNOWN_PARTITION; + LOG_WARN("fail to find splitted partition in hidden part array", KR(ret), K(splitted_tablet_id), + K(splitting_table_schema)); + } else if (splitted_part->get_partition_type() != PARTITION_TYPE_SPLIT_SOURCE) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the partition is not split source partition", KR(ret), KPC(splitted_part), K(splitting_table_schema)); + } + } + + void *del_schema_ptr = allocator.alloc(sizeof(ObTableSchema)); + ObPartition mock_part; + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(del_schema_ptr)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail alloc memory", KR(ret)); + } else if (FALSE_IT(del_table_schema = new (del_schema_ptr)ObTableSchema(&allocator))) { + } else if (OB_FAIL(del_table_schema->assign(splitting_table_schema))) { + LOG_WARN("failed to push back table_schema", KR(ret), K(splitting_table_schema)); + } else if (FALSE_IT(del_table_schema->reset_partition_array())) { + } else if (FALSE_IT(del_table_schema->reset_hidden_partition_array())) { + } else if (FALSE_IT(del_table_schema->get_part_option().set_part_num(1))) { + } else if (OB_FAIL(mock_part.assign(*splitted_part))) { + LOG_WARN("fail to assign partition", KR(ret), KPC(splitted_part)); + } else if (FALSE_IT(mock_part.set_partition_type(PARTITION_TYPE_NORMAL))) { + // we mock the hidden source partition as a normal partition for adapting to + // the function of dropping partitions in inner_table and dropping tablets which + // will traverse all "normal" partitions and drop them based on identifier. + } else if (OB_FAIL(del_table_schema->add_partition(mock_part))) { + LOG_WARN("fail to add hidden partition", KR(ret), K(mock_part)); + } + + return ret; +} + // Rebuild index information is written to the internal table within a transaction // If sql_trans is NULL, you need to create a transaction inside the function int ObDDLService::drop_directly_and_create_index_schema_( @@ -25872,6 +27146,7 @@ int ObDDLService::drop_directly_and_create_index_schema_( ObMySQLTransaction &trans = OB_ISNULL(sql_trans) ? tmp_trans : *sql_trans; const uint64_t tenant_id = index_schema.get_tenant_id(); int64_t refreshed_schema_version = 0; + if (OB_ISNULL(schema_service)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("schema_service must not null", KR(ret)); @@ -25903,7 +27178,6 @@ int ObDDLService::drop_directly_and_create_index_schema_( false/*need_check_tablet_cnt*/, tenant_data_version))) { LOG_WARN("create_table_in_trans failed", K(index_schema), KR(ret), K(ddl_stmt_str)); } - if (OB_ISNULL(sql_trans) && trans.is_started()) { int temp_ret = OB_SUCCESS; if (OB_SUCCESS != (temp_ret = trans.end(OB_SUCC(ret)))) { @@ -40753,11 +42027,12 @@ int ObDDLService::prepare_change_modify_column_online(AlterColumnSchema &alter_c } if (OB_SUCC(ret) && orig_column_schema->get_column_name_str() != alter_column_schema.get_column_name_str()) { - if (orig_column_schema->is_tbl_part_key_column() - && OB_FAIL(modify_part_func_expr(orig_column_schema->get_column_name_str(), - alter_column_schema.get_column_name_str(), - new_table_schema, - *tz_info_wrap.get_time_zone_info(), allocator))) { + if (OB_FAIL(modify_part_func_expr(origin_table_schema, + *orig_column_schema, + alter_column_schema, + new_table_schema, + *tz_info_wrap.get_time_zone_info(), + allocator))) { LOG_WARN("modify part func expr failed", K(ret)); } else if (OB_FAIL(modify_part_func_expr_for_global_index( *orig_column_schema, alter_column_schema, new_table_schema, @@ -40791,6 +42066,130 @@ int ObDDLService::prepare_change_modify_column_online(AlterColumnSchema &alter_c return ret; } +// in generate_tables_array(), inc_aux_table_schema is copied from inc_table_schema which leads to partitions of inc_aux_table_schema +// recored the split_source_tablet_id of data table's partition rathan than that of aux table. +// thus, we need to correct split_source_tablet_id of inc_aux_table_schema's partition based on partition name. +int ObDDLService::correct_source_tablet_id_for_inc_aux_table_schema_( + const obrpc::ObAlterTableArg::AlterPartitionType op_type, + const ObPartitionLevel target_part_level, + const ObTableSchema &table_schema, + const ObTableSchema &aux_table_schema, + const AlterTableSchema &inc_table_schema, + ObTableSchema &inc_aux_table_schema) +{ + int ret = OB_SUCCESS; + const ObPartitionLevel ori_part_level = table_schema.get_part_level(); + int orig_table_part_num = table_schema.get_partition_num(); + int orig_aux_table_part_num = aux_table_schema.get_partition_num(); + int inc_aux_table_part_num = inc_aux_table_schema.get_partition_num(); + ObPartition **orig_table_parts = table_schema.get_part_array(); + ObPartition **orig_aux_table_parts = aux_table_schema.get_part_array(); + ObPartition **inc_aux_table_parts = inc_aux_table_schema.get_part_array(); + + if (obrpc::ObAlterTableArg::SPLIT_PARTITION != op_type + && obrpc::ObAlterTableArg::AUTO_SPLIT_PARTITION != op_type + && obrpc::ObAlterTableArg::REORGANIZE_PARTITION != op_type) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid type", KR(ret), K(op_type)); + } else if (OB_UNLIKELY(orig_table_part_num != orig_aux_table_part_num)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid partition num", KR(ret), K(orig_table_part_num), K(orig_aux_table_part_num)); + } else if (target_part_level == PARTITION_LEVEL_TWO) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to build part schema for aux table with subpartition", KR(ret)); + } else if (target_part_level != PARTITION_LEVEL_ONE) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(ori_part_level), K(target_part_level)); + } else { // target_part_level == PARTITION_LEVEL_ONE + if (ori_part_level == PARTITION_LEVEL_ZERO) { + for (int64_t i = 0; OB_SUCC(ret) && i < inc_aux_table_part_num; i++) { + ObPartition *inc_aux_part = inc_aux_table_parts[i]; + + if (OB_ISNULL(inc_aux_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition is NULL", KR(ret), K(inc_aux_table_schema)); + } else if (!aux_table_schema.get_tablet_id().is_valid()) { // never run here + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src_aux_table_tablet_id is invalid", KR(ret), K(aux_table_schema.get_tablet_id())); + } else { + inc_aux_part->set_split_source_tablet_id(aux_table_schema.get_tablet_id()); + } + } + } else if (ori_part_level == PARTITION_LEVEL_ONE) { + if (OB_UNLIKELY(!table_schema.is_valid_split_part_type())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("only support to split range or range column part", KR(ret), K(table_schema)); + } else { + hash::ObHashMap source_tablet_id_map; + + if (OB_FAIL(source_tablet_id_map.create(orig_table_part_num, lib::ObLabel("SourceIdMap")))) { + LOG_WARN("failed to create source tablet id map", KR(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < orig_table_part_num; i++) { + ObPartition *orig_table_part = orig_table_parts[i]; + if (OB_ISNULL(orig_table_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition is NULL", KR(ret)); + } else if (OB_FAIL(source_tablet_id_map.set_refactored(orig_table_part->get_tablet_id(), i))) { + LOG_WARN("fail to set map", KR(ret), KPC(orig_table_part)); + } + } + } + + if (OB_SUCC(ret)) { + ObTabletID src_table_tablet_id; + ObTabletID src_aux_table_tablet_id; + + for (int64_t i = 0; OB_SUCC(ret) && i < inc_aux_table_part_num; i++) { + ObPartition *inc_aux_part = inc_aux_table_parts[i]; + int64_t ori_part_index = 0; + if (OB_ISNULL(inc_aux_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition is NULL", KR(ret)); + } else if (inc_aux_part->get_split_source_tablet_id() != src_table_tablet_id) { + src_table_tablet_id = inc_aux_part->get_split_source_tablet_id(); + if (OB_FAIL(source_tablet_id_map.get_refactored(src_table_tablet_id, ori_part_index))) { + LOG_WARN("fail to get part idx", KR(ret), K(src_table_tablet_id), K(table_schema)); + } else if (OB_ISNULL(orig_aux_table_parts[ori_part_index])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partition is NULL", KR(ret), K(inc_aux_table_schema)); + } else if (orig_table_parts[ori_part_index]->get_high_bound_val() != + orig_aux_table_parts[ori_part_index]->get_high_bound_val()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to find source partition in aux table", + KR(ret), KPC(inc_aux_part), + KPC(orig_table_parts[ori_part_index]), + KPC(orig_aux_table_parts[ori_part_index]), + K(table_schema), + K(aux_table_schema)); + } else { + src_aux_table_tablet_id = orig_aux_table_parts[ori_part_index]->get_tablet_id(); + } + } /* else { + the inc_aux_part is split from the same tablet with previous inc_aux_part, + no need to update src_aux_table_tablet_id + } */ + + if (OB_SUCC(ret)) { + if (!src_aux_table_tablet_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src_aux_table_tablet_id is invalid", KR(ret), K(src_table_tablet_id), + K(inc_aux_part->get_split_source_tablet_id())); + } else { + inc_aux_part->set_split_source_tablet_id(src_aux_table_tablet_id); + } + } + } // end for + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(target_part_level), K(ori_part_level)); + } + } + return ret; +} + int ObDDLService::drop_column_online( const ObTableSchema &origin_table_schema, ObTableSchema &new_table_schema, const ObString &orig_column_name, ObDDLOperator &ddl_operator, ObSchemaGetterGuard &schema_guard, @@ -40889,9 +42288,13 @@ int ObDDLService::prepare_change_modify_column_offline(AlterColumnSchema &alter_ origin_table_schema.get_table_name_str().length(), origin_table_schema.get_table_name_str().ptr()); LOG_WARN("unknown column", K(ret), K(orig_column_name), K(new_table_schema)); - } else if (orig_column_schema->is_tbl_part_key_column() && !is_contain_part_key) { - is_contain_part_key = true; - if (OB_FAIL(new_table_schema.assign_partition_schema(alter_table_schema))) { + } else if (!is_contain_part_key) { + if (OB_FAIL(origin_table_schema.is_tbl_partition_key(*orig_column_schema, is_contain_part_key, + false /* ignore_presetting_key */))) { + LOG_WARN("fail to check is partition key", KR(ret), K(origin_table_schema), KPC(orig_column_schema)); + } else if (is_contain_part_key + && OB_FAIL(new_table_schema.assign_partition_schema_without_auto_part_attr(alter_table_schema))) { + // the auto_part_attr of alter_table_schema is default value, no need to assign invalid attributes LOG_WARN("failed to assign partition schema", K(ret)); } } @@ -40930,13 +42333,12 @@ int ObDDLService::prepare_change_modify_column_offline(AlterColumnSchema &alter_ } if (OB_SUCC(ret) && orig_column_schema->get_column_name_str() != alter_column_schema.get_column_name_str()) { - if (orig_column_schema->is_tbl_part_key_column() - && OB_FAIL(modify_part_func_expr( - orig_column_schema->get_column_name_str(), - alter_column_schema.get_column_name_str(), - new_table_schema, - *tz_info_wrap.get_time_zone_info(), - allocator))) { + if (OB_FAIL(modify_part_func_expr(origin_table_schema, + *orig_column_schema, + alter_column_schema, + new_table_schema, + *tz_info_wrap.get_time_zone_info(), + allocator))) { LOG_WARN("modify part func expr failed", K(ret)); } else if (OB_FAIL(modify_part_func_expr_for_global_index( *orig_column_schema, @@ -40986,6 +42388,436 @@ int ObDDLService::prepare_change_modify_column_offline(AlterColumnSchema &alter_ return ret; } +int ObDDLService::generate_split_info_for_schemas_(const obrpc::ObAlterTableArg::AlterPartitionType type, + ObIArray& ori_table_schemas, + ObIArray& inc_table_schemas, + ObIArray& new_table_schemas, + ObIArray& upd_table_schemas) +{ + int ret = OB_SUCCESS; + ObPartitionLevel target_part_level = ObPartitionLevel::PARTITION_LEVEL_MAX; + + if (OB_UNLIKELY(ori_table_schemas.count() != inc_table_schemas.count() || + ori_table_schemas.count() != new_table_schemas.count() || + ori_table_schemas.count() != upd_table_schemas.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schemas' number is different", KR(ret), K(ori_table_schemas.count()), K(inc_table_schemas.count()), + K(new_table_schemas.count()), K(upd_table_schemas.count())); + } else if (OB_UNLIKELY(ori_table_schemas.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("empty schemas", KR(ret)); + } else if (OB_ISNULL(ori_table_schemas.at(0))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret)); + } else if (OB_UNLIKELY(ori_table_schemas.at(0)->is_global_index_table() && ori_table_schemas.count() != 1)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("global index should not have aux table", KR(ret), KPC(ori_table_schemas.at(0)), K(ori_table_schemas.count())); + } else if (FALSE_IT(target_part_level = obrpc::ObAlterTableArg::AUTO_SPLIT_PARTITION == type ? + ori_table_schemas.at(0)->get_target_part_level_for_auto_partitioned_table() : + ori_table_schemas.at(0)->get_part_level())) { + } else if (target_part_level == PARTITION_LEVEL_TWO) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split subpartition", KR(ret), K(type), K(target_part_level), + K(ori_table_schemas.at(0)->get_part_level())); + } else if (target_part_level != PARTITION_LEVEL_ONE) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(type), K(target_part_level), + K(ori_table_schemas.at(0)->get_part_level()), + KPC(ori_table_schemas.at(0))); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < new_table_schemas.count(); ++i) { + if (OB_ISNULL(new_table_schemas.at(i)) || OB_ISNULL(inc_table_schemas.at(i)) + || OB_ISNULL(ori_table_schemas.at(i)) || OB_ISNULL(upd_table_schemas.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema ptr is NULL", KR(ret), K(new_table_schemas.at(i)), K(inc_table_schemas.at(i)), + K(ori_table_schemas.at(i)), K(upd_table_schemas.at(i))); + } else if (i > 0 && OB_FAIL(correct_source_tablet_id_for_inc_aux_table_schema_(type, + target_part_level, + *ori_table_schemas.at(0), + *ori_table_schemas.at(i), + *inc_table_schemas.at(0), + *inc_table_schemas.at(i)))) { + LOG_WARN("fail to correct source tablet id", KR(ret), + KPC(ori_table_schemas.at(0)), + KPC(ori_table_schemas.at(i)), + KPC(inc_table_schemas.at(0)), + KPC(inc_table_schemas.at(i))); + } else if (OB_FAIL(generate_split_info_for_schema_(target_part_level, + *ori_table_schemas.at(i), + *inc_table_schemas.at(i), + *new_table_schemas.at(i), + *upd_table_schemas.at(i)))) { + LOG_WARN("generate split info failed", KR(ret), + KPC(ori_table_schemas.at(i)), + KPC(inc_table_schemas.at(i)), + KPC(new_table_schemas.at(i)), + KPC(upd_table_schemas.at(i))); + } + } + + if (OB_FAIL(ret)) { + } else if (new_table_schemas.count() > 1) { + // keep partition setting of aux table be same with data table + ObTableSchema* new_table_schema = new_table_schemas.at(0); + if (OB_ISNULL(new_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret)); + } else { + ObPartitionOption& new_table_option = new_table_schema->get_part_option(); + + for (int64_t i = 1; OB_SUCC(ret) && i < new_table_schemas.count(); ++i) { + ObTableSchema* new_aux_table_schema = new_table_schemas.at(i); + if (OB_ISNULL(new_aux_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret)); + } else { + ObPartitionOption& new_aux_table_option = new_aux_table_schema->get_part_option(); + new_aux_table_option.set_part_func_type(new_table_option.get_part_func_type()); + const ObString& part_func_expr = new_table_option.get_part_func_expr_str(); + if (OB_FAIL(new_aux_table_option.set_part_expr(part_func_expr))) { + LOG_WARN("fail to set part expr", KR(ret), K(part_func_expr)); + } + } + } // end for + } + } + } + return ret; +} + +// 1. new_table_schema records the setting of table, +// 1.1 set part_num +// 1.2 set part_level +// 1.3 for auto-partitioned non-partitioned data_table/glbal_index, set part_func_expr and partition key +// 2. inc_table_schema records the setting of split partitions, +// 2.1 set part_idx of inc_table_schema, part_idx should keep partial order based on the value of partition key +// 2.2 generate part_id and tablet_id +// 2.3 for auto-partitioned non-partitioned data_table/glbal_index, genarate hidden part to mock a part with source tablet +// 3. upd_table_schema records the setting of changed origin partitions +// (only partitioned table has upd_table_schema) +// 3.1 set part_idx (need to be sorted with inc_table_schema) +// 3.2 set partition_type for source tablet (to be hidden part) +int ObDDLService::generate_split_info_for_schema_(const ObPartitionLevel target_part_level, + const ObTableSchema& ori_table_schema, + ObTableSchema& inc_table_schema, + ObTableSchema& new_table_schema, + ObTableSchema& upd_table_schema) +{ + int ret = OB_SUCCESS; + const ObPartitionLevel part_level = ori_table_schema.get_part_level(); + const int64_t ori_part_num = ori_table_schema.get_part_option().get_part_num(); + const int64_t inc_part_num = inc_table_schema.get_part_option().get_part_num(); + const int64_t all_part_num = ori_part_num + inc_part_num - 1; + new_table_schema.get_part_option().set_part_num(all_part_num); + new_table_schema.set_part_level(target_part_level); + + if (target_part_level== PARTITION_LEVEL_ONE) { + if (part_level == PARTITION_LEVEL_ZERO) { + if (OB_FAIL(generate_partition_info_from_non_partitioned_table_(ori_table_schema, + inc_table_schema, + new_table_schema))) { + LOG_WARN("fail to generate split partition info from non-partitioned table", KR(ret), + K(ori_table_schema), + K(inc_table_schema), + K(new_table_schema)); + } + } else if (part_level == PARTITION_LEVEL_ONE) { + if (OB_FAIL(generate_partition_info_from_partitioned_table_(ori_table_schema, inc_table_schema, + upd_table_schema))) { + LOG_WARN("fail to generate split partition info from non-partitioned table", KR(ret), + K(ori_table_schema), + K(inc_table_schema), + K(upd_table_schema)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(part_level), K(target_part_level)); + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("invalid part level", KR(ret), K(part_level), K(target_part_level), K(ori_table_schema)); + } + + // generate part id and tablet id for new splitting partitions + if (OB_FAIL(ret)) { + } else if (OB_FAIL(generate_object_id_for_partition_schema(inc_table_schema))) { + LOG_WARN("fail to generate object_id for partition schema", KR(ret), K(inc_table_schema)); + } else if (OB_FAIL(generate_tablet_id(inc_table_schema))) { + LOG_WARN("fail to fetch new table id", K(inc_table_schema), KR(ret)); + } + + return ret; +} + +// for inc_table_schema: +// 1. add a mock hidden partition for origin tablet. it seems that we are splitting a "partitioned" table +// 2. set part_idx for all additional splitting partitions +// for new_table_schema: +// 1. set tablet_id as invalid (partitioned table don't record tablet id in table-level) +// 2. set partition key and part_func_expr based on presetting-partition-key +int ObDDLService::generate_partition_info_from_non_partitioned_table_(const ObTableSchema& ori_table_schema, + ObTableSchema& inc_table_schema, + ObTableSchema& new_table_schema) +{ + int ret = OB_SUCCESS; + const int64_t inc_part_num = inc_table_schema.get_part_option().get_part_num(); + ObPartition **inc_part_array = nullptr; + + if (OB_ISNULL(inc_part_array = inc_table_schema.get_part_array())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", KR(ret), K(inc_table_schema)); + } else if (OB_FAIL(mock_hidden_partition_for_non_partitioned_table_(ori_table_schema, + inc_table_schema, + new_table_schema))) { + LOG_WARN("fail to mock hidden source partition for non-partitioned table", KR(ret), + K(ori_table_schema), + K(inc_table_schema)); + } else if (ori_table_schema.is_user_table() || ori_table_schema.is_global_index_table()) { + ObArray presetting_partition_keys; + if (OB_FAIL(ori_table_schema.get_presetting_partition_keys(presetting_partition_keys))) { + LOG_WARN("fail to get presetting partition key columns", KR(ret), K(ori_table_schema)); + } else if (presetting_partition_keys.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid schema for auto partitioning", KR(ret), K(ori_table_schema)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < presetting_partition_keys.count(); i++) { + uint64_t column_id = presetting_partition_keys.at(i); + if (OB_FAIL(new_table_schema.add_partition_key(column_id))){ + LOG_WARN("fail to add partition keu", KR(ret), K(new_table_schema), K(column_id)); + } + } // end for + + const bool need_set_part_expr = ori_table_schema.get_part_option().get_part_func_expr_str().empty(); + if (OB_FAIL(ret)) { + } else if (need_set_part_expr) { + ObArenaAllocator allocator(ObModIds::OB_SCHEMA); + int64_t buf_len = OB_MAX_TEXT_LENGTH; + int64_t pos = 0; + char* buf = static_cast(allocator.alloc(buf_len)); + + if (OB_ISNULL(buf)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to alloc", KR(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < presetting_partition_keys.count(); i++) { + ObColumnSchemaV2* column_schema = new_table_schema.get_column_schema(presetting_partition_keys.at(i)); + if (OB_ISNULL(column_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("column_schema is null", KR(ret)); + } else if (FALSE_IT(pos += column_schema->get_column_name_str().to_string(buf + pos, buf_len - pos))) { + } else if (i != presetting_partition_keys.count() - 1) { + J_COMMA(); + } + } // end for + + if (OB_SUCC(ret)) { + ObString part_func_expr(pos, buf); + if (OB_FAIL(new_table_schema.get_part_option().set_part_expr(part_func_expr))) { + LOG_WARN("fail to set part expr", KR(ret)); + } + } + } // end if (need_set_part_expr) + } + } else if (ori_table_schema.is_aux_lob_table() || ori_table_schema.is_index_local_storage()) { + // the partition info of local index and lob is same to data_table, no need to modify schema + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table type", KR(ret), K(ori_table_schema)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < inc_part_num; ++i) { + ObPartition* inc_part = inc_part_array[i]; + if (OB_ISNULL(inc_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("split partition is null", KR(ret)); + } else { + inc_part->set_part_idx(i); + } + } + return ret; +} + +int ObDDLService::mock_hidden_partition_for_non_partitioned_table_(const ObTableSchema& ori_table_schema, + ObTableSchema& inc_table_schema, + ObTableSchema& new_table_schema) +{ + int ret = OB_SUCCESS; + const int64_t object_cnt = 1; + const uint64_t tenant_id = ori_table_schema.get_tenant_id(); + share::schema::ObPartition mock_part; + ObObjectID object_id = OB_INVALID_ID; + + if (OB_ISNULL(schema_service_) || OB_ISNULL(schema_service_->get_schema_service())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema_service is empty", KR(ret), KP_(schema_service)); + } else if (OB_FAIL(schema_service_->get_schema_service() + ->fetch_new_partition_ids(tenant_id, object_cnt, object_id))) { + LOG_WARN("fail to get max object id", KR(ret), K(tenant_id), K(object_cnt)); + } else if (OB_FAIL(mock_part.set_part_name(ObString::make_string("mock_part")))) { + LOG_WARN("failed to set part_name", KR(ret)); + } else if (OB_FAIL(mock_part.set_high_bound_val(ObRowkey::MAX_ROWKEY))) { + LOG_WARN("failed to set high_bound_val", KR(ret)); + } else { + mock_part.set_part_idx(0); + mock_part.set_tenant_id(ori_table_schema.get_tenant_id()); + mock_part.set_table_id(ori_table_schema.get_table_id()); + mock_part.set_tablet_id(ori_table_schema.get_tablet_id()); + mock_part.set_partition_type(PartitionType::PARTITION_TYPE_SPLIT_SOURCE); + mock_part.set_part_id(object_id); + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(inc_table_schema.add_partition(mock_part))) { + LOG_WARN("fail to add partition", KR(ret), K(mock_part)); + } else { + new_table_schema.set_tablet_id(ObTabletID::INVALID_TABLET_ID); + } + } + + return ret; +} + +// inc_table_schema records the additional splitting partition, +// upd_table_schema records the modification of origin partition: +// 1. reorganize the part_idx of partition of inc_table_schema and upd_table_schema in partial order +// based on the value of partition key +// 2. set partition_type for source partition of upd_table_schema (to be hidden part) +int ObDDLService::generate_partition_info_from_partitioned_table_(const ObTableSchema& ori_table_schema, + ObTableSchema& inc_table_schema, + ObTableSchema& upd_table_schema) +{ + int ret = OB_SUCCESS; + ObPartition **ori_part_array = nullptr; + ObPartition **inc_part_array = nullptr; + const int64_t ori_part_num = ori_table_schema.get_part_option().get_part_num(); + const int64_t inc_part_num = inc_table_schema.get_part_option().get_part_num(); + + // set part_idx and partition type + if (OB_ISNULL(inc_part_array = inc_table_schema.get_part_array())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", KR(ret), K(inc_table_schema)); + } else if (OB_ISNULL(ori_part_array = ori_table_schema.get_part_array())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", KR(ret), K(ori_table_schema)); + } else if (OB_UNLIKELY(!ori_table_schema.is_valid_split_part_type())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("only support to split range or range column part", KR(ret), K(ori_table_schema)); + } else { + common::hash::ObHashSet source_tablet_id_set; + if (OB_FAIL(source_tablet_id_set.create(32))) { + LOG_WARN("failed to create source part id set", KR(ret)); + } else { + // check ori_part_array + for (int64_t i = 0; OB_SUCC(ret) && i < ori_part_num; ++i) { + ObPartition* ori_part = ori_part_array[i]; + if (OB_ISNULL(ori_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("origin partition is null", KR(ret)); + } else if (OB_UNLIKELY(ori_part->get_split_source_tablet_id().is_valid())){ + ret = OB_ERR_UNEXPECTED; + LOG_WARN("only split part could have split_source_tablet_id", KR(ret), KPC(ori_part)); + } + } // end for + + // build upd_part of upd_table_schema to update the partition_type of source split part + for (int64_t i = 0; OB_SUCC(ret) && i < inc_part_num; ++i) { + ObPartition* inc_part = inc_part_array[i]; + if (OB_ISNULL(inc_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("split partition is null", KR(ret)); + } else { + ObTabletID source_tablet_id = inc_part->get_split_source_tablet_id(); + if (OB_FAIL(source_tablet_id_set.set_refactored(source_tablet_id.id(), 0 /*flag*/))) { + if (OB_HASH_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("set_refactored from source_tablet_id_set failed", KR(ret), K(source_tablet_id)); + } + } else { + ObPartition* source_split_part = nullptr; + for (int64_t j = 0; source_split_part == nullptr && OB_SUCC(ret) && j < ori_part_num; ++j) { + ObPartition* ori_part = ori_part_array[j]; + if (OB_ISNULL(ori_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("source split part is null", KR(ret), K(j), K(ori_table_schema)); + } else if (ori_part->get_tablet_id() == source_tablet_id) { + source_split_part = ori_part; + } + } // end for + + ObPartition upd_part; + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(source_split_part)) { + ret = OB_UNKNOWN_PARTITION; + LOG_WARN("source split part is not existed", KR(ret), K(source_tablet_id), KPC(inc_part), K(ori_table_schema)); + } else if (OB_FAIL(upd_part.assign(*source_split_part))) { + LOG_WARN("fail to assign part", KR(ret), KPC(source_split_part)); + } else if (FALSE_IT(upd_part.set_partition_type(PartitionType::PARTITION_TYPE_SPLIT_SOURCE))) { + } else if (OB_FAIL(upd_table_schema.add_partition(upd_part))) { + LOG_WARN("add partition fail", KR(ret), K(upd_part)); + } + } + } + } // end for + } + + // set part_idx for inc_part and upd_part + ObArenaAllocator allocator; + ObPartition** sort_part_array; + if (OB_ISNULL(sort_part_array = static_cast(allocator.alloc( + sizeof(ObPartition*) * (ori_part_num + inc_part_num))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc", KR(ret), K(ori_part_num), K(inc_part_num)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < ori_part_num + inc_part_num; ++i) { + if (i < ori_part_num) { + if (OB_ISNULL(ori_part_array[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ori part is null", KR(ret), K(ori_table_schema)); + } else { + sort_part_array[i] = ori_part_array[i]; + } + } else { + sort_part_array[i] = inc_part_array[i - ori_part_num]; + } + } // end for + + if (OB_FAIL(ret)) { + } else { + ob_sort(sort_part_array, sort_part_array + ori_part_num + inc_part_num, + ObBasePartition::range_like_func_less_than); + + int part_idx = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < ori_part_num + inc_part_num; ++i) { + ObPartition* part = sort_part_array[i]; + int tmp_ret = source_tablet_id_set.exist_refactored(part->get_tablet_id().id()); + + if (tmp_ret == OB_HASH_NOT_EXIST) { // not source splitting part + if (part->get_part_idx() != part_idx) { + bool is_inc_part = part->get_split_source_tablet_id().is_valid(); + if (is_inc_part) { // inc part + part->set_part_idx(part_idx++); + } else { // origin part + ObPartition upd_part; + if (OB_FAIL(upd_part.assign(*part))) { + LOG_WARN("fail to assign part", KR(ret), KPC(part)); + } else if (FALSE_IT(upd_part.set_part_idx(part_idx++))) { + } else if (OB_FAIL(upd_table_schema.add_partition(upd_part))) { + LOG_WARN("add partition fail", KR(ret), K(upd_part)); + } + } + } + } else if (tmp_ret != OB_HASH_EXIST) { + ret = tmp_ret; + LOG_WARN("fail to call exist_refactored", KR(ret)); + } + } // end for + } + } + } + return ret; +} + int ObDDLService::pre_rename_mysql_columns_offline( const ObTableSchema &origin_table_schema, AlterTableSchema &alter_table_schema, bool is_oracle_mode, obrpc::ObAlterTableArg &alter_table_arg, ObTableSchema &new_table_schema, diff --git a/src/rootserver/ob_ddl_service.h b/src/rootserver/ob_ddl_service.h index 22d7ad4c1..025f11599 100644 --- a/src/rootserver/ob_ddl_service.h +++ b/src/rootserver/ob_ddl_service.h @@ -163,6 +163,18 @@ public: obrpc::ObAlterTableRes &res); + int clean_splitted_tablet(const obrpc::ObCleanSplittedTabletArg &arg); + int generate_splitted_schema_array(const obrpc::ObCleanSplittedTabletArg &arg, + ObArenaAllocator& allocator, + common::ObIArray &splitting_table_schemas, + common::ObIArray &del_table_schemas, + int64_t &refreshed_schema_version); + int generate_splitted_schema_from_partitioned_table( + ObArenaAllocator& allocator, + const ObTabletID splitted_tablet_id, + const share::schema::ObTableSchema &splitting_table_schema, + share::schema::ObTableSchema *&del_table_schema); + int create_inner_expr_index(ObMySQLTransaction &trans, const share::schema::ObTableSchema &orig_table_schema, const uint64_t tenant_data_version, @@ -368,6 +380,7 @@ public: share::schema::ObSchemaGetterGuard &schema_guard, bool &need_redistribute_column_id); int gen_alter_partition_new_table_schema_offline( + obrpc::ObAlterTableArg &alter_table_arg, const share::schema::AlterTableSchema & alter_table_schema, const share::schema::ObTableSchema &orig_table_schema, share::schema::ObTableSchema &new_table_schema); @@ -429,12 +442,14 @@ public: common::ObIArray &new_table_schemas, common::ObIArray &inc_table_schemas, common::ObIArray &del_table_schemas, + common::ObIArray &upd_table_schemas, const ObTableSchema &orig_table_schema, ObTableSchema &new_table_schema, AlterTableSchema &inc_table_schema, share::schema::ObSchemaGetterGuard &schema_guard, ObArenaAllocator &allocator); bool is_add_and_drop_partition(const obrpc::ObAlterTableArg::AlterPartitionType &op_type); + int split_global_index_partitions(obrpc::ObAlterTableArg &arg, obrpc::ObAlterTableRes &res); // execute alter_table_partitions for some tables which are data table and its local indexes // // @param [in] op_type, modify part ddl op @@ -447,6 +462,7 @@ public: common::ObIArray &new_table_schemas, common::ObIArray &inc_table_schemas, common::ObIArray &del_table_schemas, + ObIArray &upd_table_schemas, ObDDLOperator &ddl_operator, ObSchemaGetterGuard &schema_guard, ObMySQLTransaction &trans); @@ -454,6 +470,7 @@ public: const share::schema::ObTableSchema &orig_table_schema, share::schema::AlterTableSchema &inc_table_schema, share::schema::AlterTableSchema &del_table_schema, + ObTableSchema &upd_table_schema, share::schema::ObTableSchema &new_table_schema, ObDDLOperator &ddl_operator, ObSchemaGetterGuard &schema_guard, @@ -658,6 +675,7 @@ public: int cleanup_garbage(obrpc::ObAlterTableArg &alter_table_arg); int modify_hidden_table_fk_state(obrpc::ObAlterTableArg &alter_table_arg); int modify_hidden_table_not_null_column_state(const obrpc::ObAlterTableArg &alter_table_arg); + int restore_the_table_to_split_completed_state(obrpc::ObAlterTableArg &alter_table_arg); int maintain_obj_dependency_info(const obrpc::ObDependencyObjDDLArg &arg); int process_schema_object_dependency( const uint64_t tenant_id, @@ -1966,6 +1984,12 @@ private: const AlterColumnSchema &alter_column_schema, lib::Worker::CompatMode compat_mode); + int modify_part_func_expr(const share::schema::ObTableSchema &orig_table_schema, + const share::schema::ObColumnSchemaV2 &orig_column_schema, + const share::schema::AlterColumnSchema &alter_column_schema, + share::schema::ObTableSchema &new_table_schema, + const common::ObTimeZoneInfo &tz_info, + common::ObIAllocator &allocator); int modify_part_func_expr(const ObString &orig_column_name, const ObString &alter_column_name, share::schema::ObTableSchema &table_schema, @@ -2337,6 +2361,10 @@ public: int ddl_rlock(); int ddl_wlock(); int ddl_unlock() { return ddl_lock_.unlock(); } + template + int fill_part_name( + const SCHEMA &orig_schema, + ALTER_SCHEMA &alter_schema); private: int generate_tenant_schema( const obrpc::ObCreateTenantArg &arg, @@ -2669,9 +2697,6 @@ private: const common::ObIArray &short_pool_name_list, common::ObIArray &diff_pools); template - int fill_part_name(const SCHEMA &orig_schema, - ALTER_SCHEMA &alter_schema); - template int check_partition_name_valid(const SCHEMA &orig_schema, const ALTER_SCHEMA &alter_schema, const ObString part_name, @@ -2691,6 +2716,8 @@ private: const bool is_truncate); int check_alter_drop_subpartitions(const share::schema::ObTableSchema &orig_table_schema, const obrpc::ObAlterTableArg &alter_table_arg); + int check_alter_split_partitions(const share::schema::ObTableSchema &orig_table_schema, + obrpc::ObAlterTableArg &alter_table_arg); int check_alter_add_partitions(const share::schema::ObTableSchema &orig_table_schema, obrpc::ObAlterTableArg &alter_table_arg); int filter_out_duplicate_interval_part(const share::schema::ObTableSchema &orig_table_schema, @@ -2865,6 +2892,48 @@ private: const share::schema::ObTenantSchema &orig_tenant_schema, const share::schema::ObTenantSchema &new_tenant_schema); + int correct_source_tablet_id_for_inc_aux_table_schema_( + const obrpc::ObAlterTableArg::AlterPartitionType op_type, + const ObPartitionLevel target_part_level, + const ObTableSchema &table_schema, + const ObTableSchema &aux_table_schema, + const AlterTableSchema &inc_table_schema, + ObTableSchema &inc_aux_table_schema); + int generate_split_info_for_schemas_(const obrpc::ObAlterTableArg::AlterPartitionType type, + ObIArray& ori_table_schemas, + ObIArray& inc_table_schemas, + ObIArray& new_table_schemas, + ObIArray& upd_table_schemas); + int generate_split_info_for_schema_(const ObPartitionLevel target_part_level, + const ObTableSchema& ori_table_schema, + ObTableSchema& inc_table_schema, + ObTableSchema& new_table_schema, + ObTableSchema& upd_table_schema); + int generate_partition_info_from_non_partitioned_table_(const ObTableSchema& ori_table_schema, + ObTableSchema& inc_table_schema, + ObTableSchema& new_table_schema); + int mock_hidden_partition_for_non_partitioned_table_(const ObTableSchema& ori_table_schema, + ObTableSchema& inc_table_schema, + ObTableSchema& new_table_schema); + int generate_partition_info_from_partitioned_table_(const ObTableSchema& ori_table_schema, + ObTableSchema& inc_table_schema, + ObTableSchema& upd_table_schema); + int check_split_partition_val_(const share::schema::ObTableSchema &orig_table_schema, + const AlterTableSchema &alter_table_schema, + const ObPartitionLevel target_part_level, + const obrpc::ObAlterTableArg::AlterPartitionType type); + int check_split_partitions_from_same_source_(ObPartition **split_part_array, + const int64_t part_array_size, + const int64_t start, const int64_t end, + const share::schema::ObTableSchema &orig_table_schema, + const ObPartitionLevel target_part_level, + const obrpc::ObAlterTableArg::AlterPartitionType type); + int check_split_partition_name_(const share::schema::ObTableSchema &orig_table_schema, + const AlterTableSchema &alter_table_schema, + const ObPartitionLevel target_part_level); + int check_split_global_index_partition_(ObSchemaGetterGuard &schema_guard, + obrpc::ObAlterTableArg &arg, + const share::schema::ObTableSchema &orig_index_schema); // this function is used for add extra tenant config init during create excepet data version // The addition of new configuration items requires the addition or modification of related test cases to ensure their effectiveness. int add_extra_tenant_init_config_( diff --git a/src/rootserver/ob_index_builder.cpp b/src/rootserver/ob_index_builder.cpp index facbb72bc..bb9a73737 100644 --- a/src/rootserver/ob_index_builder.cpp +++ b/src/rootserver/ob_index_builder.cpp @@ -1215,9 +1215,6 @@ int ObIndexBuilder::do_create_index( } else if (!arg.is_inner_ && table_schema->is_in_recyclebin()) { ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT; LOG_WARN("can not add index on table in recyclebin", K(ret), K(arg)); - } else if (table_schema->is_in_splitting()) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("can not create index during splitting", K(ret), K(arg)); } else if (OB_FAIL(ddl_service_.check_restore_point_allow(tenant_id, *table_schema))) { LOG_WARN("failed to check restore point allow.", K(ret), K(tenant_id), K(table_id)); } else if (table_schema->get_index_tid_count() >= OB_MAX_INDEX_PER_TABLE) { @@ -1240,8 +1237,12 @@ int ObIndexBuilder::do_create_index( } else if (INDEX_TYPE_NORMAL_GLOBAL == arg.index_type_ || INDEX_TYPE_UNIQUE_GLOBAL == arg.index_type_ || INDEX_TYPE_SPATIAL_GLOBAL == arg.index_type_) { - if (!table_schema->is_partitioned_table() && !arg.index_schema_.is_partitioned_table()) { + if (!table_schema->is_partitioned_table() + && !arg.index_schema_.is_partitioned_table() + && !table_schema->is_auto_partitioned_table()) { // create a global index with local storage when both the data table and index table are non-partitioned + // specifically, if the data table is auto-partitioned, we will create auto-partitioned global index rather + // than global local index. if (OB_FAIL(do_create_local_index(schema_guard, arg, *table_schema, res))) { LOG_WARN("fail to do create local index", K(ret)); } @@ -1462,6 +1463,18 @@ int ObIndexBuilder::generate_schema( LOG_USER_ERROR(OB_NOT_SUPPORTED, "version is less than 4.2, functional index in mysql mode not supported"); } } + + if (OB_SUCC(ret) && data_schema.is_auto_partitioned_table()) { + if (arg.is_spatial_index()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to create spatial index for auto-partitioned table", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "creating spatial index for auto-partitioned table is"); + } else if (INDEX_TYPE_DOMAIN_CTXCAT_DEPRECATED == arg.index_type_) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to create domain index for auto-partitioned table", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "creating domain index for auto-partitioned table is"); + } + } } if (OB_SUCC(ret)) { @@ -1478,20 +1491,22 @@ int ObIndexBuilder::generate_schema( LOG_WARN("set_index_table_columns failed", K(arg), K(data_schema), K(ret)); } else if (OB_FAIL(set_index_table_options(arg, data_schema, schema))) { LOG_WARN("set_index_table_options failed", K(arg), K(data_schema), K(ret)); + } else if (schema.is_global_index_table() && + OB_FAIL(set_global_index_auto_partition_infos(data_schema, schema))) { + LOG_WARN("fail to set auto partition infos", KR(ret), K(data_schema), K(schema)); } else { if (!share::schema::is_built_in_vec_index(arg.index_type_)) { // only delta_buffer_table set vector_index_param schema.set_index_params(arg.index_schema_.get_index_params()); } schema.set_name_generated_type(arg.index_schema_.get_name_generated_type()); - LOG_INFO("finish generate index schema", K(schema)); + LOG_INFO("finish generate index schema", K(schema), K(arg), K(need_generate_index_schema_column), K(global_index_without_column_info)); } } if (OB_FAIL(ret)) { - } else if (data_schema.get_part_level() > 0 - && is_index_local_storage(arg.index_type_) - && OB_FAIL(schema.assign_partition_schema(data_schema))) { - LOG_WARN("fail to assign partition schema", K(schema), K(ret)); + } else if (schema.is_index_local_storage() && + OB_FAIL(set_local_index_partition_schema(data_schema, schema))) { + LOG_WARN("fail to assign partition schema", KR(ret), K(schema)); } else if (OB_FAIL(ddl_service_.try_format_partition_schema(schema))) { LOG_WARN("fail to format partition schema", KR(ret), K(schema)); } else if (generate_id) { @@ -1683,6 +1698,81 @@ int ObIndexBuilder::set_basic_infos(const ObCreateIndexArg &arg, return ret; } +int ObIndexBuilder::set_global_index_auto_partition_infos(const share::schema::ObTableSchema &data_schema, + share::schema::ObTableSchema &schema) +{ + int ret = OB_SUCCESS; + const ObPartitionOption& index_part_option = schema.get_part_option(); + + if (OB_UNLIKELY(!data_schema.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(data_schema), KR(ret)); + } else if (OB_UNLIKELY(!schema.is_global_index_table())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid index type", K(schema), KR(ret)); + } else if (data_schema.is_auto_partitioned_table()) { + // for global index, auto_part could be true only if it is valid for auto-partitioning + // and its data table enables auto-partitioning + bool enable_auto_split = true; + const int64_t auto_part_size = data_schema.get_part_option().get_auto_part_size(); + if (schema.get_part_level() == PARTITION_LEVEL_ZERO) { + if (OB_UNLIKELY(!index_part_option.get_part_func_expr_str().empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not allow to use auto-partition clause to" + "set presetting partition key for creating index", + KR(ret), K(schema), K(data_schema)); + } else { + const ObRowkeyInfo &presetting_partition_keys = schema.get_index_info(); + ObPartitionFuncType part_type = presetting_partition_keys.get_size() > 1 ? + ObPartitionFuncType::PARTITION_FUNC_TYPE_RANGE_COLUMNS : + ObPartitionFuncType::PARTITION_FUNC_TYPE_RANGE; + for (int64_t i = 0; enable_auto_split && OB_SUCC(ret) && i < presetting_partition_keys.get_size(); ++i) { + const ObRowkeyColumn *partition_column = presetting_partition_keys.get_column(i); + if (OB_ISNULL(partition_column)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the partition column is NULL, ", KR(ret), K(i), K(presetting_partition_keys)); + } else { + ObObjType type = partition_column->get_meta_type().get_type(); + if (ObResolverUtils::is_partition_range_column_type(type)) { + /* case: create index idx1 on t1(c1) global, c1 is double type*/ + part_type = ObPartitionFuncType::PARTITION_FUNC_TYPE_RANGE_COLUMNS; + } + enable_auto_split = ObResolverUtils::is_valid_partition_column_type( + partition_column->get_meta_type().get_type(), part_type, false); + } + } + } + } else if (schema.get_part_level() == PARTITION_LEVEL_ONE) { + if (OB_FAIL(schema.is_partition_key_match_rowkey_prefix(enable_auto_split))) { + LOG_WARN("fail to check whether matching", KR(ret)); + } else if (enable_auto_split && !schema.is_valid_split_part_type()) { + enable_auto_split = false; + } + } else if (schema.get_part_level() == PARTITION_LEVEL_TWO) { + enable_auto_split = false; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), K(data_schema), K(schema)); + } + + uint64_t data_version = 0; + if (OB_FAIL(ret)) { + } else if (!enable_auto_split) { + schema.forbid_auto_partition(); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(data_schema.get_tenant_id(), data_version))) { + LOG_WARN("get tenant data version failed", K(ret)); + } else if (data_version < DATA_VERSION_4_3_4_0){ + ret = OB_NOT_SUPPORTED; + LOG_WARN("current data version doesn't support to split partition", KR(ret), K(data_version)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "data version lower than 4.4 is"); + } else if (OB_FAIL(schema.enable_auto_partition(auto_part_size))) { + LOG_WARN("fail to enable auto partition", KR(ret)); + } + } + + return ret; +} + int ObIndexBuilder::set_index_table_columns(const ObCreateIndexArg &arg, const ObTableSchema &data_schema, ObTableSchema &schema) @@ -1740,6 +1830,22 @@ bool ObIndexBuilder::is_final_index_status(const ObIndexStatus index_status) con || is_error_index_status(index_status)); } +int ObIndexBuilder::set_local_index_partition_schema(const share::schema::ObTableSchema &data_schema, + share::schema::ObTableSchema &index_schema) +{ + int ret = OB_SUCCESS; + + if (!index_schema.is_index_local_storage()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(index_schema)); + } else if ((data_schema.is_partitioned_table() || data_schema.is_auto_partitioned_table())) { + if (OB_FAIL(index_schema.assign_partition_schema_without_auto_part_attr(data_schema))) { + LOG_WARN("fail to assign basic partition schema", KR(ret), K(index_schema)); + } + } + return ret; +} + int ObIndexBuilder::check_has_none_shared_index_tables_for_fts_or_multivalue_index_( const uint64_t tenant_id, const uint64_t data_table_id, diff --git a/src/rootserver/ob_index_builder.h b/src/rootserver/ob_index_builder.h index 74de7bf81..04787b3ae 100644 --- a/src/rootserver/ob_index_builder.h +++ b/src/rootserver/ob_index_builder.h @@ -130,6 +130,8 @@ private: int set_basic_infos(const obrpc::ObCreateIndexArg &arg, const share::schema::ObTableSchema &data_schema, share::schema::ObTableSchema &schema); + int set_global_index_auto_partition_infos(const share::schema::ObTableSchema &data_schema, + share::schema::ObTableSchema &schema); int set_index_table_columns(const obrpc::ObCreateIndexArg &arg, const share::schema::ObTableSchema &data_schema, share::schema::ObTableSchema &schema); @@ -138,6 +140,9 @@ private: share::schema::ObTableSchema &schema); bool is_final_index_status(const share::schema::ObIndexStatus index_status) const; + int set_local_index_partition_schema(const share::schema::ObTableSchema &data_schema, + share::schema::ObTableSchema &index_schema); + int check_has_none_shared_index_tables_for_fts_or_multivalue_index_( const uint64_t tenant_id, const uint64_t data_table_id, diff --git a/src/rootserver/ob_lob_meta_builder.cpp b/src/rootserver/ob_lob_meta_builder.cpp index ac225b09b..4acdf96a4 100644 --- a/src/rootserver/ob_lob_meta_builder.cpp +++ b/src/rootserver/ob_lob_meta_builder.cpp @@ -84,8 +84,8 @@ int ObLobMetaBuilder::generate_aux_lob_meta_schema( if (OB_FAIL(ret)) { } else if (OB_FAIL(set_lob_table_column_store_if_need(aux_lob_meta_schema))) { LOG_WARN("fail to set lob table column store if need", KR(ret)); - } else if (data_schema.get_part_level() > 0 && - OB_FAIL(aux_lob_meta_schema.assign_partition_schema(data_schema))) { + } else if ((data_schema.is_partitioned_table() || data_schema.is_auto_partitioned_table()) + && OB_FAIL(aux_lob_meta_schema.assign_partition_schema_without_auto_part_attr(data_schema))) { LOG_WARN("fail to assign partition schema", K(aux_lob_meta_schema), K(ret)); } else if (need_generate_id) { if (OB_FAIL(ddl_service_.generate_object_id_for_partition_schema(aux_lob_meta_schema))) { @@ -126,6 +126,9 @@ int ObLobMetaBuilder::set_basic_infos( int ret = OB_SUCCESS; aux_lob_meta_schema.set_table_type(AUX_LOB_META); aux_lob_meta_schema.set_data_table_id(data_schema.get_table_id()); + // reset tablet id + ObTabletID empty_id; + aux_lob_meta_schema.set_tablet_id(empty_id); // reset tablet id to zero // real tablet id will be generated by generate_tablet_id according to partition info diff --git a/src/rootserver/ob_lob_piece_builder.cpp b/src/rootserver/ob_lob_piece_builder.cpp index 162c0ea42..0cbcb349c 100644 --- a/src/rootserver/ob_lob_piece_builder.cpp +++ b/src/rootserver/ob_lob_piece_builder.cpp @@ -84,8 +84,8 @@ int ObLobPieceBuilder::generate_aux_lob_piece_schema( if (OB_FAIL(ret)) { } else if (OB_FAIL(set_lob_table_column_store_if_need(aux_lob_piece_schema))) { LOG_WARN("fail to set lob column store if need", KR(ret)); - } else if (data_schema.get_part_level() > 0 && - OB_FAIL(aux_lob_piece_schema.assign_partition_schema(data_schema))) { + } else if ((data_schema.is_partitioned_table() || data_schema.is_auto_partitioned_table()) + && OB_FAIL(aux_lob_piece_schema.assign_partition_schema_without_auto_part_attr(data_schema))) { LOG_WARN("fail to assign partition schema", K(aux_lob_piece_schema), K(ret)); } else if (need_generate_id) { if (OB_FAIL(ddl_service_.generate_object_id_for_partition_schema(aux_lob_piece_schema))) { @@ -125,6 +125,9 @@ int ObLobPieceBuilder::set_basic_infos( { int ret = OB_SUCCESS; aux_lob_piece_schema.set_data_table_id(data_schema.get_table_id()); + // reset tablet id + ObTabletID empty_id; + aux_lob_piece_schema.set_tablet_id(empty_id); // reset tablet id to zero // real tablet id will be generated by generate_tablet_id according to partition info diff --git a/src/rootserver/ob_root_service.cpp b/src/rootserver/ob_root_service.cpp index ccc3740a6..c102534b9 100644 --- a/src/rootserver/ob_root_service.cpp +++ b/src/rootserver/ob_root_service.cpp @@ -67,6 +67,7 @@ #include "share/backup/ob_backup_config.h" #include "share/backup/ob_backup_helper.h" #include "share/scheduler/ob_sys_task_stat.h" +#include "share/scheduler/ob_partition_auto_split_helper.h" #include "sql/executor/ob_executor_rpc_proxy.h" #include "sql/engine/cmd/ob_user_cmd_executor.h" @@ -915,6 +916,8 @@ int ObRootService::init(ObServerConfig &config, FLOG_WARN("init THE_RS_JOB_TABLE failed", KR(ret)); } else if (OB_FAIL(ddl_scheduler_.init(this))) { FLOG_WARN("init ddl task scheduler failed", KR(ret)); + } else if (OB_FAIL(ObRsAutoSplitScheduler::get_instance().init())) { + FLOG_WARN("init auto split task scheduler failed", K(ret)); } else if (OB_FAIL(schema_history_recycler_.init(*schema_service_, zone_manager_, sql_proxy_))) { @@ -3496,7 +3499,8 @@ int ObRootService::create_table(const ObCreateTableArg &arg, ObCreateTableRes &r //if we pass the table_schema argument, the create_index_arg can not set database_name //and table_name, which will used from get data table schema in generate_schema if (!index_arg.index_schema_.is_partitioned_table() - && !table_schema.is_partitioned_table()) { + && !table_schema.is_partitioned_table() + && !table_schema.is_auto_partitioned_table()) { if (INDEX_TYPE_NORMAL_GLOBAL == index_arg.index_type_) { index_arg.index_type_ = INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE; } else if (INDEX_TYPE_UNIQUE_GLOBAL == index_arg.index_type_) { @@ -4163,7 +4167,8 @@ int ObRootService::execute_ddl_task(const obrpc::ObAlterTableArg &arg, } break; } - case share::CLEANUP_GARBAGE_TASK: { + case share::CLEANUP_GARBAGE_TASK: + case share::PARTITION_SPLIT_RECOVERY_CLEANUP_GARBAGE_TASK: { if (OB_FAIL(ddl_service_.cleanup_garbage( const_cast(arg)))) { LOG_WARN("failed to cleanup garbage", K(ret)); @@ -4209,6 +4214,12 @@ int ObRootService::execute_ddl_task(const obrpc::ObAlterTableArg &arg, } break; } + case share::PARTITION_SPLIT_RECOVERY_TASK: { + if (OB_FAIL(ddl_service_.restore_the_table_to_split_completed_state(const_cast(arg)))) { + LOG_WARN("failed to restore the table to split completed state", K(ret)); + } + break; + } case share::SWITCH_VEC_INDEX_NAME_TASK: { if (OB_FAIL(ddl_service_.switch_index_name_and_status_for_vec_index_table(const_cast(arg)))) { LOG_WARN("make recovert restore task visible failed", K(ret), K(arg)); @@ -5081,6 +5092,82 @@ int ObRootService::rebuild_index(const obrpc::ObRebuildIndexArg &arg, obrpc::ObA return ret; } +int ObRootService::send_auto_split_tablet_task_request(const obrpc::ObAutoSplitTabletBatchArg &arg, + obrpc::ObAutoSplitTabletBatchRes &res) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret), K(inited_)); + } else if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else if (OB_FAIL(ddl_scheduler_.cache_auto_split_task(arg, res))) { + LOG_WARN("fail to cache auto split task", K(ret), K(arg), K(res)); + } + return ret; +} + +int ObRootService::split_global_index_tablet(const obrpc::ObAlterTableArg &arg) +{ + int ret = OB_SUCCESS; + bool is_oracle_mode = false; + ObSchemaGetterGuard schema_guard; + const uint64_t tenant_id = arg.alter_table_schema_.get_tenant_id(); + ObAlterTableArg &nonconst_arg = const_cast(arg); + obrpc::ObAlterTableRes res; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(!arg.is_valid()) || arg.is_add_to_scheduler_ || !arg.alter_table_schema_.is_global_index_table()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg), K(arg.is_add_to_scheduler_), K(arg.alter_table_schema_.is_global_index_table())); + } else { + if (OB_FAIL(ddl_service_.get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { + LOG_WARN("get schema guard in inner table failed", K(ret)); + } else if (OB_FAIL(check_parallel_ddl_conflict(schema_guard, arg))) { + LOG_WARN("check parallel ddl conflict failed", K(ret)); + } else if (OB_FAIL(table_allow_ddl_operation(arg))) { + LOG_WARN("table can't do ddl now", K(ret)); + } else if (OB_FAIL(ddl_service_.split_global_index_partitions(nonconst_arg, res))) { + LOG_WARN("split global index failed", K(arg), K(ret)); + } + } + char table_id_buffer[256]; + snprintf(table_id_buffer, sizeof(table_id_buffer), "table_id:%ld, hidden_table_id:%ld", + arg.table_id_, arg.hidden_table_id_); + ROOTSERVICE_EVENT_ADD("ddl scheduler", "split global index", + K(tenant_id), + "ret", ret, + "trace_id", *ObCurTraceId::get_trace_id(), + "task_id", res.task_id_, + "table_id", table_id_buffer, + "schema_version", res.schema_version_); + LOG_INFO("finish split global index tablet ddl", K(ret), K(arg), K(res), "ddl_event_info", ObDDLEventInfo()); + return ret; +} + +int ObRootService::clean_splitted_tablet(const obrpc::ObCleanSplittedTabletArg &arg) +{ + int ret = OB_SUCCESS; + uint64_t data_version = 0; + if (!inited_) { + ret = OB_NOT_INIT; + LOG_WARN("not init", KR(ret)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(arg.tenant_id_, data_version))) { + LOG_WARN("failed to get min data version", KR(ret)); + } else if (data_version < DATA_VERSION_4_3_4_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("current data version doesn't support to clean splitted tablet", K(ret), K(data_version)); + } else if (!arg.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", KR(ret), K(arg)); + } else if (OB_FAIL(ddl_service_.clean_splitted_tablet(arg))) { + LOG_WARN("ddl_service clean splitted tablet failed", KR(ret), K(arg)); + } + return ret; +} + int ObRootService::flashback_index(const ObFlashBackIndexArg &arg) { int ret = OB_SUCCESS; if (!inited_) { @@ -10525,6 +10612,7 @@ int ObRootService::table_allow_ddl_operation(const obrpc::ObAlterTableArg &arg) const ObString &origin_database_name = alter_table_schema.get_origin_database_name(); const ObString &origin_table_name = alter_table_schema.get_origin_table_name(); schema_guard.set_session_id(arg.session_id_); + bool is_index = arg.alter_table_schema_.is_index_table(); if (arg.is_refresh_sess_active_time()) { //do nothing } else if (!arg.is_valid()) { @@ -10533,17 +10621,12 @@ int ObRootService::table_allow_ddl_operation(const obrpc::ObAlterTableArg &arg) } else if (OB_FAIL(ddl_service_.get_tenant_schema_guard_with_version_in_inner_table(tenant_id, schema_guard))) { LOG_WARN("get schema guard in inner table failed", K(ret)); } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, origin_database_name, - origin_table_name, false, schema))) { + origin_table_name, is_index, schema))) { LOG_WARN("fail to get table schema", K(ret), K(tenant_id), K(origin_database_name), K(origin_table_name)); } else if (OB_ISNULL(schema)) { ret = OB_TABLE_NOT_EXIST; LOG_WARN("invalid schema", K(ret)); LOG_USER_ERROR(OB_TABLE_NOT_EXIST, to_cstring(origin_database_name), to_cstring(origin_table_name)); - } else if (schema->is_in_splitting()) { - //TODO ddl must not execute on splitting table due to split not unstable - ret = OB_OP_NOT_ALLOW; - LOG_WARN("table is physical or logical split can not split", K(ret), K(schema)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "table is in physial or logical split, ddl operation"); } else if (schema->is_ctas_tmp_table()) { if (!alter_table_schema.alter_option_bitset_.has_member(ObAlterTableArg::SESSION_ID)) { //to prevet alter table after failed to create table, the table is invisible. @@ -11619,10 +11702,10 @@ int ObRootService::drop_restore_point(const obrpc::ObDropRestorePointArg &arg) int ObRootService::build_ddl_single_replica_response(const obrpc::ObDDLBuildSingleReplicaResponseArg &arg) { int ret = OB_SUCCESS; - LOG_INFO("receive build ddl single replica response", K(arg)); ObDDLTaskInfo info; info.row_scanned_ = arg.row_scanned_; info.row_inserted_ = arg.row_inserted_; + info.physical_row_count_ = arg.physical_row_count_; if (OB_UNLIKELY(!inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); @@ -11632,7 +11715,7 @@ int ObRootService::build_ddl_single_replica_response(const obrpc::ObDDLBuildSing } else if (OB_FAIL(DDL_SIM(arg.tenant_id_, arg.task_id_, PROCESS_BUILD_SSTABLE_RESPONSE_SLOW))) { LOG_WARN("ddl sim failure: procesc build sstable response slow", K(ret)); } else if (OB_FAIL(ddl_scheduler_.on_sstable_complement_job_reply( - arg.tablet_id_/*source tablet id*/, ObDDLTaskKey(arg.dest_tenant_id_, arg.dest_schema_id_, arg.dest_schema_version_), arg.snapshot_version_, arg.execution_id_, arg.ret_code_, info))) { + arg.tablet_id_/*source tablet id*/, arg.server_addr_, ObDDLTaskKey(arg.dest_tenant_id_, arg.dest_schema_id_, arg.dest_schema_version_), arg.snapshot_version_, arg.execution_id_, arg.ret_code_, info))) { LOG_WARN("handle column checksum calc response failed", K(ret), K(arg)); } ROOTSERVICE_EVENT_ADD("ddl scheduler", "build ddl single replica response", diff --git a/src/rootserver/ob_root_service.h b/src/rootserver/ob_root_service.h index a20883438..2d1c624ab 100644 --- a/src/rootserver/ob_root_service.h +++ b/src/rootserver/ob_root_service.h @@ -516,6 +516,8 @@ public: int abort_redef_table(const obrpc::ObAbortRedefTableArg &arg); int update_ddl_task_active_time(const obrpc::ObUpdateDDLTaskActiveTimeArg &arg); int create_hidden_table(const obrpc::ObCreateHiddenTableArg &arg, obrpc::ObCreateHiddenTableRes &res); + int send_auto_split_tablet_task_request(const obrpc::ObAutoSplitTabletBatchArg &arg, obrpc::ObAutoSplitTabletBatchRes &res); + int split_global_index_tablet(const obrpc::ObAlterTableArg &arg); /** * For recover restore table ddl, data insert into the target table is selected from another tenant. * The function is used to create a hidden target table without any change on the source table, @@ -545,6 +547,10 @@ public: int rebuild_index(const obrpc::ObRebuildIndexArg &arg, obrpc::ObAlterTableRes &res); int rebuild_vec_index(const obrpc::ObRebuildIndexArg &arg, obrpc::ObAlterTableRes &res); int clone_tenant(const obrpc::ObCloneTenantArg &arg, obrpc::ObCloneTenantRes &res); + + // the interface only for gc splitted source tablet + int clean_splitted_tablet(const obrpc::ObCleanSplittedTabletArg &arg); + //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 b7e6e61d8..375a8268e 100644 --- a/src/rootserver/ob_rs_async_rpc_proxy.h +++ b/src/rootserver/ob_rs_async_rpc_proxy.h @@ -32,6 +32,10 @@ RPC_F(obrpc::OB_GET_WRS_INFO, obrpc::ObGetWRSArg, obrpc::ObSrvRpcProxy::ObRpc::Response, ObGetWRSProxy); RPC_F(obrpc::OB_CHECK_SCHEMA_VERSION_ELAPSED, obrpc::ObCheckSchemaVersionElapsedArg, obrpc::ObCheckSchemaVersionElapsedResult, ObCheckSchemaVersionElapsedProxy); +RPC_F(obrpc::OB_CHECK_MEMTABLE_CNT, obrpc::ObCheckMemtableCntArg, + obrpc::ObCheckMemtableCntResult, ObCheckMemtableCntProxy); +RPC_F(obrpc::OB_CHECK_MEDIUM_INFO_LIST_CNT, obrpc::ObCheckMediumCompactionInfoListArg, + obrpc::ObCheckMediumCompactionInfoListResult, ObCheckMediumCompactionInfoListProxy); RPC_F(obrpc::OB_DDL_BUILD_SINGLE_REPLICA_REQUEST, obrpc::ObDDLBuildSingleReplicaRequestArg, obrpc::ObDDLBuildSingleReplicaRequestResult, ObDDLBuildSingleReplicaRequestProxy); RPC_F(obrpc::OB_CHECK_MODIFY_TIME_ELAPSED, obrpc::ObCheckModifyTimeElapsedArg, diff --git a/src/rootserver/ob_rs_rpc_processor.h b/src/rootserver/ob_rs_rpc_processor.h index 9d12978cf..70f019252 100644 --- a/src/rootserver/ob_rs_rpc_processor.h +++ b/src/rootserver/ob_rs_rpc_processor.h @@ -337,6 +337,7 @@ DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_RECOVER_RESTORE_TABLE_DDL, ObRpcRecoverRes DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_PARALLEL_CREATE_TABLE, ObRpcParallelCreateTableP, parallel_create_table(arg_, result_)); DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_ALTER_TABLE, ObRpcAlterTableP, alter_table(arg_, result_)); DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_EXCHANGE_PARTITION, ObRpcExchangePartitionP, exchange_partition(arg_, result_)); +DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_SPLIT_GLOBAL_INDEX_TABLET, ObSplitGlobalIndexTabletTaskP, split_global_index_tablet(arg_)); DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_DROP_TABLE, ObRpcDropTableP, drop_table(arg_, result_)); DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_RENAME_TABLE, ObRpcRenameTableP, rename_table(arg_)); DEFINE_DDL_RS_RPC_PROCESSOR(obrpc::OB_TRUNCATE_TABLE, ObRpcTruncateTableP, truncate_table(arg_, result_)); @@ -500,6 +501,8 @@ DEFINE_RS_RPC_PROCESSOR(obrpc::OB_REQUEST_TIME_ZONE_INFO, ObRpcRequestTimeZoneIn DEFINE_RS_RPC_PROCESSOR(obrpc::OB_RS_UPDATE_STAT_CACHE, ObRpcUpdateStatCacheP, update_stat_cache(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_CALC_COLUMN_CHECKSUM_RESPONSE, ObRpcCalcColumnChecksumResponseP, calc_column_checksum_repsonse(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_DDL_BUILD_SINGLE_REPLICA_RESPONSE, ObRpcDDLBuildSingleReplicaResponseP, build_ddl_single_replica_response(arg_)); +DEFINE_RS_RPC_PROCESSOR(obrpc::OB_CLEAN_SPLITTED_TABLET, ObRpcCleanSplittedTabletP, clean_splitted_tablet(arg_)); +DEFINE_RS_RPC_PROCESSOR(obrpc::OB_AUTO_SPLIT_TABLET_TASK_REQUEST, ObAutoSplitTabletTaskP, send_auto_split_tablet_task_request(arg_,result_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_CANCEL_DDL_TASK, ObRpcCancelDDLTaskP, cancel_ddl_task(arg_)); DEFINE_RS_RPC_PROCESSOR(obrpc::OB_FORCE_CREATE_SYS_TABLE, ObForceCreateSysTableP, force_create_sys_table(arg_)); class ObForceSetLocalityP : public ObRootServerRPCProcessor diff --git a/src/rootserver/ob_split_partition_helper.cpp b/src/rootserver/ob_split_partition_helper.cpp new file mode 100644 index 000000000..7f0ba1607 --- /dev/null +++ b/src/rootserver/ob_split_partition_helper.cpp @@ -0,0 +1,866 @@ +/** + * 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 "rootserver/ob_split_partition_helper.h" +#include "share/tablet/ob_tablet_to_table_history_operator.h" + +namespace oceanbase +{ +using namespace obrpc; +using namespace share; +using namespace share::schema; + +namespace rootserver +{ + +ObSplitPartitionHelper::~ObSplitPartitionHelper() +{ + if (nullptr != tablet_creator_) { + tablet_creator_->~ObTabletCreator(); + allocator_.free(tablet_creator_); + tablet_creator_ = nullptr; + } +} + +int ObSplitPartitionHelper::execute(ObDDLTaskRecord &task_record) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(upd_table_schemas_.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("empty upd table schemas", K(ret)); + } else if (OB_FAIL(check_allow_split(schema_guard_, *upd_table_schemas_.at(0)))) { + LOG_WARN("failed to check allow split", K(ret)); + } else if (OB_FAIL(prepare_start_args_(tenant_id_, + new_table_schemas_, + upd_table_schemas_, + inc_table_schemas_, + ls_id_, + leader_addr_, + src_tablet_ids_, + dst_tablet_ids_, + start_src_arg_, + start_dst_arg_, + task_id_, + allocator_, + trans_))) { + LOG_WARN("failed to split start src", KR(ret)); + } else if (OB_FAIL(prepare_dst_tablet_creator_(tenant_id_, + tenant_data_version_, + ls_id_, + leader_addr_, + src_tablet_ids_, + dst_tablet_ids_, + inc_table_schemas_, + allocator_, + tablet_creator_, + trans_))) { + LOG_WARN("failed to prepare dst tablet creator", K(ret)); + } else if (OB_FAIL(insert_dst_tablet_to_ls_and_table_history_(tenant_id_, + ls_id_, + dst_tablet_ids_, + inc_table_schemas_, + trans_))) { + LOG_WARN("failed to insert dst tablet to ls and table history", K(ret)); + } else if (OB_FAIL(create_ddl_task_(tenant_id_, + task_id_, + split_type_, + inc_table_schemas_, + parallelism_, + allocator_, + task_record, + trans_))) { + LOG_WARN("failed to create ddl task", K(ret)); + } else if (OB_FAIL(start_src_(tenant_id_, + ls_id_, + leader_addr_, + src_tablet_ids_, + start_src_arg_, + data_end_scn_, + end_autoinc_seqs_, + trans_))) { + LOG_WARN("failed to split wait src end", KR(ret)); + } else if (OB_FAIL(start_dst_(tenant_id_, + ls_id_, + leader_addr_, + inc_table_schemas_, + dst_tablet_ids_, + start_dst_arg_, + data_end_scn_, + end_autoinc_seqs_, + task_id_, + tablet_creator_, + trans_))) { + LOG_WARN("failed to split start dst", KR(ret)); + } + return ret; +} + +int ObSplitPartitionHelper::check_allow_split( + share::schema::ObSchemaGetterGuard &schema_guard, + const share::schema::ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + bool is_db_in_recyclebin = false; + const ObTenantSchema *tenant_schema = nullptr; + ObArray zone_locality; + if (OB_UNLIKELY(table_schema.is_in_recyclebin())) { + ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT; + LOG_WARN("the table is in recyclebin.", KR(ret), K(table_schema)); + } else if (OB_FAIL(schema_guard.check_database_in_recyclebin(tenant_id, + table_schema.get_database_id(), + is_db_in_recyclebin))) { + LOG_WARN("check database in recyclebin failed", KR(ret), K(table_schema)); + } else if (OB_UNLIKELY(is_db_in_recyclebin)) { + ret = OB_ERR_OPERATION_ON_RECYCLE_OBJECT; + LOG_WARN("the database in recyclebin", KR(ret), K(table_schema)); + } else if (OB_UNLIKELY(!table_schema.is_user_table() && !table_schema.is_global_index_table())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported table type", K(ret), K(table_schema)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(schema_guard.get_tenant_info(tenant_id, tenant_schema))) { + LOG_WARN("failed to get tenant schema", K(ret)); + } else if (OB_FAIL(tenant_schema->get_zone_replica_attr_array(zone_locality))) { + LOG_WARN("failed to get zone replica attr array", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < zone_locality.count(); i++) { + if (zone_locality[i].get_columnstore_replica_num() > 0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("split with column store replica not supported", K(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split with column store replica"); + } + } + } + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(GCTX.is_shared_storage_mode())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("split in shared storage mode not supported", K(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split in shared storage mode"); + } + + return ret; +} + +int ObSplitPartitionHelper::prepare_start_args_( + const uint64_t tenant_id, + const ObIArray &new_table_schemas, + const ObIArray &upd_table_schemas, + const ObIArray &inc_table_schemas, + ObLSID &ls_id, + ObAddr &leader_addr, + ObIArray &src_tablet_ids, + ObIArray> &dst_tablet_ids, + ObTabletSplitMdsArg &start_src_arg, + ObTabletSplitMdsArg &start_dst_arg, + int64_t &task_id, + ObIAllocator &allocator, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + bool is_oracle_mode = false; + ObLocationService *location_service = nullptr; + ObArray ls_ids; + ObArray dst_high_bound_vals; + ls_id.reset(); + leader_addr.reset(); + src_tablet_ids.reset(); + dst_tablet_ids.reset(); + start_src_arg.reset(); + start_dst_arg.reset(); + task_id = 0; + ObSEArray src_data_tablet_id; + ObRootService *root_service = GCTX.root_service_; + ObTableLockOwnerID owner_id; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || upd_table_schemas.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(upd_table_schemas.count())); + } else if (OB_ISNULL(root_service)) { + ret = OB_ERR_SYS; + LOG_WARN("error sys, root service must not be nullptr", K(ret)); + } else if (OB_FAIL(upd_table_schemas.at(0)->check_if_oracle_compat_mode(is_oracle_mode))) { + LOG_WARN("failed to check oracle mode", KR(ret), K(tenant_id), KPC(upd_table_schemas.at(0))); + } + + // prepare tablet ids array for mapping between src and dst tablets later + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTabletSplitMdsArg::prepare_basic_args(upd_table_schemas, + inc_table_schemas, + src_tablet_ids, + dst_tablet_ids, + dst_high_bound_vals))) { + LOG_WARN("failed to get all tablet ids", KR(ret)); + } + + // lock and get ls_id + if (OB_FAIL(ret)) { + } else if (OB_FAIL(src_data_tablet_id.push_back(src_tablet_ids.at(0)))) { + LOG_WARN("failed to push back src data tablet id", K(ret)); + } else if (OB_FAIL(ObDDLTask::fetch_new_task_id(root_service->get_sql_proxy(), tenant_id, task_id))) { + LOG_WARN("fetch new task id failed", K(ret)); + } else if (OB_FALSE_IT(owner_id.convert_from_value(task_id))) { + } else if (OB_FAIL(ObDDLLock::lock_for_split_partition(*upd_table_schemas.at(0), nullptr/*ls_id*/, &src_data_tablet_id, dst_tablet_ids.at(0), owner_id, trans))) { + LOG_WARN("failed to lock for split src partition", K(ret), K(src_tablet_ids), K(task_id)); + } else if (OB_FAIL(ObTabletToLSTableOperator::batch_get_ls(trans, tenant_id, src_tablet_ids, ls_ids))) { + LOG_WARN("failed to batch get ls", KR(ret)); + } else if (OB_UNLIKELY(src_tablet_ids.count() != ls_ids.count() || ls_ids.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet ids ls ids", KR(ret), K(src_tablet_ids), K(ls_ids)); + } else { + ls_id = ls_ids.at(0); + for (int64_t i = 0; OB_SUCC(ret) && i < ls_ids.count(); i++) { + if (OB_UNLIKELY(ls_id != ls_ids.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src tablet ls mismatched", KR(ret), K(ls_id), K(ls_ids)); + } + } + } + + // prepare mds args + if (OB_FAIL(ret)) { + } else if (OB_FAIL(start_src_arg.init_split_start_src(tenant_id, is_oracle_mode, ls_id, new_table_schemas, upd_table_schemas, src_tablet_ids, dst_tablet_ids))) { + LOG_WARN("failed to init split start src", KR(ret)); + } else if (OB_FAIL(start_dst_arg.init_split_start_dst(tenant_id, ls_id, inc_table_schemas, src_tablet_ids, dst_tablet_ids, dst_high_bound_vals))) { + LOG_WARN("failed to init split start dst", KR(ret)); + } + + // prepare leader addr, as late as possible + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(location_service = GCTX.location_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("location_cache is null", KR(ret), KP(location_service)); + } else if (OB_FAIL(location_service->get_leader(GCONF.cluster_id, + tenant_id, + ls_id, + true, + leader_addr))) { + LOG_WARN("get leader failed", KR(ret), K(tenant_id), K(ls_id)); + } + return ret; +} + +int ObSplitPartitionHelper::prepare_dst_tablet_creator_( + const uint64_t tenant_id, + const uint64_t tenant_data_version, + const ObLSID &ls_id, + const ObAddr &leader_addr, + const ObIArray &src_tablet_ids, + const ObIArray> &dst_tablet_ids, + const ObIArray &inc_table_schemas, + ObIAllocator &allocator, + ObTabletCreator *&tablet_creator, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObArray create_commit_versions; + void *buf = nullptr; + obrpc::ObSrvRpcProxy *srv_rpc_proxy = nullptr; + if (OB_UNLIKELY(dst_tablet_ids.empty() || dst_tablet_ids.count() != inc_table_schemas.count() || nullptr != tablet_creator) || OB_ISNULL(inc_table_schemas.at(0))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KP(tablet_creator), K(dst_tablet_ids), K(inc_table_schemas.count())); + } else if (OB_ISNULL(buf = allocator.alloc(sizeof(ObTabletCreator)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate", K(ret)); + } else { + // TODO(lihongqing.lhq), use scn from split source tablet rather than frozen_scn/mock base_scn. + tablet_creator = new (buf)ObTabletCreator(tenant_id, SCN::base_scn(), trans); + if (OB_FAIL(tablet_creator->init(true/*need_check_tablet_cnt*/))) { + LOG_WARN("failed to init tablet creator", K(ret)); + } + } + + // fetch split src create_commit_versions + if (OB_SUCC(ret)) { + // FIXME: timeout ctx + const int64_t timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : GCONF.rpc_timeout; + obrpc::ObFetchSplitTabletInfoArg arg; + obrpc::ObFetchSplitTabletInfoRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + if (OB_ISNULL(srv_rpc_proxy = GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_SYS; + LOG_WARN("srv_rpc_proxy is null", KR(ret), KP(srv_rpc_proxy)); + } else if (OB_FAIL(arg.tablet_ids_.assign(src_tablet_ids))) { + LOG_WARN("failed to assign", KR(ret)); + } else if (OB_FAIL(srv_rpc_proxy->to(leader_addr).timeout(timeout_us).fetch_split_tablet_info(arg, res))) { + LOG_WARN("failed to freeze src tablet", KR(ret), K(leader_addr)); + } else if (OB_FAIL(create_commit_versions.assign(res.create_commit_versions_))) { + LOG_WARN("failed to assign", K(ret)); + } + } + + if (OB_SUCC(ret)) { + const ObTableSchema &data_table_schema = *inc_table_schemas.at(0); + const int64_t split_cnt = dst_tablet_ids.at(0).count(); + const int64_t table_cnt = inc_table_schemas.count(); + bool is_oracle_mode = false; + if (OB_UNLIKELY(create_commit_versions.count() != table_cnt || dst_tablet_ids.count() != table_cnt)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(table_cnt), K(create_commit_versions), K(dst_tablet_ids)); + } else if (OB_FAIL(data_table_schema.check_if_oracle_compat_mode(is_oracle_mode))) { + LOG_WARN("fail to check oracle mode", KR(ret), K(data_table_schema.get_table_id())); + } else { + const lib::Worker::CompatMode compat_mode = is_oracle_mode ? lib::Worker::CompatMode::ORACLE : lib::Worker::CompatMode::MYSQL; + ObArray tablet_ids; + ObArray need_create_empty_majors; + for (int64_t i = 0; OB_SUCC(ret) && i < split_cnt; i++) { + const ObTabletID &data_tablet_id = dst_tablet_ids.at(0).at(i); + ObTabletCreatorArg arg; + tablet_ids.reuse(); + need_create_empty_majors.reuse(); + for (int64_t table_idx = 0; OB_SUCC(ret) && table_idx < table_cnt; table_idx++) { + if (OB_UNLIKELY(split_cnt != dst_tablet_ids.at(table_idx).count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(split_cnt), K(table_idx), K(dst_tablet_ids)); + } else if (OB_FAIL(tablet_ids.push_back(dst_tablet_ids.at(table_idx).at(i)))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(need_create_empty_majors.push_back(false))) { + LOG_WARN("failed to push back", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(arg.init(tablet_ids, + ls_id, + data_tablet_id, + inc_table_schemas, + compat_mode, + false/*is_create_bind_hidden_tablets*/, + tenant_data_version, + need_create_empty_majors, + create_commit_versions, + false/*has cs replica*/))) { + LOG_WARN("failed to init", K(ret)); + } else if (OB_FAIL(tablet_creator->add_create_tablet_arg(arg))) { + LOG_WARN("failed to add create tablet arg", K(ret)); + } + } + } + } + return ret; +} + +int ObSplitPartitionHelper::insert_dst_tablet_to_ls_and_table_history_( + const uint64_t tenant_id, + const ObLSID &ls_id, + const ObIArray> &dst_tablet_ids, + const ObIArray &inc_table_schemas, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObArray tablet_infos; + if (OB_UNLIKELY(dst_tablet_ids.empty() || dst_tablet_ids.count() != inc_table_schemas.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(dst_tablet_ids), K(inc_table_schemas.count())); + } + for (int64_t table_idx = 0; OB_SUCC(ret) && table_idx < dst_tablet_ids.count(); table_idx++) { + const ObTableSchema *table_schema = inc_table_schemas.at(table_idx); + if (OB_ISNULL(table_schema)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table schema", K(ret)); + } else { + const uint64_t table_id = table_schema->get_table_id(); + const int64_t schema_version = table_schema->get_schema_version(); + ObArray tablet_table_pairs; + for (int64_t i = 0; OB_SUCC(ret) && i < dst_tablet_ids.at(table_idx).count(); i++) { + const ObTabletID &tablet_id = dst_tablet_ids.at(table_idx).at(i); + const ObTabletToLSInfo tablet_info(tablet_id, ls_id, table_id, 0/*transfer_seq*/); + if (OB_FAIL(tablet_table_pairs.push_back(ObTabletTablePair(tablet_id, table_id)))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(tablet_infos.push_back(tablet_info))) { + LOG_WARN("failed to push back", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTabletToTableHistoryOperator::create_tablet_to_table_history( + trans, tenant_id, schema_version, tablet_table_pairs))) { + LOG_WARN("failed to create tablet to table history", K(ret), K(tenant_id), K(schema_version), K(tablet_table_pairs)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTabletToLSTableOperator::batch_update(trans, tenant_id, tablet_infos))) { + LOG_WARN("fail to batch update tablet info", K(ret), K(tenant_id), K(tablet_infos)); + } + return ret; +} + +int ObSplitPartitionHelper::delete_src_tablet_to_ls_and_table_history_( + const uint64_t tenant_id, + const ObIArray &src_tablet_ids, + const int64_t new_schema_version, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(share::ObTabletToLSTableOperator::batch_remove(trans, tenant_id, src_tablet_ids))) { + LOG_WARN("failed to batch remove tablet to ls table", KR(ret)); + } else if (OB_FAIL(share::ObTabletToTableHistoryOperator::drop_tablet_to_table_history( + trans, tenant_id, new_schema_version, src_tablet_ids))) { + LOG_WARN("failed to drop tablet to table history", KR(ret), K(tenant_id), K(new_schema_version)); + } + return ret; +} + +int ObSplitPartitionHelper::create_ddl_task_( + const uint64_t tenant_id, + const int64_t task_id, + const ObDDLType split_type, + const ObIArray &inc_table_schemas, + const int64_t parallelism, + ObIAllocator &allocator, + ObDDLTaskRecord &task_record, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObPartitionSplitArg split_arg; + int64_t split_part_num = 0; + const ObTableSchema *split_table = nullptr; + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || !share::is_tablet_split(split_type))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(tenant_id), K(split_type), K(inc_table_schemas.count())); + } else if (OB_ISNULL(split_table = inc_table_schemas.at(0))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret)); + } else if (OB_UNLIKELY((split_part_num = split_table->get_partition_num()) < 2)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(split_part_num), KPC(split_table)); + } else if (OB_UNLIKELY(!split_table->is_user_table() && !split_table->is_global_index_table())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("partition split is only supported for user table or global index", K(ret), KPC(split_table)); + } else if (split_table->is_global_index_table() && inc_table_schemas.count() != 1) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("global index should not have aux tables", K(ret), KPC(split_table)); + } else { + split_arg.task_type_ = split_type; + ObPartition** table_parts = split_table->get_part_array(); + // for main table or global_index. + for (int64_t i = 0; OB_SUCC(ret) && i < split_part_num; i++) { + if (OB_ISNULL(table_parts[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("null part", K(ret)); + } else if (OB_FAIL(split_arg.dest_tablet_ids_.push_back(table_parts[i]->get_tablet_id()))) { + LOG_WARN("fail to push back to array", K(ret)); + } else if (i == 0) { + split_arg.src_tablet_id_ = table_parts[i]->get_split_source_tablet_id(); + } else if (OB_UNLIKELY(table_parts[i]->get_split_source_tablet_id() != split_arg.src_tablet_id_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err, split source tablet id should be same", K(ret), K(i), K(split_arg.src_tablet_id_), + "split_source_tablet_id", table_parts[i]->get_split_source_tablet_id()); + } + } + // for aux tables, containing local index table, lob table. + for (int64_t i = 1/* 0 is main table*/; OB_SUCC(ret) && i < inc_table_schemas.count(); i++) { + const ObTableSchema *aux_table_schema = inc_table_schemas.at(i); + uint64_t table_id = aux_table_schema->get_table_id(); + uint64_t table_schema_version = aux_table_schema->get_schema_version(); + ObPartition** aux_table_parts = nullptr; + if (OB_ISNULL(aux_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("null schema", K(ret)); + } else if (OB_UNLIKELY(split_part_num != aux_table_schema->get_partition_num())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(split_part_num), KPC(aux_table_schema)); + } else if (OB_ISNULL(aux_table_parts = aux_table_schema->get_part_array())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KPC(aux_table_schema)); + } else { + ObSArray *table_ids = nullptr; + ObSArray *table_schema_versions = nullptr; + ObSArray *src_tablet_ids = nullptr; + ObSArray> *dest_tablets_ids = nullptr; + if (aux_table_schema->is_index_local_storage()) { + table_ids = &split_arg.local_index_table_ids_; + table_schema_versions = &split_arg.local_index_schema_versions_; + src_tablet_ids = &split_arg.src_local_index_tablet_ids_; + dest_tablets_ids = &split_arg.dest_local_index_tablet_ids_; + } else if (aux_table_schema->is_aux_lob_table()) { + table_ids = &split_arg.lob_table_ids_; + table_schema_versions = &split_arg.lob_schema_versions_; + src_tablet_ids = &split_arg.src_lob_tablet_ids_; + dest_tablets_ids = &split_arg.dest_lob_tablet_ids_; + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("invalid type of aux table", K(ret), KPC(aux_table_schema)); + } + + if (OB_SUCC(ret)) { + ObSArray dest_tablet_ids; + for (int64_t j = 0; OB_SUCC(ret) && j < split_part_num; j++) { + ObPartition* part = aux_table_parts[j]; + if (OB_ISNULL(part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("null part", K(ret)); + } else if (OB_FAIL(dest_tablet_ids.push_back(part->get_tablet_id()))) { + LOG_WARN("fail to push back to array", K(ret)); + } else if (j == 0) { + if (OB_FAIL(src_tablet_ids->push_back(part->get_split_source_tablet_id()))) { + LOG_WARN("fail to push back to array", K(ret)); + } + } else if (OB_UNLIKELY(part->get_split_source_tablet_id() != src_tablet_ids->at(src_tablet_ids->count() - 1))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err, split source tablet id should be same", K(ret), K(j), K(src_tablet_ids->at(src_tablet_ids->count() - 1)), + "split_source_tablet_id", part->get_split_source_tablet_id()); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(table_ids->push_back(table_id))) { + LOG_WARN("push back table id failed", K(ret), K(table_id)); + } else if (OB_FAIL(table_schema_versions->push_back(table_schema_version))) { + LOG_WARN("push back table schema version failed", K(ret), + K(table_schema_version)); + } else if (OB_FAIL(dest_tablets_ids->push_back(dest_tablet_ids))) { + LOG_WARN("push back split dest tablets failed", K(ret), K(dest_tablet_ids)); + } + } + } + } + } + + if (OB_SUCC(ret)) { + ObCreateDDLTaskParam param(tenant_id, + split_type, + split_table, + nullptr, + split_table->get_table_id(), + split_table->get_schema_version(), + MAX(1, parallelism)/*parallelism*/, + split_arg.consumer_group_id_, + &allocator, + &split_arg, + 0/*parent_task_id*/, + task_id); + if (OB_FAIL(GCTX.root_service_->get_ddl_scheduler().create_ddl_task(param, trans, task_record))) { + LOG_WARN("submit ddl task failed", K(ret)); + } + LOG_TRACE("create ddl task for spliting partition", K(ret), K(param)); + } + return ret; +} + +int ObSplitPartitionHelper::start_src_( + const uint64_t tenant_id, + const ObLSID &ls_id, + const ObAddr &leader_addr, + const ObIArray &src_tablet_ids, + const ObTabletSplitMdsArg &start_src_arg, + share::SCN &data_end_scn, + ObIArray> &end_autoinc_seqs, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + obrpc::ObSrvRpcProxy *srv_rpc_proxy = nullptr; + int64_t finish_time = ObTimeUtility::current_time(); + int64_t start_time = finish_time; + data_end_scn.reset(); + end_autoinc_seqs.reset(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || !ls_id.is_valid() || !leader_addr.is_valid() + || src_tablet_ids.empty() || !start_src_arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ls id", KR(ret), K(tenant_id), K(ls_id), K(leader_addr), K(src_tablet_ids), K(start_src_arg)); + } + + // start src + if (OB_SUCC(ret)) { + if (OB_ISNULL(srv_rpc_proxy = GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_SYS; + LOG_WARN("srv_rpc_proxy is null", KR(ret), KP(srv_rpc_proxy)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::register_mds(start_src_arg, false/*need_flush_redo*/, trans))) { + LOG_WARN("failed to register mds", KR(ret)); + } + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish set src tablet mds", KR(ret), "cost_ts", finish_time - start_time); + start_time = finish_time; + } + + // wait src freeze end + if (OB_SUCC(ret)) { + // FIXME: timeout ctx + const int64_t timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : GCONF.rpc_timeout; + obrpc::ObFreezeSplitSrcTabletArg arg; + obrpc::ObFreezeSplitSrcTabletRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + if (OB_FAIL(arg.tablet_ids_.assign(src_tablet_ids))) { + LOG_WARN("failed to assign", KR(ret)); + } else if (OB_FAIL(srv_rpc_proxy->to(leader_addr).timeout(timeout_us).freeze_split_src_tablet(arg, res))) { + LOG_WARN("failed to freeze src tablet", KR(ret), K(leader_addr)); + } else { + // data_end_scn = res.data_end_scn_; + } + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish freeze_split_src_tablet", KR(ret), "cost_ts", finish_time - start_time, K(data_end_scn)); + start_time = finish_time; + } + + // set src freeze flag + if (OB_SUCC(ret)) { + const bool need_flush_redo = true; // flush redo so that the following data_end_scn will be >= this redo scn + ObTabletSplitMdsArg set_src_freeze_flag_arg; + if (OB_FAIL(set_src_freeze_flag_arg.init_set_freeze_flag(tenant_id, ls_id, src_tablet_ids))) { + LOG_WARN("failed to init split start src", KR(ret)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::register_mds(set_src_freeze_flag_arg, need_flush_redo, trans))) { + LOG_WARN("failed to register mds", KR(ret)); + } + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish set src freeze flag", KR(ret), "cost_ts", finish_time - start_time); + start_time = finish_time; + } + + // get data end scn + if (OB_SUCC(ret)) { + const int64_t timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : GCONF.rpc_timeout; + obrpc::ObFreezeSplitSrcTabletArg arg; + obrpc::ObFreezeSplitSrcTabletRes res; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + if (OB_FAIL(arg.tablet_ids_.assign(src_tablet_ids))) { + LOG_WARN("failed to assign", KR(ret)); + } else if (OB_FAIL(srv_rpc_proxy->to(leader_addr).timeout(timeout_us).freeze_split_src_tablet(arg, res))) { + LOG_WARN("failed to freeze src tablet", KR(ret), K(leader_addr)); + } else { + data_end_scn = res.data_end_scn_; + } + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish get data end scn", KR(ret), "cost_ts", finish_time - start_time, K(data_end_scn)); + start_time = finish_time; + } + + // get src tablet's non-empty autoinc_seq that are needed to sync to dst tablet + if (OB_SUCC(ret)) { + const int64_t timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : GCONF.rpc_timeout; + ObBatchGetTabletAutoincSeqProxy proxy(*srv_rpc_proxy, &obrpc::ObSrvRpcProxy::batch_get_tablet_autoinc_seq); + obrpc::ObBatchGetTabletAutoincSeqArg arg; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + if (OB_FAIL(arg.src_tablet_ids_.assign(src_tablet_ids))) { + LOG_WARN("failed to assign", KR(ret)); + } else if (OB_FAIL(arg.dest_tablet_ids_.assign(src_tablet_ids))) { + LOG_WARN("failed to assign", KR(ret)); + } else if (OB_FAIL(proxy.call(leader_addr, timeout_us, tenant_id, arg))) { + LOG_WARN("send rpc failed", KR(ret), K(arg), K(leader_addr)); + } + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = proxy.wait())) { + LOG_WARN("rpc proxy wait failed", K(tmp_ret)); + ret = OB_SUCCESS == ret ? tmp_ret : ret; + } else if (OB_SUCC(ret)) { + const auto &result_array = proxy.get_results(); + if (OB_UNLIKELY(1 != result_array.count()) || OB_ISNULL(result_array.at(0))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result count not match", KR(ret), K(result_array.count())); + } else { + const auto *cur_result = result_array.at(0); + for (int64_t j = 0; OB_SUCC(ret) && j < cur_result->autoinc_params_.count(); j++) { + const ObMigrateTabletAutoincSeqParam &autoinc_param = cur_result->autoinc_params_.at(j); + const int64_t table_idx = j; + if (OB_FAIL(autoinc_param.ret_code_)) { + LOG_WARN("failed to get autoinc", KR(ret)); + } else if (1 < autoinc_param.autoinc_seq_) { // only non-empty autoinc_seqs are needed to sync to dst + if (OB_FAIL(end_autoinc_seqs.push_back(std::make_pair(table_idx, autoinc_param.autoinc_seq_)))) { + LOG_WARN("failed to push back", KR(ret)); + } + } + } + } + } + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish batch_get_tablet_autoinc_seq", KR(ret), "cost_ts", finish_time - start_time); + start_time = finish_time; + } + return ret; +} + +int ObSplitPartitionHelper::start_dst_( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObAddr &leader_addr, + const ObIArray &inc_table_schemas, + const ObIArray> &dst_tablet_ids, + const ObTabletSplitMdsArg &start_dst_arg, + const share::SCN &data_end_scn, + const ObIArray> &end_autoinc_seqs, + const int64_t task_id, + ObTabletCreator *&tablet_creator, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + int64_t finish_time = ObTimeUtility::current_time(); + int64_t start_time = finish_time; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || !ls_id.is_valid() || !leader_addr.is_valid() + || !start_dst_arg.is_valid() || !data_end_scn.is_valid() || inc_table_schemas.empty() || OB_ISNULL(tablet_creator))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(ls_id), K(leader_addr), K(start_dst_arg), K(data_end_scn), K(inc_table_schemas.count()), KP(tablet_creator)); + } + + // create dst tablets + if (OB_FAIL(ret)) { + } else if (OB_FAIL(tablet_creator->modify_batch_args(storage::ObTabletMdsUserDataType::START_SPLIT_DST, data_end_scn, true/*clear_auto_part_size*/))) { + LOG_WARN("failed to set clog checkpoint scn of tablet creator args", KR(ret)); + } else if (OB_FAIL(tablet_creator->execute())) { + LOG_WARN("execute create partition failed", KR(ret)); + } + + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish create split dst tablets", KR(ret), "cost_ts", finish_time - start_time); + start_time = finish_time; + + // lock dst partition + ObTableLockOwnerID owner_id; + owner_id.convert_from_value(task_id); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObDDLLock::lock_for_split_partition(*inc_table_schemas.at(0), &ls_id, nullptr/*src_tablet_ids*/, dst_tablet_ids.at(0), owner_id, trans))) { + LOG_WARN("failed to lock for split src partition", K(ret), K(dst_tablet_ids), K(task_id)); + } + + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish lock dst partition", KR(ret), "cost_ts", finish_time - start_time); + start_time = finish_time; + + // sync dst tablet autoinc seq + obrpc::ObSrvRpcProxy *srv_rpc_proxy = nullptr; + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(srv_rpc_proxy = GCTX.srv_rpc_proxy_)) { + ret = OB_ERR_SYS; + LOG_WARN("srv_rpc_proxy is null", KR(ret), KP(srv_rpc_proxy)); + } else if (!end_autoinc_seqs.empty()) { + ObBatchSetTabletAutoincSeqProxy proxy(*srv_rpc_proxy, &obrpc::ObSrvRpcProxy::batch_set_tablet_autoinc_seq); + obrpc::ObBatchSetTabletAutoincSeqArg arg; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + arg.is_tablet_creating_ = true; + share::ObMigrateTabletAutoincSeqParam param; + for (int64_t i = 0; OB_SUCC(ret) && i < end_autoinc_seqs.count(); i++) { + const int64_t table_idx = end_autoinc_seqs.at(i).first; + const uint64_t end_autoinc_seq = end_autoinc_seqs.at(i).second; + if (OB_UNLIKELY(table_idx >= dst_tablet_ids.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("index out of range", KR(ret), K(table_idx), K(dst_tablet_ids)); + } else { + const ObIArray &dst_tablet_ids_of_this_table = dst_tablet_ids.at(table_idx); + param.autoinc_seq_ = end_autoinc_seq; + for (int64_t j = 0; OB_SUCC(ret) && j < dst_tablet_ids_of_this_table.count(); j++) { + param.dest_tablet_id_ = dst_tablet_ids_of_this_table.at(j); + if (OB_FAIL(arg.autoinc_params_.push_back(param))) { + LOG_WARN("failed to push back", KR(ret)); + } + } + } + } + + const int64_t timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : GCONF.rpc_timeout; + if (OB_FAIL(ret)) { + } else if (OB_FAIL(proxy.call(leader_addr, timeout_us, tenant_id, arg))) { + LOG_WARN("send rpc failed", KR(ret), K(arg), K(leader_addr)); + } + int tmp_ret = OB_SUCCESS; + if (OB_SUCCESS != (tmp_ret = proxy.wait())) { + LOG_WARN("rpc proxy wait failed", K(tmp_ret)); + ret = OB_SUCCESS == ret ? tmp_ret : ret; + } else if (OB_SUCC(ret)) { + const auto &result_array = proxy.get_results(); + if (OB_UNLIKELY(1 != result_array.count()) || OB_ISNULL(result_array.at(0))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result count not match", KR(ret), K(result_array.count())); + } else { + const auto *cur_result = result_array.at(0); + for (int64_t j = 0; OB_SUCC(ret) && j < cur_result->autoinc_params_.count(); j++) { + const ObMigrateTabletAutoincSeqParam &autoinc_param = cur_result->autoinc_params_.at(j); + if (OB_FAIL(autoinc_param.ret_code_)) { + LOG_WARN("failed to get autoinc", KR(ret)); + } + } + } + } + + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish sync dst tablet autoinc", KR(ret), "cost_ts", finish_time - start_time); + start_time = finish_time; + } + + // set dst tablet split data mds + if (OB_SUCC(ret)) { + if (OB_FAIL(ObTabletSplitMdsHelper::register_mds(start_dst_arg, false/*need_flush_redo*/, trans))) { + LOG_WARN("failed to register mds", KR(ret)); + } + finish_time = ObTimeUtility::current_time(); + LOG_INFO("finish set dst tablet mds", KR(ret), "cost_ts", finish_time - start_time); + start_time = finish_time; + } + return ret; +} + +int ObSplitPartitionHelper::clean_split_src_and_dst_tablet( + const obrpc::ObCleanSplittedTabletArg &arg, + const int64_t auto_part_size, + const int64_t new_schema_version, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = arg.tenant_id_; + ObTabletSplitMdsArg end_src_arg; + ObTabletSplitMdsArg end_dst_arg; + ObArray src_tablet_ids; + ObArray ls_ids; + ObLSID ls_id; + if (OB_FAIL(src_tablet_ids.push_back(arg.src_table_tablet_id_))) { + LOG_WARN("failed to push back src tablet id", KR(ret)); + } else if (OB_FAIL(append(src_tablet_ids, arg.src_local_index_tablet_ids_))) { + LOG_WARN("failed to append", KR(ret)); + } else if (OB_FAIL(append(src_tablet_ids, arg.src_lob_tablet_ids_))) { + LOG_WARN("failed to append", KR(ret)); + } else if (OB_FAIL(delete_src_tablet_to_ls_and_table_history_(tenant_id, src_tablet_ids, new_schema_version, trans))) { + LOG_WARN("failed to delete src tablet to ls and table history", K(ret)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTabletToLSTableOperator::batch_get_ls(trans, tenant_id, arg.dest_tablet_ids_, ls_ids))) { + LOG_WARN("failed to batch get ls", KR(ret)); + } else if (OB_UNLIKELY(arg.dest_tablet_ids_.count() != ls_ids.count() || ls_ids.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet ids ls ids", KR(ret), K(ls_ids), K(arg.dest_tablet_ids_)); + } else { + ls_id = ls_ids.at(0); + for (int64_t i = 0; OB_SUCC(ret) && i < ls_ids.count(); i++) { + if (OB_UNLIKELY(ls_id != ls_ids.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("src tablet ls mismatched", KR(ret), K(ls_id), K(ls_ids)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(end_src_arg.init_split_end_src(tenant_id, + ls_id, + arg.src_table_tablet_id_, + arg.src_local_index_tablet_ids_, + arg.src_lob_tablet_ids_))) { + LOG_WARN("failed to init split end src", K(ret)); + } else if (OB_FAIL(end_dst_arg.init_split_end_dst(tenant_id, + ls_id, + auto_part_size, + arg.dest_tablet_ids_, + arg.dest_local_index_tablet_ids_, + arg.dest_lob_tablet_ids_))) { + LOG_WARN("failed to init split end dst", K(ret)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::register_mds(end_src_arg, false/*need_flush_redo*/, trans))) { + LOG_WARN("failed to register mds", K(ret)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::register_mds(end_dst_arg, false/*need_flush_redo*/, trans))) { + LOG_WARN("failed to register mds", K(ret)); + } + return ret; +} + +} // namespace rootserver +} // namespace oceanbase diff --git a/src/rootserver/ob_split_partition_helper.h b/src/rootserver/ob_split_partition_helper.h new file mode 100644 index 000000000..c89a9fe1a --- /dev/null +++ b/src/rootserver/ob_split_partition_helper.h @@ -0,0 +1,154 @@ +/** + * 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_SPLIT_PARTITION_HELPER_H_ +#define OCEANBASE_ROOTSERVER_OB_SPLIT_PARTITION_HELPER_H_ + +#include "rootserver/ob_ddl_service.h" +#include "rootserver/ob_tablet_creator.h" + +namespace oceanbase +{ +namespace rootserver +{ + +class ObSplitPartitionHelper +{ +public: + ObSplitPartitionHelper( + ObDDLSQLTransaction &trans, + share::schema::ObSchemaGetterGuard &schema_guard, + ObIAllocator &allocator, + const uint64_t tenant_id, + const uint64_t tenant_data_version, + const share::ObDDLType split_type, + const common::ObIArray &new_table_schemas, + const common::ObIArray &upd_table_schemas, + const common::ObIArray &inc_table_schemas, + const int64_t parallelism) + : trans_(trans), schema_guard_(schema_guard), allocator_(allocator), tenant_id_(tenant_id), tenant_data_version_(tenant_data_version), split_type_(split_type), + new_table_schemas_(new_table_schemas), upd_table_schemas_(upd_table_schemas), inc_table_schemas_(inc_table_schemas), parallelism_(parallelism), + ls_id_(), leader_addr_(), src_tablet_ids_(), dst_tablet_ids_(), start_src_arg_(), start_dst_arg_(), task_id_(0), + tablet_creator_(), data_end_scn_(), end_autoinc_seqs_() {} + ~ObSplitPartitionHelper(); + + int execute(ObDDLTaskRecord &task_record); + static int clean_split_src_and_dst_tablet( + const obrpc::ObCleanSplittedTabletArg &arg, + const int64_t auto_part_size, + const int64_t new_schema_version, + ObMySQLTransaction &trans); + static int check_allow_split( + share::schema::ObSchemaGetterGuard &schema_guard, + const share::schema::ObTableSchema &table_schema); + +private: + static int prepare_start_args_( + const uint64_t tenant_id, + const common::ObIArray &new_table_schemas, + const common::ObIArray &upd_table_schemas, + const common::ObIArray &inc_table_schemas, + share::ObLSID &ls_id, + ObAddr &leader_addr, + ObIArray &src_tablet_ids, + ObIArray> &dst_tablet_ids, + storage::ObTabletSplitMdsArg &start_src_arg, + storage::ObTabletSplitMdsArg &start_dst_arg, + int64_t &task_id, + ObIAllocator &allocator, + ObMySQLTransaction &trans); + static int prepare_dst_tablet_creator_( + const uint64_t tenant_id, + const uint64_t tenant_data_version, + const share::ObLSID &ls_id, + const ObAddr &leader_addr, + const ObIArray &src_tablet_ids, + const ObIArray> &dst_tablet_ids, + const ObIArray &inc_table_schemas, + ObIAllocator &allocator, + ObTabletCreator *&tablet_creator, + ObMySQLTransaction &trans); + static int insert_dst_tablet_to_ls_and_table_history_( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObIArray> &dst_tablet_ids, + const ObIArray &inc_table_schemas, + ObMySQLTransaction &trans); + static int delete_src_tablet_to_ls_and_table_history_( + const uint64_t tenant_id, + const ObIArray &dst_tablet_ids, + const int64_t new_schema_version, + ObMySQLTransaction &trans); + static int create_ddl_task_( + const uint64_t tenant_id, + const int64_t task_id, + const share::ObDDLType split_type, + const ObIArray &inc_table_schemas, + const int64_t parallelism, + ObIAllocator &allocator, + ObDDLTaskRecord &task_record, + ObMySQLTransaction &trans); + static int start_src_( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObAddr &leader_addr, + const ObIArray &src_tablet_ids, + const storage::ObTabletSplitMdsArg &start_src_arg, + share::SCN &data_end_scn, + ObIArray> &end_autoinc_seqs, + ObMySQLTransaction &trans); + static int start_dst_( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObAddr &leader_addr, + const ObIArray &inc_table_schemas, + const ObIArray> &dst_tablet_ids, + const storage::ObTabletSplitMdsArg &start_dst_arg, + const share::SCN &data_end_scn, + const ObIArray> &end_autoinc_seqs, + const int64_t task_id, + ObTabletCreator *&tablet_creator, + ObMySQLTransaction &trans); + +private: + ObDDLSQLTransaction &trans_; + share::schema::ObSchemaGetterGuard &schema_guard_; + ObIAllocator &allocator_; + uint64_t tenant_id_; + uint64_t tenant_data_version_; + share::ObDDLType split_type_; + const common::ObIArray &new_table_schemas_; + const common::ObIArray &upd_table_schemas_; + const common::ObIArray &inc_table_schemas_; + int64_t parallelism_; + + // prepared before start_src + ObLSID ls_id_; + ObAddr leader_addr_; + ObArray src_tablet_ids_; + ObArray> dst_tablet_ids_; + ObTabletSplitMdsArg start_src_arg_; + ObTabletSplitMdsArg start_dst_arg_; + int64_t task_id_; + + // prepared before start_dst + ObTabletCreator *tablet_creator_; + share::SCN data_end_scn_; + ObArray> end_autoinc_seqs_; + +private: + DISALLOW_COPY_AND_ASSIGN(ObSplitPartitionHelper); +}; + +} // namespace rootserver +} // namespace oceanbase +#endif // OCEANBASE_ROOTSERVER_OB_SPLIT_PARTITION_HELPER_H_ diff --git a/src/rootserver/ob_table_creator.cpp b/src/rootserver/ob_table_creator.cpp index 47b8be2ed..721c84888 100644 --- a/src/rootserver/ob_table_creator.cpp +++ b/src/rootserver/ob_table_creator.cpp @@ -401,6 +401,7 @@ int ObTableCreator::generate_create_tablet_arg_( ObTabletID data_tablet_id; ObTabletCreatorArg create_tablet_arg; common::ObArray tablet_id_array; + common::ObArray no_create_commit_versions; ObTabletID tablet_id; ObBasePartition *data_part = NULL; ObBasePartition *part = NULL; @@ -462,6 +463,7 @@ int ObTableCreator::generate_create_tablet_arg_( is_create_bind_hidden_tablets, tenant_data_version, need_create_empty_majors, + no_create_commit_versions, is_cs_replica_global_visible))) { LOG_WARN("fail to init create tablet arg", KR(ret), K(schemas), K(is_create_bind_hidden_tablets)); } else if (OB_FAIL(tablet_creator_.add_create_tablet_arg(create_tablet_arg))) { diff --git a/src/rootserver/ob_table_creator.h b/src/rootserver/ob_table_creator.h index f4ec7a4d2..79a5a65b7 100644 --- a/src/rootserver/ob_table_creator.h +++ b/src/rootserver/ob_table_creator.h @@ -39,6 +39,7 @@ public: trans_(trans), ls_id_array_(), inited_(false) {} + virtual ~ObTableCreator(); int init(const bool need_tablet_cnt_check); int execute(); diff --git a/src/rootserver/ob_tablet_creator.cpp b/src/rootserver/ob_tablet_creator.cpp index 5c5d12eb5..a30f883de 100644 --- a/src/rootserver/ob_tablet_creator.cpp +++ b/src/rootserver/ob_tablet_creator.cpp @@ -34,7 +34,8 @@ bool ObTabletCreatorArg::is_valid() const && table_schemas_.count() == tablet_ids_.count() && lib::Worker::CompatMode::INVALID != compat_mode_ && tenant_data_version_ > 0 - && need_create_empty_majors_.count() == table_schemas_.count(); + && need_create_empty_majors_.count() == table_schemas_.count() + && (create_commit_versions_.empty() || create_commit_versions_.count() == tablet_ids_.count()); for (int64_t i = 0; i < tablet_ids_.count() && is_valid; i++) { is_valid = tablet_ids_.at(i).is_valid(); } @@ -51,6 +52,7 @@ void ObTabletCreatorArg::reset() is_create_bind_hidden_tablets_ = false; tenant_data_version_ = 0; need_create_empty_majors_.reset(); + create_commit_versions_.reset(); has_cs_replica_ = false; } @@ -66,6 +68,8 @@ int ObTabletCreatorArg::assign(const ObTabletCreatorArg &arg) LOG_WARN("failed to assign table schemas", KR(ret), K(arg)); } else if (OB_FAIL(need_create_empty_majors_.assign(arg.need_create_empty_majors_))) { LOG_WARN("failed to assign need create empty majors", KR(ret), K(arg)); + } else if (OB_FAIL(create_commit_versions_.assign(arg.create_commit_versions_))) { + LOG_WARN("failed to assign create commit versions", KR(ret), K(arg)); } else { data_tablet_id_ = arg.data_tablet_id_; ls_key_ = arg.ls_key_; @@ -86,6 +90,7 @@ int ObTabletCreatorArg::init( const bool is_create_bind_hidden_tablets, const uint64_t tenant_data_version, const ObIArray &need_create_empty_majors, + const ObIArray &create_commit_versions, const bool has_cs_replica) { int ret = OB_SUCCESS; @@ -107,6 +112,8 @@ int ObTabletCreatorArg::init( LOG_WARN("failed to assign table schemas", KR(ret), K(table_schemas)); } else if (OB_FAIL(need_create_empty_majors_.assign(need_create_empty_majors))) { LOG_WARN("failed to assign need create empty majors", K(ret), K(need_create_empty_majors)); + } else if (OB_FAIL(create_commit_versions_.assign(create_commit_versions))) { + LOG_WARN("failed to assign create commit versions", KR(ret), K(create_commit_versions)); } else { data_tablet_id_ = data_tablet_id; ls_key_ = ls_key; @@ -122,7 +129,7 @@ DEF_TO_STRING(ObTabletCreatorArg) { int64_t pos = 0; J_KV(K_(compat_mode), K_(tablet_ids), K_(data_tablet_id), K_(ls_key), K_(table_schemas), K_(is_create_bind_hidden_tablets), - K_(tenant_data_version), K_(need_create_empty_majors), K_(has_cs_replica)); + K_(tenant_data_version), K_(need_create_empty_majors), K_(create_commit_versions), K_(has_cs_replica)); return pos; } @@ -136,6 +143,7 @@ int ObBatchCreateTabletHelper::init( { int ret = OB_SUCCESS; const int64_t bucket_count = hash::cal_next_prime(100); + auto_part_size_arr_.reset(); if (OB_UNLIKELY(!ls_key.is_valid() || OB_INVALID_TENANT_ID == tenant_id)) { ret = OB_INVALID_ARGUMENT; @@ -182,6 +190,7 @@ int ObBatchCreateTabletHelper::add_arg_to_batch_arg( index_array, tablet_arg.compat_mode_, tablet_arg.is_create_bind_hidden_tablets_, + tablet_arg.create_commit_versions_, tablet_arg.has_cs_replica_))) { LOG_WARN("failed to init create tablet info", KR(ret), K(index_array), K(tablet_arg)); } else if (OB_FAIL(batch_arg_.tablets_.push_back(info))) { @@ -193,15 +202,19 @@ int ObBatchCreateTabletHelper::add_arg_to_batch_arg( } int ObBatchCreateTabletHelper::add_table_schema_( - const share::schema::ObTableSchema &table_schema, + const share::schema::ObTableSchema &const_table_schema, const lib::Worker::CompatMode compat_mode, const uint64_t tenant_data_version, const bool need_create_empty_major, int64_t &index) { int ret = OB_SUCCESS; - if (tenant_data_version < DATA_VERSION_4_2_2_0) { + HEAP_VAR(ObTableSchema, table_schema) { + if (OB_FAIL(table_schema.assign(const_table_schema))) { + LOG_WARN("failed to assign table_schema", KR(ret), K(const_table_schema)); + } else if (tenant_data_version < DATA_VERSION_4_2_2_0) { // compatibility with DATA_VERSION_4_2_1. + table_schema.reset_partition_schema(); index = batch_arg_.table_schemas_.count(); if (OB_FAIL(batch_arg_.table_schemas_.push_back(table_schema))) { LOG_WARN("failed to push back table schema", KR(ret), K(table_schema)); @@ -226,8 +239,11 @@ int ObBatchCreateTabletHelper::add_table_schema_( LOG_WARN("init create table extra info failed", K(ret), K(tenant_data_version), K(need_create_empty_major), K(table_schema)); } else if (OB_FAIL(batch_arg_.tablet_extra_infos_.push_back(create_tablet_extr_info))) { LOG_WARN("failed to push back tablet extra infos", K(ret), K(create_tablet_extr_info)); + } else if (OB_FAIL(auto_part_size_arr_.push_back(table_schema.is_auto_partitioned_table() ? table_schema.get_auto_part_size() : OB_INVALID_SIZE))) { + LOG_WARN("failed to push back", KR(ret)); } } + } return ret; } @@ -248,16 +264,10 @@ int ObBatchCreateTabletHelper::try_add_table_schema( //nothing } else if(OB_HASH_NOT_EXIST == ret) { ret = OB_SUCCESS; - HEAP_VAR(ObTableSchema, temp_table_schema) { - if (OB_FAIL(temp_table_schema.assign(*table_schema))) { - LOG_WARN("failed to assign temp_table_schema", KR(ret), KPC(table_schema)); - } else if (FALSE_IT(temp_table_schema.reset_partition_schema())) { - } else if (OB_FAIL(add_table_schema_(temp_table_schema, compat_mode, - tenant_data_version, need_create_empty_major, index))) { - LOG_WARN("failed to push back table schema", KR(ret), K(temp_table_schema)); - } else if (OB_FAIL(table_schemas_map_.set_refactored(temp_table_schema.get_table_id(), index))) { - LOG_WARN("failed to set table schema map", KR(ret), K(index), K(temp_table_schema)); - } + if (OB_FAIL(add_table_schema_(*table_schema, compat_mode, tenant_data_version, need_create_empty_major, index))) { + LOG_WARN("failed to push back table schema", KR(ret), KPC(table_schema)); + } else if (OB_FAIL(table_schemas_map_.set_refactored(table_schema->get_table_id(), index))) { + LOG_WARN("failed to set table schema map", KR(ret), K(index), KPC(table_schema)); } } else { LOG_WARN("failed to find table schema in map", KR(ret), KP(table_schema)); @@ -328,8 +338,7 @@ int ObTabletCreator::add_create_tablet_arg(const ObTabletCreatorArg &arg) ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("failed to allocate new arg", KR(ret), KP(batch_arg)); } else if (FALSE_IT(batch_arg = new (arg_buf)ObBatchCreateTabletHelper())) { - } else if (OB_FAIL(batch_arg->init(arg.ls_key_, tenant_id_, major_frozen_scn_, - need_check_tablet_cnt_))) { + } else if (OB_FAIL(batch_arg->init(arg.ls_key_, tenant_id_, major_frozen_scn_, need_check_tablet_cnt_))) { LOG_WARN("failed to init batch arg helper", KR(ret), K(arg)); } else if (OB_FAIL(args_map_.set_refactored(arg.ls_key_, batch_arg, 0/*not overwrite*/))) { LOG_WARN("fail to set refactored", KR(ret), K(arg)); @@ -349,8 +358,7 @@ int ObTabletCreator::add_create_tablet_arg(const ObTabletCreatorArg &arg) ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("failed to allocate new arg", KR(ret)); } else if (FALSE_IT(new_arg = new (arg_buf)ObBatchCreateTabletHelper())) { - } else if (OB_FAIL(new_arg->init(arg.ls_key_, tenant_id_, major_frozen_scn_, - need_check_tablet_cnt_))) { + } else if (OB_FAIL(new_arg->init(arg.ls_key_, tenant_id_, major_frozen_scn_, need_check_tablet_cnt_))) { LOG_WARN("failed to init batch arg helper", KR(ret), K(arg)); } else if (FALSE_IT(new_arg->next_ = batch_arg)) { } else if (OB_FAIL(args_map_.set_refactored(arg.ls_key_, new_arg, 1/*overwrite*/))) { @@ -367,6 +375,36 @@ int ObTabletCreator::add_create_tablet_arg(const ObTabletCreatorArg &arg) return ret; } +int ObTabletCreator::modify_batch_args( + const storage::ObTabletMdsUserDataType &create_type, + const SCN &clog_checkpoint_scn, + const bool clear_auto_part_size) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(0 >= args_map_.size())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("batch arg count is invalid", KR(ret)); + } else { + FOREACH_X(iter, args_map_, OB_SUCC(ret)) { + ObBatchCreateTabletHelper *batch_arg = iter->second; + if (OB_ISNULL(batch_arg)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("batch arg not be null", KR(ret)); + } else { + while (OB_SUCC(ret) && OB_NOT_NULL(batch_arg)) { + batch_arg->batch_arg_.clog_checkpoint_scn_ = clog_checkpoint_scn; + batch_arg->batch_arg_.create_type_ = create_type; + if (clear_auto_part_size) { + batch_arg->auto_part_size_arr_.reset(); + } + batch_arg = batch_arg->next_; + } // end while + } + } // end for + } + return ret; +} + int ObTabletCreator::execute() { int ret = OB_SUCCESS; @@ -431,6 +469,16 @@ int ObTabletCreator::execute() LOG_INFO("modify binding for create", KR(ret), K(buf_len), K(batch_arg->batch_arg_.tablets_.count()), "cost_ts", end_time - start_time); } + if (OB_SUCC(ret)) { + const int64_t start_time = ObTimeUtility::current_time(); + if (OB_FAIL(ObTabletSplitMdsHelper::set_auto_part_size_for_create(tenant_id_, + batch_arg->batch_arg_, batch_arg->auto_part_size_arr_, ctx.get_abs_timeout(), trans_))) { + LOG_WARN("failed to set auto part size for create", K(ret)); + } + const int64_t end_time = ObTimeUtility::current_time(); + LOG_INFO("set auto part size for create", KR(ret), K(buf_len), K(batch_arg->batch_arg_.tablets_.count()), + "cost_ts", end_time - start_time); + } } batch_arg = batch_arg->next_; } // end while diff --git a/src/rootserver/ob_tablet_creator.h b/src/rootserver/ob_tablet_creator.h index d25e15803..1c091592d 100644 --- a/src/rootserver/ob_tablet_creator.h +++ b/src/rootserver/ob_tablet_creator.h @@ -53,6 +53,7 @@ public: const bool is_create_bind_hidden_tablets, const uint64_t tenant_data_version, const ObIArray &need_create_empty_majors, + const ObIArray &create_commit_versions, const bool has_cs_replica); DECLARE_TO_STRING; @@ -64,6 +65,7 @@ public: bool is_create_bind_hidden_tablets_; uint64_t tenant_data_version_; common::ObArray need_create_empty_majors_; + common::ObArray create_commit_versions_; bool has_cs_replica_; private: DISALLOW_COPY_AND_ASSIGN(ObTabletCreatorArg); @@ -75,6 +77,7 @@ public: ObBatchCreateTabletHelper() : batch_arg_(), table_schemas_map_(), + auto_part_size_arr_(), result_(common::OB_NOT_MASTER), next_(NULL) {} @@ -92,12 +95,15 @@ public: { batch_arg_.reset(); table_schemas_map_.clear(); + auto_part_size_arr_.reset(); result_ = common::OB_NOT_MASTER; } DECLARE_TO_STRING; obrpc::ObBatchCreateTabletArg batch_arg_; //table_id : index of table_schems_ in arg common::hash::ObHashMap table_schemas_map_; + // if non-empty, auto_part_size_arr_[i] = auto_part_size of batch_arg_.table_schemas_[i] + ObArray auto_part_size_arr_; //the result of create tablet int result_; ObBatchCreateTabletHelper *next_; @@ -128,11 +134,13 @@ const static int64_t BATCH_ARG_SIZE = 1024 * 1024; // 1M trans_(trans), need_check_tablet_cnt_(false), inited_(false) {} + virtual ~ObTabletCreator(); int init(const bool need_check_tablet_cnt); int execute(); bool need_retry(int ret); int add_create_tablet_arg(const ObTabletCreatorArg &arg); + int modify_batch_args(const storage::ObTabletMdsUserDataType &create_type, const share::SCN &clog_checkpoint_scn, const bool clear_auto_part_size); void reset(); private: int find_leader_of_ls(const share::ObLSID &id, ObAddr &addr); diff --git a/src/rootserver/ob_tenant_transfer_service.cpp b/src/rootserver/ob_tenant_transfer_service.cpp index 6a270366d..00064d68a 100644 --- a/src/rootserver/ob_tenant_transfer_service.cpp +++ b/src/rootserver/ob_tenant_transfer_service.cpp @@ -743,6 +743,7 @@ int ObTenantTransferService::add_table_lock_( LOG_WARN("lock partition failed", KR(ret), K(part_lock_arg)); } } else if (PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + part_lock_arg.is_sub_part_ = true; if (OB_FAIL(ObInnerConnectionLockUtil::lock_subpartition(tenant_id_, part_lock_arg, conn))) { LOG_WARN("lock subpartition failed", KR(ret), K(part_lock_arg)); } @@ -1541,6 +1542,7 @@ int ObTenantTransferService::unlock_table_lock_( LOG_WARN("unlock partition failed", KR(ret), K(unlock_part_arg)); } } else if (PARTITION_LEVEL_TWO == table_schema.get_part_level()) { + unlock_part_arg.is_sub_part_ = true; if (OB_FAIL(ObInnerConnectionLockUtil::unlock_subpartition(tenant_id_, unlock_part_arg, conn))) { LOG_WARN("unlock subpartition failed", KR(ret), K(unlock_part_arg)); } diff --git a/src/rootserver/parallel_ddl/ob_create_table_helper.cpp b/src/rootserver/parallel_ddl/ob_create_table_helper.cpp index f242b4fd7..2468fc6a5 100644 --- a/src/rootserver/parallel_ddl/ob_create_table_helper.cpp +++ b/src/rootserver/parallel_ddl/ob_create_table_helper.cpp @@ -1149,6 +1149,11 @@ int ObCreateTableHelper::generate_table_schema_() } } + // check auto_partition validity + if (FAILEDx(new_table.check_validity_for_auto_partition())) { + LOG_WARN("fail to check auto partition setting", KR(ret), K(new_table), K(arg_)); + } + if (FAILEDx(new_tables_.push_back(new_table))) { LOG_WARN("fail to push back table", KR(ret)); } @@ -1197,7 +1202,8 @@ int ObCreateTableHelper::generate_aux_table_schemas_() index_schema.reset(); obrpc::ObCreateIndexArg &index_arg = const_cast(arg_.index_arg_list_.at(i)); if (!index_arg.index_schema_.is_partitioned_table() - && !data_table->is_partitioned_table()) { + && !data_table->is_partitioned_table() + && !data_table->is_auto_partitioned_table()) { if (INDEX_TYPE_NORMAL_GLOBAL == index_arg.index_type_) { index_arg.index_type_ = INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE; } else if (INDEX_TYPE_UNIQUE_GLOBAL == index_arg.index_type_) { diff --git a/src/share/CMakeLists.txt b/src/share/CMakeLists.txt index a9167e2eb..4bd6704b7 100644 --- a/src/share/CMakeLists.txt +++ b/src/share/CMakeLists.txt @@ -110,6 +110,7 @@ ob_set_subtarget(ob_share common ob_ddl_sim_point.cpp ob_ddl_common.cpp ob_ddl_error_message_table_operator.cpp + ob_tablet_reorganize_history_table_operator.cpp ob_ddl_task_executor.cpp ob_debug_sync.cpp ob_debug_sync_point.cpp @@ -212,6 +213,7 @@ ob_set_subtarget(ob_share common ob_cluster_event_history_table_operator.cpp scn.cpp ob_throttling_utils.cpp + ob_partition_split_query.cpp ob_storage_ha_diagnose_struct.cpp ob_storage_ha_diagnose_operator.cpp ob_vec_index_builder_util.cpp @@ -309,6 +311,7 @@ ob_set_subtarget(ob_share common_mixed scheduler/ob_tenant_dag_scheduler.cpp scheduler/ob_sys_task_stat.cpp scheduler/ob_dag_warning_history_mgr.cpp + scheduler/ob_partition_auto_split_helper.cpp compaction/ob_compaction_locality_cache.cpp compaction/ob_table_ckm_items.cpp compaction/ob_compaction_time_guard.cpp diff --git a/src/share/backup/ob_backup_tablet_reorganize_helper.cpp b/src/share/backup/ob_backup_tablet_reorganize_helper.cpp index 6af38bb7e..6b907ea3f 100644 --- a/src/share/backup/ob_backup_tablet_reorganize_helper.cpp +++ b/src/share/backup/ob_backup_tablet_reorganize_helper.cpp @@ -15,6 +15,7 @@ #include "share/rc/ob_tenant_base.h" #include "lib/utility/ob_macro_utils.h" #include "lib/hash/ob_hashset.h" +#include "share/ob_tablet_reorganize_history_table_operator.h" using namespace oceanbase::common::hash; using namespace oceanbase::common; @@ -96,11 +97,10 @@ int ObBackupTabletReorganizeHelper::check_tablet_has_reorganized(common::ObMySQL const uint64_t tenant_id, const common::ObTabletID &tablet_id, share::ObLSID &ls_id, bool &reorganized) { int ret = OB_SUCCESS; - // TODO(yanfeng): wait auto_split branch merge - // if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::check_tablet_has_reorganized( - // sql_proxy, tenant_id, tablet_id, ls_id, reorganized))) { - // LOG_WARN("failed to check tablet has reorganized", K(ret), K(tenant_id), K(tablet_id), K(ls_id)); - // } + if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::check_tablet_has_reorganized( + sql_proxy, tenant_id, tablet_id, ls_id, reorganized))) { + LOG_WARN("failed to check tablet has reorganized", K(ret), K(tenant_id), K(tablet_id), K(ls_id)); + } return ret; } @@ -200,24 +200,23 @@ int ObBackupTabletReorganizeHelper::get_all_tablet_reorganize_history_infos_( common::ObIArray &history_infos) { int ret = OB_SUCCESS; - // TODO(yanfeng): wait auto_split branch merge - // ObArray tablet_pairs; - // if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::get_all_split_tablet_pairs( - // sql_proxy, tenant_id, ls_id, tablet_pairs))) { - // LOG_WARN("failed to get all split tablet pairs", K(ret)); - // } else { - // ObTabletReorganizeInfo info; - // ARRAY_FOREACH_X(tablet_pairs, idx, cnt, OB_SUCC(ret)) { - // const ReorganizeTabletPair &pair = tablet_pairs.at(idx); - // info.tenant_id_ = tenant_id; - // info.ls_id_ = ls_id; - // info.src_tablet_id_ = pair.src_tablet_id_; - // info.dest_tablet_id_ = pair.dest_tablet_id_; - // if (OB_FAIL(history_infos.push_back(info))) { - // LOG_WARN("failed to push back", K(ret)); - // } - // } - // } + ObArray tablet_pairs; + if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::get_all_split_tablet_pairs( + sql_proxy, tenant_id, ls_id, tablet_pairs))) { + LOG_WARN("failed to get all split tablet pairs", K(ret)); + } else { + ObTabletReorganizeInfo info; + ARRAY_FOREACH_X(tablet_pairs, idx, cnt, OB_SUCC(ret)) { + const ReorganizeTabletPair &pair = tablet_pairs.at(idx); + info.tenant_id_ = tenant_id; + info.ls_id_ = ls_id; + info.src_tablet_id_ = pair.src_tablet_id_; + info.dest_tablet_id_ = pair.dest_tablet_id_; + if (OB_FAIL(history_infos.push_back(info))) { + LOG_WARN("failed to push back", K(ret)); + } + } + } return ret; } diff --git a/src/share/compaction/ob_schedule_batch_size_mgr.cpp b/src/share/compaction/ob_schedule_batch_size_mgr.cpp index 9cb175294..98fcc1519 100644 --- a/src/share/compaction/ob_schedule_batch_size_mgr.cpp +++ b/src/share/compaction/ob_schedule_batch_size_mgr.cpp @@ -8,9 +8,9 @@ // MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. // See the Mulan PubL v2 for more details. #define USING_LOG_PREFIX STORAGE_COMPACTION -#include "share/compaction/ob_schedule_batch_size_mgr.h" -#include "lib/oblog/ob_log.h" +#include #include "lib/oblog/ob_log_module.h" +#include "share/compaction/ob_schedule_batch_size_mgr.h" namespace oceanbase { @@ -19,14 +19,13 @@ namespace compaction void ObScheduleBatchSizeMgr::set_tablet_batch_size(const int64_t tablet_batch_size) { if (tablet_batch_size != tablet_batch_size_ && tablet_batch_size > 0) { - LOG_INFO("succeeded to reload new merge schedule tablet batch cnt", K(tablet_batch_size)); tablet_batch_size_ = tablet_batch_size; } } int64_t ObScheduleBatchSizeMgr::get_checker_batch_size() const { - return MAX(DEFAULT_CHECKER_BATCH_SIZE, tablet_batch_size_ / 100); + return std::max(static_cast(DEFAULT_CHECKER_BATCH_SIZE), tablet_batch_size_ / 100); } void ObScheduleBatchSizeMgr::get_rs_check_batch_size( @@ -42,7 +41,7 @@ void ObScheduleBatchSizeMgr::get_rs_check_batch_size( int64_t ObScheduleBatchSizeMgr::get_inner_table_scan_batch_size() const { - return MAX(1, (tablet_batch_size_ / DEFAULT_TABLET_BATCH_CNT)) * DEFAULT_INNER_TABLE_SCAN_BATCH_SIZE; + return std::max(1L, (tablet_batch_size_ / DEFAULT_TABLET_BATCH_CNT)) * DEFAULT_INNER_TABLE_SCAN_BATCH_SIZE; } bool ObScheduleBatchSizeMgr::need_rebuild_map( @@ -52,8 +51,8 @@ bool ObScheduleBatchSizeMgr::need_rebuild_map( int64_t &recommend_map_bucked_cnt) { bool rebuild_map_flag = false; - int64_t map_cnt = MAX(item_cnt / 3, default_map_bucket_cnt); - recommend_map_bucked_cnt = MIN(map_cnt, default_map_bucket_cnt * 30); + int64_t map_cnt = std::max(item_cnt / 3, default_map_bucket_cnt); + recommend_map_bucked_cnt = std::min(map_cnt, default_map_bucket_cnt * 30); if ((cur_bucket_cnt == 0) || (recommend_map_bucked_cnt < map_cnt / 2) || (recommend_map_bucked_cnt > map_cnt * 3)) { diff --git a/src/share/compaction/ob_table_ckm_items.cpp b/src/share/compaction/ob_table_ckm_items.cpp index 6fbd9532c..c06eff5f2 100644 --- a/src/share/compaction/ob_table_ckm_items.cpp +++ b/src/share/compaction/ob_table_ckm_items.cpp @@ -11,6 +11,7 @@ #include "share/compaction/ob_table_ckm_items.h" #include "lib/utility/ob_tracepoint.h" #include "rootserver/freeze/ob_major_merge_progress_util.h" +#include "share/resource_manager/ob_cgroup_ctrl.h" namespace oceanbase { using namespace oceanbase::common; @@ -287,7 +288,38 @@ int ObTableCkmItems::build_for_s2( } #endif +// For partition split ddl, the scenario will generate major sstables with more columns expectedly. +// 1. multi parts compact with columns cnt A. +// 2. online add column, and columns cnt will change to B. +// 3. some parts split, and the destination parts will generate major sstables with columns cnt B. +// 4. RS compaction validation will find different columns cnt between different parts. +int ObTableCkmItems::check_tail_column_checksums_legal( + const bool is_data_table, + const ObIArray &base_column_checksums, + const ObIArray &check_column_checksums) +{ + int ret = OB_SUCCESS; + if (OB_LIKELY(check_column_checksums.count() == base_column_checksums.count())) { + // do nothing. + } else if (OB_UNLIKELY(!is_data_table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("column checksums cnt between differnt parts should be equal on non-data table", K(ret), K(base_column_checksums), K(check_column_checksums)); + } else if (OB_UNLIKELY(check_column_checksums.count() < base_column_checksums.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("column checksums cnt is relatively small", K(ret), K(base_column_checksums), K(check_column_checksums)); + } else { + for (int64_t idx = base_column_checksums.count(); OB_SUCC(ret) && idx < check_column_checksums.count(); idx++) { + if (OB_UNLIKELY(0 != check_column_checksums.at(idx))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("extra tail columns' checksum should be empty", K(ret), K(idx), K(base_column_checksums), K(check_column_checksums)); + } + } + } + return ret; +} + int ObTableCkmItems::build_column_ckm_sum_array( + const bool is_data_table, const SCN &compaction_scn, const share::schema::ObTableSchema &table_schema, int64_t &row_cnt) @@ -315,8 +347,13 @@ int ObTableCkmItems::build_column_ckm_sum_array( if (OB_FAIL(ckm_items_.get(tablet_id, cur_item))) { LOG_WARN("failed to get ckm item", KR(ret), K(tablet_id), K(pair_idx), K(tablet_pairs_)); } else if (OB_UNLIKELY(cur_item->column_meta_.column_checksums_.count() != column_checksums_cnt)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("column ckm count is unexpected", KR(ret), K(cur_item), K(column_checksums_cnt)); + // Why the first ckm_item can be selected as the based one? + // Any partition alter operation will result in an increase in tablet_id, and ckm_items_ is generated order by the tablet_id. + // The smallest tablet_id means that the schema held by this partition is older. + if (OB_FAIL(check_tail_column_checksums_legal(is_data_table, + ckm_items_.at(0).column_meta_.column_checksums_, cur_item->column_meta_.column_checksums_))) { + LOG_WARN("check tail column checksum legal failed", K(ret), K(column_checksums_cnt), K(cur_item), "base_item", ckm_items_.at(0)); + } } else if (cur_item->compaction_scn_ == compaction_scn) { const ObTabletReplicaReportColumnMeta &cur_column_meta = cur_item->column_meta_; if (pre_tablet_id == OB_INVALID_ID) { // first ckm item @@ -382,9 +419,9 @@ int ObTableCkmItems::validate_column_ckm_sum( ret = OB_ERR_UNEXPECTED; LOG_WARN("data table and index table should not validate column checksum", KR(ret), KPC(data_table_schema), KPC(index_table_schema)); - } else if (OB_FAIL(data_ckm.build_column_ckm_sum_array(compaction_scn, *data_table_schema, data_row_cnt))) { + } else if (OB_FAIL(data_ckm.build_column_ckm_sum_array(true/*is_data_table*/, compaction_scn, *data_table_schema, data_row_cnt))) { LOG_WARN("failed to build column ckm sum map for data table", KR(ret)); - } else if (OB_FAIL(index_ckm.build_column_ckm_sum_array(compaction_scn, *index_table_schema, index_row_cnt))) { + } else if (OB_FAIL(index_ckm.build_column_ckm_sum_array(false/*is_data_table*/, compaction_scn, *index_table_schema, index_row_cnt))) { LOG_WARN("failed to build column ckm sum map for index table", KR(ret)); } else if (OB_UNLIKELY(data_row_cnt != index_row_cnt)) { ret = OB_CHECKSUM_ERROR; diff --git a/src/share/compaction/ob_table_ckm_items.h b/src/share/compaction/ob_table_ckm_items.h index ae180a6dc..a3e20dae5 100644 --- a/src/share/compaction/ob_table_ckm_items.h +++ b/src/share/compaction/ob_table_ckm_items.h @@ -132,6 +132,7 @@ public: const compaction::ObTabletLSPairCache &tablet_ls_pair_cache); #endif int build_column_ckm_sum_array( + const bool is_data_table, const share::SCN &compaction_scn, const share::schema::ObTableSchema &table_schema, int64_t &row_cnt); @@ -170,6 +171,10 @@ private: share::schema::ObSchemaGetterGuard &schema_guard, const compaction::ObTabletLSPairCache &tablet_ls_pair_cache, common::ObIArray &tablet_id_array); + int check_tail_column_checksums_legal( + const bool is_data_table, + const ObIArray &base_column_checksums, + const ObIArray &check_column_checksums); static const int64_t DEFAULT_COLUMN_CNT = 64; static const int64_t DEFAULT_TABLET_CNT = 16; 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 5227f15d1..b9bd7a96d 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 @@ -4781,6 +4781,158 @@ int ObInnerTableSchema::all_virtual_user_proxy_role_info_history_schema(ObTableS return ret; } +int ObInnerTableSchema::all_virtual_tablet_reorganize_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_TABLET_REORGANIZE_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(4); + 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_TABLET_REORGANIZE_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("ls_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("src_tablet_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("dest_tablet_id", //column_name + ++column_id, //column_id + 4, //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("type", //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_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_TS("finish_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_micro_index_clustered(false); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_virtual_res_mgr_directive_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.20001_20050.cpp b/src/share/inner_table/ob_inner_table_schema.20001_20050.cpp index af5b4a1c2..437d2b241 100644 --- a/src/share/inner_table/ob_inner_table_schema.20001_20050.cpp +++ b/src/share/inner_table/ob_inner_table_schema.20001_20050.cpp @@ -417,7 +417,7 @@ int ObInnerTableSchema::tables_schema(ObTableSchema &table_schema) 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 /*+ leading(a) no_use_nl(ts)*/ cast('def' as char(512)) as TABLE_CATALOG, cast(b.database_name as char(64)) collate utf8mb4_name_case as TABLE_SCHEMA, cast(a.table_name as char(64)) collate utf8mb4_name_case as TABLE_NAME, cast(case when (a.database_id = 201002 or a.table_type = 1) then 'SYSTEM VIEW' when a.table_type in (0, 2) then 'SYSTEM TABLE' when a.table_type = 4 then 'VIEW' when a.table_type = 14 then 'EXTERNAL TABLE' else 'BASE TABLE' end as char(64)) as TABLE_TYPE, cast(case when a.table_type in (0,3,5,6,7,11,12,13,15) then 'InnoDB' else 'MEMORY' end as char(64)) as ENGINE, cast(NULL as unsigned) as VERSION, cast(a.store_format as char(10)) as ROW_FORMAT, cast( coalesce(ts.row_cnt,0) as unsigned) as TABLE_ROWS, cast( coalesce(ts.avg_row_len,0) as unsigned) as AVG_ROW_LENGTH, cast( coalesce(ts.data_size,0) as unsigned) as DATA_LENGTH, cast(NULL as unsigned) as MAX_DATA_LENGTH, cast( coalesce(idx_stat.index_length, 0) as unsigned) as INDEX_LENGTH, cast(NULL as unsigned) as DATA_FREE, cast(NULL as unsigned) as AUTO_INCREMENT, cast(a.gmt_create as datetime) as CREATE_TIME, cast(a.gmt_modified as datetime) as UPDATE_TIME, cast(NULL as datetime) as CHECK_TIME, cast(d.collation as char(32)) as TABLE_COLLATION, cast(NULL as unsigned) as CHECKSUM, cast(NULL as char(255)) as CREATE_OPTIONS, cast(case when a.table_type = 4 then 'VIEW' else a.comment end as char(2048)) as TABLE_COMMENT from ( select cast(0 as signed) as tenant_id, c.database_id, c.table_id, c.table_name, c.collation_type, c.table_type, usec_to_time(d.schema_version) as gmt_create, usec_to_time(c.schema_version) as gmt_modified, c.comment, c.store_format from oceanbase.__all_virtual_core_all_table c join oceanbase.__all_virtual_core_all_table d on c.tenant_id = d.tenant_id and d.table_name = '__all_core_table' where c.tenant_id = effective_tenant_id() union all select tenant_id, database_id, table_id, table_name, collation_type, table_type, gmt_create, gmt_modified, comment, store_format from oceanbase.__all_table where table_mode >> 12 & 15 in (0,1)) a join oceanbase.__all_database b on a.database_id = b.database_id and a.tenant_id = b.tenant_id join oceanbase.__tenant_virtual_collation d on a.collation_type = d.collation_type left join ( select tenant_id, table_id, row_cnt, avg_row_len, (macro_blk_cnt * 2 * 1024 * 1024) as data_size from oceanbase.__all_table_stat where partition_id = -1 or partition_id = table_id) ts on a.table_id = ts.table_id and a.tenant_id = ts.tenant_id left join ( select e.tenant_id as tenant_id, e.data_table_id as data_table_id, SUM(f.macro_blk_cnt * 2 * 1024 * 1024) AS index_length FROM oceanbase.__all_table e JOIN oceanbase.__all_table_stat f ON e.tenant_id = f.tenant_id and e.table_id = f.table_id and (f.partition_id = -1 or f.partition_id = e.table_id) WHERE e.index_type in (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12) and e.table_type = 5 group by tenant_id, data_table_id ) idx_stat on idx_stat.tenant_id = a.tenant_id and idx_stat.data_table_id = a.table_id where a.tenant_id = 0 and a.table_type in (0, 1, 2, 3, 4, 14, 15) and b.database_name != '__recyclebin' and b.in_recyclebin = 0 and 0 = sys_privilege_check('table_acc', effective_tenant_id(), b.database_name, a.table_name) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( select /*+ leading(a) no_use_nl(ts)*/ cast('def' as char(512)) as TABLE_CATALOG, cast(b.database_name as char(64)) collate utf8mb4_name_case as TABLE_SCHEMA, cast(a.table_name as char(64)) collate utf8mb4_name_case as TABLE_NAME, cast(case when (a.database_id = 201002 or a.table_type = 1) then 'SYSTEM VIEW' when a.table_type in (0, 2) then 'SYSTEM TABLE' when a.table_type = 4 then 'VIEW' when a.table_type = 14 then 'EXTERNAL TABLE' else 'BASE TABLE' end as char(64)) as TABLE_TYPE, cast(case when a.table_type in (0,3,5,6,7,11,12,13,15) then 'InnoDB' else 'MEMORY' end as char(64)) as ENGINE, cast(NULL as unsigned) as VERSION, cast(a.store_format as char(10)) as ROW_FORMAT, cast( coalesce(ts.row_cnt,0) as unsigned) as TABLE_ROWS, cast( coalesce(ts.avg_row_len,0) as unsigned) as AVG_ROW_LENGTH, cast( coalesce(ts.data_size,0) as unsigned) as DATA_LENGTH, cast(NULL as unsigned) as MAX_DATA_LENGTH, cast( coalesce(idx_stat.index_length, 0) as unsigned) as INDEX_LENGTH, cast(NULL as unsigned) as DATA_FREE, cast(NULL as unsigned) as AUTO_INCREMENT, cast(a.gmt_create as datetime) as CREATE_TIME, cast(a.gmt_modified as datetime) as UPDATE_TIME, cast(NULL as datetime) as CHECK_TIME, cast(d.collation as char(32)) as TABLE_COLLATION, cast(NULL as unsigned) as CHECKSUM, cast(NULL as char(255)) as CREATE_OPTIONS, cast(case when a.table_type = 4 then 'VIEW' else a.comment end as char(2048)) as TABLE_COMMENT, cast(case when a.auto_part = 1 then 'TRUE' else 'FALSE' end as char(16)) as AUTO_SPLIT, cast(case when a.auto_part = 1 then a.auto_part_size else 0 end as unsigned) as AUTO_SPLIT_TABLET_SIZE from ( select cast(0 as signed) as tenant_id, c.database_id, c.table_id, c.table_name, c.collation_type, c.table_type, usec_to_time(d.schema_version) as gmt_create, usec_to_time(c.schema_version) as gmt_modified, c.comment, c.store_format, c.auto_part, c.auto_part_size from oceanbase.__all_virtual_core_all_table c join oceanbase.__all_virtual_core_all_table d on c.tenant_id = d.tenant_id and d.table_name = '__all_core_table' where c.tenant_id = effective_tenant_id() union all select tenant_id, database_id, table_id, table_name, collation_type, table_type, gmt_create, gmt_modified, comment, store_format, auto_part, auto_part_size from oceanbase.__all_table where table_mode >> 12 & 15 in (0,1)) a join oceanbase.__all_database b on a.database_id = b.database_id and a.tenant_id = b.tenant_id join oceanbase.__tenant_virtual_collation d on a.collation_type = d.collation_type left join ( select tenant_id, table_id, row_cnt, avg_row_len, (macro_blk_cnt * 2 * 1024 * 1024) as data_size from oceanbase.__all_table_stat where partition_id = -1 or partition_id = table_id) ts on a.table_id = ts.table_id and a.tenant_id = ts.tenant_id left join ( select e.tenant_id as tenant_id, e.data_table_id as data_table_id, SUM(f.macro_blk_cnt * 2 * 1024 * 1024) AS index_length FROM oceanbase.__all_table e JOIN oceanbase.__all_table_stat f ON e.tenant_id = f.tenant_id and e.table_id = f.table_id and (f.partition_id = -1 or f.partition_id = e.table_id) WHERE e.index_type in (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12) and e.table_type = 5 group by tenant_id, data_table_id ) idx_stat on idx_stat.tenant_id = a.tenant_id and idx_stat.data_table_id = a.table_id where a.tenant_id = 0 and a.table_type in (0, 1, 2, 3, 4, 14, 15) and b.database_name != '__recyclebin' and b.in_recyclebin = 0 and 0 = sys_privilege_check('table_acc', effective_tenant_id(), b.database_name, a.table_name) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21151_21200.cpp b/src/share/inner_table/ob_inner_table_schema.21151_21200.cpp index fb7f179f1..a054f5c79 100644 --- a/src/share/inner_table/ob_inner_table_schema.21151_21200.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21151_21200.cpp @@ -1947,7 +1947,7 @@ int ObInnerTableSchema::cdb_objects_schema(ObTableSchema &table_schema) 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 CAST(A.TENANT_ID AS SIGNED) AS CON_ID, CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS CHAR(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS SIGNED) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS SIGNED) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS CHAR(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATETIME) AS CREATED, CAST(A.GMT_MODIFIED AS DATETIME) AS LAST_DDL_TIME, CAST(A.GMT_CREATE AS DATETIME) AS TIMESTAMP, CAST(A.STATUS AS CHAR(7)) AS STATUS, CAST(A.TEMPORARY AS CHAR(1)) AS TEMPORARY, CAST(A.`GENERATED` AS CHAR(1)) AS "GENERATED", CAST(A.SECONDARY AS CHAR(1)) AS SECONDARY, CAST(A.NAMESPACE AS SIGNED) AS NAMESPACE, CAST(A.EDITION_NAME AS CHAR(128)) AS EDITION_NAME, CAST(NULL AS CHAR(18)) AS SHARING, CAST(NULL AS CHAR(1)) AS EDITIONABLE, CAST(NULL AS CHAR(1)) AS ORACLE_MAINTAINED, CAST(NULL AS CHAR(1)) AS APPLICATION, CAST(NULL AS CHAR(1)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS IMPORTED_OBJECT, CAST(NULL AS SIGNED) AS CREATED_APPID, CAST(NULL AS SIGNED) AS CREATED_VSNID, CAST(NULL AS SIGNED) AS MODIFIED_APPID, CAST(NULL AS SIGNED) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, USEC_TO_TIME(B.SCHEMA_VERSION) AS GMT_CREATE, USEC_TO_TIME(A.SCHEMA_VERSION) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS SIGNED) AS OBJECT_ID, A.TABLET_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE A JOIN OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID AND B.TABLE_NAME = '__all_core_table' UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + POSITION('_' IN SUBSTR(TABLE_NAME, 7))) ELSE TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5,15) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS CHAR(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.constraint_name AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CONSTRAINT CST, OCEANBASE.__ALL_VIRTUAL_TABLE TBL, OCEANBASE.__ALL_VIRTUAL_DATABASE DB WHERE CST.TENANT_ID = TBL.TENANT_ID AND TBL.TENANT_ID = DB.TENANT_ID AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX PARTITION' ELSE 'TABLE PARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX SUBPARTITION' ELSE 'TABLE SUBPARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM OCEANBASE.__ALL_VIRTUAL_PACKAGE Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_PACKAGE P UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_ROUTINE R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TYPE UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_OBJECT_TYPE WHERE TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TRIGGER T UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_SEQUENCE_OBJECT UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_SYNONYM UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS SIGNED) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TENANT_CONTEXT UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_DATABASE UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP ) A JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(A.TENANT_ID AS SIGNED) AS CON_ID, CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS CHAR(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS SIGNED) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS SIGNED) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS CHAR(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATETIME) AS CREATED, CAST(A.GMT_MODIFIED AS DATETIME) AS LAST_DDL_TIME, CAST(A.GMT_CREATE AS DATETIME) AS TIMESTAMP, CAST(A.STATUS AS CHAR(7)) AS STATUS, CAST(A.TEMPORARY AS CHAR(1)) AS TEMPORARY, CAST(A.`GENERATED` AS CHAR(1)) AS "GENERATED", CAST(A.SECONDARY AS CHAR(1)) AS SECONDARY, CAST(A.NAMESPACE AS SIGNED) AS NAMESPACE, CAST(A.EDITION_NAME AS CHAR(128)) AS EDITION_NAME, CAST(NULL AS CHAR(18)) AS SHARING, CAST(NULL AS CHAR(1)) AS EDITIONABLE, CAST(NULL AS CHAR(1)) AS ORACLE_MAINTAINED, CAST(NULL AS CHAR(1)) AS APPLICATION, CAST(NULL AS CHAR(1)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS IMPORTED_OBJECT, CAST(NULL AS SIGNED) AS CREATED_APPID, CAST(NULL AS SIGNED) AS CREATED_VSNID, CAST(NULL AS SIGNED) AS MODIFIED_APPID, CAST(NULL AS SIGNED) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, USEC_TO_TIME(B.SCHEMA_VERSION) AS GMT_CREATE, USEC_TO_TIME(A.SCHEMA_VERSION) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS SIGNED) AS OBJECT_ID, A.TABLET_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE A JOIN OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID AND B.TABLE_NAME = '__all_core_table' UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + POSITION('_' IN SUBSTR(TABLE_NAME, 7))) ELSE TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5,15) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS CHAR(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.constraint_name AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CONSTRAINT CST, OCEANBASE.__ALL_VIRTUAL_TABLE TBL, OCEANBASE.__ALL_VIRTUAL_DATABASE DB WHERE CST.TENANT_ID = TBL.TENANT_ID AND TBL.TENANT_ID = DB.TENANT_ID AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX PARTITION' ELSE 'TABLE PARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) AND P.PARTITION_TYPE = 0 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX SUBPARTITION' ELSE 'TABLE SUBPARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) AND P.PARTITION_TYPE = 0 AND SUBP.PARTITION_TYPE = 0 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM OCEANBASE.__ALL_VIRTUAL_PACKAGE Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_PACKAGE P UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_ROUTINE R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TYPE UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_OBJECT_TYPE WHERE TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_VIRTUAL_ERROR E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TRIGGER T UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_SEQUENCE_OBJECT UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_SYNONYM UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS SIGNED) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TENANT_CONTEXT UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_DATABASE UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLEGROUP ) A JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1998,7 +1998,7 @@ int ObInnerTableSchema::cdb_tables_schema(ObTableSchema &table_schema) 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 CAST(DB.TENANT_ID AS SIGNED) AS CON_ID, CAST(DB.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(T.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(TP.TABLESPACE_NAME AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS CHAR(128)) AS CLUSTER_NAME, CAST(NULL AS CHAR(128)) AS IOT_NAME, CAST('VALID' AS CHAR(8)) AS STATUS, CAST(T.PCTFREE AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS PCT_USED, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENTS, CAST(NULL AS SIGNED) AS MAX_EXTENTS, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(3)) AS LOGGING, CAST(NULL AS CHAR(1)) AS BACKED_UP, CAST(INFO.ROW_COUNT AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS BLOCKS, CAST(NULL AS SIGNED) AS EMPTY_BLOCKS, CAST(NULL AS SIGNED) AS AVG_SPACE, CAST(NULL AS SIGNED) AS CHAIN_CNT, CAST(NULL AS SIGNED) AS AVG_ROW_LEN, CAST(NULL AS SIGNED) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS SIGNED) AS NUM_FREELIST_BLOCKS, CAST(NULL AS CHAR(10)) AS DEGREE, CAST(NULL AS CHAR(10)) AS INSTANCES, CAST(NULL AS CHAR(5)) AS CACHE, CAST(NULL AS CHAR(8)) AS TABLE_LOCK, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST( CASE WHEN T.PART_LEVEL = 0 THEN 'NO' ELSE 'YES' END AS CHAR(3)) AS PARTITIONED, CAST(NULL AS CHAR(12)) AS IOT_TYPE, CAST(CASE WHEN T.TABLE_TYPE IN (6, 8, 9) THEN 'Y' ELSE 'N' END AS CHAR(1)) AS TEMPORARY, CAST(NULL AS CHAR(1)) AS SECONDARY, CAST('NO' AS CHAR(3)) AS NESTED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(8)) AS ROW_MOVEMENT, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(CASE WHEN T.TABLE_TYPE IN (6, 8) THEN 'SYS$SESSION' WHEN T.TABLE_TYPE IN (9) THEN 'SYS$TRANSACTION' ELSE NULL END AS CHAR(15)) AS DURATION, CAST(NULL AS CHAR(8)) AS SKIP_CORRUPT, CAST(NULL AS CHAR(3)) AS MONITORING, CAST(NULL AS CHAR(128)) AS CLUSTER_OWNER, CAST(NULL AS CHAR(8)) AS DEPENDENCIES, CAST(NULL AS CHAR(8)) AS COMPRESSION, CAST(NULL AS CHAR(30)) AS COMPRESS_FOR, CAST(CASE WHEN DB.IN_RECYCLEBIN = 1 THEN 'YES' ELSE 'NO' END AS CHAR(3)) AS DROPPED, CAST(NULL AS CHAR(3)) AS READ_ONLY, CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(7)) AS RESULT_CACHE, CAST(NULL AS CHAR(3)) AS CLUSTERING, CAST(NULL AS CHAR(23)) AS ACTIVITY_TRACKING, CAST(NULL AS CHAR(25)) AS DML_TIMESTAMP, CAST(NULL AS CHAR(3)) AS HAS_IDENTITY, CAST(NULL AS CHAR(3)) AS CONTAINER_DATA, CAST(NULL AS CHAR(8)) AS INMEMORY, CAST(NULL AS CHAR(8)) AS INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) AS INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) AS INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) AS INMEMORY_DUPLICATE, CAST(NULL AS CHAR(100)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS EXTERNALLY_SHARDED, CAST(NULL AS CHAR(1)) AS EXTERNALLY_DUPLICATED, CAST(CASE WHEN T.TABLE_TYPE IN (14) THEN 'YES' ELSE 'NO' END AS CHAR(3)) AS EXTERNAL, CAST(NULL AS CHAR(3)) AS HYBRID, CAST(NULL AS CHAR(24)) AS CELLMEMORY, CAST(NULL AS CHAR(3)) AS CONTAINERS_DEFAULT, CAST(NULL AS CHAR(3)) AS CONTAINER_MAP, CAST(NULL AS CHAR(3)) AS EXTENDED_DATA_LINK, CAST(NULL AS CHAR(3)) AS EXTENDED_DATA_LINK_MAP, CAST(NULL AS CHAR(12)) AS INMEMORY_SERVICE, CAST(NULL AS CHAR(1000)) AS INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(3)) AS CONTAINER_MAP_OBJECT, CAST(NULL AS CHAR(8)) AS MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) AS MEMOPTIMIZE_WRITE, CAST(NULL AS CHAR(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS CHAR(3)) AS ADMIT_NULL, CAST(NULL AS CHAR(3)) AS DATA_LINK_DML_ENABLED, CAST(NULL AS CHAR(8)) AS LOGICAL_REPLICATION FROM (SELECT TENANT_ID, TABLE_ID, ROW_CNT AS ROW_COUNT FROM OCEANBASE.__ALL_VIRTUAL_TABLE_STAT TS WHERE PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID ) INFO RIGHT JOIN (SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, PCTFREE, PART_LEVEL, TABLE_TYPE, TABLESPACE_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE UNION ALL SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, PCTFREE, PART_LEVEL, TABLE_TYPE, TABLESPACE_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLE_MODE >> 12 & 15 in (0,1)) T ON T.TENANT_ID = INFO.TENANT_ID AND T.TABLE_ID = INFO.TABLE_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE DB ON DB.TENANT_ID = T.TENANT_ID AND DB.DATABASE_ID = T.DATABASE_ID AND T.TABLE_TYPE IN (0, 3, 6, 8, 9, 14, 15) AND DB.DATABASE_NAME != '__recyclebin' LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = T.TABLESPACE_ID AND T.TENANT_ID = TP.TENANT_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB.TENANT_ID AS SIGNED) AS CON_ID, CAST(DB.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(T.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(TP.TABLESPACE_NAME AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS CHAR(128)) AS CLUSTER_NAME, CAST(NULL AS CHAR(128)) AS IOT_NAME, CAST('VALID' AS CHAR(8)) AS STATUS, CAST(T.PCTFREE AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS PCT_USED, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENTS, CAST(NULL AS SIGNED) AS MAX_EXTENTS, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(3)) AS LOGGING, CAST(NULL AS CHAR(1)) AS BACKED_UP, CAST(INFO.ROW_COUNT AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS BLOCKS, CAST(NULL AS SIGNED) AS EMPTY_BLOCKS, CAST(NULL AS SIGNED) AS AVG_SPACE, CAST(NULL AS SIGNED) AS CHAIN_CNT, CAST(NULL AS SIGNED) AS AVG_ROW_LEN, CAST(NULL AS SIGNED) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS SIGNED) AS NUM_FREELIST_BLOCKS, CAST(NULL AS CHAR(10)) AS DEGREE, CAST(NULL AS CHAR(10)) AS INSTANCES, CAST(NULL AS CHAR(5)) AS CACHE, CAST(NULL AS CHAR(8)) AS TABLE_LOCK, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST( CASE WHEN T.PART_LEVEL = 0 THEN 'NO' ELSE 'YES' END AS CHAR(3)) AS PARTITIONED, CAST(NULL AS CHAR(12)) AS IOT_TYPE, CAST(CASE WHEN T.TABLE_TYPE IN (6, 8, 9) THEN 'Y' ELSE 'N' END AS CHAR(1)) AS TEMPORARY, CAST(NULL AS CHAR(1)) AS SECONDARY, CAST('NO' AS CHAR(3)) AS NESTED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(8)) AS ROW_MOVEMENT, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(CASE WHEN T.TABLE_TYPE IN (6, 8) THEN 'SYS$SESSION' WHEN T.TABLE_TYPE IN (9) THEN 'SYS$TRANSACTION' ELSE NULL END AS CHAR(15)) AS DURATION, CAST(NULL AS CHAR(8)) AS SKIP_CORRUPT, CAST(NULL AS CHAR(3)) AS MONITORING, CAST(NULL AS CHAR(128)) AS CLUSTER_OWNER, CAST(NULL AS CHAR(8)) AS DEPENDENCIES, CAST(NULL AS CHAR(8)) AS COMPRESSION, CAST(NULL AS CHAR(30)) AS COMPRESS_FOR, CAST(CASE WHEN DB.IN_RECYCLEBIN = 1 THEN 'YES' ELSE 'NO' END AS CHAR(3)) AS DROPPED, CAST(NULL AS CHAR(3)) AS READ_ONLY, CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(7)) AS RESULT_CACHE, CAST(NULL AS CHAR(3)) AS CLUSTERING, CAST(NULL AS CHAR(23)) AS ACTIVITY_TRACKING, CAST(NULL AS CHAR(25)) AS DML_TIMESTAMP, CAST(NULL AS CHAR(3)) AS HAS_IDENTITY, CAST(NULL AS CHAR(3)) AS CONTAINER_DATA, CAST(NULL AS CHAR(8)) AS INMEMORY, CAST(NULL AS CHAR(8)) AS INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) AS INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) AS INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) AS INMEMORY_DUPLICATE, CAST(NULL AS CHAR(100)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS EXTERNALLY_SHARDED, CAST(NULL AS CHAR(1)) AS EXTERNALLY_DUPLICATED, CAST(CASE WHEN T.TABLE_TYPE IN (14) THEN 'YES' ELSE 'NO' END AS CHAR(3)) AS EXTERNAL, CAST(NULL AS CHAR(3)) AS HYBRID, CAST(NULL AS CHAR(24)) AS CELLMEMORY, CAST(NULL AS CHAR(3)) AS CONTAINERS_DEFAULT, CAST(NULL AS CHAR(3)) AS CONTAINER_MAP, CAST(NULL AS CHAR(3)) AS EXTENDED_DATA_LINK, CAST(NULL AS CHAR(3)) AS EXTENDED_DATA_LINK_MAP, CAST(NULL AS CHAR(12)) AS INMEMORY_SERVICE, CAST(NULL AS CHAR(1000)) AS INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(3)) AS CONTAINER_MAP_OBJECT, CAST(NULL AS CHAR(8)) AS MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) AS MEMOPTIMIZE_WRITE, CAST(NULL AS CHAR(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS CHAR(3)) AS ADMIT_NULL, CAST(NULL AS CHAR(3)) AS DATA_LINK_DML_ENABLED, CAST(NULL AS CHAR(8)) AS LOGICAL_REPLICATION, CAST(CASE WHEN T.AUTO_PART = 1 THEN 'TRUE' ELSE 'FALSE' END AS CHAR(16)) AS AUTO_SPLIT, CAST(CASE WHEN T.AUTO_PART = 1 THEN T.AUTO_PART_SIZE ELSE 0 END AS SIGNED) AS AUTO_SPLIT_TABLET_SIZE FROM (SELECT TENANT_ID, TABLE_ID, ROW_CNT AS ROW_COUNT FROM OCEANBASE.__ALL_VIRTUAL_TABLE_STAT TS WHERE PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID ) INFO RIGHT JOIN (SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, PCTFREE, PART_LEVEL, TABLE_TYPE, TABLESPACE_ID, AUTO_PART, AUTO_PART_SIZE FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE UNION ALL SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, PCTFREE, PART_LEVEL, TABLE_TYPE, TABLESPACE_ID, AUTO_PART, AUTO_PART_SIZE FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLE_MODE >> 12 & 15 in (0,1)) T ON T.TENANT_ID = INFO.TENANT_ID AND T.TABLE_ID = INFO.TABLE_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE DB ON DB.TENANT_ID = T.TENANT_ID AND DB.DATABASE_ID = T.DATABASE_ID AND T.TABLE_TYPE IN (0, 3, 6, 8, 9, 14, 15) AND DB.DATABASE_NAME != '__recyclebin' LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = T.TABLESPACE_ID AND T.TENANT_ID = TP.TENANT_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -2304,7 +2304,7 @@ int ObInnerTableSchema::cdb_tab_partitions_schema(ObTableSchema &table_schema) 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 CAST(DB_TB.TENANT_ID AS SIGNED) CON_ID, CAST(DB_TB.DATABASE_NAME AS CHAR(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS CHAR(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS SIGNED) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS CHAR(30)) TABLESPACE_NAME, CAST(NULL AS SIGNED) PCT_FREE, CAST(NULL AS SIGNED) PCT_USED, CAST(NULL AS SIGNED) INI_TRANS, CAST(NULL AS SIGNED) MAX_TRANS, CAST(NULL AS SIGNED) INITIAL_EXTENT, CAST(NULL AS SIGNED) NEXT_EXTENT, CAST(NULL AS SIGNED) MIN_EXTENT, CAST(NULL AS SIGNED) MAX_EXTENT, CAST(NULL AS SIGNED) MAX_SIZE, CAST(NULL AS SIGNED) PCT_INCREASE, CAST(NULL AS SIGNED) FREELISTS, CAST(NULL AS SIGNED) FREELIST_GROUPS, CAST(NULL AS CHAR(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS CHAR(30)) COMPRESS_FOR, CAST(NULL AS SIGNED) NUM_ROWS, CAST(NULL AS SIGNED) BLOCKS, CAST(NULL AS SIGNED) EMPTY_BLOCKS, CAST(NULL AS SIGNED) AVG_SPACE, CAST(NULL AS SIGNED) CHAIN_CNT, CAST(NULL AS SIGNED) AVG_ROW_LEN, CAST(NULL AS SIGNED) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS CHAR(7)) BUFFER_POOL, CAST(NULL AS CHAR(7)) FLASH_CACHE, CAST(NULL AS CHAR(7)) CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) GLOBAL_STATS, CAST(NULL AS CHAR(3)) USER_STATS, CAST(NULL AS CHAR(3)) IS_NESTED, CAST(NULL AS CHAR(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS CHAR(3)) "INTERVAL", CAST(NULL AS CHAR(4)) SEGMENT_CREATED, CAST(NULL AS CHAR(4)) INDEXING, CAST(NULL AS CHAR(4)) READ_ONLY, CAST(NULL AS CHAR(8)) INMEMORY, CAST(NULL AS CHAR(8)) INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) INMEMORY_DUPLICATE, CAST(NULL AS CHAR(24)) CELLMEMORY, CAST(NULL AS CHAR(12)) INMEMORY_SERVICE, CAST(NULL AS CHAR(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM OCEANBASE.__ALL_VIRTUAL_TABLE TB, OCEANBASE.__ALL_VIRTUAL_DATABASE DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 6, 8, 9, 15) AND TB.TABLE_MODE >> 12 & 15 in (0,1) ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.TENANT_ID AS SIGNED) CON_ID, CAST(DB_TB.DATABASE_NAME AS CHAR(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS CHAR(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS SIGNED) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS CHAR(30)) TABLESPACE_NAME, CAST(NULL AS SIGNED) PCT_FREE, CAST(NULL AS SIGNED) PCT_USED, CAST(NULL AS SIGNED) INI_TRANS, CAST(NULL AS SIGNED) MAX_TRANS, CAST(NULL AS SIGNED) INITIAL_EXTENT, CAST(NULL AS SIGNED) NEXT_EXTENT, CAST(NULL AS SIGNED) MIN_EXTENT, CAST(NULL AS SIGNED) MAX_EXTENT, CAST(NULL AS SIGNED) MAX_SIZE, CAST(NULL AS SIGNED) PCT_INCREASE, CAST(NULL AS SIGNED) FREELISTS, CAST(NULL AS SIGNED) FREELIST_GROUPS, CAST(NULL AS CHAR(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS CHAR(30)) COMPRESS_FOR, CAST(NULL AS SIGNED) NUM_ROWS, CAST(NULL AS SIGNED) BLOCKS, CAST(NULL AS SIGNED) EMPTY_BLOCKS, CAST(NULL AS SIGNED) AVG_SPACE, CAST(NULL AS SIGNED) CHAIN_CNT, CAST(NULL AS SIGNED) AVG_ROW_LEN, CAST(NULL AS SIGNED) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS CHAR(7)) BUFFER_POOL, CAST(NULL AS CHAR(7)) FLASH_CACHE, CAST(NULL AS CHAR(7)) CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) GLOBAL_STATS, CAST(NULL AS CHAR(3)) USER_STATS, CAST(NULL AS CHAR(3)) IS_NESTED, CAST(NULL AS CHAR(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS CHAR(3)) "INTERVAL", CAST(NULL AS CHAR(4)) SEGMENT_CREATED, CAST(NULL AS CHAR(4)) INDEXING, CAST(NULL AS CHAR(4)) READ_ONLY, CAST(NULL AS CHAR(8)) INMEMORY, CAST(NULL AS CHAR(8)) INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) INMEMORY_DUPLICATE, CAST(NULL AS CHAR(24)) CELLMEMORY, CAST(NULL AS CHAR(12)) INMEMORY_SERVICE, CAST(NULL AS CHAR(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM OCEANBASE.__ALL_VIRTUAL_TABLE TB, OCEANBASE.__ALL_VIRTUAL_DATABASE DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 6, 8, 9, 15) AND TB.TABLE_MODE >> 12 & 15 in (0,1) ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -2355,7 +2355,7 @@ int ObInnerTableSchema::cdb_tab_subpartitions_schema(ObTableSchema &table_schema 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 CAST(DB_TB.TENANT_ID AS SIGNED) CON_ID, CAST(DB_TB.DATABASE_NAME AS CHAR(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS CHAR(128)) TABLE_NAME, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS CHAR(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS SIGNED) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS CHAR(30)) TABLESPACE_NAME, CAST(NULL AS SIGNED) PCT_FREE, CAST(NULL AS SIGNED) PCT_USED, CAST(NULL AS SIGNED) INI_TRANS, CAST(NULL AS SIGNED) MAX_TRANS, CAST(NULL AS SIGNED) INITIAL_EXTENT, CAST(NULL AS SIGNED) NEXT_EXTENT, CAST(NULL AS SIGNED) MIN_EXTENT, CAST(NULL AS SIGNED) MAX_EXTENT, CAST(NULL AS SIGNED) MAX_SIZE, CAST(NULL AS SIGNED) PCT_INCREASE, CAST(NULL AS SIGNED) FREELISTS, CAST(NULL AS SIGNED) FREELIST_GROUPS, CAST(NULL AS CHAR(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS CHAR(30)) COMPRESS_FOR, CAST(NULL AS SIGNED) NUM_ROWS, CAST(NULL AS SIGNED) BLOCKS, CAST(NULL AS SIGNED) EMPTY_BLOCKS, CAST(NULL AS SIGNED) AVG_SPACE, CAST(NULL AS SIGNED) CHAIN_CNT, CAST(NULL AS SIGNED) AVG_ROW_LEN, CAST(NULL AS SIGNED) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS CHAR(7)) BUFFER_POOL, CAST(NULL AS CHAR(7)) FLASH_CACHE, CAST(NULL AS CHAR(7)) CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) GLOBAL_STATS, CAST(NULL AS CHAR(3)) USER_STATS, CAST('NO' AS CHAR(3)) "INTERVAL", CAST(NULL AS CHAR(3)) SEGMENT_CREATED, CAST(NULL AS CHAR(3)) INDEXING, CAST(NULL AS CHAR(3)) READ_ONLY, CAST(NULL AS CHAR(8)) INMEMORY, CAST(NULL AS CHAR(8)) INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) INMEMORY_DUPLICATE, CAST(NULL AS CHAR(12)) INMEMORY_SERVICE, CAST(NULL AS CHAR(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(24)) CELLMEMORY, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE TB, OCEANBASE.__ALL_VIRTUAL_DATABASE DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 6, 8, 9, 15) AND TB.TABLE_MODE >> 12 & 15 in (0,1)) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.TENANT_ID AS SIGNED) CON_ID, CAST(DB_TB.DATABASE_NAME AS CHAR(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS CHAR(128)) TABLE_NAME, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS CHAR(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS SIGNED) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS CHAR(30)) TABLESPACE_NAME, CAST(NULL AS SIGNED) PCT_FREE, CAST(NULL AS SIGNED) PCT_USED, CAST(NULL AS SIGNED) INI_TRANS, CAST(NULL AS SIGNED) MAX_TRANS, CAST(NULL AS SIGNED) INITIAL_EXTENT, CAST(NULL AS SIGNED) NEXT_EXTENT, CAST(NULL AS SIGNED) MIN_EXTENT, CAST(NULL AS SIGNED) MAX_EXTENT, CAST(NULL AS SIGNED) MAX_SIZE, CAST(NULL AS SIGNED) PCT_INCREASE, CAST(NULL AS SIGNED) FREELISTS, CAST(NULL AS SIGNED) FREELIST_GROUPS, CAST(NULL AS CHAR(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS CHAR(30)) COMPRESS_FOR, CAST(NULL AS SIGNED) NUM_ROWS, CAST(NULL AS SIGNED) BLOCKS, CAST(NULL AS SIGNED) EMPTY_BLOCKS, CAST(NULL AS SIGNED) AVG_SPACE, CAST(NULL AS SIGNED) CHAIN_CNT, CAST(NULL AS SIGNED) AVG_ROW_LEN, CAST(NULL AS SIGNED) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS CHAR(7)) BUFFER_POOL, CAST(NULL AS CHAR(7)) FLASH_CACHE, CAST(NULL AS CHAR(7)) CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) GLOBAL_STATS, CAST(NULL AS CHAR(3)) USER_STATS, CAST('NO' AS CHAR(3)) "INTERVAL", CAST(NULL AS CHAR(3)) SEGMENT_CREATED, CAST(NULL AS CHAR(3)) INDEXING, CAST(NULL AS CHAR(3)) READ_ONLY, CAST(NULL AS CHAR(8)) INMEMORY, CAST(NULL AS CHAR(8)) INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) INMEMORY_DUPLICATE, CAST(NULL AS CHAR(12)) INMEMORY_SERVICE, CAST(NULL AS CHAR(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(24)) CELLMEMORY, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE TB, OCEANBASE.__ALL_VIRTUAL_DATABASE DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 6, 8, 9, 15) AND TB.TABLE_MODE >> 12 & 15 in (0,1)) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp b/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp index f7e972b3a..f1ee652d3 100644 --- a/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21201_21250.cpp @@ -111,7 +111,7 @@ int ObInnerTableSchema::cdb_ind_partitions_schema(ObTableSchema &table_schema) 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 CAST(D.TENANT_ID AS SIGNED) AS CON_ID, CAST(D.DATABASE_NAME AS CHAR(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(I.TABLE_NAME, 7))) END AS CHAR(128)) AS INDEX_NAME, CAST(DT.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS CHAR(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS SIGNED) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(NULL AS CHAR(8)) AS STATUS, CAST(NULL AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENT, CAST(NULL AS SIGNED) AS MAX_EXTENT, CAST(NULL AS SIGNED) AS MAX_SIZE, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(13)) AS COMPRESSION, CAST(NULL AS SIGNED) AS BLEVEL, CAST(NULL AS SIGNED) AS LEAF_BLOCKS, CAST(NULL AS SIGNED) AS DISTINCT_KEYS, CAST(NULL AS SIGNED) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS CLUSTERING_FACTOR, CAST(NULL AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(NULL AS SIGNED) AS PCT_DIRECT_ACCESS, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST(NULL AS CHAR(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS CHAR(1000)) AS PARAMETERS, CAST('NO' AS CHAR(3)) AS "INTERVAL", CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(3)) AS ORPHANED_ENTRIES FROM OCEANBASE.__ALL_VIRTUAL_TABLE I JOIN OCEANBASE.__ALL_VIRTUAL_TABLE DT ON I.TENANT_ID = DT.TENANT_ID AND I.DATA_TABLE_ID = DT.TABLE_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON I.TENANT_ID = D.TENANT_ID AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND I.TABLE_MODE >> 12 & 15 in (0,1) JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(D.TENANT_ID AS SIGNED) AS CON_ID, CAST(D.DATABASE_NAME AS CHAR(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(I.TABLE_NAME, 7))) END AS CHAR(128)) AS INDEX_NAME, CAST(DT.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS CHAR(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS SIGNED) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(NULL AS CHAR(8)) AS STATUS, CAST(NULL AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENT, CAST(NULL AS SIGNED) AS MAX_EXTENT, CAST(NULL AS SIGNED) AS MAX_SIZE, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(13)) AS COMPRESSION, CAST(NULL AS SIGNED) AS BLEVEL, CAST(NULL AS SIGNED) AS LEAF_BLOCKS, CAST(NULL AS SIGNED) AS DISTINCT_KEYS, CAST(NULL AS SIGNED) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS CLUSTERING_FACTOR, CAST(NULL AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(NULL AS SIGNED) AS PCT_DIRECT_ACCESS, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST(NULL AS CHAR(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS CHAR(1000)) AS PARAMETERS, CAST('NO' AS CHAR(3)) AS "INTERVAL", CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(3)) AS ORPHANED_ENTRIES FROM OCEANBASE.__ALL_VIRTUAL_TABLE I JOIN OCEANBASE.__ALL_VIRTUAL_TABLE DT ON I.TENANT_ID = DT.TENANT_ID AND I.DATA_TABLE_ID = DT.TABLE_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON I.TENANT_ID = D.TENANT_ID AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND I.TABLE_MODE >> 12 & 15 in (0,1) JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -162,7 +162,7 @@ int ObInnerTableSchema::cdb_ind_subpartitions_schema(ObTableSchema &table_schema 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 CAST(D.TENANT_ID AS NUMBER) AS CON_ID, CAST(D.DATABASE_NAME AS CHAR(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(I.TABLE_NAME, 7))) END AS CHAR(128)) AS INDEX_NAME, CAST(DT.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS CHAR(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS SIGNED) SUBPARTITION_POSITION, CAST(NULL AS CHAR(8)) AS STATUS, CAST(NULL AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENT, CAST(NULL AS SIGNED) AS MAX_EXTENT, CAST(NULL AS SIGNED) AS MAX_SIZE, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(13)) AS COMPRESSION, CAST(NULL AS SIGNED) AS BLEVEL, CAST(NULL AS SIGNED) AS LEAF_BLOCKS, CAST(NULL AS SIGNED) AS DISTINCT_KEYS, CAST(NULL AS SIGNED) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS CLUSTERING_FACTOR, CAST(NULL AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST('NO' AS CHAR(3)) AS "INTERVAL", CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS CHAR(1000)) AS PARAMETERS FROM OCEANBASE.__ALL_VIRTUAL_TABLE I JOIN OCEANBASE.__ALL_VIRTUAL_TABLE DT ON I.TENANT_ID = DT.TENANT_ID AND I.DATA_TABLE_ID = DT.TABLE_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON I.TENANT_ID = D.TENANT_ID AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND I.TABLE_MODE >> 12 & 15 in (0,1) JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(D.TENANT_ID AS NUMBER) AS CON_ID, CAST(D.DATABASE_NAME AS CHAR(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(I.TABLE_NAME, 7))) END AS CHAR(128)) AS INDEX_NAME, CAST(DT.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS CHAR(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS SIGNED) SUBPARTITION_POSITION, CAST(NULL AS CHAR(8)) AS STATUS, CAST(NULL AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENT, CAST(NULL AS SIGNED) AS MAX_EXTENT, CAST(NULL AS SIGNED) AS MAX_SIZE, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(13)) AS COMPRESSION, CAST(NULL AS SIGNED) AS BLEVEL, CAST(NULL AS SIGNED) AS LEAF_BLOCKS, CAST(NULL AS SIGNED) AS DISTINCT_KEYS, CAST(NULL AS SIGNED) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS CLUSTERING_FACTOR, CAST(NULL AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST('NO' AS CHAR(3)) AS "INTERVAL", CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS CHAR(1000)) AS PARAMETERS FROM OCEANBASE.__ALL_VIRTUAL_TABLE I JOIN OCEANBASE.__ALL_VIRTUAL_TABLE DT ON I.TENANT_ID = DT.TENANT_ID AND I.DATA_TABLE_ID = DT.TABLE_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON I.TENANT_ID = D.TENANT_ID AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND I.TABLE_MODE >> 12 & 15 in (0,1) JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_PART) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_VIRTUAL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -264,7 +264,7 @@ int ObInnerTableSchema::dba_objects_schema(ObTableSchema &table_schema) 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 CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS CHAR(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS SIGNED) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS SIGNED) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS CHAR(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATETIME) AS CREATED, CAST(A.GMT_MODIFIED AS DATETIME) AS LAST_DDL_TIME, CAST(A.GMT_CREATE AS DATETIME) AS TIMESTAMP, CAST(A.STATUS AS CHAR(7)) AS STATUS, CAST(A.TEMPORARY AS CHAR(1)) AS TEMPORARY, CAST(A.`GENERATED` AS CHAR(1)) AS "GENERATED", CAST(A.SECONDARY AS CHAR(1)) AS SECONDARY, CAST(A.NAMESPACE AS SIGNED) AS NAMESPACE, CAST(A.EDITION_NAME AS CHAR(128)) AS EDITION_NAME, CAST(NULL AS CHAR(18)) AS SHARING, CAST(NULL AS CHAR(1)) AS EDITIONABLE, CAST(NULL AS CHAR(1)) AS ORACLE_MAINTAINED, CAST(NULL AS CHAR(1)) AS APPLICATION, CAST(NULL AS CHAR(1)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS IMPORTED_OBJECT, CAST(NULL AS SIGNED) AS CREATED_APPID, CAST(NULL AS SIGNED) AS CREATED_VSNID, CAST(NULL AS SIGNED) AS MODIFIED_APPID, CAST(NULL AS SIGNED) AS MODIFIED_VSNID FROM ( SELECT CAST(0 AS SIGNED) AS TENANT_ID, USEC_TO_TIME(B.SCHEMA_VERSION) AS GMT_CREATE, USEC_TO_TIME(A.SCHEMA_VERSION) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS SIGNED) AS OBJECT_ID, A.TABLET_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE A JOIN OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID AND B.TABLE_NAME = '__all_core_table' WHERE A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + POSITION('_' IN SUBSTR(TABLE_NAME, 7))) ELSE TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,CAST(TABLE_ID AS SIGNED) AS OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5,15) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS CHAR(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE WHERE TENANT_ID = 0 AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.constraint_name AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(TBL.TABLE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_CONSTRAINT CST, OCEANBASE.__ALL_TABLE TBL, OCEANBASE.__ALL_DATABASE DB WHERE CST.TENANT_ID = 0 AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 and TBL.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX PARTITION' ELSE 'TABLE PARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX SUBPARTITION' ELSE 'TABLE SUBPARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(P.PACKAGE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM OCEANBASE.__ALL_PACKAGE Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_PACKAGE P WHERE P.TENANT_ID = 0 UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(R.ROUTINE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_ROUTINE R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = 0 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(TYPE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TYPE WHERE TENANT_ID = 0 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(OBJECT_TYPE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TENANT_OBJECT_TYPE WHERE TENANT_ID = 0 AND TYPE = 2 UNION ALL SELECT TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(T.TRIGGER_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TENANT_TRIGGER T WHERE T.TENANT_ID = 0 UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(DATABASE_ID AS SIGNED) AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_DATABASE WHERE TENANT_ID = 0 UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(TABLEGROUP_ID AS SIGNED) AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLEGROUP WHERE TENANT_ID = 0 ) A JOIN OCEANBASE.__ALL_DATABASE B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = 0 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS CHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS CHAR(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS SIGNED) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS SIGNED) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS CHAR(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATETIME) AS CREATED, CAST(A.GMT_MODIFIED AS DATETIME) AS LAST_DDL_TIME, CAST(A.GMT_CREATE AS DATETIME) AS TIMESTAMP, CAST(A.STATUS AS CHAR(7)) AS STATUS, CAST(A.TEMPORARY AS CHAR(1)) AS TEMPORARY, CAST(A.`GENERATED` AS CHAR(1)) AS "GENERATED", CAST(A.SECONDARY AS CHAR(1)) AS SECONDARY, CAST(A.NAMESPACE AS SIGNED) AS NAMESPACE, CAST(A.EDITION_NAME AS CHAR(128)) AS EDITION_NAME, CAST(NULL AS CHAR(18)) AS SHARING, CAST(NULL AS CHAR(1)) AS EDITIONABLE, CAST(NULL AS CHAR(1)) AS ORACLE_MAINTAINED, CAST(NULL AS CHAR(1)) AS APPLICATION, CAST(NULL AS CHAR(1)) AS DEFAULT_COLLATION, CAST(NULL AS CHAR(1)) AS DUPLICATED, CAST(NULL AS CHAR(1)) AS SHARDED, CAST(NULL AS CHAR(1)) AS IMPORTED_OBJECT, CAST(NULL AS SIGNED) AS CREATED_APPID, CAST(NULL AS SIGNED) AS CREATED_VSNID, CAST(NULL AS SIGNED) AS MODIFIED_APPID, CAST(NULL AS SIGNED) AS MODIFIED_VSNID FROM ( SELECT CAST(0 AS SIGNED) AS TENANT_ID, USEC_TO_TIME(B.SCHEMA_VERSION) AS GMT_CREATE, USEC_TO_TIME(A.SCHEMA_VERSION) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS SIGNED) AS OBJECT_ID, A.TABLET_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE A JOIN OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID AND B.TABLE_NAME = '__all_core_table' WHERE A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + POSITION('_' IN SUBSTR(TABLE_NAME, 7))) ELSE TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,CAST(TABLE_ID AS SIGNED) AS OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5,15) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS CHAR(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE WHERE TENANT_ID = 0 AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.constraint_name AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(TBL.TABLE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_CONSTRAINT CST, OCEANBASE.__ALL_TABLE TBL, OCEANBASE.__ALL_DATABASE DB WHERE CST.TENANT_ID = 0 AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 and TBL.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX PARTITION' ELSE 'TABLE PARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) AND P.PARTITION_TYPE = 0 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(T.TABLE_NAME, 7))) ELSE T.TABLE_NAME END) AS CHAR(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,(CASE WHEN T.TABLE_TYPE = 5 THEN 'INDEX SUBPARTITION' ELSE 'TABLE SUBPARTITION' END) AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(P.PACKAGE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM OCEANBASE.__ALL_PACKAGE Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_PACKAGE P WHERE P.TENANT_ID = 0 UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(R.ROUTINE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_ROUTINE R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = 0 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(TYPE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TYPE WHERE TENANT_ID = 0 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(OBJECT_TYPE_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TENANT_OBJECT_TYPE WHERE TENANT_ID = 0 AND TYPE = 2 UNION ALL SELECT TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CAST(T.TRIGGER_ID AS SIGNED) AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM OCEANBASE.__ALL_TENANT_ERROR E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TENANT_TRIGGER T WHERE T.TENANT_ID = 0 UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(DATABASE_ID AS SIGNED) AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_DATABASE WHERE TENANT_ID = 0 UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS SIGNED) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(TABLEGROUP_ID AS SIGNED) AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLEGROUP WHERE TENANT_ID = 0 ) A JOIN OCEANBASE.__ALL_DATABASE B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -468,7 +468,7 @@ int ObInnerTableSchema::dba_tab_partitions_schema(ObTableSchema &table_schema) 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 CAST(DB_TB.DATABASE_NAME AS CHAR(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS CHAR(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS SIGNED) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS CHAR(30)) TABLESPACE_NAME, CAST(NULL AS SIGNED) PCT_FREE, CAST(NULL AS SIGNED) PCT_USED, CAST(NULL AS SIGNED) INI_TRANS, CAST(NULL AS SIGNED) MAX_TRANS, CAST(NULL AS SIGNED) INITIAL_EXTENT, CAST(NULL AS SIGNED) NEXT_EXTENT, CAST(NULL AS SIGNED) MIN_EXTENT, CAST(NULL AS SIGNED) MAX_EXTENT, CAST(NULL AS SIGNED) MAX_SIZE, CAST(NULL AS SIGNED) PCT_INCREASE, CAST(NULL AS SIGNED) FREELISTS, CAST(NULL AS SIGNED) FREELIST_GROUPS, CAST(NULL AS CHAR(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS CHAR(30)) COMPRESS_FOR, CAST(NULL AS SIGNED) NUM_ROWS, CAST(NULL AS SIGNED) BLOCKS, CAST(NULL AS SIGNED) EMPTY_BLOCKS, CAST(NULL AS SIGNED) AVG_SPACE, CAST(NULL AS SIGNED) CHAIN_CNT, CAST(NULL AS SIGNED) AVG_ROW_LEN, CAST(NULL AS SIGNED) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS CHAR(7)) BUFFER_POOL, CAST(NULL AS CHAR(7)) FLASH_CACHE, CAST(NULL AS CHAR(7)) CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) GLOBAL_STATS, CAST(NULL AS CHAR(3)) USER_STATS, CAST(NULL AS CHAR(3)) IS_NESTED, CAST(NULL AS CHAR(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS CHAR(3)) "INTERVAL", CAST(NULL AS CHAR(4)) SEGMENT_CREATED, CAST(NULL AS CHAR(4)) INDEXING, CAST(NULL AS CHAR(4)) READ_ONLY, CAST(NULL AS CHAR(8)) INMEMORY, CAST(NULL AS CHAR(8)) INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) INMEMORY_DUPLICATE, CAST(NULL AS CHAR(24)) CELLMEMORY, CAST(NULL AS CHAR(12)) INMEMORY_SERVICE, CAST(NULL AS CHAR(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM OCEANBASE.__ALL_TABLE TB, OCEANBASE.__ALL_DATABASE DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE in (3, 6) AND TB.TABLE_MODE >> 12 & 15 in (0,1) ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM OCEANBASE.__ALL_PART) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = 0 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.DATABASE_NAME AS CHAR(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS CHAR(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS SIGNED) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS CHAR(30)) TABLESPACE_NAME, CAST(NULL AS SIGNED) PCT_FREE, CAST(NULL AS SIGNED) PCT_USED, CAST(NULL AS SIGNED) INI_TRANS, CAST(NULL AS SIGNED) MAX_TRANS, CAST(NULL AS SIGNED) INITIAL_EXTENT, CAST(NULL AS SIGNED) NEXT_EXTENT, CAST(NULL AS SIGNED) MIN_EXTENT, CAST(NULL AS SIGNED) MAX_EXTENT, CAST(NULL AS SIGNED) MAX_SIZE, CAST(NULL AS SIGNED) PCT_INCREASE, CAST(NULL AS SIGNED) FREELISTS, CAST(NULL AS SIGNED) FREELIST_GROUPS, CAST(NULL AS CHAR(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS CHAR(30)) COMPRESS_FOR, CAST(NULL AS SIGNED) NUM_ROWS, CAST(NULL AS SIGNED) BLOCKS, CAST(NULL AS SIGNED) EMPTY_BLOCKS, CAST(NULL AS SIGNED) AVG_SPACE, CAST(NULL AS SIGNED) CHAIN_CNT, CAST(NULL AS SIGNED) AVG_ROW_LEN, CAST(NULL AS SIGNED) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS CHAR(7)) BUFFER_POOL, CAST(NULL AS CHAR(7)) FLASH_CACHE, CAST(NULL AS CHAR(7)) CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) GLOBAL_STATS, CAST(NULL AS CHAR(3)) USER_STATS, CAST(NULL AS CHAR(3)) IS_NESTED, CAST(NULL AS CHAR(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS CHAR(3)) "INTERVAL", CAST(NULL AS CHAR(4)) SEGMENT_CREATED, CAST(NULL AS CHAR(4)) INDEXING, CAST(NULL AS CHAR(4)) READ_ONLY, CAST(NULL AS CHAR(8)) INMEMORY, CAST(NULL AS CHAR(8)) INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) INMEMORY_DUPLICATE, CAST(NULL AS CHAR(24)) CELLMEMORY, CAST(NULL AS CHAR(12)) INMEMORY_SERVICE, CAST(NULL AS CHAR(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM OCEANBASE.__ALL_TABLE TB, OCEANBASE.__ALL_DATABASE DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE in (3, 6) AND TB.TABLE_MODE >> 12 & 15 in (0,1) ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM OCEANBASE.__ALL_PART) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = 0 AND PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -519,7 +519,7 @@ int ObInnerTableSchema::dba_tab_subpartitions_schema(ObTableSchema &table_schema 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 CAST(DB_TB.DATABASE_NAME AS CHAR(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS CHAR(128)) TABLE_NAME, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS CHAR(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS SIGNED) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS CHAR(30)) TABLESPACE_NAME, CAST(NULL AS SIGNED) PCT_FREE, CAST(NULL AS SIGNED) PCT_USED, CAST(NULL AS SIGNED) INI_TRANS, CAST(NULL AS SIGNED) MAX_TRANS, CAST(NULL AS SIGNED) INITIAL_EXTENT, CAST(NULL AS SIGNED) NEXT_EXTENT, CAST(NULL AS SIGNED) MIN_EXTENT, CAST(NULL AS SIGNED) MAX_EXTENT, CAST(NULL AS SIGNED) MAX_SIZE, CAST(NULL AS SIGNED) PCT_INCREASE, CAST(NULL AS SIGNED) FREELISTS, CAST(NULL AS SIGNED) FREELIST_GROUPS, CAST(NULL AS CHAR(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS CHAR(30)) COMPRESS_FOR, CAST(NULL AS SIGNED) NUM_ROWS, CAST(NULL AS SIGNED) BLOCKS, CAST(NULL AS SIGNED) EMPTY_BLOCKS, CAST(NULL AS SIGNED) AVG_SPACE, CAST(NULL AS SIGNED) CHAIN_CNT, CAST(NULL AS SIGNED) AVG_ROW_LEN, CAST(NULL AS SIGNED) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS CHAR(7)) BUFFER_POOL, CAST(NULL AS CHAR(7)) FLASH_CACHE, CAST(NULL AS CHAR(7)) CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) GLOBAL_STATS, CAST(NULL AS CHAR(3)) USER_STATS, CAST('NO' AS CHAR(3)) "INTERVAL", CAST(NULL AS CHAR(3)) SEGMENT_CREATED, CAST(NULL AS CHAR(3)) INDEXING, CAST(NULL AS CHAR(3)) READ_ONLY, CAST(NULL AS CHAR(8)) INMEMORY, CAST(NULL AS CHAR(8)) INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) INMEMORY_DUPLICATE, CAST(NULL AS CHAR(12)) INMEMORY_SERVICE, CAST(NULL AS CHAR(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(24)) CELLMEMORY, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM OCEANBASE.__ALL_TABLE TB, OCEANBASE.__ALL_DATABASE DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TABLE_MODE >> 12 & 15 in (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 6)) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_PART) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = 0 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.DATABASE_NAME AS CHAR(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS CHAR(128)) TABLE_NAME, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS CHAR(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS SIGNED) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS CHAR(30)) TABLESPACE_NAME, CAST(NULL AS SIGNED) PCT_FREE, CAST(NULL AS SIGNED) PCT_USED, CAST(NULL AS SIGNED) INI_TRANS, CAST(NULL AS SIGNED) MAX_TRANS, CAST(NULL AS SIGNED) INITIAL_EXTENT, CAST(NULL AS SIGNED) NEXT_EXTENT, CAST(NULL AS SIGNED) MIN_EXTENT, CAST(NULL AS SIGNED) MAX_EXTENT, CAST(NULL AS SIGNED) MAX_SIZE, CAST(NULL AS SIGNED) PCT_INCREASE, CAST(NULL AS SIGNED) FREELISTS, CAST(NULL AS SIGNED) FREELIST_GROUPS, CAST(NULL AS CHAR(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS CHAR(30)) COMPRESS_FOR, CAST(NULL AS SIGNED) NUM_ROWS, CAST(NULL AS SIGNED) BLOCKS, CAST(NULL AS SIGNED) EMPTY_BLOCKS, CAST(NULL AS SIGNED) AVG_SPACE, CAST(NULL AS SIGNED) CHAIN_CNT, CAST(NULL AS SIGNED) AVG_ROW_LEN, CAST(NULL AS SIGNED) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS CHAR(7)) BUFFER_POOL, CAST(NULL AS CHAR(7)) FLASH_CACHE, CAST(NULL AS CHAR(7)) CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) GLOBAL_STATS, CAST(NULL AS CHAR(3)) USER_STATS, CAST('NO' AS CHAR(3)) "INTERVAL", CAST(NULL AS CHAR(3)) SEGMENT_CREATED, CAST(NULL AS CHAR(3)) INDEXING, CAST(NULL AS CHAR(3)) READ_ONLY, CAST(NULL AS CHAR(8)) INMEMORY, CAST(NULL AS CHAR(8)) INMEMORY_PRIORITY, CAST(NULL AS CHAR(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS CHAR(17)) INMEMORY_COMPRESSION, CAST(NULL AS CHAR(13)) INMEMORY_DUPLICATE, CAST(NULL AS CHAR(12)) INMEMORY_SERVICE, CAST(NULL AS CHAR(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS CHAR(24)) CELLMEMORY, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_READ, CAST(NULL AS CHAR(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM OCEANBASE.__ALL_TABLE TB, OCEANBASE.__ALL_DATABASE DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TABLE_MODE >> 12 & 15 in (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 6)) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_PART) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -672,7 +672,7 @@ int ObInnerTableSchema::dba_ind_partitions_schema(ObTableSchema &table_schema) 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 CAST(D.DATABASE_NAME AS CHAR(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(I.TABLE_NAME, 7))) END AS CHAR(128)) AS INDEX_NAME, CAST(DT.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS CHAR(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS SIGNED) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(NULL AS CHAR(8)) AS STATUS, CAST(NULL AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENT, CAST(NULL AS SIGNED) AS MAX_EXTENT, CAST(NULL AS SIGNED) AS MAX_SIZE, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(13)) AS COMPRESSION, CAST(NULL AS SIGNED) AS BLEVEL, CAST(NULL AS SIGNED) AS LEAF_BLOCKS, CAST(NULL AS SIGNED) AS DISTINCT_KEYS, CAST(NULL AS SIGNED) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS CLUSTERING_FACTOR, CAST(NULL AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(NULL AS SIGNED) AS PCT_DIRECT_ACCESS, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST(NULL AS CHAR(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS CHAR(1000)) AS PARAMETERS, CAST('NO' AS CHAR(3)) AS "INTERVAL", CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(3)) AS ORPHANED_ENTRIES FROM OCEANBASE.__ALL_TABLE I JOIN OCEANBASE.__ALL_TABLE DT ON I.TENANT_ID = DT.TENANT_ID AND I.DATA_TABLE_ID = DT.TABLE_ID JOIN OCEANBASE.__ALL_DATABASE D ON I.TENANT_ID = D.TENANT_ID AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM OCEANBASE.__ALL_PART) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = 0 AND I.TABLE_MODE >> 12 & 15 in (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(D.DATABASE_NAME AS CHAR(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(I.TABLE_NAME, 7))) END AS CHAR(128)) AS INDEX_NAME, CAST(DT.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS CHAR(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS SIGNED) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(NULL AS CHAR(8)) AS STATUS, CAST(NULL AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENT, CAST(NULL AS SIGNED) AS MAX_EXTENT, CAST(NULL AS SIGNED) AS MAX_SIZE, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(13)) AS COMPRESSION, CAST(NULL AS SIGNED) AS BLEVEL, CAST(NULL AS SIGNED) AS LEAF_BLOCKS, CAST(NULL AS SIGNED) AS DISTINCT_KEYS, CAST(NULL AS SIGNED) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS CLUSTERING_FACTOR, CAST(NULL AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(NULL AS SIGNED) AS PCT_DIRECT_ACCESS, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST(NULL AS CHAR(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS CHAR(1000)) AS PARAMETERS, CAST('NO' AS CHAR(3)) AS "INTERVAL", CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(3)) AS ORPHANED_ENTRIES FROM OCEANBASE.__ALL_TABLE I JOIN OCEANBASE.__ALL_TABLE DT ON I.TENANT_ID = DT.TENANT_ID AND I.DATA_TABLE_ID = DT.TABLE_ID JOIN OCEANBASE.__ALL_DATABASE D ON I.TENANT_ID = D.TENANT_ID AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM OCEANBASE.__ALL_PART) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = 0 AND I.TABLE_MODE >> 12 & 15 in (0,1) AND PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -723,7 +723,7 @@ int ObInnerTableSchema::dba_ind_subpartitions_schema(ObTableSchema &table_schema 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 CAST(D.DATABASE_NAME AS CHAR(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(I.TABLE_NAME, 7))) END AS CHAR(128)) AS INDEX_NAME, CAST(DT.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS CHAR(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS SIGNED) SUBPARTITION_POSITION, CAST(NULL AS CHAR(8)) AS STATUS, CAST(NULL AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENT, CAST(NULL AS SIGNED) AS MAX_EXTENT, CAST(NULL AS SIGNED) AS MAX_SIZE, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(13)) AS COMPRESSION, CAST(NULL AS SIGNED) AS BLEVEL, CAST(NULL AS SIGNED) AS LEAF_BLOCKS, CAST(NULL AS SIGNED) AS DISTINCT_KEYS, CAST(NULL AS SIGNED) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS CLUSTERING_FACTOR, CAST(NULL AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST('NO' AS CHAR(3)) AS "INTERVAL", CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS CHAR(1000)) AS PARAMETERS FROM OCEANBASE.__ALL_TABLE I JOIN OCEANBASE.__ALL_TABLE DT ON I.TENANT_ID = DT.TENANT_ID AND I.DATA_TABLE_ID = DT.TABLE_ID JOIN OCEANBASE.__ALL_DATABASE D ON I.TENANT_ID = D.TENANT_ID AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_PART) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = 0 AND I.TABLE_MODE >> 12 & 15 in (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(D.DATABASE_NAME AS CHAR(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + POSITION('_' IN SUBSTR(I.TABLE_NAME, 7))) END AS CHAR(128)) AS INDEX_NAME, CAST(DT.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(PART.PART_NAME AS CHAR(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS CHAR(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS CHAR(262144)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS SIGNED) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS SIGNED) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS SIGNED) SUBPARTITION_POSITION, CAST(NULL AS CHAR(8)) AS STATUS, CAST(NULL AS CHAR(30)) AS TABLESPACE_NAME, CAST(NULL AS SIGNED) AS PCT_FREE, CAST(NULL AS SIGNED) AS INI_TRANS, CAST(NULL AS SIGNED) AS MAX_TRANS, CAST(NULL AS SIGNED) AS INITIAL_EXTENT, CAST(NULL AS SIGNED) AS NEXT_EXTENT, CAST(NULL AS SIGNED) AS MIN_EXTENT, CAST(NULL AS SIGNED) AS MAX_EXTENT, CAST(NULL AS SIGNED) AS MAX_SIZE, CAST(NULL AS SIGNED) AS PCT_INCREASE, CAST(NULL AS SIGNED) AS FREELISTS, CAST(NULL AS SIGNED) AS FREELIST_GROUPS, CAST(NULL AS CHAR(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS CHAR(13)) AS COMPRESSION, CAST(NULL AS SIGNED) AS BLEVEL, CAST(NULL AS SIGNED) AS LEAF_BLOCKS, CAST(NULL AS SIGNED) AS DISTINCT_KEYS, CAST(NULL AS SIGNED) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS SIGNED) AS CLUSTERING_FACTOR, CAST(NULL AS SIGNED) AS NUM_ROWS, CAST(NULL AS SIGNED) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS CHAR(7)) AS BUFFER_POOL, CAST(NULL AS CHAR(7)) AS FLASH_CACHE, CAST(NULL AS CHAR(7)) AS CELL_FLASH_CACHE, CAST(NULL AS CHAR(3)) AS USER_STATS, CAST(NULL AS CHAR(3)) AS GLOBAL_STATS, CAST('NO' AS CHAR(3)) AS "INTERVAL", CAST(NULL AS CHAR(3)) AS SEGMENT_CREATED, CAST(NULL AS CHAR(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS CHAR(1000)) AS PARAMETERS FROM OCEANBASE.__ALL_TABLE I JOIN OCEANBASE.__ALL_TABLE DT ON I.TENANT_ID = DT.TENANT_ID AND I.DATA_TABLE_ID = DT.TABLE_ID JOIN OCEANBASE.__ALL_DATABASE D ON I.TENANT_ID = D.TENANT_ID AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM OCEANBASE.__ALL_PART) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM OCEANBASE.__ALL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = 0 AND I.TABLE_MODE >> 12 & 15 in (0,1) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21251_21300.cpp b/src/share/inner_table/ob_inner_table_schema.21251_21300.cpp index 7e385d6ec..073a97d73 100644 --- a/src/share/inner_table/ob_inner_table_schema.21251_21300.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21251_21300.cpp @@ -111,7 +111,7 @@ int ObInnerTableSchema::dba_tab_statistics_schema(ObTableSchema &table_schema) 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 CAST(DB.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(V.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS CHAR(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS CHAR(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS CHAR(12)) AS OBJECT_TYPE, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(STAT.AVG_ROW_LEN AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS IM_IMCU_COUNT, CAST(NULL AS NUMBER) AS IM_BLOCK_COUNT, CAST(NULL AS DATETIME) AS IM_STAT_UPDATE_TIME, CAST(NULL AS NUMBER) AS SCAN_RATE, CAST(STAT.SPARE1 AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATETIME(6)) AS LAST_ANALYZED, CAST((CASE STAT.GLOBAL_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS GLOBAL_STATS, CAST((CASE STAT.USER_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS USER_STATS, CAST((CASE WHEN STAT.STATTYPE_LOCKED & 15 IS NULL THEN NULL ELSE (CASE STAT.STATTYPE_LOCKED & 15 WHEN 0 THEN NULL WHEN 1 THEN 'DATA' WHEN 2 THEN 'CACHE' ELSE 'ALL' END) END) AS CHAR(5)) AS STATTYPE_LOCKED, CAST((CASE STAT.STALE_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS STALE_STATS, CAST(NULL AS CHAR(7)) AS SCOPE FROM ( (SELECT CAST(0 AS SIGNED) AS TENANT_ID, DATABASE_ID, TABLE_ID, -2 AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE IN (0,2,3,6,14,15) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN -2 ELSE -1 END AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM oceanbase.__all_table T WHERE T.TABLE_TYPE IN (0,2,3,6,14,15) AND T.TABLE_MODE >> 12 & 15 in (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, P.PART_ID, T.TABLE_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM oceanbase.__all_table T JOIN oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,6,14,15) AND T.TABLE_MODE >> 12 & 15 in (0,1) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, T.TABLE_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM oceanbase.__all_table T JOIN oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID JOIN oceanbase.__all_sub_part SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,6,14,15) AND T.TABLE_MODE >> 12 & 15 in (0,1) ) V JOIN oceanbase.__all_database DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID AND V.TENANT_ID = 0 LEFT JOIN oceanbase.__all_table_stat STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND (V.PARTITION_ID = STAT.PARTITION_ID OR V.PARTITION_ID = -2) AND STAT.INDEX_TYPE = 0 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST(DB.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(V.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS CHAR(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS CHAR(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS CHAR(12)) AS OBJECT_TYPE, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(STAT.AVG_ROW_LEN AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS IM_IMCU_COUNT, CAST(NULL AS NUMBER) AS IM_BLOCK_COUNT, CAST(NULL AS DATETIME) AS IM_STAT_UPDATE_TIME, CAST(NULL AS NUMBER) AS SCAN_RATE, CAST(STAT.SPARE1 AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATETIME(6)) AS LAST_ANALYZED, CAST((CASE STAT.GLOBAL_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS GLOBAL_STATS, CAST((CASE STAT.USER_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS USER_STATS, CAST((CASE WHEN STAT.STATTYPE_LOCKED & 15 IS NULL THEN NULL ELSE (CASE STAT.STATTYPE_LOCKED & 15 WHEN 0 THEN NULL WHEN 1 THEN 'DATA' WHEN 2 THEN 'CACHE' ELSE 'ALL' END) END) AS CHAR(5)) AS STATTYPE_LOCKED, CAST((CASE STAT.STALE_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS STALE_STATS, CAST(NULL AS CHAR(7)) AS SCOPE FROM ( (SELECT CAST(0 AS SIGNED) AS TENANT_ID, DATABASE_ID, TABLE_ID, -2 AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE IN (0,2,3,6,14,15) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN -2 ELSE -1 END AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM oceanbase.__all_table T WHERE T.TABLE_TYPE IN (0,2,3,6,14,15) AND T.TABLE_MODE >> 12 & 15 in (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, P.PART_ID, T.TABLE_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM oceanbase.__all_table T JOIN oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,6,14,15) AND T.TABLE_MODE >> 12 & 15 in (0,1) AND (P.PARTITION_TYPE = 0 OR P.PARTITION_TYPE IS NULL) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, T.TABLE_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM oceanbase.__all_table T JOIN oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID JOIN oceanbase.__all_sub_part SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,6,14,15) AND T.TABLE_MODE >> 12 & 15 in (0,1) AND (P.PARTITION_TYPE = 0 OR P.PARTITION_TYPE IS NULL) AND (SP.PARTITION_TYPE = 0 OR SP.PARTITION_TYPE IS NULL) ) V JOIN oceanbase.__all_database DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID AND V.TENANT_ID = 0 LEFT JOIN oceanbase.__all_table_stat STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND (V.PARTITION_ID = STAT.PARTITION_ID OR V.PARTITION_ID = -2) AND STAT.INDEX_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -213,7 +213,7 @@ int ObInnerTableSchema::dba_part_col_statistics_schema(ObTableSchema &table_sche 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 cast(db.database_name as CHAR(128)) as OWNER, cast(t.table_name as CHAR(128)) as TABLE_NAME, cast (part.part_name as CHAR(128)) as PARTITION_NAME, cast(c.column_name as CHAR(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as CHAR(128)) as LOW_VALUE, cast(stat.max_value as CHAR(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.last_analyzed as DATETIME(6)) as LAST_ANALYZED, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, CAST((CASE stat.GLOBAL_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS GLOBAL_STATS, CAST((CASE stat.USER_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS USER_STATS, cast(NULL as CHAR(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as CHAR(15)) as HISTOGRAM FROM oceanbase.__all_table t JOIN oceanbase.__all_database db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id and t.tenant_id = 0 JOIN oceanbase.__all_column c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id JOIN oceanbase.__all_part part on t.tenant_id = part.tenant_id and t.table_id = part.table_id left join oceanbase.__all_column_stat stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND part.part_id = stat.partition_id AND stat.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT cast(db.database_name as CHAR(128)) as OWNER, cast(t.table_name as CHAR(128)) as TABLE_NAME, cast (part.part_name as CHAR(128)) as PARTITION_NAME, cast(c.column_name as CHAR(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as CHAR(128)) as LOW_VALUE, cast(stat.max_value as CHAR(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.last_analyzed as DATETIME(6)) as LAST_ANALYZED, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, CAST((CASE stat.GLOBAL_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS GLOBAL_STATS, CAST((CASE stat.USER_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS USER_STATS, cast(NULL as CHAR(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as CHAR(15)) as HISTOGRAM FROM oceanbase.__all_table t JOIN oceanbase.__all_database db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id and t.tenant_id = 0 JOIN oceanbase.__all_column c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id JOIN oceanbase.__all_part part on t.tenant_id = part.tenant_id and t.table_id = part.table_id left join oceanbase.__all_column_stat stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND part.part_id = stat.partition_id AND stat.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) AND part.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -264,7 +264,7 @@ int ObInnerTableSchema::dba_subpart_col_statistics_schema(ObTableSchema &table_s 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 cast(db.database_name as CHAR(128)) as OWNER, cast(t.table_name as CHAR(128)) as TABLE_NAME, cast (subpart.sub_part_name as CHAR(128)) as SUBPARTITION_NAME, cast(c.column_name as CHAR(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as CHAR(128)) as LOW_VALUE, cast(stat.max_value as CHAR(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.last_analyzed as DATETIME(6)) as LAST_ANALYZED, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, CAST((CASE stat.GLOBAL_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS GLOBAL_STATS, CAST((CASE stat.USER_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS USER_STATS, cast(NULL as CHAR(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as CHAR(15)) as HISTOGRAM FROM oceanbase.__all_table t JOIN oceanbase.__all_database db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id and t.tenant_id = 0 JOIN oceanbase.__all_column c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id JOIN oceanbase.__all_sub_part subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id left join oceanbase.__all_column_stat stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND stat.partition_id = subpart.sub_part_id AND stat.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT cast(db.database_name as CHAR(128)) as OWNER, cast(t.table_name as CHAR(128)) as TABLE_NAME, cast (subpart.sub_part_name as CHAR(128)) as SUBPARTITION_NAME, cast(c.column_name as CHAR(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as CHAR(128)) as LOW_VALUE, cast(stat.max_value as CHAR(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.last_analyzed as DATETIME(6)) as LAST_ANALYZED, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, CAST((CASE stat.GLOBAL_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS GLOBAL_STATS, CAST((CASE stat.USER_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS USER_STATS, cast(NULL as CHAR(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as CHAR(15)) as HISTOGRAM FROM oceanbase.__all_table t JOIN oceanbase.__all_database db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id and t.tenant_id = 0 JOIN oceanbase.__all_column c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id JOIN oceanbase.__all_sub_part subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id left join oceanbase.__all_column_stat stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND stat.partition_id = subpart.sub_part_id AND stat.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) AND subpart.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -366,7 +366,7 @@ int ObInnerTableSchema::dba_part_histograms_schema(ObTableSchema &table_schema) 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 cast(db.database_name as CHAR(128)) as OWNER, cast(t.table_name as CHAR(128)) as TABLE_NAME, cast(part.part_name as CHAR(128)) as PARTITION_NAME, cast(c.column_name as CHAR(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as CHAR(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.b_endpoint_value as CHAR(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM oceanbase.__all_table t JOIN oceanbase.__all_database db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id and t.tenant_id = 0 JOIN oceanbase.__all_column c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id JOIN oceanbase.__all_part part on t.tenant_id = part.tenant_id and t.table_id = part.table_id JOIN oceanbase.__all_histogram_stat hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND part.part_id = hist.partition_id AND hist.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as CHAR(128)) as OWNER, cast(t.table_name as CHAR(128)) as TABLE_NAME, cast(part.part_name as CHAR(128)) as PARTITION_NAME, cast(c.column_name as CHAR(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as CHAR(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.b_endpoint_value as CHAR(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM oceanbase.__all_table t JOIN oceanbase.__all_database db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id and t.tenant_id = 0 JOIN oceanbase.__all_column c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id JOIN oceanbase.__all_part part on t.tenant_id = part.tenant_id and t.table_id = part.table_id JOIN oceanbase.__all_histogram_stat hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND part.part_id = hist.partition_id AND hist.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) AND part.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -417,7 +417,7 @@ int ObInnerTableSchema::dba_subpart_histograms_schema(ObTableSchema &table_schem 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 cast(db.database_name as CHAR(128)) as OWNER, cast(t.table_name as CHAR(128)) as TABLE_NAME, cast(subpart.sub_part_name as CHAR(128)) as SUBPARTITION_NAME, cast(c.column_name as CHAR(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as CHAR(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.b_endpoint_value as CHAR(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM oceanbase.__all_table t JOIN oceanbase.__all_database db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id and t.tenant_id = 0 JOIN oceanbase.__all_column c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id JOIN oceanbase.__all_sub_part subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id JOIN oceanbase.__all_histogram_stat hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND hist.partition_id = subpart.sub_part_id AND hist.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as CHAR(128)) as OWNER, cast(t.table_name as CHAR(128)) as TABLE_NAME, cast(subpart.sub_part_name as CHAR(128)) as SUBPARTITION_NAME, cast(c.column_name as CHAR(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as CHAR(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.b_endpoint_value as CHAR(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM oceanbase.__all_table t JOIN oceanbase.__all_database db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id and t.tenant_id = 0 JOIN oceanbase.__all_column c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id JOIN oceanbase.__all_sub_part subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id JOIN oceanbase.__all_histogram_stat hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND hist.partition_id = subpart.sub_part_id AND hist.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) AND subpart.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -519,7 +519,7 @@ int ObInnerTableSchema::dba_ind_statistics_schema(ObTableSchema &table_schema) 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 CAST(DB.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(V.INDEX_NAME AS CHAR(128)) AS INDEX_NAME, CAST(DB.DATABASE_NAME AS CHAR(128)) AS TABLE_OWNER, CAST(T.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS CHAR(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS CHAR(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS CHAR(12)) AS OBJECT_TYPE, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATETIME(6)) AS LAST_ANALYZED, CAST((CASE STAT.GLOBAL_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS GLOBAL_STATS, CAST((CASE STAT.USER_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS USER_STATS, CAST((CASE WHEN STAT.STATTYPE_LOCKED & 15 IS NULL THEN NULL ELSE (CASE STAT.STATTYPE_LOCKED & 15 WHEN 0 THEN NULL WHEN 1 THEN 'DATA' WHEN 2 THEN 'CACHE' ELSE 'ALL' END) END) AS CHAR(5)) AS STATTYPE_LOCKED, CAST((CASE STAT.STALE_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS STALE_STATS, CAST(NULL AS CHAR(7)) AS SCOPE FROM ( (SELECT CAST(0 AS SIGNED) AS TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, -2 AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN -2 ELSE -1 END AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM oceanbase.__all_table T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.TABLE_MODE >> 12 & 15 in (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, P.PART_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM oceanbase.__all_table T JOIN oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM oceanbase.__all_table T JOIN oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID JOIN oceanbase.__all_sub_part SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN oceanbase.__all_table T ON T.TABLE_ID = V.DATA_TABLE_ID AND T.TENANT_ID = V.TENANT_ID AND T.DATABASE_ID = V.DATABASE_ID JOIN oceanbase.__all_database DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID AND V.TENANT_ID = 0 LEFT JOIN oceanbase.__all_table_stat STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND (V.PARTITION_ID = STAT.PARTITION_ID OR V.PARTITION_ID = -2) AND STAT.INDEX_TYPE = 1 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST(DB.DATABASE_NAME AS CHAR(128)) AS OWNER, CAST(V.INDEX_NAME AS CHAR(128)) AS INDEX_NAME, CAST(DB.DATABASE_NAME AS CHAR(128)) AS TABLE_OWNER, CAST(T.TABLE_NAME AS CHAR(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS CHAR(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS CHAR(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS CHAR(12)) AS OBJECT_TYPE, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATETIME(6)) AS LAST_ANALYZED, CAST((CASE STAT.GLOBAL_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS GLOBAL_STATS, CAST((CASE STAT.USER_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS USER_STATS, CAST((CASE WHEN STAT.STATTYPE_LOCKED & 15 IS NULL THEN NULL ELSE (CASE STAT.STATTYPE_LOCKED & 15 WHEN 0 THEN NULL WHEN 1 THEN 'DATA' WHEN 2 THEN 'CACHE' ELSE 'ALL' END) END) AS CHAR(5)) AS STATTYPE_LOCKED, CAST((CASE STAT.STALE_STATS WHEN 0 THEN 'NO' WHEN 1 THEN 'YES' ELSE NULL END) AS CHAR(3)) AS STALE_STATS, CAST(NULL AS CHAR(7)) AS SCOPE FROM ( (SELECT CAST(0 AS SIGNED) AS TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, -2 AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN -2 ELSE -1 END AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM oceanbase.__all_table T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.TABLE_MODE >> 12 & 15 in (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, P.PART_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM oceanbase.__all_table T JOIN oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE = 5 AND P.PARTITION_TYPE = 0 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM oceanbase.__all_table T JOIN oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID JOIN oceanbase.__all_sub_part SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE = 5 AND P.PARTITION_TYPE = 0 AND SP.PARTITION_TYPE = 0 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN oceanbase.__all_table T ON T.TABLE_ID = V.DATA_TABLE_ID AND T.TENANT_ID = V.TENANT_ID AND T.DATABASE_ID = V.DATABASE_ID JOIN oceanbase.__all_database DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID AND V.TENANT_ID = 0 LEFT JOIN oceanbase.__all_table_stat STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND (V.PARTITION_ID = STAT.PARTITION_ID OR V.PARTITION_ID = -2) AND STAT.INDEX_TYPE = 1 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21301_21350.cpp b/src/share/inner_table/ob_inner_table_schema.21301_21350.cpp index 30cd8babd..85e173531 100644 --- a/src/share/inner_table/ob_inner_table_schema.21301_21350.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21301_21350.cpp @@ -985,7 +985,7 @@ int ObInnerTableSchema::dba_ob_table_locations_schema(ObTableSchema &table_schem 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 D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' WHEN A.TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, CASE WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 0 THEN 'STRONG' WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 1 THEN 'WEAK' ELSE 'NONE' END AS DUPLICATE_READ_CONSISTENCY, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 AND TENANT_ID = 0 UNION ALL SELECT T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = 0 UNION ALL SELECT T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID = Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 AND T.TENANT_ID = 0 ) A JOIN OCEANBASE.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN OCEANBASE.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN OCEANBASE.__ALL_DATABASE D ON A.DATABASE_ID = D.DATABASE_ID LEFT JOIN OCEANBASE.__ALL_TABLEGROUP TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE D.TENANT_ID = 0 ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' WHEN A.TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, CASE WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 0 THEN 'STRONG' WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 1 THEN 'WEAK' ELSE 'NONE' END AS DUPLICATE_READ_CONSISTENCY, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 AND TENANT_ID = 0 UNION ALL SELECT T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = 0 AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID = Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 AND T.TENANT_ID = 0 AND P.PARTITION_TYPE = 0 AND Q.PARTITION_TYPE = 0 ) A JOIN OCEANBASE.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN OCEANBASE.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN OCEANBASE.__ALL_DATABASE D ON A.DATABASE_ID = D.DATABASE_ID LEFT JOIN OCEANBASE.__ALL_TABLEGROUP TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID WHERE D.TENANT_ID = 0 ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1036,7 +1036,7 @@ int ObInnerTableSchema::cdb_ob_table_locations_schema(ObTableSchema &table_schem 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 A.TENANT_ID, D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' WHEN A.TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, CASE WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 0 THEN 'STRONG' WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 1 THEN 'WEAK' ELSE 'NONE' END AS DUPLICATE_READ_CONSISTENCY, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 UNION ALL SELECT P.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID AND T.PART_LEVEL = 1 UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID =Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 ) A JOIN OCEANBASE.CDB_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID AND A.TENANT_ID = B.TENANT_ID JOIN OCEANBASE.CDB_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID AND A.TENANT_ID = C.TENANT_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON A.TENANT_ID = D.TENANT_ID AND A.DATABASE_ID = D.DATABASE_ID LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TABLEGROUP TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID AND A.TENANT_ID = TG.TENANT_ID ORDER BY A.TENANT_ID, A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT A.TENANT_ID, D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' WHEN A.TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, CASE WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 0 THEN 'STRONG' WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 1 THEN 'WEAK' ELSE 'NONE' END AS DUPLICATE_READ_CONSISTENCY, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLET_ID != 0 AND PART_LEVEL = 0 UNION ALL SELECT P.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID AND T.PART_LEVEL = 1 AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID =Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 AND P.PARTITION_TYPE = 0 AND Q.PARTITION_TYPE = 0 ) A JOIN OCEANBASE.CDB_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID AND A.TENANT_ID = B.TENANT_ID JOIN OCEANBASE.CDB_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID AND A.TENANT_ID = C.TENANT_ID JOIN OCEANBASE.__ALL_VIRTUAL_DATABASE D ON A.TENANT_ID = D.TENANT_ID AND A.DATABASE_ID = D.DATABASE_ID LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TABLEGROUP TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID AND A.TENANT_ID = TG.TENANT_ID ORDER BY A.TENANT_ID, A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.21351_21400.cpp b/src/share/inner_table/ob_inner_table_schema.21351_21400.cpp index 9964f48c3..fb6cd5946 100644 --- a/src/share/inner_table/ob_inner_table_schema.21351_21400.cpp +++ b/src/share/inner_table/ob_inner_table_schema.21351_21400.cpp @@ -366,7 +366,7 @@ int ObInnerTableSchema::partitions_schema(ObTableSchema &table_schema) 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 CAST('def' as CHAR(4096)) AS TABLE_CATALOG, DB.DATABASE_NAME collate utf8mb4_name_case AS TABLE_SCHEMA, T.TABLE_NAME collate utf8mb4_name_case AS TABLE_NAME, P.PART_NAME AS PARTITION_NAME, SP.SUB_PART_NAME AS SUBPARTITION_NAME, CAST(PART_POSITION AS UNSIGNED) AS PARTITION_ORDINAL_POSITION, CAST(SUB_PART_POSITION AS UNSIGNED) AS SUBPARTITION_ORDINAL_POSITION, CAST(CASE WHEN T.PART_LEVEL = 0 THEN NULL ELSE (CASE T.PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) PARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE T.SUB_PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) SUBPARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE T.PART_FUNC_EXPR END AS CHAR(2048)) PARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE T.SUB_PART_FUNC_EXPR END AS CHAR(2048)) SUBPARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL ELSE P.LIST_VAL END) END AS CHAR(4096)) AS PARTITION_DESCRIPTION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL ELSE SP.LIST_VAL END) END AS CHAR(4096)) AS SUBPARTITION_DESCRIPTION, CAST(TS.ROW_CNT AS UNSIGNED) AS TABLE_ROWS, CAST(TS.AVG_ROW_LEN AS UNSIGNED) AS AVG_ROW_LENGTH, CAST(COALESCE(TS.MACRO_BLK_CNT * 2 * 1024 * 1024, 0) AS UNSIGNED) AS DATA_LENGTH, CAST(NULL AS UNSIGNED) AS MAX_DATA_LENGTH, CAST(COALESCE(IDX_STAT.INDEX_LENGTH, 0) AS UNSIGNED) AS INDEX_LENGTH, CAST(NULL AS UNSIGNED) AS DATA_FREE, CASE T.PART_LEVEL WHEN 0 THEN T.GMT_CREATE WHEN 1 THEN P.GMT_CREATE WHEN 2 THEN SP.GMT_CREATE END AS CREATE_TIME, CAST(NULL AS DATETIME) AS UPDATE_TIME, CAST(NULL AS DATETIME) AS CHECK_TIME, CAST(NULL AS SIGNED) AS CHECKSUM, CAST(CASE T.PART_LEVEL WHEN 0 THEN NULL WHEN 1 THEN P.COMMENT WHEN 2 THEN SP.COMMENT END AS CHAR(1024)) AS PARTITION_COMMENT, CAST('default' AS CHAR(256)) NODEGROUP, CAST(TP.TABLESPACE_NAME AS CHAR(268)) AS TABLESPACE_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_DATABASE DB ON T.DATABASE_ID = DB.DATABASE_ID AND T.TENANT_ID = DB.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID ORDER BY PART_IDX) AS PART_POSITION FROM OCEANBASE.__ALL_PART ) P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, SUB_PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID,PART_ID ORDER BY SUB_PART_IDX) AS SUB_PART_POSITION FROM OCEANBASE.__ALL_SUB_PART ) SP ON T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID AND T.TENANT_ID = SP.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = IFNULL(SP.TABLESPACE_ID, P.TABLESPACE_ID) AND TP.TENANT_ID = T.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TABLE_STAT TS ON T.TENANT_ID = TS.TENANT_ID AND TS.TABLE_ID = T.TABLE_ID AND TS.PARTITION_ID = CASE T.PART_LEVEL WHEN 0 THEN T.TABLE_ID WHEN 1 THEN P.PART_ID WHEN 2 THEN SP.SUB_PART_ID END LEFT JOIN ( SELECT E.TENANT_ID AS TENANT_ID, E.DATA_TABLE_ID AS DATA_TABLE_ID, F.PART_IDX AS PART_IDX, SF.SUB_PART_IDX AS SUB_PART_IDX, SUM(G.macro_blk_cnt * 2 * 1024 * 1024) AS INDEX_LENGTH FROM OCEANBASE.__ALL_TABLE E LEFT JOIN OCEANBASE.__ALL_PART F ON E.TENANT_ID = F.TENANT_ID AND E.TABLE_ID = F.TABLE_ID LEFT JOIN OCEANBASE.__ALL_SUB_PART SF ON E.TENANT_ID = SF.TENANT_ID AND E.TABLE_ID = SF.TABLE_ID AND F.PART_ID = SF.PART_ID JOIN OCEANBASE.__ALL_TABLE_STAT G ON E.TENANT_ID = G.TENANT_ID AND E.TABLE_ID = G.TABLE_ID AND G.PARTITION_ID = CASE E.PART_LEVEL WHEN 0 THEN E.TABLE_ID WHEN 1 THEN F.PART_ID WHEN 2 THEN SF.SUB_PART_ID END WHERE E.INDEX_TYPE in (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12) AND E.TABLE_TYPE = 5 GROUP BY TENANT_ID, DATA_TABLE_ID, PART_IDX, SUB_PART_IDX ) IDX_STAT ON IDX_STAT.TENANT_ID = T.TENANT_ID AND IDX_STAT.DATA_TABLE_ID = T.TABLE_ID AND CASE T.PART_LEVEL WHEN 0 THEN 1 WHEN 1 THEN P.PART_IDX = IDX_STAT.PART_IDX WHEN 2 THEN P.PART_IDX = IDX_STAT.PART_IDX AND SP.SUB_PART_IDX = IDX_STAT.SUB_PART_IDX END WHERE T.TABLE_TYPE IN (3,6,8,9,14,15) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST('def' as CHAR(4096)) AS TABLE_CATALOG, DB.DATABASE_NAME collate utf8mb4_name_case AS TABLE_SCHEMA, T.TABLE_NAME collate utf8mb4_name_case AS TABLE_NAME, P.PART_NAME AS PARTITION_NAME, SP.SUB_PART_NAME AS SUBPARTITION_NAME, CAST(PART_POSITION AS UNSIGNED) AS PARTITION_ORDINAL_POSITION, CAST(SUB_PART_POSITION AS UNSIGNED) AS SUBPARTITION_ORDINAL_POSITION, CAST(CASE WHEN T.PART_LEVEL = 0 THEN NULL ELSE (CASE T.PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) PARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE T.SUB_PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) SUBPARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE T.PART_FUNC_EXPR END AS CHAR(2048)) PARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE T.SUB_PART_FUNC_EXPR END AS CHAR(2048)) SUBPARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL ELSE P.LIST_VAL END) END AS CHAR(4096)) AS PARTITION_DESCRIPTION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL ELSE SP.LIST_VAL END) END AS CHAR(4096)) AS SUBPARTITION_DESCRIPTION, CAST(TS.ROW_CNT AS UNSIGNED) AS TABLE_ROWS, CAST(TS.AVG_ROW_LEN AS UNSIGNED) AS AVG_ROW_LENGTH, CAST(COALESCE(TS.MACRO_BLK_CNT * 2 * 1024 * 1024, 0) AS UNSIGNED) AS DATA_LENGTH, CAST(NULL AS UNSIGNED) AS MAX_DATA_LENGTH, CAST(COALESCE(IDX_STAT.INDEX_LENGTH, 0) AS UNSIGNED) AS INDEX_LENGTH, CAST(NULL AS UNSIGNED) AS DATA_FREE, CASE T.PART_LEVEL WHEN 0 THEN T.GMT_CREATE WHEN 1 THEN P.GMT_CREATE WHEN 2 THEN SP.GMT_CREATE END AS CREATE_TIME, CAST(NULL AS DATETIME) AS UPDATE_TIME, CAST(NULL AS DATETIME) AS CHECK_TIME, CAST(NULL AS SIGNED) AS CHECKSUM, CAST(CASE T.PART_LEVEL WHEN 0 THEN NULL WHEN 1 THEN P.COMMENT WHEN 2 THEN SP.COMMENT END AS CHAR(1024)) AS PARTITION_COMMENT, CAST('default' AS CHAR(256)) NODEGROUP, CAST(TP.TABLESPACE_NAME AS CHAR(268)) AS TABLESPACE_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_DATABASE DB ON T.DATABASE_ID = DB.DATABASE_ID AND T.TENANT_ID = DB.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, PARTITION_TYPE, PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID ORDER BY PART_IDX) AS PART_POSITION FROM OCEANBASE.__ALL_PART ) P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, PARTITION_TYPE, SUB_PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID,PART_ID ORDER BY SUB_PART_IDX) AS SUB_PART_POSITION FROM OCEANBASE.__ALL_SUB_PART ) SP ON T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID AND T.TENANT_ID = SP.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = IFNULL(SP.TABLESPACE_ID, P.TABLESPACE_ID) AND TP.TENANT_ID = T.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TABLE_STAT TS ON T.TENANT_ID = TS.TENANT_ID AND TS.TABLE_ID = T.TABLE_ID AND TS.PARTITION_ID = CASE T.PART_LEVEL WHEN 0 THEN T.TABLE_ID WHEN 1 THEN P.PART_ID WHEN 2 THEN SP.SUB_PART_ID END LEFT JOIN ( SELECT E.TENANT_ID AS TENANT_ID, E.DATA_TABLE_ID AS DATA_TABLE_ID, F.PART_IDX AS PART_IDX, SF.SUB_PART_IDX AS SUB_PART_IDX, SUM(G.macro_blk_cnt * 2 * 1024 * 1024) AS INDEX_LENGTH FROM OCEANBASE.__ALL_TABLE E LEFT JOIN OCEANBASE.__ALL_PART F ON E.TENANT_ID = F.TENANT_ID AND E.TABLE_ID = F.TABLE_ID LEFT JOIN OCEANBASE.__ALL_SUB_PART SF ON E.TENANT_ID = SF.TENANT_ID AND E.TABLE_ID = SF.TABLE_ID AND F.PART_ID = SF.PART_ID JOIN OCEANBASE.__ALL_TABLE_STAT G ON E.TENANT_ID = G.TENANT_ID AND E.TABLE_ID = G.TABLE_ID AND G.PARTITION_ID = CASE E.PART_LEVEL WHEN 0 THEN E.TABLE_ID WHEN 1 THEN F.PART_ID WHEN 2 THEN SF.SUB_PART_ID END WHERE E.INDEX_TYPE in (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12) AND E.TABLE_TYPE = 5 GROUP BY TENANT_ID, DATA_TABLE_ID, PART_IDX, SUB_PART_IDX ) IDX_STAT ON IDX_STAT.TENANT_ID = T.TENANT_ID AND IDX_STAT.DATA_TABLE_ID = T.TABLE_ID AND CASE T.PART_LEVEL WHEN 0 THEN 1 WHEN 1 THEN P.PART_IDX = IDX_STAT.PART_IDX WHEN 2 THEN P.PART_IDX = IDX_STAT.PART_IDX AND SP.SUB_PART_IDX = IDX_STAT.SUB_PART_IDX END WHERE T.TABLE_TYPE IN (3,6,8,9,14,15) AND (P.PARTITION_TYPE = 0 OR P.PARTITION_TYPE is NULL) AND (SP.PARTITION_TYPE = 0 OR SP.PARTITION_TYPE is NULL) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.25001_25050.cpp b/src/share/inner_table/ob_inner_table_schema.25001_25050.cpp index e5d39ace5..0504d3fd3 100644 --- a/src/share/inner_table/ob_inner_table_schema.25001_25050.cpp +++ b/src/share/inner_table/ob_inner_table_schema.25001_25050.cpp @@ -111,7 +111,7 @@ int ObInnerTableSchema::dba_objects_ora_schema(ObTableSchema &table_schema) 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 CAST(B.DATABASE_NAME AS VARCHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 AND bitand((TBL.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS VARCHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 AND bitand((TBL.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND P.PARTITION_TYPE = 0 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, CAST(201001 AS NUMBER) AS DATABASE_ID, TABLEGROUP_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, TABLEGROUP_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'TABLEGROUP' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -162,7 +162,7 @@ int ObInnerTableSchema::all_objects_schema(ObTableSchema &table_schema) 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 CAST(B.DATABASE_NAME AS VARCHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, CAST(A.TABLE_ID AS NUMBER) AS PRIV_OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,TABLE_ID PRIV_OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5,15) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 and bitand((TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,TBL.TABLE_ID AS PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 AND bitand((TBL.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,P.TABLE_ID PRIV_OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLE_ID PRIV_OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,PACKAGE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,P.PACKAGE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,R.ROUTINE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,TS.TYPE_ID AS PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,OBJECT_TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,OBJECT_TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,T.TRIGGER_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,SEQUENCE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,SYNONYM_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,CONTEXT_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID()*/ UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() AND (A.DATABASE_ID = USERENV('SCHEMAID') OR (A.PRIV_OBJECT_ID != -1 AND USER_CAN_ACCESS_OBJ(DECODE(OBJECT_TYPE, 'TABLE', 1, 'VIEW', 1, 'INDEX', 1, 'MATERIALIZED VIEW', 1, 'MATERIALIZED VIEW LOG', 1, 'TABLE PARTITION', 1, 'TABLE SUBPARTITION', 1, 'INDEX PARTITION', 1, 'INDEX SUBPARTITION', 1, 'SEQUENCE', 2, 'PACKAGE', 3, 'PACKAGE BODY', 3, 'TYPE', 4, 'TYPE BODY', 4, 'TRIGGER', 7, 'FUNCTION', 9, 'PROCEDURE', 12, 'SYNONYM', 13, 1), A.PRIV_OBJECT_ID, A.DATABASE_ID) = 1)) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS VARCHAR(128)) AS OWNER, CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, CAST(A.TABLE_ID AS NUMBER) AS PRIV_OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,TABLE_ID PRIV_OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5,15) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 and bitand((TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,TBL.TABLE_ID AS PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 AND bitand((TBL.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,P.TABLE_ID PRIV_OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND P.PARTITION_TYPE = 0 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLE_ID PRIV_OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,PACKAGE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,P.PACKAGE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,R.ROUTINE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,TS.TYPE_ID AS PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,OBJECT_TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,OBJECT_TYPE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,T.TRIGGER_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,SEQUENCE_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,SYNONYM_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,CONTEXT_ID PRIV_OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID()*/ UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, CAST(-1 AS NUMBER) AS PRIV_OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() AND (A.DATABASE_ID = USERENV('SCHEMAID') OR (A.PRIV_OBJECT_ID != -1 AND USER_CAN_ACCESS_OBJ(DECODE(OBJECT_TYPE, 'TABLE', 1, 'VIEW', 1, 'INDEX', 1, 'MATERIALIZED VIEW', 1, 'MATERIALIZED VIEW LOG', 1, 'TABLE PARTITION', 1, 'TABLE SUBPARTITION', 1, 'INDEX PARTITION', 1, 'INDEX SUBPARTITION', 1, 'SEQUENCE', 2, 'PACKAGE', 3, 'PACKAGE BODY', 3, 'TYPE', 4, 'TYPE BODY', 4, 'TRIGGER', 7, 'FUNCTION', 9, 'PROCEDURE', 12, 'SYNONYM', 13, 1), A.PRIV_OBJECT_ID, A.DATABASE_ID) = 1)) )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -213,7 +213,7 @@ int ObInnerTableSchema::user_objects_schema(ObTableSchema &table_schema) 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 CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5,15) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 AND bitand((TBL.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID()*/ UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() AND A.DATABASE_ID = USERENV('SCHEMAID') )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(A.OBJECT_NAME AS VARCHAR(128)) AS OBJECT_NAME, CAST(A.SUBOBJECT_NAME AS VARCHAR2(128)) AS SUBOBJECT_NAME, CAST(A.OBJECT_ID AS NUMBER) AS OBJECT_ID, CAST(A.DATA_OBJECT_ID AS NUMBER) AS DATA_OBJECT_ID, CAST(A.OBJECT_TYPE AS VARCHAR2(23)) AS OBJECT_TYPE, CAST(A.GMT_CREATE AS DATE) AS CREATED, CAST(A.GMT_MODIFIED AS DATE) AS LAST_DDL_TIME, CAST(TO_CHAR(A.GMT_CREATE) AS VARCHAR2(19)) AS TIMESTAMP, CAST(A.STATUS AS VARCHAR2(7)) AS STATUS, CAST(A.TEMPORARY AS VARCHAR2(1)) AS TEMPORARY, CAST(A."GENERATED" AS VARCHAR2(1)) AS "GENERATED", CAST(A.SECONDARY AS VARCHAR2(1)) AS SECONDARY, CAST(A.NAMESPACE AS NUMBER) AS NAMESPACE, CAST(A.EDITION_NAME AS VARCHAR2(128)) AS EDITION_NAME, CAST(NULL AS VARCHAR2(18)) AS SHARING, CAST(NULL AS VARCHAR2(1)) AS EDITIONABLE, CAST(NULL AS VARCHAR2(1)) AS ORACLE_MAINTAINED, CAST(NULL AS VARCHAR2(1)) AS APPLICATION, CAST(NULL AS VARCHAR2(1)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS IMPORTED_OBJECT, CAST(NULL AS NUMBER) AS CREATED_APPID, CAST(NULL AS NUMBER) AS CREATED_VSNID, CAST(NULL AS NUMBER) AS MODIFIED_APPID, CAST(NULL AS NUMBER) AS MODIFIED_VSNID FROM ( SELECT A.TENANT_ID, (TO_DATE('19700101','YYYYMMDD') + B.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_CREATE, (TO_DATE('19700101','YYYYMMDD') + A.SCHEMA_VERSION / 86400 / 1000000 + TO_NUMBER(SUBSTR(TZ_OFFSET(SESSIONTIMEZONE),1,3))/24) AS GMT_MODIFIED, A.DATABASE_ID, A.TABLE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, CAST(A.TABLE_ID AS NUMBER) AS OBJECT_ID, A.TABLE_ID AS DATA_OBJECT_ID, 'TABLE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE A JOIN SYS.ALL_VIRTUAL_CORE_ALL_TABLE B ON A.TENANT_ID = B.TENANT_ID WHERE B.TABLE_NAME = '__all_core_table' AND A.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,CAST((CASE WHEN DATABASE_ID = 201004 THEN TABLE_NAME WHEN TABLE_TYPE = 5 THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,NULL SUBOBJECT_NAME ,TABLE_ID OBJECT_ID ,(CASE WHEN TABLET_ID != 0 THEN TABLET_ID ELSE NULL END) DATA_OBJECT_ID ,CASE WHEN TABLE_TYPE IN (0,3,6,8,9,14) THEN 'TABLE' WHEN TABLE_TYPE IN (2) THEN 'VIRTUAL TABLE' WHEN TABLE_TYPE IN (1,4) THEN 'VIEW' WHEN TABLE_TYPE IN (5) THEN 'INDEX' WHEN TABLE_TYPE IN (7) THEN 'MATERIALIZED VIEW' WHEN TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS OBJECT_TYPE ,CAST(CASE WHEN TABLE_TYPE IN (5,15) THEN CASE WHEN INDEX_STATUS = 2 THEN 'VALID' WHEN INDEX_STATUS = 3 THEN 'CHECKING' WHEN INDEX_STATUS = 4 THEN 'INELEGIBLE' WHEN INDEX_STATUS = 5 THEN 'ERROR' ELSE 'UNUSABLE' END ELSE CASE WHEN OBJECT_STATUS = 1 THEN 'VALID' ELSE 'INVALID' END END AS VARCHAR2(10)) AS STATUS ,CASE WHEN TABLE_TYPE IN (6,8,9) THEN 'Y' ELSE 'N' END AS TEMPORARY ,CASE WHEN TABLE_TYPE IN (0,1) THEN 'Y' ELSE 'N' END AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT CST.TENANT_ID ,CST.GMT_CREATE ,CST.GMT_MODIFIED ,DB.DATABASE_ID ,CST.CONSTRAINT_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TBL.TABLE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'INDEX' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONSTRAINT_REAL_AGENT CST, SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TBL, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE CST.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_ID = TBL.DATABASE_ID AND TBL.TABLE_ID = CST.TABLE_ID and CST.CONSTRAINT_TYPE = 1 AND TBL.TABLE_TYPE != 12 AND TBL.TABLE_TYPE != 13 AND bitand((TBL.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,P.PART_NAME SUBOBJECT_NAME ,P.PART_ID OBJECT_ID ,CASE WHEN P.TABLET_ID != 0 THEN P.TABLET_ID ELSE NULL END AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX PARTITION', 'TABLE PARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY , NULL AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND P.PARTITION_TYPE = 0 UNION ALL SELECT SUBP.TENANT_ID ,SUBP.GMT_CREATE ,SUBP.GMT_MODIFIED ,T.DATABASE_ID ,CAST((CASE WHEN T.DATABASE_ID = 201004 THEN T.TABLE_NAME WHEN T.TABLE_TYPE = 5 THEN SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) ELSE T.TABLE_NAME END) AS VARCHAR2(128)) AS OBJECT_NAME ,SUBP.SUB_PART_NAME SUBOBJECT_NAME ,SUBP.SUB_PART_ID OBJECT_ID ,SUBP.TABLET_ID AS DATA_OBJECT_ID ,DECODE (T.TABLE_TYPE, 5, 'INDEX SUBPARTITION', 'TABLE SUBPARTITION') AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'Y' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T, SYS.ALL_VIRTUAL_PART_REAL_AGENT P,SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_SYS_AGENT UNION ALL SELECT P.TENANT_ID ,P.GMT_CREATE ,P.GMT_MODIFIED ,P.DATABASE_ID ,P.PACKAGE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,P.PACKAGE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN TYPE = 1 THEN 'PACKAGE' WHEN TYPE = 2 THEN 'PACKAGE BODY' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE P.TENANT_ID = E.TENANT_ID AND P.PACKAGE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 3 OR E.OBJ_TYPE = 5)) THEN 'INVALID' WHEN TYPE = 2 AND EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT Eb WHERE OBJ_ID IN (SELECT PACKAGE_ID FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT Pb WHERE Pb.PACKAGE_NAME = P.PACKAGE_NAME AND Pb.DATABASE_ID = P.DATABASE_ID AND Pb.TENANT_ID = P.TENANT_ID AND TYPE = 1) AND Eb.OBJ_TYPE = 3) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_PACKAGE_REAL_AGENT P WHERE P.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT R.TENANT_ID ,R.GMT_CREATE ,R.GMT_MODIFIED ,R.DATABASE_ID ,R.ROUTINE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,R.ROUTINE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,CASE WHEN ROUTINE_TYPE = 1 THEN 'PROCEDURE' WHEN ROUTINE_TYPE = 2 THEN 'FUNCTION' ELSE NULL END AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE R.TENANT_ID = E.TENANT_ID AND R.ROUTINE_ID = E.OBJ_ID AND (E.OBJ_TYPE = 9 OR E.OBJ_TYPE = 12)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_ROUTINE_REAL_AGENT R WHERE (ROUTINE_TYPE = 1 OR ROUTINE_TYPE = 2) AND R.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,TS.TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TS.TYPE_ID AS OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TS.TENANT_ID = E.TENANT_ID AND TS.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_SYS_AGENT TS UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,TYPE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 4) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT EFFECTIVE_TENANT_ID() AS TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE EFFECTIVE_TENANT_ID() = E.TENANT_ID AND TS.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_SYS_AGENT TS WHERE TYPE = 2 UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,OBJECT_TYPE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TYPE BODY' AS OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE TY.TENANT_ID = E.TENANT_ID AND TY.OBJECT_TYPE_ID = E.OBJ_ID AND E.OBJ_TYPE = 6) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_OBJECT_TYPE_REAL_AGENT TY WHERE TENANT_ID = EFFECTIVE_TENANT_ID() and TYPE = 2 UNION ALL SELECT T.TENANT_ID ,T.GMT_CREATE ,T.GMT_MODIFIED ,T.DATABASE_ID ,T.TRIGGER_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,T.TRIGGER_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'TRIGGER' OBJECT_TYPE ,CASE WHEN EXISTS (SELECT OBJ_ID FROM SYS.ALL_VIRTUAL_TENANT_ERROR_REAL_AGENT E WHERE T.TENANT_ID = E.TENANT_ID AND T.TRIGGER_ID = E.OBJ_ID AND (E.OBJ_TYPE = 7)) THEN 'INVALID' ELSE 'VALID' END AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TENANT_TRIGGER_REAL_AGENT T WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SEQUENCE_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SEQUENCE_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SEQUENCE' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SEQUENCE_OBJECT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,DATABASE_ID ,SYNONYM_NAME AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,SYNONYM_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'SYNONYM' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_SYNONYM_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() /*UNION ALL SELECT TENANT_ID ,GMT_CREATE ,GMT_MODIFIED ,CAST(201006 AS NUMBER) AS DATABASE_ID ,NAMESPACE AS OBJECT_NAME ,NULL AS SUBOBJECT_NAME ,CONTEXT_ID OBJECT_ID ,NULL AS DATA_OBJECT_ID ,'CONTEXT' AS OBJECT_TYPE ,'VALID' AS STATUS ,'N' AS TEMPORARY ,'N' AS "GENERATED" ,'N' AS SECONDARY ,21 AS NAMESPACE ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_CONTEXT_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID()*/ UNION ALL SELECT TENANT_ID, GMT_CREATE, GMT_MODIFIED, DATABASE_ID, DATABASE_NAME AS OBJECT_NAME, NULL AS SUBOBJECT_NAME, DATABASE_ID AS OBJECT_ID, NULL AS DATA_OBJECT_ID, 'DATABASE' AS OBJECT_TYPE, 'VALID' AS STATUS, 'N' AS TEMPORARY, 'N' AS "GENERATED", 'N' AS SECONDARY, 0 AS NAMESPACE, NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.TENANT_ID = B.TENANT_ID AND A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() AND A.DATABASE_ID = USERENV('SCHEMAID') )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1386,7 +1386,7 @@ int ObInnerTableSchema::all_tables_schema(ObTableSchema &table_schema) 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 CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_NAME, CAST(NULL AS VARCHAR2(128)) AS IOT_NAME, CAST('VALID' AS VARCHAR2(8)) AS STATUS, CAST(T."PCTFREE" AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS PCT_USED, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENTS, CAST(NULL AS NUMBER) AS MAX_EXTENTS, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(NULL AS VARCHAR2(1)) AS BACKED_UP, CAST(INFO.ROW_COUNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(NULL AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS VARCHAR2(10)) AS DEGREE, CAST(NULL AS VARCHAR2(10)) AS INSTANCES, CAST(NULL AS VARCHAR2(5)) AS CACHE, CAST(NULL AS VARCHAR2(8)) AS TABLE_LOCK, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST( CASE WHEN T.PART_LEVEL = 0 THEN 'NO' ELSE 'YES' END AS VARCHAR2(3)) AS PARTITIONED, CAST(NULL AS VARCHAR2(12)) AS IOT_TYPE, CAST(DECODE (T.TABLE_TYPE, 8, 'Y', 9, 'Y', 'N') AS VARCHAR2(1)) AS TEMPORARY, CAST(NULL AS VARCHAR2(1)) AS SECONDARY, CAST('NO' AS VARCHAR2(3)) AS NESTED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(8)) AS ROW_MOVEMENT, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(DECODE (T.TABLE_TYPE, 8, 'SYS$SESSION', 9, 'SYS$TRANSACTION', NULL) AS VARCHAR2(15)) AS DURATION, CAST(NULL AS VARCHAR2(8)) AS SKIP_CORRUPT, CAST(NULL AS VARCHAR2(3)) AS MONITORING, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_OWNER, CAST(NULL AS VARCHAR2(8)) AS DEPENDENCIES, CAST(NULL AS VARCHAR2(8)) AS COMPRESSION, CAST(NULL AS VARCHAR2(30)) AS COMPRESS_FOR, CAST(CASE WHEN DB.IN_RECYCLEBIN = 1 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) AS DROPPED, CAST(NULL AS VARCHAR2(3)) AS READ_ONLY, CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(7)) AS RESULT_CACHE, CAST(NULL AS VARCHAR2(3)) AS CLUSTERING, CAST(NULL AS VARCHAR2(23)) AS ACTIVITY_TRACKING, CAST(NULL AS VARCHAR2(25)) AS DML_TIMESTAMP, CAST(NULL AS VARCHAR2(3)) AS HAS_IDENTITY, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_DATA, CAST(NULL AS VARCHAR2(8)) AS INMEMORY, CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(100)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_DUPLICATED, CAST(DECODE (T.TABLE_TYPE, 14, 'YES', 'NO') AS VARCHAR2(3)) AS EXTERNAL, CAST(NULL AS VARCHAR2(3)) AS HYBRID, CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY, CAST(NULL AS VARCHAR2(3)) AS CONTAINERS_DEFAULT, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK_MAP, CAST(NULL AS VARCHAR2(12)) AS INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) AS INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP_OBJECT, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_WRITE, CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION FROM (SELECT TENANT_ID, TABLE_ID, ROW_CNT AS ROW_COUNT FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT TS WHERE TS.TENANT_ID = EFFECTIVE_TENANT_ID() AND (PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) ) INFO RIGHT JOIN (SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION ALL SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((TABLE_MODE / 4096), 15) IN (0,1) ) T ON T.TENANT_ID = INFO.TENANT_ID AND T.TABLE_ID = INFO.TABLE_ID AND INFO.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = T.TENANT_ID AND DB.DATABASE_ID = T.DATABASE_ID AND T.TABLE_TYPE IN (0, 3, 8, 9, 14, 15) AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_NAME != '__recyclebin' AND (T.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, T.TABLE_ID, T.DATABASE_ID) =1) LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = T.TABLESPACE_ID AND T.TENANT_ID = TP.TENANT_ID AND TP.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_NAME, CAST(NULL AS VARCHAR2(128)) AS IOT_NAME, CAST('VALID' AS VARCHAR2(8)) AS STATUS, CAST(T."PCTFREE" AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS PCT_USED, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENTS, CAST(NULL AS NUMBER) AS MAX_EXTENTS, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(NULL AS VARCHAR2(1)) AS BACKED_UP, CAST(INFO.ROW_COUNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(NULL AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS VARCHAR2(10)) AS DEGREE, CAST(NULL AS VARCHAR2(10)) AS INSTANCES, CAST(NULL AS VARCHAR2(5)) AS CACHE, CAST(NULL AS VARCHAR2(8)) AS TABLE_LOCK, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST( CASE WHEN T.PART_LEVEL = 0 THEN 'NO' ELSE 'YES' END AS VARCHAR2(3)) AS PARTITIONED, CAST(NULL AS VARCHAR2(12)) AS IOT_TYPE, CAST(DECODE (T.TABLE_TYPE, 8, 'Y', 9, 'Y', 'N') AS VARCHAR2(1)) AS TEMPORARY, CAST(NULL AS VARCHAR2(1)) AS SECONDARY, CAST('NO' AS VARCHAR2(3)) AS NESTED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(8)) AS ROW_MOVEMENT, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(DECODE (T.TABLE_TYPE, 8, 'SYS$SESSION', 9, 'SYS$TRANSACTION', NULL) AS VARCHAR2(15)) AS DURATION, CAST(NULL AS VARCHAR2(8)) AS SKIP_CORRUPT, CAST(NULL AS VARCHAR2(3)) AS MONITORING, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_OWNER, CAST(NULL AS VARCHAR2(8)) AS DEPENDENCIES, CAST(NULL AS VARCHAR2(8)) AS COMPRESSION, CAST(NULL AS VARCHAR2(30)) AS COMPRESS_FOR, CAST(CASE WHEN DB.IN_RECYCLEBIN = 1 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) AS DROPPED, CAST(NULL AS VARCHAR2(3)) AS READ_ONLY, CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(7)) AS RESULT_CACHE, CAST(NULL AS VARCHAR2(3)) AS CLUSTERING, CAST(NULL AS VARCHAR2(23)) AS ACTIVITY_TRACKING, CAST(NULL AS VARCHAR2(25)) AS DML_TIMESTAMP, CAST(NULL AS VARCHAR2(3)) AS HAS_IDENTITY, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_DATA, CAST(NULL AS VARCHAR2(8)) AS INMEMORY, CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(100)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_DUPLICATED, CAST(DECODE (T.TABLE_TYPE, 14, 'YES', 'NO') AS VARCHAR2(3)) AS EXTERNAL, CAST(NULL AS VARCHAR2(3)) AS HYBRID, CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY, CAST(NULL AS VARCHAR2(3)) AS CONTAINERS_DEFAULT, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK_MAP, CAST(NULL AS VARCHAR2(12)) AS INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) AS INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP_OBJECT, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_WRITE, CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION, CAST(CASE WHEN T.AUTO_PART = 1 THEN 'TRUE' ELSE 'FALSE' END AS VARCHAR2(16)) AS AUTO_SPLIT, CAST(CASE WHEN T.AUTO_PART = 1 THEN T.AUTO_PART_SIZE ELSE 0 END AS VARCHAR2(128)) AS AUTO_SPLIT_TABLET_SIZE FROM (SELECT TENANT_ID, TABLE_ID, ROW_CNT AS ROW_COUNT FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT TS WHERE TS.TENANT_ID = EFFECTIVE_TENANT_ID() AND (PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) ) INFO RIGHT JOIN (SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID, AUTO_PART, AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION ALL SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID, AUTO_PART, AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((TABLE_MODE / 4096), 15) IN (0,1) ) T ON T.TENANT_ID = INFO.TENANT_ID AND T.TABLE_ID = INFO.TABLE_ID AND INFO.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = T.TENANT_ID AND DB.DATABASE_ID = T.DATABASE_ID AND T.TABLE_TYPE IN (0, 3, 8, 9, 14, 15) AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_NAME != '__recyclebin' AND (T.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, T.TABLE_ID, T.DATABASE_ID) =1) LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = T.TABLESPACE_ID AND T.TENANT_ID = TP.TENANT_ID AND TP.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1437,7 +1437,7 @@ int ObInnerTableSchema::dba_tables_schema(ObTableSchema &table_schema) 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 CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_NAME, CAST(NULL AS VARCHAR2(128)) AS IOT_NAME, CAST('VALID' AS VARCHAR2(8)) AS STATUS, CAST(T."PCTFREE" AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS PCT_USED, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENTS, CAST(NULL AS NUMBER) AS MAX_EXTENTS, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(NULL AS VARCHAR2(1)) AS BACKED_UP, CAST(INFO.ROW_COUNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(NULL AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS VARCHAR2(10)) AS DEGREE, CAST(NULL AS VARCHAR2(10)) AS INSTANCES, CAST(NULL AS VARCHAR2(5)) AS CACHE, CAST(NULL AS VARCHAR2(8)) AS TABLE_LOCK, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST( CASE WHEN T.PART_LEVEL = 0 THEN 'NO' ELSE 'YES' END AS VARCHAR2(3)) AS PARTITIONED, CAST(NULL AS VARCHAR2(12)) AS IOT_TYPE, CAST(DECODE (T.TABLE_TYPE, 8, 'Y', 9, 'Y', 'N') AS VARCHAR2(1)) AS TEMPORARY, CAST(NULL AS VARCHAR2(1)) AS SECONDARY, CAST('NO' AS VARCHAR2(3)) AS NESTED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(8)) AS ROW_MOVEMENT, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(DECODE (T.TABLE_TYPE, 8, 'SYS$SESSION', 9, 'SYS$TRANSACTION', NULL) AS VARCHAR2(15)) AS DURATION, CAST(NULL AS VARCHAR2(8)) AS SKIP_CORRUPT, CAST(NULL AS VARCHAR2(3)) AS MONITORING, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_OWNER, CAST(NULL AS VARCHAR2(8)) AS DEPENDENCIES, CAST(NULL AS VARCHAR2(8)) AS COMPRESSION, CAST(NULL AS VARCHAR2(30)) AS COMPRESS_FOR, CAST(CASE WHEN DB.IN_RECYCLEBIN = 1 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) AS DROPPED, CAST(NULL AS VARCHAR2(3)) AS READ_ONLY, CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(7)) AS RESULT_CACHE, CAST(NULL AS VARCHAR2(3)) AS CLUSTERING, CAST(NULL AS VARCHAR2(23)) AS ACTIVITY_TRACKING, CAST(NULL AS VARCHAR2(25)) AS DML_TIMESTAMP, CAST(NULL AS VARCHAR2(3)) AS HAS_IDENTITY, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_DATA, CAST(NULL AS VARCHAR2(8)) AS INMEMORY, CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(100)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_DUPLICATED, CAST(DECODE (T.TABLE_TYPE, 14, 'YES', 'NO') AS VARCHAR2(3)) AS EXTERNAL, CAST(NULL AS VARCHAR2(3)) AS HYBRID, CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY, CAST(NULL AS VARCHAR2(3)) AS CONTAINERS_DEFAULT, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK_MAP, CAST(NULL AS VARCHAR2(12)) AS INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) AS INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP_OBJECT, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_WRITE, CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION FROM (SELECT TENANT_ID, TABLE_ID, ROW_CNT AS ROW_COUNT FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT TS WHERE TS.TENANT_ID = EFFECTIVE_TENANT_ID() AND (PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) ) INFO RIGHT JOIN (SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION ALL SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) ) T ON T.TENANT_ID = INFO.TENANT_ID AND T.TABLE_ID = INFO.TABLE_ID AND INFO.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = T.TENANT_ID AND DB.DATABASE_ID = T.DATABASE_ID AND T.TABLE_TYPE IN (0, 3, 8, 9, 14, 15) AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_NAME != '__recyclebin' LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = T.TABLESPACE_ID AND T.TENANT_ID = TP.TENANT_ID AND TP.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_NAME, CAST(NULL AS VARCHAR2(128)) AS IOT_NAME, CAST('VALID' AS VARCHAR2(8)) AS STATUS, CAST(T."PCTFREE" AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS PCT_USED, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENTS, CAST(NULL AS NUMBER) AS MAX_EXTENTS, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(NULL AS VARCHAR2(1)) AS BACKED_UP, CAST(INFO.ROW_COUNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(NULL AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS VARCHAR2(10)) AS DEGREE, CAST(NULL AS VARCHAR2(10)) AS INSTANCES, CAST(NULL AS VARCHAR2(5)) AS CACHE, CAST(NULL AS VARCHAR2(8)) AS TABLE_LOCK, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST( CASE WHEN T.PART_LEVEL = 0 THEN 'NO' ELSE 'YES' END AS VARCHAR2(3)) AS PARTITIONED, CAST(NULL AS VARCHAR2(12)) AS IOT_TYPE, CAST(DECODE (T.TABLE_TYPE, 8, 'Y', 9, 'Y', 'N') AS VARCHAR2(1)) AS TEMPORARY, CAST(NULL AS VARCHAR2(1)) AS SECONDARY, CAST('NO' AS VARCHAR2(3)) AS NESTED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(8)) AS ROW_MOVEMENT, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(DECODE (T.TABLE_TYPE, 8, 'SYS$SESSION', 9, 'SYS$TRANSACTION', NULL) AS VARCHAR2(15)) AS DURATION, CAST(NULL AS VARCHAR2(8)) AS SKIP_CORRUPT, CAST(NULL AS VARCHAR2(3)) AS MONITORING, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_OWNER, CAST(NULL AS VARCHAR2(8)) AS DEPENDENCIES, CAST(NULL AS VARCHAR2(8)) AS COMPRESSION, CAST(NULL AS VARCHAR2(30)) AS COMPRESS_FOR, CAST(CASE WHEN DB.IN_RECYCLEBIN = 1 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) AS DROPPED, CAST(NULL AS VARCHAR2(3)) AS READ_ONLY, CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(7)) AS RESULT_CACHE, CAST(NULL AS VARCHAR2(3)) AS CLUSTERING, CAST(NULL AS VARCHAR2(23)) AS ACTIVITY_TRACKING, CAST(NULL AS VARCHAR2(25)) AS DML_TIMESTAMP, CAST(NULL AS VARCHAR2(3)) AS HAS_IDENTITY, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_DATA, CAST(NULL AS VARCHAR2(8)) AS INMEMORY, CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(100)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_DUPLICATED, CAST(DECODE (T.TABLE_TYPE, 14, 'YES', 'NO') AS VARCHAR2(3)) AS EXTERNAL, CAST(NULL AS VARCHAR2(3)) AS HYBRID, CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY, CAST(NULL AS VARCHAR2(3)) AS CONTAINERS_DEFAULT, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK_MAP, CAST(NULL AS VARCHAR2(12)) AS INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) AS INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP_OBJECT, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_WRITE, CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION, CAST(CASE WHEN T.AUTO_PART = 1 THEN 'TRUE' ELSE 'FALSE' END AS VARCHAR2(16)) AS AUTO_SPLIT, CAST(CASE WHEN T.AUTO_PART = 1 THEN T.AUTO_PART_SIZE ELSE 0 END AS VARCHAR2(128)) AS AUTO_SPLIT_TABLET_SIZE FROM (SELECT TENANT_ID, TABLE_ID, ROW_CNT AS ROW_COUNT FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT TS WHERE TS.TENANT_ID = EFFECTIVE_TENANT_ID() AND (PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) ) INFO RIGHT JOIN (SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID, AUTO_PART, AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION ALL SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID, AUTO_PART, AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) ) T ON T.TENANT_ID = INFO.TENANT_ID AND T.TABLE_ID = INFO.TABLE_ID AND INFO.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = T.TENANT_ID AND DB.DATABASE_ID = T.DATABASE_ID AND T.TABLE_TYPE IN (0, 3, 8, 9, 14, 15) AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_NAME != '__recyclebin' LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = T.TABLESPACE_ID AND T.TENANT_ID = TP.TENANT_ID AND TP.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1488,7 +1488,7 @@ int ObInnerTableSchema::user_tables_schema(ObTableSchema &table_schema) 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 CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_NAME, CAST(NULL AS VARCHAR2(128)) AS IOT_NAME, CAST('VALID' AS VARCHAR2(8)) AS STATUS, CAST(T."PCTFREE" AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS PCT_USED, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENTS, CAST(NULL AS NUMBER) AS MAX_EXTENTS, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(NULL AS VARCHAR2(1)) AS BACKED_UP, CAST(INFO.ROW_COUNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(NULL AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS VARCHAR2(10)) AS DEGREE, CAST(NULL AS VARCHAR2(10)) AS INSTANCES, CAST(NULL AS VARCHAR2(5)) AS CACHE, CAST(NULL AS VARCHAR2(8)) AS TABLE_LOCK, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST( CASE WHEN T.PART_LEVEL = 0 THEN 'NO' ELSE 'YES' END AS VARCHAR2(3)) AS PARTITIONED, CAST(NULL AS VARCHAR2(12)) AS IOT_TYPE, CAST(DECODE (T.TABLE_TYPE, 8, 'Y', 9, 'Y', 'N') AS VARCHAR2(1)) AS TEMPORARY, CAST(NULL AS VARCHAR2(1)) AS SECONDARY, CAST('NO' AS VARCHAR2(3)) AS NESTED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(8)) AS ROW_MOVEMENT, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(DECODE (T.TABLE_TYPE, 8, 'SYS$SESSION', 9, 'SYS$TRANSACTION', NULL) AS VARCHAR2(15)) AS DURATION, CAST(NULL AS VARCHAR2(8)) AS SKIP_CORRUPT, CAST(NULL AS VARCHAR2(3)) AS MONITORING, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_OWNER, CAST(NULL AS VARCHAR2(8)) AS DEPENDENCIES, CAST(NULL AS VARCHAR2(8)) AS COMPRESSION, CAST(NULL AS VARCHAR2(30)) AS COMPRESS_FOR, CAST(CASE WHEN DB.IN_RECYCLEBIN = 1 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) AS DROPPED, CAST(NULL AS VARCHAR2(3)) AS READ_ONLY, CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(7)) AS RESULT_CACHE, CAST(NULL AS VARCHAR2(3)) AS CLUSTERING, CAST(NULL AS VARCHAR2(23)) AS ACTIVITY_TRACKING, CAST(NULL AS VARCHAR2(25)) AS DML_TIMESTAMP, CAST(NULL AS VARCHAR2(3)) AS HAS_IDENTITY, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_DATA, CAST(NULL AS VARCHAR2(8)) AS INMEMORY, CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(100)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_DUPLICATED, CAST(DECODE (T.TABLE_TYPE, 14, 'YES', 'NO') AS VARCHAR2(3)) AS EXTERNAL, CAST(NULL AS VARCHAR2(3)) AS HYBRID, CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY, CAST(NULL AS VARCHAR2(3)) AS CONTAINERS_DEFAULT, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK_MAP, CAST(NULL AS VARCHAR2(12)) AS INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) AS INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP_OBJECT, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_WRITE, CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION FROM (SELECT TENANT_ID, TABLE_ID, ROW_CNT AS ROW_COUNT FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT TS WHERE TS.TENANT_ID = EFFECTIVE_TENANT_ID() AND (PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) ) INFO RIGHT JOIN (SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION ALL SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) ) T ON T.TENANT_ID = INFO.TENANT_ID AND T.TABLE_ID = INFO.TABLE_ID AND INFO.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = T.TENANT_ID AND DB.DATABASE_ID = T.DATABASE_ID AND T.TABLE_TYPE IN (0, 3, 8, 9, 14, 15) AND T.DATABASE_ID = USERENV('SCHEMAID') AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_NAME != '__recyclebin' LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = T.TABLESPACE_ID AND T.TENANT_ID = TP.TENANT_ID AND TP.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_NAME, CAST(NULL AS VARCHAR2(128)) AS IOT_NAME, CAST('VALID' AS VARCHAR2(8)) AS STATUS, CAST(T."PCTFREE" AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS PCT_USED, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENTS, CAST(NULL AS NUMBER) AS MAX_EXTENTS, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(NULL AS VARCHAR2(1)) AS BACKED_UP, CAST(INFO.ROW_COUNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(NULL AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS VARCHAR2(10)) AS DEGREE, CAST(NULL AS VARCHAR2(10)) AS INSTANCES, CAST(NULL AS VARCHAR2(5)) AS CACHE, CAST(NULL AS VARCHAR2(8)) AS TABLE_LOCK, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST( CASE WHEN T.PART_LEVEL = 0 THEN 'NO' ELSE 'YES' END AS VARCHAR2(3)) AS PARTITIONED, CAST(NULL AS VARCHAR2(12)) AS IOT_TYPE, CAST(DECODE (T.TABLE_TYPE, 8, 'Y', 9, 'Y', 'N') AS VARCHAR2(1)) AS TEMPORARY, CAST(NULL AS VARCHAR2(1)) AS SECONDARY, CAST('NO' AS VARCHAR2(3)) AS NESTED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(8)) AS ROW_MOVEMENT, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(DECODE (T.TABLE_TYPE, 8, 'SYS$SESSION', 9, 'SYS$TRANSACTION', NULL) AS VARCHAR2(15)) AS DURATION, CAST(NULL AS VARCHAR2(8)) AS SKIP_CORRUPT, CAST(NULL AS VARCHAR2(3)) AS MONITORING, CAST(NULL AS VARCHAR2(128)) AS CLUSTER_OWNER, CAST(NULL AS VARCHAR2(8)) AS DEPENDENCIES, CAST(NULL AS VARCHAR2(8)) AS COMPRESSION, CAST(NULL AS VARCHAR2(30)) AS COMPRESS_FOR, CAST(CASE WHEN DB.IN_RECYCLEBIN = 1 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) AS DROPPED, CAST(NULL AS VARCHAR2(3)) AS READ_ONLY, CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(7)) AS RESULT_CACHE, CAST(NULL AS VARCHAR2(3)) AS CLUSTERING, CAST(NULL AS VARCHAR2(23)) AS ACTIVITY_TRACKING, CAST(NULL AS VARCHAR2(25)) AS DML_TIMESTAMP, CAST(NULL AS VARCHAR2(3)) AS HAS_IDENTITY, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_DATA, CAST(NULL AS VARCHAR2(8)) AS INMEMORY, CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(100)) AS DEFAULT_COLLATION, CAST(NULL AS VARCHAR2(1)) AS DUPLICATED, CAST(NULL AS VARCHAR2(1)) AS SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_SHARDED, CAST(NULL AS VARCHAR2(1)) AS EXTERNALLY_DUPLICATED, CAST(DECODE (T.TABLE_TYPE, 14, 'YES', 'NO') AS VARCHAR2(3)) AS EXTERNAL, CAST(NULL AS VARCHAR2(3)) AS HYBRID, CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY, CAST(NULL AS VARCHAR2(3)) AS CONTAINERS_DEFAULT, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK, CAST(NULL AS VARCHAR2(3)) AS EXTENDED_DATA_LINK_MAP, CAST(NULL AS VARCHAR2(12)) AS INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) AS INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(3)) AS CONTAINER_MAP_OBJECT, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) AS MEMOPTIMIZE_WRITE, CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION, CAST(CASE WHEN T.AUTO_PART = 1 THEN 'TRUE' ELSE 'FALSE' END AS VARCHAR2(16)) AS AUTO_SPLIT, CAST(CASE WHEN T.AUTO_PART = 1 THEN T.AUTO_PART_SIZE ELSE 0 END AS VARCHAR2(128)) AS AUTO_SPLIT_TABLET_SIZE FROM (SELECT TENANT_ID, TABLE_ID, ROW_CNT AS ROW_COUNT FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT TS WHERE TS.TENANT_ID = EFFECTIVE_TENANT_ID() AND (PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) ) INFO RIGHT JOIN (SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID, AUTO_PART, AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION ALL SELECT TENANT_ID, TABLE_ID, TABLE_NAME, DATABASE_ID, "PCTFREE", PART_LEVEL, TABLE_TYPE, TABLESPACE_ID, AUTO_PART, AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) ) T ON T.TENANT_ID = INFO.TENANT_ID AND T.TABLE_ID = INFO.TABLE_ID AND INFO.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = T.TENANT_ID AND DB.DATABASE_ID = T.DATABASE_ID AND T.TABLE_TYPE IN (0, 3, 8, 9, 14, 15) AND T.DATABASE_ID = USERENV('SCHEMAID') AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.DATABASE_NAME != '__recyclebin' LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = T.TABLESPACE_ID AND T.TENANT_ID = TP.TENANT_ID AND TP.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -2151,7 +2151,7 @@ int ObInnerTableSchema::user_segments_schema(ObTableSchema &table_schema) 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 CAST(CASE WHEN A.TABLE_TYPE = 5 AND A.DATABASE_ID != 201004 THEN SUBSTR(A.SEGMENT_NAME, 7 + INSTR(SUBSTR(A.SEGMENT_NAME, 7), '_')) ELSE A.SEGMENT_NAME END AS VARCHAR2(128)) AS SEGMENT_NAME ,CAST(A.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME ,CAST(A.SEGMENT_TYPE AS VARCHAR2(18)) AS SEGMENT_TYPE ,CAST(NULL AS VARCHAR2(10)) AS SEGMENT_SUBTYPE ,CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME ,CAST(NULL AS NUMBER) AS HEADER_FILE ,CAST(NULL AS NUMBER) AS HEADER_BLOCK ,CAST(A.DATA_SIZE AS NUMBER) AS BYTES ,CAST(A.BLOCK_SIZE AS NUMBER) AS BLOCKS ,CAST(NULL AS NUMBER) AS EXTENTS ,CAST(NULL AS NUMBER) AS INITIAL_EXTENT ,CAST(NULL AS NUMBER) AS NEXT_EXTENT ,CAST(NULL AS NUMBER) AS MIN_EXTENTS ,CAST(NULL AS NUMBER) AS MAX_EXTENTS ,CAST(NULL AS NUMBER) AS MAX_SIZE ,CAST(NULL AS VARCHAR(7)) AS RETENTION ,CAST(NULL AS NUMBER) AS MINRETENTION ,CAST(NULL AS NUMBER) AS PCT_INCREASE ,CAST(NULL AS NUMBER) AS FREELISTS ,CAST(NULL AS NUMBER) AS FREELIST_GROUPS ,CAST(NULL AS NUMBER) AS RELATIVE_FNO ,CAST('DEFAULT' AS VARCHAR2(7)) AS BUFFER_POOL ,CAST('DEFAULT' AS VARCHAR2(7)) AS FLASH_CACHE ,CAST('DEFAULT' AS VARCHAR2(7)) AS CELL_FLASH_CACHE ,CAST(NULL AS VARCHAR2(8)) AS INMEMORY ,CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY ,CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE ,CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE ,CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION ,CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY FROM ( SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,NULL PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM (SELECT TENANT_ID, TABLE_ID, DATABASE_ID, TABLE_NAME, TABLE_TYPE, BLOCK_SIZE, PART_LEVEL FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION SELECT TENANT_ID, TABLE_ID, DATABASE_ID, TABLE_NAME, TABLE_TYPE, BLOCK_SIZE, PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE bitand((TABLE_MODE / 4096), 15) IN (0,1)) T LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT WHERE PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) TS ON T.TABLE_ID = TS.TABLE_ID AND T.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 0 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,P.PART_NAME PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE PARTITION' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX PARTITION' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND P.TENANT_ID = T.TENANT_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PARTITION_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT) TS ON P.TABLE_ID = TS.TABLE_ID AND P.PART_ID = TS.PARTITION_ID AND P.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,SUBP.SUB_PART_NAME PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE SUBPARTITION' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX SUBPARTITION' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP ON P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND P.TENANT_ID = SUBP.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PARTITION_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT) TS ON SUBP.TABLE_ID = TS.TABLE_ID AND SUBP.SUB_PART_ID = TS.PARTITION_ID AND SUBP.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() )A WHERE DATABASE_ID=USERENV('SCHEMAID') )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(CASE WHEN A.TABLE_TYPE = 5 AND A.DATABASE_ID != 201004 THEN SUBSTR(A.SEGMENT_NAME, 7 + INSTR(SUBSTR(A.SEGMENT_NAME, 7), '_')) ELSE A.SEGMENT_NAME END AS VARCHAR2(128)) AS SEGMENT_NAME ,CAST(A.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME ,CAST(A.SEGMENT_TYPE AS VARCHAR2(18)) AS SEGMENT_TYPE ,CAST(NULL AS VARCHAR2(10)) AS SEGMENT_SUBTYPE ,CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME ,CAST(NULL AS NUMBER) AS HEADER_FILE ,CAST(NULL AS NUMBER) AS HEADER_BLOCK ,CAST(A.DATA_SIZE AS NUMBER) AS BYTES ,CAST(A.BLOCK_SIZE AS NUMBER) AS BLOCKS ,CAST(NULL AS NUMBER) AS EXTENTS ,CAST(NULL AS NUMBER) AS INITIAL_EXTENT ,CAST(NULL AS NUMBER) AS NEXT_EXTENT ,CAST(NULL AS NUMBER) AS MIN_EXTENTS ,CAST(NULL AS NUMBER) AS MAX_EXTENTS ,CAST(NULL AS NUMBER) AS MAX_SIZE ,CAST(NULL AS VARCHAR(7)) AS RETENTION ,CAST(NULL AS NUMBER) AS MINRETENTION ,CAST(NULL AS NUMBER) AS PCT_INCREASE ,CAST(NULL AS NUMBER) AS FREELISTS ,CAST(NULL AS NUMBER) AS FREELIST_GROUPS ,CAST(NULL AS NUMBER) AS RELATIVE_FNO ,CAST('DEFAULT' AS VARCHAR2(7)) AS BUFFER_POOL ,CAST('DEFAULT' AS VARCHAR2(7)) AS FLASH_CACHE ,CAST('DEFAULT' AS VARCHAR2(7)) AS CELL_FLASH_CACHE ,CAST(NULL AS VARCHAR2(8)) AS INMEMORY ,CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY ,CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE ,CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE ,CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION ,CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY FROM ( SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,NULL PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM (SELECT TENANT_ID, TABLE_ID, DATABASE_ID, TABLE_NAME, TABLE_TYPE, BLOCK_SIZE, PART_LEVEL FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION SELECT TENANT_ID, TABLE_ID, DATABASE_ID, TABLE_NAME, TABLE_TYPE, BLOCK_SIZE, PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE bitand((TABLE_MODE / 4096), 15) IN (0,1)) T LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT WHERE PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) TS ON T.TABLE_ID = TS.TABLE_ID AND T.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 0 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,P.PART_NAME PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE PARTITION' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX PARTITION' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND P.TENANT_ID = T.TENANT_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PARTITION_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT) TS ON P.TABLE_ID = TS.TABLE_ID AND P.PART_ID = TS.PARTITION_ID AND P.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,SUBP.SUB_PART_NAME PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE SUBPARTITION' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX SUBPARTITION' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP ON P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND P.TENANT_ID = SUBP.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PARTITION_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT) TS ON SUBP.TABLE_ID = TS.TABLE_ID AND SUBP.SUB_PART_ID = TS.PARTITION_ID AND SUBP.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 )A WHERE DATABASE_ID=USERENV('SCHEMAID') )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -2202,7 +2202,7 @@ int ObInnerTableSchema::dba_segments_schema(ObTableSchema &table_schema) 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 CAST(B.DATABASE_NAME AS VARCHAR2(128)) AS OWNER ,CAST(CASE WHEN A.TABLE_TYPE = 5 AND B.DATABASE_NAME != '__recyclebin' THEN SUBSTR(A.SEGMENT_NAME, 7 + INSTR(SUBSTR(A.SEGMENT_NAME, 7), '_')) ELSE A.SEGMENT_NAME END AS VARCHAR2(128)) AS SEGMENT_NAME ,CAST(A.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME ,CAST(A.SEGMENT_TYPE AS VARCHAR2(18)) AS SEGMENT_TYPE ,CAST(NULL AS VARCHAR2(10)) AS SEGMENT_SUBTYPE ,CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME ,CAST(NULL AS NUMBER) AS HEADER_FILE ,CAST(NULL AS NUMBER) AS HEADER_BLOCK ,CAST(A.DATA_SIZE AS NUMBER) AS BYTES ,CAST(A.BLOCK_SIZE AS NUMBER) AS BLOCKS ,CAST(NULL AS NUMBER) AS EXTENTS ,CAST(NULL AS NUMBER) AS INITIAL_EXTENT ,CAST(NULL AS NUMBER) AS NEXT_EXTENT ,CAST(NULL AS NUMBER) AS MIN_EXTENTS ,CAST(NULL AS NUMBER) AS MAX_EXTENTS ,CAST(NULL AS NUMBER) AS MAX_SIZE ,CAST(NULL AS VARCHAR(7)) AS RETENTION ,CAST(NULL AS NUMBER) AS MINRETENTION ,CAST(NULL AS NUMBER) AS PCT_INCREASE ,CAST(NULL AS NUMBER) AS FREELISTS ,CAST(NULL AS NUMBER) AS FREELIST_GROUPS ,CAST(NULL AS NUMBER) AS RELATIVE_FNO ,CAST('DEFAULT' AS VARCHAR2(7)) AS BUFFER_POOL ,CAST('DEFAULT' AS VARCHAR2(7)) AS FLASH_CACHE ,CAST('DEFAULT' AS VARCHAR2(7)) AS CELL_FLASH_CACHE ,CAST(NULL AS VARCHAR2(8)) AS INMEMORY ,CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY ,CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE ,CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE ,CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION ,CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY FROM ( SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,NULL PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM (SELECT TENANT_ID, TABLE_ID, DATABASE_ID, TABLE_NAME, TABLE_TYPE, BLOCK_SIZE, PART_LEVEL FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION SELECT TENANT_ID, TABLE_ID, DATABASE_ID, TABLE_NAME, TABLE_TYPE, BLOCK_SIZE, PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE bitand((TABLE_MODE / 4096), 15) IN (0,1)) T LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT WHERE PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) TS ON T.TABLE_ID = TS.TABLE_ID AND T.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 0 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,P.PART_NAME PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE PARTITION' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX PARTITION' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND P.TENANT_ID = T.TENANT_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PARTITION_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT) TS ON P.TABLE_ID = TS.TABLE_ID AND P.PART_ID = TS.PARTITION_ID AND P.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,SUBP.SUB_PART_NAME PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE SUBPARTITION' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX SUBPARTITION' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP ON P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND P.TENANT_ID = SUBP.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PARTITION_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT) TS ON SUBP.TABLE_ID = TS.TABLE_ID AND SUBP.SUB_PART_ID = TS.PARTITION_ID AND SUBP.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() )A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(B.DATABASE_NAME AS VARCHAR2(128)) AS OWNER ,CAST(CASE WHEN A.TABLE_TYPE = 5 AND B.DATABASE_NAME != '__recyclebin' THEN SUBSTR(A.SEGMENT_NAME, 7 + INSTR(SUBSTR(A.SEGMENT_NAME, 7), '_')) ELSE A.SEGMENT_NAME END AS VARCHAR2(128)) AS SEGMENT_NAME ,CAST(A.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME ,CAST(A.SEGMENT_TYPE AS VARCHAR2(18)) AS SEGMENT_TYPE ,CAST(NULL AS VARCHAR2(10)) AS SEGMENT_SUBTYPE ,CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME ,CAST(NULL AS NUMBER) AS HEADER_FILE ,CAST(NULL AS NUMBER) AS HEADER_BLOCK ,CAST(A.DATA_SIZE AS NUMBER) AS BYTES ,CAST(A.BLOCK_SIZE AS NUMBER) AS BLOCKS ,CAST(NULL AS NUMBER) AS EXTENTS ,CAST(NULL AS NUMBER) AS INITIAL_EXTENT ,CAST(NULL AS NUMBER) AS NEXT_EXTENT ,CAST(NULL AS NUMBER) AS MIN_EXTENTS ,CAST(NULL AS NUMBER) AS MAX_EXTENTS ,CAST(NULL AS NUMBER) AS MAX_SIZE ,CAST(NULL AS VARCHAR(7)) AS RETENTION ,CAST(NULL AS NUMBER) AS MINRETENTION ,CAST(NULL AS NUMBER) AS PCT_INCREASE ,CAST(NULL AS NUMBER) AS FREELISTS ,CAST(NULL AS NUMBER) AS FREELIST_GROUPS ,CAST(NULL AS NUMBER) AS RELATIVE_FNO ,CAST('DEFAULT' AS VARCHAR2(7)) AS BUFFER_POOL ,CAST('DEFAULT' AS VARCHAR2(7)) AS FLASH_CACHE ,CAST('DEFAULT' AS VARCHAR2(7)) AS CELL_FLASH_CACHE ,CAST(NULL AS VARCHAR2(8)) AS INMEMORY ,CAST(NULL AS VARCHAR2(8)) AS INMEMORY_PRIORITY ,CAST(NULL AS VARCHAR2(15)) AS INMEMORY_DISTRIBUTE ,CAST(NULL AS VARCHAR2(13)) AS INMEMORY_DUPLICATE ,CAST(NULL AS VARCHAR2(17)) AS INMEMORY_COMPRESSION ,CAST(NULL AS VARCHAR2(24)) AS CELLMEMORY FROM ( SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,NULL PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM (SELECT TENANT_ID, TABLE_ID, DATABASE_ID, TABLE_NAME, TABLE_TYPE, BLOCK_SIZE, PART_LEVEL FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE UNION SELECT TENANT_ID, TABLE_ID, DATABASE_ID, TABLE_NAME, TABLE_TYPE, BLOCK_SIZE, PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE bitand((TABLE_MODE / 4096), 15) IN (0,1)) T LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT WHERE PARTITION_ID = -1 OR PARTITION_ID = TABLE_ID) TS ON T.TABLE_ID = TS.TABLE_ID AND T.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 0 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,P.PART_NAME PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE PARTITION' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX PARTITION' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND P.TENANT_ID = T.TENANT_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PARTITION_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT) TS ON P.TABLE_ID = TS.TABLE_ID AND P.PART_ID = TS.PARTITION_ID AND P.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TABLE_ID ,T.DATABASE_ID ,T.TABLE_NAME SEGMENT_NAME ,SUBP.SUB_PART_NAME PARTITION_NAME ,CASE WHEN T.TABLE_TYPE IN (0, 3, 8, 9) THEN 'TABLE SUBPARTITION' WHEN T.TABLE_TYPE IN (5) THEN 'INDEX SUBPARTITION' ELSE NULL END AS SEGMENT_TYPE ,T.BLOCK_SIZE ,TS.DATA_SIZE ,T.TABLE_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SUBP ON P.TABLE_ID = SUBP.TABLE_ID AND P.PART_ID = SUBP.PART_ID AND P.TENANT_ID = SUBP.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PARTITION_ID, (MACRO_BLK_CNT * 2 * 1024 * 1024) AS DATA_SIZE FROM SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT) TS ON SUBP.TABLE_ID = TS.TABLE_ID AND SUBP.SUB_PART_ID = TS.PARTITION_ID AND SUBP.TENANT_ID = TS.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.PARTITION_TYPE =0 AND P.PARTITION_TYPE = 0 )A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.25051_25100.cpp b/src/share/inner_table/ob_inner_table_schema.25051_25100.cpp index 51b79eb40..f774cf050 100644 --- a/src/share/inner_table/ob_inner_table_schema.25051_25100.cpp +++ b/src/share/inner_table/ob_inner_table_schema.25051_25100.cpp @@ -1131,7 +1131,7 @@ int ObInnerTableSchema::all_tab_partitions_ora_schema(ObTableSchema &table_schem 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 CAST(DB_TB.DATABASE_NAME AS VARCHAR2(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST(NULL AS VARCHAR2(3)) IS_NESTED, CAST(NULL AS VARCHAR2(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(4)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(4)) INDEXING, CAST(NULL AS VARCHAR2(4)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND (TB.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, TB.TABLE_ID, TB.DATABASE_ID) = 1) ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.DATABASE_NAME AS VARCHAR2(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST(NULL AS VARCHAR2(3)) IS_NESTED, CAST(NULL AS VARCHAR2(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(4)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(4)) INDEXING, CAST(NULL AS VARCHAR2(4)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND (TB.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, TB.TABLE_ID, TB.DATABASE_ID) = 1) ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() AND PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1182,7 +1182,7 @@ int ObInnerTableSchema::all_tab_subpartitions_ora_schema(ObTableSchema &table_sc 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 CAST(DB_TB.DATABASE_NAME AS VARCHAR2(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST('NO' AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(3)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) INDEXING, CAST(NULL AS VARCHAR2(3)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND (TB.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, TB.TABLE_ID, TB.DATABASE_ID) = 1)) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.DATABASE_NAME AS VARCHAR2(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST('NO' AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(3)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) INDEXING, CAST(NULL AS VARCHAR2(3)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND (TB.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, TB.TABLE_ID, TB.DATABASE_ID) = 1)) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1386,7 +1386,7 @@ int ObInnerTableSchema::dba_tab_partitions_ora_schema(ObTableSchema &table_schem 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 CAST(DB_TB.DATABASE_NAME AS VARCHAR2(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST(NULL AS VARCHAR2(3)) IS_NESTED, CAST(NULL AS VARCHAR2(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(4)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(4)) INDEXING, CAST(NULL AS VARCHAR2(4)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.DATABASE_NAME AS VARCHAR2(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST(NULL AS VARCHAR2(3)) IS_NESTED, CAST(NULL AS VARCHAR2(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(4)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(4)) INDEXING, CAST(NULL AS VARCHAR2(4)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() AND PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1437,7 +1437,7 @@ int ObInnerTableSchema::user_tab_partitions_ora_schema(ObTableSchema &table_sche 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 CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST(NULL AS VARCHAR2(3)) IS_NESTED, CAST(NULL AS VARCHAR2(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(4)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(4)) INDEXING, CAST(NULL AS VARCHAR2(4)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND TB.DATABASE_ID = USERENV('SCHEMAID') ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(CASE DB_TB.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST(NULL AS VARCHAR2(3)) IS_NESTED, CAST(NULL AS VARCHAR2(128)) PARENT_TABLE_PARTITION, CAST (CASE WHEN PART.PARTITION_POSITION > MAX (CASE WHEN PART.HIGH_BOUND_VAL = DB_TB.B_TRANSITION_POINT THEN PART.PARTITION_POSITION ELSE NULL END) OVER(PARTITION BY DB_TB.TABLE_ID) THEN 'YES' ELSE 'NO' END AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(4)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(4)) INDEXING, CAST(NULL AS VARCHAR2(4)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(100)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME, TB.B_TRANSITION_POINT, TB.PART_LEVEL FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND TB.DATABASE_ID = USERENV('SCHEMAID') ) DB_TB JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND PART.TENANT_ID = DB_TB.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() AND PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1488,7 +1488,7 @@ int ObInnerTableSchema::dba_tab_subpartitions_ora_schema(ObTableSchema &table_sc 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 CAST(DB_TB.DATABASE_NAME AS VARCHAR2(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST('NO' AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(3)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) INDEXING, CAST(NULL AS VARCHAR2(3)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9)) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.DATABASE_NAME AS VARCHAR2(128)) TABLE_OWNER, CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST('NO' AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(3)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) INDEXING, CAST(NULL AS VARCHAR2(3)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9)) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1539,7 +1539,7 @@ int ObInnerTableSchema::user_tab_subpartitions_ora_schema(ObTableSchema &table_s 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 CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST('NO' AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(3)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) INDEXING, CAST(NULL AS VARCHAR2(3)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND TB.DATABASE_ID = USERENV('SCHEMAID')) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(DB_TB.TABLE_NAME AS VARCHAR2(128)) TABLE_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(TP.TABLESPACE_NAME AS VARCHAR2(30)) TABLESPACE_NAME, CAST(NULL AS NUMBER) PCT_FREE, CAST(NULL AS NUMBER) PCT_USED, CAST(NULL AS NUMBER) INI_TRANS, CAST(NULL AS NUMBER) MAX_TRANS, CAST(NULL AS NUMBER) INITIAL_EXTENT, CAST(NULL AS NUMBER) NEXT_EXTENT, CAST(NULL AS NUMBER) MIN_EXTENT, CAST(NULL AS NUMBER) MAX_EXTENT, CAST(NULL AS NUMBER) MAX_SIZE, CAST(NULL AS NUMBER) PCT_INCREASE, CAST(NULL AS NUMBER) FREELISTS, CAST(NULL AS NUMBER) FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(8)) COMPRESSION, CAST(PART.COMPRESS_FUNC_NAME AS VARCHAR2(30)) COMPRESS_FOR, CAST(NULL AS NUMBER) NUM_ROWS, CAST(NULL AS NUMBER) BLOCKS, CAST(NULL AS NUMBER) EMPTY_BLOCKS, CAST(NULL AS NUMBER) AVG_SPACE, CAST(NULL AS NUMBER) CHAIN_CNT, CAST(NULL AS NUMBER) AVG_ROW_LEN, CAST(NULL AS NUMBER) SAMPLE_SIZE, CAST(NULL AS DATE) LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) GLOBAL_STATS, CAST(NULL AS VARCHAR2(3)) USER_STATS, CAST('NO' AS VARCHAR2(3)) "INTERVAL", CAST(NULL AS VARCHAR2(3)) SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) INDEXING, CAST(NULL AS VARCHAR2(3)) READ_ONLY, CAST(NULL AS VARCHAR2(8)) INMEMORY, CAST(NULL AS VARCHAR2(8)) INMEMORY_PRIORITY, CAST(NULL AS VARCHAR2(15)) INMEMORY_DISTRIBUTE, CAST(NULL AS VARCHAR2(17)) INMEMORY_COMPRESSION, CAST(NULL AS VARCHAR2(13)) INMEMORY_DUPLICATE, CAST(NULL AS VARCHAR2(12)) INMEMORY_SERVICE, CAST(NULL AS VARCHAR2(1000)) INMEMORY_SERVICE_NAME, CAST(NULL AS VARCHAR2(24)) CELLMEMORY, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_READ, CAST(NULL AS VARCHAR2(8)) MEMOPTIMIZE_WRITE FROM (SELECT DB.TENANT_ID, DB.DATABASE_NAME, DB.DATABASE_ID, TB.TABLE_ID, TB.TABLE_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT TB, SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB WHERE TB.DATABASE_ID = DB.DATABASE_ID AND bitand((TB.TABLE_MODE / 4096), 15) IN (0,1) AND TB.TENANT_ID = DB.TENANT_ID AND TB.TABLE_TYPE IN (3, 8, 9) AND TB.DATABASE_ID = USERENV('SCHEMAID')) DB_TB JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.TABLESPACE_ID, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TENANT_TABLESPACE_REAL_AGENT TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.25101_25150.cpp b/src/share/inner_table/ob_inner_table_schema.25101_25150.cpp index 9a451267d..4b254e61d 100644 --- a/src/share/inner_table/ob_inner_table_schema.25101_25150.cpp +++ b/src/share/inner_table/ob_inner_table_schema.25101_25150.cpp @@ -825,7 +825,7 @@ int ObInnerTableSchema::all_ind_partitions_schema(ObTableSchema &table_schema) 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 CAST(D.DATABASE_NAME AS VARCHAR2(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS NUMBER) AS PCT_DIRECT_ACCESS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) AS ORPHANED_ENTRIES FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND (I.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, I.DATA_TABLE_ID, I.DATABASE_ID) = 1) JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(D.DATABASE_NAME AS VARCHAR2(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS NUMBER) AS PCT_DIRECT_ACCESS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) AS ORPHANED_ENTRIES FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND (I.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, I.DATA_TABLE_ID, I.DATABASE_ID) = 1) JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() AND PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -876,7 +876,7 @@ int ObInnerTableSchema::user_ind_partitions_schema(ObTableSchema &table_schema) 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 CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS NUMBER) AS PCT_DIRECT_ACCESS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) AS ORPHANED_ENTRIES FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND I.DATABASE_ID = USERENV('SCHEMAID') JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS NUMBER) AS PCT_DIRECT_ACCESS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) AS ORPHANED_ENTRIES FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND I.DATABASE_ID = USERENV('SCHEMAID') JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() AND PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -927,7 +927,7 @@ int ObInnerTableSchema::dba_ind_partitions_ora_schema(ObTableSchema &table_schem 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 CAST(D.DATABASE_NAME AS VARCHAR2(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS NUMBER) AS PCT_DIRECT_ACCESS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) AS ORPHANED_ENTRIES FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(D.DATABASE_NAME AS VARCHAR2(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN 'YES' ELSE 'NO' END AS CHAR(3)) COMPOSITE, CAST(PART.PART_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(CASE I.PART_LEVEL WHEN 2 THEN PART.SUB_PART_NUM ELSE 0 END AS NUMBER) SUBPARTITION_COUNT, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(7)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS NUMBER) AS PCT_DIRECT_ACCESS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(3)) AS ORPHANED_ENTRIES FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 JOIN (SELECT TENANT_ID, TABLE_ID, PART_NAME, SUB_PART_NUM, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() AND PART.PARTITION_TYPE = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -978,7 +978,7 @@ int ObInnerTableSchema::dba_ind_subpartitions_ora_schema(ObTableSchema &table_sc 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 CAST(D.DATABASE_NAME AS VARCHAR2(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(D.DATABASE_NAME AS VARCHAR2(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1029,7 +1029,7 @@ int ObInnerTableSchema::all_ind_subpartitions_schema(ObTableSchema &table_schema 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 CAST(D.DATABASE_NAME AS VARCHAR2(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND (I.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, I.DATA_TABLE_ID, I.DATABASE_ID) = 1) JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(D.DATABASE_NAME AS VARCHAR2(128)) AS INDEX_OWNER, CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND (I.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, I.DATA_TABLE_ID, I.DATABASE_ID) = 1) JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1080,7 +1080,7 @@ int ObInnerTableSchema::user_ind_subpartitions_schema(ObTableSchema &table_schem 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 CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND I.DATABASE_ID = USERENV('SCHEMAID') JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT CAST(CASE WHEN D.DATABASE_NAME = '__recyclebin' THEN I.TABLE_NAME ELSE SUBSTR(I.TABLE_NAME, 7 + INSTR(SUBSTR(I.TABLE_NAME, 7), '_')) END AS VARCHAR2(128)) AS INDEX_NAME, CAST(PART.PART_NAME AS VARCHAR2(128)) PARTITION_NAME, CAST(PART.SUB_PART_NAME AS VARCHAR2(128)) SUBPARTITION_NAME, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN PART.HIGH_BOUND_VAL ELSE PART.LIST_VAL END AS VARCHAR(32767)) HIGH_VALUE, CAST(CASE WHEN length(PART.HIGH_BOUND_VAL) > 0 THEN length(PART.HIGH_BOUND_VAL) ELSE length(PART.LIST_VAL) END AS NUMBER) HIGH_VALUE_LENGTH, CAST(PART.PARTITION_POSITION AS NUMBER) PARTITION_POSITION, CAST(PART.SUBPARTITION_POSITION AS NUMBER) SUBPARTITION_POSITION, CAST(NULL AS VARCHAR2(8)) AS STATUS, CAST(NULL AS VARCHAR2(30)) AS TABLESPACE_NAME, CAST(NULL AS NUMBER) AS PCT_FREE, CAST(NULL AS NUMBER) AS INI_TRANS, CAST(NULL AS NUMBER) AS MAX_TRANS, CAST(NULL AS NUMBER) AS INITIAL_EXTENT, CAST(NULL AS NUMBER) AS NEXT_EXTENT, CAST(NULL AS NUMBER) AS MIN_EXTENT, CAST(NULL AS NUMBER) AS MAX_EXTENT, CAST(NULL AS NUMBER) AS MAX_SIZE, CAST(NULL AS NUMBER) AS PCT_INCREASE, CAST(NULL AS NUMBER) AS FREELISTS, CAST(NULL AS NUMBER) AS FREELIST_GROUPS, CAST(NULL AS VARCHAR2(3)) AS LOGGING, CAST(CASE WHEN PART.COMPRESS_FUNC_NAME IS NULL THEN 'DISABLED' ELSE 'ENABLED' END AS VARCHAR2(13)) AS COMPRESSION, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(NULL AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(NULL AS DATE) AS LAST_ANALYZED, CAST(NULL AS VARCHAR2(7)) AS BUFFER_POOL, CAST(NULL AS VARCHAR2(7)) AS FLASH_CACHE, CAST(NULL AS VARCHAR2(7)) AS CELL_FLASH_CACHE, CAST(NULL AS VARCHAR2(3)) AS USER_STATS, CAST(NULL AS VARCHAR2(3)) AS GLOBAL_STATS, CAST('NO' AS VARCHAR2(3)) AS "INTERVAL", CAST(NULL AS VARCHAR2(3)) AS SEGMENT_CREATED, CAST(NULL AS VARCHAR2(6)) AS DOMIDX_OPSTATUS, CAST(NULL AS VARCHAR2(1000)) AS PARAMETERS FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT I JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON I.TENANT_ID = D.TENANT_ID AND bitand((I.TABLE_MODE / 4096), 15) IN (0,1) AND I.DATABASE_ID = D.DATABASE_ID AND I.TABLE_TYPE = 5 AND I.DATABASE_ID = USERENV('SCHEMAID') JOIN (SELECT P_PART.TENANT_ID, P_PART.TABLE_ID, P_PART.PART_NAME, P_PART.PARTITION_POSITION, S_PART.SUB_PART_NAME, S_PART.HIGH_BOUND_VAL, S_PART.LIST_VAL, S_PART.COMPRESS_FUNC_NAME, S_PART.SUBPARTITION_POSITION FROM (SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC ) AS PARTITION_POSITION FROM SYS.ALL_VIRTUAL_PART_REAL_AGENT) P_PART, (SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC ) AS SUBPARTITION_POSITION FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID AND P_PART.TENANT_ID = S_PART.TENANT_ID AND P_PART.PARTITION_TYPE = 0 AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.25151_25200.cpp b/src/share/inner_table/ob_inner_table_schema.25151_25200.cpp index f95139a8c..893ce68c6 100644 --- a/src/share/inner_table/ob_inner_table_schema.25151_25200.cpp +++ b/src/share/inner_table/ob_inner_table_schema.25151_25200.cpp @@ -1233,7 +1233,7 @@ int ObInnerTableSchema::all_ind_statistics_ora_schema(ObTableSchema &table_schem 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 CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(V.INDEX_NAME AS VARCHAR2(128)) AS INDEX_NAME, CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS TABLE_OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( (SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, TABLE_ID AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, P.PART_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID AND T.TENANT_ID = V.TENANT_ID AND T.DATABASE_ID = V.DATABASE_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID AND (V.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, V.TABLE_ID, V.DATABASE_ID) = 1) AND V.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID AND STAT.INDEX_TYPE = 1; )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(V.INDEX_NAME AS VARCHAR2(128)) AS INDEX_NAME, CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS TABLE_OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( (SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, TABLE_ID AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, P.PART_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) WHERE T.TABLE_TYPE = 5 AND P.PARTITION_TYPE = 0 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE = 5 AND P.PARTITION_TYPE = 0 AND SP.PARTITION_TYPE = 0 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID AND T.TENANT_ID = V.TENANT_ID AND T.DATABASE_ID = V.DATABASE_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID AND (V.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, V.TABLE_ID, V.DATABASE_ID) = 1) AND V.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID AND STAT.INDEX_TYPE = 1; )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1284,7 +1284,7 @@ int ObInnerTableSchema::dba_ind_statistics_ora_schema(ObTableSchema &table_schem 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 CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(V.INDEX_NAME AS VARCHAR2(128)) AS INDEX_NAME, CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS TABLE_OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( (SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, TABLE_ID AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, P.PART_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID AND T.TENANT_ID = V.TENANT_ID AND T.DATABASE_ID = V.DATABASE_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID AND STAT.INDEX_TYPE = 1; )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(V.INDEX_NAME AS VARCHAR2(128)) AS INDEX_NAME, CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS TABLE_OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( (SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, TABLE_ID AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, P.PART_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) WHERE T.TABLE_TYPE = 5 AND P.PARTITION_TYPE = 0 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE = 5 AND P.PARTITION_TYPE = 0 AND SP.PARTITION_TYPE = 0 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID AND T.TENANT_ID = V.TENANT_ID AND T.DATABASE_ID = V.DATABASE_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID AND STAT.INDEX_TYPE = 1; )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1335,7 +1335,7 @@ int ObInnerTableSchema::user_ind_statistics_ora_schema(ObTableSchema &table_sche 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 CAST(V.INDEX_NAME AS VARCHAR2(128)) AS INDEX_NAME, CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS TABLE_OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.DATABASE_ID = USERENV('SCHEMAID') AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, P.PART_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.DATABASE_ID = USERENV('SCHEMAID') UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.DATABASE_ID = USERENV('SCHEMAID') ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID AND T.TENANT_ID = V.TENANT_ID AND T.DATABASE_ID = V.DATABASE_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID AND STAT.INDEX_TYPE = 1; WHERE T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST(V.INDEX_NAME AS VARCHAR2(128)) AS INDEX_NAME, CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS TABLE_OWNER, CAST(T.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(NULL AS NUMBER) AS BLEVEL, CAST(NULL AS NUMBER) AS LEAF_BLOCKS, CAST(NULL AS NUMBER) AS DISTINCT_KEYS, CAST(NULL AS NUMBER) AS AVG_LEAF_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS AVG_DATA_BLOCKS_PER_KEY, CAST(NULL AS NUMBER) AS CLUSTERING_FACTOR, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_ID, DATA_TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) AS INDEX_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'INDEX' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.DATABASE_ID = USERENV('SCHEMAID') AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, P.PART_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) WHERE T.TABLE_TYPE = 5 AND T.DATABASE_ID = USERENV('SCHEMAID') AND P.PARTITION_TYPE = 0 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, T.DATA_TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, SUBSTR(T.TABLE_NAME, 7 + INSTR(SUBSTR(T.TABLE_NAME, 7), '_')) AS INDEX_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE = 5 AND T.DATABASE_ID = USERENV('SCHEMAID') AND P.PARTITION_TYPE = 0 AND SP.PARTITION_TYPE = 0 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID AND T.TENANT_ID = V.TENANT_ID AND T.DATABASE_ID = V.DATABASE_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID AND STAT.INDEX_TYPE = 1; WHERE T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.28051_28100.cpp b/src/share/inner_table/ob_inner_table_schema.28051_28100.cpp index a0eee2c1c..5e9238d30 100644 --- a/src/share/inner_table/ob_inner_table_schema.28051_28100.cpp +++ b/src/share/inner_table/ob_inner_table_schema.28051_28100.cpp @@ -1233,7 +1233,7 @@ int ObInnerTableSchema::all_part_col_statistics_ora_schema(ObTableSchema &table_ 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 cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND (t.database_id = userenv('SCHEMAID') OR user_can_access_obj(1, t.table_id, t.database_id) = 1) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND part.part_id = stat.partition_id AND stat.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND (t.database_id = userenv('SCHEMAID') OR user_can_access_obj(1, t.table_id, t.database_id) = 1) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND part.part_id = stat.partition_id AND stat.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND part.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1284,7 +1284,7 @@ int ObInnerTableSchema::dba_part_col_statistics_ora_schema(ObTableSchema &table_ 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 cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND part.part_id = stat.partition_id AND stat.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND part.part_id = stat.partition_id AND stat.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND part.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1335,7 +1335,7 @@ int ObInnerTableSchema::user_part_col_statistics_ora_schema(ObTableSchema &table 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 cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND part.part_id = stat.partition_id AND stat.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND part.part_id = stat.partition_id AND stat.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND part.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1386,7 +1386,7 @@ int ObInnerTableSchema::all_subpart_col_statistics_ora_schema(ObTableSchema &tab 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 cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND (t.database_id = userenv('SCHEMAID') OR user_can_access_obj(1, t.table_id, t.database_id) = 1) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND stat.partition_id = subpart.sub_part_id AND stat.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND (t.database_id = userenv('SCHEMAID') OR user_can_access_obj(1, t.table_id, t.database_id) = 1) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND stat.partition_id = subpart.sub_part_id AND stat.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND subpart.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1437,7 +1437,7 @@ int ObInnerTableSchema::dba_subpart_col_statistics_ora_schema(ObTableSchema &tab 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 cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND stat.partition_id = subpart.sub_part_id AND stat.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND stat.partition_id = subpart.sub_part_id AND stat.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND subpart.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1488,7 +1488,7 @@ int ObInnerTableSchema::user_subpart_col_statistics_ora_schema(ObTableSchema &ta 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 cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND stat.partition_id = subpart.sub_part_id AND stat.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast (subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(stat.distinct_cnt as NUMBER) as NUM_DISTINCT, cast(stat.min_value as /* TODO: RAW */ varchar(128)) as LOW_VALUE, cast(stat.max_value as /* TODO: RAW */ varchar(128)) as HIGH_VALUE, cast(stat.density as NUMBER) as DENSITY, cast(stat.null_cnt as NUMBER) as NUM_NULLS, cast(stat.bucket_cnt as NUMBER) as NUM_BUCKETS, cast(stat.sample_size as NUMBER) as SAMPLE_SIZE, cast(stat.last_analyzed as DATE) as LAST_ANALYZED, CAST(decode(stat.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(stat.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, cast(NULL as VARCHAR2(80)) as NOTES, cast(stat.avg_len as NUMBER) as AVG_COL_LEN, cast((case when stat.histogram_type = 1 then 'FREQUENCY' when stat.histogram_type = 3 then 'TOP-FREQUENCY' when stat.histogram_type = 4 then 'HYBRID' else NULL end) as VARCHAR2(15)) as HISTOGRAM FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id left join SYS.ALL_VIRTUAL_COLUMN_STAT_REAL_AGENT stat ON c.table_id = stat.table_id AND c.column_id = stat.column_id AND stat.partition_id = subpart.sub_part_id AND stat.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND subpart.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1692,7 +1692,7 @@ int ObInnerTableSchema::all_part_histograms_ora_schema(ObTableSchema &table_sche 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 cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND (t.database_id = userenv('SCHEMAID') OR user_can_access_obj(1, t.table_id, t.database_id) = 1) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND part.part_id = hist.partition_id AND hist.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND (t.database_id = userenv('SCHEMAID') OR user_can_access_obj(1, t.table_id, t.database_id) = 1) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND part.part_id = hist.partition_id AND hist.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND part.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1743,7 +1743,7 @@ int ObInnerTableSchema::dba_part_histograms_ora_schema(ObTableSchema &table_sche 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 cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND part.part_id = hist.partition_id AND hist.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND part.part_id = hist.partition_id AND hist.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND part.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1794,7 +1794,7 @@ int ObInnerTableSchema::user_part_histograms_ora_schema(ObTableSchema &table_sch 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 cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND part.part_id = hist.partition_id AND hist.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(part.part_name as VARCHAR2(128)) as PARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT part on t.tenant_id = part.tenant_id and t.table_id = part.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND part.part_id = hist.partition_id AND hist.object_type = 2 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND part.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1845,7 +1845,7 @@ int ObInnerTableSchema::all_subpart_histograms_ora_schema(ObTableSchema &table_s 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 cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND (t.database_id = userenv('SCHEMAID') OR user_can_access_obj(1, t.table_id, t.database_id) = 1) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND hist.partition_id = subpart.sub_part_id AND hist.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND (t.database_id = userenv('SCHEMAID') OR user_can_access_obj(1, t.table_id, t.database_id) = 1) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND hist.partition_id = subpart.sub_part_id AND hist.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND subpart.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1896,7 +1896,7 @@ int ObInnerTableSchema::dba_subpart_histograms_ora_schema(ObTableSchema &table_s 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 cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND hist.partition_id = subpart.sub_part_id AND hist.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(db.database_name as VARCHAR2(128)) as OWNER, cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = t.tenant_id AND db.database_id = t.database_id AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND hist.partition_id = subpart.sub_part_id AND hist.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND subpart.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1947,7 +1947,7 @@ int ObInnerTableSchema::user_subpart_histograms_ora_schema(ObTableSchema &table_ 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 cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND hist.partition_id = subpart.sub_part_id AND hist.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(select cast(t.table_name as VARCHAR2(128)) as TABLE_NAME, cast(subpart.sub_part_name as VARCHAR2(128)) as SUBPARTITION_NAME, cast(c.column_name as VARCHAR2(128)) as COLUMN_NAME, cast(hist.endpoint_num as NUMBER) as ENDPOINT_NUMBER, cast(NULL as NUMBER) as ENDPOINT_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE, cast(hist.endpoint_value as VARCHAR2(4000)) as ENDPOINT_ACTUAL_VALUE_RAW, cast(hist.endpoint_repeat_cnt as NUMBER) as ENDPOINT_REPEAT_COUNT FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT t JOIN SYS.ALL_VIRTUAL_COLUMN_REAL_AGENT c ON c.tenant_id = t.tenant_id AND c.table_id = t.table_id AND C.TENANT_ID = EFFECTIVE_TENANT_ID() JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT subpart on t.tenant_id = subpart.tenant_id and t.table_id = subpart.table_id join SYS.ALL_VIRTUAL_HISTOGRAM_STAT_REAL_AGENT hist ON c.table_id = hist.table_id AND c.column_id = hist.column_id AND hist.partition_id = subpart.sub_part_id AND hist.object_type = 3 WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) AND subpart.partition_type = 0 )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -1998,7 +1998,7 @@ int ObInnerTableSchema::all_tab_statistics_ora_schema(ObTableSchema &table_schem 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 CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(V.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(STAT.AVG_ROW_LEN AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS IM_IMCU_COUNT, CAST(NULL AS NUMBER) AS IM_BLOCK_COUNT, CAST(NULL AS TIMESTAMP(9)) AS IM_STAT_UPDATE_TIME, CAST(NULL AS NUMBER) AS SCAN_RATE, CAST(STAT.SPARE1 AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( (SELECT TENANT_ID, DATABASE_ID, TABLE_ID, TABLE_ID AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLE_TYPE IN (0,2,3,8,9,14,15) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, P.PART_ID, T.TABLE_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, T.TABLE_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) ) V JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID AND (V.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, V.TABLE_ID, V.DATABASE_ID) = 1) AND V.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(V.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(STAT.AVG_ROW_LEN AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS IM_IMCU_COUNT, CAST(NULL AS NUMBER) AS IM_BLOCK_COUNT, CAST(NULL AS TIMESTAMP(9)) AS IM_STAT_UPDATE_TIME, CAST(NULL AS NUMBER) AS SCAN_RATE, CAST(STAT.SPARE1 AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( (SELECT TENANT_ID, DATABASE_ID, TABLE_ID, TABLE_ID AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLE_TYPE IN (0,2,3,8,9,14,15) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, P.PART_ID, T.TABLE_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, T.TABLE_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND P.PARTITION_TYPE = 0 AND SP.PARTITION_TYPE = 0 ) V JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB ON DB.TENANT_ID = V.TENANT_ID AND DB.DATABASE_ID = V.DATABASE_ID AND (V.DATABASE_ID = USERENV('SCHEMAID') OR USER_CAN_ACCESS_OBJ(1, V.TABLE_ID, V.DATABASE_ID) = 1) AND V.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -2049,7 +2049,7 @@ int ObInnerTableSchema::dba_tab_statistics_ora_schema(ObTableSchema &table_schem 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 CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(V.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(STAT.AVG_ROW_LEN AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS IM_IMCU_COUNT, CAST(NULL AS NUMBER) AS IM_BLOCK_COUNT, CAST(NULL AS TIMESTAMP(9)) AS IM_STAT_UPDATE_TIME, CAST(NULL AS NUMBER) AS SCAN_RATE, CAST(STAT.SPARE1 AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( (SELECT TENANT_ID, DATABASE_ID, TABLE_ID, TABLE_ID AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLE_TYPE IN (0,2,3,8,9,14,15) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, P.PART_ID, T.TABLE_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, T.TABLE_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) ) V JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = V.tenant_id AND db.database_id = V.database_id AND V.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST(DB.DATABASE_NAME AS VARCHAR2(128)) AS OWNER, CAST(V.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(STAT.AVG_ROW_LEN AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS IM_IMCU_COUNT, CAST(NULL AS NUMBER) AS IM_BLOCK_COUNT, CAST(NULL AS TIMESTAMP(9)) AS IM_STAT_UPDATE_TIME, CAST(NULL AS NUMBER) AS SCAN_RATE, CAST(STAT.SPARE1 AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( (SELECT TENANT_ID, DATABASE_ID, TABLE_ID, TABLE_ID AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLE_TYPE IN (0,2,3,8,9,14,15) UNION ALL SELECT TENANT_ID, DATABASE_ID, TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1)) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, P.PART_ID, T.TABLE_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, T.TABLE_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND P.PARTITION_TYPE = 0 AND SP.PARTITION_TYPE = 0 ) V JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db ON db.tenant_id = V.tenant_id AND db.database_id = V.database_id AND V.TENANT_ID = EFFECTIVE_TENANT_ID() AND DB.TENANT_ID = EFFECTIVE_TENANT_ID() LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } @@ -2100,7 +2100,7 @@ int ObInnerTableSchema::user_tab_statistics_ora_schema(ObTableSchema &table_sche 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 CAST(V.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(STAT.AVG_ROW_LEN AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS IM_IMCU_COUNT, CAST(NULL AS NUMBER) AS IM_BLOCK_COUNT, CAST(NULL AS TIMESTAMP(9)) AS IM_STAT_UPDATE_TIME, CAST(NULL AS NUMBER) AS SCAN_RATE, CAST(STAT.SPARE1 AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND t.database_id = USERENV('SCHEMAID') UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, P.PART_ID, T.TABLE_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND t.database_id = USERENV('SCHEMAID') UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, T.TABLE_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND t.database_id = USERENV('SCHEMAID') ) V LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__(SELECT CAST(V.TABLE_NAME AS VARCHAR2(128)) AS TABLE_NAME, CAST(V.PARTITION_NAME AS VARCHAR2(128)) AS PARTITION_NAME, CAST(V.PARTITION_POSITION AS NUMBER) AS PARTITION_POSITION, CAST(V.SUBPARTITION_NAME AS VARCHAR2(128)) AS SUBPARTITION_NAME, CAST(V.SUBPARTITION_POSITION AS NUMBER) AS SUBPARTITION_POSITION, CAST(V.OBJECT_TYPE AS VARCHAR2(12)) AS OBJECT_TYPE, CAST(STAT.ROW_CNT AS NUMBER) AS NUM_ROWS, CAST(NULL AS NUMBER) AS BLOCKS, CAST(NULL AS NUMBER) AS EMPTY_BLOCKS, CAST(NULL AS NUMBER) AS AVG_SPACE, CAST(NULL AS NUMBER) AS CHAIN_CNT, CAST(STAT.AVG_ROW_LEN AS NUMBER) AS AVG_ROW_LEN, CAST(NULL AS NUMBER) AS AVG_SPACE_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS NUM_FREELIST_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHED_BLOCKS, CAST(NULL AS NUMBER) AS AVG_CACHE_HIT_RATIO, CAST(NULL AS NUMBER) AS IM_IMCU_COUNT, CAST(NULL AS NUMBER) AS IM_BLOCK_COUNT, CAST(NULL AS TIMESTAMP(9)) AS IM_STAT_UPDATE_TIME, CAST(NULL AS NUMBER) AS SCAN_RATE, CAST(STAT.SPARE1 AS NUMBER) AS SAMPLE_SIZE, CAST(STAT.LAST_ANALYZED AS DATE) AS LAST_ANALYZED, CAST(decode(STAT.GLOBAL_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS GLOBAL_STATS, CAST(decode(STAT.USER_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS USER_STATS, CAST(decode(bitand(STAT.STATTYPE_LOCKED, 15), NULL, NULL, 0, NULL, 1, 'DATA', 2, 'CACHE', 'ALL') AS VARCHAR2(5)) AS STATTYPE_LOCKED, CAST(decode(STAT.STALE_STATS, 0, 'NO', 1, 'YES', NULL) AS VARCHAR2(3)) AS STALE_STATS, CAST(NULL AS VARCHAR2(7)) AS SCOPE FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_ID, CASE WHEN PART_LEVEL = 0 THEN TABLE_ID ELSE -1 END AS PARTITION_ID, TABLE_NAME, NULL AS PARTITION_NAME, NULL AS SUBPARTITION_NAME, NULL AS PARTITION_POSITION, NULL AS SUBPARTITION_POSITION, 'TABLE' AS OBJECT_TYPE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND t.database_id = USERENV('SCHEMAID') UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, P.PART_ID, T.TABLE_NAME, P.PART_NAME, NULL, P.PART_IDX + 1, NULL, 'PARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND t.database_id = USERENV('SCHEMAID') AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, T.TABLE_ID, SP.SUB_PART_ID AS PARTITION_ID, T.TABLE_NAME, P.PART_NAME, SP.SUB_PART_NAME, P.PART_IDX + 1, SP.SUB_PART_IDX + 1, 'SUBPARTITION' FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) JOIN SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT SP ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND t.database_id = USERENV('SCHEMAID') AND P.PARTITION_TYPE = 0 AND SP.PARTITION_TYPE = 0 ) V LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT ON V.TENANT_ID = STAT.TENANT_ID AND V.TABLE_ID = STAT.TABLE_ID AND V.PARTITION_ID = STAT.PARTITION_ID )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.28151_28200.cpp b/src/share/inner_table/ob_inner_table_schema.28151_28200.cpp index 0eebaa578..5781a6ba1 100644 --- a/src/share/inner_table/ob_inner_table_schema.28151_28200.cpp +++ b/src/share/inner_table/ob_inner_table_schema.28151_28200.cpp @@ -162,7 +162,7 @@ int ObInnerTableSchema::dba_ob_table_locations_ora_schema(ObTableSchema &table_s 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 D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' WHEN A.TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, CASE WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 0 THEN 'STRONG' WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 1 THEN 'WEAK' ELSE 'NONE' END AS DUPLICATE_READ_CONSISTENCY, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLET_ID != 0 AND T.PART_LEVEL = 0 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT Q JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON P.PART_ID =Q.PART_ID AND Q.TENANT_ID = P.TENANT_ID JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID =P.TABLE_ID AND T.TENANT_ID = Q.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() ) A JOIN SYS.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN SYS.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON A.DATABASE_ID = D.DATABASE_ID AND A.TENANT_ID = D.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { + if (OB_FAIL(table_schema.set_view_definition(R"__( SELECT D.DATABASE_NAME, A.TABLE_NAME, A.TABLE_ID, CASE WHEN A.TABLE_TYPE IN (0) THEN 'SYSTEM TABLE' WHEN A.TABLE_TYPE IN (3,6,8,9) THEN 'USER TABLE' WHEN A.TABLE_TYPE IN (5) THEN 'INDEX' WHEN A.TABLE_TYPE IN (12,13) THEN 'LOB AUX TABLE' WHEN A.TABLE_TYPE IN (15) THEN 'MATERIALIZED VIEW LOG' ELSE NULL END AS TABLE_TYPE, A.PARTITION_NAME, A.SUBPARTITION_NAME, /* INDEX_NAME is valid when table is index */ CASE WHEN A.TABLE_TYPE != 5 THEN NULL WHEN D.DATABASE_NAME != '__recyclebin' THEN SUBSTR(TABLE_NAME, 7 + INSTR(SUBSTR(TABLE_NAME, 7), '_')) ELSE TABLE_NAME END AS INDEX_NAME, CASE WHEN DATA_TABLE_ID = 0 THEN NULL ELSE DATA_TABLE_ID END AS DATA_TABLE_ID, A.TABLET_ID, C.LS_ID, C.ZONE, C.SVR_IP AS SVR_IP, C.SVR_PORT AS SVR_PORT, C.ROLE, C.REPLICA_TYPE, CASE WHEN A.DUPLICATE_SCOPE = 1 THEN 'CLUSTER' ELSE 'NONE' END AS DUPLICATE_SCOPE, CASE WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 0 THEN 'STRONG' WHEN A.DUPLICATE_SCOPE = 1 AND A.DUPLICATE_READ_CONSISTENCY = 1 THEN 'WEAK' ELSE 'NONE' END AS DUPLICATE_READ_CONSISTENCY, A.OBJECT_ID, TG.TABLEGROUP_NAME, TG.TABLEGROUP_ID, TG.SHARDING FROM ( SELECT TENANT_ID, DATABASE_ID, TABLE_NAME, TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE WHERE TABLET_ID != 0 AND TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, 'NULL' AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, TABLE_ID AS OBJECT_ID, TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T WHERE T.TABLET_ID != 0 AND T.PART_LEVEL = 0 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, 'NULL' AS SUBPARTITION_NAME, P.PART_ID AS OBJECT_ID, P.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TENANT_ID AS TENANT_ID, T.DATABASE_ID AS DATABASE_ID, T.TABLE_NAME AS TABLE_NAME, T.TABLE_ID AS TABLE_ID, P.PART_NAME AS PARTITION_NAME, Q.SUB_PART_NAME AS SUBPARTITION_NAME, Q.SUB_PART_ID AS OBJECT_ID, Q.TABLET_ID AS TABLET_ID, TABLE_TYPE, DATA_TABLE_ID, DUPLICATE_SCOPE, DUPLICATE_READ_CONSISTENCY, TABLEGROUP_ID FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT Q JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON P.PART_ID =Q.PART_ID AND Q.TENANT_ID = P.TENANT_ID JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID =P.TABLE_ID AND T.TENANT_ID = Q.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND Q.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 ) A JOIN SYS.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN SYS.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT D ON A.DATABASE_ID = D.DATABASE_ID AND A.TENANT_ID = D.TENANT_ID LEFT JOIN SYS.ALL_VIRTUAL_TABLEGROUP_REAL_AGENT TG ON A.TABLEGROUP_ID = TG.TABLEGROUP_ID ORDER BY A.TABLE_ID, A.TABLET_ID, C.ZONE, SVR_IP, SVR_PORT )__"))) { LOG_ERROR("fail to set view_definition", K(ret)); } } diff --git a/src/share/inner_table/ob_inner_table_schema.28251_28300.cpp b/src/share/inner_table/ob_inner_table_schema.28251_28300.cpp index 518afe6d5..b11d58b44 100644 --- a/src/share/inner_table/ob_inner_table_schema.28251_28300.cpp +++ b/src/share/inner_table/ob_inner_table_schema.28251_28300.cpp @@ -11039,6 +11039,114 @@ int ObInnerTableSchema::all_dbms_lock_allocated_idx_dbms_lock_allocated_expirati return ret; } +int ObInnerTableSchema::all_tablet_reorganize_history_idx_tablet_his_table_id_src_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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_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(4); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(USER_INDEX); + table_schema.set_index_type(INDEX_TYPE_NORMAL_LOCAL); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_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())); + 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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_TID); + table_schema.set_micro_index_clustered(false); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + column_id + 1, //column_id + 1, //rowkey_id + 1, //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("src_tablet_id", //column_name + column_id + 3, //column_id + 2, //rowkey_id + 2, //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 + 2, //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("dest_tablet_id", //column_name + column_id + 4, //column_id + 4, //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_NORMAL_LOCAL); + table_schema.set_data_table_id(OB_ALL_TABLET_REORGANIZE_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id + 4); + return ret; +} + int ObInnerTableSchema::all_kv_ttl_task_idx_kv_ttl_task_table_id_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -12538,6 +12646,114 @@ int ObInnerTableSchema::all_scheduler_job_run_detail_v2_idx_scheduler_job_run_de return ret; } +int ObInnerTableSchema::all_tablet_reorganize_history_idx_tablet_his_table_id_dest_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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_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(4); + table_schema.set_load_type(TABLE_LOAD_TYPE_IN_DISK); + table_schema.set_table_type(USER_INDEX); + table_schema.set_index_type(INDEX_TYPE_NORMAL_LOCAL); + table_schema.set_def_type(TABLE_DEF_TYPE_INTERNAL); + + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.set_table_name(OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_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())); + 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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_TID); + table_schema.set_micro_index_clustered(false); + + if (OB_SUCC(ret)) { + ADD_COLUMN_SCHEMA("tenant_id", //column_name + column_id + 1, //column_id + 1, //rowkey_id + 1, //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("dest_tablet_id", //column_name + column_id + 4, //column_id + 2, //rowkey_id + 2, //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 + 2, //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("src_tablet_id", //column_name + column_id + 3, //column_id + 4, //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_NORMAL_LOCAL); + table_schema.set_data_table_id(OB_ALL_TABLET_REORGANIZE_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id + 4); + return ret; +} + int ObInnerTableSchema::all_virtual_table_real_agent_ora_idx_data_table_id_real_agent_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 b25b315e4..b0fd4615b 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 @@ -10512,6 +10512,160 @@ int ObInnerTableSchema::all_import_table_task_history_schema(ObTableSchema &tabl return ret; } +int ObInnerTableSchema::all_tablet_reorganize_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_TABLET_REORGANIZE_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(4); + 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_TABLET_REORGANIZE_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("ls_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("src_tablet_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("dest_tablet_id", //column_name + ++column_id, //column_id + 4, //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("type", //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_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_TS("finish_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_TABLET_REORGANIZE_HISTORY_TID); + table_schema.set_micro_index_clustered(false); + table_schema.set_aux_lob_meta_tid(OB_ALL_TABLET_REORGANIZE_HISTORY_AUX_LOB_META_TID); + table_schema.set_aux_lob_piece_tid(OB_ALL_TABLET_REORGANIZE_HISTORY_AUX_LOB_PIECE_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_storage_ha_error_diagnose_history_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; 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 c8387f429..7ddf2478e 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 @@ -4241,6 +4241,142 @@ int ObInnerTableSchema::all_import_table_task_history_aux_lob_meta_schema(ObTabl return ret; } +int ObInnerTableSchema::all_tablet_reorganize_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_TABLET_REORGANIZE_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_TABLET_REORGANIZE_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_TABLET_REORGANIZE_HISTORY_AUX_LOB_META_TID); + table_schema.set_micro_index_clustered(false); + table_schema.set_data_table_id(OB_ALL_TABLET_REORGANIZE_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_storage_ha_error_diagnose_history_aux_lob_meta_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; 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 4c64b8181..925b5bc0f 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 @@ -2846,6 +2846,97 @@ int ObInnerTableSchema::all_import_table_task_history_aux_lob_piece_schema(ObTab return ret; } +int ObInnerTableSchema::all_tablet_reorganize_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_TABLET_REORGANIZE_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_TABLET_REORGANIZE_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_TABLET_REORGANIZE_HISTORY_AUX_LOB_PIECE_TID); + table_schema.set_micro_index_clustered(false); + table_schema.set_data_table_id(OB_ALL_TABLET_REORGANIZE_HISTORY_TID); + + table_schema.set_max_used_column_id(column_id); + return ret; +} + int ObInnerTableSchema::all_storage_ha_error_diagnose_history_aux_lob_piece_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; diff --git a/src/share/inner_table/ob_inner_table_schema.h b/src/share/inner_table/ob_inner_table_schema.h index 0268964b3..da27b419e 100644 --- a/src/share/inner_table/ob_inner_table_schema.h +++ b/src/share/inner_table/ob_inner_table_schema.h @@ -605,6 +605,7 @@ 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_tablet_reorganize_history_schema(share::schema::ObTableSchema &table_schema); static int all_storage_ha_error_diagnose_history_schema(share::schema::ObTableSchema &table_schema); static int all_storage_ha_perf_diagnose_history_schema(share::schema::ObTableSchema &table_schema); static int all_clone_job_schema(share::schema::ObTableSchema &table_schema); @@ -1092,6 +1093,7 @@ public: static int all_virtual_user_proxy_info_history_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_user_proxy_role_info_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_user_proxy_role_info_history_schema(share::schema::ObTableSchema &table_schema); + static int all_virtual_tablet_reorganize_history_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_res_mgr_directive_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_service_schema(share::schema::ObTableSchema &table_schema); static int all_virtual_tenant_resource_limit_schema(share::schema::ObTableSchema &table_schema); @@ -2634,6 +2636,7 @@ 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_tablet_reorganize_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_storage_ha_error_diagnose_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_storage_ha_perf_diagnose_history_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); static int all_clone_job_aux_lob_meta_schema(share::schema::ObTableSchema &table_schema); @@ -2941,6 +2944,7 @@ 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_tablet_reorganize_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_storage_ha_error_diagnose_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_storage_ha_perf_diagnose_history_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); static int all_clone_job_aux_lob_piece_schema(share::schema::ObTableSchema &table_schema); @@ -3162,6 +3166,7 @@ public: 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_tablet_reorganize_history_idx_tablet_his_table_id_src_schema(share::schema::ObTableSchema &table_schema); static int all_kv_ttl_task_idx_kv_ttl_task_table_id_schema(share::schema::ObTableSchema &table_schema); static int all_kv_ttl_task_history_idx_kv_ttl_task_history_upd_time_schema(share::schema::ObTableSchema &table_schema); static int all_mview_refresh_run_stats_idx_mview_refresh_run_stats_num_mvs_current_schema(share::schema::ObTableSchema &table_schema); @@ -3173,6 +3178,7 @@ public: static int all_user_proxy_info_idx_user_proxy_info_proxy_user_id_schema(share::schema::ObTableSchema &table_schema); static int all_user_proxy_info_history_idx_user_proxy_info_proxy_user_id_history_schema(share::schema::ObTableSchema &table_schema); static int all_user_proxy_role_info_history_idx_user_proxy_role_info_proxy_user_id_history_schema(share::schema::ObTableSchema &table_schema); + static int all_tablet_reorganize_history_idx_tablet_his_table_id_dest_schema(share::schema::ObTableSchema &table_schema); static int all_scheduler_job_run_detail_v2_idx_scheduler_job_run_detail_v2_time_schema(share::schema::ObTableSchema &table_schema); static int all_scheduler_job_run_detail_v2_idx_scheduler_job_run_detail_v2_job_class_time_schema(share::schema::ObTableSchema &table_schema); @@ -3467,6 +3473,7 @@ 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_tablet_reorganize_history_schema, ObInnerTableSchema::all_storage_ha_error_diagnose_history_schema, ObInnerTableSchema::all_storage_ha_perf_diagnose_history_schema, ObInnerTableSchema::all_clone_job_schema, @@ -3957,6 +3964,7 @@ const schema_create_func virtual_table_schema_creators [] = { ObInnerTableSchema::all_virtual_user_proxy_info_history_schema, ObInnerTableSchema::all_virtual_user_proxy_role_info_schema, ObInnerTableSchema::all_virtual_user_proxy_role_info_history_schema, + ObInnerTableSchema::all_virtual_tablet_reorganize_history_schema, ObInnerTableSchema::all_virtual_res_mgr_directive_schema, ObInnerTableSchema::all_virtual_service_schema, ObInnerTableSchema::all_virtual_tenant_resource_limit_schema, @@ -5422,6 +5430,7 @@ const schema_create_func sys_index_table_schema_creators [] = { 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_tablet_reorganize_history_idx_tablet_his_table_id_src_schema, ObInnerTableSchema::all_kv_ttl_task_idx_kv_ttl_task_table_id_schema, ObInnerTableSchema::all_kv_ttl_task_history_idx_kv_ttl_task_history_upd_time_schema, ObInnerTableSchema::all_mview_refresh_run_stats_idx_mview_refresh_run_stats_num_mvs_current_schema, @@ -5435,6 +5444,7 @@ const schema_create_func sys_index_table_schema_creators [] = { ObInnerTableSchema::all_user_proxy_role_info_history_idx_user_proxy_role_info_proxy_user_id_history_schema, ObInnerTableSchema::all_scheduler_job_run_detail_v2_idx_scheduler_job_run_detail_v2_time_schema, ObInnerTableSchema::all_scheduler_job_run_detail_v2_idx_scheduler_job_run_detail_v2_job_class_time_schema, + ObInnerTableSchema::all_tablet_reorganize_history_idx_tablet_his_table_id_dest_schema, NULL,}; const schema_create_func information_schema_table_schema_creators[] = { @@ -5699,6 +5709,7 @@ 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_TABLET_REORGANIZE_HISTORY_TID, OB_ALL_CLONE_JOB_TID, OB_ALL_CLONE_JOB_HISTORY_TID, OB_ALL_ROUTINE_PRIVILEGE_TID, @@ -7194,6 +7205,7 @@ const uint64_t tenant_space_tables [] = { 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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_TID, OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TID, OB_ALL_KV_TTL_TASK_HISTORY_IDX_KV_TTL_TASK_HISTORY_UPD_TIME_TID, OB_ALL_MVIEW_REFRESH_RUN_STATS_IDX_MVIEW_REFRESH_RUN_STATS_NUM_MVS_CURRENT_TID, @@ -7207,6 +7219,7 @@ const uint64_t tenant_space_tables [] = { OB_ALL_USER_PROXY_ROLE_INFO_HISTORY_IDX_USER_PROXY_ROLE_INFO_PROXY_USER_ID_HISTORY_TID, OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_TIME_TID, OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_JOB_CLASS_TIME_TID, + OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_TID, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_DATA_TABLE_ID_REAL_AGENT_TID, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_DB_TB_NAME_REAL_AGENT_TID, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_TB_NAME_REAL_AGENT_TID, @@ -7536,6 +7549,7 @@ 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_TABLET_REORGANIZE_HISTORY_AUX_LOB_META_TID, OB_ALL_CLONE_JOB_AUX_LOB_META_TID, OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TID, OB_ALL_ROUTINE_PRIVILEGE_AUX_LOB_META_TID, @@ -7817,6 +7831,7 @@ 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_TABLET_REORGANIZE_HISTORY_AUX_LOB_PIECE_TID, OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID, OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TID, OB_ALL_ROUTINE_PRIVILEGE_AUX_LOB_PIECE_TID, @@ -8426,6 +8441,7 @@ 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_TABLET_REORGANIZE_HISTORY_TNAME, OB_ALL_CLONE_JOB_TNAME, OB_ALL_CLONE_JOB_HISTORY_TNAME, OB_ALL_ROUTINE_PRIVILEGE_TNAME, @@ -9921,6 +9937,7 @@ const char* const tenant_space_table_names [] = { 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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_TNAME, OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TNAME, OB_ALL_KV_TTL_TASK_HISTORY_IDX_KV_TTL_TASK_HISTORY_UPD_TIME_TNAME, OB_ALL_MVIEW_REFRESH_RUN_STATS_IDX_MVIEW_REFRESH_RUN_STATS_NUM_MVS_CURRENT_TNAME, @@ -9934,6 +9951,7 @@ const char* const tenant_space_table_names [] = { OB_ALL_USER_PROXY_ROLE_INFO_HISTORY_IDX_USER_PROXY_ROLE_INFO_PROXY_USER_ID_HISTORY_TNAME, OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_TIME_TNAME, OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_JOB_CLASS_TIME_TNAME, + OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_TNAME, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_DATA_TABLE_ID_REAL_AGENT_TNAME, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_DB_TB_NAME_REAL_AGENT_TNAME, OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_TB_NAME_REAL_AGENT_TNAME, @@ -10263,6 +10281,7 @@ 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_TABLET_REORGANIZE_HISTORY_AUX_LOB_META_TNAME, OB_ALL_CLONE_JOB_AUX_LOB_META_TNAME, OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_META_TNAME, OB_ALL_ROUTINE_PRIVILEGE_AUX_LOB_META_TNAME, @@ -10544,6 +10563,7 @@ 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_TABLET_REORGANIZE_HISTORY_AUX_LOB_PIECE_TNAME, OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TNAME, OB_ALL_CLONE_JOB_HISTORY_AUX_LOB_PIECE_TNAME, OB_ALL_ROUTINE_PRIVILEGE_AUX_LOB_PIECE_TNAME, @@ -13323,6 +13343,14 @@ LOBMapping const lob_aux_table_mappings [] = { ObInnerTableSchema::all_import_table_task_history_aux_lob_piece_schema }, + { + OB_ALL_TABLET_REORGANIZE_HISTORY_TID, + OB_ALL_TABLET_REORGANIZE_HISTORY_AUX_LOB_META_TID, + OB_ALL_TABLET_REORGANIZE_HISTORY_AUX_LOB_PIECE_TID, + ObInnerTableSchema::all_tablet_reorganize_history_aux_lob_meta_schema, + ObInnerTableSchema::all_tablet_reorganize_history_aux_lob_piece_schema + }, + { OB_ALL_STORAGE_HA_ERROR_DIAGNOSE_HISTORY_TID, OB_ALL_STORAGE_HA_ERROR_DIAGNOSE_HISTORY_AUX_LOB_META_TID, @@ -13600,12 +13628,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 = 304; -const int64_t OB_VIRTUAL_TABLE_COUNT = 851; +const int64_t OB_SYS_TABLE_COUNT = 305; +const int64_t OB_VIRTUAL_TABLE_COUNT = 852; const int64_t OB_SYS_VIEW_COUNT = 965; -const int64_t OB_SYS_TENANT_TABLE_COUNT = 2125; +const int64_t OB_SYS_TENANT_TABLE_COUNT = 2127; const int64_t OB_CORE_SCHEMA_VERSION = 1; -const int64_t OB_BOOTSTRAP_SCHEMA_VERSION = 2128; +const int64_t OB_BOOTSTRAP_SCHEMA_VERSION = 2130; } // 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 7bf499c52..e0437fc38 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(307, ObModIds::OB_INNER_LOB_HASH_SET))) { + if (OB_FAIL(inner_lob_map.create(308, 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 87fc6cc41..fac2c89a0 100644 --- a/src/share/inner_table/ob_inner_table_schema_constants.h +++ b/src/share/inner_table/ob_inner_table_schema_constants.h @@ -305,6 +305,7 @@ 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_TABLET_REORGANIZE_HISTORY_TID = 482; // "__all_tablet_reorganize_history" const uint64_t OB_ALL_STORAGE_HA_ERROR_DIAGNOSE_HISTORY_TID = 483; // "__all_storage_ha_error_diagnose_history" const uint64_t OB_ALL_STORAGE_HA_PERF_DIAGNOSE_HISTORY_TID = 484; // "__all_storage_ha_perf_diagnose_history" const uint64_t OB_ALL_CLONE_JOB_TID = 485; // "__all_clone_job" @@ -792,6 +793,7 @@ const uint64_t OB_ALL_VIRTUAL_USER_PROXY_INFO_TID = 12474; // "__all_virtual_use const uint64_t OB_ALL_VIRTUAL_USER_PROXY_INFO_HISTORY_TID = 12475; // "__all_virtual_user_proxy_info_history" const uint64_t OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_TID = 12476; // "__all_virtual_user_proxy_role_info" const uint64_t OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TID = 12477; // "__all_virtual_user_proxy_role_info_history" +const uint64_t OB_ALL_VIRTUAL_TABLET_REORGANIZE_HISTORY_TID = 12478; // "__all_virtual_tablet_reorganize_history" const uint64_t OB_ALL_VIRTUAL_RES_MGR_DIRECTIVE_TID = 12479; // "__all_virtual_res_mgr_directive" const uint64_t OB_ALL_VIRTUAL_SERVICE_TID = 12480; // "__all_virtual_service" const uint64_t OB_ALL_VIRTUAL_TENANT_RESOURCE_LIMIT_TID = 12481; // "__all_virtual_tenant_resource_limit" @@ -2334,6 +2336,7 @@ 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_TABLET_REORGANIZE_HISTORY_AUX_LOB_META_TID = 50482; // "__all_tablet_reorganize_history_aux_lob_meta" const uint64_t OB_ALL_STORAGE_HA_ERROR_DIAGNOSE_HISTORY_AUX_LOB_META_TID = 50483; // "__all_storage_ha_error_diagnose_history_aux_lob_meta" const uint64_t OB_ALL_STORAGE_HA_PERF_DIAGNOSE_HISTORY_AUX_LOB_META_TID = 50484; // "__all_storage_ha_perf_diagnose_history_aux_lob_meta" const uint64_t OB_ALL_CLONE_JOB_AUX_LOB_META_TID = 50485; // "__all_clone_job_aux_lob_meta" @@ -2641,6 +2644,7 @@ 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_TABLET_REORGANIZE_HISTORY_AUX_LOB_PIECE_TID = 60482; // "__all_tablet_reorganize_history_aux_lob_piece" const uint64_t OB_ALL_STORAGE_HA_ERROR_DIAGNOSE_HISTORY_AUX_LOB_PIECE_TID = 60483; // "__all_storage_ha_error_diagnose_history_aux_lob_piece" const uint64_t OB_ALL_STORAGE_HA_PERF_DIAGNOSE_HISTORY_AUX_LOB_PIECE_TID = 60484; // "__all_storage_ha_perf_diagnose_history_aux_lob_piece" const uint64_t OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TID = 60485; // "__all_clone_job_aux_lob_piece" @@ -2787,6 +2791,7 @@ const uint64_t OB_ALL_RLS_CONTEXT_HISTORY_IDX_RLS_CONTEXT_HIS_TABLE_ID_TID = 101 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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_TID = 101092; // "__all_tablet_reorganize_history" const uint64_t OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TID = 101093; // "__all_kv_ttl_task" const uint64_t OB_ALL_KV_TTL_TASK_HISTORY_IDX_KV_TTL_TASK_HISTORY_UPD_TIME_TID = 101094; // "__all_kv_ttl_task_history" const uint64_t OB_ALL_MVIEW_REFRESH_RUN_STATS_IDX_MVIEW_REFRESH_RUN_STATS_NUM_MVS_CURRENT_TID = 101095; // "__all_mview_refresh_run_stats" @@ -2800,6 +2805,7 @@ const uint64_t OB_ALL_USER_PROXY_INFO_HISTORY_IDX_USER_PROXY_INFO_PROXY_USER_ID_ const uint64_t OB_ALL_USER_PROXY_ROLE_INFO_HISTORY_IDX_USER_PROXY_ROLE_INFO_PROXY_USER_ID_HISTORY_TID = 101103; // "__all_user_proxy_role_info_history" const uint64_t OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_TIME_TID = 101105; // "__all_scheduler_job_run_detail_v2" const uint64_t OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_JOB_CLASS_TIME_TID = 101106; // "__all_scheduler_job_run_detail_v2" +const uint64_t OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_TID = 101104; // "__all_tablet_reorganize_history" const uint64_t OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_DATA_TABLE_ID_REAL_AGENT_TID = 15306; // "ALL_VIRTUAL_TABLE_REAL_AGENT_ORA" const uint64_t OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_DB_TB_NAME_REAL_AGENT_TID = 15307; // "ALL_VIRTUAL_TABLE_REAL_AGENT_ORA" const uint64_t OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_TB_NAME_REAL_AGENT_TID = 15308; // "ALL_VIRTUAL_TABLE_REAL_AGENT_ORA" @@ -3154,6 +3160,7 @@ 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_TABLET_REORGANIZE_HISTORY_TNAME = "__all_tablet_reorganize_history"; const char *const OB_ALL_STORAGE_HA_ERROR_DIAGNOSE_HISTORY_TNAME = "__all_storage_ha_error_diagnose_history"; const char *const OB_ALL_STORAGE_HA_PERF_DIAGNOSE_HISTORY_TNAME = "__all_storage_ha_perf_diagnose_history"; const char *const OB_ALL_CLONE_JOB_TNAME = "__all_clone_job"; @@ -3641,6 +3648,7 @@ const char *const OB_ALL_VIRTUAL_USER_PROXY_INFO_TNAME = "__all_virtual_user_pro const char *const OB_ALL_VIRTUAL_USER_PROXY_INFO_HISTORY_TNAME = "__all_virtual_user_proxy_info_history"; const char *const OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_TNAME = "__all_virtual_user_proxy_role_info"; const char *const OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TNAME = "__all_virtual_user_proxy_role_info_history"; +const char *const OB_ALL_VIRTUAL_TABLET_REORGANIZE_HISTORY_TNAME = "__all_virtual_tablet_reorganize_history"; const char *const OB_ALL_VIRTUAL_RES_MGR_DIRECTIVE_TNAME = "__all_virtual_res_mgr_directive"; const char *const OB_ALL_VIRTUAL_SERVICE_TNAME = "__all_virtual_service"; const char *const OB_ALL_VIRTUAL_TENANT_RESOURCE_LIMIT_TNAME = "__all_virtual_tenant_resource_limit"; @@ -5183,6 +5191,7 @@ 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_TABLET_REORGANIZE_HISTORY_AUX_LOB_META_TNAME = "__all_tablet_reorganize_history_aux_lob_meta"; const char *const OB_ALL_STORAGE_HA_ERROR_DIAGNOSE_HISTORY_AUX_LOB_META_TNAME = "__all_storage_ha_error_diagnose_history_aux_lob_meta"; const char *const OB_ALL_STORAGE_HA_PERF_DIAGNOSE_HISTORY_AUX_LOB_META_TNAME = "__all_storage_ha_perf_diagnose_history_aux_lob_meta"; const char *const OB_ALL_CLONE_JOB_AUX_LOB_META_TNAME = "__all_clone_job_aux_lob_meta"; @@ -5490,6 +5499,7 @@ 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_TABLET_REORGANIZE_HISTORY_AUX_LOB_PIECE_TNAME = "__all_tablet_reorganize_history_aux_lob_piece"; const char *const OB_ALL_STORAGE_HA_ERROR_DIAGNOSE_HISTORY_AUX_LOB_PIECE_TNAME = "__all_storage_ha_error_diagnose_history_aux_lob_piece"; const char *const OB_ALL_STORAGE_HA_PERF_DIAGNOSE_HISTORY_AUX_LOB_PIECE_TNAME = "__all_storage_ha_perf_diagnose_history_aux_lob_piece"; const char *const OB_ALL_CLONE_JOB_AUX_LOB_PIECE_TNAME = "__all_clone_job_aux_lob_piece"; @@ -5636,6 +5646,7 @@ const char *const OB_ALL_RLS_CONTEXT_HISTORY_IDX_RLS_CONTEXT_HIS_TABLE_ID_TNAME 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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_TNAME = "__idx_482_idx_tablet_his_table_id_src"; const char *const OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TNAME = "__idx_410_idx_kv_ttl_task_table_id"; const char *const OB_ALL_KV_TTL_TASK_HISTORY_IDX_KV_TTL_TASK_HISTORY_UPD_TIME_TNAME = "__idx_411_idx_kv_ttl_task_history_upd_time"; const char *const OB_ALL_MVIEW_REFRESH_RUN_STATS_IDX_MVIEW_REFRESH_RUN_STATS_NUM_MVS_CURRENT_TNAME = "__idx_467_idx_mview_refresh_run_stats_num_mvs_current"; @@ -5649,6 +5660,7 @@ const char *const OB_ALL_USER_PROXY_INFO_HISTORY_IDX_USER_PROXY_INFO_PROXY_USER_ const char *const OB_ALL_USER_PROXY_ROLE_INFO_HISTORY_IDX_USER_PROXY_ROLE_INFO_PROXY_USER_ID_HISTORY_TNAME = "__idx_515_idx_user_proxy_role_info_proxy_user_id_history"; const char *const OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_TIME_TNAME = "__idx_519_idx_scheduler_job_run_detail_v2_time"; const char *const OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_JOB_CLASS_TIME_TNAME = "__idx_519_idx_scheduler_job_run_detail_v2_job_class_time"; +const char *const OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_TNAME = "__idx_482_idx_tablet_his_table_id_dest"; const char *const OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_DATA_TABLE_ID_REAL_AGENT_TNAME = "__idx_15120_idx_data_table_id_real_agent"; const char *const OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_DB_TB_NAME_REAL_AGENT_TNAME = "__idx_15120_idx_db_tb_name_real_agent"; const char *const OB_ALL_VIRTUAL_TABLE_REAL_AGENT_ORA_IDX_TB_NAME_REAL_AGENT_TNAME = "__idx_15120_idx_tb_name_real_agent"; 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 af85e93ed..96f2bf4d5 100755 --- a/src/share/inner_table/ob_inner_table_schema_def.py +++ b/src/share/inner_table/ob_inner_table_schema_def.py @@ -6847,7 +6847,29 @@ def_table_schema( # 481 : __all_import_stmt_exec_history -# 482 : __all_tablet_reorganize_history + +def_table_schema( + owner = 'hanxuan.gzh', + table_name = '__all_tablet_reorganize_history', + table_id = '482', + table_type = 'SYSTEM_TABLE', + gm_columns = [], + rowkey_columns = [ + ('tenant_id', 'int'), + ('ls_id', 'int'), + ('src_tablet_id', 'int'), + ('dest_tablet_id', 'int'), + ], + is_cluster_private = False, + in_tenant_space = True, + + normal_columns = [ + ('type', 'int'), + ('create_time', 'timestamp'), + ('finish_time', 'timestamp'), + ], +) + def_table_schema( owner = 'zhixing.yh', table_name = '__all_storage_ha_error_diagnose_history', @@ -14807,7 +14829,10 @@ def_table_schema(**gen_iterate_virtual_table_def( table_name = '__all_virtual_user_proxy_role_info_history', keywords = all_def_keywords['__all_user_proxy_role_info_history'])) -# 12478: __all_virtual_tablet_reorganize_history +def_table_schema(**gen_iterate_virtual_table_def( + table_id = '12478', + table_name = '__all_virtual_tablet_reorganize_history', + keywords = all_def_keywords['__all_tablet_reorganize_history'])) def_table_schema(**gen_iterate_virtual_table_def( table_id = '12479', @@ -16085,7 +16110,11 @@ def_table_schema( cast(NULL as unsigned) as CHECKSUM, cast(NULL as char(255)) as CREATE_OPTIONS, cast(case when a.table_type = 4 then 'VIEW' - else a.comment end as char(2048)) as TABLE_COMMENT + else a.comment end as char(2048)) as TABLE_COMMENT, + cast(case when a.auto_part = 1 then 'TRUE' + else 'FALSE' end as char(16)) as AUTO_SPLIT, + cast(case when a.auto_part = 1 then a.auto_part_size + else 0 end as unsigned) as AUTO_SPLIT_TABLET_SIZE from ( select cast(0 as signed) as tenant_id, @@ -16097,7 +16126,9 @@ def_table_schema( usec_to_time(d.schema_version) as gmt_create, usec_to_time(c.schema_version) as gmt_modified, c.comment, - c.store_format + c.store_format, + c.auto_part, + c.auto_part_size from oceanbase.__all_virtual_core_all_table c join oceanbase.__all_virtual_core_all_table d on c.tenant_id = d.tenant_id and d.table_name = '__all_core_table' @@ -16112,7 +16143,9 @@ def_table_schema( gmt_create, gmt_modified, comment, - store_format + store_format, + auto_part, + auto_part_size from oceanbase.__all_table where table_mode >> 12 & 15 in (0,1)) a join oceanbase.__all_database b on a.database_id = b.database_id @@ -21232,7 +21265,7 @@ def_table_schema( , 0 AS NAMESPACE ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID - WHERE T.TENANT_ID = P.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) + WHERE T.TENANT_ID = P.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) AND P.PARTITION_TYPE = 0 UNION ALL @@ -21258,6 +21291,8 @@ def_table_schema( FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) + AND P.PARTITION_TYPE = 0 + AND SUBP.PARTITION_TYPE = 0 UNION ALL @@ -21599,7 +21634,9 @@ SELECT CAST(NULL AS CHAR(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS CHAR(3)) AS ADMIT_NULL, CAST(NULL AS CHAR(3)) AS DATA_LINK_DML_ENABLED, - CAST(NULL AS CHAR(8)) AS LOGICAL_REPLICATION + CAST(NULL AS CHAR(8)) AS LOGICAL_REPLICATION, + CAST(CASE WHEN T.AUTO_PART = 1 THEN 'TRUE' ELSE 'FALSE' END AS CHAR(16)) AS AUTO_SPLIT, + CAST(CASE WHEN T.AUTO_PART = 1 THEN T.AUTO_PART_SIZE ELSE 0 END AS SIGNED) AS AUTO_SPLIT_TABLET_SIZE FROM (SELECT TENANT_ID, @@ -21620,7 +21657,9 @@ FROM PCTFREE, PART_LEVEL, TABLE_TYPE, - TABLESPACE_ID + TABLESPACE_ID, + AUTO_PART, + AUTO_PART_SIZE FROM OCEANBASE.__ALL_VIRTUAL_CORE_ALL_TABLE @@ -21634,7 +21673,9 @@ FROM PCTFREE, PART_LEVEL, TABLE_TYPE, - TABLESPACE_ID + TABLESPACE_ID, + AUTO_PART, + AUTO_PART_SIZE FROM OCEANBASE.__ALL_VIRTUAL_TABLE WHERE TABLE_MODE >> 12 & 15 in (0,1)) T ON @@ -22403,6 +22444,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -22413,6 +22455,7 @@ def_table_schema( LEFT JOIN OCEANBASE.__ALL_VIRTUAL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID + WHERE PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -22511,6 +22554,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -22525,6 +22569,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -22532,7 +22577,9 @@ def_table_schema( FROM OCEANBASE.__ALL_VIRTUAL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN @@ -22968,6 +23015,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -22975,6 +23023,7 @@ def_table_schema( FROM OCEANBASE.__ALL_VIRTUAL_PART) PART ON I.TENANT_ID = PART.TENANT_ID AND I.TABLE_ID = PART.TABLE_ID + WHERE PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -23059,6 +23108,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -23072,6 +23122,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -23079,7 +23130,9 @@ def_table_schema( FROM OCEANBASE.__ALL_VIRTUAL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID """.replace("\n", " ") ) @@ -23264,6 +23317,7 @@ def_table_schema( ,NULL AS EDITION_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) + AND P.PARTITION_TYPE = 0 UNION ALL @@ -23289,6 +23343,7 @@ def_table_schema( FROM OCEANBASE.__ALL_TABLE T, OCEANBASE.__ALL_PART P,OCEANBASE.__ALL_SUB_PART SUBP WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = 0 AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = SUBP.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) + AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 UNION ALL @@ -23811,6 +23866,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -23822,6 +23878,7 @@ def_table_schema( ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = 0 + AND PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -23920,6 +23977,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -23934,6 +23992,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -23941,7 +24000,9 @@ def_table_schema( FROM OCEANBASE.__ALL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN @@ -24253,6 +24314,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -24262,7 +24324,8 @@ def_table_schema( AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = 0 - AND I.TABLE_MODE >> 12 & 15 in (0,1) + AND I.TABLE_MODE >> 12 & 15 in (0,1) + AND PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -24346,6 +24409,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -24359,6 +24423,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -24366,7 +24431,9 @@ def_table_schema( FROM OCEANBASE.__ALL_SUB_PART) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = 0 AND I.TABLE_MODE >> 12 & 15 in (0,1) @@ -25635,7 +25702,8 @@ def_table_schema( ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,6,14,15) - AND T.TABLE_MODE >> 12 & 15 in (0,1) + AND T.TABLE_MODE >> 12 & 15 in (0,1) + AND (P.PARTITION_TYPE = 0 OR P.PARTITION_TYPE IS NULL) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, @@ -25659,7 +25727,9 @@ def_table_schema( AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,6,14,15) - AND T.TABLE_MODE >> 12 & 15 in (0,1) + AND T.TABLE_MODE >> 12 & 15 in (0,1) + AND (P.PARTITION_TYPE = 0 OR P.PARTITION_TYPE IS NULL) + AND (SP.PARTITION_TYPE = 0 OR SP.PARTITION_TYPE IS NULL) ) V JOIN oceanbase.__all_database DB @@ -25804,6 +25874,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) + AND part.partition_type = 0 """.replace("\n", " ") ) @@ -25862,6 +25933,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) + AND subpart.partition_type = 0 """.replace("\n", " ") ) @@ -25961,6 +26033,7 @@ def_table_schema( c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) + AND part.partition_type = 0 """.replace("\n", " ") ) @@ -26008,6 +26081,7 @@ def_table_schema( c.is_hidden = 0 AND t.table_type in (0,3,6,14) AND t.table_mode >> 12 & 15 in (0,1) + AND subpart.partition_type = 0 """.replace("\n", " ") ) @@ -26200,7 +26274,9 @@ def_table_schema( oceanbase.__all_part P ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID - WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) + WHERE T.TABLE_TYPE = 5 + AND P.PARTITION_TYPE = 0 + AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, @@ -26224,7 +26300,10 @@ def_table_schema( ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID - WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) + WHERE T.TABLE_TYPE = 5 + AND P.PARTITION_TYPE = 0 + AND SP.PARTITION_TYPE = 0 + AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN oceanbase.__all_table T ON T.TABLE_ID = V.DATA_TABLE_ID @@ -28973,6 +29052,7 @@ FROM ( FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_PART P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = 0 + AND P.PARTITION_TYPE = 0 UNION ALL @@ -28993,6 +29073,8 @@ FROM ( WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID = Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 AND T.TENANT_ID = 0 + AND P.PARTITION_TYPE = 0 + AND Q.PARTITION_TYPE = 0 ) A JOIN OCEANBASE.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN OCEANBASE.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID @@ -29115,7 +29197,7 @@ FROM ( TABLEGROUP_ID FROM OCEANBASE.__ALL_VIRTUAL_TABLE T JOIN OCEANBASE.__ALL_VIRTUAL_PART P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = P.TENANT_ID AND T.PART_LEVEL = 1 - + AND P.PARTITION_TYPE = 0 UNION ALL SELECT @@ -29135,6 +29217,7 @@ FROM ( FROM OCEANBASE.__ALL_VIRTUAL_TABLE T, OCEANBASE.__ALL_VIRTUAL_PART P,OCEANBASE.__ALL_VIRTUAL_SUB_PART Q WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=Q.TABLE_ID AND P.PART_ID =Q.PART_ID AND T.TENANT_ID = P.TENANT_ID AND P.TENANT_ID = Q.TENANT_ID AND T.PART_LEVEL = 2 + AND P.PARTITION_TYPE = 0 AND Q.PARTITION_TYPE = 0 ) A JOIN OCEANBASE.CDB_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID AND A.TENANT_ID = B.TENANT_ID JOIN OCEANBASE.CDB_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID AND A.TENANT_ID = C.TENANT_ID @@ -30969,6 +31052,7 @@ FROM TABLESPACE_ID, GMT_CREATE, COMMENT, + PARTITION_TYPE, PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID ORDER BY PART_IDX) AS PART_POSITION FROM OCEANBASE.__ALL_PART @@ -30985,6 +31069,7 @@ FROM TABLESPACE_ID, GMT_CREATE, COMMENT, + PARTITION_TYPE, SUB_PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID,PART_ID ORDER BY SUB_PART_IDX) AS SUB_PART_POSITION FROM OCEANBASE.__ALL_SUB_PART @@ -31006,6 +31091,8 @@ FROM IDX_STAT.DATA_TABLE_ID = T.TABLE_ID AND CASE T.PART_LEVEL WHEN 0 THEN 1 WHEN 1 THEN P.PART_IDX = IDX_STAT.PART_IDX WHEN 2 THEN P.PART_IDX = IDX_STAT.PART_IDX AND SP.SUB_PART_IDX = IDX_STAT.SUB_PART_IDX END WHERE T.TABLE_TYPE IN (3,6,8,9,14,15) + AND (P.PARTITION_TYPE = 0 OR P.PARTITION_TYPE is NULL) + AND (SP.PARTITION_TYPE = 0 OR SP.PARTITION_TYPE is NULL) """.replace("\n", " "), ) @@ -37907,6 +37994,7 @@ def_table_schema( ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 + AND P.PARTITION_TYPE = 0 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) UNION ALL @@ -37933,6 +38021,7 @@ def_table_schema( WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) + AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 UNION ALL @@ -38405,6 +38494,7 @@ def_table_schema( ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) + AND P.PARTITION_TYPE = 0 UNION ALL @@ -38432,6 +38522,7 @@ def_table_schema( WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) + AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 UNION ALL @@ -38913,6 +39004,7 @@ def_table_schema( ,NULL AS EDITION_NAME FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID WHERE T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) + AND P.PARTITION_TYPE = 0 UNION ALL @@ -38939,6 +39031,7 @@ def_table_schema( WHERE T.TABLE_ID =P.TABLE_ID AND P.TABLE_ID=SUBP.TABLE_ID AND P.PART_ID =SUBP.PART_ID AND T.TENANT_ID = EFFECTIVE_TENANT_ID() AND P.TENANT_ID = EFFECTIVE_TENANT_ID() AND SUBP.TENANT_ID = EFFECTIVE_TENANT_ID() AND T.TABLE_TYPE != 12 AND T.TABLE_TYPE != 13 AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) + AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 UNION ALL @@ -41502,7 +41595,9 @@ SELECT CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, - CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION + CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION, + CAST(CASE WHEN T.AUTO_PART = 1 THEN 'TRUE' ELSE 'FALSE' END AS VARCHAR2(16)) AS AUTO_SPLIT, + CAST(CASE WHEN T.AUTO_PART = 1 THEN T.AUTO_PART_SIZE ELSE 0 END AS VARCHAR2(128)) AS AUTO_SPLIT_TABLET_SIZE FROM (SELECT TENANT_ID, @@ -41524,7 +41619,9 @@ FROM "PCTFREE", PART_LEVEL, TABLE_TYPE, - TABLESPACE_ID + TABLESPACE_ID, + AUTO_PART, + AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE @@ -41538,7 +41635,9 @@ FROM "PCTFREE", PART_LEVEL, TABLE_TYPE, - TABLESPACE_ID + TABLESPACE_ID, + AUTO_PART, + AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND bitand((TABLE_MODE / 4096), 15) IN (0,1) @@ -41676,7 +41775,9 @@ SELECT CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, - CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION + CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION, + CAST(CASE WHEN T.AUTO_PART = 1 THEN 'TRUE' ELSE 'FALSE' END AS VARCHAR2(16)) AS AUTO_SPLIT, + CAST(CASE WHEN T.AUTO_PART = 1 THEN T.AUTO_PART_SIZE ELSE 0 END AS VARCHAR2(128)) AS AUTO_SPLIT_TABLET_SIZE FROM (SELECT TENANT_ID, @@ -41698,7 +41799,9 @@ FROM "PCTFREE", PART_LEVEL, TABLE_TYPE, - TABLESPACE_ID + TABLESPACE_ID, + AUTO_PART, + AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE @@ -41712,7 +41815,9 @@ FROM "PCTFREE", PART_LEVEL, TABLE_TYPE, - TABLESPACE_ID + TABLESPACE_ID, + AUTO_PART, + AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) @@ -41847,7 +41952,9 @@ SELECT CAST(NULL AS VARCHAR2(3)) AS HAS_SENSITIVE_COLUMN, CAST(NULL AS VARCHAR2(3)) AS ADMIT_NULL, CAST(NULL AS VARCHAR2(3)) AS DATA_LINK_DML_ENABLED, - CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION + CAST(NULL AS VARCHAR2(8)) AS LOGICAL_REPLICATION, + CAST(CASE WHEN T.AUTO_PART = 1 THEN 'TRUE' ELSE 'FALSE' END AS VARCHAR2(16)) AS AUTO_SPLIT, + CAST(CASE WHEN T.AUTO_PART = 1 THEN T.AUTO_PART_SIZE ELSE 0 END AS VARCHAR2(128)) AS AUTO_SPLIT_TABLET_SIZE FROM (SELECT TENANT_ID, @@ -41869,7 +41976,9 @@ FROM "PCTFREE", PART_LEVEL, TABLE_TYPE, - TABLESPACE_ID + TABLESPACE_ID, + AUTO_PART, + AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_CORE_ALL_TABLE @@ -41883,7 +41992,9 @@ FROM "PCTFREE", PART_LEVEL, TABLE_TYPE, - TABLESPACE_ID + TABLESPACE_ID, + AUTO_PART, + AUTO_PART_SIZE FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT WHERE TENANT_ID = EFFECTIVE_TENANT_ID() AND TABLE_TYPE != 12 AND TABLE_TYPE != 13 AND bitand((TABLE_MODE / 4096), 15) IN (0,1) @@ -42988,6 +43099,7 @@ def_table_schema( WHERE T.PART_LEVEL = 1 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() + AND P.PARTITION_TYPE = 0 UNION ALL @@ -43023,6 +43135,7 @@ def_table_schema( WHERE T.PART_LEVEL = 2 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() + AND SUBP.PARTITION_TYPE = 0 AND P.PARTITION_TYPE = 0 )A WHERE DATABASE_ID=USERENV('SCHEMAID') """.replace("\n", " ") ) @@ -43147,6 +43260,7 @@ def_table_schema( WHERE T.PART_LEVEL = 1 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() + AND P.PARTITION_TYPE = 0 UNION ALL @@ -43182,6 +43296,7 @@ def_table_schema( WHERE T.PART_LEVEL = 2 AND T.TABLE_TYPE IN (0, 3, 5, 8, 9) AND T.TENANT_ID = EFFECTIVE_TENANT_ID() + AND SUBP.PARTITION_TYPE =0 AND P.PARTITION_TYPE = 0 )A JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT B ON A.DATABASE_ID = B.DATABASE_ID AND B.TENANT_ID = EFFECTIVE_TENANT_ID() @@ -45875,6 +45990,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -45887,6 +46003,7 @@ def_table_schema( ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() + AND PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -45988,6 +46105,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -46002,6 +46120,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -46009,7 +46128,9 @@ def_table_schema( FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN @@ -46472,6 +46593,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -46484,6 +46606,7 @@ def_table_schema( ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() + AND PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -46597,6 +46720,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -46609,6 +46733,7 @@ def_table_schema( ON TP.TABLESPACE_ID = PART.TABLESPACE_ID AND TP.TENANT_ID = PART.TENANT_ID WHERE DB_TB.TENANT_ID = EFFECTIVE_TENANT_ID() + AND PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -46708,6 +46833,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -46722,6 +46848,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -46729,7 +46856,9 @@ def_table_schema( FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN @@ -46836,6 +46965,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -46850,6 +46980,7 @@ def_table_schema( LIST_VAL, COMPRESS_FUNC_NAME, TABLESPACE_ID, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -46857,7 +46988,9 @@ def_table_schema( FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON DB_TB.TABLE_ID = PART.TABLE_ID AND DB_TB.TENANT_ID = PART.TENANT_ID LEFT JOIN @@ -49010,6 +49143,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -49019,6 +49153,7 @@ def_table_schema( AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() + AND PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -49106,6 +49241,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -49115,6 +49251,7 @@ def_table_schema( AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() + AND PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -49203,6 +49340,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -49212,6 +49350,7 @@ def_table_schema( AND I.TABLE_ID = PART.TABLE_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() + AND PART.PARTITION_TYPE = 0 """.replace("\n", " ") ) @@ -49298,6 +49437,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -49311,6 +49451,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -49318,7 +49459,9 @@ def_table_schema( FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -49403,6 +49546,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -49416,6 +49560,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -49423,7 +49568,9 @@ def_table_schema( FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -49506,6 +49653,7 @@ def_table_schema( TABLE_ID, PART_ID, PART_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID ORDER BY PART_IDX, PART_ID ASC @@ -49519,6 +49667,7 @@ def_table_schema( HIGH_BOUND_VAL, LIST_VAL, COMPRESS_FUNC_NAME, + PARTITION_TYPE, ROW_NUMBER() OVER ( PARTITION BY TENANT_ID, TABLE_ID, PART_ID ORDER BY SUB_PART_IDX, SUB_PART_ID ASC @@ -49526,7 +49675,9 @@ def_table_schema( FROM SYS.ALL_VIRTUAL_SUB_PART_REAL_AGENT) S_PART WHERE P_PART.PART_ID = S_PART.PART_ID AND P_PART.TABLE_ID = S_PART.TABLE_ID - AND P_PART.TENANT_ID = S_PART.TENANT_ID) PART + AND P_PART.TENANT_ID = S_PART.TENANT_ID + AND P_PART.PARTITION_TYPE = 0 + AND S_PART.PARTITION_TYPE = 0) PART ON I.TABLE_ID = PART.TABLE_ID AND I.TENANT_ID = PART.TENANT_ID WHERE I.TENANT_ID = EFFECTIVE_TENANT_ID() """.replace("\n", " ") @@ -52796,7 +52947,9 @@ def_table_schema( ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) - WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) + WHERE T.TABLE_TYPE = 5 + AND P.PARTITION_TYPE = 0 + AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, @@ -52821,7 +52974,10 @@ def_table_schema( ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID - WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) + WHERE T.TABLE_TYPE = 5 + AND P.PARTITION_TYPE = 0 + AND SP.PARTITION_TYPE = 0 + AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID @@ -52934,7 +53090,9 @@ def_table_schema( ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) - WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) + WHERE T.TABLE_TYPE = 5 + AND P.PARTITION_TYPE = 0 + AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, @@ -52959,7 +53117,10 @@ def_table_schema( ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID - WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) + WHERE T.TABLE_TYPE = 5 + AND P.PARTITION_TYPE = 0 + AND SP.PARTITION_TYPE = 0 + AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID @@ -53052,7 +53213,9 @@ def_table_schema( ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) - WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.DATABASE_ID = USERENV('SCHEMAID') + WHERE T.TABLE_TYPE = 5 AND T.DATABASE_ID = USERENV('SCHEMAID') + AND P.PARTITION_TYPE = 0 + AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, @@ -53077,7 +53240,10 @@ def_table_schema( ON T.TENANT_ID = SP.TENANT_ID AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID - WHERE T.TABLE_TYPE = 5 AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) AND T.DATABASE_ID = USERENV('SCHEMAID') + WHERE T.TABLE_TYPE = 5 AND T.DATABASE_ID = USERENV('SCHEMAID') + AND P.PARTITION_TYPE = 0 + AND SP.PARTITION_TYPE = 0 + AND T.INDEX_TYPE NOT IN (13, 14, 16, 17, 19, 20, 22) ) V JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID = V.DATA_TABLE_ID @@ -60703,6 +60869,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND part.partition_type = 0 """.replace("\n", " ") ) @@ -60765,6 +60932,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND part.partition_type = 0 """.replace("\n", " ") ) @@ -60822,6 +60990,7 @@ WHERE AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND part.partition_type = 0 """.replace("\n", " ") ) @@ -60886,6 +61055,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND subpart.partition_type = 0 """.replace("\n", " ") ) @@ -60948,6 +61118,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND subpart.partition_type = 0 """.replace("\n", " ") ) @@ -61005,6 +61176,7 @@ WHERE AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND subpart.partition_type = 0 """.replace("\n", " ") ) @@ -61213,6 +61385,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND part.partition_type = 0 """.replace("\n", " ") ) @@ -61264,6 +61437,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND part.partition_type = 0 """.replace("\n", " ") ) def_table_schema( @@ -61308,6 +61482,7 @@ WHERE AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND part.partition_type = 0 """.replace("\n", " ") ) @@ -61361,6 +61536,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND subpart.partition_type = 0 """.replace("\n", " ") ) @@ -61412,6 +61588,7 @@ WHERE c.is_hidden = 0 AND t.table_type in (0,2,3,8,9,14) AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND subpart.partition_type = 0 """.replace("\n", " ") ) @@ -61457,6 +61634,7 @@ WHERE AND t.table_type in (0,2,3,8,9,14) AND t.database_id = USERENV('SCHEMAID') AND bitand((t.TABLE_MODE / 4096), 15) IN (0,1) + AND subpart.partition_type = 0 """.replace("\n", " ") ) @@ -61548,7 +61726,8 @@ def_table_schema( ON T.TENANT_ID = P.TENANT_ID AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) - AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) + AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) + AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, @@ -61573,6 +61752,8 @@ def_table_schema( AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) + AND P.PARTITION_TYPE = 0 + AND SP.PARTITION_TYPE = 0 ) V JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT DB @@ -61679,6 +61860,7 @@ def_table_schema( AND T.TABLE_ID = P.TABLE_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) + AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, @@ -61703,6 +61885,8 @@ def_table_schema( AND T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) + AND P.PARTITION_TYPE = 0 + AND SP.PARTITION_TYPE = 0 ) V JOIN SYS.ALL_VIRTUAL_DATABASE_REAL_AGENT db @@ -61794,6 +61978,7 @@ def_table_schema( WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND bitand((T.TABLE_MODE / 4096), 15) IN (0,1) AND t.database_id = USERENV('SCHEMAID') + AND P.PARTITION_TYPE = 0 UNION ALL SELECT T.TENANT_ID, T.DATABASE_ID, @@ -61819,6 +62004,8 @@ def_table_schema( AND P.PART_ID = SP.PART_ID WHERE T.TABLE_TYPE IN (0,2,3,8,9,14,15) AND t.database_id = USERENV('SCHEMAID') + AND P.PARTITION_TYPE = 0 + AND SP.PARTITION_TYPE = 0 ) V LEFT JOIN SYS.ALL_VIRTUAL_TABLE_STAT_REAL_AGENT STAT @@ -64184,6 +64371,7 @@ FROM ( FROM SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID WHERE T.PART_LEVEL = 1 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() + AND P.PARTITION_TYPE = 0 UNION ALL @@ -64205,6 +64393,8 @@ FROM ( JOIN SYS.ALL_VIRTUAL_PART_REAL_AGENT P ON P.PART_ID =Q.PART_ID AND Q.TENANT_ID = P.TENANT_ID JOIN SYS.ALL_VIRTUAL_TABLE_REAL_AGENT T ON T.TABLE_ID =P.TABLE_ID AND T.TENANT_ID = Q.TENANT_ID WHERE T.PART_LEVEL = 2 AND T.TENANT_ID = EFFECTIVE_TENANT_ID() + AND Q.PARTITION_TYPE = 0 + AND P.PARTITION_TYPE = 0 ) A JOIN SYS.DBA_OB_TABLET_TO_LS B ON A.TABLET_ID = B.TABLET_ID JOIN SYS.DBA_OB_LS_LOCATIONS C ON B.LS_ID = C.LS_ID @@ -67059,7 +67249,13 @@ def_sys_index_table( index_type = 'INDEX_TYPE_NORMAL_LOCAL', keywords = all_def_keywords['__all_dbms_lock_allocated']) -# 101092: __all_tablet_reorganize_history +def_sys_index_table( + index_name = 'idx_tablet_his_table_id_src', + index_table_id = 101092, + index_columns = ['tenant_id', 'src_tablet_id'], + index_using_type = 'USING_BTREE', + index_type = 'INDEX_TYPE_NORMAL_LOCAL', + keywords = all_def_keywords['__all_tablet_reorganize_history']) def_sys_index_table( index_name = 'idx_kv_ttl_task_table_id', @@ -67215,6 +67411,14 @@ def_sys_index_table( # * # 100001: __all_table ################################################################################ +def_sys_index_table( + index_name = 'idx_tablet_his_table_id_dest', + index_table_id = 101104, + index_columns = ['tenant_id', 'dest_tablet_id'], + index_using_type = 'USING_BTREE', + index_type = 'INDEX_TYPE_NORMAL_LOCAL', + keywords = all_def_keywords['__all_tablet_reorganize_history']) + ################################################################################ # Oracle Agent table Index def_agent_index_table( 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 e875f4058..7824da3f1 100644 --- a/src/share/inner_table/ob_inner_table_schema_misc.ipp +++ b/src/share/inner_table/ob_inner_table_schema_misc.ipp @@ -1997,6 +1997,7 @@ case OB_ALL_VIRTUAL_TABLE_STAT_TID: case OB_ALL_VIRTUAL_TABLE_STAT_HISTORY_TID: case OB_ALL_VIRTUAL_TABLEGROUP_TID: case OB_ALL_VIRTUAL_TABLEGROUP_HISTORY_TID: +case OB_ALL_VIRTUAL_TABLET_REORGANIZE_HISTORY_TID: case OB_ALL_VIRTUAL_TABLET_TO_LS_TID: case OB_ALL_VIRTUAL_TABLET_TO_TABLE_HISTORY_TID: case OB_ALL_VIRTUAL_TEMP_TABLE_TID: @@ -4074,6 +4075,21 @@ case OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TID: break; } + case OB_ALL_VIRTUAL_TABLET_REORGANIZE_HISTORY_TID: { + ObIterateVirtualTable *iter = NULL; + if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { + SERVER_LOG(WARN, "create virtual table iterator failed", K(ret)); + } else if (OB_FAIL(iter->init(OB_ALL_TABLET_REORGANIZE_HISTORY_TID, index_schema, params))) { + SERVER_LOG(WARN, "virtual table iter init failed", K(ret)); + iter->~ObIterateVirtualTable(); + allocator.free(iter); + iter = NULL; + } else { + vt_iter = iter; + } + break; + } + case OB_ALL_VIRTUAL_TABLET_TO_LS_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -4148,7 +4164,9 @@ case OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TENANT_DIRECTORY_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -4163,9 +4181,7 @@ case OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TENANT_DIRECTORY_HISTORY_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -4450,7 +4466,9 @@ case OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TENANT_SCHEDULER_PROGRAM_ARGUMENT_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -4465,9 +4483,7 @@ case OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_TENANT_TABLESPACE_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -4752,7 +4768,9 @@ case OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TID: } break; } + END_CREATE_VT_ITER_SWITCH_LAMBDA + BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_USER_PROXY_INFO_HISTORY_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -4767,9 +4785,7 @@ case OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_HISTORY_TID: } break; } - END_CREATE_VT_ITER_SWITCH_LAMBDA - BEGIN_CREATE_VT_ITER_SWITCH_LAMBDA case OB_ALL_VIRTUAL_USER_PROXY_ROLE_INFO_TID: { ObIterateVirtualTable *iter = NULL; if (OB_FAIL(NEW_VIRTUAL_TABLE(ObIterateVirtualTable, iter))) { @@ -5170,6 +5186,7 @@ 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_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_TID: case OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TID: case OB_ALL_KV_TTL_TASK_HISTORY_IDX_KV_TTL_TASK_HISTORY_UPD_TIME_TID: case OB_ALL_MVIEW_REFRESH_RUN_STATS_IDX_MVIEW_REFRESH_RUN_STATS_NUM_MVS_CURRENT_TID: @@ -5183,6 +5200,7 @@ case OB_ALL_USER_PROXY_INFO_HISTORY_IDX_USER_PROXY_INFO_PROXY_USER_ID_HISTORY_TI case OB_ALL_USER_PROXY_ROLE_INFO_HISTORY_IDX_USER_PROXY_ROLE_INFO_PROXY_USER_ID_HISTORY_TID: case OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_TIME_TID: case OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_JOB_CLASS_TIME_TID: +case OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_TID: #endif @@ -5216,11 +5234,12 @@ case OB_ALL_DBLINK_TID: case OB_ALL_ROUTINE_PARAM_TID: case OB_ALL_DATABASE_PRIVILEGE_TID: case OB_ALL_TENANT_OLS_LABEL_TID: +case OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_TID: case OB_ALL_TENANT_KEYSTORE_TID: case OB_ALL_USER_PROXY_INFO_TID: case OB_ALL_COLUMN_TID: case OB_ALL_CLIENT_TO_SERVER_SESSION_INFO_TID: -case OB_ALL_MVIEW_REFRESH_RUN_STATS_TID: +case OB_ALL_TABLET_REORGANIZE_HISTORY_TID: case OB_ALL_KV_TTL_TASK_TID: case OB_ALL_RLS_CONTEXT_TID: case OB_ALL_BACKUP_SET_FILES_TID: @@ -5262,7 +5281,7 @@ case OB_ALL_TENANT_OBJECT_TYPE_TID: case OB_ALL_FOREIGN_KEY_HISTORY_TID: case OB_ALL_RLS_GROUP_HISTORY_TID: case OB_ALL_SYNONYM_TID: -case OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_TID: +case OB_ALL_MVIEW_REFRESH_RUN_STATS_TID: case OB_ALL_TENANT_SECURITY_AUDIT_TID: case OB_ALL_ROOTSERVICE_JOB_TID: case OB_ALL_PENDING_TRANSACTION_TID: @@ -5481,6 +5500,15 @@ case OB_ALL_TENANT_OLS_LABEL_TID: { } break; } +case OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_TID: { + if (FAILEDx(index_tids.push_back(OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_TIME_TID))) { + LOG_WARN("fail to push back index tid", KR(ret)); + } + if (FAILEDx(index_tids.push_back(OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_JOB_CLASS_TIME_TID))) { + LOG_WARN("fail to push back index tid", KR(ret)); + } + break; +} case OB_ALL_TENANT_KEYSTORE_TID: { if (FAILEDx(index_tids.push_back(OB_ALL_TENANT_KEYSTORE_IDX_KEYSTORE_MASTER_KEY_ID_TID))) { LOG_WARN("fail to push back index tid", KR(ret)); @@ -5508,8 +5536,11 @@ case OB_ALL_CLIENT_TO_SERVER_SESSION_INFO_TID: { } break; } -case OB_ALL_MVIEW_REFRESH_RUN_STATS_TID: { - if (FAILEDx(index_tids.push_back(OB_ALL_MVIEW_REFRESH_RUN_STATS_IDX_MVIEW_REFRESH_RUN_STATS_NUM_MVS_CURRENT_TID))) { +case OB_ALL_TABLET_REORGANIZE_HISTORY_TID: { + if (FAILEDx(index_tids.push_back(OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_TID))) { + LOG_WARN("fail to push back index tid", KR(ret)); + } + if (FAILEDx(index_tids.push_back(OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_TID))) { LOG_WARN("fail to push back index tid", KR(ret)); } break; @@ -5796,11 +5827,8 @@ case OB_ALL_SYNONYM_TID: { } break; } -case OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_TID: { - if (FAILEDx(index_tids.push_back(OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_TIME_TID))) { - LOG_WARN("fail to push back index tid", KR(ret)); - } - if (FAILEDx(index_tids.push_back(OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_JOB_CLASS_TIME_TID))) { +case OB_ALL_MVIEW_REFRESH_RUN_STATS_TID: { + if (FAILEDx(index_tids.push_back(OB_ALL_MVIEW_REFRESH_RUN_STATS_IDX_MVIEW_REFRESH_RUN_STATS_NUM_MVS_CURRENT_TID))) { LOG_WARN("fail to push back index tid", KR(ret)); } break; @@ -6180,6 +6208,21 @@ case OB_ALL_TENANT_OLS_LABEL_TID: { } break; } +case OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_TID: { + index_schema.reset(); + if (FAILEDx(ObInnerTableSchema::all_scheduler_job_run_detail_v2_idx_scheduler_job_run_detail_v2_time_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)); + } + index_schema.reset(); + if (FAILEDx(ObInnerTableSchema::all_scheduler_job_run_detail_v2_idx_scheduler_job_run_detail_v2_job_class_time_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_TENANT_KEYSTORE_TID: { index_schema.reset(); if (FAILEDx(ObInnerTableSchema::all_tenant_keystore_idx_keystore_master_key_id_schema(index_schema))) { @@ -6222,9 +6265,15 @@ case OB_ALL_CLIENT_TO_SERVER_SESSION_INFO_TID: { } break; } -case OB_ALL_MVIEW_REFRESH_RUN_STATS_TID: { +case OB_ALL_TABLET_REORGANIZE_HISTORY_TID: { index_schema.reset(); - if (FAILEDx(ObInnerTableSchema::all_mview_refresh_run_stats_idx_mview_refresh_run_stats_num_mvs_current_schema(index_schema))) { + if (FAILEDx(ObInnerTableSchema::all_tablet_reorganize_history_idx_tablet_his_table_id_src_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)); + } + index_schema.reset(); + if (FAILEDx(ObInnerTableSchema::all_tablet_reorganize_history_idx_tablet_his_table_id_dest_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)); @@ -6672,15 +6721,9 @@ case OB_ALL_SYNONYM_TID: { } break; } -case OB_ALL_SCHEDULER_JOB_RUN_DETAIL_V2_TID: { +case OB_ALL_MVIEW_REFRESH_RUN_STATS_TID: { index_schema.reset(); - if (FAILEDx(ObInnerTableSchema::all_scheduler_job_run_detail_v2_idx_scheduler_job_run_detail_v2_time_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)); - } - index_schema.reset(); - if (FAILEDx(ObInnerTableSchema::all_scheduler_job_run_detail_v2_idx_scheduler_job_run_detail_v2_job_class_time_schema(index_schema))) { + if (FAILEDx(ObInnerTableSchema::all_mview_refresh_run_stats_idx_mview_refresh_run_stats_num_mvs_current_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)); @@ -6944,6 +6987,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_DBMS_LOCK_ALLOCATED_IDX_DBMS_LOCK_ALLOCATED_EXPIRATION_TID))) { LOG_WARN("add index id failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_ids.push_back(OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_SRC_TID))) { + LOG_WARN("add index id failed", KR(ret), K(tenant_id)); } else if (OB_FAIL(table_ids.push_back(OB_ALL_KV_TTL_TASK_IDX_KV_TTL_TASK_TABLE_ID_TID))) { LOG_WARN("add index id failed", KR(ret), K(tenant_id)); } else if (OB_FAIL(table_ids.push_back(OB_ALL_KV_TTL_TASK_HISTORY_IDX_KV_TTL_TASK_HISTORY_UPD_TIME_TID))) { @@ -6970,5 +7015,7 @@ 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_SCHEDULER_JOB_RUN_DETAIL_V2_IDX_SCHEDULER_JOB_RUN_DETAIL_V2_JOB_CLASS_TIME_TID))) { LOG_WARN("add index id failed", KR(ret), K(tenant_id)); + } else if (OB_FAIL(table_ids.push_back(OB_ALL_TABLET_REORGANIZE_HISTORY_IDX_TABLET_HIS_TABLE_ID_DEST_TID))) { + LOG_WARN("add index id failed", KR(ret), K(tenant_id)); #endif diff --git a/src/share/inner_table/sys_package/dbms_space.sql b/src/share/inner_table/sys_package/dbms_space.sql new file mode 100644 index 000000000..205f5c37e --- /dev/null +++ b/src/share/inner_table/sys_package/dbms_space.sql @@ -0,0 +1,13 @@ +#package_name:dbms_space +#author: liuqifan.lqf + +CREATE OR REPLACE PACKAGE DBMS_SPACE AUTHID CURRENT_USER AS + PROCEDURE CREATE_INDEX_COST ( + ddl IN VARCHAR2, + used_bytes OUT NUMBER, + alloc_bytes OUT NUMBER, + plan_table IN VARCHAR2 := NULL + ); + +END DBMS_SPACE; +// \ No newline at end of file diff --git a/src/share/inner_table/sys_package/dbms_space_body.sql b/src/share/inner_table/sys_package/dbms_space_body.sql new file mode 100644 index 000000000..60a35196d --- /dev/null +++ b/src/share/inner_table/sys_package/dbms_space_body.sql @@ -0,0 +1,14 @@ +#package_name:dbms_space +#author: liuqifan.lqf + +CREATE OR REPLACE PACKAGE BODY DBMS_SPACE AS + PROCEDURE CREATE_INDEX_COST ( + ddl IN VARCHAR2, + used_bytes OUT NUMBER, + alloc_bytes OUT NUMBER, + plan_table IN VARCHAR2 DEFAULT NULL + ); + PRAGMA INTERFACE(C, CREATE_INDEX_COST); + +END DBMS_SPACE; +// \ No newline at end of file diff --git a/src/share/inner_table/sys_package/dbms_space_body_mysql.sql b/src/share/inner_table/sys_package/dbms_space_body_mysql.sql new file mode 100644 index 000000000..daf4d327c --- /dev/null +++ b/src/share/inner_table/sys_package/dbms_space_body_mysql.sql @@ -0,0 +1,13 @@ +#package_name:dbms_space +#author: liuqifan.lqf + +CREATE OR REPLACE PACKAGE BODY DBMS_SPACE + PROCEDURE CREATE_INDEX_COST ( + ddl VARCHAR(65535), + OUT used_bytes DECIMAL, + OUT alloc_bytes DECIMAL, + plan_table VARCHAR(65535) DEFAULT NULL + ); + PRAGMA INTERFACE(C, CREATE_INDEX_COST); + +END DBMS_SPACE; \ No newline at end of file diff --git a/src/share/inner_table/sys_package/dbms_space_mysql.sql b/src/share/inner_table/sys_package/dbms_space_mysql.sql new file mode 100644 index 000000000..7a7bd69a5 --- /dev/null +++ b/src/share/inner_table/sys_package/dbms_space_mysql.sql @@ -0,0 +1,12 @@ +#package_name:dbms_space +#author: liuqifan.lqf + +CREATE OR REPLACE PACKAGE DBMS_SPACE AUTHID CURRENT_USER + PROCEDURE CREATE_INDEX_COST ( + ddl VARCHAR(65535), + OUT used_bytes DECIMAL, + OUT alloc_bytes DECIMAL, + plan_table VARCHAR(65535) DEFAULT NULL + ); + +END DBMS_SPACE; \ No newline at end of file diff --git a/src/share/inner_table/table_id_to_name b/src/share/inner_table/table_id_to_name index 14c2913ce..c513e1cd8 100644 --- a/src/share/inner_table/table_id_to_name +++ b/src/share/inner_table/table_id_to_name @@ -329,6 +329,7 @@ # 478: __all_import_table_job_history # 479: __all_import_table_task # 480: __all_import_table_task_history +# 482: __all_tablet_reorganize_history # 483: __all_storage_ha_error_diagnose_history # 484: __all_storage_ha_perf_diagnose_history # 485: __all_clone_job @@ -1137,6 +1138,8 @@ # 12477: __all_virtual_user_proxy_role_info_history # 12477: __all_user_proxy_role_info # BASE_TABLE_NAME # 12477: __all_user_proxy_role_info_history # BASE_TABLE_NAME1 +# 12478: __all_virtual_tablet_reorganize_history +# 12478: __all_tablet_reorganize_history # BASE_TABLE_NAME # 12479: __all_virtual_res_mgr_directive # 12479: __all_res_mgr_directive # BASE_TABLE_NAME # 12480: __all_virtual_service @@ -3119,6 +3122,9 @@ # 101091: __idx_471_idx_dbms_lock_allocated_expiration # 101091: idx_dbms_lock_allocated_expiration # INDEX_NAME # 101091: __all_dbms_lock_allocated # DATA_BASE_TABLE_NAME +# 101092: __idx_482_idx_tablet_his_table_id_src +# 101092: idx_tablet_his_table_id_src # INDEX_NAME +# 101092: __all_tablet_reorganize_history # DATA_BASE_TABLE_NAME # 101093: __idx_410_idx_kv_ttl_task_table_id # 101093: idx_kv_ttl_task_table_id # INDEX_NAME # 101093: __all_kv_ttl_task # DATA_BASE_TABLE_NAME @@ -3160,6 +3166,9 @@ # 101106: __idx_519_idx_scheduler_job_run_detail_v2_job_class_time # 101106: idx_scheduler_job_run_detail_v2_job_class_time # INDEX_NAME # 101106: __all_scheduler_job_run_detail_v2 # DATA_BASE_TABLE_NAME +# 101104: __idx_482_idx_tablet_his_table_id_dest +# 101104: idx_tablet_his_table_id_dest # INDEX_NAME +# 101104: __all_tablet_reorganize_history # DATA_BASE_TABLE_NAME # 15306: __idx_15120_idx_data_table_id_real_agent # 15306: idx_data_table_id_real_agent # INDEX_NAME # 15306: __all_table # DATA_BASE_TABLE_NAME diff --git a/src/share/io/ob_io_define.cpp b/src/share/io/ob_io_define.cpp index bfb132df4..9d7aa952c 100644 --- a/src/share/io/ob_io_define.cpp +++ b/src/share/io/ob_io_define.cpp @@ -1114,6 +1114,11 @@ void ObIORequest::reset() //only for test, not dec resut_ref { int ret = OB_SUCCESS; retry_count_ = 0; + // only read need destroy here + // TODO(yanfeng): works now, need refactor + if (fd_.is_backup_block_file() && nullptr != io_result_ && io_result_->flag_.is_read()) { + backup::ObLSBackupFactory::free(static_cast(fd_.device_handle_)); + } if (nullptr != control_block_ && nullptr != fd_.device_handle_) { fd_.device_handle_->free_iocb(control_block_); control_block_ = nullptr; @@ -1403,7 +1408,9 @@ int ObIORequest::prepare(char *next_buffer, int64_t next_size, int64_t next_offs ret = OB_INVALID_ARGUMENT; LOG_WARN("io result is null", K(ret)); } else { - if (io_result_->flag_.is_read()) { + if (fd_.is_backup_block_file()) { + // ignore + } else if (io_result_->flag_.is_read()) { if (OB_FAIL(fd_.device_handle_->io_prepare_pread( fd_, io_buf, diff --git a/src/share/io/ob_io_struct.cpp b/src/share/io/ob_io_struct.cpp index 10349846b..ce4bda5be 100644 --- a/src/share/io/ob_io_struct.cpp +++ b/src/share/io/ob_io_struct.cpp @@ -2527,9 +2527,6 @@ int ObSyncIOChannel::do_sync_io(ObIORequest &req) ret = OB_NOT_SUPPORTED; LOG_WARN("not supported io mode", K(ret), K(req)); } - if (OB_NOT_NULL(req.io_result_)) { - req.io_result_->time_log_.return_ts_ = ObTimeUtility::fast_current_time(); - } if (OB_SUCC(ret)) { req.io_result_->complete_size_ = io_size; if (req.can_callback()) { diff --git a/src/share/ob_common_rpc_proxy.h b/src/share/ob_common_rpc_proxy.h index 7e864f9c4..f5f694fbb 100644 --- a/src/share/ob_common_rpc_proxy.h +++ b/src/share/ob_common_rpc_proxy.h @@ -67,6 +67,7 @@ public: RPC_S(PRD recover_restore_table_ddl, obrpc::OB_RECOVER_RESTORE_TABLE_DDL, (ObRecoverRestoreTableDDLArg)); RPC_S(PRD parallel_create_table, obrpc::OB_PARALLEL_CREATE_TABLE, (ObCreateTableArg), ObCreateTableRes); RPC_S(PRD alter_table, obrpc::OB_ALTER_TABLE, (ObAlterTableArg), ObAlterTableRes); + RPC_S(PRD split_global_index_tablet, obrpc::OB_SPLIT_GLOBAL_INDEX_TABLET, (ObAlterTableArg)); RPC_S(PRD create_hidden_table, obrpc::OB_CREATE_HIDDEN_TABLE, (obrpc::ObCreateHiddenTableArg), ObCreateHiddenTableRes); RPC_S(PRD alter_database, obrpc::OB_ALTER_DATABASE, (ObAlterDatabaseArg)); RPC_S(PRD drop_database, obrpc::OB_DROP_DATABASE, (ObDropDatabaseArg), ObDropDatabaseRes); @@ -261,6 +262,8 @@ public: RPC_S(PR5 request_time_zone_info, obrpc::OB_REQUEST_TIME_ZONE_INFO, (common::ObRequestTZInfoArg), common::ObRequestTZInfoResult); RPC_S(PR5 calc_column_checksum_response, obrpc::OB_CALC_COLUMN_CHECKSUM_RESPONSE, (obrpc::ObCalcColumnChecksumResponseArg)); RPC_S(PR5 build_ddl_single_replica_response, obrpc::OB_DDL_BUILD_SINGLE_REPLICA_RESPONSE, (obrpc::ObDDLBuildSingleReplicaResponseArg)); + RPC_S(PRD clean_splitted_tablet, obrpc::OB_CLEAN_SPLITTED_TABLET, (ObCleanSplittedTabletArg)); + RPC_S(PR5 send_auto_split_tablet_task_request, obrpc::OB_AUTO_SPLIT_TABLET_TASK_REQUEST, (obrpc::ObAutoSplitTabletBatchArg), obrpc::ObAutoSplitTabletBatchRes); RPC_S(PR5 cancel_ddl_task, obrpc::OB_CANCEL_DDL_TASK, (obrpc::ObCancelDDLTaskArg)); RPC_S(PR5 start_redef_table, obrpc::OB_START_REDEF_TABLE, (ObStartRedefTableArg), ObStartRedefTableRes); RPC_S(PR5 copy_table_dependents, obrpc::OB_COPY_TABLE_DEPENDENTS, (ObCopyTableDependentsArg)); diff --git a/src/share/ob_ddl_common.cpp b/src/share/ob_ddl_common.cpp index 846ead917..ec9bd4f52 100644 --- a/src/share/ob_ddl_common.cpp +++ b/src/share/ob_ddl_common.cpp @@ -28,6 +28,7 @@ #include "storage/tablet/ob_tablet.h" #include "storage/tx_storage/ob_ls_handle.h" #include "storage/tx_storage/ob_ls_map.h" +#include "storage/tx_storage/ob_ls_service.h" #include "rootserver/ob_root_service.h" #include "rootserver/ddl_task/ob_ddl_task.h" #include "storage/column_store/ob_column_oriented_sstable.h" @@ -140,6 +141,9 @@ const char *oceanbase::share::get_ddl_type(ObDDLType ddl_type) case ObDDLType::DDL_CHANGE_COLUMN_NAME: ret_name = "DDL_CHANGE_COLUMN_NAME"; break; + case ObDDLType::DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION: + ret_name = "DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION"; + break; default: break; } @@ -1789,6 +1793,29 @@ bool ObDDLUtil::need_remote_write(const int ret_code) || OB_EAGAIN == ret_code); } + +int ObDDLUtil::get_tablet_leader( + const uint64_t tenant_id, + const common::ObTabletID &tablet_id, + common::ObAddr &leader_addr) +{ + int ret = OB_SUCCESS; + ObLSLocation location; + share::ObLSID unused_ls_id; + if (OB_INVALID_TENANT_ID == tenant_id || !tablet_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get tablet leader, invalid id", K(ret), K(tenant_id), K(tablet_id)); + } else if (OB_FAIL(get_tablet_replica_location(tenant_id, tablet_id, unused_ls_id, location))) { + LOG_WARN("fail to get tablet replica location", K(ret), K(tenant_id), K(tablet_id)); + } else if (OB_FAIL(location.get_leader(leader_addr))) { + LOG_WARN("fail to get tablet leader addr", K(ret), K(tenant_id), K(tablet_id)); + } else if (!leader_addr.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get tablet leader, addr is invalid", K(ret), K(tenant_id), K(tablet_id)); + } + return ret; +} + int ObDDLUtil::get_tablet_paxos_member_list( const uint64_t tenant_id, const common::ObTabletID &tablet_id, @@ -1798,10 +1825,11 @@ int ObDDLUtil::get_tablet_paxos_member_list( int ret = OB_SUCCESS; ObLSLocation location; paxos_member_count = 0; + share::ObLSID unused_ls_id; if (OB_INVALID_TENANT_ID == tenant_id || !tablet_id.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("fail to get tablet replica location, invalid id", K(ret), K(tenant_id), K(tablet_id)); - } else if (OB_FAIL(get_tablet_replica_location(tenant_id, tablet_id, location))) { + } else if (OB_FAIL(get_tablet_replica_location(tenant_id, tablet_id, unused_ls_id, location))) { LOG_WARN("fail to get tablet replica location", K(tenant_id), K(tablet_id), K(ret)); } else { const ObIArray &ls_locations = location.get_replica_locations(); @@ -1821,17 +1849,102 @@ int ObDDLUtil::get_tablet_paxos_member_list( } return ret; } +int ObDDLUtil::get_tablet_physical_row_cnt( + const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const bool calc_sstable, + const bool calc_memtable, + int64_t &physical_row_count /*OUT*/) +{ + int ret = OB_SUCCESS; + + // get total rows of the table; physical + // src_tablet_id -> tablet -> sstables -> sstable_metas -> row_count + // -> memtables -> physical_row_cnt + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTableStoreIterator table_store_iter; + + physical_row_count = 0; + + if (!ls_id.is_valid() || !tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("get ls failed", K(ret), K(ls_id)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("fail to get tablet", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpecter error", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is nullptr", K(ret), K(tablet_handle)); + } else if (OB_FAIL(tablet->get_all_tables(table_store_iter))) { + LOG_WARN("get all tables failed", K(ret)); + } else if (!table_store_iter.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table_store_iter is invalid", K(ret), K(table_store_iter), KPC(tablet)); + } else { + table_store_iter.resume(); + while (OB_SUCC(ret)) { + ObITable *table = nullptr; + ObSSTable *sstable = nullptr; + memtable::ObMemtable* memtable = nullptr; + ObSSTableMetaHandle sstable_meta_hdl; + if (OB_FAIL(table_store_iter.get_next(table))) { + if (OB_UNLIKELY(OB_ITER_END == ret)) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("get next table failed", K(ret)); + } + } else if (OB_UNLIKELY(OB_ISNULL(table))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KPC(table)); + } else if (calc_sstable && table->is_sstable()) { + if (OB_FALSE_IT(sstable = static_cast(table))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sstable static_cast failed", K(ret), KPC(table)); + } else if (OB_ISNULL(sstable) || !sstable->is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the sstable is null or invalid", K(ret)); + } else if (OB_FAIL(sstable->get_meta(sstable_meta_hdl))) { + LOG_WARN("get sstable meta failed", K(ret), KPC(sstable)); + } else { + physical_row_count += sstable_meta_hdl.get_sstable_meta().get_row_count(); + } + } else if (calc_memtable && table->is_memtable()) { + if (OB_FALSE_IT(memtable = static_cast(table))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("memtable static_cast failed", K(ret), KPC(table)); + } else if (OB_ISNULL(memtable)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get memtable meta failed", K(ret), KPC(memtable)); + } else { + physical_row_count += memtable->get_physical_row_cnt(); + } + } + } // end while + } + if (OB_FAIL(ret)) { + physical_row_count = 0; + } + return ret; +} int ObDDLUtil::get_tablet_replica_location( const uint64_t tenant_id, const common::ObTabletID &tablet_id, + ObLSID &ls_id, ObLSLocation &location) { int ret = OB_SUCCESS; const int64_t cluster_id = GCONF.cluster_id; - share::ObLSID ls_id; int64_t expire_renew_time = INT64_MAX; bool is_cache_hit = false; + ls_id.reset(); if (OB_UNLIKELY(nullptr == GCTX.location_service_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("location service ptr is null", K(ret)); @@ -1855,6 +1968,96 @@ int ObDDLUtil::get_tablet_replica_location( return ret; } +// filter offline replica and arbitration one. +int ObDDLUtil::get_split_replicas_addrs( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + ObIArray &member_addrs_array, + ObIArray &learner_addrs_array) +{ + int ret = OB_SUCCESS; + member_addrs_array.reset(); + learner_addrs_array.reset(); + ObLSInfo ls_info; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(GCTX.lst_operator_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lst_operator is null", K(ret)); + } else if (OB_FAIL(GCTX.lst_operator_->get(GCONF.cluster_id, tenant_id, ls_id, share::ObLSTable::COMPOSITE_MODE/*for sys tenant only*/, ls_info))) { + LOG_WARN("fail to get ls info", K(ret), K(tenant_id), K(ls_id)); + } else { + int64_t leader_replica_index = OB_INVALID_INDEX; + ObArray filter_replica_addrs; // for split, we should ignore offline replica and arbitration replica. + const ObLSInfo::ReplicaArray &all_replicas = ls_info.get_replicas(); + for (int64_t idx = 0; OB_SUCC(ret) && idx < all_replicas.count(); idx++) { + const ObLSReplica &tmp_replica = all_replicas.at(idx); + if (REPLICA_TYPE_ARBITRATION == tmp_replica.get_replica_type() + || REPLICA_STATUS_OFFLINE == tmp_replica.get_replica_status()) { + if (OB_FAIL(filter_replica_addrs.push_back(tmp_replica.get_server()))) { + LOG_WARN("push back failed", K(ret)); + } else { + LOG_TRACE("filter offline replica and arbitration replica for split", K(ret), K(tmp_replica)); + } + } else if (ObRole::LEADER == tmp_replica.get_role()) { + leader_replica_index = idx; + } + } + if (OB_SUCC(ret)) { + if (OB_INVALID_INDEX == leader_replica_index) { + ret = OB_EAGAIN; + LOG_WARN("No leader found, try again", K(ret), K(tenant_id), K(ls_id), K(all_replicas)); + } else { + const ObLSReplica &leader_replica = all_replicas.at(leader_replica_index); + const ObLSReplica::MemberList &member_list = leader_replica.get_member_list(); + for (int64_t idx = 0; OB_SUCC(ret) && idx < member_list.count(); ++idx) { + const common::ObAddr &addr = member_list.at(idx).get_server(); + if (common::is_contain(filter_replica_addrs, addr)) { + // filter. + LOG_TRACE("ignore replica", K(ret), K(addr)); + } else if (OB_FAIL(member_addrs_array.push_back(addr))) { + LOG_WARN("failed to push addr", K(ret)); + } + } + const common::GlobalLearnerList &learner_list = leader_replica.get_learner_list(); + for (int64_t idx = 0; OB_SUCC(ret) && idx < learner_list.get_member_number(); ++idx) { + common::ObAddr addr; + if (OB_FAIL(learner_list.get_server_by_index(idx, addr))) { + LOG_WARN("failed to push addr", KR(ret), K(idx)); + } else if (OB_FAIL(learner_addrs_array.push_back(addr))) { + LOG_WARN("failed to push addr", KR(ret), K(addr)); + } + } + } + } + } + if (OB_SUCC(ret) && member_addrs_array.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected empty member list", K(ret), K(tenant_id), K(ls_id)); + } + return ret; +} + +int ObDDLUtil::get_split_replicas_addrs( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + ObIArray &replica_addr_array) +{ + int ret = OB_SUCCESS; + replica_addr_array.reset(); + ObArray member_addrs_array; + ObArray learners_addr_array; + if (OB_FAIL(get_split_replicas_addrs(tenant_id, ls_id, member_addrs_array, learners_addr_array))) { + LOG_WARN("get addrs failed", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(append(replica_addr_array/*dst*/, member_addrs_array/*src*/))) { + LOG_WARN("append failed", K(ret)); + } else if (OB_FAIL(append(replica_addr_array/*dst*/, learners_addr_array/*src*/))) { + LOG_WARN("append failed", K(ret)); + } + return ret; +} + int ObDDLUtil::construct_ls_tablet_id_map( const uint64_t &tenant_id, const share::ObLSID &ls_id, @@ -2397,6 +2600,18 @@ static inline void try_replace_user_tenant_id(const uint64_t user_tenant_id, uin check_tenant_id = !is_user_tenant(check_tenant_id) ? check_tenant_id : user_tenant_id; } +int ObDDLUtil::replace_user_tenant_id(const uint64_t tenant_id, + obrpc::ObPartitionSplitArg &split_arg) +{ + int ret = OB_SUCCESS; + if (!is_user_tenant(tenant_id)) { + LOG_TRACE("not user tenant, no need to replace", K(tenant_id)); + } else { + try_replace_user_tenant_id(tenant_id, split_arg.exec_tenant_id_); + } + return ret; +} + int ObDDLUtil::replace_user_tenant_id( const ObDDLType &ddl_type, const uint64_t tenant_id, @@ -3029,6 +3244,35 @@ int ObDDLUtil::update_tablet_gc_info(const ObTabletID &tablet_id, const int64_t #endif +int ObDDLUtil::get_global_index_table_ids(const schema::ObTableSchema &table_schema, ObIArray &global_index_table_ids, ObSchemaGetterGuard &schema_guard) +{ + int ret = OB_SUCCESS; + ObSEArray simple_index_infos; + global_index_table_ids.reset(); + if (OB_UNLIKELY(!table_schema.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(table_schema), K(table_schema.is_valid())); + } else if (OB_FAIL(table_schema.get_simple_index_infos(simple_index_infos))) { + LOG_WARN("get simple index infos failed", K(ret)); + } else { + const uint64_t tenant_id = table_schema.get_tenant_id(); + for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); i++) { + const ObTableSchema *aux_table_schema = NULL; + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, simple_index_infos.at(i).table_id_, aux_table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(tenant_id), K(simple_index_infos.at(i).table_id_)); + } else if (OB_ISNULL(aux_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table schema should not be null", K(ret)); + } else if (aux_table_schema->is_global_index_table()) { + if (OB_FAIL(global_index_table_ids.push_back(aux_table_schema->get_table_id()))) { + LOG_WARN("failed to push back", K(ret), K(aux_table_schema->get_table_id())); + } + } + } + } + return ret; +} + int64_t ObDDLUtil::get_real_parallelism(const int64_t parallelism, const bool is_mv_refresh) { int64_t real_parallelism = 0L; @@ -3838,6 +4082,40 @@ int ObCODDLUtil::need_column_group_store(const schema::ObTableSchema &table_sche return ret; } +// for partition split. +int ObSplitUtil::deserializ_parallel_datum_rowkey( + common::ObIAllocator &rowkey_allocator, + const char *buf, const int64_t data_len, int64_t &pos, + ObIArray ¶llel_datum_rowkey_list) +{ + int ret = OB_SUCCESS; + parallel_datum_rowkey_list.reset(); + if (pos == data_len) { + LOG_INFO("no parallel info", K(pos), K(data_len), KP(buf)); + } else if (OB_UNLIKELY(nullptr == buf || pos > data_len)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KP(buf), K(pos), K(data_len)); + } else { + int64_t rowkey_arr_cnt = 0; + LST_DO_CODE(OB_UNIS_DECODE, rowkey_arr_cnt); + if (FAILEDx(parallel_datum_rowkey_list.prepare_allocate(rowkey_arr_cnt))) { + LOG_WARN("reserve failed", K(ret), K(rowkey_arr_cnt)); + } else { + ObStorageDatum tmp_storage_datum[OB_INNER_MAX_ROWKEY_COLUMN_NUMBER]; + ObDatumRowkey tmp_datum_rowkey; + tmp_datum_rowkey.assign(tmp_storage_datum, OB_INNER_MAX_ROWKEY_COLUMN_NUMBER); + for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_arr_cnt; i++) { + if (OB_FAIL(tmp_datum_rowkey.deserialize(buf, data_len, pos))) { + LOG_WARN("failed to decode concurrent cnt", K(ret), K(i), K(rowkey_arr_cnt), K(data_len), K(pos)); + } else if (OB_FAIL(tmp_datum_rowkey.deep_copy(parallel_datum_rowkey_list.at(i), rowkey_allocator))) { + LOG_WARN("failed to deep copy end key", K(ret), K(i), K(tmp_datum_rowkey)); + } + } + } + } + return ret; +} + //record trace_id ObDDLEventInfo::ObDDLEventInfo() : addr_(GCTX.self_addr()), diff --git a/src/share/ob_ddl_common.h b/src/share/ob_ddl_common.h index 274127439..615593ecb 100644 --- a/src/share/ob_ddl_common.h +++ b/src/share/ob_ddl_common.h @@ -18,6 +18,7 @@ #include "share/schema/ob_table_schema.h" #include "share/schema/ob_schema_service.h" #include "share/location_cache/ob_location_struct.h" +#include "storage/blocksstable/ob_block_sstable_struct.h" #include "storage/tablet/ob_tablet_common.h" namespace oceanbase @@ -25,6 +26,7 @@ namespace oceanbase namespace obrpc { class ObSrvRpcProxy; +struct ObPartitionSplitArg; struct ObAlterTableArg; struct ObDropDatabaseArg; struct ObDropTableArg; @@ -357,6 +359,22 @@ static const char* ddl_task_status_to_str(const ObDDLTaskStatus &task_status) { return str; } +static bool is_partition_split_recovery_table_redefinition(const ObDDLType ddl_type) { + return ddl_type == DDL_PARTITION_SPLIT_RECOVERY_TABLE_REDEFINITION; +} + +static bool is_tablet_split(const ObDDLType ddl_type) { + return ddl_type >= DDL_AUTO_SPLIT_BY_RANGE && ddl_type <= DDL_MANUAL_SPLIT_NON_RANGE; +} + +static bool is_range_split(const ObDDLType ddl_type) { + return DDL_AUTO_SPLIT_BY_RANGE == ddl_type || DDL_MANUAL_SPLIT_BY_RANGE == ddl_type; +} + +static bool is_auto_split(const ObDDLType ddl_type) { + return DDL_AUTO_SPLIT_BY_RANGE == ddl_type || DDL_AUTO_SPLIT_NON_RANGE == ddl_type; +} + static inline bool is_simple_table_long_running_ddl(const ObDDLType type) { return type > DDL_INVALID && type < DDL_DROP_SCHEMA_AVOID_CONCURRENT_TRANS; @@ -429,6 +447,17 @@ static inline bool is_direct_load_retry_err(const int ret) ; } +static inline bool is_supported_pre_split_ddl_type(const ObDDLType type) +{ + return DDL_MODIFY_COLUMN == type + || DDL_ADD_PRIMARY_KEY == type + || DDL_DROP_PRIMARY_KEY == type + || DDL_ALTER_PRIMARY_KEY == type + || DDL_CONVERT_TO_CHARACTER == type + || DDL_TABLE_REDEFINITION == type + || DDL_ALTER_PARTITION_BY == type; +} + static inline bool is_replica_build_ddl_task_status(const ObDDLTaskStatus &task_status) { return ObDDLTaskStatus::REPENDING == task_status || ObDDLTaskStatus::REDEFINITION == task_status; @@ -639,7 +668,17 @@ public: static int get_tablet_replica_location( const uint64_t tenant_id, const common::ObTabletID &tablet_id, + ObLSID &ls_id, ObLSLocation &location); + static int get_split_replicas_addrs( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + ObIArray &member_addrs_array, + ObIArray &learner_addrs_array); + static int get_split_replicas_addrs( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + ObIArray &replica_addr_array); static int construct_ls_tablet_id_map( const uint64_t &tenant_id, const share::ObLSID &ls_id, @@ -676,7 +715,10 @@ public: const ObString &partition_name, common::ObIAllocator &allocator, bool &is_running_status); - + static int get_tablet_leader( + const uint64_t tenant_id, + const common::ObTabletID &tablet_id, + common::ObAddr &leader_addr); static int check_table_exist( const uint64_t tenant_id, const uint64_t table_id, @@ -696,6 +738,7 @@ public: int64_t &snapshot_version, share::ObDDLTaskStatus &task_status); + static int replace_user_tenant_id(const uint64_t tenant_id, obrpc::ObPartitionSplitArg &split_arg); static int get_data_information( const uint64_t tenant_id, const uint64_t task_id, @@ -766,13 +809,17 @@ public: share::schema::ObSchemaGetterGuard &hold_buf_dst_tenant_schema_guard, share::schema::ObSchemaGetterGuard *&src_tenant_schema_guard, share::schema::ObSchemaGetterGuard *&dst_tenant_schema_guard); - + static int get_tablet_physical_row_cnt( + const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const bool calc_sstable, + const bool calc_memtable, + int64_t &physical_row_count /*OUT*/); static int check_table_empty_in_oracle_mode( const uint64_t tenant_id, const uint64_t table_id, share::schema::ObSchemaGetterGuard &schema_guard, bool &is_table_empty); - static int check_tenant_status_normal( ObISQLClient *proxy, const uint64_t check_tenant_id); @@ -833,6 +880,7 @@ public: } return res; } + static int get_global_index_table_ids(const schema::ObTableSchema &table_schema, ObIArray &global_index_table_ids, share::schema::ObSchemaGetterGuard &schema_guard); static bool use_idempotent_mode(const int64_t data_format_version); static bool is_mview_not_retryable(const int64_t data_format_version, const share::ObDDLType task_type); static int64_t get_real_parallelism(const int64_t parallelism, const bool is_mv_refresh); @@ -995,6 +1043,15 @@ private: hash::ObHashMap> &ip_tablets_map); }; +class ObSplitUtil +{ +public: + static int deserializ_parallel_datum_rowkey( + common::ObIAllocator &rowkey_allocator, + const char *buf, const int64_t data_len, int64_t &pos, + ObIArray ¶llel_datum_rowkey_list); +}; + typedef common::ObCurTraceId::TraceId DDLTraceId; class ObDDLEventInfo final { diff --git a/src/share/ob_debug_sync_point.h b/src/share/ob_debug_sync_point.h index 7c2259907..bb9ec3685 100755 --- a/src/share/ob_debug_sync_point.h +++ b/src/share/ob_debug_sync_point.h @@ -340,11 +340,15 @@ class ObString; ACT(COLUMN_REDEFINITION_COPY_TABLE_CONSTRAINTS,)\ ACT(COLUMN_REDEFINITION_COPY_TABLE_FOREIGN_KEYS,)\ ACT(COLUMN_REDEFINITION_TAKE_EFFECT,)\ + ACT(PARTITION_SPLIT_PREPARE,) \ ACT(PARTITION_SPLIT_WAIT_FREEZE_END,)\ ACT(PARTITION_SPLIT_WAIT_COMPACTION_END,)\ ACT(PARTITION_SPLIT_WAIT_DATA_TABLET_SPLIT_END,)\ ACT(PARTITION_SPLIT_WAIT_LOCAL_INDEX_SPLIT_END,)\ ACT(PARTITION_SPLIT_WAIT_LOB_TABLET_SPLIT_END,)\ + ACT(PARTITION_SPLIT_WAIT_TRANS_END,)\ + ACT(PARTITION_SPLIT_TAKE_EFFECT,)\ + ACT(PARTITION_SPLIT_SUCCESS,)\ ACT(CREATE_INDEX_WAIT_TRANS_END,)\ ACT(CREATE_INDEX_REPLICA_BUILD,)\ ACT(CREATE_INDEX_VERIFY_CHECKSUM,)\ @@ -600,6 +604,7 @@ class ObString; ACT(HANG_IN_CLONE_SYS_FAILED_STATUS,)\ ACT(BEFORE_BACKUP_PREFETCH_TASK,)\ ACT(BEFORE_BACKUP_DATA_TASK,)\ + ACT(BEFORE_CHECK_NEED_TABLET_GC,)\ ACT(BEFORE_TABLET_FULL_DIRECT_LOAD_MGR_CLOSE,)\ ACT(BEFORE_WAIT_TRANSFER_OUT_TABLET_READY,)\ ACT(BEFORE_CHECK_TABLET_READY,)\ @@ -618,13 +623,6 @@ class ObString; ACT(BEFORE_MIGRATE_WARMUP_RETRY_FETCH_DAG,)\ ACT(BEFORE_ADD_SERVER_TRANS,)\ ACT(AFTER_MEMBERLIST_CHANGED,)\ - ACT(AFTER_CREATE_SPLIT_TASK,)\ - ACT(BEFORE_PARTITION_SPLIT_TASK_CLEANUP,)\ - ACT(BEFORE_TABLET_SPLIT_PREPARE_TASK,)\ - ACT(BEFORE_TABLET_SPLIT_WRITE_TASK,)\ - ACT(BEFORE_TABLET_SPLIT_MERGE_TASK,)\ - ACT(AFTER_TABLET_SPLIT_MERGE_TASK,)\ - ACT(BEFORE_CHECK_NEED_TABLET_GC,)\ ACT(AFTER_FIRST_CLONE_CHECK_FOR_STANDBY,)\ ACT(BEFORE_REMOVE_BALANCE_TASK_HELPER,)\ ACT(BEFORE_CHOOSE_SOURCE,)\ @@ -648,6 +646,15 @@ class ObString; ACT(AFTER_PHYSICAL_RESTORE_CREATE_TENANT,)\ ACT(BEFROE_UPDATE_MIG_TABLET_CONVERT_CO_PROGRESSING,)\ ACT(AFTER_SET_CO_CONVERT_RETRY_EXHUASTED,)\ + ACT(AFTER_CREATE_SPLIT_TASK,)\ + ACT(BEFORE_PARTITION_SPLIT_TASK_CLEANUP,)\ + ACT(BEFORE_TABLET_SPLIT_PREPARE_TASK,)\ + ACT(BEFORE_TABLET_SPLIT_WRITE_TASK,)\ + ACT(BEFORE_TABLET_SPLIT_MERGE_TASK,)\ + ACT(AFTER_TABLET_SPLIT_MERGE_TASK,)\ + ACT(START_DDL_PRE_SPLIT_PARTITION,)\ + ACT(BEFORE_PREFETCH_BACKUP_INFO_TASK,)\ + ACT(RS_CHANGE_TURN_DEBUG_SYNC,)\ ACT(MAX_DEBUG_SYNC_POINT,) DECLARE_ENUM(ObDebugSyncPoint, debug_sync_point, OB_DEBUG_SYNC_POINT_DEF); diff --git a/src/share/ob_errno.cpp b/src/share/ob_errno.cpp index 92f73647b..83627293e 100644 --- a/src/share/ob_errno.cpp +++ b/src/share/ob_errno.cpp @@ -27501,13 +27501,13 @@ static const _error _error_OB_TABLET_IS_SPLIT_SRC = { .error_solution = "Contact OceanBase Support", .mysql_errno = -1, .sqlstate = "HY000", - .str_error = "cannot access split src tablet", - .str_user_error = "cannot access split src tablet", + .str_error = "cannot write to split src tablet", + .str_user_error = "cannot write to split src tablet", .oracle_errno = 600, - .oracle_str_error = "ORA-00600: internal error code, arguments: -9123, cannot access split src tablet", - .oracle_str_user_error = "ORA-00600: internal error code, arguments: -9123, cannot access split src tablet", - .ob_str_error = "OBE-00600: internal error code, arguments: -9123, cannot access split src tablet", - .ob_str_user_error = "OBE-00600: internal error code, arguments: -9123, cannot access split src tablet" + .oracle_str_error = "ORA-00600: internal error code, arguments: -9123, cannot write to split src tablet", + .oracle_str_user_error = "ORA-00600: internal error code, arguments: -9123, cannot write to split src tablet", + .ob_str_error = "OBE-00600: internal error code, arguments: -9123, cannot write to split src tablet", + .ob_str_user_error = "OBE-00600: internal error code, arguments: -9123, cannot write to split src tablet" }; static const _error _error_OB_ALLOCATE_TMP_FILE_PAGE_FAILED = { .error_name = "OB_ALLOCATE_TMP_FILE_PAGE_FAILED", diff --git a/src/share/ob_errno.def b/src/share/ob_errno.def index b74f05b33..06336b4a9 100755 --- a/src/share/ob_errno.def +++ b/src/share/ob_errno.def @@ -2325,8 +2325,7 @@ DEFINE_ERROR_EXT_DEP(OB_RESTORE_SOURCE_NOT_ENOUGH, -9119, -1, "HY000", "do not h DEFINE_ERROR_DEP(OB_OBJECT_NOT_EXIST, -9120, -1, "HY000", "cannot find object on object storage"); DEFINE_ERROR_DEP(OB_S2_REUSE_VERSION_MISMATCH, -9121, -1, "HY000", "reuse_version of mem_block or phy_block is not mismatched with micro_meta in s2 micro_cache"); DEFINE_ERROR_DEP(OB_S2_ENTRY_NOT_EXIST, -9122, -1, "HY000", "entry not exist in s2 micro_cache"); -DEFINE_ERROR(OB_TABLET_IS_SPLIT_SRC, -9123, -1, "HY000", "cannot access split src tablet"); - +DEFINE_ERROR(OB_TABLET_IS_SPLIT_SRC, -9123, -1, "HY000", "cannot write to split src tablet"); DEFINE_ERROR_DEP(OB_ALLOCATE_TMP_FILE_PAGE_FAILED, -9124, -1, "HY000", "fail to allocate a tmp file page"); DEFINE_ERROR_DEP(OB_SS_MICRO_CACHE_DISABLED, -9125, -1, "HY000", "ss_micro_cache is disabled"); DEFINE_ERROR_DEP(OB_SS_CACHE_REACH_MEM_LIMIT, -9126, -1, "HY000", "ss_micro_cache has reached memory limit"); diff --git a/src/share/ob_errno.h b/src/share/ob_errno.h index 529ebc212..87bd88774 100644 --- a/src/share/ob_errno.h +++ b/src/share/ob_errno.h @@ -3905,7 +3905,7 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_OBJECT_NOT_EXIST__USER_ERROR_MSG "cannot find object on object storage" #define OB_S2_REUSE_VERSION_MISMATCH__USER_ERROR_MSG "reuse_version of mem_block or phy_block is not mismatched with micro_meta in s2 micro_cache" #define OB_S2_ENTRY_NOT_EXIST__USER_ERROR_MSG "entry not exist in s2 micro_cache" -#define OB_TABLET_IS_SPLIT_SRC__USER_ERROR_MSG "cannot access split src tablet" +#define OB_TABLET_IS_SPLIT_SRC__USER_ERROR_MSG "cannot write to split src tablet" #define OB_ALLOCATE_TMP_FILE_PAGE_FAILED__USER_ERROR_MSG "fail to allocate a tmp file page" #define OB_SS_MICRO_CACHE_DISABLED__USER_ERROR_MSG "ss_micro_cache is disabled" #define OB_SS_CACHE_REACH_MEM_LIMIT__USER_ERROR_MSG "ss_micro_cache has reached memory limit" @@ -8226,8 +8226,8 @@ constexpr int OB_ERR_INVALID_DATE_MSG_FMT_V2 = -4219; #define OB_S2_REUSE_VERSION_MISMATCH__OBE_USER_ERROR_MSG "OBE-00600: internal error code, arguments: -9121, reuse_version of mem_block or phy_block is not mismatched with micro_meta in s2 micro_cache" #define OB_S2_ENTRY_NOT_EXIST__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -9122, entry not exist in s2 micro_cache" #define OB_S2_ENTRY_NOT_EXIST__OBE_USER_ERROR_MSG "OBE-00600: internal error code, arguments: -9122, entry not exist in s2 micro_cache" -#define OB_TABLET_IS_SPLIT_SRC__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -9123, cannot access split src tablet" -#define OB_TABLET_IS_SPLIT_SRC__OBE_USER_ERROR_MSG "OBE-00600: internal error code, arguments: -9123, cannot access split src tablet" +#define OB_TABLET_IS_SPLIT_SRC__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -9123, cannot write to split src tablet" +#define OB_TABLET_IS_SPLIT_SRC__OBE_USER_ERROR_MSG "OBE-00600: internal error code, arguments: -9123, cannot write to split src tablet" #define OB_ALLOCATE_TMP_FILE_PAGE_FAILED__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -9124, fail to allocate a tmp file page" #define OB_ALLOCATE_TMP_FILE_PAGE_FAILED__OBE_USER_ERROR_MSG "OBE-00600: internal error code, arguments: -9124, fail to allocate a tmp file page" #define OB_SS_MICRO_CACHE_DISABLED__ORA_USER_ERROR_MSG "ORA-00600: internal error code, arguments: -9125, ss_micro_cache is disabled" diff --git a/src/share/ob_local_device.cpp b/src/share/ob_local_device.cpp index 5a5faedcf..c550d023b 100644 --- a/src/share/ob_local_device.cpp +++ b/src/share/ob_local_device.cpp @@ -1369,7 +1369,7 @@ int ObLocalDevice::resize_block_file(const int64_t new_size) } else if (0 == delta_size) { SHARE_LOG(INFO, "The file size is not changed, ", K(new_size), K(block_file_size_)); } else if (0 != (sys_ret = ::fallocate(block_fd_, 0, block_file_size_, delta_size))) { - ret = ObIODeviceLocalFileOp::convert_sys_errno();; + ret = ObIODeviceLocalFileOp::convert_sys_errno(); SHARE_LOG(WARN, "fail to expand file size", K(ret), K(sys_ret), K(block_file_size_), K(delta_size), K(errno), KERRMSG); } else if (OB_ISNULL(new_free_block_array diff --git a/src/share/ob_partition_split_query.cpp b/src/share/ob_partition_split_query.cpp new file mode 100644 index 000000000..6cb84c206 --- /dev/null +++ b/src/share/ob_partition_split_query.cpp @@ -0,0 +1,522 @@ +/** + * 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_partition_split_query.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/tablet/ob_tablet_split_mds_helper.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/ls/ob_ls.h" + +using namespace oceanbase::share; +using namespace oceanbase::common; +using namespace oceanbase::share::schema; +using namespace oceanbase::obrpc; +using namespace oceanbase::sql; +using namespace oceanbase::storage; + +int ObPartitionSplitQuery::get_tablet_handle( + const ObTabletID &tablet_id, + const ObLSID &ls_id, + storage::ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + const ObTabletMapKey key(ls_id, tablet_id); + const int64_t snapshot_version = INT64_MAX; // MAX_TRANS_VERSION + if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, tablet_handle, + ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, + ObMDSGetTabletMode::READ_READABLE_COMMITED, + snapshot_version))) { + if (OB_TABLET_NOT_EXIST != ret) { + LOG_WARN("fail to check and get tablet", K(ret), K(key), K(snapshot_version)); + } + } else if (OB_ISNULL(tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet handle is invalid", K(ret), K(tablet_handle)); + } + return ret; +} + +/* + * Atention!!! + * split range is left close right open, like: [1,10) + * note: + * if split start key >= src end key or split end key <= src start key, not need to split + * new start key = max (split start key, src start key) + * new end key = min (split end key, src end key) + * if split start key > src start key, set left bounder closed + * if split end key < src end key, set right bounder closed +*/ +int ObPartitionSplitQuery::get_tablet_split_range( + const ObTablet &tablet, + const blocksstable::ObStorageDatumUtils &datum_utils, + const storage::ObTabletSplitTscInfo &split_info, + ObIAllocator &allocator, + blocksstable::ObDatumRange &src_range) +{ + int ret = OB_SUCCESS; + int compare_ret = 0; + + if (!src_range.is_valid() || !split_info.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to split range, invalid argument", K(ret), K(src_range), K(split_info)); + } else { + if (split_info.split_type_ == ObTabletSplitType::RANGE && split_info.partkey_is_rowkey_prefix_) { + const ObDatumRowkey &split_start_key = split_info.start_partkey_; + const ObDatumRowkey &split_end_key = split_info.end_partkey_; + const ObDatumRowkey &src_start_key = src_range.get_start_key(); + const ObDatumRowkey &src_end_key = src_range.get_end_key(); + bool is_empty_range = false; + // ObDatumRowkey + if (OB_FAIL(split_start_key.compare(split_end_key, datum_utils, compare_ret))) { + LOG_WARN("fail to split range, compare error.", K(ret), K(split_info)); + } else if (compare_ret >= 0) { // invalid split key range + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to split range, left key should smaller than right key", K(ret), K(split_info)); + } else if (OB_FAIL(src_start_key.compare(src_end_key, datum_utils, compare_ret))) { + LOG_WARN("fail to split range, compare error.", K(ret), K(src_range)); + } else if (compare_ret > 0 || + (compare_ret == 0 && (src_range.is_left_open() || src_range.is_right_open()))) { + /* src range left/right bounder not all closed but left key equal to right, + * like (1,1] or [1,1) or (1,1), return empty range */ + is_empty_range = true; + } else { + if (OB_FAIL(split_start_key.compare(src_end_key, datum_utils, compare_ret))) { + LOG_WARN("fail to split range, compare error.", K(ret), K(split_info)); + } else if (compare_ret >= 0) { + is_empty_range = true; + if (compare_ret == 0) { + // when split start key == src end key, src range is only src end key + // when compare_ret is 0, split key column cnt must be equal to src key column cnt + if (src_range.is_right_closed()) { + src_range.set_start_key(split_start_key); + src_range.set_end_key(split_start_key); + src_range.set_left_closed(); + is_empty_range = false; + } + } + } else if (OB_FAIL(split_end_key.compare(src_start_key, datum_utils, compare_ret))) { + LOG_WARN("fail to split range, compare error.", K(ret), K(split_info)); + } else if (compare_ret <= 0) { + /* split end key <= src start key, no need change src range, + * the result should be empty because split range is right bounder open. + * like: src=[3,5], split=[1,3), result=[] */ + is_empty_range = true; + } else { + if (OB_FAIL(split_start_key.compare(src_start_key, datum_utils, compare_ret))) { + LOG_WARN("fail to compare start key to src start key", K(ret), K(split_start_key), K(src_range)); + } else if (compare_ret > 0) { + // split start key > src start key, set src start key to split start key + ObDatumRowkey new_key; + if (split_start_key.get_datum_cnt() < src_start_key.get_datum_cnt()) { + if (OB_FAIL(copy_split_key(split_start_key, src_start_key, new_key, allocator))) { + LOG_WARN("fail to copy split key.", K(ret)); + } else { + src_range.set_start_key(new_key); + src_range.set_left_open(); + } + } else { + src_range.set_start_key(split_start_key); + src_range.set_left_closed(); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(split_end_key.compare(src_end_key, datum_utils, compare_ret))) { + LOG_WARN("fail to compare end key to src start key", K(ret), K(split_end_key), K(src_range)); + } else if (compare_ret <= 0) { + /* split end key <= src end key, set end key of split end key and right bounder open + * like: src=[1,5], split=[2,5), result=[2,5) */ + ObDatumRowkey new_key; + if (split_end_key.get_datum_cnt() < src_end_key.get_datum_cnt()) { + if (OB_FAIL(copy_split_key(split_end_key, src_end_key, new_key, allocator))) { + LOG_WARN("fail to copy split key.", K(ret)); + } else { + src_range.set_end_key(new_key); + } + } else { + src_range.set_end_key(split_end_key); + } + if (OB_SUCC(ret)) { + src_range.set_right_open(); + } + } + } + } + } + if (OB_SUCC(ret)) { + if (is_empty_range) { + src_range.reset(); // set empty range + } else { + const ObColDescIArray &col_descs = tablet.get_rowkey_read_info().get_columns_desc(); + if (OB_FAIL(src_range.prepare_memtable_readable(col_descs, allocator))) { + STORAGE_LOG(WARN, "Fail to transfer store rowkey", K(ret), K(src_range), K(col_descs)); + } + } + } + } else { + LOG_INFO("No need to split range", K(split_info)); + } + } + return ret; +} + +int ObPartitionSplitQuery::copy_split_key( + const ObDatumRowkey &split_key, + const ObDatumRowkey &src_key, + ObDatumRowkey &new_key, + ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + // copy column datum + ObStorageDatum *datums = nullptr; + const int src_datum_cnt = src_key.get_datum_cnt(); + if (OB_ISNULL(datums = (ObStorageDatum*) allocator.alloc(sizeof(ObStorageDatum) * src_datum_cnt))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + COMMON_LOG(WARN, "Failed to alloc memory for datum key", K(ret), K(src_datum_cnt)); + } else { + datums = new (datums) ObStorageDatum[src_datum_cnt]; + for (int64_t i = 0; i < src_datum_cnt; ++ i) { + if (i < split_key.get_datum_cnt()) { + datums[i] = split_key.get_datum(i); + } else { + datums[i].set_min(); + } + } + if (OB_FAIL(new_key.assign(datums, src_datum_cnt))) { + STORAGE_LOG(WARN, "Failed to assign datum rowkey", K(ret), KP(datums), K(src_datum_cnt)); + new_key.reset(); + allocator.free(datums); + datums = nullptr; + } + } + return ret; +} + +int ObPartitionSplitQuery::get_tablet_split_ranges( + const common::ObIArray &ori_ranges, + common::ObIArray &new_ranges, + ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + if (tablet_handle_.is_valid() && split_info_.is_valid()) { + if (ObTabletSplitType::RANGE == split_info_.split_type_) { // RANGE + new_ranges.reset(); + ObDatumRange datum_range; + common::ObStoreRange tmp_range; + + const ObStorageDatumUtils &datum_utils = + tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(); + const ObColDescIArray &col_descs = + tablet_handle_.get_obj()->get_rowkey_read_info().get_columns_desc(); + + for (int64_t i = 0; OB_SUCC(ret) && i < ori_ranges.count(); i++) { + tmp_range.reset(); + if (OB_FAIL(ori_ranges.at(i).deep_copy(allocator, tmp_range))) { + LOG_WARN("Fail to deep copy src range", K(ret), K(ori_ranges.at(i))); + } else if (OB_FAIL(datum_range.from_range(tmp_range, allocator))) { + LOG_WARN("Failed to transfer store range", K(ret), K(tmp_range)); + } else if (OB_FAIL(get_tablet_split_range(*tablet_handle_.get_obj(), datum_utils, split_info_, allocator, datum_range))) { + LOG_WARN("Fail to get tabelt split range", K(ret), K(split_info_)); + } else if (OB_FAIL(datum_range.to_store_range(col_descs, allocator, tmp_range))) { + LOG_WARN("fail to transfer to store range", K(ret), K(datum_range)); + } else if (OB_FAIL(new_ranges.push_back(tmp_range))) { + LOG_WARN("Fail to push back to new ranges", K(ret), K(tmp_range)); + } + } + } + } + return ret; +} + +int ObPartitionSplitQuery::get_split_datum_range( + const blocksstable::ObStorageDatumUtils *datum_utils, + ObIAllocator &allocator, + blocksstable::ObDatumRange &datum_range) +{ + int ret = OB_SUCCESS; + if (tablet_handle_.is_valid() && split_info_.is_valid()) { + if (OB_ISNULL(datum_utils)) { + datum_utils = &tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(); + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(get_tablet_split_range(*tablet_handle_.get_obj(), *datum_utils, split_info_, allocator, datum_range))) { + STORAGE_LOG(WARN, "Failed to split range", K(ret), K(split_info_)); + } + } + return ret; +} + +int ObPartitionSplitQuery::get_tablet_split_info( + const ObTabletID &tablet_id, + const ObLSID &ls_id, + ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + + if (!tablet_id.is_valid() || !ls_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid argument", K(ret), K(tablet_id), K(ls_id)); + } else if (OB_FAIL(get_tablet_handle(tablet_id, ls_id, tablet_handle_))) { + LOG_WARN("Fail to get tablet handle", K(ret), K(tablet_id), K(ls_id)); + } else if (OB_ISNULL(tablet_handle_.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Tablet handle get obj is null", K(ret), K(tablet_handle_)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::get_split_info(*tablet_handle_.get_obj(), allocator, split_info_))) { + LOG_WARN("fail to get tablet split info.", K(ret)); + } + return ret; +} + +int ObPartitionSplitQuery::set_tablet_handle(const ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(tablet_handle_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet handle already has a valid handle", K(ret), K(tablet_handle_)); + } else { + tablet_handle_ = tablet_handle; + } + return ret; +} + +int ObPartitionSplitQuery::set_split_info(const ObTabletSplitTscInfo &split_info) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(split_info_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("split info is already valid", K(ret), K(split_info_)); + } else { + split_info_ = split_info; + } + return ret; +} + +int ObPartitionSplitQuery::split_multi_ranges_if_need( + const ObIArray &src_ranges, + ObIArray &new_ranges, + ObIAllocator &allocator, + const ObTabletHandle &tablet_handle, + bool &is_splited_range) +{ + int ret = OB_SUCCESS; + is_splited_range = false; + ObTabletSplitTscInfo split_info; + bool is_tablet_spliting = false; + + if (!tablet_handle.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tablet_handle)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::get_is_spliting(*tablet_handle.get_obj(), is_tablet_spliting))) { + STORAGE_LOG(WARN, "fail to get tablet split status", K(ret)); + } else if (!is_tablet_spliting) { + // do nothing + } else if (OB_FAIL(ObTabletSplitMdsHelper::get_split_info(*tablet_handle.get_obj(), allocator, split_info))) { + LOG_WARN("fail to get split info", K(ret)); + } else if (split_info.is_valid()) { + /* No matter local index or main table, we have to get current and origin tablet to calculate + dividing a large range to smaller range in the function. Specifically for local index, + it's no need to multiple a split partition ratio to estimate size of tablet */ + if (OB_FAIL(set_tablet_handle(tablet_handle))) { + LOG_WARN("fail to set tablet handle", K(ret)); + } else if (OB_FAIL(set_split_info(split_info))) { // shadow copy + LOG_WARN("fail to set split info", K(ret)); + } else if (OB_FAIL(get_tablet_split_ranges(src_ranges, new_ranges, allocator))) { + LOG_INFO("get tablet split new ranges err, maybe no spilitng is happening", + K(ret), K(src_ranges), K(new_ranges)); + } else if (new_ranges.count() != src_ranges.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get tablet split range.", K(ret)); + } else { + is_splited_range = true; + } + } + return ret; +} + +int ObPartitionSplitQuery::check_rowkey_is_included( + const ObDatumRowkey &target_rowkey, + const blocksstable::ObStorageDatumUtils *datum_utils, + bool &is_included) +{ + int ret = OB_SUCCESS; + if (tablet_handle_.is_valid() && split_info_.is_valid()) { + if (ObTabletSplitType::RANGE == split_info_.split_type_) { // range + if (OB_ISNULL(datum_utils)) { + datum_utils = &tablet_handle_.get_obj()->get_rowkey_read_info().get_datum_utils(); + } + const ObDatumRowkey &split_start_key = split_info_.start_partkey_; + const ObDatumRowkey &split_end_key = split_info_.end_partkey_; + int compare_ret = 0; + if (OB_FAIL(split_start_key.compare(split_end_key, *datum_utils, compare_ret))) { + LOG_WARN("fail to check rowkey included, compare error.", K(ret), K(split_info_)); + } else if (compare_ret >= 0) { // invalid split key range + ret = OB_ERR_UNEXPECTED; + LOG_WARN("split left key should smaller than split right key", K(ret), K(split_info_)); + } else if (OB_FAIL(target_rowkey.compare(split_start_key, *datum_utils, compare_ret))) { + LOG_WARN("fail to check rowkey included, compare error.", + K(ret), K(target_rowkey), K(split_start_key)); + } else if (compare_ret < 0) { // target rowkey less than split start key + is_included = false; + LOG_DEBUG("target rowkey is less than split range start key, not include in split range", + K(ret), K(target_rowkey), K(split_start_key)); + } else if (OB_FAIL(target_rowkey.compare(split_end_key, *datum_utils, compare_ret))) { + LOG_WARN("fail to check rowkey included, compare error.", + K(ret), K(target_rowkey), K(split_end_key)); + } else if (compare_ret >= 0) { // target rowkey large than split end key, Attention: end key should not included in split range. + is_included = false; + } else { + LOG_DEBUG("rowkey is include in split range", + K(ret), K(target_rowkey), K(split_start_key), K(split_end_key)); + } + } + } + return ret; +} + +int ObPartitionSplitQuery::fill_auto_split_params( + const ObTabletID &tablet_id, + const share::ObLSID &ls_id, + sql::ObPushdownOperator *op, + const uint64_t filter_type, + sql::ExprFixedArray *filter_params, + ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTabletSplitTscInfo split_info; + ObTablet *tablet = nullptr; + + if (!tablet_id.is_valid() || !ls_id.is_valid() + || OB_ISNULL(op) || OB_INVALID_ID == filter_type || OB_ISNULL(filter_params)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", + K(ret), K(tablet_id), K(ls_id), KP(op), K(filter_type), KP(filter_params)); + } else if (OB_FAIL(filter_params->count() <= 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("auto split filter params is zero", K(ret)); + } else if (OB_FAIL(get_tablet_handle(tablet_id, ls_id, tablet_handle))) { + LOG_WARN("fail to get tablet handle", K(ret), K(tablet_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("null pointer tablet handle obj", K(ret), K(tablet)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::get_split_info(*tablet, allocator, split_info))) { + LOG_WARN("fail to get tablet split info", K(ret)); + } else { + sql::ObEvalCtx &eval_ctx = op->get_eval_ctx(); + sql::ObExpr *expr = nullptr; + if (OB_FAIL(ret)) { + } else if (split_info.is_valid()) { // if tablet is spliting + if (filter_type == static_cast(ObTabletSplitType::RANGE)) { + if (OB_FAIL(fill_range_filter_param(split_info, eval_ctx, filter_params))) { + LOG_WARN("fail to fill range filter param", K(ret)); + } + } else if (filter_type == static_cast(ObTabletSplitType::MAX_TYPE)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("filter type is not expected", K(ret), K(filter_type)); + } + } else { + // only need to fill bypass expr. + if (OB_ISNULL(expr = filter_params->at(0))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is null", K(ret), K(expr)); + } else { + ObDatum &expr_datum = expr->locate_datum_for_write(eval_ctx); + expr_datum.set_int(1); // all pass + } + } + } + return ret; +} + +/* + * auto split range filter params order: + * |-- passby --|-- lower1 --|-- lower2 --|..|-- upper1 --|-- upper2 --|... + * + * if tablet is in spliting, fill param expr with actual value. + * if tablet is not in spliting, only need to fill bypass expr with true. +*/ +int ObPartitionSplitQuery::fill_range_filter_param( + ObTabletSplitTscInfo &split_info, + sql::ObEvalCtx &eval_ctx, + sql::ExprFixedArray *filter_params) +{ + int ret = OB_SUCCESS; + blocksstable::ObDatumRowkey &lower_bound = split_info.start_partkey_; + blocksstable::ObDatumRowkey &upper_bound = split_info.end_partkey_; + + if (OB_ISNULL(filter_params)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(filter_params)); + } else if (lower_bound.get_datum_cnt() != upper_bound.get_datum_cnt()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected partition datum cnt", K(ret), K(lower_bound), K(upper_bound)); + } else { + const int64_t filter_params_cnt = filter_params->count(); + const int64_t part_column_cnt = lower_bound.get_datum_cnt(); + const int64_t total_filled_cnt = part_column_cnt * 2 + 1; + + if (filter_params_cnt != total_filled_cnt) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("filter param cnt is not equal to need filled cnt", + K(ret), K(filter_params_cnt), K(total_filled_cnt)); + } + sql::ObExpr *expr = nullptr; + const bool need_copy = true; + for (int i = 0; OB_SUCC(ret) && i < filter_params->count(); ++i) { + if (OB_ISNULL(expr = filter_params->at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr is null", K(ret), K(expr)); + } + LOG_DEBUG("print filter batch result flag", K(expr->batch_result_)); + if (OB_SUCC(ret)) { + const int col_idx = (i - 1) % part_column_cnt; + ObDatum &expr_datum = expr->locate_datum_for_write(eval_ctx); + if (i == 0) { // 1. bypass param expr. + expr_datum.set_int(0); + } else if (i <= part_column_cnt) { // 2. lower bound param expr. + const ObDatum &lower_datum = lower_bound.get_datum(col_idx); + if (lower_datum.is_min()) { + expr_datum.set_outrow(); // min + if (expr_datum.is_outrow()) { + LOG_DEBUG("set is outrow", K(ret), K(expr_datum)); + } + } else if (OB_FAIL(expr_datum.from_storage_datum( + lower_datum, + expr->obj_datum_map_, + need_copy))) { + LOG_WARN("fail to from storage datum", K(ret), K(lower_datum)); + } + } else if (i <= part_column_cnt * 2) { // 3. upper bound param expr. + const ObDatum &upper_datum = upper_bound.get_datum(col_idx); + if (upper_datum.is_max()) { + expr_datum.set_ext(); // max + if (expr_datum.is_ext()) { + LOG_DEBUG("set is ext", K(ret), K(expr_datum)); + } + } else if (OB_FAIL(expr_datum.from_storage_datum( + upper_datum, + expr->obj_datum_map_, + need_copy))) { + LOG_WARN("fail to from storage datum", K(ret), K(upper_datum)); + } + } + } + } + } + LOG_DEBUG("fill range filter param", K(ret), K(lower_bound), K(upper_bound)); + return ret; +} diff --git a/src/share/ob_partition_split_query.h b/src/share/ob_partition_split_query.h new file mode 100644 index 000000000..155777db2 --- /dev/null +++ b/src/share/ob_partition_split_query.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_SHARE_OB_PARTITION_SPLIT_QUERY_H +#define OCEANBASE_SHARE_OB_PARTITION_SPLIT_QUERY_H + +#include "lib/allocator/page_arena.h" +#include "share/schema/ob_table_schema.h" +#include "share/schema/ob_schema_service.h" +#include "share/location_cache/ob_location_struct.h" +#include "storage/tablet/ob_tablet_common.h" +#include "storage/ob_storage_struct.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "sql/engine/expr/ob_expr.h" + +namespace oceanbase +{ +namespace sql +{ +class ObPushdownOperator; +} +namespace storage +{ +class ObTabletHandle; +class ObLSHandle; +struct ObTabletSplitTscInfo; +} +namespace share +{ +class ObPartitionSplitQuery final +{ +public: + ObPartitionSplitQuery() : + tablet_handle_(), + split_info_() + {} + ~ObPartitionSplitQuery() { + tablet_handle_.reset(); + split_info_.reset(); + } +public: + int get_tablet_handle( + const ObTabletID &tablet_id, + const ObLSID &ls_id, + storage::ObTabletHandle &tablet_handle); + + int get_tablet_split_range( + const ObTablet &tablet, + const blocksstable::ObStorageDatumUtils &datum_utils, + const storage::ObTabletSplitTscInfo &split_info, + ObIAllocator &allocator, + blocksstable::ObDatumRange &src_range); + + int get_tablet_split_ranges( + const common::ObIArray &ori_ranges, + common::ObIArray &new_ranges, + ObIAllocator &allocator); + + int get_split_datum_range( + const blocksstable::ObStorageDatumUtils *datum_utils, + ObIAllocator &allocator, + blocksstable::ObDatumRange &datum_range); + + int get_tablet_split_info( + const ObTabletID &tablet_id, + const ObLSID &ls_id, + ObIAllocator &allocator); + + int split_multi_ranges_if_need( + const ObIArray &src_ranges, + ObIArray &new_ranges, + ObIAllocator &allocator, + const storage::ObTabletHandle &tablet_handle, + bool &is_splited_range); + + int fill_auto_split_params( + const ObTabletID &tablet_id, + const share::ObLSID &ls_id, + sql::ObPushdownOperator *op, + const uint64_t filter_type, + sql::ExprFixedArray *filter_params, + ObIAllocator &allocator); + + int fill_range_filter_param( + storage::ObTabletSplitTscInfo &split_info, + sql::ObEvalCtx &eval_ctx, + sql::ExprFixedArray *filter_params); + + int check_rowkey_is_included( + const blocksstable::ObDatumRowkey &target_rowkey, + const blocksstable::ObStorageDatumUtils *datum_utils, + bool &is_included); + + int set_tablet_handle(const storage::ObTabletHandle &tablet_handle); + int set_split_info(const storage::ObTabletSplitTscInfo &split_info); + +private: + int copy_split_key( + const blocksstable::ObDatumRowkey &split_key, + const blocksstable::ObDatumRowkey &src_key, + blocksstable::ObDatumRowkey &new_key, + ObIAllocator &allocator); + +private: + ObTabletHandle tablet_handle_; + ObTabletSplitTscInfo split_info_; +}; + +} // end namespace share +} // end namespace oceanbase + +#endif // end OCEANBASE_SHARE_OB_PARTITION_SPLIT_QUERY_H diff --git a/src/share/ob_rpc_struct.cpp b/src/share/ob_rpc_struct.cpp index 90ca6391e..c46af972b 100644 --- a/src/share/ob_rpc_struct.cpp +++ b/src/share/ob_rpc_struct.cpp @@ -2740,6 +2740,12 @@ OB_DEF_SERIALIZE(ObAlterTableArg) lock_priority_, is_direct_load_partition_); + if (OB_SUCC(ret)) { + if (OB_FAIL(rebuild_index_arg_list_.serialize(buf, buf_len, pos))) { + SHARE_SCHEMA_LOG(WARN, "fail to serialize rebuild_index_arg_list_", K(ret)); + } + } + return ret; } @@ -2860,6 +2866,7 @@ OB_DEF_SERIALIZE_SIZE(ObAlterTableArg) len += nls_formats_[i].get_serialize_size(); } len += foreign_key_arg_list_.get_serialize_size(); + len += rebuild_index_arg_list_.get_serialize_size(); len += sequence_ddl_arg_.get_serialize_size(); len += serialization::encoded_length_i64(sql_mode_); LST_DO_CODE(OB_UNIS_ADD_LEN, @@ -3428,8 +3435,7 @@ OB_SERIALIZE_MEMBER((ObCreateIndexArg, ObIndexArg), index_cgs_, vidx_refresh_info_, is_rebuild_index_, - is_index_scope_specified_ - ); + is_index_scope_specified_); int ObCreateAuxIndexArg::assign(const ObCreateAuxIndexArg &other) { @@ -8953,11 +8959,55 @@ OB_SERIALIZE_MEMBER(ObLogReqUnloadProxyResponse, err_); OB_SERIALIZE_MEMBER(ObLogReqLoadProxyProgressRequest, agency_addr_seq_, principal_addr_seq_); OB_SERIALIZE_MEMBER(ObLogReqLoadProxyProgressResponse, err_, progress_); -OB_SERIALIZE_MEMBER(ObDDLBuildSingleReplicaRequestArg, tenant_id_, ls_id_, source_tablet_id_, dest_tablet_id_, - source_table_id_, dest_schema_id_, schema_version_, snapshot_version_, ddl_type_, task_id_, - execution_id_, parallelism_, tablet_task_id_, data_format_version_, consumer_group_id_, dest_tenant_id_, dest_ls_id_, dest_schema_version_, - compaction_scn_, can_reuse_macro_block_, split_sstable_type_, - lob_col_idxs_, parallel_datum_rowkey_list_); +OB_DEF_SERIALIZE(ObDDLBuildSingleReplicaRequestArg) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, tenant_id_, ls_id_, source_tablet_id_, dest_tablet_id_, + source_table_id_, dest_schema_id_, schema_version_, snapshot_version_, ddl_type_, task_id_, execution_id_, + parallelism_, tablet_task_id_, data_format_version_, consumer_group_id_, dest_tenant_id_, + dest_ls_id_, dest_schema_version_, + compaction_scn_, can_reuse_macro_block_, split_sstable_type_, + lob_col_idxs_, parallel_datum_rowkey_list_); + return ret; +} + +OB_DEF_DESERIALIZE(ObDDLBuildSingleReplicaRequestArg) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, tenant_id_, ls_id_, source_tablet_id_, dest_tablet_id_, + source_table_id_, dest_schema_id_, schema_version_, snapshot_version_, ddl_type_, task_id_, execution_id_, + parallelism_, tablet_task_id_, data_format_version_, consumer_group_id_, dest_tenant_id_, + dest_ls_id_, dest_schema_version_, + compaction_scn_, can_reuse_macro_block_, split_sstable_type_, + lob_col_idxs_); + if (FAILEDx(ObSplitUtil::deserializ_parallel_datum_rowkey( + rowkey_allocator_, buf, data_len, pos, parallel_datum_rowkey_list_))) { + LOG_WARN("deserialzie parallel info failed", K(ret)); + } + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObDDLBuildSingleReplicaRequestArg) +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, tenant_id_, ls_id_, source_tablet_id_, dest_tablet_id_, + source_table_id_, dest_schema_id_, schema_version_, snapshot_version_, ddl_type_, task_id_, execution_id_, + parallelism_, tablet_task_id_, data_format_version_, consumer_group_id_, dest_tenant_id_, + dest_ls_id_, dest_schema_version_, + compaction_scn_, can_reuse_macro_block_, split_sstable_type_, + lob_col_idxs_, parallel_datum_rowkey_list_); + return len; +} + +bool ObDDLBuildSingleReplicaRequestArg::is_valid() const +{ + bool is_valid = OB_INVALID_ID != tenant_id_ && ls_id_.is_valid() && source_tablet_id_.is_valid() && dest_tablet_id_.is_valid() + && OB_INVALID_ID != source_table_id_ && OB_INVALID_ID != dest_schema_id_ + && schema_version_ > 0 && snapshot_version_ > 0 && task_id_ > 0 && parallelism_ > 0 + && tablet_task_id_ > 0 && data_format_version_ > 0 && consumer_group_id_ >= 0 + && dest_tenant_id_ != OB_INVALID_ID && dest_ls_id_.is_valid() && dest_schema_version_ > 0; + return is_valid; +} int ObDDLBuildSingleReplicaRequestArg::assign(const ObDDLBuildSingleReplicaRequestArg &other) { @@ -8967,7 +9017,7 @@ int ObDDLBuildSingleReplicaRequestArg::assign(const ObDDLBuildSingleReplicaReque LOG_WARN("invalid arg", K(ret), K(other)); } else if (OB_FAIL(lob_col_idxs_.assign(other.lob_col_idxs_))) { LOG_WARN("failed to assign to lob col idxs", K(ret)); - } else if (OB_FAIL(parallel_datum_rowkey_list_.assign(other.parallel_datum_rowkey_list_))) { + } else if (OB_FAIL(parallel_datum_rowkey_list_.assign(other.parallel_datum_rowkey_list_))) { // shallow copy. LOG_WARN("assign failed", K(ret)); } else { tenant_id_ = other.tenant_id_; @@ -9035,6 +9085,305 @@ int ObDDLBuildSingleReplicaResponseArg::assign(const ObDDLBuildSingleReplicaResp return ret; } +// === Functions for tablet split start. === +OB_SERIALIZE_MEMBER(ObPrepareSplitRangesArg, ls_id_, tablet_id_, + user_parallelism_, schema_tablet_size_); +OB_DEF_SERIALIZE(ObPrepareSplitRangesRes) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, parallel_datum_rowkey_list_); + return ret; +} + +OB_DEF_DESERIALIZE(ObPrepareSplitRangesRes) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObSplitUtil::deserializ_parallel_datum_rowkey( + rowkey_allocator_, buf, data_len, pos, parallel_datum_rowkey_list_))) { + LOG_WARN("deserialzie parallel info failed", K(ret)); + } + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObPrepareSplitRangesRes) +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, parallel_datum_rowkey_list_); + return len; +} + +bool ObTabletSplitArg::is_valid() const +{ + bool is_valid = ls_id_.is_valid() && OB_INVALID_ID != table_id_ + && schema_version_ > 0 && task_id_ > 0 + && source_tablet_id_.is_valid() && dest_tablets_id_.count() > 0 + && compaction_scn_ > 0 + && data_format_version_ > 0 && consumer_group_id_ >= 0 + && split_sstable_type_ >= share::ObSplitSSTableType::SPLIT_BOTH + && split_sstable_type_ <= share::ObSplitSSTableType::SPLIT_MINOR; + if (!lob_col_idxs_.empty()) { + is_valid = is_valid && (OB_INVALID_ID != lob_table_id_); + } + return is_valid; +} + +int ObTabletSplitArg::assign(const ObTabletSplitArg &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else if (OB_FAIL(dest_tablets_id_.assign(other.dest_tablets_id_))) { + LOG_WARN("assign failed", K(ret), K(other)); + } else if (OB_FAIL(lob_col_idxs_.assign(other.lob_col_idxs_))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(parallel_datum_rowkey_list_.assign(other.parallel_datum_rowkey_list_))) { // shallow cpy. + LOG_WARN("assign failed", K(ret), K(other)); + } else { + ls_id_ = other.ls_id_; + table_id_ = other.table_id_; + lob_table_id_ = other.lob_table_id_; + schema_version_ = other.schema_version_; + task_id_ = other.task_id_; + source_tablet_id_ = other.source_tablet_id_; + compaction_scn_ = other.compaction_scn_; + data_format_version_ = other.data_format_version_; + consumer_group_id_ = other.consumer_group_id_; + can_reuse_macro_block_ = other.can_reuse_macro_block_; + split_sstable_type_ = other.split_sstable_type_; + } + return ret; +} + +bool ObTabletSplitStartArg::is_valid() const +{ + bool is_valid = true; + for (int64_t i = 0; is_valid && i < split_info_array_.count(); i++) { + is_valid = is_valid && split_info_array_.at(i).is_valid(); + } + return is_valid; +} + +int ObTabletSplitStartArg::assign(const ObTabletSplitStartArg &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else if (OB_FAIL(split_info_array_.assign(other.split_info_array_))) { + LOG_WARN("assign tablet split info failed", K(ret)); + } + return ret; +} + +int ObTabletSplitStartResult::assign(const ObTabletSplitStartResult &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ret_codes_.assign(other.ret_codes_))) { + LOG_WARN("failed to assign to ret_codes_", K(ret)); + } + return ret; +} + +bool ObTabletSplitFinishArg::is_valid() const +{ + bool is_valid = true; + for (int64_t i = 0; is_valid && i < split_info_array_.count(); i++) { + is_valid = is_valid && split_info_array_.at(i).is_valid(); + } + return is_valid; +} + +int ObTabletSplitFinishArg::assign(const ObTabletSplitFinishArg &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else if (OB_FAIL(split_info_array_.assign(other.split_info_array_))) { + LOG_WARN("assign tablet split info failed", K(ret)); + } + return ret; +} + +int ObTabletSplitFinishResult::assign(const ObTabletSplitFinishResult &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ret_codes_.assign(other.ret_codes_))) { + LOG_WARN("failed to assign to ret_codes_", K(ret)); + } + return ret; +} + +OB_DEF_SERIALIZE(ObTabletSplitArg) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, ls_id_, table_id_, lob_table_id_, + schema_version_, task_id_, source_tablet_id_, + dest_tablets_id_, compaction_scn_, data_format_version_, + consumer_group_id_, can_reuse_macro_block_, split_sstable_type_, + lob_col_idxs_, parallel_datum_rowkey_list_); + return ret; +} + +OB_DEF_DESERIALIZE(ObTabletSplitArg) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, ls_id_, table_id_, lob_table_id_, + schema_version_, task_id_, source_tablet_id_, + dest_tablets_id_, compaction_scn_, data_format_version_, + consumer_group_id_, can_reuse_macro_block_, split_sstable_type_, + lob_col_idxs_); + if (FAILEDx(ObSplitUtil::deserializ_parallel_datum_rowkey( + rowkey_allocator_, buf, data_len, pos, parallel_datum_rowkey_list_))) { + LOG_WARN("deserialzie parallel info failed", K(ret)); + } + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObTabletSplitArg) +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, ls_id_, table_id_, lob_table_id_, + schema_version_, task_id_, source_tablet_id_, + dest_tablets_id_, compaction_scn_, data_format_version_, + consumer_group_id_, can_reuse_macro_block_, split_sstable_type_, + lob_col_idxs_, parallel_datum_rowkey_list_); + return len; +} + +OB_SERIALIZE_MEMBER(ObTabletSplitStartArg, split_info_array_); +OB_SERIALIZE_MEMBER(ObTabletSplitStartResult, ret_codes_); +OB_SERIALIZE_MEMBER(ObTabletSplitFinishArg, split_info_array_); +OB_SERIALIZE_MEMBER(ObTabletSplitFinishResult, ret_codes_); + +int ObFreezeSplitSrcTabletArg::assign(const ObFreezeSplitSrcTabletArg &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else if (OB_FAIL(tablet_ids_.assign(other.tablet_ids_))) { + LOG_WARN("failed to assign", K(ret)); + } else { + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObFreezeSplitSrcTabletArg, tenant_id_, ls_id_, tablet_ids_); + +int ObFreezeSplitSrcTabletRes::assign(const ObFreezeSplitSrcTabletRes &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else { + data_end_scn_ = other.data_end_scn_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObFreezeSplitSrcTabletRes, data_end_scn_); + +int ObAutoSplitTabletArg::assign(const ObAutoSplitTabletArg &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else { + ls_id_ = other.ls_id_; + tablet_id_ = other.tablet_id_; + tenant_id_ = other.tenant_id_; + auto_split_tablet_size_ = other.auto_split_tablet_size_; + used_disk_space_ = other.used_disk_space_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObAutoSplitTabletArg, ls_id_, tablet_id_, + tenant_id_, auto_split_tablet_size_, used_disk_space_); + +int ObAutoSplitTabletBatchArg::assign(const ObAutoSplitTabletBatchArg &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else if (OB_FAIL(args_.assign(other.args_))) { + LOG_WARN("fail to assign args_", K(ret)); + } + return ret; +} + +bool ObAutoSplitTabletBatchArg::is_valid() const +{ + bool valid = (args_.count() > 0); + for (int64_t i = 0; valid && i < args_.count(); ++i) + { + valid = args_.at(i).is_valid(); + } + return valid; +} + +OB_SERIALIZE_MEMBER(ObAutoSplitTabletBatchArg, args_); + +bool ObAutoSplitTabletBatchRes::is_valid() const +{ + return (rets_.count() > 0) && (suggested_next_valid_time_ != OB_INVALID_TIMESTAMP); +} +int ObAutoSplitTabletBatchRes::assign(const ObAutoSplitTabletBatchRes &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(other)); + } else if (OB_FAIL(rets_.assign(other.rets_))) { + LOG_WARN("fail to assign args_", K(ret)); + } else { + suggested_next_valid_time_ = other.suggested_next_valid_time_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObAutoSplitTabletBatchRes, rets_, suggested_next_valid_time_); + +int ObFetchSplitTabletInfoArg::assign(const ObFetchSplitTabletInfoArg &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else if (OB_FAIL(tablet_ids_.assign(other.tablet_ids_))) { + LOG_WARN("failed to assign", K(ret)); + } else { + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObFetchSplitTabletInfoArg, tenant_id_, ls_id_, tablet_ids_); + +int ObFetchSplitTabletInfoRes::assign(const ObFetchSplitTabletInfoRes &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(other)); + } else if (OB_FAIL(create_commit_versions_.assign(other.create_commit_versions_))) { + LOG_WARN("failed to assign", K(ret)); + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObFetchSplitTabletInfoRes, create_commit_versions_); + +// === Functions for tablet split end. === + int ObCreateDirectoryArg::assign(const ObCreateDirectoryArg &other) { int ret = OB_SUCCESS; @@ -9693,6 +10042,139 @@ OB_DEF_SERIALIZE_SIZE(ObBatchRemoveTabletArg) return len; } +int ObPartitionSplitArg::assign(const ObPartitionSplitArg &other) +{ + int ret = OB_SUCCESS; + src_tablet_id_ = other.src_tablet_id_; + task_type_ = other.task_type_; + if (OB_FAIL(ObDDLArg::assign(other))) { + LOG_WARN("assign ddl arg failed", K(ret)); + } else if (OB_FAIL(dest_tablet_ids_.assign(other.dest_tablet_ids_))) { + LOG_WARN("failed to assign dest tablet ids", K(ret)); + } else if (OB_FAIL(local_index_table_ids_.assign(other.local_index_table_ids_))) { + LOG_WARN("failed to assign local index table ids", K(ret)); + } else if (OB_FAIL(local_index_schema_versions_.assign(other.local_index_schema_versions_))) { + LOG_WARN("faled to assign to local index schema versions", K(ret)); + } else if (OB_FAIL(src_local_index_tablet_ids_.assign(other.src_local_index_tablet_ids_))) { + LOG_WARN("failed to assign src local index tablet ids", K(ret)); + } else if (OB_FAIL(dest_local_index_tablet_ids_.assign(other.dest_local_index_tablet_ids_))) { + LOG_WARN("failed to assign dest local index tablet ids", K(ret)); + } else if (OB_FAIL(lob_table_ids_.assign(other.lob_table_ids_))) { + LOG_WARN("failed to assign lob table ids", K(ret)); + } else if (OB_FAIL(lob_schema_versions_.assign(other.lob_schema_versions_))) { + LOG_WARN("failed to assign to lob schema versions", K(ret)); + } else if (OB_FAIL(src_lob_tablet_ids_.assign(other.src_lob_tablet_ids_))) { + LOG_WARN("failed to assign src lob tablet ids", K(ret)); + } else if (OB_FAIL(dest_lob_tablet_ids_.assign(other.dest_lob_tablet_ids_))) { + LOG_WARN("failed to assign dest lob tablet ids", K(ret)); + } + return ret; +} + +OB_SERIALIZE_MEMBER((ObPartitionSplitArg, ObDDLArg), + src_tablet_id_, + dest_tablet_ids_, + local_index_table_ids_, + local_index_schema_versions_, + src_local_index_tablet_ids_, + dest_local_index_tablet_ids_, + lob_table_ids_, + lob_schema_versions_, + src_lob_tablet_ids_, + dest_lob_tablet_ids_, + task_type_); + +int ObCleanSplittedTabletArg::assign(const ObCleanSplittedTabletArg &other) +{ + int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; + table_id_ = other.table_id_; + task_id_ = other.task_id_; + src_table_tablet_id_ = other.src_table_tablet_id_; + is_auto_split_ = other.is_auto_split_; + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(dest_tablet_ids_.assign(other.dest_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret), K(other.dest_tablet_ids_)); + } else if (OB_FAIL(local_index_table_ids_.assign(other.local_index_table_ids_))) { + LOG_WARN("fail to assign array", KR(ret), K(other.local_index_table_ids_)); + } else if (OB_FAIL(src_local_index_tablet_ids_.assign(other.src_local_index_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret), K(other.src_local_index_tablet_ids_)); + } else if (OB_FAIL(dest_local_index_tablet_ids_.assign(other.dest_local_index_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret), K(other.dest_local_index_tablet_ids_)); + } else if (OB_FAIL(src_lob_tablet_ids_.assign(other.src_lob_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret), K(other.src_lob_tablet_ids_)); + } else if (OB_FAIL(dest_lob_tablet_ids_.assign(other.dest_lob_tablet_ids_))) { + LOG_WARN("fail to assign array", KR(ret), K(other.dest_lob_tablet_ids_)); + } else if (OB_FAIL(lob_table_ids_.assign(other.lob_table_ids_))) { + LOG_WARN("fail to assign array", KR(ret), K(other.lob_table_ids_)); + } + + return ret; +} +OB_SERIALIZE_MEMBER(ObCleanSplittedTabletArg, + tenant_id_, + table_id_, + task_id_, + local_index_table_ids_, + lob_table_ids_, + src_table_tablet_id_, + dest_tablet_ids_, + src_local_index_tablet_ids_, + dest_local_index_tablet_ids_, + src_lob_tablet_ids_, + dest_lob_tablet_ids_, + is_auto_split_); + +int ObCheckMemtableCntArg::assign(const ObCheckMemtableCntArg &other) +{ + int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + tablet_id_ = other.tablet_id_; + return ret; +} + +OB_SERIALIZE_MEMBER(ObCheckMemtableCntArg, + tenant_id_, + ls_id_, + tablet_id_); + +int ObCheckMemtableCntResult::assign(const ObCheckMemtableCntResult &other) +{ + int ret = OB_SUCCESS; + memtable_cnt_ = other.memtable_cnt_; + return ret; +} + +OB_SERIALIZE_MEMBER(ObCheckMemtableCntResult, + memtable_cnt_); + +int ObCheckMediumCompactionInfoListArg::assign(const ObCheckMediumCompactionInfoListArg &other) +{ + int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + tablet_id_ = other.tablet_id_; + return ret; +} + +OB_SERIALIZE_MEMBER(ObCheckMediumCompactionInfoListArg, + tenant_id_, + ls_id_, + tablet_id_); + +int ObCheckMediumCompactionInfoListResult::assign(const ObCheckMediumCompactionInfoListResult &other) +{ + int ret = OB_SUCCESS; + info_list_cnt_ = other.info_list_cnt_; + primary_compaction_scn_ = other.primary_compaction_scn_; + return ret; +} +OB_SERIALIZE_MEMBER(ObCheckMediumCompactionInfoListResult, + info_list_cnt_, + primary_compaction_scn_); + OB_DEF_DESERIALIZE(ObBatchRemoveTabletArg) { int ret = OB_SUCCESS; @@ -9758,6 +10240,7 @@ int ObCreateTabletInfo::init(const ObIArray &tablet_ids, const common::ObIArray &table_schema_index, const lib::Worker::CompatMode &mode, const bool is_create_bind_hidden_tablets, + const ObIArray &create_commit_versions, const bool has_cs_replica) { int ret = OB_SUCCESS; @@ -9775,6 +10258,8 @@ int ObCreateTabletInfo::init(const ObIArray &tablet_ids, LOG_WARN("failed to assign table schema index", KR(ret), K(table_schema_index)); } else if (OB_FAIL(table_schema_index_.assign(table_schema_index))) { LOG_WARN("failed to assign table schema index", KR(ret), K(table_schema_index)); + } else if (OB_FAIL(create_commit_versions_.assign(create_commit_versions))) { + LOG_WARN("failed to assign create commit versions", KR(ret), K(create_commit_versions)); } else { data_tablet_id_ = data_tablet_id; compat_mode_ = mode; @@ -11469,6 +11954,51 @@ int ObBatchGetTabletBindingRes::assign(const ObBatchGetTabletBindingRes &other) return binding_datas_.assign(other.binding_datas_); } +OB_SERIALIZE_MEMBER(ObBatchGetTabletSplitArg, tenant_id_, ls_id_, tablet_ids_, check_committed_); + +int ObBatchGetTabletSplitArg::assign(const ObBatchGetTabletSplitArg &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(other)); + } else if (OB_FAIL(tablet_ids_.assign(other.tablet_ids_))) { + LOG_WARN("failed to assign", K(ret)); + } else { + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + check_committed_ = other.check_committed_; + } + return ret; +} + +int ObBatchGetTabletSplitArg::init(const uint64_t tenant_id, const share::ObLSID &ls_id, const ObIArray &tablet_ids, const bool check_committed) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || !ls_id.is_valid() || tablet_ids.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(ls_id), K(tablet_ids), K(check_committed)); + } else if (OB_FAIL(tablet_ids_.assign(tablet_ids))) { + LOG_WARN("failed to assign", K(ret)); + } else { + tenant_id_ = tenant_id; + ls_id_ = ls_id; + check_committed_ = check_committed; + } + if (OB_SUCC(ret) && OB_UNLIKELY(!is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(*this)); + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObBatchGetTabletSplitRes, split_datas_); + +int ObBatchGetTabletSplitRes::assign(const ObBatchGetTabletSplitRes &other) +{ + return split_datas_.assign(other.split_datas_); +} + OB_SERIALIZE_MEMBER(ObFetchLocationResult, servers_); int ObFetchLocationResult::assign(const ObFetchLocationResult &other) diff --git a/src/share/ob_rpc_struct.h b/src/share/ob_rpc_struct.h index ce9ea1e2f..ec99d8266 100644 --- a/src/share/ob_rpc_struct.h +++ b/src/share/ob_rpc_struct.h @@ -60,6 +60,8 @@ #include "storage/ddl/ob_ddl_struct.h" #include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" #include "storage/tablet/ob_tablet_binding_mds_user_data.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "storage/tablet/ob_tablet_split_mds_user_data.h" #include "storage/tx/ob_trans_define.h" #include "storage/tx/ob_multi_data_source.h" #include "share/unit/ob_unit_info.h" //ObUnit* @@ -2325,6 +2327,19 @@ public: || alter_table_schema_.alter_option_bitset_.has_member(PROGRESSIVE_MERGE_NUM) || alter_table_schema_.alter_option_bitset_.has_member(ENCRYPTION); } + bool is_split_partition() const { + return is_manual_split_partition() || + is_auto_split_partition(); + } + + bool is_manual_split_partition() const { + return alter_part_type_ == REORGANIZE_PARTITION || + alter_part_type_ == SPLIT_PARTITION; + } + + bool is_auto_split_partition() const { + return alter_part_type_ == AUTO_SPLIT_PARTITION; + } ObAlterTableArg &operator=(const ObAlterTableArg &other) = delete; ObAlterTableArg(const ObAlterTableArg &other) = delete; virtual bool is_allow_when_disable_ddl() const; @@ -2371,6 +2386,7 @@ public: K_(mview_refresh_info), K_(alter_algorithm), K_(alter_auto_partition_attr), + K_(rebuild_index_arg_list), K_(client_session_id), K_(client_session_create_ts), K_(lock_priority), @@ -2930,6 +2946,233 @@ public: typedef ObCreateIndexArg ObAlterPrimaryArg; +struct ObPartitionSplitArg : public ObDDLArg +{ + OB_UNIS_VERSION(1); +public: + ObPartitionSplitArg() + : ObDDLArg(), + src_tablet_id_(common::ObTabletID::INVALID_TABLET_ID), + dest_tablet_ids_(), + local_index_table_ids_(), + local_index_schema_versions_(), + src_local_index_tablet_ids_(), + dest_local_index_tablet_ids_(), + lob_table_ids_(), + lob_schema_versions_(), + src_lob_tablet_ids_(), + dest_lob_tablet_ids_(), + task_type_(share::ObDDLType::DDL_INVALID) + {} + virtual ~ObPartitionSplitArg() {} + bool is_valid() const + { + return src_tablet_id_.is_valid() + && local_index_table_ids_.count() == src_local_index_tablet_ids_.count() + && local_index_schema_versions_.count() == src_local_index_tablet_ids_.count() + && src_local_index_tablet_ids_.count() == dest_local_index_tablet_ids_.count() + && lob_table_ids_.count() == src_lob_tablet_ids_.count() + && lob_schema_versions_.count() == src_lob_tablet_ids_.count() + && src_lob_tablet_ids_.count() == dest_lob_tablet_ids_.count() + && task_type_ > share::ObDDLType::DDL_INVALID + && task_type_ < share::ObDDLType::DDL_MAX; + } + int assign(const ObPartitionSplitArg &other); + void reset() + { + dest_tablet_ids_.reset(); + src_tablet_id_ = common::ObTabletID::INVALID_TABLET_ID; + local_index_table_ids_.reset(); + local_index_schema_versions_.reset(); + src_local_index_tablet_ids_.reset(); + dest_local_index_tablet_ids_.reset(); + lob_table_ids_.reset(); + lob_schema_versions_.reset(); + src_lob_tablet_ids_.reset(); + dest_lob_tablet_ids_.reset(); + task_type_ = share::ObDDLType::DDL_INVALID; + ObDDLArg::reset(); + } + INHERIT_TO_STRING_KV("ObDDLArg", ObDDLArg, + K(src_tablet_id_), K(dest_tablet_ids_), K(local_index_table_ids_), + K(local_index_schema_versions_), K(src_local_index_tablet_ids_), + K(dest_local_index_tablet_ids_), K(lob_table_ids_), K(lob_schema_versions_), + K(src_lob_tablet_ids_), K(dest_lob_tablet_ids_), + K(task_type_)); +public: + ObTabletID src_tablet_id_; + ObSArray dest_tablet_ids_; + ObSArray local_index_table_ids_; + ObSArray local_index_schema_versions_; + ObSArray src_local_index_tablet_ids_; + ObSArray> dest_local_index_tablet_ids_; + ObSArray lob_table_ids_; + ObSArray lob_schema_versions_; + ObSArray src_lob_tablet_ids_; + ObSArray> dest_lob_tablet_ids_; + share::ObDDLType task_type_; +}; + +struct ObCleanSplittedTabletArg final +{ + OB_UNIS_VERSION(1); +public: + ObCleanSplittedTabletArg() + : tenant_id_(common::OB_INVALID_ID), + table_id_(common::OB_INVALID_ID), + task_id_(0), + local_index_table_ids_(), + lob_table_ids_(), + src_table_tablet_id_(), + dest_tablet_ids_(), + src_local_index_tablet_ids_(), + dest_local_index_tablet_ids_(), + src_lob_tablet_ids_(), + dest_lob_tablet_ids_(), + is_auto_split_(false) + {} + ~ObCleanSplittedTabletArg() = default; + int assign(const ObCleanSplittedTabletArg &other); + bool is_valid() const + { + bool valid = tenant_id_ != OB_INVALID_ID && + table_id_ != OB_INVALID_ID && + task_id_ != 0 && + src_table_tablet_id_.is_valid() && + local_index_table_ids_.count() == src_local_index_tablet_ids_.count() && + lob_table_ids_.count() == src_lob_tablet_ids_.count() && + src_local_index_tablet_ids_.count() == dest_local_index_tablet_ids_.count() && + src_lob_tablet_ids_.count() == dest_lob_tablet_ids_.count(); + for (int64_t i = 0; valid && i < local_index_table_ids_.count(); i++) { + valid = local_index_table_ids_.at(i) != OB_INVALID_ID && + src_local_index_tablet_ids_.at(i).is_valid(); + } + for (int64_t i = 0; valid && i < lob_table_ids_.count(); i++) { + valid = lob_table_ids_.at(i) != OB_INVALID_ID && + src_lob_tablet_ids_.at(i).is_valid(); + } + return valid; + } + void reset() + { + tenant_id_ = OB_INVALID_ID; + table_id_ = OB_INVALID_ID; + task_id_ = 0; + local_index_table_ids_.reset(); + lob_table_ids_.reset(); + src_table_tablet_id_ = common::ObTabletID::INVALID_TABLET_ID; + dest_tablet_ids_.reset(); + src_local_index_tablet_ids_.reset(); + dest_local_index_tablet_ids_.reset(); + src_lob_tablet_ids_.reset(); + dest_lob_tablet_ids_.reset(); + is_auto_split_ = false; + } + TO_STRING_KV(K_(tenant_id), + K_(table_id), + K_(task_id), + K_(local_index_table_ids), + K_(lob_table_ids), + K_(src_table_tablet_id), + K_(dest_tablet_ids), + K_(src_local_index_tablet_ids), + K_(dest_local_index_tablet_ids), + K_(src_lob_tablet_ids), + K_(dest_lob_tablet_ids), + K_(is_auto_split)); +public: + uint64_t tenant_id_; + uint64_t table_id_; + int64_t task_id_; + ObSArray local_index_table_ids_; + ObSArray lob_table_ids_; + ObTabletID src_table_tablet_id_; + ObSArray dest_tablet_ids_; + ObSArray src_local_index_tablet_ids_; + ObSArray> dest_local_index_tablet_ids_; + ObSArray src_lob_tablet_ids_; + ObSArray> dest_lob_tablet_ids_; + + bool is_auto_split_; +}; + +struct ObCheckMemtableCntArg final +{ + OB_UNIS_VERSION(1); +public: + ObCheckMemtableCntArg() + : tenant_id_(OB_INVALID_TENANT_ID), + ls_id_(), + tablet_id_(common::ObTabletID::INVALID_TABLET_ID) + {} + ~ObCheckMemtableCntArg() {} + bool is_valid() const + { + return OB_INVALID_ID != tenant_id_ && + ls_id_.is_valid() && + tablet_id_.is_valid(); + } + int assign(const ObCheckMemtableCntArg &other); + TO_STRING_KV(K(tenant_id_), K(ls_id_), K(tablet_id_)); +public: + uint64_t tenant_id_; + share::ObLSID ls_id_; + ObTabletID tablet_id_; +}; + +struct ObCheckMemtableCntResult final +{ + OB_UNIS_VERSION(1); +public: + ObCheckMemtableCntResult() + : memtable_cnt_(-1) {} + ~ObCheckMemtableCntResult() {} + int assign(const ObCheckMemtableCntResult &other); + TO_STRING_KV(K_(memtable_cnt)); +public: + int64_t memtable_cnt_; +}; + +struct ObCheckMediumCompactionInfoListArg final +{ + OB_UNIS_VERSION(1); +public: + ObCheckMediumCompactionInfoListArg() + : tenant_id_(OB_INVALID_TENANT_ID), + ls_id_(), + tablet_id_(common::ObTabletID::INVALID_TABLET_ID) + {} + ~ObCheckMediumCompactionInfoListArg() {} + bool is_valid() const + { + return OB_INVALID_ID != tenant_id_ && + ls_id_.is_valid() && + tablet_id_.is_valid(); + } + int assign(const ObCheckMediumCompactionInfoListArg &other); + TO_STRING_KV(K(tenant_id_), K(ls_id_), K(tablet_id_)); +public: + uint64_t tenant_id_; + share::ObLSID ls_id_; + ObTabletID tablet_id_; +}; + +struct ObCheckMediumCompactionInfoListResult final +{ + OB_UNIS_VERSION(1); +public: + ObCheckMediumCompactionInfoListResult() + : info_list_cnt_(-1), + primary_compaction_scn_(-1) + {} + ~ObCheckMediumCompactionInfoListResult() {} + int assign(const ObCheckMediumCompactionInfoListResult &other); + TO_STRING_KV(K(info_list_cnt_), K_(primary_compaction_scn)); +public: + int64_t info_list_cnt_; + int64_t primary_compaction_scn_; +}; + struct ObCreateMLogArg : public ObDDLArg { OB_UNIS_VERSION_V(1); @@ -4078,6 +4321,7 @@ public: const common::ObIArray &table_schema_index, const lib::Worker::CompatMode &mode, const bool is_create_bind_hidden_tablets, + const ObIArray &create_commit_versions, const bool has_cs_replica); common::ObTabletID get_data_tablet_id() const { return data_tablet_id_; } int64_t get_tablet_count() const { return tablet_ids_.count(); } @@ -10276,27 +10520,25 @@ struct ObDDLBuildSingleReplicaRequestArg final { OB_UNIS_VERSION(1); public: - ObDDLBuildSingleReplicaRequestArg() : tenant_id_(OB_INVALID_ID), ls_id_(), source_tablet_id_(), dest_tablet_id_(), - source_table_id_(OB_INVALID_ID), dest_schema_id_(OB_INVALID_ID), - schema_version_(0), snapshot_version_(0), ddl_type_(0), task_id_(0), parallelism_(0), execution_id_(-1), tablet_task_id_(0), - data_format_version_(0), consumer_group_id_(0), dest_tenant_id_(OB_INVALID_ID), dest_ls_id_(), dest_schema_version_(0), - compaction_scn_(0), can_reuse_macro_block_(false), split_sstable_type_(share::ObSplitSSTableType::SPLIT_BOTH), - lob_col_idxs_(), parallel_datum_rowkey_list_() + ObDDLBuildSingleReplicaRequestArg() : + rowkey_allocator_("SplitRangeRPC"), + tenant_id_(OB_INVALID_ID), ls_id_(), source_tablet_id_(), dest_tablet_id_(), + source_table_id_(OB_INVALID_ID), dest_schema_id_(OB_INVALID_ID), + schema_version_(0), snapshot_version_(0), ddl_type_(0), task_id_(0), parallelism_(0), execution_id_(-1), tablet_task_id_(0), + data_format_version_(0), consumer_group_id_(0), dest_tenant_id_(OB_INVALID_ID), dest_ls_id_(), dest_schema_version_(0), + compaction_scn_(0), can_reuse_macro_block_(false), split_sstable_type_(share::ObSplitSSTableType::SPLIT_BOTH), + lob_col_idxs_(), parallel_datum_rowkey_list_() {} - bool is_valid() const { - return OB_INVALID_ID != tenant_id_ && ls_id_.is_valid() && source_tablet_id_.is_valid() && dest_tablet_id_.is_valid() - && OB_INVALID_ID != source_table_id_ && OB_INVALID_ID != dest_schema_id_ && schema_version_ > 0 - && snapshot_version_ > 0 && dest_schema_version_ > 0 && task_id_ > 0 && parallelism_ > 0 && tablet_task_id_ > 0 - && data_format_version_ > 0 && consumer_group_id_ >= 0; - } + bool is_valid() const; int assign(const ObDDLBuildSingleReplicaRequestArg &other); - TO_STRING_KV(K_(tenant_id), K_(dest_tenant_id), K_(ls_id), K_(dest_ls_id), K_(source_tablet_id), - K_(dest_tablet_id), K_(source_table_id), K_(dest_schema_id), K_(schema_version), K_(dest_schema_version), - K_(snapshot_version), K_(task_id), K_(parallelism), K_(execution_id), K_(tablet_task_id), K_(data_format_version), - K_(consumer_group_id), - K_(compaction_scn), K_(can_reuse_macro_block), K_(split_sstable_type), - K_(lob_col_idxs), K_(parallel_datum_rowkey_list)); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(source_tablet_id), K_(dest_tablet_id), + K_(source_table_id), K_(dest_schema_id), K_(schema_version), K_(snapshot_version), K_(ddl_type), + K_(task_id), K_(parallelism), K_(execution_id), K_(tablet_task_id), K_(data_format_version), + K_(consumer_group_id), K_(dest_tenant_id), K_(dest_ls_id), K_(dest_schema_version), + K_(compaction_scn), K_(can_reuse_macro_block), K_(split_sstable_type), K_(lob_col_idxs), + K_(parallel_datum_rowkey_list)); public: + common::ObArenaAllocator rowkey_allocator_; // alloc buf for datum rowkey. uint64_t tenant_id_; share::ObLSID ls_id_; ObTabletID source_tablet_id_; @@ -10363,11 +10605,21 @@ public: physical_row_count_(0) {} ~ObDDLBuildSingleReplicaResponseArg() = default; - bool is_valid() const { return OB_INVALID_ID != tenant_id_ && OB_INVALID_ID != dest_tenant_id_ - && ls_id_.is_valid() && dest_ls_id_.is_valid() && tablet_id_.is_valid() - && OB_INVALID_ID != source_table_id_ && OB_INVALID_ID != dest_schema_id_ - && snapshot_version_ > 0 && schema_version_ > 0 && dest_schema_version_ > 0 - && task_id_ > 0 && execution_id_ >= 0; } + bool is_valid() const { + return OB_INVALID_ID != tenant_id_ && + OB_INVALID_ID != dest_tenant_id_ && + ls_id_.is_valid() && + dest_ls_id_.is_valid() && + tablet_id_.is_valid() && + OB_INVALID_ID != source_table_id_ && + OB_INVALID_ID != dest_schema_id_ && + snapshot_version_ > 0 && + schema_version_ > 0 && + dest_schema_version_ > 0 && + task_id_ > 0 && + execution_id_ >= 0 && + server_addr_.is_valid(); + } int assign(const ObDDLBuildSingleReplicaResponseArg &other); TO_STRING_KV(K_(tenant_id), K_(dest_tenant_id), K_(ls_id), K_(dest_ls_id), K_(tablet_id), K_(source_table_id), K_(dest_schema_id), K_(ret_code), @@ -10393,6 +10645,262 @@ public: int64_t physical_row_count_; }; +// === RPC for tablet split start. === +struct ObPrepareSplitRangesArg final +{ + OB_UNIS_VERSION(1); +public: + ObPrepareSplitRangesArg() + : ls_id_(), + tablet_id_(), + user_parallelism_(0), + schema_tablet_size_(0) + {} + ~ObPrepareSplitRangesArg() {} + bool is_valid() const + { + return ls_id_.is_valid() && tablet_id_.is_valid(); + } + TO_STRING_KV(K(ls_id_), K(tablet_id_), K_(user_parallelism), K_(schema_tablet_size)); +public: + share::ObLSID ls_id_; + ObTabletID tablet_id_; + int64_t user_parallelism_; + int64_t schema_tablet_size_; +DISALLOW_COPY_AND_ASSIGN(ObPrepareSplitRangesArg); +}; + +struct ObPrepareSplitRangesRes final +{ + OB_UNIS_VERSION(1); +public: + ObPrepareSplitRangesRes() + : rowkey_allocator_("SplitRangeRPC"), + parallel_datum_rowkey_list_() + {} + ~ObPrepareSplitRangesRes() = default; + TO_STRING_KV(K_(parallel_datum_rowkey_list)); +public: + common::ObArenaAllocator rowkey_allocator_; // alloc buf for datum rowkey. + common::ObSArray parallel_datum_rowkey_list_; +private: + DISALLOW_COPY_AND_ASSIGN(ObPrepareSplitRangesRes); +}; + +struct ObTabletSplitArg final +{ + OB_UNIS_VERSION(1); +public: + ObTabletSplitArg() + : rowkey_allocator_("SplitRangeRPC"), + ls_id_(), table_id_(OB_INVALID_ID), lob_table_id_(OB_INVALID_ID), + schema_version_(0), task_id_(0), source_tablet_id_(), + dest_tablets_id_(), compaction_scn_(0), data_format_version_(0), + consumer_group_id_(0), can_reuse_macro_block_(false), split_sstable_type_(share::ObSplitSSTableType::SPLIT_BOTH), + lob_col_idxs_(), parallel_datum_rowkey_list_() + {} + ~ObTabletSplitArg() = default; + bool is_valid() const; + int assign(const ObTabletSplitArg &other); + TO_STRING_KV(K_(ls_id), K_(table_id), K_(lob_table_id), + K_(schema_version), K_(task_id), K_(source_tablet_id), + K_(dest_tablets_id), K_(compaction_scn), K_(data_format_version), + K_(consumer_group_id), K_(can_reuse_macro_block), K_(split_sstable_type), + K_(lob_col_idxs), K_(parallel_datum_rowkey_list)); +public: + common::ObArenaAllocator rowkey_allocator_; // alloc buf for datum rowkey. + share::ObLSID ls_id_; + uint64_t table_id_; // scan rows needed. + uint64_t lob_table_id_; // scan rows needed. + int64_t schema_version_; // report replica build status needed. + int64_t task_id_; // report replica build status needed. + common::ObTabletID source_tablet_id_; + common::ObSArray dest_tablets_id_; + int64_t compaction_scn_; + int64_t data_format_version_; + uint64_t consumer_group_id_; + bool can_reuse_macro_block_; + share::ObSplitSSTableType split_sstable_type_; + common::ObSEArray lob_col_idxs_; + common::ObSArray parallel_datum_rowkey_list_; +}; + +struct ObTabletSplitStartArg final +{ + OB_UNIS_VERSION(1); +public: + ObTabletSplitStartArg() + : split_info_array_() + {} + ~ObTabletSplitStartArg() = default; + bool is_valid() const; + int assign(const ObTabletSplitStartArg &other); + TO_STRING_KV(K_(split_info_array)); +public: + common::ObSArray split_info_array_; +}; + +struct ObTabletSplitStartResult final +{ + OB_UNIS_VERSION(1); +public: + ObTabletSplitStartResult() + : ret_codes_() + {} + ~ObTabletSplitStartResult() = default; + int assign(const ObTabletSplitStartResult &other); + TO_STRING_KV(K_(ret_codes)); +public: + common::ObSArray ret_codes_; +}; + +struct ObTabletSplitFinishArg final +{ + OB_UNIS_VERSION(1); +public: + ObTabletSplitFinishArg() + : split_info_array_() + {} + ~ObTabletSplitFinishArg() = default; + bool is_valid() const; + int assign(const ObTabletSplitFinishArg &other); + TO_STRING_KV(K_(split_info_array)); +public: + common::ObSArray split_info_array_; +}; + +struct ObTabletSplitFinishResult final +{ + OB_UNIS_VERSION(1); +public: + ObTabletSplitFinishResult() + : ret_codes_() + {} + ~ObTabletSplitFinishResult() = default; + int assign(const ObTabletSplitFinishResult &other); + TO_STRING_KV(K_(ret_codes)); +public: + common::ObSArray ret_codes_; + uint64_t dest_tenant_id_; + share::ObLSID dest_ls_id_; + int64_t dest_schema_version_; + common::ObAddr server_addr_; +}; + +struct ObFreezeSplitSrcTabletArg final +{ + OB_UNIS_VERSION(1); +public: + ObFreezeSplitSrcTabletArg() : tenant_id_(OB_INVALID_TENANT_ID), ls_id_(), tablet_ids_() {} + ~ObFreezeSplitSrcTabletArg() = default; + bool is_valid() const { return tenant_id_ != OB_INVALID_TENANT_ID && ls_id_.is_valid() && !tablet_ids_.empty(); } + int assign(const ObFreezeSplitSrcTabletArg &other); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_ids)); +public: + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObSArray tablet_ids_; +}; + +struct ObFreezeSplitSrcTabletRes final +{ + OB_UNIS_VERSION(1); +public: + ObFreezeSplitSrcTabletRes() : data_end_scn_() {} + ~ObFreezeSplitSrcTabletRes() = default; + bool is_valid() const { return data_end_scn_.is_valid_and_not_min(); } + int assign(const ObFreezeSplitSrcTabletRes &other); + TO_STRING_KV(K_(data_end_scn)); +public: + share::SCN data_end_scn_; +}; + +struct ObAutoSplitTabletArg final +{ + OB_UNIS_VERSION(1); +public: + ObAutoSplitTabletArg() + : ls_id_(), tablet_id_(), tenant_id_(OB_INVALID), + auto_split_tablet_size_(OB_INVALID_SIZE), used_disk_space_(OB_INVALID_SIZE) + {} + ~ObAutoSplitTabletArg() = default; + int assign(const ObAutoSplitTabletArg &other); + bool is_valid() const + { + return OB_INVALID_ID != tenant_id_ && ls_id_.is_valid() && tablet_id_.is_valid() + && OB_INVALID_SIZE != auto_split_tablet_size_ && OB_INVALID_SIZE != used_disk_space_; + }; + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_id), K_(auto_split_tablet_size), K_(used_disk_space)); +public: + share::ObLSID ls_id_; + ObTabletID tablet_id_; + uint64_t tenant_id_; + int64_t auto_split_tablet_size_; + int64_t used_disk_space_; +}; + +struct ObAutoSplitTabletBatchArg final +{ + OB_UNIS_VERSION(1); +public: + ObAutoSplitTabletBatchArg() + : args_() + {} + ~ObAutoSplitTabletBatchArg() = default; + int assign(const ObAutoSplitTabletBatchArg &other); + bool is_valid() const; + TO_STRING_KV(K_(args)); +public: + ObSArray args_; +}; + +struct ObAutoSplitTabletBatchRes final +{ + OB_UNIS_VERSION(1); +public: + ObAutoSplitTabletBatchRes() + : rets_(), suggested_next_valid_time_(OB_INVALID_TIMESTAMP) + {} + ~ObAutoSplitTabletBatchRes() = default; + int assign(const ObAutoSplitTabletBatchRes &other); + bool is_valid() const; + TO_STRING_KV(K_(rets), K_(suggested_next_valid_time)); +public: + ObSArray rets_; + int64_t suggested_next_valid_time_; +}; + +struct ObFetchSplitTabletInfoArg final +{ + OB_UNIS_VERSION(1); +public: + ObFetchSplitTabletInfoArg() : tenant_id_(OB_INVALID_TENANT_ID), ls_id_(), tablet_ids_() {} + ~ObFetchSplitTabletInfoArg() = default; + bool is_valid() const { return tenant_id_ != OB_INVALID_TENANT_ID && ls_id_.is_valid() && !tablet_ids_.empty(); } + int assign(const ObFetchSplitTabletInfoArg &other); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_ids)); +public: + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObSArray tablet_ids_; +}; + +struct ObFetchSplitTabletInfoRes final +{ + OB_UNIS_VERSION(1); +public: + ObFetchSplitTabletInfoRes() : create_commit_versions_() {} + ~ObFetchSplitTabletInfoRes() = default; + bool is_valid() const { return !create_commit_versions_.empty(); } + int assign(const ObFetchSplitTabletInfoRes &other); + TO_STRING_KV(K_(create_commit_versions)); +public: + common::ObSArray create_commit_versions_; +}; + + +// === RPC for tablet split end. === + struct ObLogReqLoadProxyRequest { OB_UNIS_VERSION(1); @@ -10776,7 +11284,7 @@ public: ~ObGetSSMicroBlockMetaArg() {} bool is_valid() const { - return OB_INVALID_TENANT_ID != tenant_id_ && micro_key_.is_valid();; + return OB_INVALID_TENANT_ID != tenant_id_ && micro_key_.is_valid(); } TO_STRING_KV(K_(tenant_id), K_(micro_key)); public: @@ -11522,6 +12030,40 @@ public: common::ObSArray binding_datas_; }; +struct ObBatchGetTabletSplitArg final +{ + OB_UNIS_VERSION(1); +public: + ObBatchGetTabletSplitArg() + : tenant_id_(OB_INVALID_ID), ls_id_(), tablet_ids_(), check_committed_(false) + {} + ~ObBatchGetTabletSplitArg() {} +public: + int assign(const ObBatchGetTabletSplitArg &other); + bool is_valid() const { return tenant_id_ != OB_INVALID_ID && ls_id_.is_valid() && tablet_ids_.count() > 0; } + int init(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObIArray &tablet_ids, const bool check_committed); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_ids), K_(check_committed)); +public: + uint64_t tenant_id_; + share::ObLSID ls_id_; + common::ObSArray tablet_ids_; + bool check_committed_; +}; + +struct ObBatchGetTabletSplitRes final +{ + OB_UNIS_VERSION(1); +public: + ObBatchGetTabletSplitRes() : split_datas_() {} + ~ObBatchGetTabletSplitRes() {} +public: + int assign(const ObBatchGetTabletSplitRes &other); + bool is_valid() const { return split_datas_.count() > 0; } + TO_STRING_KV(K_(split_datas)); +public: + common::ObSArray split_datas_; +}; + struct ObFetchLocationResult { public: diff --git a/src/share/ob_srv_rpc_proxy.h b/src/share/ob_srv_rpc_proxy.h index 96b01deb5..acfdc48de 100644 --- a/src/share/ob_srv_rpc_proxy.h +++ b/src/share/ob_srv_rpc_proxy.h @@ -91,10 +91,11 @@ public: RPC_AP(PR5 minor_freeze, OB_MINOR_FREEZE, (ObMinorFreezeArg), obrpc::Int64); RPC_AP(PR5 check_schema_version_elapsed, OB_CHECK_SCHEMA_VERSION_ELAPSED, (ObCheckSchemaVersionElapsedArg), ObCheckSchemaVersionElapsedResult); + RPC_AP(PR5 check_memtable_cnt, OB_CHECK_MEMTABLE_CNT, (ObCheckMemtableCntArg), ObCheckMemtableCntResult); + RPC_AP(PR5 check_medium_compaction_info_list_cnt, OB_CHECK_MEDIUM_INFO_LIST_CNT, (ObCheckMediumCompactionInfoListArg), ObCheckMediumCompactionInfoListResult); RPC_AP(PR5 check_modify_time_elapsed, OB_CHECK_MODIFY_TIME_ELAPSED, (ObCheckModifyTimeElapsedArg), ObCheckModifyTimeElapsedResult); RPC_AP(PR5 check_ddl_tablet_merge_status, OB_DDL_CHECK_TABLET_MERGE_STATUS, (ObDDLCheckTabletMergeStatusArg), ObDDLCheckTabletMergeStatusResult); - RPC_S(PR5 switch_leader, OB_SWITCH_LEADER, (ObSwitchLeaderArg)); RPC_S(PR5 batch_switch_rs_leader, OB_BATCH_SWITCH_RS_LEADER, (ObAddr)); RPC_S(PR5 get_partition_count, OB_GET_PARTITION_COUNT, @@ -146,7 +147,12 @@ public: RPC_S(PR5 force_set_server_list, OB_FORCE_SET_SERVER_LIST, (ObForceSetServerListArg)); RPC_S(PR5 calc_column_checksum_request, OB_CALC_COLUMN_CHECKSUM_REQUEST, (ObCalcColumnChecksumRequestArg), obrpc::ObCalcColumnChecksumRequestRes); RPC_AP(PR5 build_ddl_single_replica_request, OB_DDL_BUILD_SINGLE_REPLICA_REQUEST, (obrpc::ObDDLBuildSingleReplicaRequestArg), obrpc::ObDDLBuildSingleReplicaRequestResult); + RPC_S(PR5 build_split_tablet_data_start_request, OB_SPLIT_TABLET_DATA_START_REQUEST, (obrpc::ObTabletSplitStartArg), obrpc::ObTabletSplitStartResult); + RPC_S(PR5 build_split_tablet_data_finish_request, OB_SPLIT_TABLET_DATA_FINISH_REQUEST, (obrpc::ObTabletSplitFinishArg), obrpc::ObTabletSplitFinishResult); + RPC_S(PR5 freeze_split_src_tablet, OB_FREEZE_SPLIT_SRC_TABLET, (obrpc::ObFreezeSplitSrcTabletArg), obrpc::ObFreezeSplitSrcTabletRes); + RPC_S(PR5 prepare_tablet_split_task_ranges, OB_PREPARE_TABLET_SPLIT_TASK_RANGES, (obrpc::ObPrepareSplitRangesArg), obrpc::ObPrepareSplitRangesRes); RPC_S(PR5 check_and_cancel_ddl_complement_dag, OB_CHECK_AND_CANCEL_DDL_COMPLEMENT_DAG, (ObDDLBuildSingleReplicaRequestArg), Bool); + RPC_S(PR5 fetch_split_tablet_info, OB_FETCH_SPLIT_TABLET_INFO, (obrpc::ObFetchSplitTabletInfoArg), obrpc::ObFetchSplitTabletInfoRes); RPC_S(PR5 check_and_cancel_delete_lob_meta_row_dag, OB_CHECK_AND_CANCEL_DELETE_LOB_META_ROW_DAG, (ObDDLBuildSingleReplicaRequestArg), Bool); RPC_S(PR5 fetch_tablet_autoinc_seq_cache, OB_FETCH_TABLET_AUTOINC_SEQ_CACHE, (obrpc::ObFetchTabletSeqArg), obrpc::ObFetchTabletSeqRes); RPC_AP(PR5 batch_get_tablet_autoinc_seq, OB_BATCH_GET_TABLET_AUTOINC_SEQ, (obrpc::ObBatchGetTabletAutoincSeqArg), obrpc::ObBatchGetTabletAutoincSeqRes); @@ -154,6 +160,7 @@ public: RPC_S(PR5 set_tablet_autoinc_seq, OB_SET_TABLET_AUTOINC_SEQ, (obrpc::ObBatchSetTabletAutoincSeqArg), obrpc::ObBatchSetTabletAutoincSeqRes); RPC_AP(PR5 clear_tablet_autoinc_seq_cache, OB_CLEAR_TABLET_AUTOINC_SEQ_CACHE, (obrpc::ObClearTabletAutoincSeqCacheArg), obrpc::Int64); RPC_S(PR5 batch_get_tablet_binding, OB_BATCH_GET_TABLET_BINDING, (obrpc::ObBatchGetTabletBindingArg), obrpc::ObBatchGetTabletBindingRes); + RPC_S(PR5 batch_get_tablet_split, OB_BATCH_GET_TABLET_SPLIT, (obrpc::ObBatchGetTabletSplitArg), obrpc::ObBatchGetTabletSplitRes); RPC_S(PRD force_create_sys_table, OB_FORCE_CREATE_SYS_TABLE, (ObForceCreateSysTableArg)); RPC_S(PRD schema_revise, OB_SCHEMA_REVISE, (ObSchemaReviseArg)); RPC_S(PRD force_set_locality, OB_FORCE_SET_LOCALITY, (ObForceSetLocalityArg)); @@ -207,9 +214,11 @@ public: transaction::tablelock::ObTableLockTaskResult); RPC_AP(PR4 unlock_table, OB_HIGH_PRIORITY_TABLE_LOCK_TASK, (transaction::tablelock::ObTableLockTaskRequest), transaction::tablelock::ObTableLockTaskResult); - RPC_AP(PR5 batch_lock_obj, OB_BATCH_TABLE_LOCK_TASK, (transaction::tablelock::ObLockTaskBatchRequest), + RPC_AP(PR5 batch_lock_obj, OB_BATCH_TABLE_LOCK_TASK, (transaction::tablelock::ObLockTaskBatchRequest), transaction::tablelock::ObTableLockTaskResult); - RPC_AP(PR4 batch_unlock_obj, OB_HIGH_PRIORITY_BATCH_TABLE_LOCK_TASK, (transaction::tablelock::ObLockTaskBatchRequest), + RPC_AP(PR4 batch_unlock_obj, OB_HIGH_PRIORITY_BATCH_TABLE_LOCK_TASK, (transaction::tablelock::ObLockTaskBatchRequest), + transaction::tablelock::ObTableLockTaskResult); + RPC_AP(PR5 batch_replace_lock_obj, OB_BATCH_REPLACE_TABLE_LOCK_TASK, (transaction::tablelock::ObLockTaskBatchRequest), transaction::tablelock::ObTableLockTaskResult); RPC_S(PR4 admin_remove_lock_op, OB_REMOVE_OBJ_LOCK, (transaction::tablelock::ObAdminRemoveLockOpArg)); RPC_S(PR4 admin_update_lock_op, OB_UPDATE_OBJ_LOCK, (transaction::tablelock::ObAdminUpdateLockOpArg)); diff --git a/src/share/ob_tablet_reorganize_history_table_operator.cpp b/src/share/ob_tablet_reorganize_history_table_operator.cpp index 1d16222d8..c2d0de773 100644 --- a/src/share/ob_tablet_reorganize_history_table_operator.cpp +++ b/src/share/ob_tablet_reorganize_history_table_operator.cpp @@ -40,10 +40,11 @@ int ObTabletReorganizeHistoryTableOperator::check_tablet_has_reorganized( } else { HEAP_VAR(ObMySQLProxy::ReadResult, res) { ObMySQLResult *result = NULL; + const uint64_t zero_tenant_id = 0; if (OB_FAIL(sql.assign_fmt( "select * from %s where tenant_id = %lu and src_tablet_id = %ld", - OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, tenant_id, tablet_id.id()))) { - LOG_WARN("failed to assign sql", K(ret), K(sql), K(tenant_id), K(tablet_id)); + OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, zero_tenant_id, tablet_id.id()))) { + LOG_WARN("failed to assign sql", K(ret), K(sql), K(tablet_id)); } else if (OB_FAIL(proxy.read(res, tenant_id, sql.ptr()))) { LOG_WARN("failed to exec sql", K(ret), K(tenant_id), K(sql)); } else if (OB_ISNULL(result = res.get_result())) { @@ -64,7 +65,6 @@ int ObTabletReorganizeHistoryTableOperator::check_tablet_has_reorganized( } } } - return ret; } @@ -84,8 +84,9 @@ int ObTabletReorganizeHistoryTableOperator::get_all_split_tablet_pairs( } else { SMART_VAR(ObMySQLProxy::MySQLResult, res) { sqlclient::ObMySQLResult *result = NULL; - if (OB_FAIL(sql_string.assign_fmt("SELECT src_tablet_id, dest_tablet_id FROM %s WHERE tenant_id = %ld " - "AND ls_id = %ld", OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, tenant_id, ls_id.id()))) { + const uint64_t zero_tenant_id = 0; + if (OB_FAIL(sql_string.assign_fmt("SELECT src_tablet_id, dest_tablet_id FROM %s WHERE " + " tenant_id = %lu and ls_id = %ld", OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, zero_tenant_id, ls_id.id()))) { LOG_WARN("assign sql string failed", K(ret), K(tenant_id), K(ls_id)); } else if (OB_FAIL(sql_proxy.read(res, tenant_id, sql_string.ptr()))) { LOG_WARN("read tablet ids from all tablet reorganize history table failed", K(ret), K(sql_string)); @@ -136,8 +137,9 @@ int ObTabletReorganizeHistoryTableOperator::get_split_tablet_pairs_by_src( } else { SMART_VAR(ObMySQLProxy::MySQLResult, res) { sqlclient::ObMySQLResult *result = NULL; - if (OB_FAIL(sql_string.assign_fmt("SELECT src_tablet_id, dest_tablet_id FROM %s WHERE tenant_id = %ld " - "AND ls_id = %ld and src_tablet_id = %ld", OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, tenant_id, ls_id.id(), tablet_id.id()))) { + const uint64_t zero_tenant_id = 0; + if (OB_FAIL(sql_string.assign_fmt("SELECT src_tablet_id, dest_tablet_id FROM %s WHERE " + " tenant_id = %lu and ls_id = %ld and src_tablet_id = %ld", OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, zero_tenant_id, ls_id.id(), tablet_id.id()))) { LOG_WARN("assign sql string failed", K(ret), K(tenant_id), K(ls_id)); } else if (OB_FAIL(sql_proxy.read(res, tenant_id, sql_string.ptr()))) { LOG_WARN("read tablet ids from all tablet reorganize history table failed", K(ret), K(sql_string)); @@ -186,10 +188,11 @@ int ObTabletReorganizeHistoryTableOperator::get_split_tablet_pairs_by_dest( } else { HEAP_VAR(ObMySQLProxy::ReadResult, res) { ObMySQLResult *result = NULL; + const uint64_t zero_tenant_id = 0; if (OB_FAIL(sql.assign_fmt( "select * from %s where tenant_id = %lu and dest_tablet_id = %ld", - OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, tenant_id, tablet_id.id()))) { - LOG_WARN("failed to assign sql", K(ret), K(sql), K(tenant_id), K(tablet_id)); + OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, zero_tenant_id, tablet_id.id()))) { + LOG_WARN("failed to assign sql", K(ret), K(sql), K(tablet_id)); } else if (OB_FAIL(sql_proxy.read(res, tenant_id, sql.ptr()))) { LOG_WARN("failed to exec sql", K(ret), K(tenant_id), K(sql)); } else if (OB_ISNULL(result = res.get_result())) { @@ -223,14 +226,14 @@ int ObTabletReorganizeHistoryTableOperator::insert( if (OB_FAIL(insert_sql.assign_fmt("INSERT INTO %s (tenant_id, ls_id, src_tablet_id, dest_tablet_id, " "type, create_time, finish_time) VALUES (%lu, %ld, %ld, %ld, %ld, usec_to_time(%lu), usec_to_time(%lu))" " ON DUPLICATE KEY UPDATE finish_time = usec_to_time(%lu)", - OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, record.tenant_id_, record.ls_id_.id(), record.src_tablet_id_.id(), + OB_ALL_TABLET_REORGANIZE_HISTORY_TNAME, ObSchemaUtils::get_extract_tenant_id(record.tenant_id_, record.tenant_id_), record.ls_id_.id(), record.src_tablet_id_.id(), record.dest_tablet_id_.id(), int64_t(record.type_), record.create_time_, record.finish_time_, record.finish_time_))) { LOG_WARN("failed to assign fmt", K(ret), K(record.tenant_id_), K(record.ls_id_), K(record.src_tablet_id_), K(record.dest_tablet_id_), K(record.type_), K(record.create_time_), K(record.finish_time_)); } else if (OB_FAIL(sql_proxy.write(record.tenant_id_, insert_sql.ptr(), affected_rows))) { LOG_WARN("failed to write sql", K(ret), K(insert_sql)); } else { - LOG_INFO("insert tabler reorganize history table success", K(ret), K(record.tenant_id_), K(record.ls_id_), + LOG_INFO("insert tablet reorganize history table success", K(ret), K(record.tenant_id_), K(record.ls_id_), K(record.src_tablet_id_), K(record.dest_tablet_id_), K(record.type_), K(record.create_time_), K(record.finish_time_)); } @@ -240,7 +243,9 @@ int ObTabletReorganizeHistoryTableOperator::insert( int ObTabletReorganizeHistoryTableOperator::batch_insert( ObISQLClient &sql_proxy, const uint64_t tenant_id, - const obrpc::ObPartitionSplitArg &split_arg) + const obrpc::ObPartitionSplitArg &split_arg, + const int64 start_time, + const int64 finish_time) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; @@ -248,7 +253,7 @@ int ObTabletReorganizeHistoryTableOperator::batch_insert( if (OB_FAIL(trans.start(&sql_proxy, tenant_id))) { LOG_WARN("failed to start trans", K(ret)); } else { - if (OB_FAIL(inner_batch_insert_(trans, tenant_id, split_arg.src_tablet_id_, split_arg.dest_tablet_ids_))) { + if (OB_FAIL(inner_batch_insert_(trans, tenant_id, split_arg.src_tablet_id_, split_arg.dest_tablet_ids_, start_time, finish_time))) { LOG_WARN("failed to inner batch insert", K(ret)); } else if (split_arg.src_local_index_tablet_ids_.count() != split_arg.dest_local_index_tablet_ids_.count()) { ret = OB_ERR_UNEXPECTED; @@ -257,7 +262,7 @@ int ObTabletReorganizeHistoryTableOperator::batch_insert( ARRAY_FOREACH_X(split_arg.dest_local_index_tablet_ids_, idx, cnt, OB_SUCC(ret)) { const ObTabletID &src_tablet_id = split_arg.src_local_index_tablet_ids_.at(idx); const ObSArray &dest_tablet_ids = split_arg.dest_local_index_tablet_ids_.at(idx); - if (OB_FAIL(inner_batch_insert_(trans, tenant_id, src_tablet_id, dest_tablet_ids))) { + if (OB_FAIL(inner_batch_insert_(trans, tenant_id, src_tablet_id, dest_tablet_ids, start_time, finish_time))) { LOG_WARN("failed to inner batch insert", K(ret)); } } @@ -270,7 +275,7 @@ int ObTabletReorganizeHistoryTableOperator::batch_insert( ARRAY_FOREACH_X(split_arg.dest_lob_tablet_ids_, idx, cnt, OB_SUCC(ret)) { const ObTabletID &src_tablet_id = split_arg.src_lob_tablet_ids_.at(idx); const ObSArray &dest_tablet_ids = split_arg.dest_lob_tablet_ids_.at(idx); - if (OB_FAIL(inner_batch_insert_(trans, tenant_id, src_tablet_id, dest_tablet_ids))) { + if (OB_FAIL(inner_batch_insert_(trans, tenant_id, src_tablet_id, dest_tablet_ids, start_time, finish_time))) { LOG_WARN("failed to inner batch insert", K(ret)); } } @@ -289,7 +294,9 @@ int ObTabletReorganizeHistoryTableOperator::inner_batch_insert_( ObISQLClient &sql_proxy, const uint64_t tenant_id, const ObTabletID &tablet_id, - const ObSArray &dest_tablet_ids) + const ObSArray &dest_tablet_ids, + const int64 start_time, + const int64 finish_time) { int ret = OB_SUCCESS; ARRAY_FOREACH_X(dest_tablet_ids, idx, cnt, OB_SUCC(ret)) { @@ -311,8 +318,8 @@ int ObTabletReorganizeHistoryTableOperator::inner_batch_insert_( src_tablet_id, dest_tablet_id, ObTabletReorganizeType::SPLIT, - 0/*create_time*/, - 0/*finish_time*/); + start_time/*create_time*/, + finish_time/*finish_time*/); // TODO(yanfeng): do real batch later if (OB_FAIL(insert(sql_proxy, record))) { LOG_WARN("failed to insert record", K(ret), K(record)); diff --git a/src/share/ob_tablet_reorganize_history_table_operator.h b/src/share/ob_tablet_reorganize_history_table_operator.h index 3f3682620..0354398a6 100644 --- a/src/share/ob_tablet_reorganize_history_table_operator.h +++ b/src/share/ob_tablet_reorganize_history_table_operator.h @@ -118,13 +118,21 @@ public: static int insert( ObISQLClient &sql_proxy, const ObTabletReorganizeRecord &record); + static int batch_insert( + ObISQLClient &sql_proxy, + const uint64_t tenant_id, + const obrpc::ObPartitionSplitArg &split_arg, + const int64 start_time, + const int64 finish_time); private: static int inner_batch_insert_( ObISQLClient &sql_proxy, const uint64_t tenant_id, const ObTabletID &tablet_id, - const ObSArray &dest_tablet_ids); + const ObSArray &dest_tablet_ids, + const int64 start_time, + const int64 finish_time); }; // class ObTabletReorganizeHistoryTableOperator } // namespace share diff --git a/src/share/parameter/ob_parameter_seed.ipp b/src/share/parameter/ob_parameter_seed.ipp index fb0653625..3f2872c04 100644 --- a/src/share/parameter/ob_parameter_seed.ipp +++ b/src/share/parameter/ob_parameter_seed.ipp @@ -1943,6 +1943,18 @@ DEF_TIME(_ha_rpc_timeout, OB_TENANT_PARAMETER, "0", "[0,120s]", DEF_BOOL(_enable_trace_tablet_leak, OB_TENANT_PARAMETER, "False", "enable t3m tablet leak checker. The default value is False", ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::STATIC_EFFECTIVE)); +DEF_BOOL(enable_auto_split, OB_TENANT_PARAMETER, "False", + "if the auto-partition clause is not used" + "this config judge whether to enable auto-partition for creating table.", + ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +DEF_CAP(auto_split_tablet_size, OB_TENANT_PARAMETER, "128M", "[128M,)", + "when create an auto-partitioned table in \"create table\" syntax or " + "modify a table as an auto-partitioned table in \"alter table\" syntax," + "if the splitting threshold of tablet size is not setted," + "this config will be setted as the threshold of the table." + "Note that the modification of this config will not affect the created auto-partitioned table." + "Range: [128M, +∞)", + ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); DEF_INT(_inlist_rewrite_threshold, OB_TENANT_PARAMETER, "2147483647", "[1, 2147483647]" "specifies transform how much const params in IN list to values table", ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); @@ -2153,6 +2165,10 @@ DEF_STR_WITH_CHECKER(sql_plan_management_mode, OB_TENANT_PARAMETER, "Disable", "\"Disable\" represent disable spm (default value)." "\"OnlineEvolve\" represent evolve plan online.", ObParameterAttr(Section::TENANT, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); +ERRSIM_DEF_TIME(errsim_delay_gc_interval, OB_CLUSTER_PARAMETER, "30m", "[0,)", + "delay gc interval in errsim mode" + "Range: [0, +∞)", + ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE)); // regexp engine DEF_STR_WITH_CHECKER(_regex_engine, OB_TENANT_PARAMETER, "ICU", common::ObConfigRegexpEngineChecker, diff --git a/src/share/rc/ob_tenant_base.h b/src/share/rc/ob_tenant_base.h index cbd60f184..95f035b5f 100755 --- a/src/share/rc/ob_tenant_base.h +++ b/src/share/rc/ob_tenant_base.h @@ -243,6 +243,7 @@ class ObIndexUsageInfoMgr; class ObStorageIOUsageRepoter; class ObResourceLimitCalculator; class ObPluginVectorIndexService; +class ObAutoSplitTaskCache; namespace schema { class ObTenantSchemaService; @@ -424,6 +425,7 @@ using ObTableScanIteratorObjPool = common::ObServerObjectPool= QUICK_RESTORE_FINISH && status_ <= WAIT_RESTORE_MAJOR_DATA) return NONE == status_ || QUICK_RESTORE_FINISH == status_; } Status get_status() const { return status_; } diff --git a/src/share/rpc/ob_async_rpc_proxy.h b/src/share/rpc/ob_async_rpc_proxy.h index 351b887b0..a82bd4b5c 100644 --- a/src/share/rpc/ob_async_rpc_proxy.h +++ b/src/share/rpc/ob_async_rpc_proxy.h @@ -524,6 +524,7 @@ int ObAsyncRpcProxy::check_return_cnt( typedef obrpc::ObAsyncRpcProxy *, const obrpc::ObRpcOpts &), obrpc::ObSrvRpcProxy> name + }//end namespace obrpc }//end namespace oceanbase diff --git a/src/share/scheduler/ob_dag_scheduler_config.h b/src/share/scheduler/ob_dag_scheduler_config.h index f84f780f8..7977ea7c9 100644 --- a/src/share/scheduler/ob_dag_scheduler_config.h +++ b/src/share/scheduler/ob_dag_scheduler_config.h @@ -81,6 +81,8 @@ DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_DDL_KV_MERGE, ObDagPrio::DAG_PRIO_DDL_HIGH, true, 3, {"ls_id", "tablet_id", "rec_scn"}) DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_DDL_DEL_LOB_META, ObDagPrio::DAG_PRIO_DDL, ObSysTaskType::DDL_TASK, "DDL_DEL_LOB_META", "DROP_VEC_INDEX", true, 7, {"ls_id", "source_tablet_id", "dest_tablet_id", "data_table_id", "target_table_id", "schema_version", "snapshot_version"}) +DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_TABLET_SPLIT, ObDagPrio::DAG_PRIO_DDL, ObSysTaskType::DDL_TABLET_SPLIT, "DDL_TABLET_SPLIT", "DDL", + true, 2, {"ls_id", "source_tablet_id"}) // DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_MIGRATE, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "MIGRATE", "MIGRATE") DAG_SCHEDULER_DAG_TYPE_DEF(DAG_TYPE_INITIAL_COMPLETE_MIGRATION, ObDagPrio::DAG_PRIO_HA_HIGH, ObSysTaskType::MIGRATION_TASK, "INITIAL_COMPLETE_MIGRATION", "MIGRATE", diff --git a/src/share/scheduler/ob_partition_auto_split_helper.cpp b/src/share/scheduler/ob_partition_auto_split_helper.cpp new file mode 100644 index 000000000..57491bb8d --- /dev/null +++ b/src/share/scheduler/ob_partition_auto_split_helper.cpp @@ -0,0 +1,1821 @@ +/** + * 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_partition_auto_split_helper.h" +#include "lib/string/ob_sql_string.h" +#include "lib/container/ob_array.h" +#include "share/schema/ob_schema_getter_guard.h" +#include "share/schema/ob_schema_struct.h" +#include "share/schema/ob_schema_mgr.h" +#include "share/schema/ob_multi_version_schema_service.h" +#include "share/system_variable/ob_system_variable_alias.h" +#include "share/ob_rpc_struct.h" +#include "observer/omt/ob_tenant_timezone_mgr.h" +#include "observer/ob_server_struct.h" +#include "rootserver/ob_root_service.h" +#include "storage/ob_storage_rpc.h" +#include "storage/tx_storage/ob_ls_service.h" + +namespace oceanbase +{ +namespace share +{ +ObAutoSplitTaskKey::ObAutoSplitTaskKey() + : tenant_id_(OB_INVALID_TENANT_ID), + tablet_id_(common::ObTabletID::INVALID_TABLET_ID) + {} + +ObAutoSplitTaskKey::ObAutoSplitTaskKey(const uint64_t tenant_id, const ObTabletID &tablet_id) + : tenant_id_(tenant_id), + tablet_id_(tablet_id) + {} + +uint64_t ObAutoSplitTaskKey::hash() const +{ + uint64_t hash_val = murmurhash(&tenant_id_, sizeof(tenant_id_), 0); + hash_val = murmurhash(&tablet_id_, sizeof(tablet_id_), hash_val); + return hash_val; +} + +bool ObAutoSplitTaskKey::operator==(const ObAutoSplitTaskKey &other) const +{ + return tenant_id_ == other.tenant_id_ && tablet_id_ == other.tablet_id_; +} + +bool ObAutoSplitTaskKey::operator!=(const ObAutoSplitTaskKey &other) const +{ + return !(*this == other); +} + +int ObAutoSplitTaskKey::assign(const ObAutoSplitTaskKey &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(other)); + } else { + tenant_id_ = other.tenant_id_; + tablet_id_ = other.tablet_id_; + } + return ret; +} + +int ObAutoSplitTask::assign(const ObAutoSplitTask &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(other)); + } else { + auto_split_tablet_size_ = other.auto_split_tablet_size_; + ls_id_ = other.ls_id_; + retry_times_ = other.retry_times_; + tablet_id_ = other.tablet_id_; + tenant_id_ = other.tenant_id_; + used_disk_space_ = other.used_disk_space_; + } + return ret; +} + +ObAutoSplitTaskCache::ObAutoSplitTaskCache() + : inited_(false), total_tasks_(0), tenant_id_(OB_INVALID_TENANT_ID), + max_heap_(max_comp_, &cache_malloc_), min_heap_(min_comp_, &cache_malloc_) + {} + +int ObAutoSplitTaskCache::init(const int64_t capacity, const uint64_t tenant_id, const uint64_t host_tenant_id) +{ + int ret = OB_SUCCESS; + ObLockGuard guard(lock_); + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init ObAutoSplitTaskCache twice", K(ret), K(inited_)); + } else if (OB_UNLIKELY(capacity <= 0 || OB_INVALID_TENANT_ID == tenant_id || OB_INVALID_TENANT_ID == host_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(capacity), K(tenant_id), K(host_tenant_id)); + } else if (OB_FAIL(tasks_set_.create(capacity, ObMemAttr(host_tenant_id, "task_cache")))) { + LOG_WARN("fail to create hashset", KR(ret)); + } else { + inited_ = true; + tenant_id_ = tenant_id; + host_tenant_id_ = host_tenant_id; + cache_malloc_.set_attr(ObMemAttr(host_tenant_id_, "task_cache")); + } + return ret; +} + +int ObAutoSplitTaskCache::mtl_init(ObAutoSplitTaskCache *&task_cache) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(task_cache)) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("unexpeted null ptr of task_cache", K(ret), KP(task_cache)); + } else if (OB_FAIL(task_cache->init(ObAutoSplitTaskCache::CACHE_MAX_CAPACITY, MTL_ID(), MTL_ID()))) { + LOG_WARN("failed to init ObAutoSplitTaskCache", K(ret), "tenant_id: ", MTL_ID()); + } + return ret; +} + +void ObAutoSplitTaskCache::destroy() +{ + ObLockGuard guard(lock_); + const ObIArray &min_heap_array = min_heap_.get_heap_data(); + const ObIArray &max_heap_array = max_heap_.get_heap_data(); + for (int64_t i = 0; i < min_heap_array.count(); ++i) { + ObAutoSplitTaskWrapper *ptr_to_tsak_wrapper = min_heap_array.at(i); + if (OB_NOT_NULL(ptr_to_tsak_wrapper)) { + (*ptr_to_tsak_wrapper).~ObAutoSplitTaskWrapper(); + cache_malloc_.free(ptr_to_tsak_wrapper); + ptr_to_tsak_wrapper = nullptr; + } + } + for (int64_t i = 0; i < max_heap_array.count(); ++i) { + ObAutoSplitTaskWrapper *ptr_in_max = max_heap_array.at(i); + bool find = false; + for (int64_t j = 0; j < min_heap_array.count(); ++j) { + ObAutoSplitTaskWrapper *ptr_in_min = min_heap_array.at(j); + if (ptr_in_min == ptr_in_max) { + find = true; + break; + } + } + if (OB_UNLIKELY(!find) && OB_NOT_NULL(ptr_in_max)) { + (*ptr_in_max).~ObAutoSplitTaskWrapper(); + cache_malloc_.free(ptr_in_max); + ptr_in_max = nullptr; + } + } + inited_ = false; + total_tasks_ = 0; + tenant_id_ = OB_INVALID_TENANT_ID; + max_heap_.reset(); + min_heap_.reset(); + (void) tasks_set_.destroy(); +} + +int ObAutoSplitTaskCache::remove_tasks(const int64_t num_tasks_to_rem) +{ + int ret = OB_SUCCESS; + int64_t num_tasks_rem = 0; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_UNLIKELY(num_tasks_to_rem <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(num_tasks_to_rem)); + } else { + int64_t num_tasks_can_rem = min(get_tasks_num(), num_tasks_to_rem); + for (; OB_SUCC(ret) && num_tasks_can_rem > 0; --num_tasks_can_rem) { + if (OB_FAIL(atomic_remove_task())) { + LOG_WARN("atomic remove task failed", K(ret)); + } + } + } + return ret; +} + +int ObAutoSplitTaskCache::atomic_remove_task() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_UNLIKELY(min_heap_.count() <= 0 || max_heap_.count() <= 0)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("no element to remove", K(ret), K(min_heap_.count()), K(max_heap_.count())); + } else { + ObAutoSplitTaskWrapper *ptr_task_wrapper = min_heap_.top(); + if (OB_ISNULL(ptr_task_wrapper)) { + ret = OB_NULL_CHECK_ERROR; + LOG_ERROR("ptr_task_wrapper is nullptr", K(ret)); + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(min_heap_.pop())) { + LOG_WARN("pop from min heap failed", K(ret)); + } + } else if (OB_FAIL(tasks_set_.erase_refactored(ObAutoSplitTaskKey(ptr_task_wrapper->task_.tenant_id_, ptr_task_wrapper->task_.tablet_id_))) && OB_HASH_NOT_EXIST != ret) { + LOG_WARN("remove key from task_set_ failed", K(ret)); + } else { + if (OB_HASH_NOT_EXIST == ret) { + LOG_WARN("task key not existed in tasks_sets", K(ret), K(ObAutoSplitTaskKey(ptr_task_wrapper->task_.tenant_id_, ptr_task_wrapper->task_.tablet_id_))); + //overwrite ret + ret = OB_SUCCESS; + } + int64_t pos_at_max_heap = ptr_task_wrapper->pos_at_max_heap_; + if (pos_at_max_heap >= 0 && pos_at_max_heap < max_heap_.count() && max_heap_.at(pos_at_max_heap) == ptr_task_wrapper) { + if (OB_FAIL(max_heap_.remove(ptr_task_wrapper))) { + LOG_ERROR("remove from max_heap failed", K(ret)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the content of min heap and max heap don't match", K(ret), KPC(max_heap_.at(pos_at_max_heap)), KPC(ptr_task_wrapper)); + //overwrite ret + ret = OB_SUCCESS; + } + if (OB_SUCC(ret)) { + if (OB_FAIL(min_heap_.pop())) { + LOG_ERROR("pop from min heap failed", K(ret)); + } else { + (*ptr_task_wrapper).~ObAutoSplitTaskWrapper(); + cache_malloc_.free(ptr_task_wrapper); + ptr_task_wrapper = nullptr; + (void) ATOMIC_FAA(&total_tasks_, -1); + } + } + } + } + return ret; +} + +int ObAutoSplitTaskCache::atomic_push_task(const ObAutoSplitTask &task) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_UNLIKELY(!task.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(task)); + } else if (OB_ISNULL(buf = cache_malloc_.alloc(sizeof(ObAutoSplitTaskWrapper)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory for task failed", K(ret)); + } else { + ObAutoSplitTaskWrapper *ptr_t_wra_to_min = new (buf) ObAutoSplitTaskWrapper; + ObAutoSplitTaskWrapper *ptr_t_wra_to_max = nullptr; + ptr_t_wra_to_min->priority_ = static_cast(task.used_disk_space_) / task.auto_split_tablet_size_; + int tmp_ret = OB_SUCCESS; + (void) ATOMIC_FAA(&total_tasks_, 1); + if (OB_FAIL(ptr_t_wra_to_min->task_.assign(task))) { + LOG_WARN("task assign failed", K(ret), K(task)); + } else if (OB_FAIL(min_heap_.push(ptr_t_wra_to_min))) { + LOG_WARN("push task into min_heap_ failed", K(ret), K(task)); + } else if (OB_FALSE_IT(ptr_t_wra_to_max = ptr_t_wra_to_min)) { + } else if (OB_FALSE_IT(ptr_t_wra_to_min = nullptr)) { + } else if (OB_FAIL(max_heap_.push(ptr_t_wra_to_max))) { + LOG_WARN("push task into max_heap_ failed", K(ret), K(task)); + } else if (OB_FALSE_IT(ptr_t_wra_to_max = nullptr)) { + } else if (OB_FAIL(tasks_set_.set_refactored(ObAutoSplitTaskKey (task.tenant_id_, task.tablet_id_)))) { + LOG_WARN("push into task_set_ failed", K(ret)); + } + if (OB_NOT_NULL(ptr_t_wra_to_min)) { + (void) ATOMIC_FAA(&total_tasks_, -1); + (*ptr_t_wra_to_min).~ObAutoSplitTaskWrapper(); + cache_malloc_.free(ptr_t_wra_to_min); + ptr_t_wra_to_min = nullptr; + } + } + return ret; +} + +int ObAutoSplitTaskCache::atomic_pop_task(ObAutoSplitTask &task) +{ + int ret = OB_SUCCESS; + task.reset(); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_UNLIKELY(min_heap_.count() <= 0 || max_heap_.count() <= 0)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("no element to pop", K(ret), K(min_heap_.count()), K(max_heap_.count())); + } else { + ObAutoSplitTaskWrapper *ptr_task_wrapper = max_heap_.top(); + if (OB_ISNULL(ptr_task_wrapper)) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("ptr_task_wrapper is nullptr", K(ret)); + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(max_heap_.pop())) { + LOG_WARN("pop from min heap failed", K(ret)); + } + } else if (OB_FAIL(task.assign(ptr_task_wrapper->task_))) { + LOG_WARN("assign task failed", K(ret), K(task)); + } else if (OB_FAIL(tasks_set_.erase_refactored(ObAutoSplitTaskKey(task.tenant_id_, task.tablet_id_))) && OB_HASH_NOT_EXIST != ret) { + LOG_WARN("remove key from task_set_ failed", K(ret)); + } else { + if (OB_HASH_NOT_EXIST == ret) { + LOG_WARN("task key not existed in tasks_sets", K(ret)); + //overwrite ret + ret = OB_SUCCESS; + } + if (OB_FAIL(max_heap_.pop())) { + //overwrite ret + LOG_ERROR("max_heap_ pop failed", K(ret)); + } else if (OB_FAIL(min_heap_.remove(ptr_task_wrapper))) { + //overwrite ret + LOG_WARN("remove from min_heap_ failed", K(ret)); + } else { + (*ptr_task_wrapper).~ObAutoSplitTaskWrapper(); + cache_malloc_.free(ptr_task_wrapper); + ptr_task_wrapper = nullptr; + (void) ATOMIC_FAA(&total_tasks_, -1); + } + } + } + return ret; +} + +int ObAutoSplitTaskCache::pop_tasks(const int64_t num_tasks_to_pop, ObArray &task_array) +{ + int ret = OB_SUCCESS; + task_array.reuse(); + ObLockGuard guard(lock_); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_UNLIKELY(num_tasks_to_pop <= 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(num_tasks_to_pop)); + } else if (OB_UNLIKELY(min_heap_.count() <= 0 || max_heap_.count() <= 0)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_DEBUG("no element to pop", K(ret), K(min_heap_.count()), K(max_heap_.count())); + } else { + int ret = OB_SUCCESS; + int64_t num_tasks_can_pop = min(get_tasks_num(), num_tasks_to_pop); + ObAutoSplitTask task; + for (; OB_SUCC(ret) && num_tasks_can_pop > 0; --num_tasks_can_pop) { + task.reset(); + if (OB_FAIL(atomic_pop_task(task))) { + LOG_WARN("pop task failed", K(ret)); + } else if (OB_FAIL(task_array.push_back(task))) { + LOG_WARN("push back into task array failed", K(ret)); + } + } + } + return ret; +} + +int ObAutoSplitTaskCache::push_tasks(const ObArray &task_array) +{ + ObLockGuard guard(lock_); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_UNLIKELY(task_array.count() == 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(task_array)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < task_array.count(); ++i) { + const ObAutoSplitTask &task = task_array.at(i); + double task_priority = 0; + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(!task.is_valid())) { + tmp_ret = OB_INVALID_ARGUMENT; + LOG_WARN("trying to push an invalid task into cache", K(tmp_ret), K(task)); + } else if (OB_FALSE_IT(task_priority = static_cast(task.used_disk_space_) / task.auto_split_tablet_size_)) { + } else if (get_tasks_num() >= CACHE_MAX_CAPACITY && task_priority <= min_heap_.top()->priority_) { + // do nothing + } else if (OB_TMP_FAIL(tasks_set_.exist_refactored(ObAutoSplitTaskKey(task.tenant_id_, task.tablet_id_)))) { + if (OB_HASH_NOT_EXIST == tmp_ret) { + tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(atomic_push_task(task))) { + LOG_WARN("atomic push task failed", K(tmp_ret)); + } + } else if (OB_HASH_EXIST == tmp_ret) { + tmp_ret = OB_SUCCESS; + } else { + LOG_WARN("check task key existed failed", K(tmp_ret)); + } + } else { + //ObHashSet::exist_refactored always returns error + LOG_WARN("never expect to reach here", K(ret)); + } + } + if (OB_SUCC(ret)) { + int64_t diff = get_tasks_num() - CACHE_MAX_CAPACITY; + if (diff > 0 && OB_FAIL(remove_tasks(diff))) { + LOG_WARN("remove task from cache failed", K(ret), K(diff)); + } + } + } + return ret; +} + +int ObRsAutoSplitScheduler::pop_tasks(ObArray &task_array) +{ + int ret = OB_SUCCESS; + task_array.reuse(); + ObArray> tenant_task_arrays; + if (polling_mgr_.empty()) { + //do nothing + } else if (OB_FAIL(polling_mgr_.pop_tasks(ObRsAutoSplitScheduler::MAX_SPLIT_TASKS_ONE_ROUND, tenant_task_arrays))) { + LOG_WARN("fail to pop tasks from tree", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tenant_task_arrays.count(); ++i) { + ObArray &tmp_array = tenant_task_arrays.at(i); + if (OB_FAIL(task_array.push_back(tmp_array))) { + LOG_WARN("push tasks failed", K(ret)); + } + } + } + return ret; +} + +int ObRsAutoSplitScheduler::push_tasks(const ObArray &task_array) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(task_array.count() == 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(task_array)); + } else if (OB_FAIL(polling_mgr_.push_tasks(task_array))) { + LOG_WARN("fail to push tasks into polling_mgr_", K(ret)); + } + return ret; +} + +bool ObRsAutoSplitScheduler::can_retry(const ObAutoSplitTask &task, const int ret) +{ + return task.retry_times_ < ObRsAutoSplitScheduler::MAX_TIMES_TASK_RETRY + && ((!share::ObIDDLTask::in_ddl_retry_black_list(ret) && share::ObIDDLTask::in_ddl_retry_white_list(ret)) || OB_ERR_PARALLEL_DDL_CONFLICT == ret); +} + +ObServerAutoSplitScheduler &ObServerAutoSplitScheduler::get_instance() +{ + static ObServerAutoSplitScheduler instance; + return instance; +} + +ObRsAutoSplitScheduler &ObRsAutoSplitScheduler::get_instance() +{ + static ObRsAutoSplitScheduler instance; + return instance; +} + +int ObServerAutoSplitScheduler::check_tablet_creation_limit(const int64_t inc_tablet_cnt, const double safe_ratio) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = MTL_ID(); + ObUnitInfoGetter::ObTenantConfig unit; + ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); + int64_t tablet_cnt_per_gb = ObServerAutoSplitScheduler::TABLET_CNT_PER_GB; // default value + { + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); + if (OB_UNLIKELY(!tenant_config.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("get invalid tenant config", K(ret)); + } else { + tablet_cnt_per_gb = tenant_config->_max_tablet_cnt_per_gb; + } + } + + if (FAILEDx(GCTX.omt_->get_tenant_unit(tenant_id, unit))) { + if (OB_TENANT_NOT_IN_SERVER != ret) { + LOG_WARN("failed to get tenant unit", K(ret), K(tenant_id)); + } else { + // during restart, tenant unit not ready, skip check + ret = OB_SUCCESS; + } + } else { + const double memory_limit = unit.config_.memory_size(); + const int64_t max_tablet_cnt = static_cast(memory_limit / (1 << 30) * tablet_cnt_per_gb * safe_ratio); + const int64_t cur_tablet_cnt = t3m->get_total_tablet_cnt(); + if (OB_UNLIKELY(cur_tablet_cnt + inc_tablet_cnt > max_tablet_cnt)) { + ret = OB_TOO_MANY_PARTITIONS_ERROR; + LOG_WARN("too many partitions of tenant", K(ret), K(tenant_id), K(memory_limit), K(tablet_cnt_per_gb), + K(max_tablet_cnt), K(cur_tablet_cnt), K(inc_tablet_cnt)); + } + } + return ret; +} + +int ObRsAutoSplitScheduler::check_ls_migrating( + const uint64_t tenant_id, + const ObTabletID &tablet_id, + bool &is_migrating) +{ + int ret = OB_SUCCESS; + is_migrating = false; + ObLSID ls_id; + ObAddr leader_addr; + const int64_t rpc_timeout = ObDDLUtil::get_default_ddl_rpc_timeout(); + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || !tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(tenant_id), K(tablet_id)); + } else if (OB_FAIL(ObDDLUtil::get_tablet_leader_addr(GCTX.location_service_, + tenant_id, tablet_id, rpc_timeout, ls_id, leader_addr))) { + LOG_WARN("failed to get orig leader addr", K(ret), K(tenant_id), K(tablet_id)); + } else { + obrpc::ObFetchLSMemberAndLearnerListArg arg; + arg.tenant_id_ = tenant_id; + arg.ls_id_ = ls_id; + storage::ObStorageHASrcInfo src_info; + src_info.cluster_id_ = GCONF.cluster_id; + src_info.src_addr_ = leader_addr; + storage::ObStorageRpc *storage_rpc = nullptr; + ObLSService *ls_service = nullptr; + obrpc::ObFetchLSMemberAndLearnerListInfo member_info; + MTL_SWITCH (OB_SYS_TENANT_ID) { + if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls service should not be NULL", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_ISNULL(storage_rpc = ls_service->get_storage_rpc())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("storage rpc should not be NULL", K(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(storage_rpc->fetch_ls_member_and_learner_list(tenant_id, ls_id, src_info, member_info))) { + LOG_WARN("failed to check ls is valid member", K(ret), K(tenant_id), K(ls_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && !is_migrating && i < member_info.member_list_.get_member_number(); i++) { + common::ObMember member; + if (OB_FAIL(member_info.member_list_.get_member_by_index(i, member))) { + LOG_WARN("get member failed", K(ret), K(i), K(member_info)); + } else if (member.is_migrating()) { + is_migrating = true; + } + } + for (int64_t i = 0; OB_SUCC(ret) && !is_migrating && i < member_info.learner_list_.get_member_number(); i++) { + common::ObMember member; + if (OB_FAIL(member_info.learner_list_.get_member_by_index(i, member))) { + LOG_WARN("get member failed", K(ret), K(i), K(member_info)); + } else if (member.is_migrating()) { + is_migrating = true; + } + } + } + } + } + return ret; +} + +int ObServerAutoSplitScheduler::check_sstable_limit(const storage::ObTablet &tablet, bool &exceed_limit) +{ + int ret = OB_SUCCESS; + ObTableStoreIterator iter; + ObITable *unused_table = nullptr; + int64_t count = 0; + exceed_limit = false; + if (OB_UNLIKELY(!tablet.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(tablet)); + } else if (OB_FAIL(tablet.get_all_sstables(iter))) { + LOG_WARN("get all sstables failed", K(ret), K(tablet)); + } + while (OB_SUCC(ret)) { + if (OB_FAIL(iter.get_next(unused_table))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("try to iterate sstables of the tablet failed", K(ret), K(tablet)); + } else { + //overwrite ret + ret = OB_SUCCESS; + break; + } + } else if (OB_UNLIKELY((++count) > ObServerAutoSplitScheduler::SOURCE_TABLET_SSTABLE_LIMIT)) { + exceed_limit = true; + break; + } + } + return ret; +} + +int ObServerAutoSplitScheduler::check_and_fetch_tablet_split_info(const storage::ObTabletHandle &tablet_handle, + storage::ObLS &ls, + bool &can_split, + ObAutoSplitTask &task) +{ + int ret = OB_SUCCESS; + int64_t used_disk_space = OB_INVALID_SIZE; + int64_t auto_split_tablet_size = OB_INVALID_SIZE; + bool is_committed = false; + ObTablet *tablet = nullptr; + ObTabletPointer *tablet_ptr = nullptr; + ObRole role = INVALID_ROLE; + const share::ObLSID ls_id = ls.get_ls_id(); + bool num_sstables_exceed_limit = false; + can_split = false; + task.reset(); + if (OB_UNLIKELY(!tablet_handle.is_valid() || !ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tablet_handle), K(ls_id)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("pointer to tablet is nullptr", K(ret), KP(tablet)); + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_split_data(ReadSplitDataAutoPartSizeOp(auto_split_tablet_size), is_committed))) { + if (OB_EMPTY_RESULT == ret) { + ret = OB_SUCCESS; + auto_split_tablet_size = OB_INVALID_SIZE; + } else { + LOG_WARN("fail to get_auto_split_size", K(ret), KP(tablet)); + } + } else if (OB_ISNULL(tablet_ptr = static_cast(tablet->get_pointer_handle().get_resource_ptr()))) { + ret = OB_ERR_NULL_VALUE; + LOG_WARN("unexpected null tablet pointer", K(ret), KP(tablet)); + } else if (is_committed) { + tablet_ptr->set_auto_part_size(auto_split_tablet_size); + } else { + auto_split_tablet_size = tablet_ptr->get_auto_part_size(); + } + + if (OB_FAIL(ret)) { + } else if (OB_INVALID_SIZE == auto_split_tablet_size) { + can_split = false; + } else if (OB_FAIL(check_sstable_limit(*tablet, num_sstables_exceed_limit))) { + LOG_WARN("fail to check sstable limit", K(ret), KPC(tablet)); + } else if (OB_FAIL(ls.get_ls_role(role))) { + LOG_WARN("get role failed", K(ret), K(MTL_ID()), K(ls_id)); + } else { + can_split = tablet->get_major_table_count() > 0 && tablet->get_data_tablet_id() == tablet->get_tablet_id() + && common::ObRole::LEADER == role && !num_sstables_exceed_limit; + // TODO gaishun.gs resident_info + const int64_t used_disk_space = tablet->get_tablet_meta().space_usage_.all_sstable_data_required_size_; + can_split &= (used_disk_space > auto_split_tablet_size); + if (OB_SUCC(ret) && can_split) { + ObTabletCreateDeleteMdsUserData user_data; + common::ObArenaAllocator allocator; + const compaction::ObMediumCompactionInfoList *medium_info_list = nullptr; + if (OB_FAIL(check_tablet_creation_limit(ObAutoSplitArgBuilder::get_max_split_partition_num(), 0.8/*safe_ratio*/))) { + LOG_WARN("check_create_new_tablets fail", K(ret)); + if (OB_TOO_MANY_PARTITIONS_ERROR == ret) { + can_split = false; + ret = OB_SUCCESS; + } + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), + user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet status", K(ret), KP(tablet)); + can_split = false; + } else if (OB_FAIL(tablet->read_medium_info_list(allocator, medium_info_list))) { + LOG_WARN("failed to get medium info list", K(ret), KP(tablet)); + can_split = false; + } else if ((can_split = user_data.get_tablet_status() == ObTabletStatus::Status::NORMAL && (medium_info_list->size() == 0))) { + task.tenant_id_ = MTL_ID(); + task.ls_id_ = ls_id; + task.tablet_id_ = tablet->get_tablet_id(); + task.auto_split_tablet_size_ = auto_split_tablet_size; + task.used_disk_space_ = used_disk_space; + task.retry_times_ = 0; + } + } + } + return ret; +} + +int ObServerAutoSplitScheduler::push_task(const storage::ObTabletHandle &tablet_handle, oceanbase::storage::ObLS &ls) +{ + int ret = OB_SUCCESS; + ObArray task_array; + ObAutoSplitTask task; + bool can_split = false; + if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tablet_handle)); + } else if (OB_FAIL(check_and_fetch_tablet_split_info(tablet_handle, ls, can_split, task))) { + LOG_WARN("failed to check and fetch tablet split info", K(ret), K(task)); + } else if (can_split && OB_FAIL(task_array.push_back(task))) { + LOG_WARN("task_array push back failed" , K(ret), K(task_array)); + } else if (can_split && OB_FAIL(polling_manager_.push_tasks(task_array))) { + LOG_WARN("polling manager push task failed" , K(ret)); + } else if (ObTimeUtility::current_time() > ATOMIC_LOAD(&next_valid_time_) && !polling_manager_.empty()) { + ObArray> tenant_task_arrays; + if (OB_FAIL(polling_manager_.pop_tasks(ObServerAutoSplitScheduler::MAX_SPLIT_RPC_IN_BATCH, tenant_task_arrays))) { + if (OB_ENTRY_NOT_EXIST == ret) { + LOG_DEBUG("tree pop task fail", K(ret) ,K(task_array)); + //overwrite ret + ret = OB_SUCCESS; + } else { + LOG_WARN("tree pop task fail", K(ret), K(task_array)); + } + } else if (task_array.count() == 0) { + //do nothing + } else if (OB_FAIL(batch_send_split_request(tenant_task_arrays))) { + LOG_WARN("fail to send split request", K(ret), K(tenant_task_arrays)); + } + } + return ret; +} + +int ObServerAutoSplitScheduler::batch_send_split_request(const ObArray> &tenant_task_arrays) +{ + int ret = OB_SUCCESS; + obrpc::ObCommonRpcProxy *rpc_proxy = GCTX.rs_rpc_proxy_; + obrpc::ObAutoSplitTabletBatchArg args; + for (int64_t i = 0; OB_SUCC(ret) && i < tenant_task_arrays.count(); ++i) { + const ObArray &task_array = tenant_task_arrays.at(i); + for (int64_t j = 0; OB_SUCC(ret) && j < task_array.size(); ++j) { + const ObAutoSplitTask task = task_array.at(j); + if (OB_UNLIKELY(!task.is_valid())) { + //ignore ret + int tmp_ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid split task", K(tmp_ret), K(task)); + } else { + obrpc::ObAutoSplitTabletArg single_arg; + single_arg.auto_split_tablet_size_ = task.auto_split_tablet_size_; + single_arg.ls_id_ = task.ls_id_; + single_arg.tablet_id_ = task.tablet_id_; + single_arg.tenant_id_ = task.tenant_id_; + single_arg.used_disk_space_ = task.used_disk_space_; + if (OB_FAIL(args.args_.push_back(single_arg))) { + LOG_WARN("push task failed", K(ret), K(task), K(j)); + } + } + } + obrpc::ObAutoSplitTabletBatchRes results; + if (OB_SUCC(ret)) { + if (OB_FAIL(rpc_proxy->timeout(GCONF._ob_ddl_timeout).send_auto_split_tablet_task_request(args, results))) { + LOG_WARN("failed to send_auto_split_tablet_task_request", KR(ret), K(args), K(results)); + } else if (OB_UNLIKELY(results.rets_.count() != args.args_.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("send_auto_split_tablet_task_request rpc failed, the number of results doesn't match the number of arguments", + K(ret), K(results.rets_), K(args.args_)); + } else { + int64_t next_valid_time = max(ATOMIC_LOAD(&next_valid_time_), results.suggested_next_valid_time_); + ATOMIC_STORE(&next_valid_time_, next_valid_time); + } + } + } + return ret; +} + +int ObAutoSplitTaskPollingMgr::init() +{ + int ret = OB_SUCCESS; + ObLockGuard guard(lock_); + if (OB_UNLIKELY(inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("try to init an inited ObAutoSplitTaskPollingMgr", K(ret)); + } else if (OB_FAIL(map_tenant_to_cache_.create(ObAutoSplitTaskPollingMgr::INITIAL_TENANT_COUNT, ObMemAttr(OB_SERVER_TENANT_ID, "spl_task_map")))) { + LOG_WARN("fail to create map_tenant_to_cache_", K(ret)); + } else { + inited_ = true; + polling_mgr_malloc_.set_attr(ObMemAttr(OB_SERVER_TENANT_ID, "spl_task_mal")); + } + return ret; +} + +void ObAutoSplitTaskPollingMgr::reset() +{ + ObLockGuard guard(lock_); + for (hash::ObHashMap::iterator iter = map_tenant_to_cache_.begin(); iter != map_tenant_to_cache_.end(); iter++) { + uint64_t tenant_id = iter->first; + ObAutoSplitTaskCache *&tenant_cache = iter->second; + if (OB_NOT_NULL(tenant_cache)) { + tenant_cache->destroy(); + polling_mgr_malloc_.free(tenant_cache); + tenant_cache = nullptr; + } + } + (void) map_tenant_to_cache_.destroy(); + polling_mgr_malloc_.reset(); + inited_ = false; + total_tasks_ = 0; +} + +int ObAutoSplitTaskPollingMgr::get_tenant_cache(const int tenant_id, ObAutoSplitTaskCache *&tenant_cache) +{ + int ret = OB_SUCCESS; + tenant_cache = nullptr; + int64_t tenant_cache_idx = OB_INVALID_INDEX; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_INVALID_TENANT_ID == tenant_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id)); + } else if (OB_FAIL(map_tenant_to_cache_.get_refactored(tenant_id, tenant_cache))) { + LOG_WARN("get tenant cache index failed", K(ret), K(tenant_id)); + } + if (OB_SUCC(ret) && OB_ISNULL(tenant_cache)) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("unexpected of null ptr of tenant_cache", K(ret), KP(tenant_cache)); + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(map_tenant_to_cache_.erase_refactored(tenant_id))) { + LOG_WARN("failed to remove tenant cache from map_tenant_to_cache_", K(ret)); + } + } + return ret; +} + +int ObAutoSplitTaskPollingMgr::pop_tasks_from_tenant_cache(const int64_t num_tasks_to_pop, + ObArray &task_array, + ObAutoSplitTaskCache *tenant_cache) +{ + int ret = OB_SUCCESS; + task_array.reuse(); + int64_t tenant_cache_idx = OB_INVALID_INDEX; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (num_tasks_to_pop <= 0 || OB_ISNULL(tenant_cache)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(num_tasks_to_pop), KP(tenant_cache)); + } else { + int64_t cache_total_task_old = OB_INVALID_SIZE; + if (OB_FALSE_IT(cache_total_task_old = tenant_cache->get_tasks_num())) { + } else if (OB_FAIL(tenant_cache->pop_tasks(num_tasks_to_pop, task_array))) { + if (OB_ENTRY_NOT_EXIST == ret) { + LOG_DEBUG("trying to pop from empty tenant cache", K(ret)); + //overwrite ret + ret = OB_SUCCESS; + } else { + LOG_WARN("pop tasks from tenant's cache failed", K(ret)); + } + } + if (OB_NOT_NULL(tenant_cache) && cache_total_task_old != OB_INVALID_SIZE) { + const int64_t cache_total_task_new = tenant_cache->get_tasks_num(); + if (OB_LIKELY(cache_total_task_old >= 0 && cache_total_task_new >=0 && cache_total_task_old > cache_total_task_new)) { + (void) ATOMIC_FAA(&total_tasks_, cache_total_task_new - cache_total_task_old); + } + } + } + return ret; +} + +int ObAutoSplitTaskPollingMgr::pop_tasks(const int64_t num_tasks_to_pop, ObArray> &task_array) +{ + int ret = OB_SUCCESS; + task_array.reuse(); + ObArray tmp_array; + ObLockGuard guard(lock_); + int64_t total_tasks_pop_budge = num_tasks_to_pop; + int tmp_ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (num_tasks_to_pop <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(num_tasks_to_pop)); + } else if (OB_UNLIKELY(get_total_tenants() == 0)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_DEBUG("no task exist", K(ret)); + } else if ((!is_root_server_) && + OB_TMP_FAIL(pop_tasks_from_tenant_cache(1/*num_tasks_to_pop*/, tmp_array, MTL(ObAutoSplitTaskCache*)))) { + LOG_WARN("pop tasks from tenant cache failed", K(tmp_ret)); + } else if (tmp_array.count() == 0) { + } else if (tmp_array.count() > 0 && OB_TMP_FAIL(task_array.push_back(tmp_array))) { + LOG_WARN("push task into task array failed", K(tmp_ret)); + } else { + --total_tasks_pop_budge; + } + if (OB_SUCC(ret) && OB_LIKELY(total_tasks_pop_budge > 0)) { + ObArray tenants_id; + for (hash::ObHashMap::iterator iter = map_tenant_to_cache_.begin(); iter != map_tenant_to_cache_.end(); iter++) { + uint64_t tenant_id = iter->first; + if (OB_FAIL(tenants_id.push_back(tenant_id))) { + LOG_WARN("failed to push task into tenants_id", K(ret)); + } + } + int64_t tasks_budget_per_tenant = max(total_tasks_pop_budge / get_total_tenants(), 1); + int64_t tasks_pop_this_round = (total_tasks_pop_budge / get_total_tenants() == 0) ? 0 : total_tasks_pop_budge % get_total_tenants(); + total_tasks_pop_budge -= tasks_pop_this_round; + if (tasks_budget_per_tenant == 1) { + std::random_shuffle(tenants_id.begin(), tenants_id.end()); + } + for (int64_t i = 0; OB_SUCC(ret) && (tasks_pop_this_round > 0 || total_tasks_pop_budge > 0) && i < tenants_id.size(); ++i) { + int tmp_ret = OB_SUCCESS; + int64_t tenant_id = tenants_id.at(i); + ObAutoSplitTaskCache * tenant_cache = nullptr; + tmp_array.reuse(); + if (total_tasks_pop_budge > 0) { + total_tasks_pop_budge -= tasks_budget_per_tenant; + tasks_pop_this_round+=tasks_budget_per_tenant; + } + if (!is_root_server_) { + MAKE_TENANT_SWITCH_SCOPE_GUARD(guard); + if (OB_TMP_FAIL(guard.switch_to(tenant_id, false /*need_check_allow*/))) { + LOG_WARN("failed to switch to tenant", K(tmp_ret), K(tenant_id)); + if (OB_TMP_FAIL(map_tenant_to_cache_.erase_refactored(tenant_id))) { + LOG_WARN("failed to remove cache from map_tenant_to_cache_", K(tmp_ret), K(tenant_id)); + } + } else if (OB_FALSE_IT(tenant_cache = MTL(ObAutoSplitTaskCache*))) { + } else if (OB_TMP_FAIL(pop_tasks_from_tenant_cache(tasks_pop_this_round, tmp_array, tenant_cache))) { + LOG_WARN("failed to pop tasks from tenant cache", K(tmp_ret)); + } + } else if (OB_TMP_FAIL(get_tenant_cache(tenant_id, tenant_cache))) { + LOG_WARN("get tenant cache failed", K(tmp_ret), K(tenant_id)); + } else if (OB_TMP_FAIL(pop_tasks_from_tenant_cache(tasks_pop_this_round, tmp_array, tenant_cache))) { + LOG_WARN("failed to pop tasks from tenant cache", K(tmp_ret)); + } + if OB_FAIL(ret) { + } else { + tasks_pop_this_round -= tmp_array.count(); + if (OB_FAIL(tmp_array.count() > 0 && OB_FAIL(task_array.push_back(tmp_array)))) { + LOG_WARN("failed to push tasks into task_array", K(ret)); + } + } + } + } + return ret; +} + +int ObAutoSplitTaskPollingMgr::push_tasks(const ObArray &task_array) +{ + int ret = OB_SUCCESS; + ObAutoSplitTaskCache *tenant_cache = nullptr; + ObLockGuard guard(lock_); + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (task_array.count() == 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(task_array)); + } else { + uint64_t tenant_id = OB_INVALID_TENANT_ID; + // ensure all valid task share the same tenant id and ignore invalid task + for (int64_t i = 0; OB_SUCC(ret) && i < task_array.count(); ++i) { + const ObAutoSplitTask &task = task_array.at(i); + if (OB_UNLIKELY(!task.is_valid())) { + //ignore ret + int tmp_ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(tmp_ret)); + } else if (OB_INVALID_TENANT_ID == tenant_id && FALSE_IT(tenant_id = task.tenant_id_)) { + } else if (OB_UNLIKELY(task.tenant_id_ != tenant_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tenant ids don't match", K(ret), K(task.tenant_id_), K(tenant_id)); + } + } + ObAutoSplitTaskCache *tenant_cache = nullptr; + if (OB_FAIL(ret)) { + } else if (OB_FAIL(map_tenant_to_cache_.get_refactored(tenant_id, tenant_cache))) { + if (OB_HASH_NOT_EXIST == ret) { + //overwrite ret + ret = OB_SUCCESS; + if (is_root_server_ && OB_FAIL(create_tenant_cache(tenant_id, OB_SERVER_TENANT_ID, tenant_cache))) { + LOG_WARN("failed to create tenant cache", K(ret), K(tenant_id)); + } else if (OB_FAIL(register_tenant_cache(tenant_id, tenant_cache))) { + LOG_WARN("failed to register tenant cache", K(ret), K(tenant_id), KP(tenant_cache)); + if (OB_NOT_NULL(tenant_cache)) { + tenant_cache->destroy(); + polling_mgr_malloc_.free(tenant_cache); + tenant_cache = nullptr; + } + } + } else { + LOG_WARN("failed to get tenant_cache from map_tenant_to_cache_", K(ret), K(tenant_id)); + } + } + if (OB_FAIL(ret)) { + } else { + tenant_cache = is_root_server_ ? tenant_cache : MTL(ObAutoSplitTaskCache*); + int64_t cache_total_task_old = OB_INVALID_SIZE; + if (OB_ISNULL(tenant_cache)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpted null ptr of tenant_cache", K(ret), KP(tenant_cache), K(tenant_id), K(is_root_server_), K(MTL_ID())); + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(map_tenant_to_cache_.erase_refactored(tenant_id))) { + LOG_WARN("erase from tenantid_idx failed", K(tmp_ret)); + } + } else if (OB_FALSE_IT(cache_total_task_old = tenant_cache->get_tasks_num())) { + } else if (OB_FAIL(tenant_cache->push_tasks(task_array))) { + LOG_WARN("push tasks into tenant cache failed", K(ret)); + } + if (OB_NOT_NULL(tenant_cache) && cache_total_task_old != OB_INVALID_SIZE) { + const int64_t cache_total_task_new = tenant_cache->get_tasks_num(); + if (OB_LIKELY(cache_total_task_old >= 0 && cache_total_task_new >=0 && cache_total_task_old < cache_total_task_new)) { + (void) ATOMIC_FAA(&total_tasks_, cache_total_task_new - cache_total_task_old); + } + } + } + } + return ret; +} + +int ObAutoSplitTaskPollingMgr::create_tenant_cache(const uint64_t tenant_id, const uint64_t host_tenant_id, ObAutoSplitTaskCache *&tenant_cache) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + tenant_cache = nullptr; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || OB_INVALID_TENANT_ID == host_tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id), K(host_tenant_id)); + } else if (OB_ISNULL(buf = polling_mgr_malloc_.alloc(sizeof(ObAutoSplitTaskCache)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("allocate memory failed", K(ret), KP(buf)); + } else if (FALSE_IT(tenant_cache = new (buf) ObAutoSplitTaskCache())) { + } else if (OB_FAIL(tenant_cache->init(ObAutoSplitTaskCache::CACHE_MAX_CAPACITY, tenant_id, host_tenant_id))) { + LOG_WARN("failed to init ", K(ret)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(tenant_cache)) { + tenant_cache->destroy(); + polling_mgr_malloc_.free(tenant_cache); + tenant_cache = nullptr; + } + return ret; +} + +int ObAutoSplitTaskPollingMgr::register_tenant_cache(const uint64_t tenant_id, ObAutoSplitTaskCache * const tenant_cache) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret), K(inited_)); + } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id)); + } else if (OB_FAIL(map_tenant_to_cache_.set_refactored(tenant_id, tenant_cache))) { + LOG_WARN("push into map_tenant_to_cache_ failed", K(ret)); + } + return ret; +} + +int ObAutoSplitArgBuilder::build_arg(const uint64_t tenant_id, + const share::ObLSID ls_id, + const ObTabletID tablet_id, + const int64_t auto_split_tablet_size, + const int64_t used_disk_space, + obrpc::ObAlterTableArg &arg) +{ + int ret = OB_SUCCESS; + const share::schema::ObTableSchema *table_schema = nullptr; + const share::schema::ObSimpleDatabaseSchema *db_schema = nullptr; + ObSplitSampler sampler; + ObArray ranges; + common::ObArenaAllocator range_allocator; + int64_t ranges_num = 0; + arg.reset(); + + if (tenant_id == OB_INVALID_ID || !ls_id.is_valid() || !tablet_id.is_valid() || + auto_split_tablet_size <= 0 || used_disk_space <= 0 || + used_disk_space < auto_split_tablet_size ) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KR(ret), K(tenant_id), K(ls_id), K(tablet_id), + K(auto_split_tablet_size), K(used_disk_space)); + } else if (FALSE_IT(ranges_num = (used_disk_space / auto_split_tablet_size + + (used_disk_space % auto_split_tablet_size == 0 ? 0 : 1)))) { + } else if (FALSE_IT(ranges_num = MAX_SPLIT_PARTITION_NUM > ranges_num ? + ranges_num : MAX_SPLIT_PARTITION_NUM)) { + } else if (OB_FAIL(acquire_schema_info_of_tablet_(tenant_id, tablet_id, table_schema, db_schema, arg))) { + LOG_WARN("fail to acquire schema info of tablet", KR(ret), K(tenant_id), K(tablet_id)); + } else if (OB_ISNULL(table_schema) || OB_ISNULL(db_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), K(tablet_id), KPC(table_schema), KPC(db_schema)); + } else if (OB_UNLIKELY(!table_schema->is_auto_partitioned_table())) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("attempt to auto split tablet of a non-auto-partitioned table", KR(ret), KPC(table_schema)); + } else if (OB_FAIL(table_schema->check_validity_for_auto_partition())) { + LOG_WARN("table is invalid for auto partition", KR(ret), K(tenant_id), K(tablet_id), KPC(table_schema)); + } else if (OB_FAIL(sampler.query_ranges(tenant_id, + db_schema->get_database_name_str(), + *table_schema, + tablet_id, + ranges_num, + used_disk_space, + range_allocator, + ranges))) { + LOG_WARN("fail to acquire ranges for split partition", KR(ret)); + } else if (OB_UNLIKELY(ranges.empty())) { // fail to sample + ret = OB_EAGAIN; + LOG_WARN("partition is empty or all data have same partition key", KR(ret)); + } else { + if (OB_FAIL(build_arg_(tenant_id, db_schema->get_database_name_str(), + *table_schema, tablet_id, ranges, arg))) { + LOG_WARN("fail to build split arg", KR(ret), K(tenant_id), KPC(db_schema), + KPC(table_schema), K(tablet_id), K(ranges)); + } + } + + return ret; +} + +int ObAutoSplitArgBuilder::acquire_schema_info_of_tablet_(const uint64_t tenant_id, + const ObTabletID tablet_id, + const share::schema::ObTableSchema *&table_schema, + const share::schema::ObSimpleDatabaseSchema *&db_schema, + obrpc::ObAlterTableArg &arg) +{ + int ret = OB_SUCCESS; + share::schema::ObMultiVersionSchemaService *schema_service = GCTX.schema_service_; + share::schema::ObSchemaGetterGuard guard; + uint64_t table_id = OB_INVALID_ID; + uint64_t db_id = OB_INVALID_ID; + + if (OB_ISNULL(schema_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), K(tenant_id), K(tablet_id)); + } else if (OB_FAIL(acquire_table_id_of_tablet_(tenant_id, tablet_id, table_id))) { + LOG_WARN("fail to acquire tablet info", KR(ret), K(tablet_id)); + } else if (OB_FAIL(schema_service->get_tenant_schema_guard(tenant_id, guard))){ + LOG_WARN("fail to get tenant schema guard", KR(ret), K(tenant_id)); + } else if (OB_FAIL(guard.get_table_schema(tenant_id, table_id, table_schema))){ + LOG_WARN("fail to get table schema", KR(ret), K(tenant_id), K(table_id), K(tablet_id)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), K(tenant_id), K(table_id), K(tablet_id)); + } else if (OB_FAIL(arg.based_schema_object_infos_.push_back(ObBasedSchemaObjectInfo(table_schema->get_table_id(), + schema::TABLE_SCHEMA, table_schema->get_schema_version(), table_schema->get_tenant_id())))) { + LOG_WARN("fail to push back into based_schema_object_infos_", K(ret)); + } else if (FALSE_IT(db_id = table_schema->get_database_id())){ + } else if (OB_FAIL(guard.get_database_schema(tenant_id, db_id, db_schema))) { + LOG_WARN("fail to get database schema", KR(ret), K(tenant_id), K(table_id), K(tablet_id)); + } else if (OB_ISNULL(db_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), K(tenant_id), K(db_id), K(table_id), K(tablet_id)); + } + return ret; +} + +int ObAutoSplitArgBuilder::acquire_table_id_of_tablet_(const uint64_t tenant_id, + const ObTabletID tablet_id, + uint64_t& table_id) +{ + int ret = OB_SUCCESS; + ObSqlString sql; + ObMySQLProxy *mysql_proxy = GCTX.sql_proxy_; + + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + sqlclient::ObMySQLResult* sql_result = nullptr; + if (OB_ISNULL(mysql_proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret)); + } else if (OB_FAIL(sql.assign_fmt("SELECT table_id FROM oceanbase.%s " + "WHERE tablet_id = %lu", + share::OB_ALL_TABLET_TO_LS_TNAME, + tablet_id.id()))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(mysql_proxy->read(res, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(sql)); + } else if (OB_ISNULL(sql_result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret), K(sql)); + } else { + // tablet_id is pk, at most one row can be selected + if (OB_SUCC(sql_result->next())) { + EXTRACT_INT_FIELD_MYSQL(*sql_result, "table_id", table_id, int64_t); + } else if (OB_UNLIKELY(OB_ITER_END == ret)) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("the tablet_id does not exist", KR(ret), K(tablet_id), K(sql)); + } else { + LOG_WARN("failed to find result", KR(ret), K(tablet_id), K(sql)); + } + } + } + return ret; +} + +int ObAutoSplitArgBuilder::build_arg_(const uint64_t tenant_id, + const ObString &db_name, + const share::schema::ObTableSchema &table_schema, + const ObTabletID split_source_tablet_id, + const ObArray &ranges, + obrpc::ObAlterTableArg &arg) +{ + int ret = OB_SUCCESS; + arg.reset(); + ObTZMapWrap tz_map_wrap; + share::schema::AlterTableSchema& alter_table_schema = arg.alter_table_schema_; + + if (tenant_id == OB_INVALID_ID) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tenant_id", KR(ret), K(tenant_id)); + } else if (OB_FAIL(build_alter_table_schema_(tenant_id, db_name, table_schema, + split_source_tablet_id, + ranges, + alter_table_schema))) { + LOG_WARN("fail to build alter_table_schema", KR(ret), K(tenant_id), K(db_name), + K(table_schema), K(split_source_tablet_id), + K(ranges)); + } else if (OB_FAIL(OTTZ_MGR.get_tenant_tz(tenant_id, tz_map_wrap))) { + LOG_WARN("get tenant timezone map failed", KR(ret), K(tenant_id)); + } else { + arg.alter_part_type_ = obrpc::ObAlterTableArg::AlterPartitionType::AUTO_SPLIT_PARTITION; + arg.exec_tenant_id_ = tenant_id; + arg.is_alter_partitions_ = true; + arg.is_inner_ = true; + arg.is_add_to_scheduler_ = false; + arg.tz_info_wrap_.set_tz_info_offset(0); + arg.nls_formats_[ObNLSFormatEnum::NLS_DATE] = ObTimeConverter::COMPAT_OLD_NLS_DATE_FORMAT; + arg.nls_formats_[ObNLSFormatEnum::NLS_TIMESTAMP] = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_FORMAT; + arg.nls_formats_[ObNLSFormatEnum::NLS_TIMESTAMP_TZ] = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_TZ_FORMAT; + arg.set_tz_info_map(tz_map_wrap.get_tz_map()); + } + + return ret; +} + +int ObAutoSplitArgBuilder::build_alter_table_schema_(const uint64_t tenant_id, + const ObString &db_name, + const share::schema::ObTableSchema &table_schema, + const ObTabletID split_source_tablet_id, + const ObArray &ranges, + share::schema::AlterTableSchema &alter_table_schema) +{ + int ret = OB_SUCCESS; + const ObString& table_name = table_schema.get_table_name_str(); + const uint64_t table_id = table_schema.get_table_id(); + const int64_t part_num = ranges.size(); + const ObString& part_func_expr = table_schema.get_part_option().get_part_func_expr_str(); + const ObPartitionFuncType part_func_type = table_schema.get_part_option().get_part_func_type(); + const ObPartitionLevel target_part_level = table_schema.get_target_part_level_for_auto_partitioned_table(); + + if (OB_FAIL(alter_table_schema.set_origin_database_name(db_name))) { + LOG_WARN("fail to set origin database name", KR(ret), K(db_name)); + } else if (OB_FAIL(alter_table_schema.set_origin_table_name(table_name))) { + LOG_WARN("fail to set origin table name", KR(ret), K(table_name)); + } else if (OB_UNLIKELY(target_part_level == ObPartitionLevel::PARTITION_LEVEL_MAX)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid target part level", KR(ret), K(table_schema)); + } else if (FALSE_IT(alter_table_schema.set_table_type(table_schema.get_table_type()))) { + } else if (FALSE_IT(alter_table_schema.set_index_type(table_schema.get_index_type()))) { + } else if (FALSE_IT(alter_table_schema.set_tenant_id(tenant_id))) { + } else if (FALSE_IT(alter_table_schema.set_part_level(target_part_level))) { + } else if (FALSE_IT(alter_table_schema.get_part_option().set_part_func_type(part_func_type))) { + } else if (FALSE_IT(alter_table_schema.get_part_option().set_part_expr(part_func_expr))) { + } else if (FALSE_IT(alter_table_schema.set_part_num(part_num))) { + } else { + share::schema::ObPartition new_part; + + for (int64_t i = 0; OB_SUCC(ret) && i < part_num; i++) { + const ObRowkey& high_bound_val = ranges[i].get_end_key(); + + if (OB_FAIL(build_partition_(tenant_id, table_id, + split_source_tablet_id, high_bound_val, + new_part))) { + LOG_WARN("fail to build partition", KR(ret), K(tenant_id), K(table_id), K(split_source_tablet_id), + K(high_bound_val), K(table_schema)); + } else if (OB_FAIL(alter_table_schema.add_partition(new_part))) { + LOG_WARN("fail to add partition", KR(ret), K(new_part)); + } else { + new_part.reset(); + } + } + } + return ret; +} + +int ObAutoSplitArgBuilder::build_partition_(const uint64_t tenant_id, const uint64_t table_id, + const ObTabletID split_source_tablet_id, + const ObRowkey &high_bound_val, + share::schema::ObPartition &new_part) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(new_part.set_high_bound_val(high_bound_val))) { + LOG_WARN("failed to set high_bound_val", KR(ret)); + } else { + new_part.set_is_empty_partition_name(true); // rs will generate the name + new_part.set_tenant_id(tenant_id); + new_part.set_table_id(table_id); + new_part.set_split_source_tablet_id(split_source_tablet_id); + new_part.set_partition_type(PartitionType::PARTITION_TYPE_NORMAL); + } + + return ret; +} + +// sample rowkey ranges of data_table/global_index from given tablet +int ObSplitSampler::query_ranges(const uint64_t tenant_id, + const ObString &db_name, + const share::schema::ObTableSchema &table_schema, + const ObTabletID tablet_id, + const int64_t range_num, const int64_t used_disk_space, + common::ObArenaAllocator &range_allocator, + ObArray &ranges) +{ + int ret = OB_SUCCESS; + const uint64_t table_id = table_schema.get_table_id(); + PartitionMeta part_meta; + ObArray column_names; + ObArray unused_column_ranges; + common::ObRowkey low_bound_val; + common::ObRowkey high_bound_val; + + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || OB_INVALID_ID == table_id || + !tablet_id.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid id", KR(ret), K(tenant_id), K(table_id), K(tablet_id)); + } else if (OB_UNLIKELY(db_name.empty())){ + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid db name", KR(ret)); + } else if (OB_UNLIKELY(range_num < 2)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("it's no need to split", KR(ret), K(range_num)); + } else if (OB_UNLIKELY(used_disk_space == 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("used_disk_space can't be 0", KR(ret)); + } else if (OB_UNLIKELY(!table_schema.is_user_table() && !table_schema.is_global_index_table())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only support to sample data_table or global index", KR(ret), K(table_schema)); + } else if (OB_FAIL(acquire_partition_key_name_(table_schema, column_names))){ + LOG_WARN("fail to acquire partition key name", KR(ret), K(table_schema)); + } else if (OB_UNLIKELY(column_names.empty())){ + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid array count", KR(ret), K(column_names)); + } else if (table_schema.is_partitioned_table()) { + if (OB_FAIL(acquire_partition_meta_(table_schema, tablet_id, part_meta))) { + LOG_WARN("fail to acquire partition meta", KR(ret), K(tenant_id), K(table_id), K(tablet_id)); + } else if (nullptr == part_meta.part_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("meta's partition is NULL", KR(ret), K(tenant_id), K(table_id), K(tablet_id), K(part_meta)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(fill_query_range_bounder(part_meta, unused_column_ranges, column_names.count(), low_bound_val, high_bound_val, range_allocator))) { + LOG_WARN("fail to fill query range bounder", K(ret)); + } else if (OB_FAIL(query_ranges_(tenant_id, db_name, table_schema.get_table_name_str(), part_meta, + column_names, unused_column_ranges, + range_num, used_disk_space, + table_schema.is_global_index_table(), + low_bound_val, high_bound_val, + range_allocator, ranges))) { + LOG_WARN("fail to acquire ranges for split partition", KR(ret), K(tenant_id), K(db_name), + K(table_schema), K(part_meta), + K(range_num), K(used_disk_space), + K(ranges)); + } + LOG_DEBUG("query range result", K(ret), K(ranges)); + return ret; +} + +// this function is only called by pre-splitting partition. +// it will sample ranges of given column from data_table. +// column_names records a set of columns which we want to sample(the empty column_names sample all). +// column_ranges should be empty or be same size with column_names. +// each range of column_ranges records the scope of column in column_names, +// we will filter the sampling result which are not in the scope. +int ObSplitSampler::query_ranges(const uint64_t tenant_id, + const ObString &db_name, + const share::schema::ObTableSchema &data_table_schema, + const ObIArray &column_names, + const ObIArray &column_ranges, + const int64_t range_num, const int64_t used_disk_space, + common::ObArenaAllocator &range_allocator, + ObArray &ranges) +{ + int ret = OB_SUCCESS; + PartitionMeta unused_part_meta; + const int64_t unused_presetting_column_cnt = 0; + common::ObRowkey low_bound_val; + common::ObRowkey high_bound_val; + + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tenant id", KR(ret), K(tenant_id)); + } else if (OB_UNLIKELY(db_name.empty())){ + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid db name", KR(ret)); + } else if (OB_UNLIKELY(range_num < 2)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("it's no need to split", KR(ret), K(range_num)); + } else if (OB_UNLIKELY(used_disk_space == 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("used_disk_space can't be 0", KR(ret)); + } else if (OB_UNLIKELY(column_names.empty())){ + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid array count", KR(ret), K(column_names)); + } else if (OB_UNLIKELY(!column_ranges.empty() && column_names.count() != column_ranges.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid array count", KR(ret), K(column_names), K(column_ranges)); + } else if (OB_FAIL(fill_query_range_bounder(unused_part_meta, column_ranges, unused_presetting_column_cnt, low_bound_val, high_bound_val, range_allocator))) { + LOG_WARN("fail to fill query range bounder", K(ret), K(column_ranges)); + } else if (OB_FAIL(query_ranges_(tenant_id, db_name, data_table_schema.get_table_name_str(), + unused_part_meta, + column_names, column_ranges, + range_num, used_disk_space, + false /*query_index*/, + low_bound_val, high_bound_val, + range_allocator, ranges))) { + LOG_WARN("fail to acquire ranges for split partition", KR(ret), K(tenant_id), K(db_name), + K(data_table_schema), K(range_num), + K(used_disk_space), + K(ranges)); + } + LOG_DEBUG("query range result", K(ret), K(column_ranges), K(ranges)); + return ret; +} + +/* + 如果是重建自动分区全局索引非分区表,part_column_cnt为潜在的分区键 +*/ +int ObSplitSampler::fill_query_range_bounder( + const PartitionMeta& part_meta, + const ObIArray &column_ranges, + const int64_t presetting_part_column_cnt, + common::ObRowkey &l_bound_val, + common::ObRowkey &h_bound_val, + common::ObArenaAllocator &allocator) +{ + int ret = OB_SUCCESS; + l_bound_val.set_min_row(); + h_bound_val.set_max_row(); + if (nullptr != part_meta.part_) { + l_bound_val = part_meta.part_->get_low_bound_val(); + h_bound_val = part_meta.part_->get_high_bound_val(); + } else if (column_ranges.count() > 0 || presetting_part_column_cnt > 0) { + // row key complement + ObObj l_obj_buf[OB_MAX_ROWKEY_COLUMN_NUMBER]; + ObObj h_obj_buf[OB_MAX_ROWKEY_COLUMN_NUMBER]; + const int64_t column_range_cnt = column_ranges.count(); + const int64_t column_obj_cnt = 1; + int64_t copy_key_length = 0; + if (column_range_cnt > 0) { + for (int64_t i = 0; OB_SUCC(ret) && i < column_range_cnt; ++i) { + const ObNewRange &tmp_range = column_ranges.at(i); + const ObRowkey &l_key = tmp_range.start_key_; + const ObRowkey &h_key = tmp_range.end_key_; + if (l_key.get_obj_cnt() != column_obj_cnt || h_key.get_obj_cnt() != column_obj_cnt) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to fill query range bounder", K(ret), K(l_key), K(h_key)); + } else if (OB_ISNULL(l_key.get_obj_ptr()) || OB_ISNULL(h_key.get_obj_ptr())) { // shallow copy + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("check null ptr failed", K(ret), KP(l_key.get_obj_ptr()), KP(h_key.get_obj_ptr()), K(column_ranges)); + } else { + l_obj_buf[i] = l_key.get_obj_ptr()[0]; + h_obj_buf[i] = h_key.get_obj_ptr()[0]; + } + } + copy_key_length = column_range_cnt; + } else { + for (int64_t i = 0; i < presetting_part_column_cnt; ++i) { + ObObj tmp_l_buf; + ObObj tmp_h_buf; + tmp_l_buf.set_min_value(); + tmp_h_buf.set_max_value(); + l_obj_buf[i] = tmp_l_buf; + h_obj_buf[i] = tmp_h_buf; + } + copy_key_length = presetting_part_column_cnt; + } + if (OB_SUCC(ret)) { + ObRowkey l_rowkey(l_obj_buf, copy_key_length); + ObRowkey h_rowkey(h_obj_buf, copy_key_length); + if (OB_FAIL(l_rowkey.deep_copy(l_bound_val, allocator))) { + LOG_WARN("fail to set low bound val", K(ret), K(l_rowkey)); + } else if (OB_FAIL(h_rowkey.deep_copy(h_bound_val, allocator))) { + LOG_WARN("fail to set high bound val", K(ret), K(h_rowkey)); + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to fill query range bounder", + K(ret), K(part_meta), K(column_ranges), K(presetting_part_column_cnt)); + } + return ret; +} + +int ObSplitSampler::acquire_partition_meta_(const share::schema::ObTableSchema &table_schema, + const ObTabletID &tablet_id, PartitionMeta &meta) +{ + int ret = OB_SUCCESS; + ObPartitionSchemaIter iter(table_schema, ObCheckPartitionMode::CHECK_PARTITION_MODE_NORMAL); + PartitionMeta tmp_meta; + bool find = false; + while (!find && OB_SUCC(iter.next_partition_info(tmp_meta))) { + if (tmp_meta.tablet_id_ == tablet_id) { + find = true; + meta = tmp_meta; + } + } + + if (OB_FAIL(ret)) { + if (ret == OB_ITER_END) { + ret = OB_UNKNOWN_PARTITION; + LOG_WARN("fail to find partition info in table schema", KR(ret), K(tablet_id)); + } else { + LOG_WARN("fail to get next partition info", KR(ret), K(tablet_id)); + } + } + return ret; +} + +int ObSplitSampler::query_ranges_(const uint64_t tenant_id, const ObString &db_name, + const ObString &table_name, + const PartitionMeta &part_meta, + const ObIArray &column_names, + const ObIArray &column_ranges, + const int64_t range_num, const int64_t used_disk_space, + const bool query_index, + common::ObRowkey &low_bound_val, + common::ObRowkey &high_bound_val, + common::ObArenaAllocator& range_allocator, + ObArray &ranges) +{ + int ret = OB_SUCCESS; + const ObString* part_name = nullptr; + if (nullptr != part_meta.part_) { + part_name = &part_meta.part_->get_part_name(); + } + ObSqlString sql; + ObSingleConnectionProxy single_conn_proxy; + static const int64_t MAX_SAMPLE_SCALE = 128L * 1024 * 1024; // at most sample 128MB + double sample_pct = MAX_SAMPLE_SCALE >= used_disk_space ? + 100 : + static_cast(MAX_SAMPLE_SCALE) / used_disk_space * 100; + ranges.reset(); + + if (OB_FAIL(single_conn_proxy.connect(tenant_id, 0 /* group_id*/, GCTX.sql_proxy_))) { + LOG_WARN("failed to get mysql connect", KR(ret), K(tenant_id)); + } else if (query_index) { + ObSqlString set_sql; + int64_t affected_rows = 0; + if (OB_FAIL(set_sql.assign_fmt("SET session %s = true", share::OB_SV_ENABLE_INDEX_DIRECT_SELECT))) { + LOG_WARN("failed to assign sql", KR(ret)); + } else if (OB_FAIL(single_conn_proxy.write(tenant_id, set_sql.ptr(), affected_rows))) { + LOG_WARN("single_conn_proxy write failed", KR(ret), K(set_sql)); + } + } + + // the sql will sample spliting table and acquire "range_num" rowkeys as split points + if (OB_FAIL(ret)) { + } else if (OB_FAIL(build_sample_sql_(db_name, table_name, part_name, + column_names, column_ranges, + range_num, sample_pct, sql))) { + LOG_WARN("fail to build sample sql", KR(ret), K(db_name), K(table_name), K(part_name), + K(column_names), K(column_ranges), + K(range_num), K(sample_pct)); + } else { + SMART_VAR(ObMySQLProxy::MySQLResult, res) { + sqlclient::ObMySQLResult *sql_result = nullptr; + if (OB_FAIL(single_conn_proxy.read(res, tenant_id, sql.ptr()))) { + LOG_WARN("execute sql failed", KR(ret), K(sql)); + } else if (OB_ISNULL(sql_result = res.get_result())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("result is null", KR(ret), K(sql)); + } else { + const ObNewRow *row = nullptr; + bool is_first_row = true; + int column_count = 0; + ObObj objs[OB_MAX_ROWKEY_COLUMN_NUMBER]; + ObNewRange range; + + while (OB_SUCC(ret)) { + if (OB_FAIL(sql_result->next())) { + if (OB_ITER_END != ret) { + LOG_WARN("get next result failed", KR(ret), K(sql)); + } + } else if (OB_ISNULL(row = sql_result->get_row())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL row", KR(ret), K(sql)); + } else if (is_first_row) { + // to acquire "range_num" split partitions, + // only need "range_num - 1" split points, + // the first point from sampling sql is unused. + is_first_row = false; + column_count = row->get_count(); + } else if (OB_UNLIKELY(column_count <= 0 || column_count > OB_MAX_ROWKEY_COLUMN_NUMBER)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid column count", KR(ret), K(column_count), K(sql)); + } else { + // build start_row_key + if (ranges.size() == 0) { + // copy low_bound_val to range.start_key_ + if (OB_FAIL(low_bound_val.deep_copy(range.start_key_, range_allocator))) { + LOG_WARN("fail to copy low_bound_val to range.start_key_", KR(ret)); + } + } else { + ObRowkey& old_end = ranges[ranges.size()-1].end_key_; + range.start_key_.assign(old_end.get_obj_ptr(), column_count); + } + + // build end_row_key + if (OB_FAIL(ret)) { + } else { + for (int64_t i = 0; i < column_count; i++) { + objs[i] = row->get_cell(i); + } + + ObRowkey end(objs, column_count); + // copy end to range.end_key_ + if (OB_FAIL(end.deep_copy(range.end_key_, range_allocator))) { + LOG_WARN("fail to copy ObRowkey", KR(ret)); + } else { + range.border_flag_.set_inclusive_end(); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ranges.push_back(range))) { + LOG_WARN("range push back failed", KR(ret)); + } + } + } // end while + + if (OB_LIKELY(OB_ITER_END == ret)) { + ret = OB_SUCCESS; + if (!ranges.empty()) { + ObRowkey& old_end = ranges[ranges.size()-1].end_key_; + range.start_key_.assign(old_end.get_obj_ptr(), column_count); + + if (OB_FAIL(high_bound_val.deep_copy(range.end_key_, range_allocator))) { + LOG_WARN("fail to copy high_bound_val to range.end_key_", KR(ret)); + } else if (OB_FAIL(ranges.push_back(range))) { + LOG_WARN("range push back failed", KR(ret)); + } + } + } + } + } // end SMART_VAR(ObMySQLProxy::MySQLResult, res) + } + + return ret; +} + +int ObSplitSampler::build_sample_sql_(const ObString &db_name, const ObString &table_name, const ObString *part_name, + const ObIArray &column_names, + const ObIArray &column_ranges, + const int range_num, const double sample_pct, + ObSqlString &sql) +{ + int ret = OB_SUCCESS; + ObSqlString col_alias_str; + ObSqlString col_name_alias_str; + + if (OB_FAIL(gen_column_alias_(column_names, col_alias_str, col_name_alias_str))) { + LOG_WARN("fail to gen column alias", KR(ret), K(column_names)); + } else if (OB_FAIL(sql.assign_fmt( + "SELECT %.*s FROM " + "(SELECT %.*s, bucket, ROW_NUMBER() OVER (PARTITION BY bucket ORDER BY %.*s) rn FROM " + "(SELECT %.*s, NTILE(%d) OVER (ORDER BY %.*s) bucket FROM " + "(SELECT /*+ index(%.*s primary) */ %.*s FROM %s%.*s%s.%s%.*s%s ", + static_cast(col_alias_str.length()), col_alias_str.ptr(), + + static_cast(col_alias_str.length()), col_alias_str.ptr(), + static_cast(col_alias_str.length()), col_alias_str.ptr(), + + static_cast(col_alias_str.length()), col_alias_str.ptr(), + range_num, + static_cast(col_alias_str.length()), col_alias_str.ptr(), + + table_name.length(), table_name.ptr(), + static_cast(col_name_alias_str.length()), col_name_alias_str.ptr(), + "`", + db_name.length(), db_name.ptr(), + "`", + "`", + table_name.length(), table_name.ptr(), + "`"))) { + LOG_WARN("string assign failed", KR(ret), K(col_alias_str), K(col_name_alias_str), K(db_name), K(table_name)); + } + + if (OB_FAIL(ret)){ + } else if (part_name != nullptr) { + if (OB_FAIL(sql.append_fmt("PARTITION (%.*s) ", part_name->length(), part_name->ptr()))) { + LOG_WARN("string assign failed", KR(ret), KPC(part_name)); + } + } + + if (OB_FAIL(ret)){ + } else if (sample_pct < 100 && OB_FAIL(sql.append_fmt("SAMPLE BLOCK(%g) ", sample_pct))) { + LOG_WARN("string assign failed", KR(ret), K(sample_pct)); + } else if (OB_FAIL(add_sample_condition_sqls_(column_names, column_ranges, sql))) { + LOG_WARN("fail to add sample conditions", KR(ret), K(column_names), K(column_ranges)); + } else if (OB_FAIL(sql.append_fmt(") a) b) c WHERE rn = 1 GROUP BY %.*s ORDER BY %.*s", + static_cast(col_alias_str.length()), col_alias_str.ptr(), + static_cast(col_alias_str.length()), col_alias_str.ptr()))) { + LOG_WARN("string assign failed", KR(ret), K(col_alias_str)); + } + return ret; +} + +int ObSplitSampler::add_sample_condition_sqls_(const ObIArray &columns, + const ObIArray &column_ranges, + ObSqlString &sql) +{ + int ret = OB_SUCCESS; + if (column_ranges.empty()) { + } else if (OB_UNLIKELY(columns.count() != column_ranges.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid count", KR(ret), K(columns), K(column_ranges)); + } else if (OB_FAIL(sql.append_fmt("WHERE 1=1 "))) { + LOG_WARN("string assign failed", KR(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < columns.count(); i++) { + const ObString& column = columns.at(i); + const ObNewRange& range = column_ranges.at(i); + if (range.start_key_.is_min_row() && range.end_key_.is_max_row()) { + } else if (OB_FAIL(sql.append_fmt("AND "))) { + LOG_WARN("string assign failed", KR(ret)); + } else if (OB_FAIL(add_sample_condition_sql_(column, range, sql))) { + LOG_WARN("fail to add sample condition", KR(ret), K(column), K(range)); + } + } + } + return ret; +} + +int ObSplitSampler::add_sample_condition_sql_(const ObString &column, + const ObNewRange &range, + ObSqlString &sql) +{ + int ret = OB_SUCCESS; + const int64_t buf_len = common::OB_MAX_ROW_KEY_LENGTH; + char *range_buf = nullptr; + int64_t pos = 0; + ObArenaAllocator allocator; + + if (range.start_key_.get_obj_cnt() != 1 || range.end_key_.get_obj_cnt() != 1 || + range.start_key_.is_max_row() || range.end_key_.is_min_row()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid range", KR(ret), K(column), K(range.start_key_), K(range.end_key_)); + } else if (OB_ISNULL(range_buf = (char *)allocator.alloc(buf_len))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc buf", KR(ret)); + } else { + if (!range.start_key_.is_min_row()) { + ObString min_val; + char *min_val_buf = range_buf; + pos = range.start_key_.to_plain_string(min_val_buf, buf_len); + min_val.assign(min_val_buf, pos); + + if (OB_UNLIKELY(min_val.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get min val", KR(ret), K(column), K(range)); + } else if (OB_FAIL(sql.append_fmt("%.*s %s %.*s ", + column.length(), column.ptr(), + range.border_flag_.inclusive_start() ? ">=" : ">", + min_val.length(), min_val.ptr() + ))) { + LOG_WARN("string assign failed", KR(ret), K(column), K(range)); + } + } + + if (OB_FAIL(ret)) { + } else if (!range.end_key_.is_max_row()) { + if (pos > 0 && OB_FAIL(sql.append_fmt("AND "))) { + LOG_WARN("string assign failed", KR(ret), K(column), K(range)); + } else { + ObString max_val; + char *max_val_buf = range_buf + pos; + pos = range.end_key_.to_plain_string(max_val_buf, buf_len - pos); + max_val.assign(max_val_buf, pos); + + if (OB_UNLIKELY(max_val.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to get min val", KR(ret), K(column), K(range)); + } else if (OB_FAIL(sql.append_fmt("%.*s %s %.*s ", + column.length(), column.ptr(), + range.border_flag_.inclusive_end() ? "<=" : "<", + max_val.length(), max_val.ptr() + ))) { + LOG_WARN("string assign failed", KR(ret), K(column), K(range)); + } + } + } + } + return ret; +} + +int ObSplitSampler::acquire_partition_key_name_(const share::schema::ObTableSchema &table_schema, + ObIArray &column_names) +{ + int ret = OB_SUCCESS; + ObArray column_ids; + if (table_schema.is_partitioned_table() && + OB_FAIL(table_schema.get_partition_key_info().get_column_ids(column_ids))) { + LOG_WARN("get column ids failed", KR(ret), K(table_schema)); + } else if (!table_schema.is_partitioned_table() && + OB_FAIL(table_schema.get_presetting_partition_keys(column_ids))) { + LOG_WARN("get column ids failed", KR(ret), K(table_schema)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < column_ids.count(); i++) { + const ObColumnSchemaV2 *col = table_schema.get_column_schema(column_ids.at(i)); + + if (OB_ISNULL(col)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get column schema failed", KR(ret), "col", column_names.at(i)); + } else if (OB_FAIL(column_names.push_back(ObString(col->get_column_name_str().length(), + col->get_column_name_str().ptr())))) { + LOG_WARN("append string failed", KR(ret), KPC(col)); + } + } + } + return ret; +} + +int ObSplitSampler::gen_column_alias_(const ObIArray &columns, + ObSqlString &col_alias_str, + ObSqlString &col_name_alias_str) +{ + int ret = OB_SUCCESS; + col_alias_str.reset(); + col_name_alias_str.reset(); + + for (int64_t i = 0; OB_SUCC(ret) && i < columns.count(); i++) { + if (i > 0) { + if (OB_FAIL(col_alias_str.append(", "))) { + LOG_WARN("string append failed", KR(ret)); + } else if (OB_FAIL(col_name_alias_str.append(", "))) { + LOG_WARN("string append failed", KR(ret)); + } + } + if (OB_SUCC(ret)) { + ObSqlString alias; + const ObString &column = columns.at(i); + if (OB_FAIL(alias.append_fmt("col%ld", i))) { + LOG_WARN("append string failed", KR(ret)); + } else if (OB_FAIL(col_alias_str.append(alias.string()))) { + LOG_WARN("append string failed", KR(ret)); + } else if (OB_FAIL(col_name_alias_str.append_fmt( + "%s%.*s%s AS %.*s", + "`", + column.length(), column.ptr(), + "`", + alias.string().length(), + alias.string().ptr()))) { + LOG_WARN("append string failed", KR(ret)); + } + } + } + + return ret; +} + +} +} diff --git a/src/share/scheduler/ob_partition_auto_split_helper.h b/src/share/scheduler/ob_partition_auto_split_helper.h new file mode 100644 index 000000000..ff9747e17 --- /dev/null +++ b/src/share/scheduler/ob_partition_auto_split_helper.h @@ -0,0 +1,344 @@ +/** + * 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 OCEABASE_STORAGE_PARTITION_AUTO_SPLIT_HELPER_ +#define OCEABASE_STORAGE_PARTITION_AUTO_SPLIT_HELPER_ + +#include "logservice/ob_log_base_type.h" +#include "share/schema/ob_part_mgr_util.h" +#include "share/schema/ob_table_schema.h" +#include "share/ob_ls_id.h" +#include "common/ob_tablet_id.h" + +namespace oceanbase +{ +namespace obrpc +{ +struct ObAlterTableArg; +} +namespace share +{ +namespace schema +{ +struct AlterTableSchema; +class ObSimpleDatabaseSchema; +} + +class ObAutoSplitTaskKey final +{ +public: + ObAutoSplitTaskKey(); + ObAutoSplitTaskKey(const uint64_t tenant_id, const ObTabletID &tablet_id); + ~ObAutoSplitTaskKey() = default; + uint64_t hash() const; + int hash(uint64_t &hash_val) const + { + hash_val = hash(); return OB_SUCCESS; + } + bool operator==(const ObAutoSplitTaskKey &other) const; + bool operator!=(const ObAutoSplitTaskKey &other) const; + bool is_valid() const + { + return OB_INVALID_TENANT_ID != tenant_id_ && tablet_id_.is_valid(); + } + int assign(const ObAutoSplitTaskKey&other); + TO_STRING_KV(K(tenant_id_), K(tablet_id_)); + +public: + uint64_t tenant_id_; + ObTabletID tablet_id_; +}; + +struct ObAutoSplitTask final +{ +public: + ObAutoSplitTask() + : tenant_id_(OB_INVALID_ID), ls_id_(), tablet_id_(), auto_split_tablet_size_(OB_INVALID_SIZE), used_disk_space_(OB_INVALID_SIZE), retry_times_(OB_INVALID_COUNT) + {} + ObAutoSplitTask(const uint64_t tenant_id, const ObLSID &ls_id, const ObTableID &tablet_id, const int64_t auto_split_tablet_size, const int64_t used_disk_space, const int64_t retry_times) + : tenant_id_(tenant_id), ls_id_(ls_id), tablet_id_(tablet_id), + auto_split_tablet_size_(auto_split_tablet_size), used_disk_space_(used_disk_space), retry_times_(retry_times) + {} + ~ObAutoSplitTask() = default; + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(tablet_id), K_(auto_split_tablet_size), K_(used_disk_space), K_(retry_times)); + bool is_valid() const + { + return ls_id_.is_valid() && tablet_id_.is_valid() && retry_times_ >= 0 + && auto_split_tablet_size_ > 0 && used_disk_space_ > 0 && used_disk_space_ > auto_split_tablet_size_; + } + void reset() + { + tenant_id_ = OB_INVALID_ID; + auto_split_tablet_size_ = OB_INVALID_SIZE; + used_disk_space_ = OB_INVALID_SIZE; + retry_times_ = OB_INVALID_COUNT; + ls_id_.reset(); + tablet_id_.reset(); + } + int assign(const ObAutoSplitTask &other); + void increment_retry_times() { ++retry_times_; } +public: + uint64_t tenant_id_; + ObLSID ls_id_; + ObTabletID tablet_id_; + int64_t auto_split_tablet_size_; + int64_t used_disk_space_; + int64_t retry_times_; +}; + +class ObAutoSplitTaskCache final +{ + struct ObAutoSplitTaskWrapper + { + public: + ObAutoSplitTaskWrapper () {} + ~ObAutoSplitTaskWrapper () {} + TO_STRING_KV(K_(priority), K_(pos_at_min_heap), K_(pos_at_max_heap), K_(task)); + public: + double priority_; + int64_t pos_at_min_heap_; + int64_t pos_at_max_heap_; + ObAutoSplitTask task_; + }; + struct MaxHeapComp + { + public: + int get_error_code() { return OB_SUCCESS; } + bool operator()(const ObAutoSplitTaskWrapper *lhs, const ObAutoSplitTaskWrapper *rhs) { return lhs->priority_ < rhs->priority_ ? true : false; } + }; + struct MinHeapComp + { + public: + int get_error_code() { return OB_SUCCESS; } + bool operator()(const ObAutoSplitTaskWrapper *lhs, const ObAutoSplitTaskWrapper *rhs) { return lhs->priority_ > rhs->priority_ ? true : false; } + }; +public: + ObAutoSplitTaskCache (); + ~ObAutoSplitTaskCache() { destroy(); } + int init(const int64_t capacity, const uint64_t tenant_id, const uint64_t host_tenant_id); + void destroy(); + int pop_tasks(const int64_t num_tasks_to_pop, ObArray &task_array); + int push_tasks(const ObArray &task_array); + uint64_t get_tenant_id() const { return tenant_id_; }; + inline int64_t get_tasks_num() { return ATOMIC_LOAD(&total_tasks_); } + inline uint64_t get_tenant_id() { return tenant_id_; } + static int mtl_init(ObAutoSplitTaskCache *&task_cache); + TO_STRING_KV(K_(max_heap), K_(min_heap), K_(tasks_set)); +public: + const static int64_t CACHE_MAX_CAPACITY = 100; +private: + int atomic_push_task(const ObAutoSplitTask &task); + int atomic_pop_task(ObAutoSplitTask &task); + int atomic_remove_task(); + int remove_tasks(const int64_t num_tasks_to_rem); + +private: + bool inited_; + int64_t total_tasks_; + uint64_t tenant_id_; + uint64_t host_tenant_id_; + ObSpinLock lock_; + MaxHeapComp max_comp_; + MinHeapComp min_comp_; + ObMalloc cache_malloc_; + ObRemovableHeap max_heap_; + ObRemovableHeap min_heap_; + common::hash::ObHashSet tasks_set_; +}; + +class ObAutoSplitTaskPollingMgr +{ +public: + ObAutoSplitTaskPollingMgr(const bool is_root_server) + : is_root_server_(is_root_server), inited_(false), total_tasks_(0) + {} + ~ObAutoSplitTaskPollingMgr() { reset(); } + int init(); + void reset(); + int pop_tasks(const int64_t num_tasks_to_pop, ObArray> &task_array); + int push_tasks(const ObArray &task_array); + inline bool is_busy() { return ATOMIC_LOAD(&total_tasks_) >= ObAutoSplitTaskPollingMgr::BUSY_THRESHOLD; } + inline bool empty() { return ATOMIC_LOAD(&total_tasks_) == 0; }; + +private: + inline int64_t get_total_tenants() { return map_tenant_to_cache_.size(); } + int pop_tasks_from_tenant_cache(const int64_t num_tasks_to_pop, + ObArray &task_array, + ObAutoSplitTaskCache *tenant_cache); + int create_tenant_cache(const uint64_t tenant_id, const uint64_t host_tenant_id, ObAutoSplitTaskCache *&tenant_cache); + int register_tenant_cache(const uint64_t tenant_id, ObAutoSplitTaskCache * const tenant_cache); + int get_tenant_cache(const int tenant_id, ObAutoSplitTaskCache *&tenant_cache); + +private: + const static int64_t INITIAL_TENANT_COUNT = 10; + const static int64_t BUSY_THRESHOLD = 500; + const bool is_root_server_; + bool inited_; + int64_t total_tasks_; + //key:tenant_id, val: idx at tenants_cache_ + common::hash::ObHashMap map_tenant_to_cache_; + ObMalloc polling_mgr_malloc_; + ObSpinLock lock_; +}; + +class ObAutoSplitArgBuilder final +{ +public: + ObAutoSplitArgBuilder() {} + ~ObAutoSplitArgBuilder() {} + inline static int32_t get_max_split_partition_num() { return MAX_SPLIT_PARTITION_NUM; } + int build_arg(const uint64_t tenant_id, + const share::ObLSID ls_id, + const ObTabletID tablet_id, + const int64_t auto_split_tablet_size, + const int64_t used_disk_space, + obrpc::ObAlterTableArg &arg); +private: + int acquire_schema_info_of_tablet_(const uint64_t tenant_id, + const ObTabletID tablet_id, + const share::schema::ObTableSchema *&table_schema, + const share::schema::ObSimpleDatabaseSchema *&db_schema, + obrpc::ObAlterTableArg &arg); + int acquire_table_id_of_tablet_(const uint64_t tenant_id, + const ObTabletID tablet_id, + uint64_t &table_id); + int build_arg_(const uint64_t tenant_id, + const ObString &db_name, + const share::schema::ObTableSchema &table_schema, + const ObTabletID split_source_tablet_id, + const ObArray &ranges, + obrpc::ObAlterTableArg &arg); + int build_alter_table_schema_(const uint64_t tenant_id, + const ObString &db_name, + const share::schema::ObTableSchema &table_schema, + const ObTabletID split_source_tablet_id, + const ObArray &ranges, + share::schema::AlterTableSchema &alter_table_schema); + int build_partition_(const uint64_t tenant_id, const uint64_t table_id, + const ObTabletID split_source_tablet_id, + const ObRowkey &high_bound_val, + share::schema::ObPartition &new_part); +private: + static const int32_t MAX_SPLIT_PARTITION_NUM = 2; +}; + + +class ObRsAutoSplitScheduler final +{ +public: + static ObRsAutoSplitScheduler &get_instance(); + inline bool is_busy() { return polling_mgr_.is_busy(); } + int push_tasks(const ObArray &task_array); + int pop_tasks(ObArray &task_array); + bool can_retry(const ObAutoSplitTask &task, const int ret); + int init() { return polling_mgr_.init(); } + void reset() { polling_mgr_.reset(); } + static int check_ls_migrating(const uint64_t tenant_id, const ObTabletID &tablet_id, bool &is_migrating); +private: + ObRsAutoSplitScheduler () + : polling_mgr_(true/*is_root_server*/) + {} + ~ObRsAutoSplitScheduler () {} +private: + const static int64_t MAX_SPLIT_TASKS_ONE_ROUND = 5; + const static int64_t MAX_TIMES_TASK_RETRY = 5; + ObAutoSplitTaskPollingMgr polling_mgr_; +}; + +class ObServerAutoSplitScheduler final +{ +public: + const static int64_t OB_SERVER_DELAYED_TIME = (10 * 1000L * 1000L); //10s +public: + static ObServerAutoSplitScheduler &get_instance(); + int push_task(const storage::ObTabletHandle &teblet_handle, storage::ObLS &ls); + int init() { return polling_manager_.init(); } + void reset() { polling_manager_.reset(); } + static int check_tablet_creation_limit(const int64_t inc_tablet_cnt, const double safe_ratio); +private: + ObServerAutoSplitScheduler () + : next_valid_time_(0), polling_manager_(false/*is_root_server*/) + {} + ~ObServerAutoSplitScheduler () {} + int batch_send_split_request(const ObArray> &task_array); + int check_and_fetch_tablet_split_info(const storage::ObTabletHandle &teblet_handle, storage::ObLS &ls, bool &can_split, ObAutoSplitTask &task); + int check_sstable_limit(const storage::ObTablet &tablet, bool &exceed_limit); +private: + const static int64_t MAX_SPLIT_RPC_IN_BATCH = 20; + const static int64_t TABLET_CNT_PER_GB = 20000; + const static int64_t SOURCE_TABLET_SSTABLE_LIMIT = 30; + int64_t next_valid_time_; + ObAutoSplitTaskPollingMgr polling_manager_; +}; + +class ObSplitSampler +{ +public: + typedef share::schema::ObPartitionSchemaIter::Info PartitionMeta; + +public: + ObSplitSampler() {} + ~ObSplitSampler() {} + int query_ranges(const uint64_t tenant_id, + const ObString &db_name, + const share::schema::ObTableSchema &table_schema, + const ObTabletID tablet_id, + const int64_t range_num, const int64_t used_disk_space, + common::ObArenaAllocator &range_allocator, + ObArray &ranges); + int query_ranges(const uint64_t tenant_id, + const ObString &db_name, + const share::schema::ObTableSchema &data_table_schema, + const ObIArray &column_names, + const ObIArray &column_ranges, + const int64_t range_num, const int64_t used_disk_space, + common::ObArenaAllocator &range_allocator, + ObArray &ranges); + +private: + int query_ranges_(const uint64_t tenant_id, const ObString &db_name, const ObString &table_name, const PartitionMeta &part_meta, + const ObIArray &column_names, + const ObIArray &column_ranges, + const int64_t range_num, const int64_t used_disk_space, + const bool query_index, + common::ObRowkey &low_bound_val, + common::ObRowkey &high_bound_val, + common::ObArenaAllocator &range_allocator, + ObArray &ranges); + int build_sample_sql_(const ObString &db_name, const ObString &table_name, const ObString* part_name, + const ObIArray &column_names, + const ObIArray &column_ranges, + const int range_num, const double sample_pct, + ObSqlString &sql); + int add_sample_condition_sqls_(const ObIArray &columns, + const ObIArray &column_ranges, + ObSqlString &sql); + int add_sample_condition_sql_(const ObString &column, + const ObNewRange &range, + ObSqlString &sql); + int acquire_partition_meta_(const share::schema::ObTableSchema &table_schema, const ObTabletID &tablet_id, PartitionMeta &meta); + int acquire_partition_key_name_(const share::schema::ObTableSchema &table_schema, ObIArray &column_names); + int gen_column_alias_(const ObIArray &columns, + ObSqlString &col_alias_str, + ObSqlString &col_name_alias_str); + int fill_query_range_bounder(const PartitionMeta& part_meta, + const ObIArray &column_ranges, + const int64_t presetting_part_column_cnt, + common::ObRowkey &low_bound_val, + common::ObRowkey &high_bound_val, + common::ObArenaAllocator &allocator); +}; +} + +} + +#endif diff --git a/src/share/scheduler/ob_sys_task_stat.cpp b/src/share/scheduler/ob_sys_task_stat.cpp index b4fe4933d..f8c1d0b49 100644 --- a/src/share/scheduler/ob_sys_task_stat.cpp +++ b/src/share/scheduler/ob_sys_task_stat.cpp @@ -42,7 +42,8 @@ const static char *ObSysTaskTypeStr[] = { "TENANT_SNAPSHOT_CREATE", "TENANT_SNAPSHOT_GC", "BATCH_FREEZE_TABLET_TASK", - "VECTOR_INDEX_TASK" + "VECTOR_INDEX_TASK", + "DDL_TABLET_SPLIT" }; 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 20e8fcd86..7b83d0d9b 100644 --- a/src/share/scheduler/ob_sys_task_stat.h +++ b/src/share/scheduler/ob_sys_task_stat.h @@ -56,6 +56,7 @@ enum ObSysTaskType TENANT_SNAPSHOT_GC_TASK, BATCH_FREEZE_TABLET_TASK, VECTOR_INDEX_TASK, + DDL_TABLET_SPLIT, MAX_SYS_TASK_TYPE }; diff --git a/src/share/scheduler/ob_tenant_dag_scheduler.cpp b/src/share/scheduler/ob_tenant_dag_scheduler.cpp index ca0b728b3..36f253647 100644 --- a/src/share/scheduler/ob_tenant_dag_scheduler.cpp +++ b/src/share/scheduler/ob_tenant_dag_scheduler.cpp @@ -3180,30 +3180,6 @@ int ObDagPrioScheduler::diagnose_compaction_dags() return ret; } -int ObDagPrioScheduler::get_complement_data_dag_progress(const ObIDag &dag, - int64_t &row_scanned, - int64_t &row_inserted) -{ - int ret = OB_SUCCESS; - ObMutexGuard guard(prio_lock_); - ObIDag *stored_dag = nullptr; - if (dag.get_type() != ObDagType::DAG_TYPE_DDL) { - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "invalid arugment", K(ret), K(dag)); - } else if (OB_FAIL(dag_map_.get_refactored(&dag, stored_dag))) { - if (OB_HASH_NOT_EXIST != ret) { - LOG_WARN("failed to get from dag map", K(ret)); - } - } else if (OB_ISNULL(stored_dag)) { - ret = OB_ERR_SYS; - LOG_WARN("dag is null", K(ret)); - } else { - row_scanned = static_cast(stored_dag)->get_context().row_scanned_; - row_inserted = static_cast(stored_dag)->get_context().row_inserted_; - } - return ret; -} - int ObDagPrioScheduler::deal_with_finish_task( ObITask &task, ObTenantDagWorker &worker, @@ -5083,23 +5059,6 @@ int ObTenantDagScheduler::cancel_dag_net(const ObDagId &dag_id) return ret; } -int ObTenantDagScheduler::get_complement_data_dag_progress(const ObIDag *dag, - int64_t &row_scanned, - int64_t &row_inserted) -{ - int ret = OB_SUCCESS; - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - COMMON_LOG(WARN, "ObDagScheduler is not inited", K(ret)); - } else if (OB_ISNULL(dag) || dag->get_type() != ObDagType::DAG_TYPE_DDL) { - ret = OB_INVALID_ARGUMENT; - COMMON_LOG(WARN, "invalid arugment", K(ret), KP(dag)); - } else if (OB_FAIL(prio_sche_[dag->get_priority()].get_complement_data_dag_progress(*dag, row_scanned, row_inserted))) { - COMMON_LOG(WARN, "fail to get complement data dag progress", K(ret), KPC(dag)); - } - return ret; -} - // for unittest int ObTenantDagScheduler::get_first_dag_net(ObIDagNet *&dag_net) { diff --git a/src/share/scheduler/ob_tenant_dag_scheduler.h b/src/share/scheduler/ob_tenant_dag_scheduler.h index 29de8ae09..62270cf5b 100644 --- a/src/share/scheduler/ob_tenant_dag_scheduler.h +++ b/src/share/scheduler/ob_tenant_dag_scheduler.h @@ -952,6 +952,31 @@ public: int diagnose_minor_exe_dag( const compaction::ObMergeDagHash &merge_dag_info, compaction::ObDiagnoseTabletCompProgress &progress); + + template + int get_dag_progress(const T &dag, int64_t &row_inserted, int64_t &physical_row_count) + { + int ret = OB_SUCCESS; + lib::ObMutexGuard guard(prio_lock_); + ObIDag *stored_dag = nullptr; + if (OB_UNLIKELY(dag.get_type() != ObDagType::DAG_TYPE_DDL + && dag.get_type() != ObDagType::DAG_TYPE_TABLET_SPLIT)) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "invalid arugment", K(ret), K(dag)); + } else if (OB_FAIL(dag_map_.get_refactored(&dag, stored_dag))) { + if (OB_HASH_NOT_EXIST != ret) { + COMMON_LOG(WARN, "failed to get from dag map", K(ret)); + } + } else if (OB_ISNULL(stored_dag)) { + ret = OB_ERR_SYS; + COMMON_LOG(WARN, "dag is null", K(ret)); + } else { + row_inserted = static_cast(stored_dag)->get_context().row_inserted_; + physical_row_count = static_cast(stored_dag)->get_context().physical_row_count_; + } + return ret; + } + int diagnose_compaction_dags(); int get_complement_data_dag_progress(const ObIDag &dag, int64_t &row_scanned, @@ -1184,11 +1209,28 @@ public: int check_dag_net_exist( const ObDagId &dag_id, bool &exist); int cancel_dag_net(const ObDagId &dag_id); - int get_complement_data_dag_progress(const ObIDag *dag, int64_t &row_scanned, int64_t &row_inserted); int deal_with_finish_task(ObITask &task, ObTenantDagWorker &worker, int error_code); bool try_switch(ObTenantDagWorker &worker); int dispatch_task(ObITask &task, ObTenantDagWorker *&ret_worker, const int64_t priority); void finish_dag_net(ObIDagNet *dag_net); + template + int get_dag_progress(const T *dag, + int64_t &row_inserted, + int64_t &physical_row_count) + { + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + COMMON_LOG(WARN, "ObDagScheduler is not inited", K(ret)); + } else if (OB_ISNULL(dag) || + (ObDagType::DAG_TYPE_DDL != dag->get_type() && ObDagType::DAG_TYPE_TABLET_SPLIT != dag->get_type())) { + ret = OB_INVALID_ARGUMENT; + COMMON_LOG(WARN, "invalid arugment", K(ret), KPC(dag)); + } else if (OB_FAIL(prio_sche_[dag->get_priority()].get_dag_progress(*dag, row_inserted, physical_row_count))) { + COMMON_LOG(WARN, "fail to get dag progress", K(ret), KPC(dag)); + } + return ret; + } // for unittest int get_first_dag_net(ObIDagNet *&dag_net); diff --git a/src/share/schema/ob_part_mgr_util.h b/src/share/schema/ob_part_mgr_util.h index 5b0fb8d8c..f1551dc79 100644 --- a/src/share/schema/ob_part_mgr_util.h +++ b/src/share/schema/ob_part_mgr_util.h @@ -179,6 +179,16 @@ private: DISALLOW_COPY_AND_ASSIGN(ObPartitionSchemaIter); }; +struct ObPartitionNameCmp +{ + ObPartitionNameCmp(const ObCollationType collation_type) : collation_type_(collation_type) {} + ~ObPartitionNameCmp() {} + bool operator()(const ObPartition *lhs, const ObPartition *rhs) { + return 0 > ObCharset::strcmp(collation_type_, lhs->get_part_name(), rhs->get_part_name()); + } + ObCollationType collation_type_; +}; + } } } diff --git a/src/share/schema/ob_partition_sql_helper.cpp b/src/share/schema/ob_partition_sql_helper.cpp index 3f655e6c1..3224b0e08 100644 --- a/src/share/schema/ob_partition_sql_helper.cpp +++ b/src/share/schema/ob_partition_sql_helper.cpp @@ -1188,6 +1188,214 @@ int ObDropIncPartDMLGenerator::extract_part_info(PartInfo &part_info) return ret; } +int ObUpdatePartHelper::update_partition_info() +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(ori_table_) || OB_ISNULL(upd_table_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table is null", K(ret)); + } else if (!ori_table_->is_user_partition_table()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("attempt to update partition informations of non-partitioned table", KR(ret), KPC(ori_table_)); + } else { + const uint64_t tenant_id = ori_table_->get_tenant_id(); + const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); + ObDMLSqlSplicer dml; + ObDMLSqlSplicer history_dml; + const int64_t deleted = false; + const int64_t part_num = upd_table_->get_partition_num(); + const int64_t hidden_part_num = upd_table_->get_hidden_partition_num(); + const int64_t all_part_num = part_num + hidden_part_num; + ObPartition **part_array = upd_table_->get_part_array(); + ObPartition **hidden_part_array = upd_table_->get_hidden_part_array(); + + if (OB_ISNULL(part_array) && OB_ISNULL(hidden_part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", K(ret), K(upd_table_)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < all_part_num; ++i) { + ObPartition *part = nullptr; + if (i < part_num) { + part = part_array[i]; + } else { + part = hidden_part_array[i - part_num]; + } + if (OB_ISNULL(part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", K(ret), K(i), K(part_num), K(hidden_part_num), KPC(upd_table_)); + } else { + HEAP_VAR(ObAddIncPartDMLGenerator, update_dml_gen, + ori_table_, *part, all_part_num, i, schema_version_) { + if (OB_FAIL(update_dml_gen.gen_dml(dml))) { + LOG_WARN("gen dml failed", K(ret)); + } else if (OB_FAIL(dml.finish_row())) { + LOG_WARN("failed to finish row", K(ret)); + } else if (OB_FAIL(update_dml_gen.gen_dml(history_dml))) { + LOG_WARN("gen dml history failed", K(ret)); + } else if (OB_FAIL(history_dml.add_column("is_deleted", deleted))) { + LOG_WARN("add column failed", K(ret)); + } else if (OB_FAIL(history_dml.finish_row())) { + LOG_WARN("failed to finish row", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (PARTITION_LEVEL_TWO != ori_table_->get_part_level()) { + // skip + } else if (OB_ISNULL(part->get_subpart_array())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("subpart array is null", K(ret)); + } else { + // TODO: need to implement code to update subpartition + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to update subpartition info", K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + int64_t affected_rows = 0; + ObSqlString part_history_sql; + if (OB_FAIL(history_dml.splice_batch_insert_sql(share::OB_ALL_PART_HISTORY_TNAME, + part_history_sql))) { + LOG_WARN("failed to splice batch insert sql", K(ret), K(part_history_sql)); + } else if (OB_FAIL(sql_client_.write(exec_tenant_id, part_history_sql.ptr(), affected_rows))) { + LOG_WARN("execute sql failed", K(ret), K(part_history_sql)); + } else if (affected_rows != all_part_num) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("history affected_rows is unexpected", K(ret), K(affected_rows), K(part_num), K(hidden_part_num), K(part_history_sql)); + } + } + + if (OB_SUCC(ret)) { + ObSqlString part_sql; + int64_t affected_rows = 0; + if (OB_FAIL(dml.splice_batch_insert_update_sql(share::OB_ALL_PART_TNAME, part_sql))) { + LOG_WARN("failed to splice batch insert sql", K(ret), K(part_sql)); + } else if (OB_FAIL(sql_client_.write(exec_tenant_id, part_sql.ptr(), affected_rows))) { + LOG_WARN("execute sql failed", K(ret), K(part_sql)); + } else if (affected_rows != 2 * all_part_num) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("affected_rows is unexpected", K(ret), K(affected_rows), K(part_num), K(hidden_part_num), K(part_sql)); + } + } + } + return ret; +} + +// 1. "part_array" records a set of new split partitions of table +// 2. "hidden_part_array" records the mock source partition: +// when split tablet of non-partitioned table, +// we will generate a mock partition for origin tablet. +// it seems that we are splitting a partitioned-table. +int ObAddSplitIncPartHelper::add_split_partition_info() +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(ori_table_) || OB_ISNULL(inc_table_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table is null", KR(ret)); + } else if (inc_table_->get_part_level() != PARTITION_LEVEL_ONE) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), KPC(inc_table_)); + } else if (OB_UNLIKELY(is_inner_table(ori_table_->get_table_id()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table type", KR(ret), KPC(ori_table_)); + } else if (OB_UNLIKELY(ori_table_->get_part_level() == ObPartitionLevel::PARTITION_LEVEL_MAX)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", KR(ret), KPC(ori_table_)); + } else { + const uint64_t tenant_id = ori_table_->get_tenant_id(); + const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); + ObDMLSqlSplicer dml; + ObDMLSqlSplicer history_dml; + const bool is_split_non_partitioned_table = ori_table_->get_part_level() == + ObPartitionLevel::PARTITION_LEVEL_ZERO; + const int64_t inc_normal_part_num = inc_table_->get_partition_num(); + const int64_t inc_hidden_part_num = inc_table_->get_hidden_partition_num(); + const int64_t inc_part_num = inc_normal_part_num + inc_hidden_part_num; + const int64_t deleted = false; + + if (OB_ISNULL(inc_table_->get_part_array())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", KR(ret), KPC(inc_table_)); + } else if (inc_normal_part_num <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part num", KR(ret), K(inc_normal_part_num)); + } else if (is_split_non_partitioned_table) { + // in order to mock splitting a partitioned table, + // when split non-partitioned table (ori_table_), + // inc_table schema will add a hidden partition for source tablet. + if (inc_hidden_part_num != 1 || OB_ISNULL(inc_table_->get_hidden_part_array())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("inc table for non-partitioned table should have a mock hidden partition", + KR(ret), KPC(ori_table_), KPC(inc_table_)); + } + } else if (inc_hidden_part_num > 0) { // !is_split_non_partitioned_table + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partitioned table should not have mock hidden partition", KR(ret), KPC(ori_table_), + KPC(inc_table_)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < inc_part_num; ++i) { + const bool is_normal_part = i < inc_normal_part_num; + ObPartition **part_array = is_normal_part ? + inc_table_->get_part_array() : + inc_table_->get_hidden_part_array(); + int64_t part_array_size = is_normal_part ? inc_normal_part_num : inc_hidden_part_num; + int64_t index = is_normal_part ? i : i - inc_normal_part_num; + ObPartition *part = part_array[index]; + if (OB_ISNULL(part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", KR(ret), K(index), K(inc_table_)); + } else { + HEAP_VAR(ObAddIncPartDMLGenerator, part_dml_gen, + ori_table_, *part, part_array_size, index, schema_version_) { + if (OB_FAIL(part_dml_gen.gen_dml(dml))) { + LOG_WARN("gen dml failed", KR(ret)); + } else if (OB_FAIL(dml.finish_row())) { + LOG_WARN("failed to finish row", KR(ret)); + } else if (OB_FAIL(part_dml_gen.gen_dml(history_dml))) { + LOG_WARN("gen dml history failed", KR(ret)); + } else if (OB_FAIL(history_dml.add_column("is_deleted", deleted))) { + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(history_dml.finish_row())) { + LOG_WARN("failed to finish row", KR(ret)); + } + } // end HEAP_VAR + } + } + + if (OB_SUCC(ret)) { + int64_t affected_rows = 0; + ObSqlString part_history_sql; + if (OB_FAIL(history_dml.splice_batch_insert_sql(share::OB_ALL_PART_HISTORY_TNAME, + part_history_sql))) { + LOG_WARN("failed to splice batch insert sql", KR(ret), K(part_history_sql)); + } else if (OB_FAIL(sql_client_.write(exec_tenant_id, part_history_sql.ptr(), affected_rows))) { + LOG_WARN("execute sql failed", KR(ret), K(part_history_sql)); + } else if (OB_UNLIKELY(affected_rows != inc_part_num)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("history affected_rows is unexpected", KR(ret), K(inc_part_num), K(affected_rows)); + } + } + + if (OB_SUCC(ret)) { + ObSqlString part_sql; + int64_t affected_rows = 0; + if (OB_FAIL(dml.splice_batch_insert_sql(share::OB_ALL_PART_TNAME, part_sql))) { + LOG_WARN("failed to splice batch insert sql", KR(ret), K(part_sql)); + } else if (OB_FAIL(sql_client_.write(exec_tenant_id, part_sql.ptr(), affected_rows))) { + LOG_WARN("execute sql failed", KR(ret), K(part_sql)); + } else if (OB_UNLIKELY(affected_rows != inc_part_num)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("affected_rows is unexpected", KR(ret), K(inc_part_num), K(affected_rows)); + } + } + } + return ret; +} + int ObAddIncPartHelper::add_partition_info() { int ret = OB_SUCCESS; diff --git a/src/share/schema/ob_partition_sql_helper.h b/src/share/schema/ob_partition_sql_helper.h index be7a7d6e2..6fe3f0498 100644 --- a/src/share/schema/ob_partition_sql_helper.h +++ b/src/share/schema/ob_partition_sql_helper.h @@ -321,6 +321,50 @@ private: DISALLOW_COPY_AND_ASSIGN(ObDropPartInfoHelper); }; +// update partition +class ObUpdatePartHelper +{ +public: + ObUpdatePartHelper(const ObPartitionSchema *ori_table, + const ObPartitionSchema *upd_table, + const int64_t schema_version, + common::ObISQLClient &sql_client) + : ori_table_(ori_table), + upd_table_(upd_table), + schema_version_(schema_version), + sql_client_(sql_client) {} + virtual ~ObUpdatePartHelper() {} + int update_partition_info(); +private: + const ObPartitionSchema *ori_table_; + const ObPartitionSchema *upd_table_; + int64_t schema_version_; + common::ObISQLClient &sql_client_; + DISALLOW_COPY_AND_ASSIGN(ObUpdatePartHelper); +}; + +// split partition +class ObAddSplitIncPartHelper +{ +public: + ObAddSplitIncPartHelper(const ObPartitionSchema *ori_table, + const ObPartitionSchema *inc_table, + const int64_t schema_version, + common::ObISQLClient &sql_client) + : ori_table_(ori_table), + inc_table_(inc_table), + schema_version_(schema_version), + sql_client_(sql_client) {} + virtual ~ObAddSplitIncPartHelper() {} + int add_split_partition_info(); +private: + const ObPartitionSchema *ori_table_; + const ObPartitionSchema *inc_table_; + int64_t schema_version_; + common::ObISQLClient &sql_client_; + DISALLOW_COPY_AND_ASSIGN(ObAddSplitIncPartHelper); +}; + // add/truncate partition class ObAddIncPartHelper { diff --git a/src/share/schema/ob_schema_getter_guard.cpp b/src/share/schema/ob_schema_getter_guard.cpp index 6edbe28ff..427fb34e9 100644 --- a/src/share/schema/ob_schema_getter_guard.cpp +++ b/src/share/schema/ob_schema_getter_guard.cpp @@ -10047,6 +10047,57 @@ int ObSchemaGetterGuard::check_global_index_exist(const uint64_t tenant_id, cons return ret; } +// TODO YIREN, remove it when MDS prepare. +int ObSchemaGetterGuard::get_range_part_high_bound( + const ObTableSchema &table_schema, + const common::ObTabletID &tablet_id, + ObIAllocator &allocator, + common::ObRowkey &high_bound) +{ + int ret = OB_SUCCESS; + high_bound.reset(); + if (OB_UNLIKELY(!table_schema.is_valid() || !tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(tablet_id), K(table_schema)); + } else if (OB_UNLIKELY((PARTITION_LEVEL_ONE == table_schema.get_part_level() + && !is_range_part(table_schema.get_part_option().get_part_func_type())) + || (PARTITION_LEVEL_TWO == table_schema.get_part_level() + && !is_range_part(table_schema.get_sub_part_option().get_part_func_type())))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(table_schema)); + } else if (OB_UNLIKELY(get_tenant_id() != table_schema.get_tenant_id())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("tenant_id is not match with schema_guard", K(ret), K(tenant_id_), "tenant_id", table_schema.get_tenant_id()); + } else if (!table_schema.has_tablet()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("this table do not have tablet", K(ret), K(table_schema)); + } else { + ObPartitionSchemaIter::Info part_info; + ObPartitionSchemaIter iter(table_schema, ObCheckPartitionMode::CHECK_PARTITION_MODE_ALL); + while (OB_SUCC(ret) && (OB_SUCC(iter.next_partition_info(part_info)))) { + if (OB_ISNULL(part_info.partition_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the part_info.partition_ is nullptr", K(ret), K(part_info)); + } else if (part_info.partition_->get_tablet_id() == tablet_id) { + const common::ObRowkey &part_high_bound = part_info.partition_->get_high_bound_val(); + if (OB_UNLIKELY(!part_high_bound.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret)); + } else if (OB_FAIL(part_high_bound.deep_copy(high_bound, allocator))) { + LOG_WARN("deep copy failed", K(ret), K(part_high_bound)); + } else { + break; + } + } + } + if (OB_SUCC(ret) && !high_bound.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(tablet_id), K(table_schema)); + } + } + return ret; +} + int ObSchemaGetterGuard::deep_copy_index_name_map( common::ObIAllocator &allocator, ObIndexNameMap &index_name_cache) diff --git a/src/share/schema/ob_schema_getter_guard.h b/src/share/schema/ob_schema_getter_guard.h index eb0b686db..3b54b295f 100644 --- a/src/share/schema/ob_schema_getter_guard.h +++ b/src/share/schema/ob_schema_getter_guard.h @@ -1083,6 +1083,10 @@ public: const uint64_t column_id, bool &is_key); + int get_range_part_high_bound(const ObTableSchema &table_schema, + const common::ObTabletID &tablet_id, + ObIAllocator &allocator, + common::ObRowkey &high_bound); int deep_copy_index_name_map(common::ObIAllocator &allocator, ObIndexNameMap &index_name_cache); #define GET_SIMPLE_SCHEMAS_IN_DATABASE_FUNC_DECLARE(SCHEMA, SCHEMA_TYPE) \ diff --git a/src/share/schema/ob_schema_printer.cpp b/src/share/schema/ob_schema_printer.cpp index 0a3b04e05..30d2c8093 100644 --- a/src/share/schema/ob_schema_printer.cpp +++ b/src/share/schema/ob_schema_printer.cpp @@ -2020,7 +2020,8 @@ int ObSchemaPrinter::print_table_definition_table_options(const ObTableSchema &t static int print_partition_func(const ObTableSchema &table_schema, ObSqlString &disp_part_str, - bool is_subpart) + bool is_subpart, + bool strict_compat) { int ret = OB_SUCCESS; const ObPartitionOption &part_opt = table_schema.get_part_option(); @@ -2039,28 +2040,67 @@ static int print_partition_func(const ObTableSchema &table_schema, } } else if (OB_FAIL(get_part_type_str(is_oracle_mode, type, type_str))) { SHARE_SCHEMA_LOG(WARN, "failed to get part type string", K(ret)); - } else if (OB_FAIL(disp_part_str.append_fmt("partition by %.*s(%.*s)", + } + + if (OB_FAIL(ret)) { + } else if (part_opt.get_auto_part() && part_opt.is_range_part() && !part_opt.is_interval_part()) { + // is auto partition table + // do not support show index table auto part info, because now we do not support index auto split sql grammar + if (!table_schema.is_index_table()) { + if (!strict_compat) { + int64_t auto_split_size = part_opt.get_auto_part_size(); + auto_split_size = auto_split_size >> 20; // MB + if (OB_FAIL(disp_part_str.append_fmt("partition by %.*s(%.*s) size (\'%ldMB\')", + type_str.length(), + type_str.ptr(), + func_expr.length(), + func_expr.ptr(), + auto_split_size))) { + SHARE_SCHEMA_LOG(WARN, "fail to append display auto split expr", K(ret)); + } + } else if (OB_FAIL(disp_part_str.append_fmt("partition by %.*s(%.*s)", type_str.length(), type_str.ptr(), func_expr.length(), func_expr.ptr()))) { - } else if (is_subpart) { // sub part - const ObPartitionOption &sub_part_opt = table_schema.get_sub_part_option(); - ObString sub_type_str; - ObPartitionFuncType sub_type = sub_part_opt.get_part_func_type(); - - const ObString &sub_func_expr = sub_part_opt.get_part_func_expr_str(); - if (OB_FAIL(get_part_type_str(is_oracle_mode, sub_type, sub_type_str))) { - SHARE_SCHEMA_LOG(WARN, "failed to get part type string", K(ret)); - } else if (OB_FAIL(disp_part_str.append_fmt(" subpartition by %.*s(%.*s)", - sub_type_str.length(), - sub_type_str.ptr(), - sub_func_expr.length(), - sub_func_expr.ptr()))) { - SHARE_SCHEMA_LOG(WARN, "fail to append diaplay partition expr", - K(ret), K(sub_type_str), K(sub_func_expr)); + SHARE_SCHEMA_LOG(WARN, "fail to append display partition expr", K(ret), K(type_str), K(func_expr)); + } + } else { + if (OB_ISNULL(table_schema.get_part_array())) { + // do not show partition func expr of auto split none partition table + } else if (OB_FAIL(disp_part_str.append_fmt("partition by %.*s(%.*s)", + type_str.length(), + type_str.ptr(), + func_expr.length(), + func_expr.ptr()))) { + SHARE_SCHEMA_LOG(WARN, "fail to append display partition expr", K(ret), K(type_str), K(func_expr)); + } } - } else {} + } else { + if (OB_FAIL(disp_part_str.append_fmt("partition by %.*s(%.*s)", + type_str.length(), + type_str.ptr(), + func_expr.length(), + func_expr.ptr()))) { + SHARE_SCHEMA_LOG(WARN, "fail to append display partition expr", K(ret), K(type_str), K(func_expr)); + } else if (is_subpart) { // sub part + const ObPartitionOption &sub_part_opt = table_schema.get_sub_part_option(); + ObString sub_type_str; + ObPartitionFuncType sub_type = sub_part_opt.get_part_func_type(); + + const ObString &sub_func_expr = sub_part_opt.get_part_func_expr_str(); + if (OB_FAIL(get_part_type_str(is_oracle_mode, sub_type, sub_type_str))) { + SHARE_SCHEMA_LOG(WARN, "failed to get part type string", K(ret)); + } else if (OB_FAIL(disp_part_str.append_fmt(" subpartition by %.*s(%.*s)", + sub_type_str.length(), + sub_type_str.ptr(), + sub_func_expr.length(), + sub_func_expr.ptr()))) { + SHARE_SCHEMA_LOG(WARN, "fail to append display partition expr", + K(ret), K(sub_type_str), K(sub_func_expr)); + } + } else {} + } return ret; } @@ -2163,7 +2203,7 @@ int ObSchemaPrinter::print_table_definition_partition_options(const ObTableSchem const ObTimeZoneInfo *tz_info) const { int ret = OB_SUCCESS; - if (table_schema.is_partitioned_table() + if ((table_schema.is_partitioned_table() || table_schema.is_auto_partitioned_table()) && !table_schema.is_index_local_storage() && !table_schema.is_oracle_tmp_table()) { ObString disp_part_fun_expr_str; @@ -2178,7 +2218,7 @@ int ObSchemaPrinter::print_table_definition_partition_options(const ObTableSchem } if (OB_FAIL(databuff_printf(buf, buf_len, pos, "\n"))) { SHARE_SCHEMA_LOG(WARN, "fail to print enter", K(ret)); - } else if (OB_FAIL(print_partition_func(table_schema, disp_part_str, is_subpart))) { + } else if (OB_FAIL(print_partition_func(table_schema, disp_part_str, is_subpart, strict_compat_))) { SHARE_SCHEMA_LOG(WARN, "failed to print part func", K(ret)); } else if (FALSE_IT(disp_part_fun_expr_str = disp_part_str.string())) { // will not reach here @@ -3607,6 +3647,9 @@ int ObSchemaPrinter::print_range_partition_elements(const ObPartitionSchema *&sc SHARE_SCHEMA_LOG(WARN, "schema is null", K(ret)); } else if (OB_FAIL(schema->check_if_oracle_compat_mode(is_oracle_mode))) { LOG_WARN("fail to check oracle mode", KR(ret), KPC(schema)); + } else if (schema->get_part_option().get_auto_part() + && OB_ISNULL(schema->get_part_array())) { + // in auto partition mode, part array is empty is possible. here no need to print partition element } else { ObPartition **part_array = schema->get_part_array(); if (OB_ISNULL(part_array)) { diff --git a/src/share/schema/ob_schema_struct.cpp b/src/share/schema/ob_schema_struct.cpp index ecc814d39..e377e8d52 100644 --- a/src/share/schema/ob_schema_struct.cpp +++ b/src/share/schema/ob_schema_struct.cpp @@ -2852,6 +2852,7 @@ int ObPartitionSchema::assign_partition_schema(const ObPartitionSchema &src_sche partition_schema_version_ = src_schema.partition_schema_version_; partition_status_ = src_schema.partition_status_; sub_part_template_flags_ = src_schema.sub_part_template_flags_; + if (OB_SUCC(ret)) { part_option_ = src_schema.part_option_; if (OB_FAIL(part_option_.get_err_ret())) { @@ -3340,6 +3341,26 @@ int ObPartitionSchema::get_max_part_idx(int64_t &part_idx, const bool skip_exter return ret; } +bool ObPartitionSchema::is_in_splitting() const +{ + int ret = OB_SUCCESS; + bool is_splitting = false; + + if (hidden_partition_array_ != nullptr) { + for (int64_t i = 0; OB_SUCC(ret) && !is_splitting && i < hidden_partition_num_; ++i) { + ObPartition *part = hidden_partition_array_[i]; + + if (OB_ISNULL(part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", K(ret), K(i), K(hidden_partition_num_)); + } else if (part->is_in_splitting()) { + is_splitting = true; + } + } + } + return is_splitting; +} + bool ObPartitionSchema::is_valid() const { return ObSchema::is_valid(); @@ -5033,6 +5054,68 @@ bool ObPartitionOption::is_valid() const return ObSchema::is_valid() && part_num_ > 0; } +void ObPartitionOption::assign_auto_partition_attr(const ObPartitionOption & src) +{ + auto_part_ = src.auto_part_; + auto_part_size_ = src.auto_part_size_; +} + +int ObPartitionOption::enable_auto_partition(const int64_t auto_part_size) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_valid_split_part_type())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("invalid part type for split partition", KR(ret), K(part_func_type_)); + } else if (OB_FAIL(enable_auto_partition_(auto_part_size))) { + LOG_WARN("fail to enable auto_partition", KR(ret), K(auto_part_size)); + } + + return ret; +} + +int ObPartitionOption::enable_auto_partition(const int64_t auto_part_size, + const ObPartitionFuncType part_func_type) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_valid_split_part_type(part_func_type))) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("invalid part type for split partition", KR(ret), K(part_func_type)); + } else if (OB_FAIL(enable_auto_partition_(auto_part_size))) { + LOG_WARN("fail to enable auto_partition", KR(ret), K(auto_part_size)); + } else { + part_func_type_ = part_func_type; + } + + return ret; +} + +int ObPartitionOption::enable_auto_partition_(const int64_t auto_part_size) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(auto_part_size < ObPartitionOption::MIN_AUTO_PART_SIZE)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("the auto split tablet size is less than MIN_AUTO_PART_SIZE", KR(ret), K(auto_part_size)); + } else { + auto_part_ = true; + auto_part_size_ = auto_part_size; + } + + return ret; +} + +void ObPartitionOption::forbid_auto_partition(const bool is_partitioned_table) +{ + if (!is_partitioned_table) { + part_func_type_ = PARTITION_FUNC_TYPE_HASH; + reset_string(part_func_expr_); + } + auto_part_ = false; + auto_part_size_ = -1; +} + OB_DEF_SERIALIZE(ObPartitionOption) { int ret = OB_SUCCESS; @@ -9725,6 +9808,13 @@ bool is_mlog_table(const ObTableType table_type) return (ObTableType::MATERIALIZED_VIEW_LOG == table_type); } +bool is_support_split_index_type(const ObIndexType index_type) +{ + return INDEX_TYPE_NORMAL_LOCAL == index_type || INDEX_TYPE_UNIQUE_LOCAL == index_type + || INDEX_TYPE_NORMAL_GLOBAL == index_type || INDEX_TYPE_UNIQUE_GLOBAL == index_type + || INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE == index_type || INDEX_TYPE_UNIQUE_GLOBAL_LOCAL_STORAGE == index_type; +} + const char *schema_type_str(const ObSchemaType schema_type) { const char *str = ""; @@ -13174,7 +13264,7 @@ int ObContextSchema::assign(const ObContextSchema &src_schema) if (OB_FAIL(set_namespace(src_schema.namespace_))) { LOG_WARN("failed to set ctx namespace", K(ret)); } else if (OB_FAIL(set_schema_name(src_schema.schema_name_))) { - LOG_WARN("failed to set schema name", K(ret));; + LOG_WARN("failed to set schema name", K(ret)); } else if (OB_FAIL(set_trusted_package(src_schema.trusted_package_))) { LOG_WARN("failed to set trusted package name", K(ret)); } diff --git a/src/share/schema/ob_schema_struct.h b/src/share/schema/ob_schema_struct.h index b20b02373..c5e385ed3 100755 --- a/src/share/schema/ob_schema_struct.h +++ b/src/share/schema/ob_schema_struct.h @@ -351,6 +351,8 @@ enum ObIndexType INDEX_TYPE_MAX = 30, }; +bool is_support_split_index_type(const ObIndexType index_type); + // using type for index enum ObIndexUsingType { @@ -802,6 +804,13 @@ inline bool index_has_tablet(const ObIndexType &index_type) || is_vec_index(index_type); } +inline static bool is_local_unique_index_table(const ObIndexType index_type) +{ + return INDEX_TYPE_UNIQUE_LOCAL == index_type + || INDEX_TYPE_UNIQUE_GLOBAL_LOCAL_STORAGE == index_type + || INDEX_TYPE_UNIQUE_MULTIVALUE_LOCAL == index_type; +} + struct ObTenantTableId { ObTenantTableId() : tenant_id_(common::OB_INVALID_ID), table_id_(common::OB_INVALID_ID) @@ -2005,9 +2014,14 @@ public: { return share::schema::is_key_part(part_func_type_); } inline bool is_list_part() const { return share::schema::is_list_part(part_func_type_); } - inline bool is_auto_range_part() const + inline bool is_valid_split_part_type() const { - return auto_part_ && is_range_part(); + return is_range_part() && !is_interval_part(); + } + inline bool is_valid_split_part_type(const ObPartitionFuncType part_func_type) const + { + return share::schema::is_range_part(part_func_type) && + !share::schema::is_interval_part(part_func_type); } //set methods @@ -2030,6 +2044,9 @@ public: inline ObPartitionFuncType get_sub_part_func_type() const { return part_func_type_; } const common::ObString &get_intervel_start_str() const { return interval_start_; } const common::ObString &get_part_intervel_str() const { return part_interval_; } + inline bool get_auto_part() const { + return auto_part_; + } inline int64_t get_auto_part_size() const { return auto_part_size_; } @@ -2040,8 +2057,22 @@ public: int64_t assign(const ObPartitionOption & src_part); int64_t get_convert_size() const ; virtual bool is_valid() const; + inline bool is_valid_auto_part_size() const { + return auto_part_size_ >= MIN_AUTO_PART_SIZE; + } + void assign_auto_partition_attr(const ObPartitionOption & src); + int enable_auto_partition(const int64_t auto_part_size); + int enable_auto_partition(const int64_t auto_part_size, const ObPartitionFuncType part_func_type); + void forbid_auto_partition(const bool is_partitioned_table); + bool is_enable_auto_part() const { return auto_part_ && auto_part_size_ >= MIN_AUTO_PART_SIZE; } TO_STRING_KV(K_(part_func_type), K_(part_func_expr), K_(part_num), K_(auto_part), K_(auto_part_size)); +private: + int enable_auto_partition_(const int64_t auto_part_size); + +public: + static const int64_t MIN_AUTO_PART_SIZE = 128LL * 1024 * 1024; // 128M + private: ObPartitionFuncType part_func_type_; common::ObString part_func_expr_; @@ -2049,8 +2080,8 @@ private: int64_t part_num_; common::ObString interval_start_; //interval start value common::ObString part_interval_; // interval partition step - bool auto_part_;// Whether it is automatic partition - int64_t auto_part_size_;// Automatic partition size, 0 is auto + bool auto_part_;// Whether it is auto-partitioned table + int64_t auto_part_size_;// Automatic partition size }; // For any questions about the role of this structure, please contact @jiage @@ -2225,6 +2256,13 @@ public: int64_t get_tablespace_id() const { return tablespace_id_; } + void set_split_source_tablet_id(const ObTabletID split_source_tablet_id) + { split_source_tablet_id_ = split_source_tablet_id; } + void set_split_source_tablet_id(const uint64_t split_source_tablet_id) + { split_source_tablet_id_ = split_source_tablet_id; } + ObTabletID get_split_source_tablet_id() const + { return split_source_tablet_id_; } + int assign(const ObBasePartition & src_part); // This interface is not strictly semantically less than, please note @@ -2267,6 +2305,8 @@ public: virtual bool is_normal_partition() const = 0; virtual bool is_hidden_partition() const { return share::schema::is_hidden_partition(partition_type_); } + bool is_in_splitting() const { return partition_type_ == PARTITION_TYPE_SPLIT_SOURCE; } + // convert character set. int convert_character_for_range_columns_part(const ObCollationType &to_collation); int convert_character_for_list_columns_part(const ObCollationType &to_collation); @@ -2277,7 +2317,7 @@ public: { return external_location_; } VIRTUAL_TO_STRING_KV(K_(tenant_id), K_(table_id), K_(part_id), K_(name), K_(low_bound_val), K_(high_bound_val), K_(list_row_values), K_(part_idx), - K_(is_empty_partition_name), K_(tablet_id), K_(external_location)); + K_(is_empty_partition_name), K_(tablet_id), K_(external_location), K_(split_source_tablet_id)); protected: uint64_t tenant_id_; uint64_t table_id_; @@ -2305,7 +2345,9 @@ protected: PartitionType partition_type_; common::ObRowkey low_bound_val_; ObTabletID tablet_id_; + common::ObString external_location_; + // Attention: // split_source_tablet_id_ will not be persisted in inner_table. // it is only used when attempting to split partition. ObTabletID split_source_tablet_id_; @@ -2565,8 +2607,9 @@ public: inline bool is_list_part() const { return part_option_.is_list_part(); } inline bool is_list_subpart() const { return sub_part_option_.is_list_part(); } - inline bool is_auto_partitioned_table() const { return part_option_.is_auto_range_part();} - + inline bool is_valid_split_part_type() const { return part_option_.is_valid_split_part_type();} + inline bool is_auto_partitioned_table() const { return part_option_.get_auto_part() && + part_option_.is_valid_auto_part_size(); } inline const ObPartitionOption &get_part_option() const { return part_option_; } inline ObPartitionOption &get_part_option() { return part_option_; } inline const ObPartitionOption &get_sub_part_option() const { return sub_part_option_; } @@ -2640,6 +2683,7 @@ public: /* ----------------------------------*/ inline void set_partition_schema_version(const int64_t schema_version) { partition_schema_version_ = schema_version; } inline int64_t get_partition_schema_version() const { return partition_schema_version_; } + virtual bool is_hidden_schema() const = 0; virtual bool is_normal_schema() const = 0; @@ -2654,6 +2698,11 @@ public: partition_num_ = 0; partition_array_ = NULL; } + void reset_hidden_partition_array() { + hidden_partition_array_capacity_ = 0; + hidden_partition_num_ = 0; + hidden_partition_array_ = NULL; + } int64_t get_hidden_partition_num() const { return hidden_partition_num_; } ObPartition **get_hidden_part_array() const { return hidden_partition_array_; } @@ -2671,9 +2720,10 @@ public: inline void set_partition_status(const ObPartitionStatus partition_status) { partition_status_ = partition_status; } inline ObPartitionStatus get_partition_status() const { return partition_status_; } - bool is_in_splitting() const { return partition_status_ == PARTITION_STATUS_LOGICAL_SPLITTING - || partition_status_ == PARTITION_STATUS_PHYSICAL_SPLITTING; } + bool is_in_splitting() const; + // deprecated bool is_in_logical_split () const { return partition_status_ == PARTITION_STATUS_LOGICAL_SPLITTING; } + // deprecated bool is_in_physical_split() const { return partition_status_ == PARTITION_STATUS_PHYSICAL_SPLITTING; } //other methods virtual void reset(); @@ -2777,7 +2827,7 @@ protected: /* template subpartition define end*/ // Record the split schema, initialized to 0, not cleared after splitting, the bottom layer needs to be used int64_t partition_schema_version_; - ObPartitionStatus partition_status_; + ObPartitionStatus partition_status_; // deprecated /* * Here is the different values for sub_part_template_flags_: * 1) 0: sub_part_template is not defined. diff --git a/src/share/schema/ob_table_schema.cpp b/src/share/schema/ob_table_schema.cpp index 0b3b60bf6..aa89b49d8 100644 --- a/src/share/schema/ob_table_schema.cpp +++ b/src/share/schema/ob_table_schema.cpp @@ -351,6 +351,7 @@ ObPartitionLevel ObSimpleTableSchemaV2::get_part_level() const && part_option_.get_part_func_expr_str().empty()) { part_level = PARTITION_LEVEL_ZERO; } else { }//do nothing + return part_level; } @@ -1157,6 +1158,54 @@ int ObSimpleTableSchemaV2::get_part_idx_by_tablet(const ObTabletID &tablet_id, i return ret; } +// only used for the first level parition; +// not support get subpart_id by tablet_id; +int ObSimpleTableSchemaV2::get_hidden_part_id_by_tablet_id(const ObTabletID &tablet_id, int64_t &part_id /*OUT*/) const +{ + int ret = OB_SUCCESS; + part_id = OB_INVALID_PARTITION_ID; + if (!tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tablet_id is invalid", KR(ret), K(tablet_id), KPC(this)); + } else if (part_level_ != PARTITION_LEVEL_ONE) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part type", KR(ret), KPC(this)); + } else if (!has_tablet()) { + ret = OB_OP_NOT_ALLOW; + LOG_WARN("There are no tablets in virtual table and view", KR(ret), KPC(this)); + } else { + ObPartition **part_array = get_hidden_part_array(); + int64_t part_num = get_hidden_partition_num(); + if (OB_ISNULL(part_array)) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("part array is null", KR(ret), KPC(this)); + } else { + bool found = false; + for (int64_t i = 0; OB_SUCC(ret) && i < part_num && !found; ++i) { + if (OB_ISNULL(part_array[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", K(i), KR(ret), KPC(this)); + } else if (PARTITION_LEVEL_ONE == part_level_) { + if (part_array[i]->get_tablet_id() == tablet_id) { + part_id = part_array[i]->get_part_id(); + found = true; + } + } + } + if (OB_FAIL(ret)) { + // error occurred + } else if (!found) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("part is not exist", KR(ret), KPC(this)); + } + } + } + if (OB_FAIL(ret)) { + part_id = OB_INVALID_PARTITION_ID; + } + return ret; +} + int ObSimpleTableSchemaV2::get_part_id_by_tablet(const ObTabletID &tablet_id, int64_t &part_id, int64_t &subpart_id) const { int ret = OB_SUCCESS; @@ -1798,6 +1847,90 @@ int ObTableSchema::assign_column_group(const ObTableSchema &other) return ret; } +int ObTableSchema::assign_partition_schema_without_auto_part_attr(const ObTableSchema &src_schema) +{ + int ret = OB_SUCCESS; + if (this != &src_schema) { + bool auto_part = part_option_.get_auto_part(); + int64_t auto_part_size = part_option_.get_auto_part_size(); + + if (OB_FAIL(assign_partition_schema(src_schema))) { + LOG_WARN("fail to assign partition schema", KR(ret), K(src_schema), KPC(this)); + } else { + part_option_.set_auto_part(auto_part); + part_option_.set_auto_part_size(auto_part_size); + } + } + return ret; +} + +int ObTableSchema::enable_auto_partition(const int64_t auto_part_size) +{ + int ret = OB_SUCCESS; + if (is_partitioned_table()) { + if (OB_FAIL(part_option_.enable_auto_partition(auto_part_size))) { + LOG_WARN("fail to enable auto partition", KR(ret), K(auto_part_size)); + } + } else { + ObPartitionFuncType part_func_type; + if (OB_FAIL(detect_part_func_type(part_func_type))) { + LOG_WARN("fail to check part func type", K(ret)); + } else if (OB_FAIL(part_option_.enable_auto_partition(auto_part_size, part_func_type))) { + LOG_WARN("fail to enable auto partition", KR(ret), K(auto_part_size)); + } + } + return ret; +} + +int ObTableSchema::detect_part_func_type(ObPartitionFuncType &part_func_type) +{ + int ret = OB_SUCCESS; + part_func_type = PARTITION_FUNC_TYPE_MAX; + const ObString &part_expr = part_option_.get_part_func_expr_str(); + static const char DELIMITER = ','; + bool is_range_columns = !part_expr.empty() ? + part_expr.find(DELIMITER) != nullptr : + is_index_table() ? get_index_column_num() > 1 : + get_rowkey_column_num() > 1; + if (!is_range_columns && part_expr.empty()) { + /*in case of create table t1(a timestamp, b VARCHAR(150), c int, d VARCHAR(4000), primary key(a)) partition by range ()*/ + ObObjMeta type; + if (!is_index_table()) { + ObRowkeyColumn row_key_col; + const common::ObRowkeyInfo &row_key_info = get_rowkey_info(); + if (OB_FAIL(row_key_info.get_column(0/*since there is only one row key, we only need to check the first one*/, row_key_col))) { + LOG_WARN("get row key column failed", K(ret), K(row_key_info)); + } else { + type = row_key_col.get_meta_type(); + } + } else { + ObIndexColumn index_key_col; + const common::ObIndexInfo &index_key_info = get_index_info(); + if (OB_FAIL(index_key_info.get_column(0/*since there is only one index key, we only need to check the first one*/, index_key_col))) { + LOG_WARN("get index key column failed", K(ret), K(index_key_info)); + } else { + type = index_key_col.get_meta_type(); + } + } + if OB_FAIL(ret) { + } else { + is_range_columns = ObResolverUtils::is_partition_range_column_type(type.get_type()); + } + } + + if (OB_SUCC(ret)) { + part_func_type = is_range_columns ? + PARTITION_FUNC_TYPE_RANGE_COLUMNS : + PARTITION_FUNC_TYPE_RANGE; + } + return ret; +} + +void ObTableSchema::forbid_auto_partition() +{ + part_option_.forbid_auto_partition(is_partitioned_table()); +} + bool ObTableSchema::is_valid() const { bool valid_ret = true; @@ -2786,15 +2919,40 @@ int ObTableSchema::add_partition_key(const common::ObString &column_name) ObPartitionKeyColumn partition_key_column; if (NULL == (column = const_cast(get_column_schema(column_name)))) { ret = OB_ERR_BAD_FIELD_ERROR; - LOG_WARN("fail to get column schema, return NULL", K(column_name), K(ret)); - } else if (column->is_part_key_column()) { - LOG_INFO("already partition key", K(column_name), K(ret)); - } else if (FALSE_IT(construct_partition_key_column(*column, partition_key_column))) { - } else if (OB_FAIL(column->set_part_key_pos(partition_key_info_.get_size() + 1))) { - LOG_WARN("Failed to set partition key position", K(ret)); + LOG_WARN("fail to get column schema, return NULL", K(column_name), KR(ret)); + } else if (OB_FAIL(add_partition_key_(*column))) { + LOG_WARN("Failed to add partition key", KR(ret), K(column_name)); + } + return ret; +} + +int ObTableSchema::add_partition_key(const uint64_t column_id) +{ + int ret = OB_SUCCESS; + ObColumnSchemaV2 *column = NULL; + ObPartitionKeyColumn partition_key_column; + if (NULL == (column = const_cast(get_column_schema(column_id)))) { + ret = OB_ERR_BAD_FIELD_ERROR; + LOG_WARN("fail to get column schema, return NULL", K(column_id), KR(ret)); + } else if (OB_FAIL(add_partition_key_(*column))) { + LOG_WARN("Failed to add partition key", KR(ret), K(column_id)); + } + return ret; +} + +int ObTableSchema::add_partition_key_(ObColumnSchemaV2 &column) +{ + int ret = OB_SUCCESS; + ObPartitionKeyColumn partition_key_column; + + if (column.is_part_key_column()) { + LOG_INFO("already partition key", K(column), KR(ret)); + } else if (FALSE_IT(construct_partition_key_column(column, partition_key_column))) { + } else if (OB_FAIL(column.set_part_key_pos(partition_key_info_.get_size() + 1))) { + LOG_WARN("Failed to set partition key position", KR(ret)); } else if (OB_FAIL(partition_key_info_.set_column(partition_key_info_.get_size(), partition_key_column))) { - LOG_WARN("Failed to set partition coumn"); + LOG_WARN("Failed to set partition column", KR(ret)); } else { part_key_column_num_ = partition_key_info_.get_size(); } @@ -2816,7 +2974,7 @@ int ObTableSchema::add_subpartition_key(const common::ObString &column_name) LOG_WARN("Failed to set partition key position", K(ret)); } else if (OB_FAIL(subpartition_key_info_.set_column(subpartition_key_info_.get_size(), partition_key_column))) { - LOG_WARN("Failed to set partition coumn"); + LOG_WARN("Failed to set partition column", KR(ret)); } else { subpart_key_column_num_ = subpartition_key_info_.get_size(); } @@ -4700,6 +4858,7 @@ int ObTableSchema::check_prohibition_rules(const ObColumnSchemaV2 &src_schema, bool is_enable = false; bool is_same = false; bool has_prefix_idx_col_deps = false; + bool is_tbl_part_key = false; bool is_column_in_fk = is_column_in_foreign_key(src_schema.get_column_id()); if (OB_FAIL(check_is_exactly_same_type(src_schema, dst_schema, is_same))) { LOG_WARN("failed to check is exactly same type", K(ret)); @@ -4713,7 +4872,10 @@ int ObTableSchema::check_prohibition_rules(const ObColumnSchemaV2 &src_schema, // The column contains the check constraint to prohibit modification of the type in mysql mode ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "Alter column with check constraint"); - } else if (is_oracle_mode && src_schema.is_tbl_part_key_column()) { + } else if (is_oracle_mode && OB_FAIL(is_tbl_partition_key(src_schema, is_tbl_part_key, + false /* ignore_presetting_key */))) { + LOG_WARN("fail to check partition key", KR(ret), K(src_schema)); + } else if (is_oracle_mode && is_tbl_part_key) { // Partition key prohibited to modify the type in oracle mode ret = OB_NOT_SUPPORTED; LOG_USER_ERROR(OB_NOT_SUPPORTED, "Alter column with partition key"); @@ -7437,6 +7599,436 @@ OB_DEF_SERIALIZE_SIZE(ObTableSchema) return len; } +// the part_level of an auto-partitioned table might be changed after auto partitioning is triggered: +// if the table is a no primary key table, +// target_part_level = PARTITION_LEVEL_MAX +// if the table is non-partitioned table and presetting partition key matches rowkey prefix, +// target_part_level = PARTITION_LEVEL_ONE +// if the table is non-partitioned table and presetting partition key doesn't match rowkey prefix, +// target_part_level = PARTITION_LEVEL_TWO (TODO) +// if the table is partitioned table and partition key matches rowkey prefix, +// target_part_level = PARTITION_LEVEL_ONE +// if the table is partitioned table and partition key doesn't match rowkey prefix, +// target_part_level = PARTITION_LEVEL_TWO (TODO) +// if the table is subpartitioned table and partition key, subpartition key match rowkey prefix, +// target_part_level = PARTITION_LEVEL_TWO (TODO) +// if the table is subpartitioned table and partition key, subpartition key don't match rowkey prefix, +// target_part_level = PARTITION_LEVEL_MAX +// Attention: +// PARTITION_LEVEL_MAX is invalid partition level which means the function run failed or +// the table can not auto split partition (such as no-primary-key table). +// caller should check whether can continue if get target_part_level of PARTITION_LEVEL_MAX. +ObPartitionLevel ObTableSchema::get_target_part_level_for_auto_partitioned_table() const +{ + int ret = OB_SUCCESS; + ObPartitionLevel target_part_level = PARTITION_LEVEL_MAX; + if (is_auto_partitioned_table()) { + bool match_rowkey_prefix = false; + if (is_heap_table()) { + // not allow to auto partitioning no primary key table + // target_part_level = PARTITION_LEVEL_MAX + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get target part level from a no primary key table", KR(ret), KPC(this)); + } else if (part_level_ == PARTITION_LEVEL_ZERO) { + if (OB_FAIL(is_presetting_partition_key_match_rowkey_prefix(match_rowkey_prefix))) { + // target_part_level = PARTITION_LEVEL_MAX; + LOG_WARN("fail to check whether presetting partition key matches rowkey prefix", KR(ret), KPC(this)); + } else if (match_rowkey_prefix) { + // when trigger auto partitioning, the non-partitioned table will be set as partitioned table + target_part_level = PARTITION_LEVEL_ONE; + } else { + // when trigger auto partitioning, the non-partitioned table will be set as sub-partitioned table + target_part_level = PARTITION_LEVEL_TWO; + } + } else if (OB_FAIL(is_partition_key_match_rowkey_prefix(match_rowkey_prefix))) { + // target_part_level = PARTITION_LEVEL_MAX; + LOG_WARN("fail to check primary key match partition column", KR(ret), KPC(this)); + } else if (part_level_ == PARTITION_LEVEL_ONE) { + if (match_rowkey_prefix) { + // when trigger auto partitioning, the partition will be split into two partitions + target_part_level = PARTITION_LEVEL_ONE; + } else { + // when trigger auto partitioning, the partitioned table will be set as sub-partitioned table, + target_part_level = PARTITION_LEVEL_TWO; + } + } else if (part_level_ == PARTITION_LEVEL_TWO) { + if (match_rowkey_prefix) { + // when trigger auto partitioning, the subpartition will be split into two subpartitions + target_part_level = PARTITION_LEVEL_TWO; + } else { + // not allow to split + // target_part_level = PARTITION_LEVEL_MAX; + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get target part level from a subpartitioned table" + "with mismatching between partition key, subpartition key and primary key prefix", + KR(ret), KPC(this)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get invalid part level", KR(ret), K(part_level_)); + } + } else { + // target_part_level = PARTITION_LEVEL_MAX + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get target part level from a non-auto-partitioned table", KR(ret), KPC(this)); + } + + return target_part_level; +} + +int ObTableSchema::check_validity_for_auto_partition() const +{ + int ret = OB_SUCCESS; + if (is_auto_partitioned_table()) { + if (OB_FAIL(check_enable_split_partition(true /*is_auto_partitioning*/))) { + LOG_WARN("fail to check enable split partition", KR(ret)); + } + } + return ret; +} + +int ObTableSchema::check_can_do_manual_split_partition() const +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(check_enable_split_partition(false /*is_auto_partitioning*/))) { + LOG_WARN("fail to check enable split partition", KR(ret)); + } + + return ret; +} + +// 1. not support data version which is lower than 4.4 +// 2. not support to split partition of sys_table/local_index/domain_index/spatial_index/lob +// 3. not support to split partition of no primary key table +// 4. not support to split partition of a table belong to tablegroup +// 5. not support to split partition of a table including spatial index or domain index +// 6. not support to split hash/list/interval partition +// 7. not support to split subpartition +// 8. not support mismatching between partition key and primary key prefix +// 9. not support column store table to split partition +// 10. only support automatic partitioning global index tables in non user tables +int ObTableSchema::check_enable_split_partition(bool is_auto_partitioning) const +{ + int ret = OB_SUCCESS; + uint64_t data_version = 0; + bool is_table_column_store = false; + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id_, data_version))) { + LOG_WARN("fail to get min data version", KR(ret), K(tenant_id_)); + } else if (data_version < DATA_VERSION_4_3_4_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("current data version doesn't support to split partition", KR(ret), K(data_version)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "data version lower than 4.4 is"); + } else if (is_in_recyclebin()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split table in recyclebin", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "recyclebin table is"); + } else if (is_heap_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of no primary key table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "reorganizing table without primary key(s) is"); + } else if (OB_FAIL(get_is_column_store(is_table_column_store))) { + LOG_WARN("failed to get is column store", K(ret)); + } else if (is_table_column_store) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of column store table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "column store table is"); + } else if (is_user_table()) { + // check tablegroup and indexes of auto-partitioned data table + ObArray simple_index_infos; + + if (tablegroup_id_ != OB_INVALID_ID) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("split partition of a table in tablegroup is not supported", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition of a table in tablegroup is"); + } else if (OB_FAIL(get_simple_index_infos(simple_index_infos))) { + LOG_WARN("get_simple_index_infos failed", KR(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) { + if (is_spatial_index(simple_index_infos[i].index_type_)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support spatial index", KR(ret), K(simple_index_infos[i].index_type_)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition of a table with spatial index is"); + } else if (share::schema::is_fts_index(simple_index_infos[i].index_type_)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support fulltext index", KR(ret), K(simple_index_infos[i].index_type_)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition of a table with fulltext index is"); + } else if (share::schema::is_multivalue_index(simple_index_infos[i].index_type_)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support multivalue index", KR(ret), K(simple_index_infos[i].index_type_)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition of a table with multivalue index is"); + } else if (share::schema::is_vec_index(simple_index_infos[i].index_type_)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support vec index", KR(ret), K(simple_index_infos[i].index_type_)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition of a table with vec index is"); + } else if (INDEX_TYPE_DOMAIN_CTXCAT_DEPRECATED == simple_index_infos[i].index_type_) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support domain index", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split partition of a table with domain index is"); + } + } // end for + } + } else { // !is_user_table() + // 1. manual partition split is only supported for user-table + // 2. auto partition split is supported for user-table and global index + if (is_materialized_view() || is_mlog_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of materialized view or materialized view log table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "materialized view or materialized view log table is"); + } else if (is_index_table() && is_fts_index()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of fulltext index table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "fulltext index table is"); + } else if (is_index_table() && is_multivalue_index()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of multivalue index table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "multivalue index table is"); + } else if (is_index_table() && is_spatial_index()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of spatial index", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "spatial index is"); + } else if (is_index_table() && share::schema::is_vec_index(index_type_)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of vec index", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "spatial index is"); + } else if (is_tmp_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of temporary table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "temporary table is"); + } else if (is_external_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of external table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "external table is"); + } else if (is_aux_lob_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of auxiliary table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "auxiliary table is"); + } else if (is_aux_vp_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split a partition of auxiliary vertical partition table", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "vertical partition table is"); + } else if (is_auto_partitioning && is_global_index_table()) { + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table type", KR(ret), KPC(this)); + } + } + + ObPartitionLevel target_part_level = is_auto_partitioning ? + get_target_part_level_for_auto_partitioned_table() : + get_part_level(); + if (OB_FAIL(ret)) { + } else if (!is_valid_split_part_type()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("only support to split range or range columns partition", KR(ret), K(part_option_)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "hash/list/interval partition is"); + } else if (target_part_level != ObPartitionLevel::PARTITION_LEVEL_ONE) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to split subpartition", KR(ret), KPC(this)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "split subpartition is"); + } else if (!is_auto_partitioning) { + bool is_match_rowkey_prefix = false; + if (OB_FAIL(is_partition_key_match_rowkey_prefix(is_match_rowkey_prefix))) { + LOG_WARN("fail to check whether primary key prefix match partition columns", KR(ret)); + } else if (!is_match_rowkey_prefix) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("split partition should keep primary key prefix equal to partition key", KR(ret)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "mismatching between primary key prefix and partition key is"); + } + } + + return ret; +} + +// for auto-partitioned non-partitioned table, +// the empty part_func_expr means when the table/global_index triggers auto partitioning, +// the primary_keys/index_columns will be choosen as partition key. +// thus, if using_auto_partitioned_mode==true, we will generate the "possible" partition key +// for auto-partitioned non-partitioned table with empty part_func_expr +int ObTableSchema::get_part_func_expr_str(ObString &part_func_expr, common::ObIAllocator &allocator, + const bool using_auto_partitioned_mode) const +{ + int ret = OB_SUCCESS; + part_func_expr.reset(); + if (!part_option_.get_part_func_expr_str().empty()) { + if (OB_FAIL(ob_write_string(allocator, part_option_.get_part_func_expr_str(), + part_func_expr, true /*c_style*/))) { + LOG_WARN("fail to write string", KR(ret), KPC(this)); + } + } else if (is_auto_partitioned_table() && !is_partitioned_table() && + (is_user_table() || is_global_index_table()) && + using_auto_partitioned_mode) { + ObSqlString presetting_partition_key_str; + const ObRowkeyInfo &presetting_partition_keys = is_global_index_table() ? + get_index_info() : get_rowkey_info(); + for (int64_t i = 0; OB_SUCC(ret) && i < presetting_partition_keys.get_size(); ++i) { + const ObRowkeyColumn *partition_column = presetting_partition_keys.get_column(i); + const ObColumnSchemaV2 *column = nullptr; + if (OB_ISNULL(partition_column)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the partition key is NULL, ", KR(ret), K(i), K(presetting_partition_keys), KPC(this)); + } else if (is_shadow_column(partition_column->column_id_)) { + } else if (OB_ISNULL(column = get_column_schema(partition_column->column_id_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the column schema is NULL, ", KR(ret), KPC(partition_column), KPC(this)); + } else if (OB_FAIL(presetting_partition_key_str.append(column->get_column_name()))) { + LOG_WARN("fail to append str", KR(ret), KPC(column), KPC(this)); + } else if (i != presetting_partition_keys.get_size() - 1 && + OB_FAIL(presetting_partition_key_str.append(", "))) { + LOG_WARN("fail to append str", KR(ret), KPC(column), KPC(this)); + } + } + + if (OB_SUCC(ret)) { + if (OB_UNLIKELY(presetting_partition_key_str.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to acquire presetting partition keys", KR(ret), KPC(this)); + } else if (OB_FAIL(ob_write_string(allocator, presetting_partition_key_str.string(), + part_func_expr, true /*c_style*/))) { + LOG_WARN("fail to write string", KR(ret), KPC(this)); + } + } + } + + return ret; +} + +// if an auto-partitioned table is non-partitioned table, +// the "part_func_expr" of it records its presetting partition key. +// the presetting partition key will be set as partition key +// when the auto-partitioned table triggers partition splitting. +// if the part_func_expr is not empty, the columns of it are equal to presetting partition key; +// if the part_func_expr is empty, it means: +// 1. for user_table, the presetting partition key will always equal to "current" primary key, +// 2. for global_index, the presetting partition key will always equal to its index columns. +// Attention: +// due to we only allow user-table to set presetting key by using auto-partition clause, +// the presetting partition key of global index must be index columns (part_func_expr is empty). +int ObTableSchema::get_presetting_partition_keys(common::ObIArray &partition_key_ids) const +{ + int ret = OB_SUCCESS; + static const char DELIMITER = ','; + ObArenaAllocator alloc; + ObString part_func_str; + const ObString &ori_part_func_str = part_option_.get_part_func_expr_str(); + bool is_oracle_mode = false; + partition_key_ids.reset(); + + if (!is_auto_partitioned_table() || is_partitioned_table()) { + // only a auto-partitioned non-partitioned table has presetting partition key + ret = OB_OP_NOT_ALLOW; + LOG_WARN("attempt to get presetting partition key from invalid table", + KR(ret), K(is_auto_partitioned_table()), K(is_partitioned_table()), KPC(this)); + } else if (!is_user_table() && !is_global_index_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table type", KR(ret), KPC(this)); + } else if (ori_part_func_str.empty()) { + const ObRowkeyInfo &partition_keys = is_global_index_table() ? get_index_info() : get_rowkey_info(); + for (int64_t i = 0; OB_SUCC(ret) && i < partition_keys.get_size(); ++i) { + const ObRowkeyColumn *partition_column = partition_keys.get_column(i); + if (OB_ISNULL(partition_column)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the partition key is NULL, ", KR(ret), K(i), K(partition_keys), KPC(this)); + } else if (!is_shadow_column(partition_column->column_id_) && + OB_FAIL(partition_key_ids.push_back(partition_column->column_id_))) { + LOG_WARN("failed to push back rowkey column id", KR(ret), KPC(this)); + } + } + } else if (!is_user_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("only user-table could set presetting partition key specially", KR(ret), KPC(this)); + } else if (OB_FAIL(ob_write_string(alloc, ori_part_func_str, part_func_str, true /*c_style*/))) { + LOG_WARN("fail to write string", KR(ret), KPC(this)); + } else if (OB_FAIL(get_partition_keys_by_part_func_expr(part_func_str, partition_key_ids))) { + LOG_WARN("fail to get partition key", K(ret), K(part_func_str), K(ori_part_func_str)); + } + return ret; +} + +int ObTableSchema::get_partition_keys_by_part_func_expr(common::ObString &part_func_expr_str, common::ObIArray &partition_key_ids) const +{ + int ret = OB_SUCCESS; + static const char DELIMITER = ','; + bool is_oracle_mode = false; + + if (OB_FAIL(check_if_oracle_compat_mode(is_oracle_mode))) { + LOG_WARN("fail to check oracle mode", KR(ret)); + } else { + ObArray presetting_partition_keys; + const char quote = is_oracle_mode ? '\"' : '`'; + bool parse_over = false; + while (OB_SUCC(ret) && !parse_over) { + // attention: + // after calling split_on() for splitting string "a,b", + // the function will return "a" and set the origin string as "b"; + // if the string couldn't be split, the function will return empty string + ObString partition_key_name = part_func_expr_str.split_on(DELIMITER); + if (partition_key_name.empty()) { + parse_over = true; + partition_key_name = part_func_expr_str; + } + // trim quote + char* start = partition_key_name.ptr(); + char* end = partition_key_name.ptr() + partition_key_name.length() - 1; + int64_t length = partition_key_name.length(); + if (OB_NOT_NULL(start) && OB_NOT_NULL(end) && length > 0) { + if (*start == quote && *end == quote) { + length -= 2; + start++; + } else if (*start != quote && *end != quote) { + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part func str", KR(ret)); + } + if (OB_FAIL(ret)) { + } else if (FALSE_IT(partition_key_name.assign_ptr(start, length))) { + } else if (is_oracle_mode && FALSE_IT(str_toupper(partition_key_name.ptr(), + partition_key_name.length()))) { + // column name in oracle mode is capital + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(presetting_partition_keys.push_back(partition_key_name))) { + LOG_WARN("fail to push back", KR(ret), K(partition_key_name)); + } + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < presetting_partition_keys.count(); i++) { + const ObString& partition_key_name = presetting_partition_keys.at(i).trim(); + const ObColumnSchemaV2 *column = get_column_schema(partition_key_name); + + if (OB_ISNULL(column)) { + ret = OB_ERR_BAD_FIELD_ERROR; + LOG_WARN("fail to get column schema", KR(ret), K(partition_key_name)); + } else if (OB_FAIL(partition_key_ids.push_back(column->get_column_id()))) { + LOG_WARN("fail to push back", KR(ret), KPC(column)); + } + } + } + + return ret; +} + +int ObTableSchema::is_presetting_partition_key(const uint64_t partition_key_id, + bool &is_presetting_partition_key) const +{ + int ret = OB_SUCCESS; + ObArray partition_key_ids; + is_presetting_partition_key = false; + + if (OB_FAIL(get_presetting_partition_keys(partition_key_ids))) { + LOG_WARN("fail to get presetting partition key", KR(ret), KPC(this)); + } else { + for (int64_t i = 0; !is_presetting_partition_key && i < partition_key_ids.count(); i++) { + if (partition_key_id == partition_key_ids.at(i)) { + is_presetting_partition_key = true; + } + } + } + + return ret; +} + int ObTableSchema::check_primary_key_cover_partition_column() { int ret = OB_SUCCESS; @@ -7531,24 +8123,6 @@ int ObTableSchema::check_index_table_cover_partition_keys( } return ret; } -int ObTableSchema::check_auto_partition_valid() -{ - int ret = OB_SUCCESS; - if (!is_auto_partitioned_table()) { - } else { - bool is_prefix = false; - if (0 >= partition_key_info_.get_size()) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("none of partition key with primary key", KR(ret)); - } else if (OB_FAIL(is_partition_key_match_rowkey_prefix(is_prefix))) { - LOG_WARN("failed to check is prefix", KR(ret)); - } else if (!is_prefix) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("partition key not prefix of rowkey", KR(ret)); - } - } - return ret; -} int ObTableSchema::check_skip_index_valid() const { @@ -7594,9 +8168,13 @@ int ObTableSchema::check_skip_index_valid() const return ret; } -// Distinguish the following two scenarios: -// 1. For non-partitioned tables, return 0 directly; -// 2. For a partitioned table, and the first-level partition mode is key(), take the number of primary key columns; +// Distinguish the following three scenarios: +// 1. For a non-auto-partitioned non-partitioned table, return 0 directly; +// 2. For a auto-partitioned non-partitioned table +// 2.1: if its "part_func_expr" is not empty, calculate the number of presetting partition key +// 2.2: if its "part_func_expr" is empty, return index_column_num if it is global index, return +// rowkey_column_num if it is user-table +// 3. For a partitioned table, and the first-level partition mode is key(), take the number of primary key columns; // otherwise, calculate the number of expression vectors int ObTableSchema::calc_part_func_expr_num(int64_t &part_func_expr_num) const { @@ -7605,13 +8183,29 @@ int ObTableSchema::calc_part_func_expr_num(int64_t &part_func_expr_num) const if (PARTITION_LEVEL_MAX == part_level_) { ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid part level", K(ret), K_(part_level)); - } else if (PARTITION_LEVEL_ZERO == part_level_) { + } else if (PARTITION_LEVEL_ZERO == part_level_ && !is_auto_partitioned_table()) { part_func_expr_num = 0; } else { ObArray sub_columns; ObString table_func_expr_str = get_part_option().get_part_func_expr_str(); if (table_func_expr_str.empty()) { - if (is_key_part()) { + if (is_auto_partitioned_table()) { + // current auto-partitioned table only support range partition + if (is_partitioned_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("partitioned table without part_func_expr", KR(ret), KPC(this)); + } else if (!is_valid_split_part_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part type", KR(ret), KPC(this)); + } else if (is_global_index_table()) { + part_func_expr_num = get_index_column_num(); + } else if (is_user_table()) { + part_func_expr_num = get_rowkey_column_num(); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid auto-partitioned table", KR(ret), KPC(this)); + } + } else if (is_key_part()) { part_func_expr_num = get_rowkey_column_num(); } else { ret = OB_ERR_UNEXPECTED; @@ -7626,6 +8220,34 @@ int ObTableSchema::calc_part_func_expr_num(int64_t &part_func_expr_num) const return ret; } +int ObTableSchema::extract_actual_index_rowkey_columns_name(ObIArray &rowkey_columns_name) const +{ + int ret = OB_SUCCESS; + rowkey_columns_name.reset(); + if ((!is_global_index_table() && !is_global_local_index_table() && !is_local_unique_index_table()) + || is_spatial_index()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not expected index type", KR(ret), KPC(this)); + } else { + const ObColumnSchemaV2 *index_column = NULL; + const ObRowkeyColumn *index_key_column = NULL; + const ObIndexInfo &index_info = get_index_info(); + for (int64_t i = 0; OB_SUCC(ret) && i < index_info.get_size(); ++i) { + if (OB_ISNULL(index_key_column = index_info.get_column(i))) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("get index column failed", K(ret)); + } else if (OB_ISNULL(index_column = get_column_schema(index_key_column->column_id_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get index column schema failed", K(ret)); + } else if (index_column->is_hidden() || index_column->is_shadow_column()) { // do nothing + } else if (OB_FAIL(rowkey_columns_name.push_back(index_column->get_column_name()))) { + LOG_WARN("push back index column failed", K(ret)); + } + } + } + return ret; +} + // Distinguish the following two scenarios: // 1. For non-partitioned tables, return 0 directly; // 2. For the second-level partition table, and the second-level partition mode is key(), take the number of primary key columns; @@ -7860,22 +8482,77 @@ int ObTableSchema::delete_constraint(const ObString &constraint_name) return ret; } -int ObTableSchema::is_partition_key(uint64_t column_id, bool &result) const +int ObTableSchema::is_tbl_partition_key(const uint64_t column_id, bool &result, + const bool ignore_presetting_key) const { int ret = OB_SUCCESS; result = false; if (is_partitioned_table()) { if (OB_FAIL(get_partition_key_info().is_rowkey_column(column_id, result))) { - LOG_WARN("check is partition key failed", K(ret), K(column_id)); + LOG_WARN("check is partition key failed", KR(ret), K(column_id)); } else if (!result && PARTITION_LEVEL_TWO == get_part_level()) { if (OB_FAIL(get_subpartition_key_info().is_rowkey_column(column_id, result))) { - LOG_WARN("check is subpartition key failed", K(ret), K(column_id)); + LOG_WARN("check is subpartition key failed", KR(ret), K(column_id)); } } + } else if (is_auto_partitioned_table() && !ignore_presetting_key && + OB_FAIL(is_presetting_partition_key(column_id, result))) { + LOG_WARN("fail to check presetting partition key", KR(ret), K(column_id)); } return ret; } +int ObTableSchema::is_tbl_partition_key(const share::schema::ObColumnSchemaV2 &orig_column_schema, + bool& result, + const bool ignore_presetting_key) const +{ + int ret = OB_SUCCESS; + result = false; + + if (is_partitioned_table()) { + result = orig_column_schema.is_tbl_part_key_column(); + } else if (is_auto_partitioned_table() && !ignore_presetting_key && + OB_FAIL(is_presetting_partition_key(orig_column_schema.get_column_id(), + result))) { + LOG_WARN("fail to check presetting partition key", KR(ret), K(orig_column_schema)); + } + + return ret; +} + +int ObTableSchema::is_partition_key(const share::schema::ObColumnSchemaV2 &orig_column_schema, + bool& result, + const bool ignore_presetting_key) const +{ + int ret = OB_SUCCESS; + result = false; + + if (is_partitioned_table()) { + result = orig_column_schema.is_part_key_column(); + } else if (is_auto_partitioned_table() && !ignore_presetting_key && + OB_FAIL(is_presetting_partition_key(orig_column_schema.get_column_id(), + result))) { + LOG_WARN("fail to check presetting partition key", KR(ret), K(orig_column_schema)); + } + + return ret; +} + +int ObTableSchema::is_subpartition_key(const share::schema::ObColumnSchemaV2 &orig_column_schema, + bool& result, + const bool ignore_presetting_key) const +{ + int ret = OB_SUCCESS; + result = false; + UNUSED(ignore_presetting_key); + + if (PARTITION_LEVEL_TWO == get_part_level()) { + result = orig_column_schema.is_subpart_key_column(); + } + + return ret; +} + int ObTableSchema::set_simple_index_infos( const common::ObIArray &simple_index_infos) { @@ -8271,6 +8948,59 @@ int ObTableSchema::get_column_encodings(common::ObIArray &col_encodings return ret; } +int ObTableSchema::is_presetting_partition_key_match_rowkey_prefix(bool &is_prefix) const +{ + int ret = OB_SUCCESS; + is_prefix = false; + + if (is_auto_partitioned_table() && !is_partitioned_table()) { + ObArray presetting_partition_key_column_ids; + + if (part_option_.get_part_func_expr_str().empty()) { + // if user doesn't set presetting partition key, + // we will choose primary key as presetting partition key for data table and + // choose index columns as presetting partition key for global index + is_prefix = true; + } else if (OB_FAIL(get_presetting_partition_keys(presetting_partition_key_column_ids))) { + LOG_WARN("fail to get presetting partition keys", KR(ret), KPC(this)); + } else if (presetting_partition_key_column_ids.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid presetting partition key", KR(ret), KPC(this)); + } else { + ObArray rowkey_column_ids; + const ObRowkeyInfo &rowkey_info = get_rowkey_info(); + const ObRowkeyColumn *rowkey_column = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_info.get_size(); ++i) { + if (NULL == (rowkey_column = rowkey_info.get_column(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("The rowkey column is NULL, ", K(i)); + } else if (OB_FAIL(rowkey_column_ids.push_back(rowkey_column->column_id_))) { + LOG_WARN("failed to push back rowkey column id", KR(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (rowkey_column_ids.count() < presetting_partition_key_column_ids.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid column ids", KR(ret), K(rowkey_column_ids), K(presetting_partition_key_column_ids)); + } else { + is_prefix = true; + for (int64_t i = 0; is_prefix && OB_SUCC(ret) && i < presetting_partition_key_column_ids.count(); i++) { + uint64_t rowkey_column_id = rowkey_column_ids.at(i); + uint64_t presetting_partition_key_column_id = presetting_partition_key_column_ids.at(i); + if (rowkey_column_id != presetting_partition_key_column_id) { + is_prefix = false; + } + } // end for + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("only auto-partitioned non-partitioned table could call this function", KR(ret), KPC(this)); + } + + return ret; +} + int ObTableSchema::is_partition_key_match_rowkey_prefix(bool &is_prefix) const { int ret = OB_SUCCESS; @@ -8318,31 +9048,6 @@ int ObTableSchema::is_partition_key_match_rowkey_prefix(bool &is_prefix) const return ret; } -// get split partition key from rowkey, for auto partition table only -int ObTableSchema::generate_partition_key_from_rowkey(const ObRowkey &rowkey, - ObRowkey &partition_key) const -{ - int ret = OB_SUCCESS; - bool is_prefix = false; - partition_key = rowkey; - if (OB_UNLIKELY(!is_auto_partitioned_table())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("should be auto partitioned table", K(ret)); - } else if (OB_UNLIKELY(rowkey.get_obj_cnt() != get_rowkey_column_num())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("rowkey size not match rowkey column num", - K(ret), K(rowkey), K(get_rowkey_column_num())); - } else if (OB_FAIL(is_partition_key_match_rowkey_prefix(is_prefix))) { - LOG_WARN("failed to check is partition key match rowkey prefix", K(ret)); - } else if (!is_prefix) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("partition key should match rowkey prefix", K(ret)); - } else { - partition_key.assign(const_cast(rowkey.get_obj_ptr()), partition_key_info_.get_size()); - } - return ret; -} - int ObTableSchema::init_column_meta_array( common::ObIArray &meta_array) const { diff --git a/src/share/schema/ob_table_schema.h b/src/share/schema/ob_table_schema.h index fed366d3d..bae28cc7b 100644 --- a/src/share/schema/ob_table_schema.h +++ b/src/share/schema/ob_table_schema.h @@ -839,6 +839,9 @@ public: const ObTabletID &tablet_id, int64_t &part_id, int64_t &subpart_id) const; + int get_hidden_part_id_by_tablet_id( + const ObTabletID &tablet_id, + int64_t &part_id) const; /** * first_level_part_id represent the first level part id of subpartition, * otherwise its value is OB_INVALID_ID @@ -1302,6 +1305,7 @@ public: int reorder_column(const ObString &column_name, const bool is_first, const ObString &prev_column_name, const ObString &next_column_name); int add_aux_vp_tid(const uint64_t aux_vp_tid); int add_partition_key(const common::ObString &column_name); + int add_partition_key(const uint64_t column_id); int add_subpartition_key(const common::ObString &column_name); int add_zone(const common::ObString &zone); int set_view_definition(const common::ObString &view_definition); @@ -1317,6 +1321,10 @@ public: int delete_constraint(const common::ObString &constraint_name); // Copy all constraint information in src_schema int assign_constraint(const ObTableSchema &other); + int assign_partition_schema_without_auto_part_attr(const ObTableSchema &other); + int enable_auto_partition(const int64_t auto_part_size); + int detect_part_func_type(ObPartitionFuncType &part_func_type); + void forbid_auto_partition(); void clear_constraint(); int set_ttl_definition(const common::ObString &ttl_definition) { return deep_copy_str(ttl_definition, ttl_definition_); } int set_kv_attributes(const common::ObString &kv_attributes) { return deep_copy_str(kv_attributes, kv_attributes_); } @@ -1646,8 +1654,17 @@ public: virtual int alloc_partition(const ObPartition *&partition); virtual int alloc_partition(const ObSubPartition *&subpartition); + int check_enable_split_partition(bool is_auto_partitioning) const; + int check_validity_for_auto_partition() const; + int check_can_do_manual_split_partition() const; + ObPartitionLevel get_target_part_level_for_auto_partitioned_table() const; + int get_part_func_expr_str(ObString &part_func_expr, common::ObIAllocator &allocator, + const bool using_auto_partitioned_mode) const; + int get_presetting_partition_keys(common::ObIArray &partition_key_ids) const; + int get_partition_keys_by_part_func_expr(common::ObString &part_func_expr_str, common::ObIArray &partition_key_ids) const; + int extract_actual_index_rowkey_columns_name(ObIArray &rowkey_columns_name) const; + int is_presetting_partition_key(const uint64_t partition_key_id, bool &is_presetting_partition_key) const; int check_primary_key_cover_partition_column(); - int check_auto_partition_valid(); int check_rowkey_cover_partition_keys(const common::ObPartitionKeyInfo &part_key); int check_index_table_cover_partition_keys(const common::ObPartitionKeyInfo &part_key) const; int check_create_index_on_hidden_primary_key(const ObTableSchema &index_table) const; @@ -1657,7 +1674,21 @@ public: virtual int calc_part_func_expr_num(int64_t &part_func_expr_num) const; virtual int calc_subpart_func_expr_num(int64_t &subpart_func_expr_num) const; - int is_partition_key(uint64_t column_id, bool &result) const; + + // checking the column is partition key or subpartition key. + // if the ignore_presetting_key == true, the following functions are equal to that of ObColumnSchemaV2, + // otherwise, they will check whether the column is presetting key. + int is_tbl_partition_key(const uint64_t column_id, bool &result, + const bool ignore_presetting_key=true) const; + int is_tbl_partition_key(const share::schema::ObColumnSchemaV2 &orig_column_schema, + bool& result, + const bool ignore_presetting_key=true) const; + int is_partition_key(const share::schema::ObColumnSchemaV2 &orig_column_schema, + bool& result, + const bool ignore_presetting_key=true) const; + int is_subpartition_key(const share::schema::ObColumnSchemaV2 &orig_column_schema, + bool& result, + const bool ignore_presetting_key=true) const; inline void reset_simple_index_infos() { simple_index_infos_.reset(); } inline const common::ObIArray &get_simple_index_infos() const { @@ -1721,14 +1752,13 @@ public: int get_all_cg_type_column_group(const ObColumnGroupSchema *&column_group) const; int get_each_column_group(ObIArray &each_cgs) const; int is_partition_key_match_rowkey_prefix(bool &is_prefix) const; + int is_presetting_partition_key_match_rowkey_prefix(bool &is_prefix) const; int get_column_group_index(const share::schema::ObColumnParam ¶m, const bool need_calculate_cg_idx, int32_t &cg_idx) const; int is_column_group_exist(const common::ObString &cg_name, bool &exist) const; int get_all_column_ids(ObIArray &column_ids) const; - int generate_partition_key_from_rowkey(const common::ObRowkey &rowkey, - common::ObRowkey &hign_bound_value) const; virtual int init_column_meta_array( common::ObIArray &meta_array) const override; int check_column_can_be_altered_online(const ObColumnSchemaV2 *src_schema, @@ -1922,6 +1952,7 @@ private: const common::hash::ObHashMap &column_id_map, ObRowkeyInfo &rowkey_info); int alter_view_column_internal(ObColumnSchemaV2 &column_schema); + int add_partition_key_(ObColumnSchemaV2 &column); int get_base_rowkey_column_group_index(int32_t &cg_idx) const; int calc_column_group_index_(const uint64_t column_id, int32_t &cg_idx) const; @@ -2102,9 +2133,7 @@ inline bool ObSimpleTableSchemaV2::is_global_unique_index_table(const ObIndexTyp inline bool ObSimpleTableSchemaV2::is_local_unique_index_table() const { // - return INDEX_TYPE_UNIQUE_LOCAL == index_type_ - || INDEX_TYPE_UNIQUE_GLOBAL_LOCAL_STORAGE == index_type_ - || INDEX_TYPE_UNIQUE_MULTIVALUE_LOCAL == index_type_; + return share::schema::is_local_unique_index_table(index_type_); } inline bool ObSimpleTableSchemaV2::is_global_local_index_table() const diff --git a/src/share/schema/ob_table_sql_service.cpp b/src/share/schema/ob_table_sql_service.cpp index dac5a0ede..f0449e236 100644 --- a/src/share/schema/ob_table_sql_service.cpp +++ b/src/share/schema/ob_table_sql_service.cpp @@ -2669,6 +2669,76 @@ int ObTableSqlService::update_index_status( return ret; } + +int ObTableSqlService::update_index_type(const ObTableSchema &data_table_schema, + const uint64_t index_table_id, + const ObIndexType index_type, + const int64_t new_schema_version, + const common::ObString *ddl_stmt_str, + common::ObISQLClient &sql_client) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = data_table_schema.get_tenant_id(); + const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); + ObDMLSqlSplicer dml; + int64_t affected_rows = 0; + const char *table_name = NULL; + + if (OB_INVALID_ID == index_table_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(index_table_id)); + } else if (OB_FAIL(check_ddl_allowed(data_table_schema))) { + LOG_WARN("check ddl allowd failed", K(ret), K(data_table_schema)); + } else if (OB_FAIL(dml.add_pk_column("tenant_id", ObSchemaUtils::get_extract_tenant_id( + exec_tenant_id, tenant_id))) + || OB_FAIL(dml.add_pk_column("table_id", ObSchemaUtils::get_extract_schema_id( + exec_tenant_id, index_table_id))) + || OB_FAIL(dml.add_column("schema_version", new_schema_version)) + || OB_FAIL(dml.add_column("index_type", index_type))) { + LOG_WARN("add column failed", K(ret)); + } else if (OB_FAIL(ObSchemaUtils::get_all_table_name(exec_tenant_id, table_name))) { + LOG_WARN("fail to get all table name", K(ret), K(exec_tenant_id)); + } else if (OB_FAIL(exec_update(sql_client, tenant_id, index_table_id, table_name, dml, affected_rows))) { + LOG_WARN("exec update failed", K(ret)); + } else if (affected_rows != 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", K(affected_rows), K(ret)); + } + + if (OB_SUCC(ret)) { + ObTableSchema index_schema; + ObRefreshSchemaStatus schema_status; + schema_status.tenant_id_ = tenant_id; + if (OB_FAIL(schema_service_.get_table_schema_from_inner_table(schema_status, index_table_id, sql_client, index_schema))) { + LOG_WARN("get_table_schema failed", K(index_table_id), K(ret)); + } else { + const bool update_object_status_ignore_version = false; + const bool only_history = true; + index_schema.set_index_type(index_type); + index_schema.set_schema_version(new_schema_version); + index_schema.set_in_offline_ddl_white_list(data_table_schema.get_in_offline_ddl_white_list()); + if (OB_FAIL(add_table(sql_client, index_schema, update_object_status_ignore_version, only_history))) { + LOG_WARN("add_table failed", K(index_schema), K(only_history), K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + ObSchemaOperation opt; + opt.tenant_id_ = tenant_id; + opt.database_id_ = 0; + opt.tablegroup_id_ = 0; + opt.table_id_ = index_table_id; + opt.op_type_ = OB_DDL_MODIFY_INDEX_TYPE; + opt.schema_version_ = new_schema_version; + opt.ddl_stmt_str_ = ddl_stmt_str ? *ddl_stmt_str : ObString(); + if (OB_FAIL(log_operation_wrapper(opt, sql_client))) { + LOG_WARN("log operation failed", K(opt), K(ret)); + } + } + return ret; +} + int ObTableSqlService::update_mview_status( const ObTableSchema &mview_table_schema, common::ObISQLClient &sql_client) @@ -3048,8 +3118,14 @@ int ObTableSqlService::gen_table_dml( LOG_WARN("fail to check table option", K(ret), K(table)); } else if (data_version < DATA_VERSION_4_1_0_0 && 0 != table.get_table_flags()) { ret = OB_NOT_SUPPORTED; - LOG_WARN("table flags is not suppported when tenant's data version is below 4.1.0.0", KR(ret), + LOG_WARN("table flags is not supported when tenant's data version is below 4.1.0.0", KR(ret), K(table)); + } else if (data_version < DATA_VERSION_4_3_4_0 && + (table.get_part_option().get_auto_part() == true || + table.get_part_option().get_auto_part_size() >= ObPartitionOption::MIN_AUTO_PART_SIZE)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("auto partition is not supported " + "when tenant's data version is below 4.4.0.0", KR(ret), K(table)); } else if (OB_FAIL(check_column_store_valid(table, data_version))) { LOG_WARN("fail to check column store valid", KR(ret), K(table), K(data_version)); } else if (data_version < DATA_VERSION_4_3_3_0 && table.get_micro_index_clustered()) { @@ -3124,12 +3200,12 @@ int ObTableSqlService::gen_table_dml( || OB_FAIL(dml.add_column("tablespace_id", ObSchemaUtils::get_extract_schema_id( exec_tenant_id, table.get_tablespace_id()))) // To avoid compatibility problems (such as error while upgrade virtual schema) in upgrade post stage, - // cluster version judgemenet is needed if columns are added in upgrade post stage. + // cluster version judgement is needed if columns are added in upgrade post stage. || OB_FAIL(dml.add_column("sub_part_template_flags", table.get_sub_part_template_flags())) || OB_FAIL(dml.add_column("dop", table.get_dop())) || OB_FAIL(dml.add_column("character_set_client", table.get_view_schema().get_character_set_client())) || OB_FAIL(dml.add_column("collation_connection", table.get_view_schema().get_collation_connection())) - || OB_FAIL(dml.add_column("auto_part", table.get_part_option().is_auto_range_part())) + || OB_FAIL(dml.add_column("auto_part", table.get_part_option().get_auto_part())) || OB_FAIL(dml.add_column("auto_part_size", table.get_part_option().get_auto_part_size())) || OB_FAIL(dml.add_column("association_table_id", ObSchemaUtils::get_extract_schema_id( exec_tenant_id, table.get_association_table_id()))) @@ -3246,8 +3322,14 @@ int ObTableSqlService::gen_table_options_dml( LOG_WARN("fail to check table option", K(ret), K(table)); } else if (data_version < DATA_VERSION_4_1_0_0 && 0 != table.get_table_flags()) { ret = OB_NOT_SUPPORTED; - LOG_WARN("table flags is not suppported when tenant's data version is below 4.1.0.0", KR(ret), + LOG_WARN("table flags is not supported when tenant's data version is below 4.1.0.0", KR(ret), K(table)); + } else if (data_version < DATA_VERSION_4_3_4_0 && + (table.get_part_option().get_auto_part() == true || + table.get_part_option().get_auto_part_size() >= ObPartitionOption::MIN_AUTO_PART_SIZE)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("auto partition is not supported " + "when tenant's data version is below 4.4.0.0", KR(ret), K(table)); } else if (data_version < DATA_VERSION_4_1_0_0 && OB_UNLIKELY(table.view_column_filled())) { ret = OB_NOT_SUPPORTED; LOG_WARN("option is not support before 4.1", K(ret), K(table)); @@ -3299,9 +3381,9 @@ int ObTableSqlService::gen_table_options_dml( || OB_FAIL(dml.add_column("tablespace_id", ObSchemaUtils::get_extract_schema_id( exec_tenant_id, table.get_tablespace_id()))) // To avoid compatibility problems (such as error while upgrade virtual schema) in upgrade post stage, - // cluster version judgemenet is needed if columns are added in upgrade post stage. + // cluster version judgement is needed if columns are added in upgrade post stage. || OB_FAIL(dml.add_column("sub_part_template_flags", table.get_sub_part_template_flags())) - || OB_FAIL(dml.add_column("auto_part", table.get_part_option().is_auto_range_part())) + || OB_FAIL(dml.add_column("auto_part", table.get_part_option().get_auto_part())) || OB_FAIL(dml.add_column("auto_part_size", table.get_part_option().get_auto_part_size())) || OB_FAIL(dml.add_column("max_dependency_version", table.get_max_dependency_version())) || OB_FAIL(dml.add_column("dop", table.get_dop())) @@ -3480,8 +3562,14 @@ int ObTableSqlService::gen_partition_option_dml(const ObTableSchema &table, ObDM LOG_WARN("fail to get min data version", K(ret)); } else if (data_version < DATA_VERSION_4_1_0_0 && 0 != table.get_table_flags()) { ret = OB_NOT_SUPPORTED; - LOG_WARN("table flags is not suppported when tenant's data version is below 4.1.0.0", KR(ret), + LOG_WARN("table flags is not supported when tenant's data version is below 4.1.0.0", KR(ret), K(table)); + } else if (data_version < DATA_VERSION_4_3_4_0 && + (table.get_part_option().get_auto_part() == true || + table.get_part_option().get_auto_part_size() >= ObPartitionOption::MIN_AUTO_PART_SIZE)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("auto partition is not supported " + "when tenant's data version is below 4.4.0.0", KR(ret), K(table)); } else if (OB_FAIL(dml.add_pk_column("tenant_id", ObSchemaUtils::get_extract_tenant_id( exec_tenant_id, tenant_id))) || OB_FAIL(dml.add_pk_column("table_id", ObSchemaUtils::get_extract_schema_id( @@ -3497,7 +3585,7 @@ int ObTableSqlService::gen_partition_option_dml(const ObTableSchema &table, ObDM || OB_FAIL(dml.add_column("partition_status", table.get_partition_status())) || OB_FAIL(dml.add_column("partition_schema_version", table.get_partition_schema_version())) || OB_FAIL(dml.add_column("sub_part_template_flags", table.get_sub_part_template_flags())) - || OB_FAIL(dml.add_column("auto_part", table.get_part_option().is_auto_range_part())) + || OB_FAIL(dml.add_column("auto_part", table.get_part_option().get_auto_part())) || OB_FAIL(dml.add_column("auto_part_size", table.get_part_option().get_auto_part_size())) || OB_FAIL(dml.add_gmt_create()) || (table.is_interval_part() && OB_FAIL(add_transition_point_val(dml, table))) @@ -3511,50 +3599,30 @@ int ObTableSqlService::gen_partition_option_dml(const ObTableSchema &table, ObDM } int ObTableSqlService::update_partition_option(ObISQLClient &sql_client, - ObTableSchema &table, + const ObTableSchema &table, const ObString *ddl_stmt_str) { int ret = OB_SUCCESS; - const uint64_t tenant_id = table.get_tenant_id(); - const uint64_t table_id = table.get_table_id(); ObDMLSqlSplicer dml; - const bool update_object_status_ignore_version = false; if (OB_FAIL(check_ddl_allowed(table))) { - LOG_WARN("check ddl allowd failed", K(ret), K(table)); + LOG_WARN("check ddl allowd failed", KR(ret), K(table)); } else if (OB_FAIL(gen_partition_option_dml(table, dml))) { - LOG_WARN("fail to gen dml", K(ret)); - } else { - int64_t affected_rows = 0; - const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); - const char *table_name = NULL; - if (OB_FAIL(ObSchemaUtils::get_all_table_name(exec_tenant_id, table_name))) { - LOG_WARN("fail to get all table name", K(ret), K(exec_tenant_id)); - } else if (OB_FAIL(exec_update(sql_client, tenant_id, table_id, - table_name, dml, affected_rows))) { - LOG_WARN("exec update failed", K(ret)); - } else if (affected_rows > 1) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", K(affected_rows), K(ret)); - } + LOG_WARN("fail to gen dml", KR(ret)); + } else if (OB_FAIL(update_partition_option_(sql_client, table, dml))) { + LOG_WARN("fail to update partition option", KR(ret), K(table)); } - // add updated table to __all_table_history if (OB_SUCC(ret)) { - const bool only_history = true; - if (OB_FAIL(add_table(sql_client, table, update_object_status_ignore_version, only_history))) { - LOG_WARN("add_table failed", K(table), K(only_history)); - } else { - ObSchemaOperation opt; - opt.tenant_id_ = tenant_id; - opt.database_id_ = table.get_database_id(); - opt.tablegroup_id_ = table.get_tablegroup_id(); - opt.table_id_ = table.get_table_id(); - opt.op_type_ = OB_DDL_ALTER_TABLE; - opt.schema_version_ = table.get_schema_version(); - opt.ddl_stmt_str_ = ddl_stmt_str ? *ddl_stmt_str : ObString(); - if (OB_FAIL(log_operation_wrapper(opt, sql_client))) { - LOG_WARN("log operation failed", K(opt), K(ret)); - } + ObSchemaOperation opt; + opt.tenant_id_ = table.get_tenant_id(); + opt.database_id_ = table.get_database_id(); + opt.tablegroup_id_ = table.get_tablegroup_id(); + opt.table_id_ = table.get_table_id(); + opt.op_type_ = OB_DDL_ALTER_TABLE; + opt.schema_version_ = table.get_schema_version(); + opt.ddl_stmt_str_ = ddl_stmt_str ? *ddl_stmt_str : ObString(); + if (OB_FAIL(log_operation_wrapper(opt, sql_client))) { + LOG_WARN("log operation failed", K(opt), KR(ret)); } } return ret; @@ -3565,40 +3633,84 @@ int ObTableSqlService::update_partition_option(ObISQLClient &sql_client, const int64_t new_schema_version) { int ret = OB_SUCCESS; - - const uint64_t tenant_id = table.get_tenant_id(); - const uint64_t table_id = table.get_table_id(); table.set_schema_version(new_schema_version); ObDMLSqlSplicer dml; + if (OB_FAIL(check_ddl_allowed(table))) { - LOG_WARN("check ddl allowd failed", K(ret), K(table)); + LOG_WARN("check ddl allowd failed", KR(ret), K(table)); } else if (OB_FAIL(gen_partition_option_dml(table, dml))) { - LOG_WARN("fail to gen dml", K(ret)); - } else { - int64_t affected_rows = 0; - const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); - const char *table_name = NULL; - if (OB_FAIL(ObSchemaUtils::get_all_table_name(exec_tenant_id, table_name))) { - LOG_WARN("fail to get all table name", K(ret), K(exec_tenant_id)); - } else if (OB_FAIL(exec_update(sql_client, tenant_id, table_id, - table_name, dml, affected_rows))) { - LOG_WARN("exec update failed", K(ret)); - } else if (affected_rows > 1) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected error", K(affected_rows), K(ret)); + LOG_WARN("fail to gen dml", KR(ret)); + } else if (OB_FAIL(update_partition_option_(sql_client, table, dml))) { + LOG_WARN("fail to update partition option", KR(ret), K(table)); + } + return ret; +} + +int ObTableSqlService::update_splitting_partition_option(ObISQLClient &sql_client, + const ObTableSchema &table) +{ + int ret = OB_SUCCESS; + ObDMLSqlSplicer dml; + + if (OB_FAIL(check_ddl_allowed(table))) { + LOG_WARN("check ddl allowd failed", KR(ret), K(table)); + } else if (OB_FAIL(gen_partition_option_dml(table, dml))) { + LOG_WARN("fail to gen dml", KR(ret)); + } else if (OB_FAIL(dml.add_column("tablet_id", table.get_tablet_id().id()))) { + // when first auto partitions non-partitioned table, + // the tablet_id record should be set as INVALID_TABLET_ID like partitioned_table + LOG_WARN("add column failed", KR(ret)); + } else if (OB_FAIL(update_partition_option_(sql_client, table, dml))) { + LOG_WARN("fail to update partition option", KR(ret), K(table)); + } + + if (OB_SUCC(ret)) { + ObSchemaOperation opt; + opt.tenant_id_ = table.get_tenant_id(); + opt.database_id_ = table.get_database_id(); + opt.tablegroup_id_ = table.get_tablegroup_id(); + opt.table_id_ = table.get_table_id(); + opt.op_type_ = OB_DDL_SPLIT_PARTITION; + opt.schema_version_ = table.get_schema_version(); + if (OB_FAIL(log_operation_wrapper(opt, sql_client))) { + LOG_WARN("log operation failed", K(opt), KR(ret)); } } + return ret; +} + +int ObTableSqlService::update_partition_option_(ObISQLClient &sql_client, + const ObTableSchema &table, + ObDMLSqlSplicer &dml) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table.get_tenant_id(); + const uint64_t exec_tenant_id = ObSchemaUtils::get_exec_tenant_id(tenant_id); + const uint64_t table_id = table.get_table_id(); + int64_t affected_rows = 0; + const char *table_name = NULL; + + if (OB_FAIL(ObSchemaUtils::get_all_table_name(exec_tenant_id, table_name))) { + LOG_WARN("fail to get all table name", KR(ret), K(exec_tenant_id)); + } else if (OB_FAIL(exec_update(sql_client, tenant_id, table_id, + table_name, dml, affected_rows))) { + LOG_WARN("exec update failed", KR(ret)); + } else if (affected_rows > 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", K(affected_rows), KR(ret)); + } // add updated table to __all_table_history if (OB_SUCC(ret)) { const bool only_history = true; const bool update_object_status_ignore_version = false; if (OB_FAIL(add_table(sql_client, table, update_object_status_ignore_version, only_history))) { - LOG_WARN("add_table failed", K(table), K(only_history)); + LOG_WARN("add_table failed", KR(ret), K(table), K(only_history)); } else {} } return ret; } + int ObTableSqlService::update_all_part_for_subpart(ObISQLClient &sql_client, const ObTableSchema &table, const ObIArray &update_part_array) @@ -4581,7 +4693,7 @@ int ObTableSqlService::add_inc_partition_info( const ObTableSchema &ori_table, ObTableSchema &inc_table, const int64_t schema_version, - bool is_truncate_table, + bool ignore_log_operation, bool is_subpart) { int ret = OB_SUCCESS; @@ -4597,7 +4709,7 @@ int ObTableSqlService::add_inc_partition_info( ori_table, inc_table, schema_version, - is_truncate_table))) { + ignore_log_operation))) { LOG_WARN("add inc subpart info failed", KR(ret)); } } @@ -4608,7 +4720,7 @@ int ObTableSqlService::add_inc_part_info(ObISQLClient &sql_client, const ObTableSchema &ori_table, const ObTableSchema &inc_table, const int64_t schema_version, - bool is_truncate_table) + bool ignore_log_operation) { int ret = OB_SUCCESS; if (OB_FAIL(check_ddl_allowed(ori_table))) { @@ -4624,7 +4736,7 @@ int ObTableSqlService::add_inc_part_info(ObISQLClient &sql_client, sql_client); if (OB_FAIL(part_helper.add_partition_info())) { LOG_WARN("add partition info failed", K(ret)); - } else if (!is_truncate_table && OB_INVALID_ID == ori_table.get_tablegroup_id()) { + } else if (!ignore_log_operation && OB_INVALID_ID == ori_table.get_tablegroup_id()) { /* * While table is in tablegroup, we only support to modify partition schema by tablegroup. * For tablegroup's partition modification, we only record tablegroup's ddl operation. @@ -4646,6 +4758,52 @@ int ObTableSqlService::add_inc_part_info(ObISQLClient &sql_client, return ret; } +int ObTableSqlService::add_split_inc_part_info(ObISQLClient &sql_client, + const ObTableSchema &ori_table, + const ObTableSchema &inc_table, + const int64_t schema_version) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(check_ddl_allowed(ori_table))) { + LOG_WARN("check ddl allowd failed", KR(ret), K(ori_table)); + } else if (OB_UNLIKELY(is_inner_table(ori_table.get_table_id()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table type", KR(ret), K(ori_table)); + } else { + ObAddSplitIncPartHelper part_helper(&ori_table, + &inc_table, + schema_version, + sql_client); + if (OB_FAIL(part_helper.add_split_partition_info())) { + LOG_WARN("add split partition info failed", KR(ret)); + } + } + return ret; +} + +int ObTableSqlService::update_part_info(ObISQLClient &sql_client, + const ObTableSchema &ori_table, + const ObTableSchema &upd_table, + const int64_t schema_version) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(check_ddl_allowed(ori_table))) { + LOG_WARN("check ddl allowd failed", K(ret), K(ori_table)); + } else if (is_inner_table(ori_table.get_table_id())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("fail to update split partition info of a inner table", K(ret), K(ori_table.get_table_id())); + } else { + const ObPartitionSchema *ori_table_schema = &ori_table; + const ObPartitionSchema *upd_table_schema = &upd_table; + ObUpdatePartHelper part_helper(ori_table_schema, upd_table_schema, + schema_version, sql_client); + if (OB_FAIL(part_helper.update_partition_info())) { + LOG_WARN("update split partition info failed", K(ret)); + } + } + return ret; +} + /* * add subpartition in non-template secondary partition table * [@input]: diff --git a/src/share/schema/ob_table_sql_service.h b/src/share/schema/ob_table_sql_service.h index ea06dcc1d..0ca76200a 100644 --- a/src/share/schema/ob_table_sql_service.h +++ b/src/share/schema/ob_table_sql_service.h @@ -65,7 +65,7 @@ public: const bool update_object_status_ignore_version, const common::ObString *ddl_stmt_str = nullptr); int update_partition_option(common::ObISQLClient &sql_client, - ObTableSchema &table, + const ObTableSchema &table, const common::ObString *ddl_stmt_str = NULL); int update_partition_option(common::ObISQLClient &sql_client, ObTableSchema &table, @@ -76,6 +76,8 @@ public: int update_all_part_for_subpart(ObISQLClient &sql_client, const ObTableSchema &table, const ObIArray &update_part_array); + int update_splitting_partition_option(common::ObISQLClient &sql_client, + const ObTableSchema &table); virtual int drop_table(const ObTableSchema &table_schema, const int64_t new_schema_version, @@ -137,6 +139,12 @@ public: const int64_t new_schema_version, common::ObISQLClient &sql_client, const common::ObString *ddl_stmt_str); + int update_index_type(const ObTableSchema &data_table_schema, + const uint64_t index_table_id, + const ObIndexType index_type, + const int64_t new_schema_version, + const common::ObString *ddl_stmt_str, + common::ObISQLClient &sql_client); virtual int update_mview_status(const ObTableSchema &mview_table_schema, common::ObISQLClient &sql_client); @@ -151,17 +159,25 @@ public: const ObTableSchema &ori_table, ObTableSchema &inc_table, const int64_t schema_version, - bool is_truncate_table, + bool ignore_log_operation, bool is_subpart); int add_inc_part_info(common::ObISQLClient &sql_client, const ObTableSchema &ori_table, const ObTableSchema &inc_table, const int64_t schema_version, - bool is_truncate_table); + bool ignore_log_operation); + int add_split_inc_part_info(common::ObISQLClient &sql_client, + const ObTableSchema &ori_table, + const ObTableSchema &inc_table, + const int64_t schema_version); int add_inc_subpart_info(common::ObISQLClient &sql_client, const ObTableSchema &ori_table, const ObTableSchema &inc_table, const int64_t schema_version); + int update_part_info(common::ObISQLClient &sql_client, + const ObTableSchema &ori_table, + const ObTableSchema &upd_table, + const int64_t schema_version); int rename_inc_part_info(common::ObISQLClient &sql_client, const ObTableSchema &ori_table, const ObTableSchema &inc_table, @@ -403,6 +419,9 @@ private: int delete_from_all_optstat_user_prefs(ObISQLClient &sql_client, const uint64_t tenant_id, const uint64_t table_id); + int update_partition_option_(ObISQLClient &sql_client, + const ObTableSchema &table, + ObDMLSqlSplicer &dml); public: int insert_column_ids_into_column_group(ObISQLClient &sql_client, diff --git a/src/share/table/ob_ttl_util.cpp b/src/share/table/ob_ttl_util.cpp index 366aadce7..c860721e4 100644 --- a/src/share/table/ob_ttl_util.cpp +++ b/src/share/table/ob_ttl_util.cpp @@ -1392,4 +1392,4 @@ bool ObTTLUtil::is_ttl_column(const ObString &orig_column_name, const ObIArray lookup_pushdown_filters; ObDASScanCtDef &scan_ctdef = spec.tsc_ctdef_.scan_ctdef_; ObDASScanCtDef *lookup_ctdef = spec.tsc_ctdef_.get_lookup_ctdef(); - if (op.use_index_merge()) { + if (OB_NOT_NULL(op.get_auto_split_filter())) { + ObRawExpr *auto_split_expr = const_cast(op.get_auto_split_filter()); + if (OB_FAIL(scan_pushdown_filters.push_back(auto_split_expr))) { + LOG_WARN("fail to push back auto split filter", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (op.use_index_merge()) { // full filters is used for final check when in index merge // we need to pushdown full filters to lookup as much as possible to avoid // the transmission of large results during DAS remote execution @@ -780,6 +787,19 @@ int ObTscCgService::extract_das_access_exprs(const ObLogTableScan &op, LOG_WARN("failed to append filter columns", K(ret)); } } + // extrace auto split filter column expr if need + if (OB_SUCC(ret)) { + if (OB_NOT_NULL(op.get_auto_split_filter())) { + ObArray auto_split_filter_columns; + ObRawExpr *auto_split_expr = const_cast(op.get_auto_split_filter()); + if (OB_FAIL(ObRawExprUtils::extract_column_exprs(auto_split_expr, + auto_split_filter_columns))) { + LOG_WARN("extract column exprs failed", K(ret)); + } else if (OB_FAIL(append_array_no_dup(access_exprs, auto_split_filter_columns))) { + LOG_WARN("append filter column to access exprs failed", K(ret)); + } + } + } // store group_id_expr when use group id if (OB_SUCC(ret) && op.use_group_id()) { const ObRawExpr* group_id_expr = op.get_group_id_expr(); @@ -788,7 +808,6 @@ int ObTscCgService::extract_das_access_exprs(const ObLogTableScan &op, LOG_WARN("failed to push back group id expr", K(ret)); } } - if (OB_SUCC(ret) && is_oracle_mapping_real_virtual_table(op.get_ref_table_id())) { //the access exprs are the agent virtual table columns, but das need the real table columns //now to replace the real table column @@ -1117,6 +1136,22 @@ int ObTscCgService::generate_das_scan_ctdef(const ObLogTableScan &op, } } + if (OB_SUCC(ret)) { + ObRawExpr *auto_split_expr = const_cast(op.get_auto_split_filter()); + const uint64_t auto_split_filter_type = op.get_auto_split_filter_type(); + if (OB_NOT_NULL(auto_split_expr) && OB_INVALID_ID != auto_split_filter_type) { + if (OB_FAIL(cg_.generate_rt_expr(*auto_split_expr, + scan_ctdef.pd_expr_spec_.auto_split_expr_))) { + LOG_WARN("generate auto split filter expr failed", K(ret)); + } else if (OB_FAIL(cg_.generate_rt_exprs(op.get_auto_split_params(), + scan_ctdef.pd_expr_spec_.auto_split_params_))) { + LOG_WARN("generate auto split params failed", K(ret)); + } else { + scan_ctdef.pd_expr_spec_.auto_split_filter_type_ = auto_split_filter_type; + } + } + } + //4. generate batch scan ctdef if (OB_SUCC(ret) && op.use_group_id()) { if (OB_FAIL(cg_.generate_rt_expr(*op.get_group_id_expr(), scan_ctdef.group_id_expr_))) { diff --git a/src/sql/das/ob_das_scan_op.cpp b/src/sql/das/ob_das_scan_op.cpp index afe908f93..1fdea00c8 100644 --- a/src/sql/das/ob_das_scan_op.cpp +++ b/src/sql/das/ob_das_scan_op.cpp @@ -291,6 +291,10 @@ int ObDASScanOp::init_scan_param() scan_param_.table_scan_opt_ = scan_ctdef_->table_scan_opt_; scan_param_.fb_snapshot_ = scan_rtdef_->fb_snapshot_; scan_param_.fb_read_tx_uncommitted_ = scan_rtdef_->fb_read_tx_uncommitted_; + scan_param_.auto_split_filter_type_ = scan_ctdef_->pd_expr_spec_.auto_split_filter_type_; + scan_param_.auto_split_filter_ = scan_ctdef_->pd_expr_spec_.auto_split_expr_; + scan_param_.auto_split_params_ = const_cast(&(scan_ctdef_->pd_expr_spec_.auto_split_params_)); + scan_param_.is_mds_query_ = false; scan_param_.main_table_scan_stat_.tsc_monitor_info_ = scan_rtdef_->tsc_monitor_info_; if (scan_rtdef_->is_for_foreign_check_) { diff --git a/src/sql/engine/basic/chunk_store/ob_chunk_block.cpp b/src/sql/engine/basic/chunk_store/ob_chunk_block.cpp index 2a4b3f67e..849456ab9 100644 --- a/src/sql/engine/basic/chunk_store/ob_chunk_block.cpp +++ b/src/sql/engine/basic/chunk_store/ob_chunk_block.cpp @@ -51,10 +51,16 @@ int ChunkRowMeta::init(const ObExprPtrIArray &exprs, const int32_t extra_size) LOG_WARN("get unexpected null pointer", K(ret)); } else if (is_fixed_length(e->datum_meta_.type_)) { int16_t len = get_type_fixed_length(e->datum_meta_.type_); - column_length_.at(i) = len; - column_offset_.at(i) = var_data_off_; - var_data_off_ += len; - fixed_cnt_++; + if (len <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fixed column len should larger than zero", + K(ret), K(len), K(e->datum_meta_.type_)); + } else { + column_length_.at(i) = len; + column_offset_.at(i) = var_data_off_; + var_data_off_ += len; + fixed_cnt_++; + } } else { column_length_.at(i) = 0; column_offset_.at(i) = 0; @@ -101,10 +107,16 @@ int ChunkRowMeta::init(const ObIArray &col_array, fixed_cnt_++; } else if (is_fixed_length(col_array.at(i).col_type_.get_type())) { int16_t len = get_type_fixed_length(col_array.at(i).col_type_.get_type()); - column_length_.at(i) = len; - column_offset_.at(i) = var_data_off_; - var_data_off_ += len; - fixed_cnt_++; + if (len <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fixed column len should larger than zero", + K(ret), K(len), K(col_array.at(i).col_type_.get_type())); + } else { + column_length_.at(i) = len; + column_offset_.at(i) = var_data_off_; + var_data_off_ += len; + fixed_cnt_++; + } } else { column_length_.at(i) = 0; column_offset_.at(i) = 0; diff --git a/src/sql/engine/basic/ob_pushdown_filter.cpp b/src/sql/engine/basic/ob_pushdown_filter.cpp index 5754d56c0..53b5a30ee 100644 --- a/src/sql/engine/basic/ob_pushdown_filter.cpp +++ b/src/sql/engine/basic/ob_pushdown_filter.cpp @@ -365,6 +365,13 @@ int ObPushdownFilterConstructor::is_white_mode(const ObRawExpr* raw_expr, bool & break; } } + // for auto split local index query filter + if (OB_SUCC(ret)) { + if (raw_expr->has_flag(IS_AUTO_PART_EXPR)) { + is_white = false; + LOG_DEBUG("has flag: is_auto_part_expr, dont go white filter"); + } + } return ret; } @@ -376,6 +383,7 @@ int ObPushdownFilterConstructor::create_black_filter_node( ObExpr *expr = nullptr; ObSEArray column_exprs; ObPushdownBlackFilterNode *black_filter_node = nullptr; + if (OB_ISNULL(raw_expr)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid null raw expr", K(ret)); @@ -1156,6 +1164,7 @@ int ObPushdownFilterExecutor::init_filter_param( const bool need_padding) { int ret = OB_SUCCESS; + const ObIArray &col_ids = get_col_ids(); const int64_t col_count = col_ids.count(); if (is_filter_node()) { @@ -1227,7 +1236,6 @@ int ObPushdownFilterExecutor::init_filter_param( } } } - if (OB_SUCC(ret)) { n_cols_ = col_count; } diff --git a/src/sql/engine/basic/ob_pushdown_filter.h b/src/sql/engine/basic/ob_pushdown_filter.h index 7f4c76214..250b77c63 100644 --- a/src/sql/engine/basic/ob_pushdown_filter.h +++ b/src/sql/engine/basic/ob_pushdown_filter.h @@ -51,6 +51,7 @@ class ObIMicroBlockRowScanner; namespace sql { class ObRawExpr; +class ObPseudoColumnRawExpr; class ObOpRawExpr; class ObExprOperatorCtx; class ObStaticEngineCG; diff --git a/src/sql/engine/cmd/ob_index_executor.cpp b/src/sql/engine/cmd/ob_index_executor.cpp index 94ff6e028..a72f0d8d5 100644 --- a/src/sql/engine/cmd/ob_index_executor.cpp +++ b/src/sql/engine/cmd/ob_index_executor.cpp @@ -28,6 +28,7 @@ #include "sql/resolver/ddl/ob_flashback_stmt.h" #include "observer/ob_server.h" #include "observer/ob_server_event_history_table_operator.h" +#include "storage/ob_partition_pre_split.h" using namespace oceanbase::common; namespace oceanbase @@ -56,6 +57,8 @@ int ObCreateIndexExecutor::execute(ObExecContext &ctx, ObCreateIndexStmt &stmt) obrpc::ObAlterTableRes res; ObString first_stmt; bool is_sync_ddl_user = false; + ObSArray index_arg_list; + ObPartitionPreSplit pre_split; ObArenaAllocator allocator("CreateIndexExec"); if (OB_FAIL(stmt.get_first_stmt(first_stmt))) { @@ -83,6 +86,11 @@ int ObCreateIndexExecutor::execute(ObExecContext &ctx, ObCreateIndexStmt &stmt) } else if (FALSE_IT(create_index_arg.is_inner_ = my_session->is_inner())) { } else if (FALSE_IT(create_index_arg.parallelism_ = stmt.get_parallelism())) { } else if (FALSE_IT(create_index_arg.consumer_group_id_ = THIS_WORKER.get_group_id())) { + } else if (OB_FAIL(index_arg_list.push_back(&create_index_arg))) { + LOG_WARN("fail to push back create index arg", K(ret)); + } else if (OB_FAIL(pre_split.get_global_index_pre_split_schema_if_need( + create_index_arg.tenant_id_, create_index_arg.session_id_, create_index_arg.database_name_, create_index_arg.table_name_, index_arg_list))) { + LOG_WARN("fail to get pre split query range", K(ret)); } else if (OB_FAIL(common_rpc_proxy->create_index(create_index_arg, res))) { //send the signal of creating index to rs LOG_WARN("rpc proxy create index failed", K(create_index_arg), "dst", common_rpc_proxy->get_server(), K(ret)); diff --git a/src/sql/engine/cmd/ob_table_executor.cpp b/src/sql/engine/cmd/ob_table_executor.cpp index 5b2c79ec0..0ff34cc2c 100644 --- a/src/sql/engine/cmd/ob_table_executor.cpp +++ b/src/sql/engine/cmd/ob_table_executor.cpp @@ -57,6 +57,8 @@ #include "share/ob_debug_sync.h" #include "share/schema/ob_schema_utils.h" #include "storage/mview/cmd/ob_mview_executor_util.h" +#include "storage/ob_partition_pre_split.h" + namespace oceanbase { using namespace common; @@ -868,8 +870,16 @@ int ObAlterTableExecutor::alter_table_rpc_v2( || obrpc::ObAlterTableArg::INTERVAL_TO_RANGE == alter_table_arg.alter_part_type_) { alter_table_arg.is_alter_partitions_ = true; } + ObPartitionPreSplit pre_split; + AlterTableSchema &alter_table_schema = const_cast(alter_table_arg.alter_table_schema_); if (OB_FAIL(populate_based_schema_obj_info_(alter_table_arg))) { LOG_WARN("fail to populate based schema obj info", KR(ret)); + } else if (OB_FAIL(pre_split.get_global_index_pre_split_schema_if_need(alter_table_schema.get_tenant_id(), + alter_table_arg.session_id_, + alter_table_schema.get_origin_database_name(), + alter_table_schema.get_origin_table_name(), + alter_table_arg.index_arg_list_))) { + LOG_WARN("fail to get pre split query range", K(ret), K(alter_table_arg)); } else if (OB_FAIL(common_rpc_proxy->alter_table(alter_table_arg, res))) { LOG_WARN("rpc proxy alter table failed", KR(ret), "dst", common_rpc_proxy->get_server(), K(alter_table_arg)); } else { @@ -1237,13 +1247,19 @@ int ObAlterTableExecutor::execute(ObExecContext &ctx, ObAlterTableStmt &stmt) } if (OB_SUCC(ret)) { + bool is_support_cancel = true; + if (obrpc::ObAlterTableArg::REORGANIZE_PARTITION == alter_table_arg.alter_part_type_ || + obrpc::ObAlterTableArg::SPLIT_PARTITION == alter_table_arg.alter_part_type_ || + obrpc::ObAlterTableArg::AUTO_SPLIT_PARTITION == alter_table_arg.alter_part_type_) { + is_support_cancel = false; + } const bool need_wait_ddl_finish = is_double_table_long_running_ddl(res.ddl_type_) || is_simple_table_long_running_ddl(res.ddl_type_); if (OB_SUCC(ret) && need_wait_ddl_finish) { int64_t affected_rows = 0; if (OB_FAIL(refresh_schema_for_table(alter_table_arg.exec_tenant_id_))) { LOG_WARN("refresh_schema_for_table failed", K(ret)); - } else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(tenant_id, res.task_id_, res.ddl_need_retry_at_executor_, my_session, common_rpc_proxy))) { + } else if (OB_FAIL(ObDDLExecutorUtil::wait_ddl_finish(tenant_id, res.task_id_, res.ddl_need_retry_at_executor_, my_session, common_rpc_proxy, is_support_cancel))) { LOG_WARN("fail to wait ddl finish", K(ret), K(tenant_id), K(res)); } } @@ -1804,17 +1820,38 @@ int ObAlterTableExecutor::check_alter_partition(ObExecContext &ctx, int ret = OB_SUCCESS; AlterTableSchema &table_schema = const_cast(arg.alter_table_schema_); - if (arg.is_alter_partitions_) { - if (obrpc::ObAlterTableArg::PARTITIONED_TABLE == arg.alter_part_type_ - || obrpc::ObAlterTableArg::REORGANIZE_PARTITION == arg.alter_part_type_ - || obrpc::ObAlterTableArg::SPLIT_PARTITION == arg.alter_part_type_) { + if (arg.is_alter_partitions_ || arg.alter_auto_partition_attr_) { + if (arg.is_manual_split_partition()) { + // if user does not define the last partition, part_num will be partition_num - 1, + // which means it is unnecessary that casting the expr value to last partition. + // after casting partition value, we need to correct part_num + int64_t part_num = table_schema.get_part_option().get_part_num(); ObPartition **partition_array = table_schema.get_part_array(); - int64_t realy_part_num = OB_INVALID_PARTITION_ID; - if (obrpc::ObAlterTableArg::SPLIT_PARTITION == arg.alter_part_type_) { - realy_part_num = table_schema.get_part_option().get_part_num(); - } else { - realy_part_num = table_schema.get_partition_num(); + if (part_num != table_schema.get_partition_num() && + part_num != table_schema.get_partition_num() - 1) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part num", K(ret), K(part_num), K(table_schema.get_partition_num())); + } else if (table_schema.is_valid_split_part_type()) { + if (OB_FAIL(ObPartitionExecutorUtils::set_range_part_high_bound(ctx, + stmt::T_CREATE_TABLE, + table_schema, + stmt, + false /*is_subpart*/))) { + LOG_WARN("partition_array is NULL", K(ret)); + } + } else { // split partition only support range partition now + ret = OB_NOT_SUPPORTED; + LOG_WARN("only support range part", K(ret), K(arg.alter_part_type_), + "partition type", table_schema.get_part_option().get_part_func_type()); } + + if (OB_FAIL(ret)) { + } else if (obrpc::ObAlterTableArg::SPLIT_PARTITION == arg.alter_part_type_) { + table_schema.get_part_option().set_part_num(table_schema.get_partition_num()); + } + } else if (obrpc::ObAlterTableArg::PARTITIONED_TABLE == arg.alter_part_type_) { + ObPartition **partition_array = table_schema.get_part_array(); + int64_t realy_part_num = table_schema.get_partition_num(); if (table_schema.is_range_part()) { if (OB_FAIL(ObPartitionExecutorUtils::set_range_part_high_bound(ctx, stmt::T_CREATE_TABLE, @@ -1837,14 +1874,6 @@ int ObAlterTableExecutor::check_alter_partition(ObExecContext &ctx, stmt.get_part_values_exprs()))) { LOG_WARN("partition_array is NULL", K(ret)); } - } else if (obrpc::ObAlterTableArg::PARTITIONED_TABLE != arg.alter_part_type_) { - ret = OB_ERR_ONLY_ON_RANGE_LIST_PARTITION; - LOG_WARN("only support range or list part", K(ret), K(arg.alter_part_type_), - "partition type", table_schema.get_part_option().get_part_func_type()); - } - if (OB_FAIL(ret)) { - } else if (obrpc::ObAlterTableArg::SPLIT_PARTITION == arg.alter_part_type_) { - const_cast(table_schema).get_part_option().set_part_num(table_schema.get_partition_num()); } } else if (obrpc::ObAlterTableArg::REPARTITION_TABLE == arg.alter_part_type_) { if (table_schema.is_range_part() || table_schema.is_list_part() diff --git a/src/sql/engine/expr/ob_expr_eval_functions.cpp b/src/sql/engine/expr/ob_expr_eval_functions.cpp index 72517e272..ba026408a 100644 --- a/src/sql/engine/expr/ob_expr_eval_functions.cpp +++ b/src/sql/engine/expr/ob_expr_eval_functions.cpp @@ -1200,8 +1200,8 @@ static ObExpr::EvalFunc g_expr_eval_functions[] = { ObExprTopNFilter::eval_topn_filter, /* 692 */ ObExprIsEnabledRole::eval_is_enabled_role, /* 693 */ ObExprCanAccessTrigger::can_access_trigger, /* 694 */ - NULL, //ObRelationalExprOperator::eval_min_max_compare, /* 695 */ - NULL, //ObRelationalExprOperator::min_max_row_eval, /* 696 */ + ObRelationalExprOperator::eval_min_max_compare, /* 695 */ + ObRelationalExprOperator::min_max_row_eval, /* 696 */ ObExprRbBuildEmpty::eval_rb_build_empty, /* 697 */ ObExprRbIsEmpty::eval_rb_is_empty, /* 698 */ ObExprRbBuildVarbinary::eval_rb_build_varbinary, /* 699 */ @@ -1400,7 +1400,7 @@ static ObExpr::EvalBatchFunc g_expr_eval_batch_functions[] = { ObBatchCast::implicit_batch_cast, /* 128 */ ObExprDecodeTraceId::calc_decode_trace_id_expr_batch, /* 129 */ ObExprTopNFilter::eval_topn_filter_batch, /* 130 */ - NULL,//ObRelationalExprOperator::eval_batch_min_max_compare, /* 131 */ + ObRelationalExprOperator::eval_batch_min_max_compare, /* 131 */ ObExprBM25::eval_batch_bm25_relevance_expr, /* 132 */ NULL,// ObExprAdd::add_vec_vec_batch, /* 133 */ NULL,// ObExprMinus::minus_vec_vec_batch, /* 134 */ @@ -1529,7 +1529,7 @@ static ObExpr::EvalVectorFunc g_expr_eval_vector_functions[] = { ObExprInOrNotIn::eval_vector_in_without_row, /* 110 */ NULL,//ObExprDecodeTraceId::calc_decode_trace_id_expr_vector /* 111 */ ObExprTopNFilter::eval_topn_filter_vector, /* 112 */ - NULL,//ObRelationalExprOperator::eval_vector_min_max_compare, /* 113 */ + ObRelationalExprOperator::eval_vector_min_max_compare, /* 113 */ ObExprCeilFloor::calc_ceil_floor_vector, /* 114 */ ObExprRepeat::eval_repeat_vector, /* 115 */ ObExprRegexpReplace::eval_hs_regexp_replace_vector, /* 116 */ diff --git a/src/sql/engine/expr/ob_expr_operator.cpp b/src/sql/engine/expr/ob_expr_operator.cpp index b9980dead..0d16cd6e8 100644 --- a/src/sql/engine/expr/ob_expr_operator.cpp +++ b/src/sql/engine/expr/ob_expr_operator.cpp @@ -37,6 +37,7 @@ #include "sql/engine/expr/ob_expr_func_round.h" #include "sql/engine/expr/ob_array_expr_utils.h" + namespace oceanbase { using namespace common; @@ -3314,6 +3315,233 @@ int ObRelationalExprOperator::eval_pl_udt_compare(const ObExpr &expr, return ret; } +int ObRelationalExprOperator::eval_min_max_compare( + const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum) +{ + int ret = OB_SUCCESS; + int cmp_ret = 0; + int is_set_null = false; + ObDatum *l_datum = NULL; + ObDatum *r_datum = NULL; + OZ(expr.eval_param_value(ctx, l_datum, r_datum)); + if (OB_SUCC(ret)) { + if (l_datum->is_outrow() || l_datum->is_ext() || + r_datum->is_outrow() || r_datum->is_ext()) { + LOG_DEBUG("is min max comparison"); + if (l_datum->is_null() || r_datum->is_null()) { + is_set_null = true; + expr_datum.set_null(); + } else if (OB_FAIL(get_min_max_cmp_ret(l_datum, r_datum, cmp_ret))) { + LOG_WARN("fail to get min max cmp ret"); + } else { + ObCmpOp cmp_op = get_cmp_op(expr.type_); + if (is_set_null) { + if (CO_NE == cmp_op) { + expr_datum.set_int(true); + } else if (CO_EQ == cmp_op) { + expr_datum.set_int(false); + } else { + expr_datum.set_null(); + } + } else { + expr_datum.set_int(is_expected_cmp_ret(cmp_op, cmp_ret)); + } + } + LOG_DEBUG("current compare object(ObDatum) min max status", + K(l_datum->is_outrow()), + K(l_datum->is_ext()), + K(r_datum->is_outrow()), + K(r_datum->is_ext())); + } else { + // normal process + LOG_DEBUG("is normal comparison"); + if (OB_ISNULL(expr.inner_functions_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null inner_eval_func in min max compare", K(ret)); + } else if (OB_ISNULL(expr.inner_functions_[0])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null pointer", K(ret)); + } else if (OB_FAIL(((ObExpr::EvalFunc)expr.inner_functions_[0])(expr, ctx, expr_datum))) { + LOG_WARN("fail to eval func", K(ret)); + } + } + } + return ret; +} + +int ObRelationalExprOperator::eval_batch_min_max_compare( + const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip, const int64_t batch_size) +{ + int ret = OB_SUCCESS; + + ObDatum *results = expr.locate_batch_datums(ctx); + const ObExpr &l_expr = *expr.args_[0]; + const ObExpr &r_expr = *expr.args_[1]; + ObBitVector &eval_flags = expr.get_evaluated_flags(ctx); + bool need_handle_ext = false; + + for (int64_t i = 0; i < batch_size; ++i) { + const ObDatum &l_datum = l_expr.is_batch_result() ? + l_expr.locate_batch_datums(ctx)[i] : l_expr.locate_expr_datum(ctx, 0); + const ObDatum &r_datum = r_expr.is_batch_result() ? + r_expr.locate_batch_datums(ctx)[i] : r_expr.locate_expr_datum(ctx, 0); + if (skip.at(i) || eval_flags.at(i)) { + continue; + } else if (l_datum.is_outrow() || l_datum.is_ext() || + r_datum.is_outrow() || r_datum.is_ext()) { + need_handle_ext = true; + break; + } + } + if (need_handle_ext) { // min max process + LOG_DEBUG("is min max comparison"); + for (int i = 0; OB_SUCC(ret) && i < batch_size; i++) { + int cmp_ret = 0; + const ObDatum &l_datum = l_expr.is_batch_result() ? + l_expr.locate_batch_datums(ctx)[i] : l_expr.locate_expr_datum(ctx, 0); + const ObDatum &r_datum = r_expr.is_batch_result() ? + r_expr.locate_batch_datums(ctx)[i] : r_expr.locate_expr_datum(ctx, 0); + + if (skip.at(i) || eval_flags.at(i)) { + continue; + } else if (l_datum.is_outrow() || l_datum.is_ext() || + r_datum.is_outrow() || r_datum.is_ext() ) { + if (l_datum.is_null() || r_datum.is_null()) { + results[i].set_null(); + eval_flags.set(i); + } else if (OB_FAIL(get_min_max_cmp_ret(&l_datum, &r_datum, cmp_ret))) { + LOG_WARN("fail to get min max cmp ret"); + } else { + results[i].set_int(is_expected_cmp_ret(get_cmp_op(expr.type_), cmp_ret)); + eval_flags.set(i); + } + LOG_DEBUG("current compare object(ObDatum) min max status", + K(l_datum.is_outrow()), + K(l_datum.is_ext()), + K(r_datum.is_outrow()), + K(r_datum.is_ext())); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect compare, it should be at lease one datum is ext", K(ret)); + } + } + } else { + LOG_DEBUG("is normal comparison"); + if (OB_ISNULL(expr.inner_functions_)) { // normal process + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null inner_eval_func in min max compare", K(ret)); + } else if (OB_ISNULL(expr.inner_functions_[1])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null pointer", K(ret)); + } else if (OB_FAIL(((ObExpr::EvalBatchFunc)expr.inner_functions_[1])(expr, ctx, skip, batch_size))) { + LOG_WARN("fail to eval func", K(ret)); + } + } + return ret; +} + +/* + 通过get_payload的方式可以获取obdatum的数据,但不能获取obdatum的is_ext的信息 + 这里从vec_uniform_const的向量里获取了is_ext属性,从get_payload里获取了obdatum数据。 +*/ +int ObRelationalExprOperator::eval_vector_min_max_compare( + const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip, const EvalBound &bound) +{ + int ret = OB_SUCCESS; + + ObBitVector &eval_flags = expr.get_evaluated_flags(ctx); + ObIVector *res_vec = expr.get_vector(ctx); + ObIVector *l_vec = nullptr; + ObIVector *r_vec = nullptr; + + if (OB_FAIL(expr.args_[0]->eval_vector(ctx, skip, bound))) { + LOG_WARN("failed to eval_vector", K(ret)); + } else if (OB_FAIL(expr.args_[1]->eval_vector(ctx, skip, bound))) { + LOG_WARN("failed to eval_vector", K(ret)); + } else if (FALSE_IT(l_vec = expr.args_[0]->get_vector(ctx))) { + } else if (FALSE_IT(r_vec = expr.args_[1]->get_vector(ctx))) { + } else if (OB_ISNULL(l_vec) || OB_ISNULL(r_vec)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to eval vector min max compare", KP(l_vec), K(r_vec)); + } else { + bool has_vec_uniform_const_type = + VEC_UNIFORM_CONST == l_vec->get_format() || VEC_UNIFORM_CONST == r_vec->get_format(); + + if (has_vec_uniform_const_type) { + ObUniformBase *uniform_l_vec = VEC_UNIFORM_CONST == l_vec->get_format() ? + static_cast(l_vec) : nullptr; + ObUniformBase *uniform_r_vec = VEC_UNIFORM_CONST == r_vec->get_format() ? + static_cast(r_vec) : nullptr; + const ObDatum *l_datums = nullptr == uniform_l_vec ? nullptr : uniform_l_vec->get_datums(); + const ObDatum *r_datums = nullptr == uniform_r_vec ? nullptr : uniform_r_vec->get_datums(); + bool need_handle_ext = false; + // find ext + if (nullptr != l_datums) { + need_handle_ext = l_datums[0].is_outrow() || l_datums[0].is_ext() ? true : false; + } else if (!need_handle_ext && nullptr != r_datums) { + need_handle_ext = r_datums[0].is_outrow() || r_datums[0].is_ext() ? true : false; + } + if (need_handle_ext) { + LOG_DEBUG("is min max comparison"); + for (int i = bound.start(); OB_SUCC(ret) && i < bound.end(); i++) { + int cmp_ret = 0; + const char *l_payload = NULL; + const char *r_payload = NULL; + ObLength l_len = 0; + ObLength r_len = 0; + // 1. datum from payload, to get is_null. + l_vec->get_payload(i, l_payload, l_len); + ObDatum l_tmp_datum(l_payload, l_len, l_vec->is_null(i)); + r_vec->get_payload(i, r_payload, r_len); + ObDatum r_tmp_datum(r_payload, r_len, r_vec->is_null(i)); + // 2. datum from payload, to get is_outrow or is_ext. + const ObDatum &l_datum = + VEC_UNIFORM_CONST == l_vec->get_format() ? l_datums[0] : l_tmp_datum; + const ObDatum &r_datum = + VEC_UNIFORM_CONST == r_vec->get_format() ? r_datums[0] : r_tmp_datum; + if (skip.at(i) || eval_flags.at(i)) { + continue; + } else if (l_datum.is_outrow() || l_datum.is_ext() || + r_datum.is_outrow() || r_datum.is_ext() ) { + if (l_datum.is_null() || r_datum.is_null()) { + res_vec->set_null(i); + eval_flags.set(i); + } else if (OB_FAIL(get_min_max_cmp_ret(&l_datum, &r_datum, cmp_ret))) { + LOG_WARN("fail to get min max cmp ret"); + } else { + res_vec->set_int(i, is_expected_cmp_ret(get_cmp_op(expr.type_), cmp_ret)); + eval_flags.set(i); + } + LOG_DEBUG("current compare object(ObDatum) min max status", + K(l_datum.is_outrow()), K(l_datum.is_ext()), + K(r_datum.is_outrow()), K(r_datum.is_ext())); + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpect compare, it should be at lease one datum is ext", K(ret)); + } + } + } else { + LOG_DEBUG("is normal comparison"); + if (OB_ISNULL(expr.inner_functions_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null inner_eval_func in min max compare", K(ret)); + } else if (OB_ISNULL(expr.inner_functions_[2])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null pointer", K(ret)); + } else if (OB_FAIL(((ObExpr::EvalVectorFunc)expr.inner_functions_[2])(expr, ctx, skip, bound))) { + LOG_WARN("fail to eval func", K(ret)); + } + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected format, auto split filter should has one VEC_UNIFORM_CONST type", + K(ret), K(l_vec->get_format()), K(r_vec->get_format())); + } + } + return ret; +} + + OB_SERIALIZE_MEMBER((ObSubQueryRelationalExpr, ObExprOperator), subquery_key_, left_is_iter_, @@ -6666,12 +6894,13 @@ int ObRelationalExprOperator::cg_expr(ObExprCGCtx &op_cg_ctx, } else if (row_dim > 0) { ret = cg_row_cmp_expr(row_dim, *op_cg_ctx.allocator_, raw_expr, input_types_,rt_expr); } else { - ret = cg_datum_cmp_expr(raw_expr, input_types_, rt_expr); + ret = cg_datum_cmp_expr(*op_cg_ctx.allocator_, raw_expr, input_types_, rt_expr); } return ret; } -int ObRelationalExprOperator::cg_datum_cmp_expr(const ObRawExpr &raw_expr, +int ObRelationalExprOperator::cg_datum_cmp_expr(ObIAllocator &allocator, + const ObRawExpr &raw_expr, const ObExprOperatorInputTypeArray &input_types, ObExpr &rt_expr) { @@ -6730,6 +6959,28 @@ int ObRelationalExprOperator::cg_datum_cmp_expr(const ObRawExpr &raw_expr, CK(NULL != rt_expr.eval_func_); CK(NULL != rt_expr.eval_batch_func_); CK(NULL != rt_expr.eval_vector_func_); + + if (OB_SUCC(ret)) { + if (raw_expr.has_flag(IS_AUTO_PART_EXPR)) { + LOG_DEBUG("set min or max compare func", K(cmp_op)); + void **inner_func_buf = NULL; + const int64_t inner_func_count = 3; + if (OB_ISNULL(inner_func_buf = (void **)allocator.alloc(sizeof(void *) * inner_func_count))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc memory for auto part expr inner function buf", K(ret)); + } else { + rt_expr.inner_functions_ = inner_func_buf; + rt_expr.inner_func_cnt_ = inner_func_count; + rt_expr.inner_functions_[0] = (void*)rt_expr.eval_func_; + rt_expr.inner_functions_[1] = (void*)rt_expr.eval_batch_func_; + rt_expr.inner_functions_[2] = (void*)rt_expr.eval_vector_func_; + // new + rt_expr.eval_func_ = &eval_min_max_compare; + rt_expr.eval_batch_func_ = &eval_batch_min_max_compare; + rt_expr.eval_vector_func_ = &eval_vector_min_max_compare; + } + } + } } return ret; } @@ -6814,7 +7065,12 @@ int ObRelationalExprOperator::cg_row_cmp_expr(const int row_dimension, } } // for end if (OB_SUCC(ret)) { - rt_expr.eval_func_ = &row_eval; + if (raw_expr.has_flag(IS_AUTO_PART_EXPR)) { + rt_expr.eval_func_ = &min_max_row_eval; + LOG_DEBUG("set min or max compare func", K(cmp_op)); + } else { + rt_expr.eval_func_ = &row_eval; + } } } } @@ -6924,6 +7180,154 @@ int ObRelationalExprOperator::row_cmp( return ret; } +int ObRelationalExprOperator::min_max_row_eval( + const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(2 != expr.arg_cnt_ + || NULL == expr.args_ + || expr.inner_func_cnt_ <= 0 + || expr.args_[0]->arg_cnt_ != expr.inner_func_cnt_ + || NULL == expr.args_[0]->args_ + || NULL == expr.args_[1]->args_ + || NULL == expr.inner_functions_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret)); + } else { + ObExpr *left_row = expr.args_[0]; + ObExpr *right_row = NULL; + if (1 == expr.args_[1]->arg_cnt_ && T_OP_ROW == expr.args_[1]->args_[0]->type_) { + if (expr.args_[1]->args_[0]->arg_cnt_ != expr.inner_func_cnt_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected arg cnt", K(ret), K(expr.inner_func_cnt_), + K(expr.args_[1]->args_[0]->arg_cnt_)); + } else { + right_row = expr.args_[1]->args_[0]; + } + } else if (OB_UNLIKELY(expr.inner_func_cnt_ != expr.args_[1]->arg_cnt_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected arg cnt", K(ret), K(expr.inner_func_cnt_), K(expr.args_[1]->arg_cnt_)); + } else { + right_row = expr.args_[1]; + } + ret = min_max_row_cmp(expr, expr_datum, left_row->args_, ctx, right_row->args_, ctx); + } + return ret; +} + +int ObRelationalExprOperator::min_max_row_cmp( + const ObExpr &expr, ObDatum &expr_datum, + ObExpr **l_row, ObEvalCtx &l_ctx, ObExpr **r_row, ObEvalCtx &r_ctx) +{ + // performance critical, do not check pointer validity. + int ret = OB_SUCCESS; + ObDatum *left = NULL; + ObDatum *right = NULL; + + bool cnt_row_null = false; + int first_nonequal_cmp_ret = 0; + int i = 0; + // locate first non-equal pair + for (; OB_SUCC(ret) && i < expr.inner_func_cnt_; i++) { + if (OB_FAIL(l_row[i]->eval(l_ctx, left))) { + if (OB_FAIL(try_get_inner_row_cmp_ret(ret, first_nonequal_cmp_ret))) { + LOG_WARN("failed to eval left in row cmp", K(ret)); + } else { + --i; + break; + } + } else if (left->is_null()) { + cnt_row_null = true; + } else if (OB_FAIL(r_row[i]->eval(r_ctx, right))) { + if (OB_FAIL(try_get_inner_row_cmp_ret(ret, first_nonequal_cmp_ret))) { + LOG_WARN("failed to eval right in row cmp", K(ret)); + } else { + --i; + break; + } + } else if (right->is_null()) { + cnt_row_null = true; + } else if (left->is_ext() || left->is_outrow() || right->is_ext() || right->is_outrow()) { + // is_outrow : min + // is_ext : max + if (OB_FAIL(get_min_max_cmp_ret(left, right, first_nonequal_cmp_ret))) { + LOG_WARN("fail to get min max cmp ret"); + } + } else if (OB_FAIL(((DatumCmpFunc)expr.inner_functions_[i])(*left, *right, first_nonequal_cmp_ret))) { + LOG_WARN("failed to cmp", K(ret)); + } else { + LOG_DEBUG("min max row cmp", + K(ret), K(left->is_ext()), K(left->is_outrow()), K(right->is_ext()), K(right->is_outrow())); + } + if (OB_SUCC(ret)) { + if (0 != first_nonequal_cmp_ret) { + break; + } + } + } // for end + ObCmpOp cmp_op = get_cmp_op(expr.type_); + if (OB_FAIL(ret)) { + // do nothing + } else if (i == expr.inner_func_cnt_) { + if (cnt_row_null) { + expr_datum.set_null(); + } else { + expr_datum.set_int(is_expected_cmp_ret(cmp_op, 0)); + } + } else { + if (cnt_row_null) { + if (CO_NE == cmp_op) { + expr_datum.set_int(true); + } else if (CO_EQ == cmp_op) { + expr_datum.set_int(false); + } else { + expr_datum.set_null(); + } + } else { + expr_datum.set_int( + is_expected_cmp_ret(cmp_op, first_nonequal_cmp_ret)); + } + } + return ret; +} + +int ObRelationalExprOperator::get_min_max_cmp_ret( + const ObDatum *left, const ObDatum *right, int &cmp_ret) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(left) || OB_ISNULL(right)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), KP(left), KP(right)); + } else { + bool is_left_min_or_max = left->is_ext() || left->is_outrow(); + bool is_right_min_or_max = right->is_ext() || right->is_outrow(); + if (is_left_min_or_max && !is_right_min_or_max) { // left is ext, right is not ext + if (left->is_ext()) { // left is max + cmp_ret = 1; + } else if (left->is_outrow()) { // left is min + cmp_ret = -1; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected cmp result", KPC(left), KPC(right)); + } + } else if (!is_left_min_or_max && is_right_min_or_max) { // left is not ext, right is ext + if (right->is_ext()) { // right is max + cmp_ret = -1; + } else if (right->is_outrow()) { // right is min + cmp_ret = 1; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected cmp result", KPC(left), KPC(right)); + } + } else { // left and right is all ext + // 在filter表达式过滤的场景里不可能出现left和right同时为is_ext的场景 + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected expr datum compare", K(ret), KPC(left), KPC(right)); + } + } + return ret; +} + template int ObRelationalExprOperator::try_get_inner_row_cmp_ret(const int ret_code, int &cmp_ret) { diff --git a/src/sql/engine/expr/ob_expr_operator.h b/src/sql/engine/expr/ob_expr_operator.h index 9edb0f1f0..38cbd056d 100644 --- a/src/sql/engine/expr/ob_expr_operator.h +++ b/src/sql/engine/expr/ob_expr_operator.h @@ -1275,7 +1275,8 @@ public: const ObRawExpr &raw_expr, const ObExprOperatorInputTypeArray &input_types, ObExpr &rt_expr); - static int cg_datum_cmp_expr(const ObRawExpr &raw_expr, + static int cg_datum_cmp_expr(common::ObIAllocator &allocator, + const ObRawExpr &raw_expr, const ObExprOperatorInputTypeArray &input_types, ObExpr &rt_expr); @@ -1286,9 +1287,18 @@ public: // CAUTION: null safe equal row compare is not included. static int row_cmp(const ObExpr &expr, ObDatum &expr_datum, ObExpr **l_row, ObEvalCtx &l_ctx, ObExpr **r_row, ObEvalCtx &r_ctx); + + // for auto split local index query + static int min_max_row_eval(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datm); + static int min_max_row_cmp(const ObExpr &expr, ObDatum &expr_datum, + ObExpr **l_row, ObEvalCtx &l_ctx, ObExpr **r_row, ObEvalCtx &r_ctx); + static int get_min_max_cmp_ret(const ObDatum *left, const ObDatum *right, int &cmp_ret); + template static int try_get_inner_row_cmp_ret(const int ret_code, int &cmp_ret); + + OB_INLINE static int get_comparator_operands( const ObExpr &expr, ObEvalCtx &ctx, @@ -1329,6 +1339,11 @@ public: static int eval_pl_udt_compare(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum); + // for auto split query + static int eval_min_max_compare(const ObExpr &expr, ObEvalCtx &ctx, ObDatum &expr_datum); + static int eval_batch_min_max_compare(const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip, const int64_t batch_size); + static int eval_vector_min_max_compare(const ObExpr &expr, ObEvalCtx &ctx, const ObBitVector &skip, const EvalBound &bound); + // get_const_cast_mode returns cast_mode for const/calculated params when compares with decimal type column // col is defined as number(10, 3) // 1. col >= 12.2341 <=> col >= 12.235 diff --git a/src/sql/engine/expr/ob_expr_pl_get_cursor_attr.cpp b/src/sql/engine/expr/ob_expr_pl_get_cursor_attr.cpp index b963b839a..91830cafe 100644 --- a/src/sql/engine/expr/ob_expr_pl_get_cursor_attr.cpp +++ b/src/sql/engine/expr/ob_expr_pl_get_cursor_attr.cpp @@ -268,7 +268,7 @@ int ObExprPLGetCursorAttr::calc_pl_get_cursor_attr( case pl::ObPLGetCursorAttrInfo::PL_CURSOR_ROWCOUNT: { if (OB_ISNULL(cursor)) { ret = OB_ERR_INVALID_CURSOR; - LOG_WARN("cursor is null", K(ret));; + LOG_WARN("cursor is null", K(ret)); } else { int64_t rowcount = 0; bool isnull = false; @@ -306,7 +306,7 @@ int ObExprPLGetCursorAttr::calc_pl_get_cursor_attr( case pl::ObPLGetCursorAttrInfo::PL_CURSOR_BULK_ROWCOUNT: { if (OB_ISNULL(cursor)) { ret = OB_ERR_INVALID_CURSOR; - LOG_WARN("cursor is null", K(ret));; + LOG_WARN("cursor is null", K(ret)); } else { int64_t index = datum->get_int(); int64_t rowcount = 0; diff --git a/src/sql/engine/px/ob_dfo.h b/src/sql/engine/px/ob_dfo.h index 6ece95b53..536127202 100644 --- a/src/sql/engine/px/ob_dfo.h +++ b/src/sql/engine/px/ob_dfo.h @@ -1048,7 +1048,6 @@ public: inline void set_execution_id(int64_t execution_id) { execution_id_ = execution_id; } inline int64_t get_execution_id() const { return execution_id_; } inline void set_result(int rc) { rc_ = rc; } - inline bool has_result() const { return rc_ <= 0; } inline int get_result() const { return rc_; } void set_das_retry_rc(int das_retry_rc) { das_retry_rc_ = (das_retry_rc_ == common::OB_SUCCESS ? das_retry_rc : das_retry_rc_); } diff --git a/src/sql/engine/px/ob_px_sqc_proxy.cpp b/src/sql/engine/px/ob_px_sqc_proxy.cpp index 717746928..97f64a1f9 100644 --- a/src/sql/engine/px/ob_px_sqc_proxy.cpp +++ b/src/sql/engine/px/ob_px_sqc_proxy.cpp @@ -365,25 +365,6 @@ int ObPxSQCProxy::get_part_ch_map(ObPxPartChInfo &map, int64_t timeout_ts) return ret; } -int ObPxSQCProxy::report_task_finish_status(int64_t task_idx, int rc) -{ - int ret = OB_SUCCESS; - auto &tasks = sqc_ctx_.get_tasks(); - if (task_idx < 0 || task_idx >= tasks.count()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid task idx", K(task_idx), K(tasks.count()), K(ret)); - } else { - ObPxTask &task = tasks.at(task_idx); - if (task.has_result()) { - ret = OB_ENTRY_EXIST; - LOG_WARN("task finish status already set", K(task), K(task_idx), K(rc), K(ret)); - } else { - task.set_result(rc); - } - } - return ret; -} - // only can be called by root thread int ObPxSQCProxy::check_task_finish_status(int64_t timeout_ts) { @@ -398,7 +379,7 @@ int ObPxSQCProxy::check_task_finish_status(int64_t timeout_ts) all_tasks_finish = true; ARRAY_FOREACH(tasks, idx) { ObPxTask &task = tasks.at(idx); - if (!task.has_result()) { + if (false == task.is_task_state_set(SQC_TASK_EXIT)) { all_tasks_finish = false; break; } diff --git a/src/sql/engine/px/ob_px_sqc_proxy.h b/src/sql/engine/px/ob_px_sqc_proxy.h index ee731426c..f647eb622 100644 --- a/src/sql/engine/px/ob_px_sqc_proxy.h +++ b/src/sql/engine/px/ob_px_sqc_proxy.h @@ -144,10 +144,6 @@ public: bool send_piece = true, bool need_wait_whole_msg = true); - - // 用于 worker 汇报执行结果 - int report_task_finish_status(int64_t task_idx, int rc); - // for root thread int check_task_finish_status(int64_t timeout_ts); diff --git a/src/sql/engine/px/ob_px_sub_coord.cpp b/src/sql/engine/px/ob_px_sub_coord.cpp index 285838402..0957b2ed0 100644 --- a/src/sql/engine/px/ob_px_sub_coord.cpp +++ b/src/sql/engine/px/ob_px_sub_coord.cpp @@ -140,34 +140,28 @@ int ObPxSubCoord::try_start_tasks(int64_t &dispatch_worker_count, bool is_fast_s void ObPxSubCoord::notify_dispatched_task_exit(int64_t dispatched_worker_count) { - (void) thread_worker_factory_.join(); + (void)thread_worker_factory_.join(); auto &tasks = sqc_ctx_.get_tasks(); - bool is_interrupted = false; - for (int64_t idx = 0; - idx < dispatched_worker_count && dispatched_worker_count <= tasks.count() && !is_interrupted; + for (int64_t idx = 0; idx < dispatched_worker_count && dispatched_worker_count <= tasks.count(); ++idx) { int tick = 1; ObPxTask &task = tasks.at(idx); - while (false == task.is_task_state_set(SQC_TASK_EXIT) && !is_interrupted) { + while (false == task.is_task_state_set(SQC_TASK_EXIT)) { // 每秒给当前 sqc 中未完成的 tasks 发送一次中断 // 首次发中断的时间为 100ms 时。定这个时间是为了 // cover px pool 调度 task 的延迟 if (tick % 1000 == 100) { ObPxSqcMeta &sqc = sqc_arg_.sqc_; - (void) ObInterruptUtil::interrupt_tasks(sqc, OB_GOT_SIGNAL_ABORTING); + (void)ObInterruptUtil::interrupt_tasks(sqc, OB_GOT_SIGNAL_ABORTING); } // 如果 10s 还没有退出,则打印一条日志。按照设计,不会出现这种情况 if (tick++ % 10000 == 0) { - is_interrupted = IS_INTERRUPTED(); - LOG_INFO("waiting for task exit", K(idx), K(dispatched_worker_count), K(tick), K(is_interrupted)); + LOG_INFO("waiting for task exit", K(idx), K(dispatched_worker_count), K(tick)); } ob_usleep(1000); } - LOG_TRACE("task exit", - K(idx), K(tasks.count()), K(dispatched_worker_count), - "dfo_id", task.dfo_id_, - "sqc_id", task.sqc_id_, - "task_id", task.task_id_); + LOG_TRACE("task exit", K(idx), K(tasks.count()), K(dispatched_worker_count), "dfo_id", + task.dfo_id_, "sqc_id", task.sqc_id_, "task_id", task.task_id_); } } @@ -929,7 +923,7 @@ int ObPxSubCoord::start_ddl() ObTabletDirectLoadInsertParam direct_load_param; direct_load_param.is_replay_ = false; - direct_load_param.common_param_.direct_load_type_ = ddl_ctrl_.direct_load_type_;; + direct_load_param.common_param_.direct_load_type_ = ddl_ctrl_.direct_load_type_; direct_load_param.common_param_.data_format_version_ = data_format_version; direct_load_param.common_param_.read_snapshot_ = snapshot_version; direct_load_param.runtime_only_param_.exec_ctx_ = exec_ctx; diff --git a/src/sql/engine/px/ob_px_worker.cpp b/src/sql/engine/px/ob_px_worker.cpp index af41fba9b..c55fd1648 100644 --- a/src/sql/engine/px/ob_px_worker.cpp +++ b/src/sql/engine/px/ob_px_worker.cpp @@ -203,7 +203,6 @@ void PxWorkerFunctor::operator ()(bool need_exec) if (OB_FAIL(runtime_arg.init_deserialize_param(mem_context, *env_arg_.get_gctx()))) { LOG_WARN("fail to init args", K(ret)); } else if (OB_FAIL(runtime_arg.deep_copy_assign(task_arg_, mem_context->get_arena_allocator()))) { - (void) ObInterruptUtil::interrupt_qc(task_arg_.task_, ret, task_arg_.exec_ctx_); LOG_WARN("fail deep copy assign arg", K(task_arg_), K(ret)); } else { // 绑定sqc_handler,方便算子任何地方都可以拿sqc_handle @@ -244,6 +243,15 @@ void PxWorkerFunctor::operator ()(bool need_exec) } else if (sqc_handler->get_flt_ctx().trace_id_.is_inited()) { OBTRACE->reset(); } + + //if start worker failed, still need set task state, interrupt qc + if (OB_FAIL(ret)) { + if (task_arg_.sqc_task_ptr_ != NULL) { + task_arg_.sqc_task_ptr_->set_task_state(SQC_TASK_EXIT); + } + (void) ObInterruptUtil::interrupt_qc(task_arg_.task_, ret, task_arg_.exec_ctx_); + } + PxWorkerFinishFunctor on_func_finish; on_func_finish(); ObCurTraceId::reset(); diff --git a/src/sql/ob_sql_define.h b/src/sql/ob_sql_define.h index 1c53c64db..474510a65 100644 --- a/src/sql/ob_sql_define.h +++ b/src/sql/ob_sql_define.h @@ -674,6 +674,27 @@ inline const ObString &ob_match_against_mode_str(const ObMatchAgainstMode mode) } } +static bool is_fixed_length_storage(ObObjType type) { + bool is_fixed = true; + ObObjTypeClass tc = ob_obj_type_class(type); + OB_ASSERT(tc >= ObNullTC && tc < ObMaxTC); + if (ObNumberTC == tc + || ObExtendTC == tc + || ObTextTC == tc + || ObEnumSetInnerTC == tc + || ObRawTC == tc + || ObRowIDTC == tc + || ObLobTC == tc + || ObJsonTC == tc + || ObGeometryTC == tc + || ObUserDefinedSQLTC == tc + || ObDecimalIntTC == tc + || ObRoaringBitmapTC == tc) { + is_fixed = false; + } + return is_fixed; +} + static bool is_fixed_length(ObObjType type) { bool is_fixed = true; ObObjTypeClass tc = ob_obj_type_class(type); diff --git a/src/sql/ob_sql_trans_control.cpp b/src/sql/ob_sql_trans_control.cpp index 59eb86a7d..208dc35aa 100644 --- a/src/sql/ob_sql_trans_control.cpp +++ b/src/sql/ob_sql_trans_control.cpp @@ -1586,9 +1586,9 @@ int ObSqlTransControl::lock_table(ObExecContext &exec_ctx, arg.timeout_us_ = lock_timeout_us; arg.is_from_sql_ = true; - OZ (lock_service->lock_table(*session->get_tx_desc(), - tx_param, - arg), + OZ (lock_service->lock(*session->get_tx_desc(), + tx_param, + arg), tx_param, table_id, lock_mode, lock_timeout_us); } else { ObLockPartitionRequest arg; diff --git a/src/sql/optimizer/ob_log_plan.h b/src/sql/optimizer/ob_log_plan.h index 28dc360ac..40bc4f4cc 100644 --- a/src/sql/optimizer/ob_log_plan.h +++ b/src/sql/optimizer/ob_log_plan.h @@ -424,6 +424,11 @@ public: ObExchangeInfo &right_exch_info); void set_insert_stmt(const ObInsertStmt *insert_stmt) { insert_stmt_ = insert_stmt; } const ObInsertStmt *get_insert_stmt() const { return insert_stmt_; } + int get_part_exprs(uint64_t table_id, + uint64_t ref_table_id, + share::schema::ObPartitionLevel &part_level, + ObRawExpr *&part_expr, + ObRawExpr *&subpart_expr); void set_nonrecursive_plan_for_fake_cte(ObSelectLogPlan *plan) { nonrecursive_plan_for_fake_cte_ = plan; } ObSelectLogPlan *get_nonrecursive_plan_for_fake_cte() { return nonrecursive_plan_for_fake_cte_; } @@ -1705,12 +1710,6 @@ protected: int get_cache_calc_part_id_expr(int64_t table_id, int64_t ref_table_id, CalcPartIdType calc_type, ObRawExpr* &expr); - int get_part_exprs(uint64_t table_id, - uint64_t ref_table_id, - share::schema::ObPartitionLevel &part_level, - ObRawExpr *&part_expr, - ObRawExpr *&subpart_expr); - int create_hash_sortkey(const int64_t part_cnt, const common::ObIArray &order_keys, OrderItem &hash_sortkey); diff --git a/src/sql/optimizer/ob_log_table_scan.cpp b/src/sql/optimizer/ob_log_table_scan.cpp index 1ea53b5fe..112522920 100644 --- a/src/sql/optimizer/ob_log_table_scan.cpp +++ b/src/sql/optimizer/ob_log_table_scan.cpp @@ -180,8 +180,13 @@ int ObLogTableScan::get_op_exprs(ObIArray &all_exprs) if (OB_ISNULL(get_plan())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret)); + } else if (OB_FAIL(generate_auto_split_filter())) { + LOG_WARN("failed to generate split filter", K(ret)); } else if (OB_FAIL(generate_access_exprs())) { - LOG_WARN("failed to generate access exprs", K(ret)); + LOG_WARN("failed to generate acess exprs", K(ret)); + } else if (NULL != auto_split_filter_ && + OB_FAIL(all_exprs.push_back(auto_split_filter_))) { + LOG_WARN("failed to push back expr", K(ret)); } else if (NULL != limit_count_expr_ && OB_FAIL(all_exprs.push_back(limit_count_expr_))) { LOG_WARN("failed to push back expr", K(ret)); @@ -493,6 +498,14 @@ int ObLogTableScan::generate_access_exprs() LOG_WARN("failed to append array no dup", K(ret)); } else { /*do nothing*/} } + if (OB_SUCC(ret) && nullptr != auto_split_filter_) { + ObSEArray temp_col_exprs; + if (OB_FAIL(ObRawExprUtils::extract_column_exprs(auto_split_filter_, temp_col_exprs))) { + LOG_WARN("failed to extract column exprs", K(ret)); + } else if (OB_FAIL(append_array_no_dup(access_exprs_, temp_col_exprs))) { + LOG_WARN("failed to append array no dup", K(ret)); + } else { /*do nothing*/} + } if (OB_SUCC(ret)) { for (int64_t i = 0; OB_SUCC(ret) && i < stmt->get_column_size(); i++) { const ColumnItem *col_item = stmt->get_column_item(i); @@ -1668,6 +1681,14 @@ int ObLogTableScan::get_plan_item_info(PlanText &plan_text, LOG_WARN("BUF_PRINTF fails", K(ret)); } + if (OB_FAIL(ret) || OB_ISNULL(auto_split_filter_)) { + } else if (OB_FAIL(BUF_PRINTF("\n "))) { + LOG_WARN("BUF_PRINTF fails", K(ret)); + } else { + ObRawExpr *auto_split_filter = auto_split_filter_; + EXPLAIN_PRINT_EXPR(auto_split_filter, type); + } + if (OB_SUCC(ret) && (!pushdown_groupby_columns_.empty() || !pushdown_aggr_exprs_.empty())) { ObIArray &pushdown_aggregation = pushdown_aggr_exprs_; @@ -2630,6 +2651,232 @@ ObRawExpr * ObLogTableScan::get_real_expr(const ObRawExpr *col) const return ret; } +int ObLogTableScan::create_exec_param_for_auto_split(const ObExprResType &type, ObRawExpr *&expr) +{ + int ret = OB_SUCCESS; + ObExecParamRawExpr *exec_param = NULL; + ObRawExprFactory *expr_factory = NULL; + expr = NULL; + if (OB_ISNULL(get_plan()) || + OB_ISNULL(expr_factory = &get_plan()->get_optimizer_context().get_expr_factory())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get invalid argument", K(ret), K(ref_table_id_)); + } else if (OB_FAIL(expr_factory->create_raw_expr(T_QUESTIONMARK, exec_param))) { + LOG_WARN("failed to create exec param expr", K(ret)); + } else if (OB_ISNULL(exec_param)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("exec param is null", K(ret), K(exec_param)); + } else { + exec_param->set_ref_expr(NULL); + exec_param->set_result_type(type); + exec_param->set_eval_by_storage(true); + expr = exec_param; + } + return ret; +} + +int ObLogTableScan::construct_table_split_range_filter(ObSQLSessionInfo *session, const int64_t filter_type) +{ + int ret = OB_SUCCESS; + ObOpRawExpr *lower_bound_vec = NULL; + ObOpRawExpr *upper_bound_vec = NULL; + ObRawExpr *filter_type_expr = NULL; + ObRawExpr *pass_by_expr = NULL; + ObRawExpr *lower_bound_expr = NULL; + ObRawExpr *upper_bound_expr = NULL; + ObRawExpr *lower_bound_filter = NULL; + ObRawExpr *upper_bound_filter = NULL; + ObRawExpr *and_expr = NULL; + ObRawExpr *or_expr = NULL; + ObSEArray or_param_exprs; + ObSEArray and_param_exprs; + + ObExprResType res_type; + res_type.set_type(ObIntType); + res_type.set_accuracy(ObAccuracy::MAX_ACCURACY[ObIntType]); + + share::schema::ObPartitionLevel part_level = share::schema::PARTITION_LEVEL_MAX; + ObRawExpr *part_expr = NULL; + ObRawExpr *subpart_expr = NULL; + ObRawExprFactory *expr_factory = NULL; + + // construct auto split filter + // :0 and (:1, :2) <= (partkey) and (partkey) < (:3, :4) + // The order in auto_split_params_ should not change + // construct auto split params: filter_type - filter_struct + if (OB_ISNULL(session)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid session", K(ret), KP(session)); + } else if (OB_ISNULL(expr_factory = &get_plan()->get_optimizer_context().get_expr_factory())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get invalid argument", K(ret), K(ref_table_id_)); + } else if (OB_FAIL(create_exec_param_for_auto_split(res_type, pass_by_expr))) { + LOG_WARN("failed to create exec param", K(ret)); + } else if (OB_FAIL(auto_split_params_.push_back(pass_by_expr))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(get_plan()->get_part_exprs(table_id_, + ref_table_id_, + part_level, + part_expr, + subpart_expr))) { + LOG_WARN("fail to get part exprs", K(ret)); + } else if (OB_ISNULL(part_expr) || + OB_UNLIKELY(PARTITION_LEVEL_ONE != part_level)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected tablet", K(table_id_), K(ref_table_id_), K(part_level), KPC(part_expr)); + } else if (T_OP_ROW == part_expr->get_expr_type()) { + int64_t row_length = part_expr->get_param_count(); + if (OB_FAIL(expr_factory->create_raw_expr(T_OP_ROW, lower_bound_vec))) { + LOG_WARN("create to_type expr failed", K(ret)); + } else if (OB_FAIL(expr_factory->create_raw_expr(T_OP_ROW, upper_bound_vec))) { + LOG_WARN("create to_type expr failed", K(ret)); + } else if (OB_ISNULL(lower_bound_vec) || OB_ISNULL(upper_bound_vec)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null expr", K(upper_bound_vec), K(lower_bound_vec)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < row_length; i ++) { + ObRawExpr *lower_exec_param = NULL; + ObRawExpr *part_key = NULL; + if (OB_ISNULL(part_key = part_expr->get_param_expr(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null expr", KPC(part_expr), K(i)); + } else if (OB_FAIL(create_exec_param_for_auto_split(part_key->get_result_type(), lower_exec_param))) { + LOG_WARN("failed to create exec param", K(ret)); + } else if (OB_FAIL(lower_bound_vec->add_param_expr(lower_exec_param))) { + LOG_WARN("failed to add param expr", K(ret)); + } else if (OB_FAIL(auto_split_params_.push_back(lower_exec_param))) { + LOG_WARN("failed to push back", K(ret)); + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < row_length; i ++) { + ObRawExpr *upper_exec_param = NULL; + ObRawExpr *part_key = NULL; + if (OB_ISNULL(part_key = part_expr->get_param_expr(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null expr", KPC(part_expr), K(i)); + } else if (OB_FAIL(create_exec_param_for_auto_split(part_key->get_result_type(), upper_exec_param))) { + LOG_WARN("failed to create exec param", K(ret)); + } else if (OB_FAIL(upper_bound_vec->add_param_expr(upper_exec_param))) { + LOG_WARN("failed to add param expr", K(ret)); + } else if (OB_FAIL(auto_split_params_.push_back(upper_exec_param))) { + LOG_WARN("failed to push back", K(ret)); + } + } + if (OB_SUCC(ret)) { + lower_bound_expr = lower_bound_vec; + upper_bound_expr = upper_bound_vec; + } + } else { + if (OB_FAIL(create_exec_param_for_auto_split(part_expr->get_result_type(), lower_bound_expr))) { + LOG_WARN("failed to create exec param", K(ret)); + } else if (OB_FAIL(create_exec_param_for_auto_split(part_expr->get_result_type(), upper_bound_expr))) { + LOG_WARN("failed to create exec param", K(ret)); + } else if (OB_FAIL(auto_split_params_.push_back(lower_bound_expr))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(auto_split_params_.push_back(upper_bound_expr))) { + LOG_WARN("failed to push back", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObRawExprUtils::build_common_binary_op_expr(*expr_factory, + T_OP_LE, + lower_bound_expr, + part_expr, + lower_bound_filter))) { + LOG_WARN("failed to build filter", K(ret)); + } else if (OB_FAIL(ObRawExprUtils::build_common_binary_op_expr(*expr_factory, + T_OP_LT, + part_expr, + upper_bound_expr, + upper_bound_filter))) { + LOG_WARN("failed to build filter", K(ret)); + } else if (OB_ISNULL(lower_bound_filter) || OB_ISNULL(upper_bound_filter)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null expr", K(lower_bound_filter), K(upper_bound_filter)); + } else if (OB_FAIL(lower_bound_filter->add_flag(IS_AUTO_PART_EXPR))) { + LOG_WARN("failed to add flag", K(ret)); + } else if (OB_FAIL(upper_bound_filter->add_flag(IS_AUTO_PART_EXPR))) { + LOG_WARN("failed to add flag", K(ret)); + } else if (OB_FAIL(and_param_exprs.push_back(lower_bound_filter))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(and_param_exprs.push_back(upper_bound_filter))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(ObRawExprUtils::build_and_expr(*expr_factory, + and_param_exprs, + and_expr))) { + LOG_WARN("failed to build and expr", K(ret)); + } else if (OB_ISNULL(and_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr null pointer", K(ret), K(and_expr)); + } else if (OB_FAIL(or_param_exprs.push_back(pass_by_expr))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(or_param_exprs.push_back(and_expr))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(ObRawExprUtils::build_or_exprs(*expr_factory, + or_param_exprs, + or_expr))) { + LOG_WARN("failed to build or expr", K(ret)); + } else if (OB_ISNULL(or_expr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("expr null pointer", K(ret), K(or_expr)); + } else if (OB_FAIL(or_expr->formalize(session))) { + LOG_WARN("failed to formalize", K(ret)); + } else { + auto_split_filter_type_ = filter_type; + auto_split_filter_ = or_expr; + } + + return ret; +} + +int ObLogTableScan::check_need_table_split_range_filter(ObSchemaGetterGuard &schema_guard, + const ObTableSchema &table_schema, + bool &need_filter) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const int64_t table_id = table_schema.get_table_id(); + const int64_t data_table_id = table_schema.get_data_table_id(); + const ObTableSchema *data_table_schema = nullptr; + if (OB_UNLIKELY(!(table_schema.is_range_part() && !table_schema.is_interval_part()))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid partition type", K(ret), K(table_id), K(table_schema.get_part_option())); + } else if (table_schema.is_index_local_storage()) { + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, data_table_id, data_table_schema))) { + LOG_WARN("failed to get data table schema", K(ret), K(table_id), K(data_table_id)); + } else if (OB_ISNULL(data_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("data table schema is null", K(ret), K(table_id), K(data_table_id)); + } else { + const ObPartitionKeyInfo &partkey_info = data_table_schema->get_partition_key_info(); + const ObRowkeyInfo &rowkey_info = table_schema.get_rowkey_info(); + bool partkey_is_rowkey_prefix = true; + if (OB_UNLIKELY(!partkey_info.is_valid() || !rowkey_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid partkey info or rowkey info", K(ret), K(partkey_info), K(rowkey_info)); + } + for (int64_t i = 0; OB_SUCC(ret) && partkey_is_rowkey_prefix && i < partkey_info.get_size(); i++) { + uint64_t partkey_column_id = OB_INVALID_ID; + uint64_t rowkey_column_id = OB_INVALID_ID; + if (OB_FAIL(partkey_info.get_column_id(i, partkey_column_id))) { + LOG_WARN("failed to get partkey column id", K(ret), K(partkey_info), K(i)); + } else if (OB_FAIL(rowkey_info.get_column_id(i, rowkey_column_id))) { + LOG_WARN("failed to get rowkey column id", K(ret), K(rowkey_info), K(i)); + } else if (partkey_column_id != rowkey_column_id) { + partkey_is_rowkey_prefix = false; + } + } + if (OB_SUCC(ret)) { + need_filter = !partkey_is_rowkey_prefix; + } + } + } else { + need_filter = false; + } + return ret; +} + int ObLogTableScan::extract_doc_id_index_back_expr(ObIArray &exprs, bool is_vec_scan) { int ret = OB_SUCCESS; @@ -2872,6 +3119,53 @@ int ObLogTableScan::print_text_retrieval_annotation(char *buf, int64_t buf_len, return ret; } +int ObLogTableScan::generate_auto_split_filter() +{ + int ret = OB_SUCCESS; + ObSQLSessionInfo *session = NULL; + share::schema::ObSchemaGetterGuard *schema_guard = NULL; + const share::schema::ObTableSchema *table_schema = NULL; + bool need_filter = false; + ObDMLStmt *stmt = NULL; + const int64_t table_id = is_index_scan() ? index_table_id_ : ref_table_id_; + + if (OB_ISNULL(get_plan()) + || OB_UNLIKELY(OB_INVALID_ID == table_id) + || OB_ISNULL(stmt = const_cast(get_stmt())) + || OB_ISNULL(session = get_plan()->get_optimizer_context().get_session_info()) + || OB_ISNULL(schema_guard = get_plan()->get_optimizer_context().get_schema_guard())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get invalid argument", K(ret), K(ref_table_id_)); + } else if (get_contains_fake_cte() || is_virtual_table(table_id)) { + // skip mock table and virtual table + } else if (OB_FAIL(schema_guard->get_table_schema( + session->get_effective_tenant_id(), + table_id, table_schema))) { + LOG_WARN("get table schema failed", K(table_id), K(ret)); + } else if (OB_ISNULL(table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table schema is null", K(ret), K(table_id), K(is_index_scan()), K(index_table_id_), K(ref_table_id_), K(table_id_)); + } else if (table_schema->get_hidden_partition_num() > 0) { + bool need_filter = false; + if (table_schema->is_range_part() && !table_schema->is_interval_part()) { + if (OB_FAIL(check_need_table_split_range_filter(*schema_guard, *table_schema, need_filter))) { + LOG_WARN("failed to check need filter", K(ret)); + } else if (need_filter && OB_FAIL(construct_table_split_range_filter(session, static_cast(ObTabletSplitType::RANGE)))) { + LOG_WARN("fail to construct table split range filter", K(ret)); + } + } else if (table_schema->is_key_part()) { + } else if (table_schema->is_hash_part()) { + } else if (table_schema->is_list_part()) { + } else { + } + if (OB_SUCC(ret) && need_filter) { + LOG_INFO("generate filter for splitting table", K(need_filter), K(ref_table_id_), K(table_id_), + K(get_index_back()), K(is_index_scan()), K(table_schema->get_table_id()), K(table_schema->get_schema_version())); + } + } + return ret; +} + int ObLogTableScan::prepare_vector_access_exprs() { int ret = OB_SUCCESS; diff --git a/src/sql/optimizer/ob_log_table_scan.h b/src/sql/optimizer/ob_log_table_scan.h index a631583d5..449c4457a 100644 --- a/src/sql/optimizer/ob_log_table_scan.h +++ b/src/sql/optimizer/ob_log_table_scan.h @@ -217,6 +217,8 @@ public: vector_index_info_(), das_keep_ordering_(false), filter_monotonicity_(), + auto_split_filter_type_(OB_INVALID_ID), + auto_split_filter_(NULL), is_tsc_with_doc_id_(false), rowkey_doc_tid_(common::OB_INVALID_ID), multivalue_col_idx_(common::OB_INVALID_ID), @@ -640,6 +642,12 @@ public: int adjust_print_access_info(ObIArray &access_exprs); static int replace_gen_column(ObLogPlan *plan, ObRawExpr *part_expr, ObRawExpr *&new_part_expr); int extract_file_column_exprs_recursively(ObRawExpr *expr); + int generate_auto_split_filter(); + int construct_table_split_range_filter(ObSQLSessionInfo *session, const int64_t filter_type); + int create_exec_param_for_auto_split(const ObExprResType &type, ObRawExpr *&expr); + uint64_t get_auto_split_filter_type() const { return auto_split_filter_type_; }; + const ObRawExpr *get_auto_split_filter() const { return auto_split_filter_; }; + const ObIArray &get_auto_split_params() const { return auto_split_params_; }; inline bool is_tsc_with_doc_id() const { return is_tsc_with_doc_id_; } inline bool is_tsc_with_vid() const { return is_tsc_with_vid_; } inline bool is_text_retrieval_scan() const { return is_index_scan() && NULL != text_retrieval_info_.match_expr_; } @@ -705,6 +713,9 @@ private: // member functions int add_mapping_columns_for_vt(ObIArray &access_exprs); int get_mbr_column_exprs(const uint64_t table_id, ObIArray &mbr_exprs); int allocate_lookup_trans_info_expr(); + static int check_need_table_split_range_filter(share::schema::ObSchemaGetterGuard &schema_guard, + const share::schema::ObTableSchema &table_schema, + bool &need_filter); int allocate_group_id_expr(); int extract_doc_id_index_back_expr(ObIArray &exprs, bool is_vec_scan = false); int extract_text_retrieval_access_expr(ObIArray &exprs); @@ -791,6 +802,8 @@ protected: // memeber variables common::ObSEArray filter_before_index_back_; // // removal these in cg layer, up to opt layer. common::ObSEArray ddl_output_column_ids_; + // auto split param + common::ObSEArray auto_split_params_; // removal these in cg layer, up to opt layer end. // table partition locations ObTablePartitionInfo *table_partition_info_; //this member is not in copy_without_child, @@ -859,6 +872,8 @@ protected: // memeber variables typedef common::ObSEArray FilterMonotonicity; FilterMonotonicity filter_monotonicity_; + uint64_t auto_split_filter_type_; + ObRawExpr *auto_split_filter_; // begin for table scan with doc id bool is_tsc_with_doc_id_; uint64_t rowkey_doc_tid_; diff --git a/src/sql/optimizer/ob_storage_estimator.cpp b/src/sql/optimizer/ob_storage_estimator.cpp index 299c3d11e..55510b9fc 100644 --- a/src/sql/optimizer/ob_storage_estimator.cpp +++ b/src/sql/optimizer/ob_storage_estimator.cpp @@ -82,7 +82,7 @@ int ObStorageEstimator::estimate_block_count_and_row_count(const obrpc::ObEstBlo // estimate scan rowcount int ObStorageEstimator::storage_estimate_rowcount(const uint64_t tenant_id, - const ObTableScanParam ¶m, + ObTableScanParam ¶m, const ObSimpleBatch &batch, obrpc::ObEstPartResElement &res) { @@ -117,7 +117,7 @@ int ObStorageEstimator::storage_estimate_rowcount(const uint64_t tenant_id, int ObStorageEstimator::storage_estimate_partition_batch_rowcount( const uint64_t tenant_id, const ObSimpleBatch &batch, - const storage::ObTableScanParam &table_scan_param, + storage::ObTableScanParam &table_scan_param, ObIArray &est_records, double &logical_row_count, double &physical_row_count) @@ -130,10 +130,11 @@ int ObStorageEstimator::storage_estimate_partition_batch_rowcount( const int64_t timeout_us = THIS_WORKER.get_timeout_remain(); ObAccessService *access_service = NULL; storage::ObTableScanRange table_scan_range; + if (OB_ISNULL(access_service = MTL(ObAccessService *))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("get unexpected null", K(ret), K(access_service)); - } else if (OB_FAIL(table_scan_range.init(batch, allocator))) { + } else if (OB_FAIL(table_scan_range.init(table_scan_param, batch, allocator))) { STORAGE_LOG(WARN, "Failed to init table scan range", K(ret), K(batch)); } else if (OB_FAIL(access_service->estimate_row_count(table_scan_param, table_scan_range, diff --git a/src/sql/optimizer/ob_storage_estimator.h b/src/sql/optimizer/ob_storage_estimator.h index b172dba40..cd2602fa2 100644 --- a/src/sql/optimizer/ob_storage_estimator.h +++ b/src/sql/optimizer/ob_storage_estimator.h @@ -55,7 +55,7 @@ private: * estimate rowcount for an index access path using storage interface */ static int storage_estimate_rowcount(const uint64_t tenant_id, - const storage::ObTableScanParam ¶m, + storage::ObTableScanParam ¶m, const ObSimpleBatch &batch, obrpc::ObEstPartResElement &res); @@ -68,7 +68,7 @@ private: static int storage_estimate_partition_batch_rowcount( const uint64_t tenant_id, const ObSimpleBatch &batch, - const storage::ObTableScanParam &table_scan_param, + storage::ObTableScanParam &table_scan_param, ObIArray &est_records, double &logical_row_count, double &physical_row_count); diff --git a/src/sql/parser/sql_parser_mysql_mode.y b/src/sql/parser/sql_parser_mysql_mode.y index 0a56cf78d..0131f13b5 100644 --- a/src/sql/parser/sql_parser_mysql_mode.y +++ b/src/sql/parser/sql_parser_mysql_mode.y @@ -397,7 +397,7 @@ END_P SET_VAR DELIMITER %type opt_resource_unit_option_list resource_unit_option %type tenant_option zone_list resource_pool_list %type with_column_group column_group_list column_group_element -%type opt_partition_option partition_option hash_partition_option key_partition_option opt_use_partition use_partition range_partition_option subpartition_option opt_range_partition_list opt_range_subpartition_list range_partition_list range_subpartition_list range_partition_element range_subpartition_element range_partition_expr range_expr_list range_expr opt_part_id sample_clause opt_block seed sample_percent opt_sample_scope modify_partition_info modify_tg_partition_info opt_partition_range_or_list auto_partition_option auto_range_type partition_size auto_partition_type use_flashback partition_options partition_num +%type opt_range_partition_info opt_auto_split_tablet_size_option auto_split_tablet_size_option opt_partition_option partition_option hash_partition_option key_partition_option opt_use_partition use_partition range_partition_option subpartition_option opt_range_partition_list opt_range_subpartition_list range_partition_list range_subpartition_list range_partition_element range_subpartition_element range_partition_expr range_expr_list range_expr opt_part_id sample_clause opt_block seed sample_percent opt_sample_scope modify_partition_info modify_tg_partition_info opt_partition_range_or_list auto_partition_option auto_range_type partition_size auto_partition_type use_flashback partition_options partition_num %type subpartition_template_option subpartition_individual_option opt_hash_partition_list hash_partition_list hash_partition_element opt_hash_subpartition_list hash_subpartition_list hash_subpartition_element opt_subpartition_list opt_engine_option %type date_unit date_params timestamp_params %type drop_table_stmt table_list drop_view_stmt table_or_tables @@ -7878,22 +7878,75 @@ PARTITION BY KEY '(' column_name_list ')' partition_options %prec LOWER_PARENS ; range_partition_option: -PARTITION BY RANGE '(' expr ')' partition_options opt_range_partition_list +PARTITION BY RANGE '(' ')' opt_partitions opt_auto_split_tablet_size_option +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_RANGE_COLUMNS_PARTITION, 7, NULL, NULL, NULL, $6, NULL, NULL, $7); +} +| +PARTITION BY RANGE '(' expr ')' partition_options opt_range_partition_info { ParseNode *params = NULL; malloc_non_terminal_node(params, result->malloc_pool_, T_EXPR_LIST, 1, $5); - malloc_non_terminal_node($$, result->malloc_pool_, T_RANGE_PARTITION, 5, params, $8, $7->children_[0], $7->children_[1], NULL); + malloc_non_terminal_node($$, result->malloc_pool_, T_RANGE_PARTITION, 7, params, $8->children_[1], $7->children_[0], $7->children_[1], NULL, NULL, $8->children_[0]); dup_expr_string($$, result, @5.first_column, @5.last_column); } -| PARTITION BY RANGE COLUMNS '(' column_name_list ')' partition_options opt_range_partition_list +| +PARTITION BY RANGE COLUMNS '(' column_name_list ')' partition_options opt_range_partition_info { ParseNode *params = NULL; merge_nodes(params, result, T_EXPR_LIST, $6); - malloc_non_terminal_node($$, result->malloc_pool_, T_RANGE_COLUMNS_PARTITION, 5, params, $9, $8->children_[0], $8->children_[1], NULL); + malloc_non_terminal_node($$, result->malloc_pool_, T_RANGE_COLUMNS_PARTITION, 7, params, $9->children_[1], $8->children_[0], $8->children_[1], NULL, NULL, $9->children_[0]); dup_expr_string($$, result, @6.first_column, @6.last_column); } ; +opt_auto_split_tablet_size_option: +/* EMPTY */ +{ + $$ = NULL; +} +| +auto_split_tablet_size_option +{ + $$ = $1; +} +; + +auto_split_tablet_size_option: +SIZE '(' STRING_VALUE ')' +{ + malloc_terminal_node($$, result->malloc_pool_, T_AUTO_SPLIT_TABLET_SIZE); + $$->str_value_ = $3->str_value_; + $$->str_len_ = $3->str_len_; +} +; + +opt_range_partition_info: +%prec LOWER_PARENS /* EMPTY */ +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_LINK_NODE, 2, NULL, NULL); +} +| +auto_split_tablet_size_option '(' range_partition_list ')' +{ + ParseNode *partition_list = NULL; + merge_nodes(partition_list, result, T_PARTITION_LIST, $3); + + malloc_non_terminal_node($$, result->malloc_pool_, T_LINK_NODE, 2, $1, partition_list); +} +| %prec LOWER_PARENS auto_split_tablet_size_option +{ + malloc_non_terminal_node($$, result->malloc_pool_, T_LINK_NODE, 2, $1, NULL); +} +|'(' range_partition_list ')' +{ + ParseNode *partition_list = NULL; + merge_nodes(partition_list, result, T_PARTITION_LIST, $2); + + malloc_non_terminal_node($$, result->malloc_pool_, T_LINK_NODE, 2, NULL, partition_list); +} +; + column_name_list: column_name { diff --git a/src/sql/resolver/cmd/ob_alter_system_resolver.cpp b/src/sql/resolver/cmd/ob_alter_system_resolver.cpp index 5b5de0638..3b8f372b8 100644 --- a/src/sql/resolver/cmd/ob_alter_system_resolver.cpp +++ b/src/sql/resolver/cmd/ob_alter_system_resolver.cpp @@ -5354,7 +5354,7 @@ int ObAlterSystemResolverUtil::get_tenant_ids(const ParseNode &t_node, ObIArray< int ObTableTTLResolver::resolve(const ParseNode& parse_tree) { int ret = OB_SUCCESS; - uint64_t tenant_data_version = 0;; + uint64_t tenant_data_version = 0; const uint64_t cur_tenant_id = session_info_->get_effective_tenant_id(); if (OB_FAIL(GET_MIN_DATA_VERSION(cur_tenant_id, tenant_data_version))) { LOG_WARN("get tenant data version failed", K(ret)); diff --git a/src/sql/resolver/ddl/ob_alter_table_resolver.cpp b/src/sql/resolver/ddl/ob_alter_table_resolver.cpp index 307579185..033ce0e49 100644 --- a/src/sql/resolver/ddl/ob_alter_table_resolver.cpp +++ b/src/sql/resolver/ddl/ob_alter_table_resolver.cpp @@ -2459,10 +2459,18 @@ int ObAlterTableResolver::generate_index_arg(obrpc::ObCreateIndexArg &index_arg, // MySQL default index mode is local, // and Oracle default index mode is global global_ = lib::is_oracle_mode(); + if (!global_) { + if (nullptr != table_schema_) { + if (OB_FAIL(get_suggest_index_scope(index_arg.tenant_id_, table_schema_->get_table_id(), index_arg, index_keyname_, global_))) { + LOG_WARN("get suggest index scope failed", K(ret)); + } + } + } } else { global_ = (GLOBAL_INDEX == index_scope_); } - if (is_unique_key) { + if (OB_FAIL(ret)) { + } else if (is_unique_key) { if (global_) { type = INDEX_TYPE_UNIQUE_GLOBAL; } else { @@ -4186,6 +4194,70 @@ int ObAlterTableResolver::resolve_modify_check_constraint_state_mysql(const Pars return ret; } +// "alter table ... split partition" sql allow to omit the definition of last split partition. +// we should fill the high bound value of it with origin schema +int ObAlterTableResolver::fill_high_bound_val_for_split_partition(const AlterTableSchema &alter_table_schema, ObPartition& split_part) +{ + int ret = OB_SUCCESS; + ObSchemaGetterGuard schema_guard; + const uint64_t tenant_id = alter_table_schema.get_tenant_id(); + const ObString &origin_database_name = alter_table_schema.get_origin_database_name(); + const ObString &origin_table_name = alter_table_schema.get_origin_table_name(); + const share::schema::ObTableSchema *orig_table_schema = NULL; + ObTabletID source_tablet_id = split_part.get_split_source_tablet_id(); + ObPartition **orig_part_array = nullptr; + + CK (!origin_database_name.empty() && !origin_table_name.empty()); + OZ (ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(tenant_id, schema_guard)); + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(schema_guard.get_table_schema(tenant_id, + origin_database_name, + origin_table_name, + false/*is_index*/, + orig_table_schema))) { + LOG_WARN("fail to get table schema", KR(ret), K(tenant_id), K(origin_database_name), K(origin_table_name)); + } else if (OB_ISNULL(orig_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("fail to find table", K(ret)); + } else if (OB_UNLIKELY(orig_table_schema->get_part_level() != PARTITION_LEVEL_ONE)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part level", K(ret), KPC(orig_table_schema)); + } else if (FALSE_IT(orig_part_array = orig_table_schema->get_part_array())) { + } else if (OB_ISNULL(orig_part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("null ptr", K(ret)); + } else if (!orig_table_schema->is_valid_split_part_type()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("only support to split range partition", K(ret)); + } else { + ObTabletID source_tablet_id = split_part.get_split_source_tablet_id(); + const ObPartition *ori_part = NULL; + bool find = false; + + for (int64_t i = 0; !find && OB_SUCC(ret) && i < orig_table_schema->get_partition_num(); ++i) { + ori_part = orig_part_array[i]; + if (OB_ISNULL(ori_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", K(ret)); + } else if (ori_part->get_tablet_id() == source_tablet_id) { + find = true; + const ObRowkey &value = ori_part->get_high_bound_val(); + if (OB_FAIL(split_part.set_high_bound_val(value))) { + LOG_WARN("failed to set high boundary", K(ret)); + } + } + } // end for + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(!find)) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("source_tablet_id not exists in origin table", K(ret), K(source_tablet_id), KPC(orig_table_schema)); + } + } + + return ret; +} + int ObAlterTableResolver::check_dup_foreign_keys_exist( share::schema::ObSchemaGetterGuard *schema_guard, const obrpc::ObCreateForeignKeyArg &foreign_key_arg) @@ -4601,14 +4673,21 @@ int ObAlterTableResolver::resolve_partition_options(const ParseNode &node) } if (OB_SUCC(ret)) { + bool is_only_modify_auto_part_attr = false; + ParseNode *partition_node = node.children_[0]; const ObPartitionLevel part_level = table_schema_->get_part_level(); if (T_ALTER_PARTITION_PARTITIONED != node.children_[0]->type_ && PARTITION_LEVEL_ZERO == part_level) { ret = OB_ERR_PARTITION_MGMT_ON_NONPARTITIONED; LOG_WARN("unsupport add/drop management on non-partition table", K(ret)); - + } else if (T_ALTER_PARTITION_PARTITIONED == node.children_[0]->type_ + && OB_FAIL(check_only_modify_auto_partition_attr(alter_table_stmt, partition_node->children_[0], + alter_table_stmt->get_alter_table_arg().alter_table_schema_, + is_only_modify_auto_part_attr))) { + LOG_WARN("fail to check only modify auto_part attr", K(ret)); } else if (T_ALTER_PARTITION_PARTITIONED == node.children_[0]->type_ && PARTITION_LEVEL_ZERO != part_level + && !is_only_modify_auto_part_attr && lib::is_oracle_mode()) { ret = OB_NOT_SUPPORTED; LOG_WARN("can't re-partitioned a partitioned table", K(ret)); @@ -4698,20 +4777,7 @@ int ObAlterTableResolver::resolve_partition_options(const ParseNode &node) break; } case T_ALTER_PARTITION_REORGANIZE: { - bool enable_split_partition = false; - if (!table_schema_->is_range_part() && !table_schema_->is_list_part()) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("reorganize hash partition not supported", K(ret)); - LOG_USER_WARN(OB_NOT_SUPPORTED, "Reorganize hash partition"); - } else if (OB_FAIL(get_enable_split_partition(session_info_->get_effective_tenant_id(), - enable_split_partition))) { - LOG_WARN("failed to get enable split partition config", K(ret), - "tenant_id", session_info_->get_effective_tenant_id()); - } else if (!enable_split_partition) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("reorganize partition not allow", K(ret)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "reorganize partition"); - } else if (OB_FAIL(resolve_reorganize_partition(partition_node, *table_schema_))) { + if (OB_FAIL(resolve_reorganize_partition(partition_node, *table_schema_))) { LOG_WARN("fail to resolve reorganize partition", K(ret)); } else { alter_table_stmt->get_alter_table_arg().alter_part_type_ = @@ -4720,20 +4786,7 @@ int ObAlterTableResolver::resolve_partition_options(const ParseNode &node) break; } case T_ALTER_PARTITION_SPLIT: { - bool enable_split_partition = false; - if (!table_schema_->is_range_part() && !table_schema_->is_list_part()) { - ret = OB_NOT_SUPPORTED; - LOG_WARN("Split hash partition not supported", K(ret)); - LOG_USER_WARN(OB_NOT_SUPPORTED, "Split hash partition"); - } else if (OB_FAIL(get_enable_split_partition(session_info_->get_effective_tenant_id(), - enable_split_partition))) { - LOG_WARN("failed to get enable split partition config", K(ret), - "tenant_id", session_info_->get_effective_tenant_id()); - } else if (!enable_split_partition) { - ret = OB_OP_NOT_ALLOW; - LOG_WARN("split partition not allow", K(ret)); - LOG_USER_ERROR(OB_OP_NOT_ALLOW, "split partition"); - } else if (OB_FAIL(resolve_split_partition(partition_node, *table_schema_))) { + if (OB_FAIL(resolve_split_partition(partition_node, *table_schema_))) { LOG_WARN("fail to resolve reorganize partition", K(ret)); } else { alter_table_stmt->get_alter_table_arg().alter_part_type_ = @@ -4817,6 +4870,8 @@ int ObAlterTableResolver::resolve_partitioned_partition(const ParseNode *node, if (OB_FAIL(ret)) { } else if (OB_FAIL(resolve_partition_node(alter_table_stmt, node->children_[0], table_schema))) { LOG_WARN("failed to resolve partition option", K(ret)); + } else if (OB_FAIL(resolve_auto_partition(alter_table_stmt, node->children_[0], table_schema))) { + LOG_WARN("failed to resolve auto partition option", K(ret)); } else if (OB_FAIL(table_schema.check_primary_key_cover_partition_column())) { LOG_WARN("fail to check primary key cover partition column", K(ret)); } else if (OB_FAIL(table_schema.set_origin_table_name(origin_table_name))) { @@ -4824,6 +4879,11 @@ int ObAlterTableResolver::resolve_partitioned_partition(const ParseNode *node, } else if (OB_FAIL(table_schema.set_origin_database_name(origin_database_name))) { LOG_WARN("fail to set origin database name", K(ret), K(origin_database_name)); } + if (OB_FAIL(ret)) { + } else if (alter_table_stmt->use_auto_partition_clause()) { + alter_table_stmt->get_alter_table_arg().alter_auto_partition_attr_ = true; + alter_table_stmt->get_alter_table_arg().is_alter_partitions_ = false; + } } return ret; } @@ -4847,6 +4907,8 @@ int ObAlterTableResolver::resolve_split_partition(const ParseNode *node, } else if (OB_ISNULL(alter_table_stmt)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("alter table stmt should not be null", K(ret)); + } else if (OB_FAIL(origin_table_schema.check_can_do_manual_split_partition())) { + LOG_WARN("fail to check split partition", K(ret)); } else { ParseNode *name_list = node->children_[0]; AlterTableSchema &alter_table_schema = @@ -4952,17 +5014,58 @@ int ObAlterTableResolver::resolve_split_partition(const ParseNode *node, LOG_WARN("fail to set origin table name", K(ret), K(origin_table_name)); } else if (OB_FAIL(alter_table_schema.set_origin_database_name(origin_database_name))) { LOG_WARN("fail to set origin database name", K(ret), K(origin_database_name)); - } else { + } else if (OB_UNLIKELY(1 == alter_table_schema.get_partition_num())) { + ret = OB_ERR_SPLIT_INTO_ONE_PARTITION; + LOG_USER_ERROR(OB_ERR_SPLIT_INTO_ONE_PARTITION); + LOG_WARN("can not split partition into one partition", K(ret), K(alter_table_schema)); + } else if (OB_UNLIKELY(0 == alter_table_schema.get_partition_num())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid part_num", K(ret), K(alter_table_schema.get_partition_num())); + } else if (OB_FAIL(fill_split_source_tablet_id(alter_table_schema.get_split_partition_name(), + origin_table_schema, alter_table_schema))) { + LOG_WARN("fail to fill source split tablet id", KR(ret)); + } else if (OB_UNLIKELY(!origin_table_schema.get_part_option().is_range_part())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid partition type", KR(ret), K(origin_table_schema)); + } else { // range part + // to be compatible with oracle, the last split partition could not defined with PARTITION_ELEMENT. + // the high bound value of the it should always be same with the origin partition + if (OB_UNLIKELY(expr_count == alter_table_schema.get_partition_num())) { + ret = OB_ERR_SPLIT_LIST_LESS_VALUE; + LOG_WARN("last partition contain bounds is not supported", KR(ret), K(expr_count), + K(alter_table_schema)); + } else if (OB_UNLIKELY(expr_count != alter_table_schema.get_partition_num() - 1)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid expr_count", KR(ret), K(expr_count), K(alter_table_schema)); + } else { + ObPartition **part_array = alter_table_schema.get_part_array(); + ObPartition *last_part = nullptr; + if (OB_ISNULL(part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("null ptr", K(ret)); + } else if (FALSE_IT(last_part = part_array[alter_table_schema.get_partition_num() - 1])) { + } else if (OB_ISNULL(last_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("null ptr", K(ret)); + } else if (OB_FAIL(fill_high_bound_val_for_split_partition(alter_table_schema, *last_part))) { + LOG_WARN("fail to fill last split partition", KR(ret)); + } + } + } + + if (OB_SUCC(ret)) { alter_table_schema.set_part_level(origin_table_schema.get_part_level()); alter_table_schema.get_part_option() = origin_table_schema.get_part_option(); - alter_table_schema.get_part_option().set_part_num(expr_count);//最后一个partition可能没有最大值,需要在rs端处理 + // "expr_count" means the number of split partitions defined with PARTITION_ELEMENT. + // in executor, we only need to casting expression value for these "expr_count" partitions. + // thus, we will set part_num as "expr_count" at first. + // after executor casting expression value, it will be corrected with alter_table_schema's partition_num + alter_table_schema.get_part_option().set_part_num(expr_count); } } return ret; } - - int ObAlterTableResolver::resolve_reorganize_partition(const ParseNode *node, const share::schema::ObTableSchema &origin_table_schema) { @@ -4978,6 +5081,8 @@ int ObAlterTableResolver::resolve_reorganize_partition(const ParseNode *node, || OB_ISNULL(node->children_[1])) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(node)); + } else if (OB_FAIL(origin_table_schema.check_can_do_manual_split_partition())) { + LOG_WARN("fail to check split partition", K(ret)); } else { if (OB_ISNULL(alter_table_stmt)) { ret = OB_ERR_UNEXPECTED; @@ -5032,12 +5137,52 @@ int ObAlterTableResolver::resolve_reorganize_partition(const ParseNode *node, ret = OB_ERR_SPLIT_INTO_ONE_PARTITION; LOG_USER_ERROR(OB_ERR_SPLIT_INTO_ONE_PARTITION); LOG_WARN("can not split partition into one partition", K(ret), K(alter_table_schema)); + } else if (OB_FAIL(fill_split_source_tablet_id(alter_table_schema.get_split_partition_name(), + origin_table_schema, alter_table_schema))) { + LOG_WARN("fail to fill source split tablet id", KR(ret)); } } } return ret; } +int ObAlterTableResolver::fill_split_source_tablet_id(const ObString& source_part_name, + const share::schema::ObTableSchema &origin_table_schema, + share::schema::AlterTableSchema &alter_table_schema) +{ + int ret = OB_SUCCESS; + ObPartition** ori_part_array = origin_table_schema.get_part_array(); + ObPartition** inc_part_array = alter_table_schema.get_part_array(); + int64_t ori_part_num = origin_table_schema.get_partition_num(); + int64_t inc_part_num = alter_table_schema.get_partition_num(); + + const ObPartition* source_part = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && source_part == nullptr && i < ori_part_num; i++) { + if (OB_ISNULL(ori_part_array[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("partition is null", K(ret), K(origin_table_schema)); + } else if (ObCharset::case_insensitive_equal(ori_part_array[i]->get_part_name(), + source_part_name)) { + source_part = ori_part_array[i]; + } + } + + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(source_part)) { + ret = OB_UNKNOWN_PARTITION; + LOG_WARN("the partition does not exist", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < inc_part_num; i++) { + if (OB_ISNULL(inc_part_array[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("partition is null", K(ret), K(alter_table_schema)); + } else { + inc_part_array[i]->set_split_source_tablet_id(source_part->get_tablet_id()); + } + } + } + return ret; +} int ObAlterTableResolver::resolve_convert_to_character(const ParseNode &node) { int ret = OB_SUCCESS; @@ -5711,7 +5856,8 @@ int ObAlterTableResolver::check_column_in_part_key(const ObTableSchema &table_sc dst_col_schema, is_same))) { LOG_WARN("check same type alter failed", K(ret)); - } else if (table_schema.is_partitioned_table() && OB_FAIL(check_table_schemas.push_back(&table_schema))) { + } else if ((table_schema.is_partitioned_table() || table_schema.is_auto_partitioned_table()) + && OB_FAIL(check_table_schemas.push_back(&table_schema))) { LOG_WARN("push back schema failed", K(ret)); } else if (OB_FAIL(table_schema.get_simple_index_infos(simple_index_infos))) { LOG_WARN("get simple index infos failed", K(ret), K(table_schema)); @@ -5725,7 +5871,8 @@ int ObAlterTableResolver::check_column_in_part_key(const ObTableSchema &table_sc } else if (OB_ISNULL(index_schema)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected null index schema", K(ret), K(simple_index_infos.at(i))); - } else if (index_schema->is_partitioned_table() && OB_FAIL(check_table_schemas.push_back(index_schema))) { + } else if ((index_schema->is_partitioned_table() || index_schema->is_auto_partitioned_table()) + && OB_FAIL(check_table_schemas.push_back(index_schema))) { LOG_WARN("push back related index schema failed", K(ret)); } } @@ -5737,9 +5884,17 @@ int ObAlterTableResolver::check_column_in_part_key(const ObTableSchema &table_sc for (int64_t i = 0; OB_SUCC(ret) && i < check_table_schemas.count(); i++) { const ObTableSchema &cur_table_schema = *check_table_schemas.at(i); const ObColumnSchemaV2 *column_schema = nullptr; + bool is_partition_key = false; + bool is_subpartition_key = false; if (OB_ISNULL(column_schema = cur_table_schema.get_column_schema(alter_column_name))) { - // do nothing, bacause the column does not exist in the schema. - } else if (column_schema->is_tbl_part_key_column()) { + // do nothing, because the column does not exist in the schema. + } else if (OB_FAIL(cur_table_schema.is_partition_key(*column_schema, is_partition_key, + false /* ignore_presetting_key */))) { + LOG_WARN("fail to check partition key", KR(ret), K(cur_table_schema), KPC(column_schema)); + } else if (!is_partition_key && OB_FAIL(cur_table_schema.is_subpartition_key(*column_schema, is_subpartition_key, + false /* ignore_presetting_key */))) { + LOG_WARN("fail to check subpartition key", KR(ret), K(cur_table_schema), KPC(column_schema)); + } else if (is_partition_key || is_subpartition_key) { if (lib::is_oracle_mode() && !is_same) { ret = OB_ERR_MODIFY_PART_COLUMN_TYPE; SQL_RESV_LOG(WARN, "data type or len of a part column may not be changed", K(ret)); @@ -5748,7 +5903,7 @@ int ObAlterTableResolver::check_column_in_part_key(const ObTableSchema &table_sc ret = OB_OP_NOT_ALLOW; LOG_WARN("alter part key column of global index table is disallowed", K(ret), KPC(column_schema), K(cur_table_schema)); LOG_USER_ERROR(OB_OP_NOT_ALLOW, "alter part key of global index is"); - } else if (OB_FAIL(check_alter_part_key_allowed(cur_table_schema, *column_schema, dst_col_schema))) { + } else if (OB_FAIL(check_alter_part_key_allowed(cur_table_schema, *column_schema, dst_col_schema, is_partition_key))) { LOG_WARN("check alter partition key allowed failed", K(ret)); } } @@ -5781,8 +5936,9 @@ int ObAlterTableResolver::alter_column_expr_in_part_expr( } int ObAlterTableResolver::check_alter_part_key_allowed(const ObTableSchema &table_schema, - const ObColumnSchemaV2 &src_col_schema, - const ObColumnSchemaV2 &dst_col_schema) + const ObColumnSchemaV2 &src_col_schema, + const ObColumnSchemaV2 &dst_col_schema, + const bool is_part_key) { int ret = OB_SUCCESS; const uint64_t table_id = table_schema.get_table_id(); @@ -5811,11 +5967,18 @@ int ObAlterTableResolver::check_alter_part_key_allowed(const ObTableSchema &tabl CK (OB_NOT_NULL(resolver_ctx.query_ctx_)); OZ (delete_stmt->get_table_items().push_back(&table_item)); OZ (delete_stmt->set_table_bit_index(table_id)); - if (src_col_schema.is_part_key_column()) { - const ObString &part_str = table_schema.get_part_option().get_part_func_expr_str(); + if (is_part_key) { + ObArenaAllocator alloc; + ObString part_str; part_type = table_schema.get_part_option().get_part_func_type(); - OZ (delete_resolver.resolve_partition_expr(table_item, table_schema, - part_type, part_str, part_expr)); + if (OB_FAIL(ret)) { + } else if (OB_FAIL(table_schema.get_part_func_expr_str(part_str, alloc, + true/*using_auto_partitioned_mode*/))) { + LOG_WARN("fail to get part func expr str", KR(ret)); + } else if (OB_FAIL(delete_resolver.resolve_partition_expr(table_item, table_schema, + part_type, part_str, part_expr))) { + LOG_WARN("fail to resolve partition expr", KR(ret)); + } } else { const ObString &part_str = table_schema.get_sub_part_option().get_part_func_expr_str(); part_type = table_schema.get_sub_part_option().get_part_func_type(); diff --git a/src/sql/resolver/ddl/ob_alter_table_resolver.h b/src/sql/resolver/ddl/ob_alter_table_resolver.h index 222e1573e..f434d4f0a 100644 --- a/src/sql/resolver/ddl/ob_alter_table_resolver.h +++ b/src/sql/resolver/ddl/ob_alter_table_resolver.h @@ -93,6 +93,7 @@ public: int add_new_indexkey_for_oracle_temp_table(obrpc::ObCreateIndexArg &index_arg); private: + int fill_high_bound_val_for_split_partition(const AlterTableSchema &alter_table_schema, ObPartition& split_part); int check_dup_foreign_keys_exist( share::schema::ObSchemaGetterGuard *schema_guard, const obrpc::ObCreateForeignKeyArg &foreign_key_arg); @@ -179,6 +180,9 @@ private: const share::schema::ObTableSchema &origin_table_schema); int resolve_split_partition(const ParseNode *node, const share::schema::ObTableSchema &origin_table_schema); + int fill_split_source_tablet_id(const ObString& source_part_name, + const share::schema::ObTableSchema &origin_table_schema, + share::schema::AlterTableSchema &alter_table_schema); virtual int get_table_schema_for_check(share::schema::ObTableSchema &table_schema) override; //int generate_new_schema(const share::schema::ObTableSchema &origin_table_schema, // share::schema::AlterTableSchema &new_table_schema); @@ -193,7 +197,8 @@ private: ObRawExpr *part_expr); int check_alter_part_key_allowed(const share::schema::ObTableSchema &table_schema, const share::schema::ObColumnSchemaV2 &src_col_schema, - const share::schema::ObColumnSchemaV2 &dst_col_schema); + const share::schema::ObColumnSchemaV2 &dst_col_schema, + const bool is_part_key); int resolve_column_group_for_column(); int generate_index_arg_cascade(); int resolve_alter_column_groups(const ParseNode &node); diff --git a/src/sql/resolver/ddl/ob_create_index_resolver.cpp b/src/sql/resolver/ddl/ob_create_index_resolver.cpp index 7dad31871..25adf7d77 100644 --- a/src/sql/resolver/ddl/ob_create_index_resolver.cpp +++ b/src/sql/resolver/ddl/ob_create_index_resolver.cpp @@ -471,7 +471,7 @@ int ObCreateIndexResolver::resolve_index_option_node( if (has_index_using_type_) { crt_idx_stmt->set_index_using_type(index_using_type_); } - if (OB_FAIL(set_table_option_to_stmt(is_partitioned))) { + if (OB_FAIL(set_table_option_to_stmt(tbl_schema->get_table_id(), is_partitioned))) { LOG_WARN("fail to set table option to stmt", K(ret)); } else if (tbl_schema->is_partitioned_table() && INDEX_TYPE_SPATIAL_GLOBAL == crt_idx_stmt->get_create_index_arg().index_type_) { @@ -785,11 +785,14 @@ int ObCreateIndexResolver::add_sort_column(const ObColumnSortItem &sort_column) return ret; } -int ObCreateIndexResolver::set_table_option_to_stmt(bool is_partitioned) +int ObCreateIndexResolver::set_table_option_to_stmt(const uint64_t data_table_id, bool is_partitioned) { int ret = OB_SUCCESS; ObCreateIndexStmt *create_index_stmt = static_cast(stmt_); - if (OB_ISNULL(create_index_stmt) || OB_ISNULL(session_info_)) { + if (OB_UNLIKELY(OB_INVALID_ID == data_table_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(data_table_id)); + } else if (OB_ISNULL(create_index_stmt) || OB_ISNULL(session_info_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("create_index_stmt can not be null", K(ret)); } else if (is_oracle_temp_table_ && GLOBAL_INDEX == index_scope_) { @@ -807,6 +810,11 @@ int ObCreateIndexResolver::set_table_option_to_stmt(bool is_partitioned) // MySQL default index mode is local, // and Oracle default index mode is global global_ = is_partitioned || lib::is_oracle_mode(); + if (!global_) { + if (OB_FAIL(get_suggest_index_scope(index_arg.tenant_id_, data_table_id, index_arg, index_keyname_, global_))) { + LOG_WARN("get suggest index type failed", K(ret), K(index_arg)); + } + } } else { global_ = (GLOBAL_INDEX == index_scope_); } diff --git a/src/sql/resolver/ddl/ob_create_index_resolver.h b/src/sql/resolver/ddl/ob_create_index_resolver.h index 44a1e6b26..02dc024f8 100644 --- a/src/sql/resolver/ddl/ob_create_index_resolver.h +++ b/src/sql/resolver/ddl/ob_create_index_resolver.h @@ -31,6 +31,7 @@ public: virtual ~ObCreateIndexResolver(); virtual int resolve(const ParseNode &parse_tree); + ObCreateIndexStmt *get_create_index_stmt() { return static_cast(stmt_); }; protected: int resolve_index_name_node( ParseNode *index_name_node, @@ -55,7 +56,7 @@ protected: int check_generated_partition_column( share::schema::ObTableSchema &index_schema); int add_sort_column(const obrpc::ObColumnSortItem &sort_column); - int set_table_option_to_stmt(bool is_partitioned); + int set_table_option_to_stmt(const uint64_t data_table_id, bool is_partitioned); int add_new_indexkey_for_oracle_temp_table(); int fill_session_info_into_arg(const sql::ObSQLSessionInfo *session, ObCreateIndexStmt *crt_idx_stmt); diff --git a/src/sql/resolver/ddl/ob_create_table_resolver.cpp b/src/sql/resolver/ddl/ob_create_table_resolver.cpp index 3ec8a4fe1..cd05701e2 100644 --- a/src/sql/resolver/ddl/ob_create_table_resolver.cpp +++ b/src/sql/resolver/ddl/ob_create_table_resolver.cpp @@ -835,6 +835,41 @@ int ObCreateTableResolver::resolve(const ParseNode &parse_tree) } } } + + if (OB_SUCC(ret)) { + ObTableSchema &table_schema = create_table_stmt->get_create_table_arg().schema_; + ParseNode *partition_node = create_table_node->children_[5]; + if (table_schema.is_user_table()) { + if (nullptr != partition_node) { + // acquire partition_node with similar logic like resolve_partition_option() + const bool is_partition_option_node_with_opt = !is_mysql_mode || 1 != create_table_node->reserved_; + if (!is_partition_option_node_with_opt) { + // current node is partition node + } else if (T_VERTICAL_COLUMNS_PARTITION == partition_node->type_) { + // no need to resolve, partition node doesn't exist + partition_node = nullptr; + } else if (T_PARTITION_OPTION != partition_node->type_) { + ret = OB_INVALID_ARGUMENT; + SQL_RESV_LOG(WARN, "node type is invalid.", K(ret), K(partition_node->type_)); + } else if (OB_UNLIKELY(partition_node->num_child_ < 1 || partition_node->num_child_ > 2)) { + ret = OB_INVALID_ARGUMENT; + SQL_RESV_LOG(WARN, "node number is invalid.", K(ret), K(partition_node->num_child_)); + } else if (OB_ISNULL(partition_node->children_[0])) { + ret = OB_ERR_UNEXPECTED; + SQL_RESV_LOG(WARN, "partition node is null.", K(ret)); + } else { + partition_node = partition_node->children_[0]; + } + } + + if (FAILEDx(resolve_auto_partition_with_tenant_config(create_table_stmt, + partition_node, + table_schema))) { + LOG_WARN("fail to resolve auto partition with tenant config", + KR(ret), KPC(create_table_stmt), K(create_table_node)); + } + } + } } } // checking uk-pk and uk-uk duplicate in oracle mode @@ -975,12 +1010,10 @@ int ObCreateTableResolver::resolve_partition_option( } if (OB_SUCC(ret) && (OB_NOT_NULL(node) || table_schema.is_external_table() || is_oracle_temp_table_)) { if (OB_FAIL(check_generated_partition_column(table_schema))) { - LOG_WARN("Failed to check generate partiton column", KR(ret)); + LOG_WARN("Failed to check generate partition column", KR(ret)); } else if (OB_FAIL(table_schema.check_primary_key_cover_partition_column())) { SQL_RESV_LOG(WARN, "fail to check primary key cover partition column", KR(ret)); - } else if (OB_FAIL(table_schema.check_auto_partition_valid())) { - LOG_WARN("failed to check auto partition valid", KR(ret)); - } else { }//do nothing + } } return ret; } @@ -2448,6 +2481,7 @@ int ObCreateTableResolver::generate_index_arg() index_arg_.index_option_.index_status_ = INDEX_STATUS_AVAILABLE; index_arg_.index_option_.index_attributes_set_ = index_attributes_set_; index_arg_.sql_mode_ = session_info_->get_sql_mode(); + index_arg_.is_index_scope_specified_ = !(NOT_SPECIFIED == index_scope_); } if (OB_FAIL(ret)) { // skip @@ -3329,6 +3363,95 @@ int ObCreateTableResolver::resolve_table_charset_info(const ParseNode *node) { return ret; } +/* +* only when default columns store is column_store +* have to add each column group +*/ +int ObCreateTableResolver::resolve_column_group(const ParseNode *cg_node) +{ + int ret = OB_SUCCESS; + ObCreateTableStmt *create_table_stmt = static_cast(stmt_); + ObArray column_ids; // not include virtual column + uint64_t compat_version = 0; + ObTableStoreType table_store_type = OB_TABLE_STORE_INVALID; + + if (OB_ISNULL(create_table_stmt)) { + ret = OB_ERR_UNEXPECTED; + SQL_RESV_LOG(WARN, "create_table_stmt should not be null", KR(ret)); + } else { + ObTableSchema &table_schema = create_table_stmt->get_create_table_arg().schema_; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const int64_t column_cnt = table_schema.get_column_count(); + if (OB_FAIL(column_ids.reserve(column_cnt))) { + LOG_WARN("fail to reserve", KR(ret), K(column_cnt)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, compat_version))) { + LOG_WARN("fail to get min data version", KR(ret), K(tenant_id)); + } else if (!(compat_version >= DATA_VERSION_4_3_0_0)) { + if (OB_NOT_NULL(cg_node) && (T_COLUMN_GROUP == cg_node->type_)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("can't support column store if version less than 4_1_0_0", KR(ret), K(compat_version)); + } + } else { + table_schema.set_column_store(true); + bool is_each_cg_exist = false; + if (OB_NOT_NULL(cg_node)) { + if (OB_FAIL(parse_column_group(cg_node, table_schema, table_schema))) { + LOG_WARN("fail to parse column group", K(ret)); + } + } + + /* build column group when cg node is null && tenant cg valid*/ + ObTenantConfigGuard tenant_config(TENANT_CONF(session_info_->get_effective_tenant_id())); + if (OB_FAIL(ret)) { + } else if ( OB_LIKELY(tenant_config.is_valid()) && nullptr == cg_node) { + /* force to build each cg*/ + if (!ObSchemaUtils::can_add_column_group(table_schema)) { + } else if (OB_FAIL(ObTableStoreFormat::find_table_store_type( + tenant_config->default_table_store_format.get_value_string(), + table_store_type))) { + LOG_WARN("fail to get table store format", K(ret), K(table_store_type)); + } else if (ObTableStoreFormat::is_with_column(table_store_type)) { + /* for default is column store, must add each column group*/ + if (OB_FAIL(ObSchemaUtils::build_add_each_column_group(table_schema, table_schema))) { + LOG_WARN("fail to add each column group", K(ret)); + } + } + + /* force to build all cg*/ + ObColumnGroupSchema all_cg; + if (OB_FAIL(ret)) { + } else if (!ObSchemaUtils::can_add_column_group(table_schema)) { + } else if (ObTableStoreFormat::is_row_with_column_store(table_store_type)) { + if (OB_FAIL(ObSchemaUtils::build_all_column_group(table_schema, table_schema.get_tenant_id(), + table_schema.get_max_used_column_group_id() + 1, all_cg))) { + LOG_WARN("fail to add all column group", K(ret)); + } else if (OB_FAIL(table_schema.add_column_group(all_cg))) { + LOG_WARN("fail to build all column group", K(ret)); + } + } + } + + // add default_type column_group, build a empty and then use alter_deafult_cg + if (OB_SUCC(ret)) { + ObColumnGroupSchema tmp_cg; + column_ids.reuse(); + if (OB_FAIL(build_column_group(table_schema, ObColumnGroupType::DEFAULT_COLUMN_GROUP, + OB_DEFAULT_COLUMN_GROUP_NAME, column_ids, DEFAULT_TYPE_COLUMN_GROUP_ID, tmp_cg))) { + LOG_WARN("fail to build default type column_group", KR(ret), K(table_store_type), + "table_id", table_schema.get_table_id()); + } else if (OB_FAIL(table_schema.add_column_group(tmp_cg))) { + LOG_WARN("fail to add default column group", KR(ret), "table_id", table_schema.get_table_id()); + } else if (OB_FAIL(ObSchemaUtils::alter_rowkey_column_group(table_schema))) { + LOG_WARN("fail to adjust rowkey column group when add column group", K(ret)); + } else if (OB_FAIL(ObSchemaUtils::alter_default_column_group(table_schema))) { + LOG_WARN("fail to adjust default column group", K(ret)); + } + } + } + } + return ret; +} + int ObCreateTableResolver::resolve_auto_partition(const ParseNode *partition_node) { int ret = OB_SUCCESS; diff --git a/src/sql/resolver/ddl/ob_create_table_resolver.h b/src/sql/resolver/ddl/ob_create_table_resolver.h index efcd4f5c1..60934d1d3 100644 --- a/src/sql/resolver/ddl/ob_create_table_resolver.h +++ b/src/sql/resolver/ddl/ob_create_table_resolver.h @@ -128,9 +128,12 @@ private: int generate_uk_idx_array(const ObIArray &index_arg_list, ObIArray &uk_idx_in_index_arg_list); bool is_pk_uk_duplicate(const ObIArray &pk_columns_name, const ObIArray &index_arg_list, const ObIArray &uk_idx); bool is_uk_uk_duplicate(const ObIArray &uk_idx, const ObIArray &index_arg_list); + int resolve_auto_partition(const ParseNode *partition_node); int check_external_table_generated_partition_column_sanity(ObTableSchema &table_schema, ObRawExpr *dependant_expr, ObIArray &external_part_idx); typedef common::hash::ObPlacementHashSet VPColumnIdHashSet; + uint64_t gen_column_group_id(); + int resolve_column_group(const ParseNode *cg_node); int add_inner_index_for_heap_gtt(); int check_max_row_data_length(const ObTableSchema &table_schema); diff --git a/src/sql/resolver/ddl/ob_create_table_resolver_base.cpp b/src/sql/resolver/ddl/ob_create_table_resolver_base.cpp index 681e5b732..765fbaf9f 100644 --- a/src/sql/resolver/ddl/ob_create_table_resolver_base.cpp +++ b/src/sql/resolver/ddl/ob_create_table_resolver_base.cpp @@ -71,10 +71,6 @@ int ObCreateTableResolverBase::resolve_partition_option( } } /* vertical partition is not support in 4.x, remove its code here */ - } else if (T_AUTO_PARTITION == node->type_) { - if (OB_FAIL(resolve_auto_partition(node))) { - SQL_RESV_LOG(WARN, "failed to resolve auto partition", KR(ret)); - } } else { ret = OB_INVALID_ARGUMENT; SQL_RESV_LOG(WARN, "node type is invalid.", KR(ret), K(node->type_)); @@ -88,138 +84,6 @@ int ObCreateTableResolverBase::resolve_partition_option( return ret; } -int ObCreateTableResolverBase::resolve_auto_partition(const ParseNode *partition_node) -{ - int ret = OB_SUCCESS; - ObCreateTableStmt *create_table_stmt = - static_cast(stmt_); - if (OB_ISNULL(partition_node) - || T_AUTO_PARTITION != partition_node->type_ - || 2 != partition_node->num_child_ - || OB_ISNULL(partition_node->children_[0]) - || OB_ISNULL(partition_node->children_[1]) - || OB_ISNULL(create_table_stmt)) { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "node is unexpected", KR(ret), - "type", get_type_name(partition_node->type_), - "child_num", partition_node->num_child_); - } else { - const ParseNode *part_type_node = partition_node->children_[0]; - ObTableSchema &table_schema = - create_table_stmt->get_create_table_arg().schema_; - PartitionInfo part_info; - share::schema::ObPartitionFuncType part_func_type = share::schema::PARTITION_FUNC_TYPE_RANGE; - share::schema::ObPartitionOption *partition_option = NULL; - part_info.part_level_ = share::schema::PARTITION_LEVEL_ONE; - partition_option = &part_info.part_option_; - const ParseNode *part_expr_node = part_type_node->children_[0]; - if (T_RANGE_COLUMNS_PARTITION == part_type_node->type_) { - part_func_type = share::schema::PARTITION_FUNC_TYPE_RANGE_COLUMNS; - } else if (T_RANGE_PARTITION == part_type_node->type_) { - part_func_type = share::schema::PARTITION_FUNC_TYPE_RANGE; - } else { - ret = OB_NOT_SUPPORTED; - SQL_RESV_LOG(WARN, "part type not supported", KR(ret), - "type", get_type_name(part_type_node->type_)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "specified part type"); - } - if (OB_FAIL(ret)) { - } else if (OB_ISNULL(partition_option)) { - ret = OB_ERR_UNEXPECTED; - SQL_RESV_LOG(WARN, "partition option is null", KR(ret)); - } else { - partition_option->set_part_func_type(part_func_type); - partition_option->set_auto_part(true/*auto_part*/); - int64_t part_size = -1; - const ParseNode *part_size_node = partition_node->children_[1]; - if (T_VARCHAR == part_size_node->type_) { - bool valid = false; - common::ObSqlString buf; - if (OB_FAIL(buf.append(part_size_node->str_value_, part_size_node->str_len_))) { - SQL_RESV_LOG(WARN, "fail to assign child str", KR(ret)); - } else { - part_size = common::ObConfigCapacityParser::get(buf.ptr(), valid); - if (!valid) { - ret = common::OB_ERR_PARSE_SQL; - } else if (OB_UNLIKELY(0 == part_size)) { - ret = OB_INVALID_ARGUMENT; - SQL_RESV_LOG(WARN, "param, the param can't be zero", KR(ret), K(buf)); - } - } - } else if (T_AUTO == part_size_node->type_) { - part_size = 0; - } else { - ret = OB_NOT_SUPPORTED; - SQL_RESV_LOG(WARN, "part type not supported", KR(ret), - "type", get_type_name(part_size_node->type_)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "specified part type"); - } - if (OB_SUCC(ret)) { - partition_option->set_auto_part_size(part_size); - } - } - if (OB_FAIL(ret)) { - } else if (OB_ISNULL(part_expr_node)) { - //暂时不支持不指定分区键 - ret = OB_NOT_SUPPORTED; - LOG_WARN("none of partition key not supported", KR(ret)); - LOG_USER_ERROR(OB_NOT_SUPPORTED, "none of partition key"); - } else { - common::ObString func_expr_name; - const bool is_subpartition = false; - func_expr_name.assign_ptr( - const_cast(part_type_node->str_value_), - static_cast(part_type_node->str_len_)); - if (OB_FAIL(resolve_part_func(params_, - part_expr_node, - part_func_type, - table_schema, - part_info.part_func_exprs_, - part_info.part_keys_))) { - SQL_RESV_LOG(WARN, "resolve part func failed", KR(ret)); - } else if (OB_FAIL(partition_option->set_part_expr(func_expr_name))) { - SQL_RESV_LOG(WARN, "set partition express string failed", KR(ret)); - } else if (OB_FAIL(set_partition_keys(table_schema, part_info.part_keys_, - is_subpartition))) { - SQL_RESV_LOG(WARN, "Failed to set partition keys", KR(ret), - K(table_schema), K(is_subpartition)); - } else { - //填充max_value - ObPartition partition; - common::ObArray rowkeys; - common::ObString part_name = common::ObString::make_string("p0"); - for (int64_t i = 0; i < part_info.part_keys_.count() && OB_SUCC(ret); ++i) { - common::ObObj obj = ObObj::make_max_obj(); - if (OB_FAIL(rowkeys.push_back(obj))) { - LOG_WARN("failed to push back obj", KR(ret), K(i)); - } - } - if (OB_SUCC(ret)) { - if (0 >= rowkeys.count()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("rowkey count can not be zero", KR(ret), K(rowkeys), - "partition_key", part_info.part_keys_); - } else { - common::ObRowkey high_value(&rowkeys.at(0), rowkeys.count()); - if (OB_FAIL(partition.set_high_bound_val(high_value))) { - LOG_WARN("failed to set high bound value", KR(ret), K(high_value)); - } else if (OB_FAIL(partition.set_part_name(part_name))) { - LOG_WARN("failed to set part name", KR(ret), K(part_name)); - } else if (OB_FAIL(table_schema.add_partition(partition))) { - LOG_WARN("failed to add partition", KR(ret), K(partition), K(table_schema)); - } - } - } - } - } - if (OB_SUCC(ret)) { - table_schema.get_part_option() = *partition_option; - table_schema.set_part_level(share::schema::PARTITION_LEVEL_ONE); - } - } - return ret; -} - int ObCreateTableResolverBase::set_table_option_to_schema(ObTableSchema &table_schema) { int ret = OB_SUCCESS; @@ -242,7 +106,7 @@ int ObCreateTableResolverBase::set_table_option_to_schema(ObTableSchema &table_s table_schema.set_is_use_bloomfilter(use_bloom_filter_); table_schema.set_auto_increment(auto_increment_); table_schema.set_tenant_id(tenant_id); - table_schema.set_tablegroup_id(OB_SYS_TABLEGROUP_ID); + table_schema.set_tablegroup_id(OB_INVALID_ID); table_schema.set_table_id(table_id_); table_schema.set_read_only(read_only_); table_schema.set_duplicate_scope(duplicate_scope_); diff --git a/src/sql/resolver/ddl/ob_create_table_resolver_base.h b/src/sql/resolver/ddl/ob_create_table_resolver_base.h index 2763a97b5..4ed1f4031 100644 --- a/src/sql/resolver/ddl/ob_create_table_resolver_base.h +++ b/src/sql/resolver/ddl/ob_create_table_resolver_base.h @@ -32,8 +32,7 @@ public: virtual ~ObCreateTableResolverBase(); protected: - int resolve_auto_partition(const ParseNode *partition_node); - //resolve partitoin option only used in ObCreateTableResolver now. + //resolve partition option only used in ObCreateTableResolver now. int resolve_partition_option(ParseNode *node, share::schema::ObTableSchema &table_schema, const bool is_partition_option_node_with_opt); diff --git a/src/sql/resolver/ddl/ob_ddl_resolver.cpp b/src/sql/resolver/ddl/ob_ddl_resolver.cpp index 832bb9c85..c26f5ce3b 100644 --- a/src/sql/resolver/ddl/ob_ddl_resolver.cpp +++ b/src/sql/resolver/ddl/ob_ddl_resolver.cpp @@ -2932,7 +2932,7 @@ int ObDDLResolver::resolve_table_option(const ParseNode *option_node, const bool break; } case T_MICRO_INDEX_CLUSTERED: { - uint64_t tenant_data_version = 0;; + uint64_t tenant_data_version = 0; if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, tenant_data_version))) { LOG_WARN("get tenant data version failed", K(ret)); } else if (tenant_data_version < DATA_VERSION_4_3_3_0) { @@ -8558,6 +8558,8 @@ int ObDDLResolver::resolve_index_partition_node( LOG_USER_ERROR(OB_NOT_SUPPORTED, "non global index with partition option"); } else if (OB_FAIL(resolve_partition_node(crt_idx_stmt, index_partition_node, index_schema))) { LOG_WARN("failed to resolve partition node", K(ret)); + } else if (OB_FAIL(resolve_auto_partition(crt_idx_stmt, index_partition_node, index_schema))) { + LOG_WARN("failed to resolve auto partition option", K(ret)); } else if (PARTITION_LEVEL_ZERO == index_schema.get_part_level() || PARTITION_LEVEL_ONE == index_schema.get_part_level()) { // good @@ -10782,7 +10784,15 @@ int ObDDLResolver::resolve_partition_node(ObPartitionedStmt *stmt, } if (OB_SUCC(ret) && !table_schema.is_external_table()) { - if (OB_FAIL(check_and_set_partition_names(stmt, table_schema))) { + if (PARTITION_LEVEL_ZERO == table_schema.get_part_level()) { + if (is_range_type_partition(part_node->type_) && + nullptr == part_node->children_[RANGE_ELEMENTS_NODE]) { + // auto-partitioned non-partitioned table + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("non-partitioned table should not have partition clause", KR(ret)); + } + } else if (OB_FAIL(check_and_set_partition_names(stmt, table_schema))) { LOG_WARN("failed to check and set partition names", K(ret)); } } @@ -11362,121 +11372,568 @@ int ObDDLResolver::resolve_partition_range(ObPartitionedStmt *stmt, common::ObSEArray part_func_exprs; common::ObSEArray range_values_exprs; share::schema::ObPartitionOption *partition_option = NULL; + static const int32_t RANGE_PARTITION_NODE_NUM = 7; + static const int32_t RANGE_SUBPARTITION_NODE_NUM = 5; - if (OB_ISNULL(stmt) || OB_ISNULL(node) || OB_ISNULL(node->children_) || - OB_ISNULL(node->children_[RANGE_ELEMENTS_NODE])) { + if (OB_ISNULL(stmt) || OB_ISNULL(node) || OB_ISNULL(node->children_)) { ret = OB_ERR_UNEXPECTED; SQL_RESV_LOG(WARN, "get unexpected null", K(ret), K(stmt), K(node)); } else if (!is_range_type_partition(node->type_)) { ret = OB_ERR_UNEXPECTED; SQL_RESV_LOG(WARN, "get unexpected partition type", K(ret), K(node->type_)); - } else if (is_subpartition) { - partition_option = &(table_schema.get_sub_part_option()); - table_schema.set_part_level(share::schema::PARTITION_LEVEL_TWO); + } else if (OB_UNLIKELY(!is_subpartition && RANGE_PARTITION_NODE_NUM != node->num_child_) || + OB_UNLIKELY(is_subpartition && RANGE_SUBPARTITION_NODE_NUM != node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + SQL_RESV_LOG(WARN, "get invalid num_child", KR(ret), K(is_subpartition), K(node->num_child_)); + } else if (nullptr == node->children_[RANGE_ELEMENTS_NODE]) { + if (!is_subpartition) { + // auto_partition clause allow sql without partition definition, do nothing + // e.g. create table t1 (c1 int primary key, c2 int) partition by range('c1') + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("subpartition without partition definition", KR(ret)); + } } else { - partition_option = &(table_schema.get_part_option()); - table_schema.set_part_level(share::schema::PARTITION_LEVEL_ONE); - } - - if (OB_SUCC(ret)) { - if (NULL != node->children_[RANGE_SUBPARTITIOPPN_NODE]) { - bool force_template = false; - if (NULL != node->children_[RANGE_SUBPARTITIOPPN_NODE]->children_[RANGE_TEMPLATE_MARK]) { - // 模板化的二级分区定义后面再解析 - stmt->set_use_def_sub_part(true); - } else if (OB_FAIL(resolve_individual_subpartition(stmt, node, - node->children_[RANGE_ELEMENTS_NODE], - node->children_[RANGE_SUBPARTITIOPPN_NODE], - table_schema, force_template))) { - SQL_RESV_LOG(WARN, "failed to resolve individual subpartition", K(ret)); - } else if (force_template) { - stmt->set_use_def_sub_part(true); - } else { - stmt->set_use_def_sub_part(false); - } - } - } - - // 1. resolve partition type, partition keys, partition expr - if (OB_SUCC(ret)) { - if (OB_FAIL(resolve_range_partition_basic_infos(node, is_subpartition, table_schema, - part_func_type, func_expr_name, part_func_exprs))) { - SQL_RESV_LOG(WARN, "failed to resolve range partition basic infos", K(ret)); - } else if (OB_FAIL(partition_option->set_part_expr(func_expr_name))) { - SQL_RESV_LOG(WARN, "set partition express string failed", K(ret)); - } else { - partition_option->set_part_func_type(part_func_type); - } - } - - // 2. resolve range partition define - if (OB_SUCC(ret)) { - if (NULL != node->children_[RANGE_PARTITION_NUM_NODE]) { - partition_num = node->children_[RANGE_PARTITION_NUM_NODE]->value_; - if (partition_num != node->children_[RANGE_ELEMENTS_NODE]->num_child_) { - ret = OB_ERR_PARSE_PARTITION_RANGE; - } - } else { - partition_num = node->children_[RANGE_ELEMENTS_NODE]->num_child_; - } - partition_option->set_part_num(partition_num); - if (OB_SUCC(ret)) { - if (OB_FAIL(check_partition_name_duplicate(node->children_[RANGE_ELEMENTS_NODE], - lib::is_oracle_mode()))) { - SQL_RESV_LOG(WARN, "duplicate partition name", K(ret)); - } else if (is_subpartition) { - if (OB_FAIL(resolve_range_subpartition_elements(stmt, - node->children_[RANGE_ELEMENTS_NODE], - table_schema, - NULL, // dummy partition - part_func_type, - part_func_exprs, - range_values_exprs))) { - SQL_RESV_LOG(WARN, "resolve reange partition elements fail", K(ret)); - } - } else { - if (OB_FAIL(resolve_range_partition_elements(stmt, - node->children_[RANGE_ELEMENTS_NODE], - table_schema, - part_func_type, - part_func_exprs, - range_values_exprs))) { - SQL_RESV_LOG(WARN, "resolve reange partition elements fail", K(ret)); - } - } - } - } - // 2.5 resolve interval clause - OZ (resolve_interval_clause(stmt, node, table_schema, range_values_exprs)); - - // 解析模板化二级分区定义 - if (OB_SUCC(ret)) { - if (NULL != node->children_[RANGE_SUBPARTITIOPPN_NODE] && stmt->use_def_sub_part()) { - if (OB_FAIL(resolve_subpartition_option(stmt, node->children_[RANGE_SUBPARTITIOPPN_NODE], table_schema))) { - SQL_RESV_LOG(WARN, "failed to resolve subpartition", K(ret)); - } - } - } - - if (OB_SUCC(ret)) { if (is_subpartition) { - if (OB_FAIL(stmt->get_subpart_fun_exprs().assign(part_func_exprs))) { - SQL_RESV_LOG(WARN, "failed to assign range fun exprs", K(ret)); - } else if (OB_FAIL(stmt->get_template_subpart_values_exprs().assign(range_values_exprs))) { - SQL_RESV_LOG(WARN, "failed to assign range values exprs", K(ret)); - } + partition_option = &(table_schema.get_sub_part_option()); + table_schema.set_part_level(share::schema::PARTITION_LEVEL_TWO); } else { - if (OB_FAIL(stmt->get_part_fun_exprs().assign(part_func_exprs))) { - SQL_RESV_LOG(WARN, "failed to assign range fun exprs", K(ret)); - } else if (OB_FAIL(stmt->get_part_values_exprs().assign(range_values_exprs))) { - SQL_RESV_LOG(WARN, "failed to assign range values exprs", K(ret)); + partition_option = &(table_schema.get_part_option()); + table_schema.set_part_level(share::schema::PARTITION_LEVEL_ONE); + } + + if (OB_SUCC(ret)) { + if (NULL != node->children_[RANGE_SUBPARTITION_NODE]) { + bool force_template = false; + if (NULL != node->children_[RANGE_SUBPARTITION_NODE]->children_[RANGE_TEMPLATE_MARK]) { + // 模板化的二级分区定义后面再解析 + stmt->set_use_def_sub_part(true); + } else if (OB_FAIL(resolve_individual_subpartition(stmt, node, + node->children_[RANGE_ELEMENTS_NODE], + node->children_[RANGE_SUBPARTITION_NODE], + table_schema, force_template))) { + SQL_RESV_LOG(WARN, "failed to resolve individual subpartition", K(ret)); + } else if (force_template) { + stmt->set_use_def_sub_part(true); + } else { + stmt->set_use_def_sub_part(false); + } } } - SQL_RESV_LOG(DEBUG, "succ to resolve_partition_range", KPC(stmt), K(part_func_exprs), K(range_values_exprs)); + + // 1. resolve partition type, partition keys, partition expr + if (OB_SUCC(ret)) { + if (OB_FAIL(resolve_range_partition_basic_infos(node, is_subpartition, table_schema, + part_func_type, func_expr_name, part_func_exprs))) { + SQL_RESV_LOG(WARN, "failed to resolve range partition basic infos", K(ret)); + } else if (OB_FAIL(partition_option->set_part_expr(func_expr_name))) { + SQL_RESV_LOG(WARN, "set partition express string failed", K(ret)); + } else { + partition_option->set_part_func_type(part_func_type); + } + } + + // 2. resolve range partition define + if (OB_SUCC(ret)) { + if (NULL != node->children_[RANGE_PARTITION_NUM_NODE]) { + partition_num = node->children_[RANGE_PARTITION_NUM_NODE]->value_; + if (partition_num != node->children_[RANGE_ELEMENTS_NODE]->num_child_) { + ret = OB_ERR_PARSE_PARTITION_RANGE; + } + } else { + partition_num = node->children_[RANGE_ELEMENTS_NODE]->num_child_; + } + partition_option->set_part_num(partition_num); + if (OB_SUCC(ret)) { + if (OB_FAIL(check_partition_name_duplicate(node->children_[RANGE_ELEMENTS_NODE], + lib::is_oracle_mode()))) { + SQL_RESV_LOG(WARN, "duplicate partition name", K(ret)); + } else if (is_subpartition) { + if (OB_FAIL(resolve_range_subpartition_elements(stmt, + node->children_[RANGE_ELEMENTS_NODE], + table_schema, + NULL, // dummy partition + part_func_type, + part_func_exprs, + range_values_exprs))) { + SQL_RESV_LOG(WARN, "resolve reange partition elements fail", K(ret)); + } + } else { + if (OB_FAIL(resolve_range_partition_elements(stmt, + node->children_[RANGE_ELEMENTS_NODE], + table_schema, + part_func_type, + part_func_exprs, + range_values_exprs))) { + SQL_RESV_LOG(WARN, "resolve reange partition elements fail", K(ret)); + } + } + } + } + // 2.5 resolve interval clause + OZ (resolve_interval_clause(stmt, node, table_schema, range_values_exprs)); + + // 解析模板化二级分区定义 + if (OB_SUCC(ret)) { + if (NULL != node->children_[RANGE_SUBPARTITION_NODE] && stmt->use_def_sub_part()) { + if (OB_FAIL(resolve_subpartition_option(stmt, node->children_[RANGE_SUBPARTITION_NODE], table_schema))) { + SQL_RESV_LOG(WARN, "failed to resolve subpartition", K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + if (is_subpartition) { + if (OB_FAIL(stmt->get_subpart_fun_exprs().assign(part_func_exprs))) { + SQL_RESV_LOG(WARN, "failed to assign range fun exprs", K(ret)); + } else if (OB_FAIL(stmt->get_template_subpart_values_exprs().assign(range_values_exprs))) { + SQL_RESV_LOG(WARN, "failed to assign range values exprs", K(ret)); + } + } else { + if (OB_FAIL(stmt->get_part_fun_exprs().assign(part_func_exprs))) { + SQL_RESV_LOG(WARN, "failed to assign range fun exprs", K(ret)); + } else if (OB_FAIL(stmt->get_part_values_exprs().assign(range_values_exprs))) { + SQL_RESV_LOG(WARN, "failed to assign range values exprs", K(ret)); + } + } + SQL_RESV_LOG(DEBUG, "succ to resolve_partition_range", KPC(stmt), K(part_func_exprs), K(range_values_exprs)); + } } return ret; } +// at first, resolve auto-partition clause. +// then, if user doesn't use the clause, check whether enable auto-partition by tenant config +int ObDDLResolver::resolve_auto_partition_with_tenant_config(ObCreateTableStmt *stmt, ParseNode *node, + ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + + if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", KR(ret), K(stmt)); + } else if (nullptr != node && OB_FAIL(resolve_auto_partition(stmt, node, table_schema))) { + LOG_WARN("fail to resolve auto partition", KR(ret), K(table_schema), KPC(stmt)); + } else if (!stmt->use_auto_partition_clause() && + OB_FAIL(try_set_auto_partition_by_config(stmt->get_index_arg_list(), table_schema))) { + LOG_WARN("fail to try to set auto_partition by config", KR(ret), K(table_schema), KPC(stmt)); + } + return ret; +} + +int ObDDLResolver::check_only_modify_auto_partition_attr(ObPartitionedStmt *stmt, ParseNode *node, + ObTableSchema &table_schema, + bool &is_only_modify_auto_part_attr) +{ + int ret = OB_SUCCESS; + bool SET_PARTITION_DEFINITION = false; + bool SET_AUTO_PARTITION_SIZE = false; + bool SET_PARTITION_KEY = false; + is_only_modify_auto_part_attr = false; + if (OB_ISNULL(node) || OB_ISNULL(node->children_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", KR(ret), K(node)); + } else if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", KR(ret), K(stmt)); + } else if (!table_schema.is_partitioned_table() || + table_schema.get_part_option().is_valid_split_part_type()) { + static const int32_t RANGE_PARTITION_NODE_NUM = 7; + SET_PARTITION_DEFINITION = node->children_[RANGE_ELEMENTS_NODE] != nullptr; + SET_PARTITION_KEY = node->children_[RANGE_FUN_EXPR_NODE] != nullptr; + SET_AUTO_PARTITION_SIZE = node->children_[RANGE_AUTO_SPLIT_TABLET_SIZE] != nullptr; + if (RANGE_PARTITION_NODE_NUM == node->num_child_) { + SET_AUTO_PARTITION_SIZE = node->children_[RANGE_AUTO_SPLIT_TABLET_SIZE] != nullptr; + } + if (!SET_PARTITION_DEFINITION && (SET_AUTO_PARTITION_SIZE || !SET_PARTITION_KEY)) { + is_only_modify_auto_part_attr = true; + } + } + return ret; +} + +// we have two types of auto-partition clause in "partition by" clause: +// 1. using "size" clause: +// e.g. create table t1 (c1 int primary key, c2 int) +// partition by range(c1) size('128MB') +// (partition p0 value less than(100), +// partition p1 value less than(MAXVALUE)) +// 2. using "partition by" clause without partition definition (whatever set presetting partition key or not): +// e.g.1. create table t1 (c1 int primary key, c2 int) partition by range() +// e.g.2. create table t1 (c1 int primary key, c2 int) partition by range('c1') +// e.g.3. create table t1 (c1 int primary key, c2 int) partition by range('c1') size('128MB') +// spcifically, if using this clause to enable auto partition and the "size" is not specified, +// it will be filled with default tenant config. +// Attention: +// 1. Some partition definitions are conflict with auto-partition attributes, +// such as the existence of space index of table. +// Thus, we will check invalid settings of schema in rootservice +// 2. Only data_table could set auto-partition attributes by using auto_partition clause. +// the auto-partition attributes of the global index are generated in RS based on its data_table. +int ObDDLResolver::resolve_auto_partition(ObPartitionedStmt *stmt, ParseNode *node, + ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + static const char* UNLIMITED_STR = "unlimited"; + bool SET_PARTITION_DEFINITION = false; + bool SET_SUBPARTITION_DEFINITION = false; + bool SET_PARTITION_KEY = false; + bool SET_AUTO_PARTITION_SIZE = false; + bool SET_AUTO_PARTITION_NUM = false; + int64_t auto_part_size = 0; + bool enable_auto_split = false; + + if (OB_ISNULL(node) || OB_ISNULL(node->children_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", KR(ret), K(node)); + } else if (OB_ISNULL(stmt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", KR(ret), K(stmt)); + } else if (!table_schema.is_partitioned_table() || + table_schema.get_part_option().is_valid_split_part_type()) { + static const int32_t RANGE_PARTITION_NODE_NUM = 7; + if (OB_UNLIKELY(RANGE_PARTITION_NODE_NUM != node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + SQL_RESV_LOG(WARN, "get invalid num_child", KR(ret), K(node->num_child_)); + } else if (FALSE_IT(SET_PARTITION_DEFINITION = node->children_[RANGE_ELEMENTS_NODE] != nullptr)) { + } else if (FALSE_IT(SET_SUBPARTITION_DEFINITION = node->children_[RANGE_SUBPARTITION_NODE] != nullptr)) { + } else if (FALSE_IT(SET_PARTITION_KEY = node->children_[RANGE_FUN_EXPR_NODE] != nullptr)) { + } else if (FALSE_IT(SET_AUTO_PARTITION_SIZE = node->children_[RANGE_AUTO_SPLIT_TABLET_SIZE] != nullptr)) { + } else if (FALSE_IT(SET_AUTO_PARTITION_NUM = node->children_[RANGE_PARTITION_NUM_NODE] != nullptr)) { + } else if (!SET_PARTITION_DEFINITION && SET_AUTO_PARTITION_NUM) { + ret = OB_ERR_PARSE_PARTITION_RANGE; + LOG_WARN("in range partition, partition number can only be set, where partition definition has been set", + KR(ret), K(table_schema.get_table_type())); + } else if (SET_PARTITION_DEFINITION) { + if (!SET_PARTITION_KEY) { + // non-partitioned table could ingore partition key setting and enable auto-partition setting, + // e.g.: + // create table t1 ... partition by range() size('128') + // however, partitioned table must have a partition key whatever auto-partition is enabled or not. + // incorrect example: + // create table t1 ... partition by range() size('128') + // (partition p0 value less than(100), + // partition p1 value less than(MAXVALUE)); + ret = OB_INVALID_ARGUMENT; + SQL_RESV_LOG(WARN, "invalid argument", KR(ret), K(node->children_)); + } else if (SET_SUBPARTITION_DEFINITION && SET_AUTO_PARTITION_SIZE) { + ret = OB_NOT_SUPPORTED; + SQL_RESV_LOG(WARN, "auto partition for subpartition is", KR(ret), K(node->children_)); + } + } else if (SET_SUBPARTITION_DEFINITION) { // !SET_PARTITION_DEFINITION + ret = OB_INVALID_ARGUMENT; + SQL_RESV_LOG(WARN, "invalid argument", KR(ret), K(node->children_)); + } + + if (OB_FAIL(ret)) { + } else if (FALSE_IT(stmt->set_use_auto_partition_clause(!SET_PARTITION_DEFINITION + || SET_AUTO_PARTITION_SIZE))) { + } else if (!stmt->use_auto_partition_clause()) { + // user doesn't use auto-partitioning sql, we will disable the feature. + // e.g. create table t1 (c1 int primary key) + // partition by range(c1) (PARTITION p0 VALUES LESS THAN (MAXVALUE)) + } else if (!table_schema.is_user_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not allow non-user-table to set auto-partition clause", KR(ret), K(table_schema.get_table_type())); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "using auto-partition clause for non-user-table is"); + } else { // table_schema.is_user_table() && stmt->use_auto_partition_clause() + if (!SET_PARTITION_DEFINITION && + OB_FAIL(resolve_presetting_partition_key(node, table_schema))) { + // non-partitioned table + LOG_WARN("fail to resolve presetting partition key", KR(ret), K(node->children_)); + } else if (SET_AUTO_PARTITION_SIZE) { // SET_AUTO_PARTITION_SIZE means auto_split_size_node is not null + ParseNode *auto_split_size_node = node->children_[RANGE_AUTO_SPLIT_TABLET_SIZE]; + if (T_AUTO_SPLIT_TABLET_SIZE != auto_split_size_node->type_) { + ret = OB_NOT_SUPPORTED; + SQL_RESV_LOG(WARN, "the type of auto_split_size_node is not varchar", + KR(ret), K(auto_split_size_node->type_)); + } else if (0 == ObString(auto_split_size_node->str_value_).case_compare(UNLIMITED_STR)) { + auto_part_size = 0; // forbid auto_parititon feature + } else { + bool valid = false; + common::ObSqlString buf; + if (OB_FAIL(buf.append(auto_split_size_node->str_value_, auto_split_size_node->str_len_))) { + SQL_RESV_LOG(WARN, "fail to assign child str", KR(ret)); + } else if (FALSE_IT(auto_part_size = common::ObConfigCapacityParser::get(buf.ptr(), valid, false))){ + } else if (!valid) { + ret = common::OB_ERR_PARSE_SQL; + LOG_WARN("invalid size", KR(ret), K(buf)); + } + } + } + + // check whether activate auto-partition + if (OB_FAIL(ret)) { + } else if (SET_AUTO_PARTITION_SIZE) { + if (auto_part_size == 0) { + SQL_RESV_LOG(INFO, "the auto split tablet size is configured as unlimited"); + enable_auto_split = false; + } else { + enable_auto_split = true; + } + } else { + // user activates auto-partitioning feature without specified auto_split_size. + // e.g. create table t1 (c1 int primary key) partition by range(); + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(MTL_ID())); + if (!tenant_config.is_valid()) { + ret = OB_EAGAIN; + LOG_WARN("tenant_config has not been loaded", KR(ret)); + } else { + enable_auto_split = true; + auto_part_size = tenant_config->auto_split_tablet_size; + LOG_INFO("use default tenant config for auto partitioning", K(auto_part_size)); + } + } + + uint64_t data_version = 0; + if (OB_FAIL(ret)) { + } else if (!enable_auto_split) { + table_schema.forbid_auto_partition(); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), data_version))) { + LOG_WARN("fail to get min data version", KR(ret), K(MTL_ID())); + } else if (data_version < DATA_VERSION_4_3_4_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("current data version doesn't support to auto split partition", KR(ret), K(data_version)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "data version lower than 4.4 is"); + } else if(OB_FAIL(table_schema.enable_auto_partition(auto_part_size))) { + LOG_WARN("fail to enable auto partition", KR(ret), K(table_schema)); + } + } + } + + return ret; +} + +// Resolve presetting partition key of auto-partitioned non-partitioned table. +// When auto-partitioned non-partitioned table triggers auto-partitioning, +// the table will choose presetting partition key as actually partition key. +// Specifically, if user doesn't set presetting partition key, +// when the table triggers auto-partitioning, +// if the table is data table, it will choose primary key as presetting partition key; +// if the table is global index, it will choose index columns as presetting partition key +int ObDDLResolver::resolve_presetting_partition_key(ParseNode *node, ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + const ObRowkeyInfo &rowkey_info = table_schema.get_rowkey_info(); + ObString part_func_name; + ParseNode *partition_fun_node = NULL; + ObSEArray presetting_partition_keys; + common::ObSEArray part_func_exprs; + share::schema::ObPartitionFuncType part_func_type = share::schema::PARTITION_FUNC_TYPE_MAX; + ObArenaAllocator alloc; + static const int32_t RANGE_PARTITION_NODE_NUM = 7; + + // check presetting partition func type whether is valid for auto-partition + if (OB_ISNULL(node) || OB_ISNULL(node->children_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get unexpected null", KR(ret), K(node)); + } else if (OB_UNLIKELY(RANGE_PARTITION_NODE_NUM != node->num_child_)) { + ret = OB_ERR_UNEXPECTED; + SQL_RESV_LOG(WARN, "get invalid num_child", KR(ret), K(node->num_child_)); + } else if (!table_schema.is_user_table()) { + // we only allow user-table to set presetting partition key by using auto-partition clause. + // the presetting partition key of auto-partitioned non-partitioned global indexs will be set as "empty", + // which means using index columns as presetting partition key + ret = OB_NOT_SUPPORTED; + LOG_WARN("set presetting partition key for non-user-table", KR(ret), K(table_schema.get_table_type())); + } else if (T_RANGE_COLUMNS_PARTITION == node->type_) { + part_func_type = PARTITION_FUNC_TYPE_RANGE_COLUMNS; + } else if (T_RANGE_PARTITION == node->type_) { + part_func_type = PARTITION_FUNC_TYPE_RANGE; + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("only support to auto partitioning range or range columns partition", KR(ret), K(node->type_)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "hash/list/interval partition is"); + } + + // check presetting partition key whether is equal to prefix of rowkey for auto-partition + if (OB_FAIL(ret)) { + } else if (OB_NOT_NULL(node->children_[RANGE_ELEMENTS_NODE])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("check presetting partition key for partitioned table", KR(ret)); + } else if (table_schema.is_heap_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support to auto partitioning no primary key table", KR(ret), K(table_schema)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "auto partitioned table without primary key is"); + } else if ((partition_fun_node = node->children_[RANGE_FUN_EXPR_NODE]) == nullptr) { + // empty presetting partition key, do nothing + } else if (OB_FAIL(resolve_part_func(params_, partition_fun_node, part_func_type, + table_schema, part_func_exprs, presetting_partition_keys))) { + LOG_WARN("resolve part func failed", KR(ret)); + } else { + const int64_t rowkey_size = table_schema.get_rowkey_column_num() - table_schema.get_shadow_rowkey_column_num(); + bool is_matched_prefix = true; + if (OB_UNLIKELY(rowkey_size < presetting_partition_keys.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid presetting partition key", KR(ret), K(presetting_partition_keys), K(rowkey_info)); + LOG_USER_ERROR(OB_ERR_UNEXPECTED, "mismatching between presetting partition key and primary key"); + } else { + for (int64_t i = 0; OB_SUCC(ret) && is_matched_prefix && i < presetting_partition_keys.count(); i++) { + uint64_t rowkey_column_id = OB_INVALID_ID; + const common::ObString &column_name = presetting_partition_keys.at(i); + const ObColumnSchemaV2 *column = table_schema.get_column_schema(column_name); + + if (OB_FAIL(rowkey_info.get_column_id(i, rowkey_column_id))) { + LOG_WARN("failed to get rowkey column id", KR(ret), K(i)); + } else if (OB_ISNULL(column)) { + ret = OB_ERR_BAD_FIELD_ERROR; + LOG_WARN("fail to get column schema", KR(ret), K(column_name)); + } else if (rowkey_column_id != column->get_column_id()) { + is_matched_prefix = false; + } + } // end for + + if (OB_FAIL(ret)) { + } else if (is_matched_prefix) { + part_func_name.assign_ptr(node->str_value_, static_cast(node->str_len_)); + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("auto-partitioning should keep primary key prefix equal to partition key", + KR(ret), K(presetting_partition_keys), K(table_schema)); + LOG_USER_ERROR(OB_NOT_SUPPORTED, "mismatching between primary key prefix and partition key is"); + } + } + } + + if (OB_SUCC(ret)) { + if (OB_FAIL(ObSQLUtils::convert_sql_text_to_schema_for_storing( + alloc, session_info_->get_dtc_params(), part_func_name))) { + LOG_WARN("fail to copy and convert string charset", KR(ret)); + } else if (OB_FAIL(table_schema.get_part_option().set_part_expr(part_func_name))) { + SQL_RESV_LOG(WARN, "set partition expression string failed", KR(ret), K(part_func_name)); + } + } + + return ret; +} + +// if tenant_config->enable_auto_split == true and table_schema is valid for auto-partition, +// enable auto-partition for the table; +// otherwise, do nothing +int ObDDLResolver::try_set_auto_partition_by_config(common::ObIArray &index_arg_list, + ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + + if (!table_schema.is_user_table()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("attempt to set auto_partition by tenant config for non_user_table", KR(ret), K(table_schema)); + } else if (table_schema.is_partitioned_table() && + !table_schema.get_part_option().is_valid_split_part_type()) { + // do nothing + } else { + uint64_t tenant_id = table_schema.get_tenant_id(); + omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id)); + + if (!tenant_config.is_valid()) { + table_schema.forbid_auto_partition(); + LOG_INFO("tenant_config has not been loaded over"); + } else if (tenant_config->enable_auto_split) { + // check table + if (OB_FAIL(table_schema.enable_auto_partition(tenant_config->auto_split_tablet_size))) { + LOG_WARN("fail to enable auto partition", KR(ret), K(table_schema)); + } else if (OB_FAIL(table_schema.check_validity_for_auto_partition())) { + if (OB_NOT_SUPPORTED == ret) { + LOG_INFO("table schema is not valid for auto partition, " + "not allow to enable auto_partition by default config", K(table_schema)); + } else { + LOG_WARN("fail to check validity for auto-partition", KR(ret), K(table_schema)); + } + } else if (!table_schema.is_partitioned_table()) { + // if data_table is non-partitioned table, when trigger auto-partitioning, + // we will choose primary key as partition key and set range partition type for it. + // thus, we need to check whether the primary key is valid partition column type + const ObRowkeyInfo &presetting_partition_keys = table_schema.get_rowkey_info(); + ObPartitionFuncType part_type = presetting_partition_keys.get_size() > 1 ? + ObPartitionFuncType::PARTITION_FUNC_TYPE_RANGE_COLUMNS : + ObPartitionFuncType::PARTITION_FUNC_TYPE_RANGE; + for (int64_t i = 0; OB_SUCC(ret) && i < presetting_partition_keys.get_size(); ++i) { + const ObRowkeyColumn *partition_column = presetting_partition_keys.get_column(i); + if (OB_ISNULL(partition_column)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the partition column is NULL, ", KR(ret), K(i), K(presetting_partition_keys)); + } else { + ObObjType type = partition_column->get_meta_type().get_type(); + if (ObResolverUtils::is_partition_range_column_type(type)) { + /* case: create table t1(c1 double, primary key(c1)) */ + part_type = ObPartitionFuncType::PARTITION_FUNC_TYPE_RANGE_COLUMNS; + } + if (!ObResolverUtils::is_valid_partition_column_type( + partition_column->get_meta_type().get_type(), part_type, false)) { + ret = OB_NOT_SUPPORTED; + LOG_INFO("primary key is not valid partition column type, " + "not allow to enable auto_partition by default config", + K(table_schema), KPC(partition_column)); + } + } + } + } + + // check index + if (OB_SUCC(ret)) { + // the index infos of table_schema have not been set in resolver, + // thus we need to check index with index_arg + for (int64_t i = 0; OB_SUCC(ret) && i < index_arg_list.count(); i++) { + obrpc::ObCreateIndexArg &index_arg = index_arg_list.at(i); + if (!index_arg.is_index_scope_specified_ && is_support_split_index_type(index_arg.index_type_) && lib::is_mysql_mode()) { + bool is_prefix = false; + if (OB_FAIL(check_primary_key_prefix_of_index_columns(table_schema, index_arg, is_prefix))) { + LOG_WARN("check primary key prefix of index columns", K(ret), K(table_schema), K(index_arg)); + } else if (!is_prefix) { // if primary key is prefix of index table, then it can still be local index + if (ObSimpleTableSchemaV2::is_unique_index(index_arg.index_type_)) { + index_arg.index_type_ = INDEX_TYPE_UNIQUE_GLOBAL; + } else { + index_arg.index_type_ = INDEX_TYPE_NORMAL_GLOBAL; + } + ObArray gen_columns; + ObTableSchema &index_schema = index_arg.index_schema_; + index_schema.set_table_type(USER_INDEX); + index_schema.set_index_type(index_arg.index_type_); + index_schema.set_tenant_id(table_schema.get_tenant_id()); + bool check_data_schema = false; + if (OB_FAIL(share::ObIndexBuilderUtil::adjust_expr_index_args( + index_arg, table_schema, *allocator_, gen_columns))) { + LOG_WARN("fail to adjust expr index args", K(ret)); + } else if (OB_FAIL(share::ObIndexBuilderUtil::set_index_table_columns( + index_arg, table_schema, index_schema, check_data_schema))) { + LOG_WARN("fail to set index table columns", K(ret)); + } + } + } + if (OB_FAIL(ret)) { + } else if (ObSimpleTableSchemaV2::is_spatial_index(index_arg.index_type_) || + INDEX_TYPE_DOMAIN_CTXCAT_DEPRECATED == index_arg.index_type_) { + ret = OB_NOT_SUPPORTED; + LOG_INFO("auto-partition doesn't support spatial index, " + "not allow to enable auto_partition by default config", + K(table_schema), K(index_arg)); + } else if (share::schema::is_local_unique_index_table(index_arg.index_type_)) { + if (OB_FAIL(ObResolverUtils::check_unique_index_cover_partition_column(table_schema, index_arg))) { + if (OB_EER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF == ret) { + ret = OB_NOT_SUPPORTED; + LOG_INFO("unique key does not cover all partition columns, " + "not allow to enable auto_partition by default config", + K(table_schema), K(index_arg)); + } else { + LOG_WARN("fail to check_unique_index_cover_partition_column", + KR(ret), K(table_schema), K(index_arg)); + } + } + } + } // end for + } + if (OB_FAIL(ret)) { + table_schema.forbid_auto_partition(); + if (OB_NOT_SUPPORTED == ret) { + ret = OB_SUCCESS; + } + } + } + } + + return ret; +} + int ObDDLResolver::resolve_partition_list(ObPartitionedStmt *stmt, ParseNode *node, const bool is_subpartition, @@ -13290,6 +13747,72 @@ int ObDDLResolver::check_skip_index(share::schema::ObTableSchema &table_schema) return ret; } +int ObDDLResolver::get_suggest_index_scope( + const uint64_t tenant_id, + const uint64_t data_table_id, + const ObCreateIndexArg &index_arg, + const INDEX_KEYNAME key, + bool &global) +{ + int ret = OB_SUCCESS; + const ObTableSchema *data_table_schema = nullptr; + if (OB_UNLIKELY(OB_INVALID_ID == tenant_id || OB_INVALID_ID == data_table_id)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(data_table_id)); + } else if (OB_ISNULL(schema_checker_)) { + ret = OB_ERR_SYS; + LOG_WARN("error sys, schema checker must not be nullptr", K(ret)); + } else if (OB_FAIL(schema_checker_->get_table_schema(tenant_id, data_table_id, data_table_schema))) { + LOG_WARN("get table schema failed", K(ret), K(data_table_id)); + } else if (OB_ISNULL(data_table_schema)) { + ret = OB_TABLE_NOT_EXIST; + LOG_WARN("table not exist", K(ret), K(data_table_id)); + } else { + if (data_table_schema->is_auto_partitioned_table() && is_support_split_index_key(key)) { + bool is_prefix = false; + if (OB_FAIL(check_primary_key_prefix_of_index_columns(*data_table_schema, index_arg, is_prefix))) { + LOG_WARN("check primary key prefix of index columns", K(ret), K(data_table_schema), K(index_arg)); + } else { + global = !is_prefix; + } + } + } + return ret; +} + +int ObDDLResolver::check_primary_key_prefix_of_index_columns( + const ObTableSchema &data_table_schema, + const ObCreateIndexArg &index_arg, + bool &is_prefix) +{ + int ret = OB_SUCCESS; + const ObRowkeyInfo &rowkey_info = data_table_schema.get_rowkey_info(); + is_prefix = rowkey_info.get_size() <= index_arg.index_columns_.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_info.get_size() && is_prefix; ++i) { + ObRowkeyColumn rowkey_column; + if (i >= index_arg.index_columns_.count()) { + ret = OB_ERR_SYS; + LOG_WARN("i is larger than index column count", K(ret), K(i), K(index_arg.index_columns_)); + } else if (OB_FAIL(rowkey_info.get_column(i, rowkey_column))) { + LOG_WARN("get column info failed", K(ret)); + } else { + const ObColumnSortItem &sort_item = index_arg.index_columns_.at(i); + const ObColumnSchemaV2 *column_schema = nullptr; + if (OB_ISNULL(column_schema = data_table_schema.get_column_schema(sort_item.column_name_))) { + is_prefix = false; + } else { + is_prefix = column_schema->get_column_id() == rowkey_column.column_id_; + } + } + } + return ret; +} + +bool ObDDLResolver::is_support_split_index_key(const INDEX_KEYNAME key) +{ + return NORMAL_KEY == key || UNIQUE_KEY == key; +} + bool ObDDLResolver::is_column_group_supported() const { bool is_supported = true; diff --git a/src/sql/resolver/ddl/ob_ddl_resolver.h b/src/sql/resolver/ddl/ob_ddl_resolver.h index 92b9bc0c6..de55ed100 100644 --- a/src/sql/resolver/ddl/ob_ddl_resolver.h +++ b/src/sql/resolver/ddl/ob_ddl_resolver.h @@ -131,10 +131,11 @@ public: enum RangeNode { RANGE_FUN_EXPR_NODE = 0, RANGE_ELEMENTS_NODE = 1, - RANGE_SUBPARTITIOPPN_NODE = 2, + RANGE_SUBPARTITION_NODE = 2, RANGE_PARTITION_NUM_NODE = 3, RANGE_TEMPLATE_MARK = 4, RANGE_INTERVAL_NODE = 5, + RANGE_AUTO_SPLIT_TABLET_SIZE = 6, }; enum ElementsNode { PARTITION_NAME_NODE = 0, @@ -682,6 +683,16 @@ protected: ParseNode *node, share::schema::ObTableSchema &table_schema, common::ObSEArray &range_exprs); + int resolve_auto_partition_with_tenant_config(ObCreateTableStmt *stmt, ParseNode *node, + ObTableSchema &table_schema); + int resolve_auto_partition(ObPartitionedStmt *stmt, ParseNode *node, + ObTableSchema &table_schema); + int resolve_presetting_partition_key(ParseNode *node, share::schema::ObTableSchema &table_schema); + int try_set_auto_partition_by_config(common::ObIArray &index_arg_list, + ObTableSchema &table_schema); + int check_only_modify_auto_partition_attr(ObPartitionedStmt *stmt, ParseNode *node, + ObTableSchema &table_schema, bool &is_only_modify_auto_part_attr); + static int resolve_interval_node( ObResolverParams ¶ms, ParseNode *interval_node, @@ -1003,6 +1014,17 @@ protected: const bool is_char_type, const ObCollationType &collation_type, ObObj &default_value, ObString &str); + int get_suggest_index_scope( + const uint64_t tenant_id, + const uint64_t data_table_id, + const ObCreateIndexArg &index_arg, + const INDEX_KEYNAME key, + bool &global); + int check_primary_key_prefix_of_index_columns( + const ObTableSchema &table_schema, + const ObCreateIndexArg &index_arg, + bool &is_prefix); + bool is_support_split_index_key(const INDEX_KEYNAME index_keyname); bool is_column_group_supported() const; int64_t block_size_; int64_t consistency_level_; diff --git a/src/sql/resolver/ddl/ob_partitioned_stmt.h b/src/sql/resolver/ddl/ob_partitioned_stmt.h index a4196a161..601f557c0 100644 --- a/src/sql/resolver/ddl/ob_partitioned_stmt.h +++ b/src/sql/resolver/ddl/ob_partitioned_stmt.h @@ -22,9 +22,11 @@ class ObPartitionedStmt : public ObDDLStmt { public: ObPartitionedStmt(common::ObIAllocator *name_pool, stmt::StmtType type) - : ObDDLStmt(name_pool, type), interval_expr_(NULL), use_def_sub_part_(true) {} + : ObDDLStmt(name_pool, type), interval_expr_(NULL), use_def_sub_part_(true), + use_auto_partition_clause_(false) {} explicit ObPartitionedStmt(stmt::StmtType type) - : ObDDLStmt(type), interval_expr_(NULL), use_def_sub_part_(true) {} + : ObDDLStmt(type), interval_expr_(NULL), use_def_sub_part_(true), + use_auto_partition_clause_(false) {} virtual ~ObPartitionedStmt() {} array_t &get_part_fun_exprs() { return part_fun_exprs_; } @@ -36,6 +38,11 @@ public: void set_interval_expr(ObRawExpr* interval_expr) { interval_expr_ = interval_expr; } bool use_def_sub_part() const { return use_def_sub_part_; } void set_use_def_sub_part(bool use_def_sub_part) { use_def_sub_part_ = use_def_sub_part; } + bool use_auto_partition_clause() const { return use_auto_partition_clause_; } + void set_use_auto_partition_clause(bool use_auto_partition_clause) + { + use_auto_partition_clause_ = use_auto_partition_clause; + } @@ -45,7 +52,8 @@ public: K_(template_subpart_values_exprs), K_(individual_subpart_values_exprs), K_(interval_expr), - K_(use_def_sub_part)); + K_(use_def_sub_part), + K_(use_auto_partition_clause)); private: /** * part_values_exprs的组织形式如下: @@ -67,6 +75,7 @@ private: array_array_t individual_subpart_values_exprs_; //for individual subpart values expr ObRawExpr *interval_expr_; bool use_def_sub_part_; // control resolver behaviour when resolve composited-partitioned table/tablegroup + bool use_auto_partition_clause_; private: DISALLOW_COPY_AND_ASSIGN(ObPartitionedStmt); }; diff --git a/src/sql/resolver/expr/ob_expr_info_flag.h b/src/sql/resolver/expr/ob_expr_info_flag.h index 780c252fa..31f25e0b7 100644 --- a/src/sql/resolver/expr/ob_expr_info_flag.h +++ b/src/sql/resolver/expr/ob_expr_info_flag.h @@ -131,6 +131,7 @@ enum ObExprInfoFlag IS_ROWID_SIMPLE_COND, // rowid = const IS_ROWID_RANGE_COND, // rowid belongs to a range IS_TABLE_ASSIGN, // update t1 set c1 = const + IS_AUTO_PART_EXPR, IS_ATTR_EXPR, // collection attr expr IS_EXISTS, }; diff --git a/src/sql/resolver/expr/ob_raw_expr.cpp b/src/sql/resolver/expr/ob_raw_expr.cpp index ab6c4e490..754c6e5dc 100644 --- a/src/sql/resolver/expr/ob_raw_expr.cpp +++ b/src/sql/resolver/expr/ob_raw_expr.cpp @@ -1974,6 +1974,7 @@ int ObExecParamRawExpr::assign(const ObRawExpr &other) outer_expr_ = tmp.outer_expr_; is_onetime_ = tmp.is_onetime_; ref_same_dblink_ = tmp.ref_same_dblink_; + eval_by_storage_ = tmp.eval_by_storage_; } } return ret; @@ -2041,7 +2042,11 @@ int ObExecParamRawExpr::get_name_internal(char *buf, ExplainType type) const { int ret = OB_SUCCESS; - if (EXPLAIN_DBLINK_STMT != type) { + if (eval_by_storage_) { + if (OB_FAIL(BUF_PRINTF("?"))) { + LOG_WARN("fail to BUF_PRINTF", K(ret)); + } + } else if (EXPLAIN_DBLINK_STMT != type) { if (OB_FAIL(ObConstRawExpr::get_name_internal(buf, buf_len, pos, type))) { LOG_WARN("failed to print const raw expr", K(ret)); } @@ -2062,7 +2067,8 @@ int64_t ObExecParamRawExpr::to_string(char *buf, const int64_t buf_len) const N_EXPR_INFO, info_, N_VALUE, value_, K_(outer_expr), - K_(is_onetime)); + K_(is_onetime), + K_(eval_by_storage)); J_OBJ_END(); return pos; } diff --git a/src/sql/resolver/expr/ob_raw_expr.h b/src/sql/resolver/expr/ob_raw_expr.h index b320fed60..f9e19985e 100644 --- a/src/sql/resolver/expr/ob_raw_expr.h +++ b/src/sql/resolver/expr/ob_raw_expr.h @@ -2430,14 +2430,16 @@ class ObExecParamRawExpr : public ObConstRawExpr public: ObExecParamRawExpr() : ObConstRawExpr(), - ref_same_dblink_(false) + ref_same_dblink_(false), + eval_by_storage_(false) { set_expr_class(ObIRawExpr::EXPR_EXEC_PARAM); } ObExecParamRawExpr(common::ObIAllocator &alloc) : ObConstRawExpr(alloc), - ref_same_dblink_(false) + ref_same_dblink_(false), + eval_by_storage_(false) { set_expr_class(ObIRawExpr::EXPR_EXEC_PARAM); } @@ -2458,6 +2460,8 @@ public: bool is_onetime() const { return is_onetime_; } bool is_ref_same_dblink() const { return ref_same_dblink_; } void set_ref_same_dblink(bool ref_same_dblink) { ref_same_dblink_ = ref_same_dblink; } + bool is_eval_by_storage() const { return eval_by_storage_; } + void set_eval_by_storage(bool eval_by_storage) { eval_by_storage_ = eval_by_storage; } int assign(const ObRawExpr &other) override; int inner_deep_copy(ObIRawExprCopier &copier) override; virtual int replace_expr(const common::ObIArray &other_exprs, @@ -2478,6 +2482,7 @@ private: ObRawExpr *outer_expr_; bool is_onetime_; bool ref_same_dblink_; + bool eval_by_storage_; }; class ObQueryRefRawExpr : public ObRawExpr diff --git a/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp b/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp index 6fad19d68..0026084d0 100644 --- a/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_deduce_type.cpp @@ -139,7 +139,9 @@ int ObRawExprDeduceType::visit(ObPlQueryRefRawExpr &expr) int ObRawExprDeduceType::visit(ObExecParamRawExpr &expr) { int ret = OB_SUCCESS; - if (OB_ISNULL(expr.get_ref_expr())) { + if (expr.is_eval_by_storage()) { + // do nothing + } else if (OB_ISNULL(expr.get_ref_expr())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ref expr is null", K(ret)); } else if (OB_FAIL(expr.get_ref_expr()->postorder_accept(*this))) { diff --git a/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp b/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp index 191b41216..32e24c873 100644 --- a/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp +++ b/src/sql/resolver/expr/ob_raw_expr_info_extractor.cpp @@ -98,16 +98,16 @@ int ObRawExprInfoExtractor::visit(ObQueryRefRawExpr &expr) int ObRawExprInfoExtractor::visit(ObExecParamRawExpr &expr) { int ret = OB_SUCCESS; - if (OB_ISNULL(expr.get_ref_expr())) { + if (!expr.is_eval_by_storage() && OB_ISNULL(expr.get_ref_expr())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("failed "); + LOG_WARN("failed", K(ret), K(expr.is_eval_by_storage())); } else if (OB_FAIL(expr.add_flag(IS_CONST))) { LOG_WARN("failed to add is const", K(ret)); } else if (OB_FAIL(expr.add_flag(IS_DYNAMIC_PARAM))) { LOG_WARN("failed to add is exec param", K(ret)); } else if (expr.is_onetime() && OB_FAIL(expr.add_flag(IS_ONETIME))) { LOG_WARN("failed to add is onetime", K(ret)); - } else if (expr.get_ref_expr()->has_enum_set_column()) { + } else if (!expr.is_eval_by_storage() && expr.get_ref_expr()->has_enum_set_column()) { OZ(expr.add_flag(CNT_ENUM_OR_SET)); OZ(expr.set_enum_set_values(expr.get_ref_expr()->get_enum_set_values())); } @@ -144,6 +144,7 @@ int ObRawExprInfoExtractor::clear_info(ObRawExpr &expr) ObExprInfo &expr_info = expr.get_expr_info(); bool is_implicit_cast = expr_info.has_member(IS_OP_OPERAND_IMPLICIT_CAST); bool is_self_param = expr_info.has_member(IS_UDT_UDF_SELF_PARAM); + bool is_auto_part_expr = expr_info.has_member(IS_AUTO_PART_EXPR); expr_info.reset(); if (is_implicit_cast) { OZ(expr_info.add_member(IS_OP_OPERAND_IMPLICIT_CAST)); @@ -151,6 +152,9 @@ int ObRawExprInfoExtractor::clear_info(ObRawExpr &expr) if (is_self_param) { OZ(expr_info.add_member(IS_UDT_UDF_SELF_PARAM)); } + if (is_auto_part_expr) { + OZ(expr_info.add_member(IS_AUTO_PART_EXPR)); + } return ret; } diff --git a/src/sql/resolver/ob_resolver_utils.cpp b/src/sql/resolver/ob_resolver_utils.cpp index 93db44e3e..2268ae8f7 100644 --- a/src/sql/resolver/ob_resolver_utils.cpp +++ b/src/sql/resolver/ob_resolver_utils.cpp @@ -3602,6 +3602,20 @@ bool ObResolverUtils::is_valid_oracle_partition_data_type(const ObObjType data_t return bret; } +bool ObResolverUtils::is_partition_range_column_type(const ObObjType type) +{ + // true means if the partition column(s) contain the type, then it's + // part_func_type must be PARTITION_FUNC_TYPE_RANGE_COLUMNS + return ob_is_float_tc(type) || + ob_is_double_tc(type) || + ob_is_decimal_int_tc(type) || + ob_is_datetime_tc(type) || + ob_is_string_tc(type) || + ob_is_date_tc(type) || + ob_is_time_tc(type) || + ob_is_number_tc(type); +} + bool ObResolverUtils::is_valid_partition_column_type(const ObObjType type, const ObPartitionFuncType part_type, const bool is_check_value) { @@ -3630,14 +3644,12 @@ bool ObResolverUtils::is_valid_partition_column_type(const ObObjType type, bret = true; } } else { - //对partition by range columns(c1) 中列的类型进行检查 /** * All integer types: TINYINT, SMALLINT, MEDIUMINT, INT (INTEGER), and BIGINT. (This is the same as with partitioning by RANGE and LIST.) * Other numeric data types (such as DECIMAL or FLOAT) are not supported as partitioning columns. * DATE and DATETIME. - * Columns using other data types relating to dates or times are not supported as partitioning columns. - * The following string types: CHAR, VARCHAR, BINARY, and VARBINARY. - * TEXT and BLOB columns are not supported as partitioning columns. + * timestamp is not supported as partitioning columns. + * The following Text types: TEXT, BLOB and LONGTEXT columns are not supported as partitioning columns. */ //https://dev.mysql.com/doc/refman/5.7/en/partitioning-columns.html ObObjTypeClass type_class = ob_obj_type_class(type); @@ -3647,9 +3659,10 @@ bool ObResolverUtils::is_valid_partition_column_type(const ObObjType type, bret = true; }else if (PARTITION_FUNC_TYPE_RANGE_COLUMNS == part_type && GET_MIN_CLUSTER_VERSION() >= CLUSTER_VERSION_4_3_0_1 && - (ObFloatTC == type_class || ObDoubleTC == type_class || - ObDecimalIntTC == type_class || ObTimestampType == type)) { + is_partition_range_column_type(type)) { /* + if the cluster version is greater than 4_3_0_1, we then make + other columns types such as timestamp, float, double, decimal available to range columns not compatible with MySql, relaied by size partition */ bret = true; @@ -3859,6 +3872,9 @@ int ObResolverUtils::check_part_value_result_type(const ObPartitionFuncType part } if (ObFloatType == part_column_expr_type || ObDoubleType == part_column_expr_type || + ObUFloatType == part_column_expr_type || + ObUDoubleType == part_column_expr_type|| + ObUNumberType == part_column_expr_type || ObDecimalIntType == part_column_expr_type) { is_allow = (ObStringTC == part_value_expr_tc || ObDecimalIntTC == part_value_expr_tc || (ObIntTC <= part_value_expr_tc && part_value_expr_tc <= ObNumberTC)); @@ -3888,7 +3904,8 @@ int ObResolverUtils::deduce_expect_value_tc(const ObObjType part_column_expr_typ case ObSmallIntType: case ObMediumIntType: case ObInt32Type: - case ObIntType: { + case ObIntType: + case ObYearType: { expect_value_tc = ObIntTC; need_cs_check = false; break; @@ -3938,14 +3955,17 @@ int ObResolverUtils::deduce_expect_value_tc(const ObObjType part_column_expr_typ break; } case ObFloatType: - case ObDoubleType: { + case ObDoubleType: + case ObUDoubleType: + case ObUFloatType: { if (is_oracle_mode || (PARTITION_FUNC_TYPE_RANGE_COLUMNS == part_func_type)) { expect_value_tc = ObStringTC; break; } } case ObNumberType: - case ObNumberFloatType: { + case ObNumberFloatType: + case ObUNumberType: { if (is_oracle_mode) { expect_value_tc = ObNumberTC; break; @@ -6323,7 +6343,7 @@ int ObResolverUtils::check_unique_index_cover_partition_column(const ObTableSche const ObCreateIndexArg &arg) { int ret = OB_SUCCESS; - if (!table_schema.is_partitioned_table() + if (!(table_schema.is_partitioned_table() || table_schema.is_auto_partitioned_table()) || (INDEX_TYPE_PRIMARY != arg.index_type_ && INDEX_TYPE_UNIQUE_LOCAL != arg.index_type_ && INDEX_TYPE_UNIQUE_MULTIVALUE_LOCAL != arg.index_type_ @@ -6336,11 +6356,17 @@ int ObResolverUtils::check_unique_index_cover_partition_column(const ObTableSche if (OB_FAIL(get_index_column_ids(table_schema, arg.index_columns_, idx_col_ids))) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Failed to get index column ids", K(ret), K(table_schema), K(arg.index_columns_)); - } else if (OB_FAIL(unique_idx_covered_partition_columns(table_schema, idx_col_ids, partition_info))) { - LOG_WARN("Unique index covered partition columns failed", K(ret)); - } else if (OB_FAIL(unique_idx_covered_partition_columns(table_schema, idx_col_ids, subpartition_info))) { - LOG_WARN("Unique index convered partition columns failed", K(ret)); - } else { }//do nothing + } else if (table_schema.is_auto_partitioned_table() && !table_schema.is_partitioned_table()) { + if (OB_FAIL(unique_idx_covered_presetting_partition_columns(table_schema, idx_col_ids))) { + LOG_WARN("Unique index covered presetting partition columns failed", KR(ret)); + } + } else { + if (OB_FAIL(unique_idx_covered_partition_columns(table_schema, idx_col_ids, partition_info))) { + LOG_WARN("Unique index covered partition columns failed", KR(ret)); + } else if (OB_FAIL(unique_idx_covered_partition_columns(table_schema, idx_col_ids, subpartition_info))) { + LOG_WARN("Unique index covered partition columns failed", KR(ret)); + } else { }//do nothing + } } return ret; } @@ -6363,6 +6389,31 @@ int ObResolverUtils::get_index_column_ids( return ret; } +int ObResolverUtils::unique_idx_covered_presetting_partition_columns(const share::schema::ObTableSchema &table_schema, + const common::ObIArray &index_columns) +{ + int ret = OB_SUCCESS; + const ObColumnSchemaV2 *column_schema = NULL; + ObArray presetting_partition_column_ids; + + if (OB_FAIL(table_schema.get_presetting_partition_keys(presetting_partition_column_ids))) { + LOG_WARN("fail to get presetting partition key columns", KR(ret), K(table_schema), K(index_columns)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < presetting_partition_column_ids.count(); i++) { + uint64_t column_id = presetting_partition_column_ids.at(i); + if (!has_exist_in_array(index_columns, column_id)) { + ret = OB_EER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF; + LOG_WARN("unique key does not include all presetting partition key", KR(ret), + K(presetting_partition_column_ids), + K(index_columns)); + LOG_USER_ERROR(OB_EER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF, "UNIQUE INDEX"); + } + } // end for + } + + return ret; +} + int ObResolverUtils::unique_idx_covered_partition_columns( const ObTableSchema &table_schema, const ObIArray &index_columns, diff --git a/src/sql/resolver/ob_resolver_utils.h b/src/sql/resolver/ob_resolver_utils.h index 8c0a36979..80e11188e 100644 --- a/src/sql/resolver/ob_resolver_utils.h +++ b/src/sql/resolver/ob_resolver_utils.h @@ -430,6 +430,8 @@ public: static int unique_idx_covered_partition_columns(const share::schema::ObTableSchema &table_schema, const common::ObIArray &index_columns, const common::ObPartitionKeyInfo &partition_info); + static int unique_idx_covered_presetting_partition_columns(const share::schema::ObTableSchema &table_schema, + const common::ObIArray &index_columns); static int get_collation_type_of_names(const ObSQLSessionInfo *session_info, const ObNameTypeClass type_class, @@ -588,6 +590,7 @@ public: static bool is_valid_partition_column_type(const common::ObObjType type, const share::schema::ObPartitionFuncType part_type, const bool is_check_value); + static bool is_partition_range_column_type(const common::ObObjType type); static bool is_valid_oracle_partition_data_type(const common::ObObjType type, const bool check_value); static bool is_valid_oracle_interval_data_type( const common::ObObjType type, diff --git a/src/sql/session/ObSQLSessionMgr实现思路.md b/src/sql/session/ObSQLSessionMgr实现思路.md old mode 100755 new mode 100644 diff --git a/src/storage/CMakeLists.txt b/src/storage/CMakeLists.txt index b4742e432..64d9efd47 100644 --- a/src/storage/CMakeLists.txt +++ b/src/storage/CMakeLists.txt @@ -335,6 +335,9 @@ ob_set_subtarget(ob_storage tablet tablet/ob_tablet_multi_source_data.cpp tablet/ob_tablet_service_clog_replay_executor.cpp tablet/ob_tablet_status.cpp + tablet/ob_tablet_split_mds_helper.cpp + tablet/ob_tablet_split_mds_user_data.cpp + tablet/ob_tablet_split_replay_executor.cpp tablet/ob_tablet_table_store.cpp tablet/ob_tablet_table_store_iterator.cpp tablet/ob_table_store_util.cpp @@ -494,6 +497,7 @@ ob_set_subtarget(ob_storage tx_storage tx_storage/ob_tenant_memory_printer.cpp tx_storage/ob_tablet_gc_service.cpp tx_storage/ob_empty_shell_task.cpp + tx_storage/ob_empty_shell_object_checker.cpp ) ob_set_subtarget(ob_storage tx_table @@ -609,6 +613,7 @@ ob_set_subtarget(ob_storage access ob_set_subtarget(ob_storage ddl ddl/ob_build_index_task.cpp ddl/ob_complement_data_task.cpp + ddl/ob_tablet_split_task.cpp ddl/ob_delete_lob_meta_row_task.cpp ddl/ob_ddl_clog.cpp ddl/ob_ddl_merge_task.cpp @@ -626,10 +631,12 @@ ob_set_subtarget(ob_storage ddl ddl/ob_ddl_replay_executor.cpp ddl/ob_ddl_heart_beat_task.cpp ddl/ob_ddl_server_client.cpp + ddl/ob_tablet_lob_split_task.cpp ddl/ob_ddl_seq_generator.cpp ddl/ob_ddl_inc_clog.cpp ddl/ob_ddl_inc_clog_callback.cpp ddl/ob_ddl_inc_redo_log_writer.cpp + ddl/ob_ddl_alter_auto_part_attr.cpp ) ob_set_subtarget(ob_storage common @@ -669,6 +676,7 @@ ob_set_subtarget(ob_storage common ob_tenant_tablet_stat_mgr.cpp ob_protected_memtable_mgr_handle.cpp ob_gc_upper_trans_helper.cpp + ob_partition_pre_split.cpp ) ob_set_subtarget(ob_storage common_mixed @@ -905,6 +913,8 @@ ob_set_subtarget(ob_storage lob lob/ob_lob_persistent_reader.cpp lob/ob_lob_persistent_iterator.cpp lob/ob_lob_write_buffer.cpp + lob/ob_lob_tablet_dml.cpp + lob/ob_lob_locator_struct.cpp ) ob_set_subtarget(ob_storage mview diff --git a/src/storage/access/ob_aggregated_store.h b/src/storage/access/ob_aggregated_store.h index 837b7ba51..0090be342 100644 --- a/src/storage/access/ob_aggregated_store.h +++ b/src/storage/access/ob_aggregated_store.h @@ -15,6 +15,7 @@ #include "sql/engine/expr/ob_expr.h" #include "ob_block_batched_row_store.h" +#include "storage/blocksstable/ob_datum_row.h" #include "storage/access/ob_pushdown_aggregate.h" #include "storage/blocksstable/index_block/ob_index_block_row_struct.h" diff --git a/src/storage/access/ob_block_row_store.cpp b/src/storage/access/ob_block_row_store.cpp index 26ca1457d..f2b3cd0b8 100644 --- a/src/storage/access/ob_block_row_store.cpp +++ b/src/storage/access/ob_block_row_store.cpp @@ -20,6 +20,8 @@ #include "storage/blocksstable/ob_micro_block_reader.h" #include "storage/blocksstable/ob_micro_block_row_scanner.h" #include "storage/access/ob_table_access_context.h" +#include "share/ob_partition_split_query.h" +#include "storage/ob_storage_struct.h" namespace oceanbase { @@ -83,7 +85,6 @@ int ObBlockRowStore::init(const ObTableAccessParam ¶m, common::hash::ObHashS is_inited_ = true; iter_param_ = ¶m.iter_param_; } - if (IS_NOT_INIT) { reset(); } diff --git a/src/storage/access/ob_dml_param.cpp b/src/storage/access/ob_dml_param.cpp index d5d5d5684..05414fc36 100644 --- a/src/storage/access/ob_dml_param.cpp +++ b/src/storage/access/ob_dml_param.cpp @@ -253,7 +253,8 @@ DEF_TO_STRING(ObDMLBaseParam) K_(branch_id), K_(direct_insert_task_id), K_(check_schema_version), - K_(ddl_task_id)); + K_(ddl_task_id), + KPC_(data_row_for_lob)); J_OBJ_END(); return pos; } diff --git a/src/storage/access/ob_dml_param.h b/src/storage/access/ob_dml_param.h index a02478d24..ae6fe8d90 100644 --- a/src/storage/access/ob_dml_param.h +++ b/src/storage/access/ob_dml_param.h @@ -197,7 +197,8 @@ struct ObDMLBaseParam write_flag_(), check_schema_version_(true), ddl_task_id_(0), - lob_allocator_(ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()) + lob_allocator_(ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()), + data_row_for_lob_(nullptr) { } @@ -233,6 +234,7 @@ struct ObDMLBaseParam bool check_schema_version_; int64_t ddl_task_id_; mutable ObArenaAllocator lob_allocator_; + const blocksstable::ObDatumRow *data_row_for_lob_; // for tablet split bool is_valid() const { return (timeout_ > 0 && schema_version_ >= 0) && nullptr != store_ctx_guard_; } bool is_direct_insert() const { return (direct_insert_task_id_ > 0); } DECLARE_TO_STRING; diff --git a/src/storage/access/ob_multiple_merge.cpp b/src/storage/access/ob_multiple_merge.cpp index 3bb590ff5..9efa5f93d 100644 --- a/src/storage/access/ob_multiple_merge.cpp +++ b/src/storage/access/ob_multiple_merge.cpp @@ -439,7 +439,6 @@ int ObMultipleMerge::get_next_row(ObDatumRow *&row) scan_state_ = ScanState::SINGLE_ROW; } } - if (OB_SUCC(ret)) { if (OB_FAIL(fill_group_idx_if_need(unprojected_row_))) { LOG_WARN("Failed to fill iter idx", K(ret), KPC(access_param_), K(unprojected_row_)); @@ -1027,6 +1026,18 @@ int ObMultipleMerge::open() stmt_iter_pool_ = access_ctx_->get_stmt_iter_pool(); } } + if (OB_SUCC(ret)) { + // fill auto split params if need + const ObTableIterParam &iter_param = access_param_->iter_param_; + const int64_t table_id = access_param_->iter_param_.table_id_; + if (OB_NOT_NULL(iter_param.auto_split_filter_) && iter_param.auto_split_filter_type_ < static_cast(ObTabletSplitType::MAX_TYPE)) { + ObPartitionSplitQuery split_query; + if (OB_FAIL(split_query.fill_auto_split_params(iter_param.tablet_id_, iter_param.ls_id_, + iter_param.op_, iter_param.auto_split_filter_type_, iter_param.auto_split_params_, *access_ctx_->stmt_allocator_))) { + LOG_WARN("fail to fill split params.", K(ret)); + } + } + } if (OB_SUCC(ret)) { access_ctx_->block_row_store_ = block_row_store_; ObMultipleMerge::reuse(); @@ -1316,19 +1327,28 @@ int ObMultipleMerge::prepare_read_tables(bool refresh) } } else if (FALSE_IT(get_table_param_->tablet_iter_.table_iter()->reset())) { } else { + const bool need_split_src_table = access_param_->iter_param_.is_tablet_spliting(); + const bool need_split_dst_table = refresh ? true : get_table_param_->need_split_dst_table_; if (OB_UNLIKELY(get_table_param_->frozen_version_ != -1)) { if (!get_table_param_->sample_info_.is_no_sample()) { ret = OB_NOT_SUPPORTED; LOG_WARN("sample query does not support frozen_version", K(ret), K_(get_table_param), KP_(access_param)); } else if (OB_FAIL(get_table_param_->tablet_iter_.refresh_read_tables_from_tablet( - get_table_param_->frozen_version_, false/*allow_not_ready*/, true/*major only*/))) { + get_table_param_->frozen_version_, + false/*allow_not_ready*/, + true/*major_sstable_only*/, + need_split_src_table, + need_split_dst_table))) { LOG_WARN("get table iterator fail", K(ret), K_(get_table_param), KP_(access_param)); } } else if (OB_FAIL(get_table_param_->tablet_iter_.refresh_read_tables_from_tablet( get_table_param_->sample_info_.is_no_sample() ? access_ctx_->store_ctx_->mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx() : INT64_MAX, - false/*allow_not_ready*/))) { + false/*allow_not_ready*/, + false/*major_sstable_only*/, + need_split_src_table, + need_split_dst_table))) { LOG_WARN("get table iterator fail", K(ret), K_(get_table_param), KP_(access_param)); } @@ -1427,6 +1447,7 @@ int ObMultipleMerge::prepare_tables_from_iterator(ObTableStoreIterator &table_it } } #endif + return ret; } @@ -1502,7 +1523,9 @@ int ObMultipleMerge::refresh_tablet_iter() snapshot_version, snapshot_version, get_table_param_->tablet_iter_, - false/*allow_not_ready*/))) { + false/*allow_not_ready*/, + true/*need_split_src_table*/, + true/*need_split_dst_table*/))) { LOG_WARN("failed to refresh tablet iterator", K(ret), K(ls_id), K_(get_table_param), KP_(access_param)); } else { get_table_param_->refreshed_merge_ = this; diff --git a/src/storage/access/ob_sample_iter_helper.cpp b/src/storage/access/ob_sample_iter_helper.cpp index fb29b60cd..5038ec1dd 100644 --- a/src/storage/access/ob_sample_iter_helper.cpp +++ b/src/storage/access/ob_sample_iter_helper.cpp @@ -29,7 +29,7 @@ int ObGetSampleIterHelper::check_scan_range_count(bool &res, ObIArrayis_valid() && OB_FAIL(get_table_param_.tablet_iter_.refresh_read_tables_from_tablet( main_table_ctx_.store_ctx_->mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), - false /*allow_not_ready*/))) { + false/*allow_not_ready*/, false/*major_sstable_only*/, true/*need_split_src_table*/, false/*need_split_dst_table*/))) { STORAGE_LOG(WARN, "Fail to read tables", K(ret)); } else if (OB_FAIL(can_retire_to_memtable_row_sample_(retire_to_memtable_row_sample, sample_ranges))) { STORAGE_LOG(WARN, "Fail to try to retire to row sample", K(ret)); diff --git a/src/storage/access/ob_sstable_row_whole_scanner.cpp b/src/storage/access/ob_sstable_row_whole_scanner.cpp index c44f219d2..5a4585cd2 100644 --- a/src/storage/access/ob_sstable_row_whole_scanner.cpp +++ b/src/storage/access/ob_sstable_row_whole_scanner.cpp @@ -117,9 +117,22 @@ int ObSSTableRowWholeScanner::init_micro_scanner(const ObDatumRange *range) } else { const bool is_whole_macro_scan = access_ctx_->query_flag_.is_whole_macro_scan(); const bool is_multi_version_minor_merge = access_ctx_->query_flag_.is_multi_version_minor_merge(); + const bool is_bare_row_scan = access_ctx_->query_flag_.is_bare_row_scan(); if (OB_UNLIKELY(!is_whole_macro_scan)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("Unexpected query flag without whole macro scan", K(ret), KPC(access_ctx_)); + } else if (is_bare_row_scan) { + if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObMicroBlockRowDirectScanner)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc mem for micro block scanner failed", K(ret)); + } else { + micro_scanner_ = new(buf) ObMicroBlockRowDirectScanner(allocator_); + if (nullptr != range) { + query_range_ = *range; + } else { + query_range_.set_whole_range(); + } + } } else if (nullptr != range && is_multi_version_minor_merge && sstable_->is_multi_version_minor_sstable()) { if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObMultiVersionMicroBlockMinorMergeRowScanner)))) { ret = OB_ALLOCATE_MEMORY_FAILED; diff --git a/src/storage/access/ob_sstable_row_whole_scanner.h b/src/storage/access/ob_sstable_row_whole_scanner.h index cdb144d90..6c9b22100 100644 --- a/src/storage/access/ob_sstable_row_whole_scanner.h +++ b/src/storage/access/ob_sstable_row_whole_scanner.h @@ -13,6 +13,7 @@ #ifndef OB_STORAGE_OB_SSTABLE_ROW_WHOLE_SCANNER_H_ #define OB_STORAGE_OB_SSTABLE_ROW_WHOLE_SCANNER_H_ +#include "storage/blocksstable/index_block/ob_index_block_macro_iterator.h" #include "storage/blocksstable/index_block/ob_index_block_dual_meta_iterator.h" #include "storage/blocksstable/ob_micro_block_row_scanner.h" #include "storage/blocksstable/ob_macro_block_bare_iterator.h" diff --git a/src/storage/access/ob_table_access_param.cpp b/src/storage/access/ob_table_access_param.cpp index d9c1fc96e..d01e61434 100644 --- a/src/storage/access/ob_table_access_param.cpp +++ b/src/storage/access/ob_table_access_param.cpp @@ -17,6 +17,7 @@ #include "storage/ob_relative_table.h" #include "storage/tablet/ob_tablet.h" #include "share/schema/ob_table_dml_param.h" +#include "sql/engine/expr/ob_expr.h" namespace oceanbase { @@ -24,10 +25,10 @@ using namespace common; using namespace blocksstable; namespace storage { - ObTableIterParam::ObTableIterParam() : table_id_(0), tablet_id_(), + ls_id_(), read_info_(nullptr), rowkey_read_info_(nullptr), tablet_handle_(nullptr), @@ -77,6 +78,7 @@ void ObTableIterParam::reset() { table_id_ = 0; tablet_id_.reset(); + ls_id_.reset(); read_info_ = nullptr; rowkey_read_info_ = nullptr; tablet_handle_ = nullptr; @@ -319,6 +321,7 @@ int ObTableAccessParam::init( iter_param_.table_scan_opt_.storage_rowsets_size_ = 1; } iter_param_.pushdown_filter_ = scan_param.pd_storage_filters_; + iter_param_.ls_id_ = scan_param.ls_id_; iter_param_.is_column_replica_table_ = table_param.is_column_replica_table(); // disable blockscan if scan order is KeepOrder(for iterator iterator and table api) // disable blockscan if use index skip scan as no large range to scan diff --git a/src/storage/access/ob_table_access_param.h b/src/storage/access/ob_table_access_param.h index be6b34f54..b468f682c 100644 --- a/src/storage/access/ob_table_access_param.h +++ b/src/storage/access/ob_table_access_param.h @@ -183,6 +183,7 @@ public: public: uint64_t table_id_; common::ObTabletID tablet_id_; + share::ObLSID ls_id_; uint32_t cg_idx_; const ObITableReadInfo *read_info_; const ObITableReadInfo *rowkey_read_info_; diff --git a/src/storage/access/ob_table_scan_iterator.cpp b/src/storage/access/ob_table_scan_iterator.cpp index 1f6009fa9..821aba638 100644 --- a/src/storage/access/ob_table_scan_iterator.cpp +++ b/src/storage/access/ob_table_scan_iterator.cpp @@ -29,6 +29,7 @@ #include "storage/tx_storage/ob_ls_service.h" #include "storage/tx/ob_trans_service.h" #include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_split_mds_helper.h" namespace oceanbase { @@ -302,9 +303,10 @@ int ObTableScanIterator::rescan(ObTableScanParam &scan_param) return ret; } -int ObTableScanIterator::init(ObTableScanParam &scan_param, const ObTabletHandle &tablet_handle) +int ObTableScanIterator::init(ObTableScanParam &scan_param, const ObTabletHandle &tablet_handle, const bool need_split_dst_table) { int ret = OB_SUCCESS; + bool is_tablet_spliting = false; ACTIVE_GLOBAL_ITERATOR_GUARD(ret, cached_iter_node_); ObStoreCtx &store_ctx = ctx_guard_.get_store_ctx(); if (OB_UNLIKELY(is_inited_)) { @@ -316,12 +318,15 @@ int ObTableScanIterator::init(ObTableScanParam &scan_param, const ObTabletHandle ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument to init table scan iter", K(ret), K(store_ctx), K(scan_param), K(tablet_handle)); - } else if (OB_FAIL(table_scan_range_.init(scan_param))) { + } else if (OB_FAIL(ObTabletSplitMdsHelper::get_is_spliting(*tablet_handle.get_obj(), is_tablet_spliting))) { + STORAGE_LOG(WARN, "Fail to get tablet spliting status", K(ret)); + } else if (OB_FAIL(table_scan_range_.init(scan_param, is_tablet_spliting))) { STORAGE_LOG(WARN, "Failed to init table scan range", K(ret), K(scan_param)); } else if (OB_FAIL(table_scan_range_.get_query_iter_type(current_iter_type_))) { STORAGE_LOG(WARN, "Failed to get query iter type", K(ret)); } else { scan_param_ = &scan_param; + get_table_param_.need_split_dst_table_ = need_split_dst_table; if (OB_FAIL(get_table_param_.tablet_iter_.set_tablet_handle(tablet_handle))) { STORAGE_LOG(WARN, "Fail to set tablet handle to iter", K(ret)); } else if (OB_FAIL(prepare_table_param(tablet_handle))) { @@ -340,9 +345,10 @@ int ObTableScanIterator::init(ObTableScanParam &scan_param, const ObTabletHandle return ret; } -int ObTableScanIterator::switch_param(ObTableScanParam &scan_param, const ObTabletHandle &tablet_handle) +int ObTableScanIterator::switch_param(ObTableScanParam &scan_param, const ObTabletHandle &tablet_handle, const bool need_split_dst_table) { int ret = OB_SUCCESS; + bool is_tablet_spliting = false; ACTIVE_GLOBAL_ITERATOR_GUARD(ret, cached_iter_node_); ObStoreCtx &store_ctx = ctx_guard_.get_store_ctx(); ObQRIterType rescan_iter_type = T_INVALID_ITER_TYPE; @@ -354,12 +360,15 @@ int ObTableScanIterator::switch_param(ObTableScanParam &scan_param, const ObTabl || OB_UNLIKELY(!tablet_handle.is_valid()))) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument, ", K(ret), K(store_ctx), K(scan_param), K(tablet_handle)); - } else if (OB_FAIL(table_scan_range_.init(scan_param))) { + } else if (OB_FAIL(ObTabletSplitMdsHelper::get_is_spliting(*tablet_handle.get_obj(), is_tablet_spliting))) { + STORAGE_LOG(WARN, "Fail to get tablet spliting status", K(ret)); + } else if (OB_FAIL(table_scan_range_.init(scan_param, is_tablet_spliting))) { STORAGE_LOG(WARN, "Failed to init table scan range", K(ret), K(scan_param)); } else if (OB_FAIL(table_scan_range_.get_query_iter_type(rescan_iter_type))) { STORAGE_LOG(WARN, "Failed to get query iter type", K(ret)); } else { scan_param_ = &scan_param; + get_table_param_.need_split_dst_table_ = need_split_dst_table; if (OB_FAIL(get_table_param_.tablet_iter_.set_tablet_handle(tablet_handle))) { STORAGE_LOG(WARN, "Fail to set tablet handle to iter", K(ret)); } else if (FALSE_IT(try_release_cached_iter_node(rescan_iter_type))) { diff --git a/src/storage/access/ob_table_scan_iterator.h b/src/storage/access/ob_table_scan_iterator.h index c9d414e16..3a6a752ae 100644 --- a/src/storage/access/ob_table_scan_iterator.h +++ b/src/storage/access/ob_table_scan_iterator.h @@ -50,8 +50,8 @@ class ObTableScanIterator : public common::ObNewRowIterator public: ObTableScanIterator(); virtual ~ObTableScanIterator(); - int init(ObTableScanParam &scan_param, const ObTabletHandle &tablet_handle); - int switch_param(ObTableScanParam &scan_param, const ObTabletHandle &tablet_handle); + int init(ObTableScanParam &scan_param, const ObTabletHandle &tablet_handle, const bool need_split_dst_table = true); + int switch_param(ObTableScanParam &scan_param, const ObTabletHandle &tablet_handle, const bool need_split_dst_table = true); int get_next_row(blocksstable::ObDatumRow *&row); virtual int get_next_row(common::ObNewRow *&row) override; virtual int get_next_row() override { blocksstable::ObDatumRow *r = nullptr; return get_next_row(r); } diff --git a/src/storage/access/ob_table_scan_range.cpp b/src/storage/access/ob_table_scan_range.cpp index a33f2ce87..82ce5c393 100644 --- a/src/storage/access/ob_table_scan_range.cpp +++ b/src/storage/access/ob_table_scan_range.cpp @@ -12,9 +12,14 @@ #include "ob_table_scan_range.h" #include "ob_dml_param.h" +#include "storage/ob_storage_struct.h" +#include "share/ob_partition_split_query.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/tablet/ob_tablet_split_mds_helper.h" namespace oceanbase { +using namespace share; using namespace common; using namespace blocksstable; namespace storage @@ -66,10 +71,9 @@ do { is_inited_ = false; } -int ObTableScanRange::init(ObTableScanParam &scan_param) +int ObTableScanRange::init(ObTableScanParam &scan_param, const bool is_tablet_spliting) { int ret = OB_SUCCESS; - if (IS_INIT) { ret = OB_INIT_TWICE; STORAGE_LOG(WARN, "ObTableScanRange is inited twice", K(ret), K(*this)); @@ -77,6 +81,7 @@ int ObTableScanRange::init(ObTableScanParam &scan_param) ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument to init ObTableScanRange", K(ret), K(scan_param)); } else { + scan_param.is_tablet_spliting_ = is_tablet_spliting; allocator_ = scan_param.scan_allocator_; status_ = scan_param.is_get_ ? GET : SCAN; const ObStorageDatumUtils *datum_utils = nullptr; @@ -88,14 +93,27 @@ int ObTableScanRange::init(ObTableScanParam &scan_param) if (scan_param.use_index_skip_scan()) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected, index skip scan can only be used in scan", K(ret)); - } else if (OB_FAIL(init_rowkeys(scan_param.key_ranges_, scan_param.scan_flag_, datum_utils))) { + } else if (OB_FAIL(init_rowkeys(scan_param.tablet_id_, scan_param.ls_id_, + scan_param.is_tablet_spliting_, + scan_param.key_ranges_, + scan_param.scan_flag_, + datum_utils))) { STORAGE_LOG(WARN, "Failed to init rowkeys", K(ret)); } } else if (scan_param.use_index_skip_scan()) { - if (OB_FAIL(init_ranges_in_skip_scan(scan_param.key_ranges_, scan_param.ss_key_ranges_, scan_param.scan_flag_, datum_utils))) { - STORAGE_LOG(WARN, "Failed to init range in skip scan", K(ret), K(scan_param.key_ranges_), K(scan_param.ss_key_ranges_)); + if (OB_FAIL(init_ranges_in_skip_scan( + scan_param.key_ranges_, + scan_param.ss_key_ranges_, + scan_param.scan_flag_, + datum_utils))) { + STORAGE_LOG(WARN, "Failed to init range in skip scan", + K(ret), K(scan_param.key_ranges_), K(scan_param.ss_key_ranges_)); } - } else if (OB_FAIL(init_ranges(scan_param.key_ranges_, scan_param.scan_flag_, datum_utils))) { + } else if (OB_FAIL(init_ranges(scan_param.tablet_id_, scan_param.ls_id_, + scan_param.is_tablet_spliting_, + scan_param.key_ranges_, + scan_param.scan_flag_, + datum_utils))) { STORAGE_LOG(WARN, "Failed to init ranges", K(ret)); } @@ -108,12 +126,17 @@ int ObTableScanRange::init(ObTableScanParam &scan_param) return ret; } -int ObTableScanRange::init(const ObSimpleBatch &simple_batch, ObIAllocator &allocator) +int ObTableScanRange::init( + ObTableScanParam &scan_param, + const ObSimpleBatch &simple_batch, + ObIAllocator &allocator) { int ret = OB_SUCCESS; ObQueryFlag scan_flag; scan_flag.scan_order_ = ObQueryFlag::Forward; - + ObPartitionSplitQuery split_query; + ObTabletHandle tablet_handle; + bool is_tablet_spliting = false; if (IS_INIT) { ret = OB_INIT_TWICE; STORAGE_LOG(WARN, "ObTableScanRange is not inited", K(ret), K(*this)); @@ -121,6 +144,12 @@ int ObTableScanRange::init(const ObSimpleBatch &simple_batch, ObIAllocator &allo ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid argument to init table scan range", K(ret), K(simple_batch)); } else if (FALSE_IT(allocator_ = &allocator)) { + } else if (OB_FAIL(split_query.get_tablet_handle(scan_param.tablet_id_, + scan_param.ls_id_, tablet_handle))) { + STORAGE_LOG(WARN, "fail to get tablet handle", K(ret), K(scan_param)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::get_is_spliting(*tablet_handle.get_obj(), is_tablet_spliting))) { + STORAGE_LOG(WARN, "fail to get tablet split status", K(ret)); + } else if (FALSE_IT(scan_param.is_tablet_spliting_ = is_tablet_spliting)) { } else if (simple_batch.type_ == ObSimpleBatch::T_SCAN) { //single scan ObSEArray ranges; @@ -129,14 +158,22 @@ int ObTableScanRange::init(const ObSimpleBatch &simple_batch, ObIAllocator &allo STORAGE_LOG(WARN, "Invalid simple batch", K(ret), K(simple_batch)); } else if (OB_FAIL(ranges.push_back(*simple_batch.range_))) { STORAGE_LOG(WARN, "Failed to push back range", K(ret)); - } else if (OB_FAIL(init_ranges(ranges, scan_flag, nullptr))) { + } else if (OB_FAIL(init_ranges(scan_param.tablet_id_, scan_param.ls_id_, + scan_param.is_tablet_spliting_, + ranges, + scan_flag, + nullptr))) { STORAGE_LOG(WARN, "Failed to init ranges", K(ret)); } //multiple scan } else if (OB_ISNULL(simple_batch.ranges_)) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "Invalid simple batch", K(ret), K(simple_batch)); - } else if (OB_FAIL(init_ranges(*simple_batch.ranges_, scan_flag, nullptr))) { + } else if (OB_FAIL(init_ranges(scan_param.tablet_id_, scan_param.ls_id_, + scan_param.is_tablet_spliting_, + *simple_batch.ranges_, + scan_flag, + nullptr))) { // 如果datum_utils不为nullptr不会对原来逻辑造成影响 STORAGE_LOG(WARN, "Failed to init ranges", K(ret)); } if (OB_SUCC(ret)) { @@ -164,9 +201,46 @@ int ObTableScanRange::always_false(const common::ObNewRange &range, bool &is_fal return ret; } -int ObTableScanRange::init_rowkeys(const common::ObIArray &ranges, - const common::ObQueryFlag &scan_flag, - const blocksstable::ObStorageDatumUtils *datum_utils) +int ObTableScanRange::get_split_partition_rowkeys( + const ObTabletID &tablet_id, + const ObLSID &ls_id, + const common::ObIArray &ranges, + const blocksstable::ObStorageDatumUtils *datum_utils) +{ + int ret = OB_SUCCESS; + ObPartitionSplitQuery split_query; + if (OB_FAIL(split_query.get_tablet_split_info(tablet_id, ls_id, *allocator_))) { + STORAGE_LOG(WARN, "fail to check tablet in spliting", K(ret), K(tablet_id)); + } else { + const int64_t range_cnt = ranges.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < range_cnt; i++) { + ObDatumRowkey datum_rowkey; + const ObRowkey &rowkey = ranges.at(i).get_start_key(); + bool is_false = false; + bool is_included = true; + if (OB_FAIL(always_false(ranges.at(i), is_false))) { + STORAGE_LOG(WARN, "Failed to check range always false", K(ret), K(ranges.at(i))); + } else if (is_false) { + } else if (OB_FAIL(datum_rowkey.from_rowkey(rowkey, *allocator_))) { + STORAGE_LOG(WARN, "Failed to transfer rowkey to datum rowkey", K(ret)); + } else if (FALSE_IT(datum_rowkey.set_group_idx(ranges.at(i).get_group_idx()))) { + } else if (OB_FAIL(split_query.check_rowkey_is_included(datum_rowkey, datum_utils, is_included))) { + STORAGE_LOG(WARN, "Failed to check rowkey is included", K(ret), K(tablet_id), K(datum_rowkey)); + } else if (is_included && OB_FAIL(rowkeys_.push_back(datum_rowkey))) { + STORAGE_LOG(WARN, "Failed to push back datum rowkey", K(ret)); + } + } + } + return ret; +} + +int ObTableScanRange::init_rowkeys( + const ObTabletID &tablet_id, + const ObLSID &ls_id, + const bool is_tablet_spliting, + const common::ObIArray &ranges, + const common::ObQueryFlag &scan_flag, + const blocksstable::ObStorageDatumUtils *datum_utils) { int ret = OB_SUCCESS; @@ -178,18 +252,24 @@ int ObTableScanRange::init_rowkeys(const common::ObIArray &r if (range_cnt == 0) { status_ = EMPTY; } else { - for (int64_t i = 0; OB_SUCC(ret) && i < range_cnt; i++) { - ObDatumRowkey datum_rowkey; - const ObRowkey &rowkey = ranges.at(i).get_start_key(); - bool is_false = false; - if (OB_FAIL(always_false(ranges.at(i), is_false))) { - STORAGE_LOG(WARN, "Failed to check range always false", K(ret), K(ranges.at(i))); - } else if (is_false) { - } else if (OB_FAIL(datum_rowkey.from_rowkey(rowkey, *allocator_))) { - STORAGE_LOG(WARN, "Failed to transfer rowkey to datum rowkey", K(ret)); - } else if (FALSE_IT(datum_rowkey.set_group_idx(ranges.at(i).get_group_id()))) { - } else if (OB_FAIL(rowkeys_.push_back(datum_rowkey))) { - STORAGE_LOG(WARN, "Failed to push back datum rowkey", K(ret)); + if (is_tablet_spliting) { + if (OB_FAIL(get_split_partition_rowkeys(tablet_id, ls_id, ranges, datum_utils))) { + STORAGE_LOG(WARN, "fail to get split partition rowkeys", K(ret)); + } + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < range_cnt; i++) { + ObDatumRowkey datum_rowkey; + const ObRowkey &rowkey = ranges.at(i).get_start_key(); + bool is_false = false; + if (OB_FAIL(always_false(ranges.at(i), is_false))) { + STORAGE_LOG(WARN, "Failed to check range always false", K(ret), K(ranges.at(i))); + } else if (is_false) { + } else if (OB_FAIL(datum_rowkey.from_rowkey(rowkey, *allocator_))) { + STORAGE_LOG(WARN, "Failed to transfer rowkey to datum rowkey", K(ret)); + } else if (FALSE_IT(datum_rowkey.set_group_idx(ranges.at(i).get_group_id()))) { + } else if (OB_FAIL(rowkeys_.push_back(datum_rowkey))) { + STORAGE_LOG(WARN, "Failed to push back datum rowkey", K(ret)); + } } } if (OB_SUCC(ret)) { @@ -209,15 +289,19 @@ int ObTableScanRange::init_rowkeys(const common::ObIArray &r return ret; } -int ObTableScanRange::init_ranges(const common::ObIArray &ranges, - const common::ObQueryFlag &scan_flag, - const blocksstable::ObStorageDatumUtils *datum_utils) +int ObTableScanRange::init_ranges( + const ObTabletID &tablet_id, + const ObLSID &ls_id, + const bool is_tablet_spliting, + const common::ObIArray &ranges, + const common::ObQueryFlag &scan_flag, + const blocksstable::ObStorageDatumUtils *datum_utils) { int ret = OB_SUCCESS; - if (OB_UNLIKELY(nullptr == allocator_)) { + if (OB_UNLIKELY(nullptr == allocator_ || !tablet_id.is_valid() || !ls_id.is_valid())) { ret = OB_INVALID_ARGUMENT; - STORAGE_LOG(WARN, "Invalid argument to init ranges", K(ret)); + STORAGE_LOG(WARN, "Invalid argument to init ranges", K(ret), K(allocator_)); } else { const int64_t range_cnt = ranges.count(); if (0 == range_cnt) { @@ -227,6 +311,11 @@ int ObTableScanRange::init_ranges(const common::ObIArray &ra STORAGE_LOG(WARN, "Failed to push back datum range", K(ret)); } } else { + ObPartitionSplitQuery split_query; + if (is_tablet_spliting && + OB_FAIL(split_query.get_tablet_split_info(tablet_id, ls_id, *allocator_))) { + STORAGE_LOG(WARN, "fail to check tablet in spliting", K(ret), K(tablet_id)); + } for (int64_t i = 0; OB_SUCC(ret) && i < range_cnt; i++) { ObDatumRange datum_range; const ObNewRange &range = ranges.at(i); @@ -236,6 +325,11 @@ int ObTableScanRange::init_ranges(const common::ObIArray &ra } else if (is_false) { } else if (OB_FAIL(datum_range.from_range(range, *allocator_))) { STORAGE_LOG(WARN, "Failed to transfer range to datum range", K(ret)); + } else if (is_tablet_spliting && OB_FAIL(split_query.get_split_datum_range( + datum_utils, + *allocator_, + datum_range))) { + STORAGE_LOG(WARN, "Failed to get split datum range", K(ret), K(tablet_id), K(ls_id)); } else if (OB_FAIL(ranges_.push_back(datum_range))) { STORAGE_LOG(WARN, "Failed to push back datum range", K(ret)); } diff --git a/src/storage/access/ob_table_scan_range.h b/src/storage/access/ob_table_scan_range.h index 4baa473ec..347437c7b 100644 --- a/src/storage/access/ob_table_scan_range.h +++ b/src/storage/access/ob_table_scan_range.h @@ -28,8 +28,10 @@ struct ObTableScanRange public: ObTableScanRange(); ~ObTableScanRange() { reset(); } - int init(ObTableScanParam &scan_param); - int init(const common::ObSimpleBatch &simple_batch, common::ObIAllocator &allocator); + int init(ObTableScanParam &scan_param, const bool is_tablet_spliting = false); + int init(ObTableScanParam &scan_param, + const common::ObSimpleBatch &simple_batch, + common::ObIAllocator &allocator); void reset(); OB_INLINE bool is_valid() const { return is_inited_; } OB_INLINE bool is_get() const { return GET == status_; } @@ -42,17 +44,33 @@ public: int get_query_iter_type(ObQRIterType &iter_type) const; TO_STRING_KV(K_(rowkeys), K_(ranges), K_(status), K_(is_inited)); private: - int init_rowkeys(const common::ObIArray &ranges, - const common::ObQueryFlag &scan_flag, - const blocksstable::ObStorageDatumUtils *datum_utils); - int init_ranges(const common::ObIArray &ranges, - const common::ObQueryFlag &scan_flag, - const blocksstable::ObStorageDatumUtils *datum_utils); - int init_ranges_in_skip_scan(const common::ObIArray &ranges, - const common::ObIArray &skip_scan_ranges, - const common::ObQueryFlag &scan_flag, - const blocksstable::ObStorageDatumUtils *datum_utils); - int always_false(const common::ObNewRange &range, bool &is_false); + int init_rowkeys( + const ObTabletID &tablet_id, + const share::ObLSID &ls_id, + const bool is_tablet_spliting, + const common::ObIArray &ranges, + const common::ObQueryFlag &scan_flag, + const blocksstable::ObStorageDatumUtils *datum_utils); + int init_ranges( + const ObTabletID &tablet_id, + const share::ObLSID &ls_id, + const bool is_tablet_spliting, + const common::ObIArray &ranges, + const common::ObQueryFlag &scan_flag, + const blocksstable::ObStorageDatumUtils *datum_utils); + int init_ranges_in_skip_scan( + const common::ObIArray &ranges, + const common::ObIArray &skip_scan_ranges, + const common::ObQueryFlag &scan_flag, + const blocksstable::ObStorageDatumUtils *datum_utils); + int always_false( + const common::ObNewRange &range, + bool &is_false); + int get_split_partition_rowkeys( + const ObTabletID &tablet_id, + const share::ObLSID &ls_id, + const common::ObIArray &ranges, + const blocksstable::ObStorageDatumUtils *datum_utils); private: struct ObSkipScanWrappedRange { diff --git a/src/storage/backup/ob_backup_ctx.cpp b/src/storage/backup/ob_backup_ctx.cpp index e5c1c30a5..cee760ed3 100644 --- a/src/storage/backup/ob_backup_ctx.cpp +++ b/src/storage/backup/ob_backup_ctx.cpp @@ -929,7 +929,7 @@ int ObBackupRetryCtx::check_and_sort_retry_list_( } if (OB_SUCC(ret)) { BackupRetryCmp cmp; - std::sort(retry_list.begin(), retry_list.end(), cmp); + lib::ob_sort(retry_list.begin(), retry_list.end(), cmp); } return ret; } @@ -1171,7 +1171,7 @@ int ObBackupRetryCtx::inner_recover_need_reuse_macro_block_( } } if (OB_SUCC(ret)) { - std::sort(reused_pair_list_.begin(), reused_pair_list_.end()); + lib::ob_sort(reused_pair_list_.begin(), reused_pair_list_.end()); } return ret; } @@ -1299,7 +1299,7 @@ int ObLSBackupCtx::open( } else { ObBackupMacroBlockIdPairComparator compare; // TODO(yanfeng): consider the list size in extreme conditions - std::sort(backup_retry_ctx_.reused_pair_list_.begin(), + lib::ob_sort(backup_retry_ctx_.reused_pair_list_.begin(), backup_retry_ctx_.reused_pair_list_.end(), compare); is_inited_ = true; @@ -1567,8 +1567,7 @@ int ObLSBackupCtx::get_all_tablet_id_list_( } int ObLSBackupCtx::seperate_tablet_id_list_(const common::ObIArray &tablet_id_list, - common::ObIArray &sys_tablet_id_list, - common::ObIArray &data_tablet_id_list) + common::ObArray &sys_tablet_id_list, common::ObArray &data_tablet_id_list) { int ret = OB_SUCCESS; sys_tablet_id_list.reset(); @@ -1585,6 +1584,10 @@ int ObLSBackupCtx::seperate_tablet_id_list_(const common::ObIArray &tablet_list); int seperate_tablet_id_list_(const common::ObIArray &tablet_id_list, - common::ObIArray &sys_tablet_list, common::ObIArray &data_tablet_id_list); + common::ObArray &sys_tablet_list, common::ObArray &data_tablet_id_list); int inner_do_next_(common::ObTabletID &tablet_id); int check_need_skip_(const common::ObTabletID &tablet_id, bool &need_skip); int check_need_skip_major_(const common::ObTabletID &tablet_id, bool &need_skip); diff --git a/src/storage/backup/ob_backup_data_struct.h b/src/storage/backup/ob_backup_data_struct.h index 4666ae400..6d9b97446 100644 --- a/src/storage/backup/ob_backup_data_struct.h +++ b/src/storage/backup/ob_backup_data_struct.h @@ -34,7 +34,7 @@ class ObLocationService; namespace backup { static const int64_t OB_DEFAULT_BACKUP_CONCURRENCY = 2; -static const int64_t OB_MAX_BACKUP_CONCURRENCY = 128; +static const int64_t OB_MAX_BACKUP_CONCURRENCY = 8; static const int64_t OB_MAX_BACKUP_MEM_BUF_LEN = 8 * 1024 * 1024; // 8MB static const int64_t OB_MAX_BACKUP_INDEX_BUF_SIZE = 16 * 1024; // 16KB; static const int64_t OB_MAX_BACKUP_FILE_SIZE = 4 * 1024 * 1024; diff --git a/src/storage/backup/ob_backup_fuse_tablet_ctx.h b/src/storage/backup/ob_backup_fuse_tablet_ctx.h index d68706a01..c6e52a060 100644 --- a/src/storage/backup/ob_backup_fuse_tablet_ctx.h +++ b/src/storage/backup/ob_backup_fuse_tablet_ctx.h @@ -29,6 +29,7 @@ enum class ObBackupFuseTabletType : uint64_t FUSE_TABLET_META_USE_V2 = 1, // when transfer seq is equal FUSE_TABLET_META_DELETED = 2, // when tablet is deleted at backup data stage FUSE_TABLET_LS_INNER_TABLET = 3, // tablet is ls inner tablet + FUSE_TABLET_META_REORGANIZED = 4, // when tablet is reorganized(split or merge) // FARM COMPAT WHITELIST MAX, }; diff --git a/src/storage/backup/ob_backup_fuse_tablet_task.cpp b/src/storage/backup/ob_backup_fuse_tablet_task.cpp index 014727acc..d490e953d 100644 --- a/src/storage/backup/ob_backup_fuse_tablet_task.cpp +++ b/src/storage/backup/ob_backup_fuse_tablet_task.cpp @@ -16,6 +16,7 @@ #include "share/backup/ob_backup_path.h" #include "observer/ob_server_event_history_table_operator.h" #include "storage/backup/ob_backup_operator.h" +#include "share/backup/ob_backup_tablet_reorganize_helper.h" using namespace oceanbase::share; @@ -673,6 +674,26 @@ int ObBackupTabletFuseTask::check_tablet_deleted_( return ret; } +int ObBackupTabletFuseTask::check_tablet_reorganized_( + const uint64_t tenant_id, + const common::ObTabletID &tablet_id, + bool &tablet_reoragnized) +{ + int ret = OB_SUCCESS; + share::ObLSID tmp_ls_id; + int64_t tablet_count = 0; + if (OB_ISNULL(sql_proxy_)) { + ret = OB_ERR_UNDEFINED; + LOG_WARN("sql proxy should not be null", K(ret)); + } else if (OB_FAIL(ObBackupTabletReorganizeHelper::check_tablet_has_reorganized( + *sql_proxy_, tenant_id, tablet_id, tmp_ls_id, tablet_reoragnized))) { + LOG_WARN("failed to check tablet has reoragnized", K(ret), K(tenant_id), K(tablet_id)); + } else { + LOG_INFO("check tablet has reorganized", K(tenant_id), K(tablet_id), K(tmp_ls_id), K(tablet_reoragnized)); + } + return ret; +} + int ObBackupTabletFuseTask::fetch_tablet_meta_in_user_data_( const ObBackupMetaIndex &meta_index, ObMigrationTabletParam &tablet_param) @@ -735,9 +756,16 @@ int ObBackupTabletFuseTask::fuse_tablet_item_( fuse_type_ = ObBackupFuseTabletType::FUSE_TABLET_LS_INNER_TABLET; } else { bool is_deleted = false; + bool is_reorganized = false; if (OB_ISNULL(group_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("group ctx should not be null", K(ret)); + } else if (OB_FAIL(check_tablet_reorganized_( + group_ctx_->param_.tenant_id_, fuse_item.tablet_id_, is_reorganized))) { + LOG_WARN("failed to check tablet has reorganized", K(ret)); + } else if (is_reorganized) { + fuse_type_ = ObBackupFuseTabletType::FUSE_TABLET_META_REORGANIZED; + output_param.ha_status_.set_restore_status(ObTabletRestoreStatus::UNDEFINED); } else if (OB_FAIL(check_tablet_deleted_( group_ctx_->param_.tenant_id_, fuse_item.tablet_id_, is_deleted))) { LOG_WARN("failed to check tablet deleted", K(ret)); diff --git a/src/storage/backup/ob_backup_fuse_tablet_task.h b/src/storage/backup/ob_backup_fuse_tablet_task.h index 38d1ab009..c8d6b8be9 100644 --- a/src/storage/backup/ob_backup_fuse_tablet_task.h +++ b/src/storage/backup/ob_backup_fuse_tablet_task.h @@ -96,6 +96,10 @@ private: const uint64_t tenant_id, const common::ObTabletID &tablet_id, bool &tablet_deleted); + int check_tablet_reorganized_( + const uint64_t tenant_id, + const common::ObTabletID &tablet_id, + bool &tablet_reoragnized); int fetch_tablet_meta_in_user_data_( const ObBackupMetaIndex &meta_index, ObMigrationTabletParam &tablet_param); diff --git a/src/storage/backup/ob_backup_iterator.cpp b/src/storage/backup/ob_backup_iterator.cpp index 09167e977..f181c5d51 100644 --- a/src/storage/backup/ob_backup_iterator.cpp +++ b/src/storage/backup/ob_backup_iterator.cpp @@ -1305,7 +1305,7 @@ int ObBackupUnorderedMacroBlockIndexIterator::init(const int64_t task_id, const ret = OB_ENTRY_NOT_EXIST; LOG_WARN("no file exists", K(ret)); } else { - std::sort(file_id_list.begin(), file_id_list.end()); + lib::ob_sort(file_id_list.begin(), file_id_list.end()); if (OB_FAIL(file_id_list_.assign(file_id_list))) { LOG_WARN("failed to assign", K(ret), K(file_id_list)); } else if (OB_FAIL(do_fetch_new_())) { diff --git a/src/storage/backup/ob_backup_linked_block_reader.cpp b/src/storage/backup/ob_backup_linked_block_reader.cpp index 1fce7a31e..64e836242 100644 --- a/src/storage/backup/ob_backup_linked_block_reader.cpp +++ b/src/storage/backup/ob_backup_linked_block_reader.cpp @@ -269,7 +269,7 @@ int ObBackupLinkedBlockItemReader::get_next_item(ObBackupLinkedItem &link_item) bool need_fetch_new = false; if (IS_NOT_INIT) { ret = OB_NOT_INIT; - LOG_WARN("ObBackupLinkedBlockItemReader has not been inited", K(ret));; + LOG_WARN("ObBackupLinkedBlockItemReader has not been inited", K(ret)); } else if (!has_prev_ && item_idx_ >= block_item_list_.count()) { ret = OB_ITER_END; LOG_WARN("ObBackupLinkedBlockItemReader has reach end", K_(has_prev), K_(item_idx), "count", block_item_list_.count()); diff --git a/src/storage/backup/ob_backup_tablet_meta_fuser.cpp b/src/storage/backup/ob_backup_tablet_meta_fuser.cpp index 20cb422c2..9676ff4a6 100644 --- a/src/storage/backup/ob_backup_tablet_meta_fuser.cpp +++ b/src/storage/backup/ob_backup_tablet_meta_fuser.cpp @@ -462,7 +462,7 @@ int ObBackupTabletMetaFuser::sort_iters_(MERGE_ITER_ARRAY &fuse_iters) // no need sort } else { ObBackupTabletMetaIteratorComparator comp(ret); - std::sort(fuse_iters.begin(), fuse_iters.end(), comp); + lib::ob_sort(fuse_iters.begin(), fuse_iters.end(), comp); if (OB_FAIL(ret)) { LOG_ERROR("failed to sort iterators", K(ret), K(fuse_iters)); } diff --git a/src/storage/backup/ob_backup_task.cpp b/src/storage/backup/ob_backup_task.cpp index 7b6e6a264..fb155c9e0 100644 --- a/src/storage/backup/ob_backup_task.cpp +++ b/src/storage/backup/ob_backup_task.cpp @@ -2028,6 +2028,16 @@ int ObPrefetchBackupInfoTask::process() DEBUG_SYNC(BEFORE_BACKUP_PREFETCH_TASK); } #endif + + if (backup_data_type_.is_user_backup() && !param_.ls_id_.is_sys_ls()) { + SERVER_EVENT_SYNC_ADD("backup", "before_backup_prefetch_task", + "tenant_id", MTL_ID(), + "ls_id", param_.ls_id_.id(), + "turn_id", param_.turn_id_, + "retry_id", param_.retry_id_); + DEBUG_SYNC(BEFORE_PREFETCH_BACKUP_INFO_TASK); + } + if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("prefetch backup info task is not inited", K(ret)); @@ -3293,10 +3303,20 @@ int ObLSBackupDataTask::do_backup_tablet_meta_(const ObTabletMetaReaderType read backup_stat_.finish_tablet_count_ += 1; ls_backup_ctx_->stat_mgr_.add_tablet_meta(backup_data_type_, tablet_id); ls_backup_ctx_->stat_mgr_.add_bytes(backup_data_type_, meta_index.length_); +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("backup", "backup_tablet_meta", + "ls_id", param_.ls_id_.id(), + "tablet_id", tablet_id.id()); +#endif } else if (BACKUP_SSTABLE_META == meta_type) { backup_stat_.finish_sstable_count_ += 1; ls_backup_ctx_->stat_mgr_.add_sstable_meta(backup_data_type_, tablet_id); ls_backup_ctx_->stat_mgr_.add_bytes(backup_data_type_, meta_index.length_); +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("backup", "backup_sstable_meta", + "ls_id", param_.ls_id_.id(), + "tablet_id", tablet_id.id()); +#endif } } if (OB_NOT_NULL(reader)) { diff --git a/src/storage/backup/ob_backup_utils.cpp b/src/storage/backup/ob_backup_utils.cpp index 135b1dd09..01b9632f8 100644 --- a/src/storage/backup/ob_backup_utils.cpp +++ b/src/storage/backup/ob_backup_utils.cpp @@ -169,7 +169,9 @@ int ObBackupUtils::fetch_major_sstables_(const storage::ObTabletHandle &tablet_h major_sstable_array_ptr = &tablet_table_store.get_major_sstables(); ObITable *last_major_sstable_ptr = NULL; bool with_major_sstable = true; + const compaction::ObMediumCompactionInfoList *medium_info_list = nullptr; ObSSTableWrapper major_wrapper; + ObArenaAllocator tmp_allocator("GetMediumList", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); if (OB_FAIL(check_tablet_with_major_sstable(tablet_handle, with_major_sstable))) { LOG_WARN("failed to check tablet with major sstable", K(ret)); @@ -178,6 +180,13 @@ int ObBackupUtils::fetch_major_sstables_(const storage::ObTabletHandle &tablet_h ret = OB_ERR_UNEXPECTED; LOG_WARN("last major sstable should not be null", K(ret), K(tablet_handle)); } + } else if (OB_FAIL(tablet_handle.get_obj()->read_medium_info_list(tmp_allocator, medium_info_list))) { + LOG_WARN("failed to load medium info list", K(ret)); + } else if (medium_info_list->get_last_compaction_scn() > 0 + && medium_info_list->get_last_compaction_scn() != last_major_sstable_ptr->get_snapshot_version()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("medium list is invalid for last major sstable", K(ret), KPC(medium_info_list), + KPC(last_major_sstable_ptr), K(tablet_handle)); } else if (last_major_sstable_ptr->is_co_sstable()) { if (OB_FAIL(static_cast(last_major_sstable_ptr)->get_all_tables(sstable_array))) { LOG_WARN("failed to get all cg tables from co table", K(ret), KPC(last_major_sstable_ptr)); @@ -1782,23 +1791,31 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar bool can_explain = false; ObTabletMemberWrapper table_store_wrapper; bool need_skip_tablet = false; + bool is_split_dst = false; if (OB_ISNULL(ls_backup_ctx_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls backup ctx should not be null", K(ret)); } else if (!tablet_id.is_valid()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid args", K(ret), K(tablet_id)); - } else if (OB_FAIL(get_tablet_handle_(tenant_id, ls_id, tablet_id, tablet_ref))) { + } else if (OB_FAIL(get_tablet_handle_(tenant_id, ls_id, tablet_id, tablet_ref, is_split_dst))) { if (OB_TABLET_NOT_EXIST == ret) { LOG_WARN("failed to get tablet handle", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); ret = OB_SUCCESS; ObBackupSkippedType skipped_type(ObBackupSkippedType::MAX_TYPE); bool need_report_skip = false; share::ObLSID split_ls_id; - if (OB_FAIL(get_tablet_skipped_type_(param_.tenant_id_, ls_id, tablet_id, skipped_type, split_ls_id))) { - LOG_WARN("failed to get tablet skipped type", K(ret), K(param_), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(check_need_report_tablet_skipped_(split_ls_id, tablet_id, skipped_type, need_report_skip))) { - LOG_WARN("failed to check need report tablet skipped", K(ret)); + if (!is_split_dst) { + if (OB_FAIL(get_tablet_skipped_type_(param_.tenant_id_, ls_id, tablet_id, skipped_type, split_ls_id))) { + LOG_WARN("failed to get tablet skipped type", K(ret), K(param_), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(check_need_report_tablet_skipped_(split_ls_id, tablet_id, skipped_type, need_report_skip))) { + LOG_WARN("failed to check need report tablet skipped", K(ret)); + } + } else { + need_report_skip = true; + skipped_type = ObBackupSkippedType(ObBackupSkippedType::REORGANIZED); + } + if (OB_FAIL(ret)) { } else if (!need_report_skip) { LOG_INFO("skip report tablet skipped", K(ret), K(tablet_id), K(skipped_type), K_(param)); } else if (OB_FAIL(report_tablet_skipped_(tablet_id, skipped_type, backup_data_type))) { @@ -1809,10 +1826,6 @@ int ObBackupTabletProvider::prepare_tablet_(const uint64_t tenant_id, const shar } else { LOG_WARN("failed to get tablet handle", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); } - } else if (OB_FAIL(check_tablet_split_status_(tenant_id, tablet_id, need_skip_tablet))) { - LOG_WARN("failed to check tablet split status", K(ret), K(tenant_id), K(tablet_id)); - } else if (need_skip_tablet) { - LOG_INFO("tablet skipped", K(tenant_id), K(tablet_id)); } else if (OB_FAIL(check_tx_data_can_explain_user_data_(tablet_ref->tablet_handle_, can_explain))) { LOG_WARN("failed to check tx data can explain user data", K(ret), K(ls_id), K(tablet_id)); } else if (!can_explain) { @@ -1963,9 +1976,10 @@ int ObBackupTabletProvider::get_consistent_scn_(share::SCN &consistent_scn) cons } int ObBackupTabletProvider::get_tablet_handle_(const uint64_t tenant_id, const share::ObLSID &ls_id, - const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_ref) + const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_ref, bool &is_split_dst) { int ret = OB_SUCCESS; + is_split_dst = false; tablet_ref = NULL; bool hold_tablet_success = false; if (OB_INVALID_ID == tenant_id || !ls_id.is_valid() || !tablet_id.is_valid()) { @@ -1990,8 +2004,12 @@ int ObBackupTabletProvider::get_tablet_handle_(const uint64_t tenant_id, const s LOG_WARN("backup get tablet handle timeout", K(ret), K(ls_id), K(tablet_id)); } else if (OB_FAIL(get_tablet_status_(ls_id, tablet_id, status))) { LOG_WARN("failed to check tablet is normal", K(ret), K(tenant_id), K(ls_id), K(rebuild_seq)); - } else if (ObTabletStatus::NORMAL != status) { - LOG_WARN("tablet status is not normal", K(tenant_id), K(ls_id), K(tablet_id)); + } else if (ObTabletStatus::SPLIT_DST == status) { + is_split_dst = true; + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("tablet is split dst when double check tablet status", K(ret), K(tenant_id), K(ls_id), K(tablet_id), K(status)); + } else if (ObTabletStatus::NORMAL != status && ObTabletStatus::SPLIT_SRC != status) { + LOG_WARN("tablet status is not normal", K(tenant_id), K(ls_id), K(tablet_id), K(status)); usleep(100 * 1000); // wait 100ms } else if (OB_FAIL(inner_get_tablet_handle_without_memtables_(tenant_id, ls_id, tablet_id, tablet_ref))) { // read readble commited, only get NORMAL and TRANSFER IN tablet. LOG_WARN("failed to inner get tablet handle without memtables", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); @@ -2007,8 +2025,9 @@ int ObBackupTabletProvider::get_tablet_handle_(const uint64_t tenant_id, const s usleep(100 * 1000); // wait 100ms } else if (OB_FAIL(get_tablet_status_(ls_id, tablet_id, status))) { LOG_WARN("failed to check tablet is normal", K(ret), K(tenant_id), K(ls_id), K(rebuild_seq)); - } else if (ObTabletStatus::NORMAL != status) { - if (ObTabletStatus::TRANSFER_OUT == status || ObTabletStatus::TRANSFER_OUT_DELETED == status || ObTabletStatus::DELETED == status) { + } else if (ObTabletStatus::NORMAL != status && ObTabletStatus::SPLIT_SRC != status) { + if (ObTabletStatus::TRANSFER_OUT == status || ObTabletStatus::TRANSFER_OUT_DELETED == status || ObTabletStatus::DELETED == status + || ObTabletStatus::SPLIT_SRC_DELETED == status) { ret = OB_TABLET_NOT_EXIST; LOG_WARN("tablet is deleted when double check tablet status", K(ret), K(tenant_id), K(ls_id), K(tablet_id), K(status)); } else { @@ -2086,7 +2105,7 @@ int ObBackupTabletProvider::get_tablet_skipped_type_(const uint64_t tenant_id, c *sql_proxy_, tenant_id, tablet_id, split_ls_id, tablet_reorganized))) { LOG_WARN("failed to check tablet has reorganized", K(ret), K(tenant_id), K(tablet_id)); } else if (tablet_reorganized) { - // do nothing + LOG_INFO("tablet reorganized", K(tablet_id), K(split_ls_id)); } else if (OB_FAIL(ObLSBackupOperator::get_tablet_to_ls_info( *sql_proxy_, tenant_id, tablet_id, tablet_count, tmp_ls_id))) { LOG_WARN("failed to get tablet to ls info", K(ret), K(tenant_id), K(tablet_id)); @@ -2120,7 +2139,7 @@ int ObBackupTabletProvider::get_tablet_skipped_type_(const uint64_t tenant_id, c } } else { skipped_type = ObBackupSkippedType(ObBackupSkippedType::TRANSFER); - LOG_INFO("tablet transfered, need change turn", K(ls_id)); + LOG_INFO("tablet transfered, need change turn", K(ls_id), K(tablet_id)); } } else { ret = OB_ERR_UNEXPECTED; @@ -2134,34 +2153,43 @@ int ObBackupTabletProvider::check_need_report_tablet_skipped_(const share::ObLSI const common::ObTabletID &tablet_id, const share::ObBackupSkippedType &skipped_type, bool &need_report_skip) { int ret = OB_SUCCESS; - need_report_skip = ObBackupSkippedType::DELETED == skipped_type.get_type() - || ObBackupSkippedType::TRANSFER == skipped_type.get_type(); - // TODO(yanfeng): need auto_split branch merge - // if (ObBackupSkippedType::REORGANIZED != skipped_type.get_type()) { - // need_report_skip = false; - // } else { - // ObArray tablet_pairs; - // if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::get_split_tablet_pairs_by_src( - // *sql_proxy_, param_.tenant_id_, ls_id, tablet_id, tablet_pairs))) { - // LOG_WARN("failed to get split tablet pairs", K(ret)); - // } else { - // ObArray *tablet_id_ptr = &ls_backup_ctx_->data_tablet_id_list_; - // ARRAY_FOREACH_X(tablet_pairs, i, cnt, OB_SUCC(ret)) { - // const ReorganizeTabletPair &pair = tablet_pairs.at(i); - // bool exist = false; - // ARRAY_FOREACH_X(*tablet_id_ptr, j, cnt, OB_SUCC(ret)) { - // if (tablet_id_ptr->at(j) == pair.dest_tablet_id_) { - // exist = true; - // break; - // } - // } - // if (!exist) { - // need_report_skip = true; - // break; - // } - // } - // } - // } + need_report_skip = false; + if (ObBackupSkippedType::DELETED == skipped_type.get_type() + || ObBackupSkippedType::TRANSFER == skipped_type.get_type()) { + need_report_skip = true; + } else { + ObArray tablet_pairs; + // TODO(yanfeng): a tablet can be max split into 64K tablet(oracle mode) or 8K tablet(mysql mode) + // so the time complexity here is K * log N, where K is the max tablet split num, the N is the total tablet count + // consider using two pointer search algorithm to optimize the search logic + if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::get_split_tablet_pairs_by_src( + *sql_proxy_, param_.tenant_id_, ls_id, tablet_id, tablet_pairs))) { + LOG_WARN("failed to get split tablet pairs", K(ret)); + } else { + ObArray *tablet_id_ptr = &ls_backup_ctx_->data_tablet_id_list_; + ARRAY_FOREACH_X(tablet_pairs, i, cnt, OB_SUCC(ret)) { + const ReorganizeTabletPair &pair = tablet_pairs.at(i); + bool exist = false; + typedef common::ObArray::iterator Iter; + Iter iter = std::lower_bound(tablet_id_ptr->begin(), tablet_id_ptr->end(), pair.dest_tablet_id_); + if (iter != tablet_id_ptr->end()) { + if (*iter != pair.dest_tablet_id_) { + exist = false; + } else { + exist = true; + } + } else { + exist = false; + } + + if (!exist) { + need_report_skip = true; + break; + } + } + LOG_INFO("need report skip", K(ls_id), K(tablet_id), K(need_report_skip), K(tablet_pairs), KPC(tablet_id_ptr)); + } + } return ret; } @@ -2497,45 +2525,44 @@ int ObBackupTabletProvider::check_tablet_split_status_(const uint64_t tenant_id, { int ret = OB_SUCCESS; need_skip_tablet = false; - // TODO(yanfeng): wait auto_split branch merge - // ReorganizeTabletPair pair; - // if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::get_split_tablet_pairs_by_dest( - // *sql_proxy_, tenant_id, tablet_id, pair))) { - // if (OB_ENTRY_NOT_EXIST == ret) { - // ret = OB_SUCCESS; - // } else { - // LOG_WARN("failed to get split tablet pair by dest", K(ret), K(tablet_id)); - // } - // } else { - // const common::ObTabletID &src_tablet_id = pair.src_tablet_id_; - // bool has_skipped = false; - // if (OB_FAIL(ObLSBackupOperator::check_tablet_skipped_by_reorganize(*sql_proxy_, tenant_id, src_tablet_id, has_skipped))) { - // LOG_WARN("failed to check tablet skipped by reorganize", K(ret), K(src_tablet_id)); - // } else if (has_skipped) { - // LOG_INFO("skip check tablet split status", K(ret), K(pair)); - // } else { - // ObArray *tablet_id_ptr = &ls_backup_ctx_->data_tablet_id_list_; - // bool src_exist = false; - // ARRAY_FOREACH_X(*tablet_id_ptr, i, cnt, OB_SUCC(ret)) { - // if (tablet_id_ptr->at(i) == src_tablet_id) { - // src_exist = true; - // break; - // } - // } - // LOG_INFO("tablet not skipped", K(*tablet_id_ptr), K(src_tablet_id), K(src_exist)); - // if (OB_SUCC(ret) && src_exist) { - // ObBackupSkippedType skipped_type(ObBackupSkippedType::REORGANIZED); - // ObBackupDataType backup_data_type; - // backup_data_type.set_major_data_backup(); - // if (OB_FAIL(report_tablet_skipped_(tablet_id, skipped_type, backup_data_type))) { - // LOG_WARN("failed to report tablet skipped", K(ret)); - // } else { - // need_skip_tablet = true; - // LOG_INFO("report skip tablet", K(tablet_id), K(skipped_type)); - // } - // } - // } - // } + ReorganizeTabletPair pair; + if (OB_FAIL(ObTabletReorganizeHistoryTableOperator::get_split_tablet_pairs_by_dest( + *sql_proxy_, tenant_id, tablet_id, pair))) { + if (OB_ENTRY_NOT_EXIST == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get split tablet pair by dest", K(ret), K(tablet_id)); + } + } else { + const common::ObTabletID &src_tablet_id = pair.src_tablet_id_; + bool has_skipped = false; + if (OB_FAIL(ObLSBackupOperator::check_tablet_skipped_by_reorganize(*sql_proxy_, tenant_id, src_tablet_id, has_skipped))) { + LOG_WARN("failed to check tablet skipped by reorganize", K(ret), K(src_tablet_id)); + } else if (has_skipped) { + LOG_INFO("skip check tablet split status", K(ret), K(pair)); + } else { + ObArray *tablet_id_ptr = &ls_backup_ctx_->data_tablet_id_list_; + bool src_exist = false; + ARRAY_FOREACH_X(*tablet_id_ptr, i, cnt, OB_SUCC(ret)) { + if (tablet_id_ptr->at(i) == src_tablet_id) { + src_exist = true; + break; + } + } + LOG_INFO("tablet not skipped", K(*tablet_id_ptr), K(src_tablet_id), K(src_exist)); + if (OB_SUCC(ret) && src_exist) { + ObBackupSkippedType skipped_type(ObBackupSkippedType::REORGANIZED); + ObBackupDataType backup_data_type; + backup_data_type.set_user_data_backup(); + if (OB_FAIL(report_tablet_skipped_(tablet_id, skipped_type, backup_data_type))) { + LOG_WARN("failed to report tablet skipped", K(ret)); + } else { + need_skip_tablet = true; + LOG_INFO("report skip tablet", K(tablet_id), K(skipped_type)); + } + } + } + } return ret; } @@ -2656,7 +2683,7 @@ int ObBackupTabletProvider::get_tablet_status_( } else if (!ls_handle.is_valid()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls_handle is in_valid", K(ret), K(ls_handle)); - } else if (OB_FAIL(ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, tablet_handle, 0 /*timeout*/, storage::ObMDSGetTabletMode::READ_READABLE_COMMITED))) { + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet_svr()->get_tablet(tablet_id, tablet_handle, 0 /*timeout*/, storage::ObMDSGetTabletMode::READ_ALL_COMMITED))) { LOG_WARN("failed to get tablet", K(ret), K(tablet_id), K(tablet_handle)); } else if (!tablet_handle.is_valid()) { ret = OB_ERR_UNEXPECTED; diff --git a/src/storage/backup/ob_backup_utils.h b/src/storage/backup/ob_backup_utils.h index 3bcb646ad..013f45085 100644 --- a/src/storage/backup/ob_backup_utils.h +++ b/src/storage/backup/ob_backup_utils.h @@ -339,7 +339,7 @@ private: // make sure clog checkpoint scn of the returned tablet is >= consistent_scn. int get_tablet_handle_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, - ObBackupTabletHandleRef *&tablet_ref); + ObBackupTabletHandleRef *&tablet_ref, bool &is_split_dst); int inner_get_tablet_handle_without_memtables_(const uint64_t tenant_id, const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, ObBackupTabletHandleRef *&tablet_ref); int get_consistent_scn_(share::SCN &consistent_scn) const; @@ -371,6 +371,7 @@ private: bool is_same_type_(const storage::ObITable::TableKey &lhs, const storage::ObITable::TableKey &rhs); int add_tablet_item_(const common::ObTabletID &tablet_id, const bool has_ss_ddl, const storage::ObITable::TableKey &table_key); int remove_duplicates_(common::ObIArray &array); + int check_tablet_status_(const storage::ObTabletHandle &tablet_handle, bool &is_normal, bool &is_split_dst); int get_tablet_status_(const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, ObTabletStatus &status); int check_tx_data_can_explain_user_data_(const storage::ObTabletHandle &tablet_handle, bool &can_explain); int get_tenant_meta_index_turn_id_(int64_t &turn_id); diff --git a/src/storage/blocksstable/index_block/ob_index_block_dumper.cpp b/src/storage/blocksstable/index_block/ob_index_block_dumper.cpp index a6ced6625..dd538a989 100644 --- a/src/storage/blocksstable/index_block/ob_index_block_dumper.cpp +++ b/src/storage/blocksstable/index_block/ob_index_block_dumper.cpp @@ -920,4 +920,4 @@ int ObIndexBlockLoader::get_next_disk_micro_block_data(ObMicroBlockData µ_b } } // namespace blocksstable -} // namespace oceanbase \ No newline at end of file +} // namespace oceanbase diff --git a/src/storage/blocksstable/index_block/ob_index_block_dumper.h b/src/storage/blocksstable/index_block/ob_index_block_dumper.h index 925da9857..e2fd4c466 100644 --- a/src/storage/blocksstable/index_block/ob_index_block_dumper.h +++ b/src/storage/blocksstable/index_block/ob_index_block_dumper.h @@ -270,4 +270,4 @@ private: } // blocksstable } // oceanbase -#endif \ No newline at end of file +#endif diff --git a/src/storage/blocksstable/ob_data_macro_block_merge_writer.h b/src/storage/blocksstable/ob_data_macro_block_merge_writer.h index 54b978f79..c1454fb8c 100644 --- a/src/storage/blocksstable/ob_data_macro_block_merge_writer.h +++ b/src/storage/blocksstable/ob_data_macro_block_merge_writer.h @@ -14,6 +14,7 @@ #define OCEANBASE_STORAGE_BLOCKSSTABLE_DATA_MACRO_BLOCK_MERGE_WRITER_H_ #include "ob_macro_block_writer.h" #include "ob_macro_block.h" +#include "index_block/ob_index_block_macro_iterator.h" #include "storage/blocksstable/index_block/ob_index_block_dual_meta_iterator.h" #include "ob_macro_block.h" #include "ob_datum_row.h" diff --git a/src/storage/blocksstable/ob_data_store_desc.cpp b/src/storage/blocksstable/ob_data_store_desc.cpp index 33f81df3c..2fc89f7bc 100644 --- a/src/storage/blocksstable/ob_data_store_desc.cpp +++ b/src/storage/blocksstable/ob_data_store_desc.cpp @@ -870,6 +870,15 @@ int ObWholeDataStoreDesc::assign(const ObDataStoreDesc &desc) return ret; } +int ObWholeDataStoreDesc::assign(const ObWholeDataStoreDesc &desc) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(assign(desc.desc_))) { + STORAGE_LOG(WARN, "failed to assign desc", KR(ret), K(desc)); + } + return ret; +} + int ObWholeDataStoreDesc::init( const ObStaticDataStoreDesc &static_desc, const ObMergeSchema &merge_schema, diff --git a/src/storage/blocksstable/ob_data_store_desc.h b/src/storage/blocksstable/ob_data_store_desc.h index 0ebe7847b..0fa6d61da 100644 --- a/src/storage/blocksstable/ob_data_store_desc.h +++ b/src/storage/blocksstable/ob_data_store_desc.h @@ -380,6 +380,7 @@ struct ObWholeDataStoreDesc const bool need_submit_io = true); int gen_index_store_desc(const ObDataStoreDesc &data_desc); int assign(const ObDataStoreDesc &desc); + int assign(const ObWholeDataStoreDesc &desc); ObStaticDataStoreDesc &get_static_desc() { return static_desc_; } ObColDataStoreDesc &get_col_desc() {return col_desc_; } ObDataStoreDesc &get_desc() { return desc_; } diff --git a/src/storage/blocksstable/ob_datum_row.cpp b/src/storage/blocksstable/ob_datum_row.cpp index cab794458..a70510e17 100644 --- a/src/storage/blocksstable/ob_datum_row.cpp +++ b/src/storage/blocksstable/ob_datum_row.cpp @@ -226,16 +226,9 @@ int ObDatumRow::deep_copy(const ObDatumRow &src, ObIAllocator &allocator) } else if (OB_UNLIKELY(get_capacity() < src.count_ || nullptr == storage_datums_)) { ret = OB_ERR_UNEXPECTED; STORAGE_LOG(WARN, "Unexpected local datum row to deep copy", K(ret), KPC(this)); + } else if (OB_FAIL(copy_attributes_except_datums(src))) { + STORAGE_LOG(WARN, "copy attribute from other failed", K(ret), K(src)); } else { - count_ = src.count_; - row_flag_ = src.row_flag_; - mvcc_row_flag_ = src.mvcc_row_flag_; - trans_id_ = src.trans_id_; - scan_index_ = src.scan_index_; - group_idx_ = src.group_idx_; - snapshot_version_ = src.snapshot_version_; - fast_filter_skipped_ = src.fast_filter_skipped_; - have_uncommited_row_ = src.have_uncommited_row_; for(int64_t i = 0; OB_SUCC(ret) && i < count_; i++) { if (OB_FAIL(storage_datums_[i].deep_copy(src.storage_datums_[i], allocator))) { STORAGE_LOG(WARN, "Failed to deep copy storage datum", K(ret), K(src.storage_datums_[i])); @@ -296,6 +289,29 @@ int ObDatumRow::is_datums_changed(const ObDatumRow &other, bool &is_changed) con return ret; } +int ObDatumRow::copy_attributes_except_datums(const ObDatumRow &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "Invalid argument to deep copy datum row", K(ret), K(other)); + } else if (OB_UNLIKELY(get_capacity() < other.count_ || nullptr == storage_datums_)) { + ret = OB_ERR_UNEXPECTED; + STORAGE_LOG(WARN, "Unexpected local datum row to deep copy", K(ret), KPC(this)); + } else { + count_ = other.count_; + row_flag_ = other.row_flag_; + mvcc_row_flag_ = other.mvcc_row_flag_; + trans_id_ = other.trans_id_; + scan_index_ = other.scan_index_; + group_idx_ = other.group_idx_; + snapshot_version_ = other.snapshot_version_; + fast_filter_skipped_ = other.fast_filter_skipped_; + have_uncommited_row_ = other.have_uncommited_row_; + } + return ret; +} + int ObDatumRow::shallow_copy(const ObDatumRow &other) { int ret = OB_SUCCESS; diff --git a/src/storage/blocksstable/ob_datum_row.h b/src/storage/blocksstable/ob_datum_row.h index 23309fa66..61d6271be 100644 --- a/src/storage/blocksstable/ob_datum_row.h +++ b/src/storage/blocksstable/ob_datum_row.h @@ -328,6 +328,7 @@ public: bool operator==(const common::ObNewRow &other) const; int is_datums_changed(const ObDatumRow &other, bool &is_changed) const; + int copy_attributes_except_datums(const ObDatumRow &other); OB_INLINE int64_t get_capacity() const { return datum_buffer_.get_capacity(); } OB_INLINE int64_t get_column_count() const { return count_; } OB_INLINE int64_t get_scan_idx() const { return scan_index_; } diff --git a/src/storage/blocksstable/ob_datum_row_utils.cpp b/src/storage/blocksstable/ob_datum_row_utils.cpp index 83142d71b..bbbc4a917 100644 --- a/src/storage/blocksstable/ob_datum_row_utils.cpp +++ b/src/storage/blocksstable/ob_datum_row_utils.cpp @@ -74,6 +74,31 @@ int ObDatumRowUtils::ob_create_rows(ObIAllocator &allocator, int64_t row_count, return ret; } +int ObDatumRowUtils::ob_create_rows_shallow_copy(ObIAllocator &allocator, const ObIArray &src_rows, ObDatumRow *&datum_rows) +{ + int ret = OB_SUCCESS; + const int64_t row_count = src_rows.count(); + if (row_count <= 0) { + datum_rows = nullptr; + } else { + void *rows_buf = nullptr; + const size_t rows_buf_len = sizeof(blocksstable::ObDatumRow) * row_count; + if (OB_ISNULL(rows_buf = allocator.alloc(rows_buf_len))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("Failed to allocate row buffer", K(ret), K(rows_buf_len)); + } else { + char *row_buf = static_cast(rows_buf); + datum_rows = new(row_buf) blocksstable::ObDatumRow[row_count](); + for (int64_t i = 0; OB_SUCC(ret) && i < row_count; ++i) { + if (OB_FAIL(datum_rows[i].shallow_copy(*src_rows.at(i)))) { + LOG_WARN("fail to init datum row", K(ret), KPC(src_rows.at(i))); + } + } + } + } + return ret; +} + int ObDatumRowUtils::prepare_rowkey( const ObDatumRow &datum_row, const int key_datum_cnt, diff --git a/src/storage/blocksstable/ob_datum_row_utils.h b/src/storage/blocksstable/ob_datum_row_utils.h index e746602eb..0467fee38 100644 --- a/src/storage/blocksstable/ob_datum_row_utils.h +++ b/src/storage/blocksstable/ob_datum_row_utils.h @@ -24,6 +24,7 @@ class ObDatumRowUtils public: static int ob_create_row(ObIAllocator &allocator, int64_t col_count, ObDatumRow *&datum_row); static int ob_create_rows(ObIAllocator &allocator, int64_t row_count, int64_t col_count, ObDatumRow *&datum_rows); + static int ob_create_rows_shallow_copy(ObIAllocator &allocator, const ObIArray &src_rows, ObDatumRow *&datum_rows); // TODO@xuanxi: rewrite it when store rowkey is no longer needed static int prepare_rowkey( const ObDatumRow &datum_row, diff --git a/src/storage/blocksstable/ob_macro_block_writer.cpp b/src/storage/blocksstable/ob_macro_block_writer.cpp index 8a063d7f0..68cae1e74 100644 --- a/src/storage/blocksstable/ob_macro_block_writer.cpp +++ b/src/storage/blocksstable/ob_macro_block_writer.cpp @@ -21,6 +21,7 @@ #include "share/ob_task_define.h" #include "share/schema/ob_table_schema.h" #include "storage/blocksstable/index_block/ob_index_block_builder.h" +#include "storage/blocksstable/index_block/ob_index_block_macro_iterator.h" #include "storage/blocksstable/index_block/ob_index_block_dual_meta_iterator.h" #include "storage/blocksstable/index_block/ob_index_block_row_struct.h" #include "storage/blocksstable/ob_macro_block_writer.h" diff --git a/src/storage/blocksstable/ob_macro_block_writer.h b/src/storage/blocksstable/ob_macro_block_writer.h index f04192a4e..449bf7ebb 100644 --- a/src/storage/blocksstable/ob_macro_block_writer.h +++ b/src/storage/blocksstable/ob_macro_block_writer.h @@ -17,6 +17,7 @@ #include "encoding/ob_micro_block_encoder.h" #include "lib/compress/ob_compressor.h" #include "lib/container/ob_array_wrap.h" +#include "index_block/ob_index_block_row_struct.h" #include "index_block/ob_index_block_aggregator.h" #include "ob_block_manager.h" #include "ob_macro_block_checker.h" diff --git a/src/storage/blocksstable/ob_micro_block_cache.cpp b/src/storage/blocksstable/ob_micro_block_cache.cpp index be7b6fbd1..033b1cb50 100644 --- a/src/storage/blocksstable/ob_micro_block_cache.cpp +++ b/src/storage/blocksstable/ob_micro_block_cache.cpp @@ -11,7 +11,6 @@ */ #define USING_LOG_PREFIX STORAGE - #include "storage/blocksstable/ob_micro_block_cache.h" #include "storage/blocksstable/ob_block_manager.h" #include "storage/blocksstable/ob_macro_block_handle.h" diff --git a/src/storage/blocksstable/ob_micro_block_row_scanner.cpp b/src/storage/blocksstable/ob_micro_block_row_scanner.cpp index 06c3280c5..71f7d64ae 100644 --- a/src/storage/blocksstable/ob_micro_block_row_scanner.cpp +++ b/src/storage/blocksstable/ob_micro_block_row_scanner.cpp @@ -820,6 +820,21 @@ int ObIMicroBlockRowScanner::filter_pushdown_filter( return ret; } +////////////////////////////////// ObMicroBlockRowDirectScanner //////////////////////////////////////////// +int ObMicroBlockRowDirectScanner::init( + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const blocksstable::ObSSTable *sstable) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObIMicroBlockRowScanner::init(param, context, sstable))) { + LOG_WARN("base init failed", K(ret)); + } else { + is_inited_ = true; + } + return ret; +} + int ObIMicroBlockRowScanner::filter_micro_block_in_blockscan(sql::PushdownFilterInfo &pd_filter_info) { int ret = OB_SUCCESS; @@ -854,6 +869,24 @@ int ObIMicroBlockRowScanner::filter_micro_block_in_blockscan(sql::PushdownFilter return ret; } +int ObMicroBlockRowDirectScanner::open( + const MacroBlockId ¯o_id, + const ObMicroBlockData &block_data, + const bool is_left_border, + const bool is_right_border) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObIMicroBlockRowScanner::open(macro_id, block_data, is_left_border, is_right_border))) { + LOG_WARN("base open failed", K(ret)); + } else if (OB_FAIL(set_base_scan_param(is_left_border, is_right_border))) { + LOG_WARN("failed to set base scan param", K(ret), K_(macro_id), K(is_left_border), K(is_right_border)); + } else if (OB_NOT_NULL(block_row_store_) && block_row_store_->is_valid()) { + // Storage pushdown filter is valid and reuse + block_row_store_->reset_blockscan(); + } + return ret; +} + int ObIMicroBlockRowScanner::filter_micro_block_in_cg( sql::ObPushdownFilterExecutor *parent, sql::PushdownFilterInfo &pd_filter_info, diff --git a/src/storage/blocksstable/ob_micro_block_row_scanner.h b/src/storage/blocksstable/ob_micro_block_row_scanner.h index c138c6162..fa92e84d3 100644 --- a/src/storage/blocksstable/ob_micro_block_row_scanner.h +++ b/src/storage/blocksstable/ob_micro_block_row_scanner.h @@ -206,6 +206,25 @@ protected: storage::ObBlockRowStore *block_row_store_; }; +// tablet split ddl task scan bared row without multi-merge. +class ObMicroBlockRowDirectScanner final : public ObIMicroBlockRowScanner +{ +public: + ObMicroBlockRowDirectScanner(common::ObIAllocator &allocator) + : ObIMicroBlockRowScanner(allocator) + {} + virtual ~ObMicroBlockRowDirectScanner() {} + virtual int init( + const storage::ObTableIterParam ¶m, + storage::ObTableAccessContext &context, + const blocksstable::ObSSTable *sstable) override final; + virtual int open( + const MacroBlockId ¯o_id, + const ObMicroBlockData &block_data, + const bool is_left_border, + const bool is_right_border) override final; +}; + // major sstable micro block scanner for query and merge class ObMicroBlockRowScanner : public ObIMicroBlockRowScanner { diff --git a/src/storage/blocksstable/ob_sstable.cpp b/src/storage/blocksstable/ob_sstable.cpp index 80dbbaad9..2e589190c 100644 --- a/src/storage/blocksstable/ob_sstable.cpp +++ b/src/storage/blocksstable/ob_sstable.cpp @@ -259,7 +259,7 @@ ObSSTable::ObSSTable() meta_(nullptr) { #if defined(__x86_64__) - static_assert(sizeof(ObSSTable) <= 256, "The size of ObSSTable will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); + static_assert(sizeof(ObSSTable) <= 264, "The size of ObSSTable will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); #endif } @@ -397,9 +397,6 @@ int ObSSTable::scan( if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("SSTable is not ready for accessing", K(ret), K_(valid_for_reading), K_(meta)); - } else if (OB_UNLIKELY(param.tablet_id_ != key_.tablet_id_)) { - ret = OB_ERR_SYS; - LOG_ERROR("Tablet id is not match", K(ret), K(*this), K(param)); } else if (OB_UNLIKELY( !param.is_valid() || !context.is_valid() @@ -456,9 +453,6 @@ int ObSSTable::get( if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("SSTable is not ready for accessing", K(ret), K_(valid_for_reading), K_(meta)); - } else if (OB_UNLIKELY(param.tablet_id_ != key_.tablet_id_)) { - ret = OB_ERR_SYS; - LOG_ERROR("Tablet id is not match", K(ret), K(*this), K(param)); } else if (OB_UNLIKELY( !param.is_valid() || !context.is_valid() @@ -513,9 +507,6 @@ int ObSSTable::multi_scan( if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("SSTable is not ready for accessing", K(ret), K_(valid_for_reading), K_(meta)); - } else if (OB_UNLIKELY(param.tablet_id_ != key_.tablet_id_)) { - ret = OB_ERR_SYS; - LOG_ERROR("Tablet id is not match", K(ret), K(*this), K(param)); } else if (OB_UNLIKELY( !param.is_valid() || !context.is_valid() @@ -569,9 +560,6 @@ int ObSSTable::multi_get( if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("SSTable is not ready for accessing", K(ret), K_(valid_for_reading), K_(meta)); - } else if (OB_UNLIKELY(param.tablet_id_ != key_.tablet_id_)) { - ret = OB_ERR_SYS; - LOG_ERROR("Tablet id is not match", K(ret), K(*this), K(param)); } else if (OB_UNLIKELY( !param.is_valid() || !context.is_valid() @@ -702,9 +690,6 @@ int ObSSTable::exist(ObRowsInfo &rows_info, bool &is_exist, bool &all_rows_found if (OB_UNLIKELY(!rows_info.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("Invalid argument", K(ret), K(rows_info)); - } else if (OB_UNLIKELY(rows_info.tablet_id_ != key_.tablet_id_)) { - ret = OB_ERR_SYS; - LOG_ERROR("Tablet id not match", K(ret), K_(key), K(rows_info)); } else if (no_data_to_read()) { // Skip } else if (rows_info.all_rows_found()) { diff --git a/src/storage/blocksstable/ob_sstable_meta.cpp b/src/storage/blocksstable/ob_sstable_meta.cpp index ee778a5b0..7939e7c72 100644 --- a/src/storage/blocksstable/ob_sstable_meta.cpp +++ b/src/storage/blocksstable/ob_sstable_meta.cpp @@ -1228,6 +1228,7 @@ int ObMigrationSSTableParam::deserialize_(const char *buf, const int64_t data_le return ret; } + DEFINE_GET_SERIALIZE_SIZE(ObMigrationSSTableParam) { int64_t len = 0; diff --git a/src/storage/compaction/ob_compaction_diagnose.cpp b/src/storage/compaction/ob_compaction_diagnose.cpp index a096d2359..f96983369 100644 --- a/src/storage/compaction/ob_compaction_diagnose.cpp +++ b/src/storage/compaction/ob_compaction_diagnose.cpp @@ -1244,7 +1244,7 @@ int ObCompactionDiagnoseMgr::diagnose_tablet_mini_merge( } else if (nullptr != first_frozen_memtable) { // have frozen memtable bool diagnose_flag = false; ObSSTable *latest_sstable = nullptr; - ObIMemtable *frozen_memtable = static_cast(first_frozen_memtable); + storage::ObIMemtable *frozen_memtable = static_cast(first_frozen_memtable); if (OB_ISNULL(latest_sstable = static_cast( table_store_wrapper.get_member()->get_minor_sstables().get_boundary_table(true/*last*/)))) { diagnose_flag = true; diff --git a/src/storage/compaction/ob_medium_compaction_func.cpp b/src/storage/compaction/ob_medium_compaction_func.cpp index 7167c8138..342439fce 100644 --- a/src/storage/compaction/ob_medium_compaction_func.cpp +++ b/src/storage/compaction/ob_medium_compaction_func.cpp @@ -877,7 +877,7 @@ int ObMediumCompactionScheduleFunc::init_co_major_merge_type( } else if (FALSE_IT(co_sstable = static_cast(first_sstable))) { } else if (OB_FAIL(iter.set_tablet_handle(tablet_handle_))) { LOG_WARN("failed to set tablet handle", K(ret), K(iter), K(tablet_handle_)); - } else if (OB_FAIL(iter.get_read_tables_from_tablet(medium_info.medium_snapshot_, false/*allow_no_ready_read*/, false/*major_sstable_only*/, tables))) { + } else if (OB_FAIL(iter.get_read_tables_from_tablet(medium_info.medium_snapshot_, false/*allow_no_ready_read*/, false/*major_sstable_only*/, false/*need_split_src_table*/, false/*need_split_dst_table*/, tables))) { LOG_WARN("failed to get read tables for estimate row cnt", K(ret), K(medium_info), K(iter)); } else if (OB_FAIL(ObCOMajorMergePolicy::decide_co_major_merge_type( *co_sstable, diff --git a/src/storage/compaction/ob_partition_merge_iter.h b/src/storage/compaction/ob_partition_merge_iter.h index a0aca4795..398cf417d 100644 --- a/src/storage/compaction/ob_partition_merge_iter.h +++ b/src/storage/compaction/ob_partition_merge_iter.h @@ -21,6 +21,8 @@ #include "storage/access/ob_table_access_param.h" #include "storage/access/ob_table_access_context.h" #include "storage/compaction/ob_index_block_micro_iterator.h" +#include "storage/blocksstable/index_block/ob_index_block_macro_iterator.h" +#include "storage/blocksstable/index_block/ob_sstable_sec_meta_iterator.h" #include "storage/blocksstable/index_block/ob_index_block_dual_meta_iterator.h" #include "storage/blocksstable/index_block/ob_sstable_sec_meta_iterator.h" #include "storage/blocksstable/ob_datum_row.h" diff --git a/src/storage/compaction/ob_schedule_dag_func.cpp b/src/storage/compaction/ob_schedule_dag_func.cpp index eccf8052f..df4d634aa 100644 --- a/src/storage/compaction/ob_schedule_dag_func.cpp +++ b/src/storage/compaction/ob_schedule_dag_func.cpp @@ -14,11 +14,13 @@ #include "ob_schedule_dag_func.h" #include "share/scheduler/ob_tenant_dag_scheduler.h" #include "storage/ddl/ob_ddl_merge_task.h" +#include "storage/ddl/ob_tablet_split_task.h" #include "storage/compaction/ob_tablet_merge_task.h" #include "storage/column_store/ob_co_merge_dag.h" #include "lib/oblog/ob_log_module.h" #include "storage/multi_data_source/ob_mds_table_merge_dag.h" #include "storage/multi_data_source/ob_mds_table_merge_dag_param.h" +#include "storage/ddl/ob_tablet_lob_split_task.h" #ifdef OB_BUILD_SHARED_STORAGE #include "storage/compaction/ob_tablet_refresh_dag.h" #include "storage/compaction/ob_verify_ckm_dag.h" @@ -47,6 +49,16 @@ namespace compaction LOG_DEBUG("success to schedule tablet merge dag", K(ret), K(param)); \ } +#define CREATE_AND_GET_DAG(T, dag) \ + { \ + if (OB_FAIL(MTL(ObTenantDagScheduler*)->create_dag(¶m, dag))) { \ + if (OB_SIZE_OVERFLOW != ret && OB_EAGAIN != ret) { \ + LOG_WARN("failed to create merge dag", K(ret), K(param)); \ + } \ + } else { \ + LOG_DEBUG("success to create and get dag", K(ret), K(param)); \ + } \ + } int ObScheduleDagFunc::schedule_tx_table_merge_dag( ObTabletMergeDagParam ¶m, const bool is_emergency) @@ -96,6 +108,43 @@ int ObScheduleDagFunc::schedule_ddl_table_merge_dag( return ret; } +int ObScheduleDagFunc::schedule_tablet_split_dag( + ObTabletSplitParam ¶m, + const bool is_emergency) +{ + int ret = OB_SUCCESS; + CREATE_DAG(ObTabletSplitDag); + return ret; +} +int ObScheduleDagFunc::schedule_and_get_tablet_split_dag( + storage::ObTabletSplitParam ¶m, + storage::ObTabletSplitDag *&dag, + const bool is_emergency) +{ + int ret = OB_SUCCESS; + CREATE_AND_GET_DAG(ObTabletSplitDag, dag); + return ret; +} + +int ObScheduleDagFunc::schedule_lob_tablet_split_dag( + ObLobSplitParam ¶m, + const bool is_emergency) +{ + int ret = OB_SUCCESS; + CREATE_DAG(ObTabletLobSplitDag); + return ret; +} + +int ObScheduleDagFunc::schedule_and_get_lob_tablet_split_dag( + storage::ObLobSplitParam ¶m, + storage::ObTabletLobSplitDag *&dag, + const bool is_emergency) +{ + int ret = OB_SUCCESS; + CREATE_AND_GET_DAG(ObTabletLobSplitDag, dag); + return ret; +} + int ObScheduleDagFunc::schedule_mds_table_merge_dag( storage::mds::ObMdsTableMergeDagParam ¶m, const bool is_emergency) diff --git a/src/storage/compaction/ob_schedule_dag_func.h b/src/storage/compaction/ob_schedule_dag_func.h index e56b253df..67a802989 100644 --- a/src/storage/compaction/ob_schedule_dag_func.h +++ b/src/storage/compaction/ob_schedule_dag_func.h @@ -28,8 +28,17 @@ namespace mds class ObMdsTableMergeDagParam; } struct ObDDLTableMergeDagParam; +struct ObTabletSplitParam; +struct ObLobSplitParam; +class ObTabletSplitDag; +class ObTabletLobSplitDag; +class ObComplementDataDag; } +namespace share +{ +class ObTenantDagScheduler; +} namespace compaction { struct ObTabletMergeDagParam; @@ -54,8 +63,22 @@ public: static int schedule_ddl_table_merge_dag( storage::ObDDLTableMergeDagParam ¶m, const bool is_emergency = false); + static int schedule_tablet_split_dag( + storage::ObTabletSplitParam ¶m, + const bool is_emergency = false); + static int schedule_and_get_tablet_split_dag( + storage::ObTabletSplitParam ¶m, + storage::ObTabletSplitDag *&dag, + const bool is_emergency = false); + static int schedule_lob_tablet_split_dag( + storage::ObLobSplitParam ¶m, + const bool is_emergency = false); static int schedule_tablet_co_merge_dag_net( ObCOMergeDagParam ¶m); + static int schedule_and_get_lob_tablet_split_dag( + storage::ObLobSplitParam ¶m, + storage::ObTabletLobSplitDag *&dag, + const bool is_emergency = false); static int schedule_mds_table_merge_dag( storage::mds::ObMdsTableMergeDagParam ¶m, const bool is_emergency = false); diff --git a/src/storage/compaction/ob_tablet_merge_checker.cpp b/src/storage/compaction/ob_tablet_merge_checker.cpp index 11be7d099..aa4d6aa65 100644 --- a/src/storage/compaction/ob_tablet_merge_checker.cpp +++ b/src/storage/compaction/ob_tablet_merge_checker.cpp @@ -73,10 +73,11 @@ int ObTabletMergeChecker::check_could_merge_for_medium( if (OB_FAIL(tablet.ObITabletMdsInterface::get_latest_tablet_status(user_data, committed_flag))) { LOG_WARN("failed to get tablet status", K(ret), K(tablet), K(user_data)); } else if (ObTabletStatus::TRANSFER_OUT == user_data.tablet_status_ - || ObTabletStatus::TRANSFER_OUT_DELETED == user_data.tablet_status_) { + || ObTabletStatus::TRANSFER_OUT_DELETED == user_data.tablet_status_ + || ObTabletStatus::SPLIT_SRC_DELETED == user_data.tablet_status_) { could_schedule_merge = false; if (REACH_TENANT_TIME_INTERVAL(PRINT_LOG_INVERVAL)) { - LOG_INFO("tablet status is TRANSFER_OUT or TRANSFER_OUT_DELETED, merging is not allowed", K(user_data), K(tablet)); + LOG_INFO("tablet status is TRANSFER_OUT or TRANSFER_OUT_DELETED or SPLIT_SRC_DELETED, merging is not allowed", K(user_data), K(tablet)); } } return ret; diff --git a/src/storage/compaction/ob_tablet_merge_ctx.cpp b/src/storage/compaction/ob_tablet_merge_ctx.cpp index f2ee689e0..d9a90fdcd 100644 --- a/src/storage/compaction/ob_tablet_merge_ctx.cpp +++ b/src/storage/compaction/ob_tablet_merge_ctx.cpp @@ -12,6 +12,7 @@ #define USING_LOG_PREFIX STORAGE_COMPACTION #include "storage/compaction/ob_tablet_merge_ctx.h" +#include "share/schema/ob_tenant_schema_service.h" #include "storage/blocksstable/index_block/ob_index_block_builder.h" #include "storage/ob_storage_schema.h" #include "storage/tablet/ob_tablet_create_delete_helper.h" diff --git a/src/storage/compaction/ob_tablet_merge_task.cpp b/src/storage/compaction/ob_tablet_merge_task.cpp index 619b23de5..cb151aef8 100644 --- a/src/storage/compaction/ob_tablet_merge_task.cpp +++ b/src/storage/compaction/ob_tablet_merge_task.cpp @@ -15,6 +15,7 @@ #include "storage/compaction/ob_partition_merger.h" #include "share/rc/ob_tenant_base.h" #include "lib/stat/ob_session_stat.h" +#include "storage/blocksstable/index_block/ob_index_block_builder.h" #include "storage/tablet/ob_tablet_common.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/compaction/ob_partition_merge_progress.h" @@ -965,8 +966,8 @@ int ObTabletMergeFinishTask::report_checkpoint_diagnose_info(ObTabletMergeCtx &c merge_history.running_info_.merge_start_time_, merge_history.running_info_.merge_finish_time_, merge_history.block_info_.occupy_size_, merge_history.static_info_.concurrent_cnt_)); } else { - ObIMemtable *memtable = nullptr; - memtable = static_cast(table); + storage::ObIMemtable *memtable = nullptr; + memtable = static_cast(table); REPORT_CHECKPOINT_DIAGNOSE_INFO(update_merge_info_for_checkpoint_unit, memtable) } } diff --git a/src/storage/ddl/ob_build_index_task.cpp b/src/storage/ddl/ob_build_index_task.cpp index 9937d2c76..c7710dbb8 100644 --- a/src/storage/ddl/ob_build_index_task.cpp +++ b/src/storage/ddl/ob_build_index_task.cpp @@ -179,7 +179,9 @@ int ObUniqueIndexChecker::scan_table_with_column_checksum( ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, param.snapshot_version_, param.snapshot_version_, - iterator, allow_not_ready))) { + iterator, allow_not_ready, + false/*need_split_src_table*/, + false/*need_split_dst_table*/))) { if (OB_REPLICA_NOT_READABLE == ret) { ret = OB_EAGAIN; } else { diff --git a/src/storage/ddl/ob_complement_data_task.cpp b/src/storage/ddl/ob_complement_data_task.cpp index 92489d544..f942aecb3 100644 --- a/src/storage/ddl/ob_complement_data_task.cpp +++ b/src/storage/ddl/ob_complement_data_task.cpp @@ -485,6 +485,33 @@ int ObComplementDataDag::init(const ObDDLBuildSingleReplicaRequestArg &arg) return ret; } +int ObComplementDataDag::calc_total_row_count() +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("has not been inited ", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(param_)); + } else if (context_.physical_row_count_ != 0) { + ret = OB_INIT_TWICE; + LOG_WARN("has calculated the row_count", K(ret), K(context_.physical_row_count_)); + } else if (param_.orig_tenant_id_ != param_.dest_tenant_id_) { + // FIXME(YIREN), How to calc the row count of the source tablet for restore table. + // RPC? + } else if (OB_FAIL(ObDDLUtil::get_tablet_physical_row_cnt( + param_.orig_ls_id_, + param_.orig_tablet_id_, + true, // calc_sstable = true + true, // calc_memtable = true + context_.physical_row_count_))) { + LOG_WARN("failed to calc row count", K(ret), K(param_), K(context_)); + } + return ret; +} + int ObComplementDataDag::create_first_task() { int ret = OB_SUCCESS; @@ -633,8 +660,8 @@ int ObComplementDataDag::report_replica_build_status() arg.dest_schema_version_ = param_.dest_schema_version_; arg.task_id_ = param_.task_id_; arg.execution_id_ = param_.execution_id_; - arg.row_scanned_ = context_.row_scanned_; arg.row_inserted_ = context_.row_inserted_; + arg.physical_row_count_ = context_.physical_row_count_; arg.server_addr_ = GCTX.self_addr(); FLOG_INFO("send replica build status response to RS", K(ret), K(context_), K(arg)); if (OB_FAIL(ret)) { @@ -766,6 +793,8 @@ int ObComplementPrepareTask::process() } else if (FALSE_IT(dag = static_cast(tmp_dag))) { } else if (OB_FAIL(dag->prepare_context())) { LOG_WARN("prepare complement context failed", K(ret)); + } else if (OB_FAIL(dag->calc_total_row_count())) { // only calc row count once time for a task + LOG_WARN("failed to calc task row count", K(ret)); } else if (context_->is_major_sstable_exist_) { FLOG_INFO("major sstable exists, all task should finish", K(ret), K(*param_)); } else if (OB_FAIL(context_->write_start_log(*param_))) { @@ -1092,8 +1121,7 @@ int ObComplementWriteTask::do_local_scan() LOG_WARN("ddl sim failure", K(ret), KPC(param_)); } else if (OB_FAIL(ls_handle.get_ls()->get_tablet_svr()->get_read_tables(param_->orig_tablet_id_, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, - param_->snapshot_version_, param_->snapshot_version_, - iterator, allow_not_ready))) { + param_->snapshot_version_, param_->snapshot_version_, iterator, allow_not_ready, false/*need_split_src_table*/, false/*need_split_dst_table*/))) { if (OB_REPLICA_NOT_READABLE == ret) { ret = OB_EAGAIN; } else { diff --git a/src/storage/ddl/ob_complement_data_task.h b/src/storage/ddl/ob_complement_data_task.h index 642f530b4..473e06d40 100644 --- a/src/storage/ddl/ob_complement_data_task.h +++ b/src/storage/ddl/ob_complement_data_task.h @@ -23,6 +23,30 @@ namespace oceanbase namespace storage { +template +int add_dag_and_get_progress( + T *dag, + int64_t &row_inserted, + int64_t &physical_row_count) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + row_inserted = 0; + physical_row_count = 0; + if (OB_ISNULL(dag)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KP(dag)); + } else if (OB_FAIL(MTL(ObTenantDagScheduler*)->add_dag(dag))) { + // caution ret = OB_EAGAIN or OB_SIZE_OVERFLOW + if (OB_EAGAIN == ret + && OB_TMP_FAIL(MTL(ObTenantDagScheduler*)->get_dag_progress(dag, row_inserted, physical_row_count))) { + // tmp_ret is used to prevent the failure from affecting DDL_Task status + LOG_WARN("get complement data progress failed", K(tmp_ret), K(ret)); + } + } + return ret; +} + class ObScan; class ObLocalScan; class ObRemoteScan; @@ -120,7 +144,7 @@ public: is_inited_(false), ddl_agent_(), direct_load_type_(ObDirectLoadType::DIRECT_LOAD_INVALID), is_major_sstable_exist_(false), complement_data_ret_(common::OB_SUCCESS), lock_(ObLatchIds::COMPLEMENT_DATA_CONTEXT_LOCK), concurrent_cnt_(0), - row_scanned_(0), row_inserted_(0), cg_row_inserted_(0), context_id_(0), lob_cols_cnt_(0) + physical_row_count_(0), row_scanned_(0), row_inserted_(0), cg_row_inserted_(0), context_id_(0), lob_cols_cnt_(0) {} ~ObComplementDataContext() { destroy(); } int init( @@ -131,7 +155,7 @@ public: int add_column_checksum(const ObIArray &report_col_checksums, const ObIArray &report_col_ids); int get_column_checksum(ObIArray &report_col_checksums, ObIArray &report_col_ids); TO_STRING_KV(K_(is_inited), K_(ddl_agent), K_(direct_load_type), K_(is_major_sstable_exist), K_(complement_data_ret), K_(concurrent_cnt), - K_(row_scanned), K_(row_inserted), K_(cg_row_inserted), K_(context_id), K_(lob_cols_cnt)); + K_(physical_row_count), K_(row_scanned), K_(row_inserted), K_(cg_row_inserted), K_(context_id), K_(lob_cols_cnt)); public: bool is_inited_; ObDirectLoadMgrAgent ddl_agent_; @@ -140,6 +164,7 @@ public: int complement_data_ret_; ObSpinLock lock_; int64_t concurrent_cnt_; + int64_t physical_row_count_; int64_t row_scanned_; int64_t row_inserted_; int64_t cg_row_inserted_; // unused now. @@ -162,9 +187,9 @@ public: int64_t hash() const; bool operator ==(const share::ObIDag &other) const; bool is_inited() const { return is_inited_; } + void handle_init_failed_ret_code(int ret) { context_.complement_data_ret_ = ret; } ObComplementDataParam &get_param() { return param_; } ObComplementDataContext &get_context() { return context_; } - void handle_init_failed_ret_code(int ret) { context_.complement_data_ret_ = ret; } int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; int fill_dag_key(char *buf, const int64_t buf_len) const override; @@ -177,6 +202,7 @@ public: virtual bool is_ha_dag() const override { return false; } // report replica build status to RS. int report_replica_build_status(); + int calc_total_row_count(); int check_and_exit_on_demand(); private: bool is_inited_; diff --git a/src/storage/ddl/ob_ddl_alter_auto_part_attr.cpp b/src/storage/ddl/ob_ddl_alter_auto_part_attr.cpp new file mode 100644 index 000000000..c4b3627e9 --- /dev/null +++ b/src/storage/ddl/ob_ddl_alter_auto_part_attr.cpp @@ -0,0 +1,682 @@ +/** + * 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_ddl_alter_auto_part_attr.h" +#include "share/schema/ob_table_schema.h" +#include "sql/resolver/ob_resolver_utils.h" +#include "src/share/ob_ddl_common.h" + +using namespace oceanbase::common; +using namespace oceanbase::share; + + +ObAlterAutoPartAttrOp::ObAlterAutoPartAttrOp(rootserver::ObDDLService &ddl_service) + : ddl_service_(&ddl_service) +{ +} + +int ObAlterAutoPartAttrOp::check_alter_table_partition_attr( + const obrpc::ObAlterTableArg &alter_table_arg, + const share::schema::ObTableSchema &orig_table_schema, + const bool is_oracle_mode, + share::ObDDLType &ddl_type) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = orig_table_schema.get_tenant_id(); + const uint64_t tablegroup_id = orig_table_schema.get_tablegroup_id(); + const ObPartitionLevel part_level = orig_table_schema.get_part_level(); + const AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; + const ObPartitionOption &part_option = alter_table_schema.get_part_option(); + ObPartition **alter_part_array = alter_table_schema.get_part_array(); + if (is_long_running_ddl(ddl_type)) { + ret = OB_NOT_SUPPORTED; + LOG_USER_ERROR(OB_NOT_SUPPORTED, "There are several mutually exclusive DDL in single statement"); + } else if (obrpc::ObAlterTableArg::REPARTITION_TABLE == alter_table_arg.alter_part_type_) { + if (is_oracle_mode && PARTITION_LEVEL_ZERO != part_level && OB_NOT_NULL(alter_part_array)) { + ret = OB_NOT_SUPPORTED; + LOG_USER_ERROR(OB_NOT_SUPPORTED, "re-partition a patitioned table"); + } else if (OB_INVALID_ID != tablegroup_id) { + ret = OB_NOT_SUPPORTED; + LOG_USER_ERROR(OB_NOT_SUPPORTED, "alter auto partition attribute of a table in tablegroup is"); + } else { + ddl_type = ObDDLType::DDL_ALTER_PARTITION_BY; + } + } else { + ddl_type = ObDDLType::DDL_NORMAL_TYPE; + } + if (OB_SUCC(ret)) { + /* in the case like "alter table partition by range() size('unlimited') + * the variables like enable_auto_split and auto_split_tablet_size will be reset to false or int64_t in ddl resolver + * then we will regard it as DDL_ALTER_PARTITION_AUTO_SPLIT_ATTRIBUTE and deal with in alter_table_in_trans */ + if (part_option.get_part_func_expr_str().empty()) { + /* alter partition by range() size(xxx) */ + ddl_type = ObDDLType::DDL_ALTER_PARTITION_AUTO_SPLIT_ATTRIBUTE; + } else { + /* alter partition by range(xxx) size(xxx) */ + if (OB_ISNULL(alter_part_array)) { + ddl_type = ObDDLType::DDL_ALTER_PARTITION_AUTO_SPLIT_ATTRIBUTE; + } + } + } + LOG_DEBUG("auto part, after switch ddl type", K(ddl_type)); + return ret; +} + +int ObAlterAutoPartAttrOp::alter_table_partition_attr( + obrpc::ObAlterTableArg &alter_table_arg, + const share::schema::ObTableSchema &orig_table_schema, + share::schema::ObTableSchema &new_table_schema) +{ + // In the alter table partition by range(xxx) size(xxx) (partitions...) case, + // it is necessary to modify attributes related to automatic partitioning here. + int ret = OB_SUCCESS; + AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; + if (OB_ISNULL(ddl_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ddl service", K(ret), KP(ddl_service_)); + } else if (OB_FAIL(ddl_service_->gen_alter_partition_new_table_schema_offline( + alter_table_arg, alter_table_schema, orig_table_schema, new_table_schema))) { + LOG_WARN("fail to gen alter partition new table schema", K(ret)); + } else if (OB_FAIL(new_table_schema.check_validity_for_auto_partition())) { + LOG_WARN("fail to check enable auto partitioning", KR(ret), K(new_table_schema)); + } + return ret; +} + +/* +description: + 0. For non-partitioned tables with automatic partitioning, the part_func_expr is not null, but part_level=zero. + 1. For partitioned tables, whether automatically partitioned or not, directly use the partition expression, or directly use the partition key. + 2. For non-partitioned tables, there are two scenarios: + a. For automatically partitioned non-partitioned tables, use the partition expression. + b. For non-automatically partitioned non-partitioned tables, use the primary key. +*/ +int ObAlterAutoPartAttrOp::get_part_key_column_ids( + const ObTableSchema &table_schema, + ObIArray &part_key_ids) +{ + int ret = OB_SUCCESS; + part_key_ids.reset(); + // origin table partition is auto partition table, and is not partition table + if (!table_schema.is_partitioned_table() && table_schema.is_auto_partitioned_table()) { + if (OB_FAIL(table_schema.get_presetting_partition_keys(part_key_ids))) { // take part func or rowkey + LOG_WARN("fail to get presetting partition keys", K(ret)); + } + } else { // origin table is partition table or is not auto partition table + ObString origin_table_part_func_expr = table_schema.get_part_option().get_part_func_expr_str(); + if (origin_table_part_func_expr.empty()) { // get rowkey as part key + const ObRowkeyInfo &part_keys = table_schema.get_rowkey_info(); + for (int64_t i = 0; OB_SUCC(ret) && i < part_keys.get_size(); ++i) { + const ObRowkeyColumn *part_key_column = part_keys.get_column(i); + if (OB_ISNULL(part_key_column)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the partition key is NULL, ", K(ret), K(part_keys)); + } else if (is_shadow_column(part_key_column->column_id_)) { + } else if (OB_FAIL(part_key_ids.push_back(part_key_column->column_id_))) { + LOG_WARN("failed to push back rowkey column id", K(ret)); + } + } + } else { + const ObPartitionKeyInfo &partition_keys = table_schema.get_partition_key_info(); + if (partition_keys.is_valid() && OB_FAIL(partition_keys.get_column_ids(part_key_ids))) { + LOG_WARN("fail to get column ids from partition keys", K(ret)); + } + } + } + LOG_DEBUG("get partition key columns id", K(ret), K(part_key_ids)); + return ret; +} + +int ObAlterAutoPartAttrOp::check_part_key_column_type( + const ObTableSchema &table_schema, + const ObPartitionOption &alter_part_option, + bool &is_valid_part_column) +{ + int ret = OB_SUCCESS; + ObArray part_key_ids; + ObString alter_part_func_expr = alter_part_option.get_part_func_expr_str(); + is_valid_part_column = true; + if (!alter_part_option.is_enable_auto_part() + && !table_schema.is_partitioned_table() && !table_schema.is_auto_partitioned_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected none partition table, not enable auto part to but check part key.", + K(ret), K(table_schema), K(alter_part_option)); + } else if (alter_part_func_expr.empty()) { + // if user not define auto part func expr, we will get part ids from old table schema. + if (OB_FAIL(get_part_key_column_ids(table_schema, part_key_ids))) { + LOG_WARN("fail to get part key ids", K(ret)); + } + } else if (OB_FAIL(table_schema.get_partition_keys_by_part_func_expr(alter_part_func_expr, part_key_ids))) { + LOG_WARN("fail to get partition key", K(ret)); + } + // check part column type is valid + if (OB_SUCC(ret)) { + const ObColumnSchemaV2 *column_schema = NULL; + ObPartitionFuncType part_type = part_key_ids.count() > 1 ? + PARTITION_FUNC_TYPE_RANGE_COLUMNS : + PARTITION_FUNC_TYPE_RANGE; + for (int64_t i = 0; OB_SUCC(ret) && is_valid_part_column && i < part_key_ids.count(); ++i) { + uint64_t part_key_id = part_key_ids.at(i); + if (part_key_id >= OB_MIN_SHADOW_COLUMN_ID || part_key_id < OB_APP_MIN_COLUMN_ID) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected part key id", K(ret), K(part_key_id)); + } else if (OB_FALSE_IT(column_schema = table_schema.get_column_schema(part_key_id))) { + } else if (OB_ISNULL(column_schema)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("column schema not exist", K(ret), K(table_schema), K(part_key_id)); + } else { + ObObjType type = column_schema->get_data_type(); + if (ObResolverUtils::is_partition_range_column_type(type)) { + /* case: + create table t1(c1 double, c2 int, primary key(c1)); + alter table t1 partition by range(); + */ + part_type = ObPartitionFuncType::PARTITION_FUNC_TYPE_RANGE_COLUMNS; + } + is_valid_part_column = + ObResolverUtils::is_valid_partition_column_type(column_schema->get_data_type(), part_type, false); + } + } + } + return ret; +} + +int ObAlterAutoPartAttrOp::lock_for_modify_auto_part_size( + const ObTableSchema &table_schema, + ObSchemaGetterGuard &schema_guard, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t data_table_id = table_schema.get_table_id(); + ObArray global_index_table_ids; + ObArray simple_index_infos; + if (OB_FAIL(table_schema.get_simple_index_infos(simple_index_infos))) { + LOG_WARN("get simple_index_infos failed", KR(ret), K(tenant_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) { + const uint64_t index_table_id = simple_index_infos.at(i).table_id_; + const ObIndexType index_type = simple_index_infos.at(i).index_type_; + if (!is_index_local_storage(index_type)) { + if (OB_FAIL(global_index_table_ids.push_back(index_table_id))) { + LOG_WARN("failed to push back", K(ret)); + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObDDLLock::lock_for_modify_auto_part_size_in_trans(tenant_id, data_table_id, global_index_table_ids, trans))) { + LOG_WARN("failed to lock for modify auto part size", K(ret)); + } + return ret; +} + +int ObAlterAutoPartAttrOp::alter_table_auto_part_attr_if_need( + const ObAlterTableArg &alter_table_arg, + const ObDDLType ddl_type, + ObSchemaGetterGuard &schema_guard, + ObTableSchema &table_schema, + rootserver::ObDDLOperator &ddl_operator, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (!alter_table_arg.alter_auto_partition_attr_ + || ddl_type != ObDDLType::DDL_ALTER_PARTITION_AUTO_SPLIT_ATTRIBUTE) { + /* in alter table partition by range() (partition...) case, + * we do not suppose to modify everything about auto split attr here */ + ret = OB_ERR_UNEXPECTED; + LOG_WARN("modified auto partition attr, not expected here", K(ret), K(ddl_type), + K(alter_table_arg.alter_auto_partition_attr_)); + } else if (table_schema.is_heap_table() || table_schema.is_in_recyclebin()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("modified auto partition attr, unexpected table status", K(ret), K(table_schema)); + } else if (OB_FAIL(lock_for_modify_auto_part_size(table_schema, schema_guard, trans))) { + LOG_WARN("failed to lock for modify auto part size", K(ret)); + } else { + const AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; + const ObPartitionOption &alter_part_option = alter_table_schema.get_part_option(); + const uint64_t tenant_id = table_schema.get_tenant_id(); + if (alter_part_option.is_enable_auto_part()) { + ObString alter_part_func_expr = alter_part_option.get_part_func_expr_str(); // no ref + bool is_valid_column_type = true; + if (OB_FAIL(check_part_key_column_type(table_schema, alter_part_option, is_valid_column_type))) { + LOG_WARN("fail to check part column type", K(ret), K(alter_part_option)); + } else if (!is_valid_column_type) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("fail to alter table partition, not support yet", K(ret)); + } + if (OB_SUCC(ret)) { + if (alter_part_func_expr.empty()) { + /* case 1: part func is empty, like: alter table partition by range() size('xxx'); */ + /* if table is none part table, and part func is empty, set partition type "range" */ + /* we will set part func type in table_schema.enable_auto_partition according to old table schema potential part func, do nothing here */ + } else { + /* case 2: part func is not empty, like : alter table partition by range(c1) size('xxx'); */ + if (OB_FAIL(check_auto_part_table_unique_index(table_schema, alter_part_func_expr, schema_guard))) { + LOG_WARN("fail to check auto part table unique index.", K(ret), K(table_schema)); + } else if (OB_FAIL(check_and_set_table_auto_part_func(alter_part_option, table_schema))) { + LOG_WARN("fail to check and set table auto part func.", K(ret), K(table_schema)); + } + } + } + // enable auto split + if (OB_SUCC(ret)) { + if (OB_FAIL(table_schema.enable_auto_partition(alter_part_option.get_auto_part_size()))) { + LOG_WARN("fail to enable auto partition", K(ret), K(alter_part_option)); + } else if (OB_FAIL(table_schema.check_enable_split_partition(true))) { // check origin table is satisfied auto partition conditions before enabled + LOG_WARN("fail to check validity for auto-partition", K(ret), K(table_schema)); + } + } + } else { + /* case 3: disable auto partition, like: alter table partition by range() size('unlimited') */ + table_schema.forbid_auto_partition(); + } + if (OB_SUCC(ret)) { + /* update global index property + * if main table is enable auto split partition table, global index table should + * change auto split property too */ + if (OB_FAIL(alter_global_indexes_auto_part_attribute_online( // update index + alter_part_option, table_schema, schema_guard, ddl_operator, trans))) { + LOG_WARN("fail to alter global index auto part property.", K(ret), K(table_schema)); + } else if (OB_FAIL(ddl_operator.update_partition_option(trans, table_schema, alter_table_arg.ddl_stmt_str_))) { // update main table + LOG_WARN("fail to update partition option", K(ret), K(table_schema)); + } + } + + if (OB_SUCC(ret)) { + const int64_t abs_timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_ts() : ObTimeUtility::current_time() + GCONF.rpc_timeout; + ObArray tablet_ids; + if (OB_FAIL(table_schema.get_tablet_ids(tablet_ids))) { + LOG_WARN("failed to get tablet ids", K(ret)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::modify_auto_part_size(tenant_id, tablet_ids, table_schema.get_auto_part_size(), abs_timeout_us, trans))) { + LOG_WARN("failed to modify auto part size", K(ret)); + } + } + } + return ret; +} + +/* +description: + 1. if origin table is none partition table, should set new partition type according to alter table partition func + 2. if origin table if partition table, should check alter table partition func is equal to origin partition func or not +*/ +int ObAlterAutoPartAttrOp::check_and_set_table_auto_part_func( + const ObPartitionOption &alter_part_option, + ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + if (table_schema.get_part_level() == PARTITION_LEVEL_ZERO) { + ObString tmp_part_func_expr = alter_part_option.get_part_func_expr_str(); + ObPartitionFuncType part_func_type; + if (OB_FAIL(extract_potential_partition_func_type(table_schema, tmp_part_func_expr, part_func_type))) { + LOG_WARN("fail to extract partition func type", K(ret), K(table_schema)); + } else { + table_schema.get_part_option().set_part_func_type(part_func_type); + /* origin table is none partition table, set alter table partition func expr directly */ + table_schema.get_part_option().set_part_expr(alter_part_option.get_part_func_expr_str()); + } + } else if (table_schema.get_part_level() == PARTITION_LEVEL_ONE) { + ObString tmp_old_part_func_expr = table_schema.get_part_option().get_part_func_expr_str(); + ObString tmp_alter_table_part_func_expr = alter_part_option.get_part_func_expr_str(); + ObArray old_expr_strs; + ObArray new_expr_strs; + // partition by range columns(c1,c2) and partition by range columns(c1, c2) is the same. + if (OB_FAIL(split_on(tmp_old_part_func_expr, ',', old_expr_strs))) { + LOG_WARN("fail to split func expr", K(ret), K(tmp_old_part_func_expr)); + } else if (OB_FAIL(split_on(tmp_alter_table_part_func_expr, ',', new_expr_strs))) { + LOG_WARN("fail to split func expr", K(ret), K(tmp_alter_table_part_func_expr)); + } else if (old_expr_strs.count() != new_expr_strs.count()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("fail to alter table partition, ori table func expr is diff from alter partition func expr.", + K(ret), K(old_expr_strs), K(new_expr_strs)); + } else { + // the columns in origin table part func expr must be in order with primary key (prefixed) + // so as to the columns order of alter partition func expr. if not the same, alter partition by will + // cause error in sql resolver. + ObArenaAllocator allocator; + for (int64_t i = 0; OB_SUCC(ret) && i < new_expr_strs.count(); ++i) { + ObString in_new_expr_str = new_expr_strs.at(i).trim(); + ObString in_old_expr_str = old_expr_strs.at(i).trim(); + ObString out_new_expr_str = in_new_expr_str; + ObString out_old_expr_str = in_old_expr_str; + if (lib::is_oracle_mode()) { + if (OB_FAIL(ob_simple_low_to_up(allocator, in_new_expr_str, out_new_expr_str))) { + LOG_WARN("failed to transfer low to up column name", K(ret)); + } else if (OB_FAIL(ob_simple_low_to_up(allocator, in_old_expr_str, out_old_expr_str))) { + LOG_WARN("failed to transfer low to up column name", K(ret)); + } + } + if (OB_SUCC(ret) && (out_new_expr_str != out_old_expr_str)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("fail to alter table partition, ori table func expr is diff from alter partition func expr", + K(ret), K(old_expr_strs), K(new_expr_strs)); + } + } + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("alter auto table partition level large than one is not support currently!!!", + K(ret), K(table_schema.get_part_level())); + } + return ret; +} + +/* +description: + 1. If is enable auto partition and table is global index table, we should change global local index to global, + 2. Specially, if table is a partition table, partition key should satisfy prefix of index rowkey. +*/ +int ObAlterAutoPartAttrOp::alter_global_indexes_auto_part_attribute_online( + const ObPartitionOption &part_option, + const ObTableSchema &table_schema, + ObSchemaGetterGuard &schema_guard, + rootserver::ObDDLOperator &ddl_operator, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObSEArray simple_index_infos; + const ObTableSchema *index_schema = nullptr; + const int64_t tenant_id = table_schema.get_tenant_id(); + int64_t index_table_id = OB_INVALID_ID; + + if (OB_FAIL(table_schema.get_simple_index_infos(simple_index_infos))) { + LOG_WARN("get simple_index_infos failed", KR(ret), K(tenant_id)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) { + index_table_id = simple_index_infos.at(i).table_id_; + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, index_table_id, index_schema))) { + LOG_WARN("fail to get to_table_schema schema", K(ret)); + } else if (OB_ISNULL(index_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("index_schema is null", K(ret)); + } else if ((!index_schema->is_global_index_table() && !index_schema->is_global_local_index_table()) + || index_schema->is_spatial_index()) { + // skip + } else { + // cover global index table auto split property + ObString ddl_stmt_str(""); // empty ddl_stmt_str + HEAP_VAR(ObTableSchema, new_index_schema) { + if (OB_FAIL(new_index_schema.assign(*index_schema))) { + LOG_WARN("assign index_schema failed", K(ret)); + } else if (OB_FAIL(update_global_auto_split_attr(part_option, new_index_schema))) { + LOG_WARN("fail to update global auto split attr", K(ret), K(part_option)); + } else if (OB_FAIL(ddl_operator.update_partition_option(trans, new_index_schema, ddl_stmt_str))) { + LOG_WARN("fail to update partition option.", K(ret), K(new_index_schema)); + } + + if (OB_SUCC(ret)) { + // Note that global local index tablets also have auto_part_size + const int64_t abs_timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_ts() : ObTimeUtility::current_time() + GCONF.rpc_timeout; + ObArray tablet_ids; + if (OB_FAIL(new_index_schema.get_tablet_ids(tablet_ids))) { + LOG_WARN("failed to get tablet ids", K(ret)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::modify_auto_part_size(tenant_id, tablet_ids, new_index_schema.get_auto_part_size(), abs_timeout_us, trans))) { + LOG_WARN("failed to modify auto part size", K(ret)); + } + } + } // end heap var + if (OB_SUCC(ret)) { + if (part_option.get_auto_part() + && table_schema.get_part_level() == PARTITION_LEVEL_ZERO + && index_schema->is_global_local_index_table()) { + ObIndexType index_type; + if (OB_FAIL(switch_global_local_index_type(*index_schema, index_type))) { + LOG_WARN("fail to switch index type", K(ret)); + } else if (OB_FAIL(ddl_operator.update_index_type( + table_schema, index_table_id, index_type, &ddl_stmt_str, trans))) { + LOG_WARN("fail to update index type", K(ret), K(index_type)); + } + } + } + } + } + return ret; +} + +int ObAlterAutoPartAttrOp::switch_global_local_index_type( + const ObTableSchema &index_schema, + ObIndexType& index_type) +{ + int ret = OB_SUCCESS; + switch (index_schema.get_index_type()) { + case INDEX_TYPE_UNIQUE_GLOBAL_LOCAL_STORAGE: { + index_type = INDEX_TYPE_UNIQUE_GLOBAL; + break; + } + case INDEX_TYPE_NORMAL_GLOBAL_LOCAL_STORAGE: { + index_type = INDEX_TYPE_NORMAL_GLOBAL; + break; + } + default: { + ret = OB_NOT_SUPPORTED; + index_type = INDEX_TYPE_MAX; + LOG_WARN("not supported index type", K(ret), K(index_type), K(index_schema)); + } + } + return ret; +} +/* +description: + 1. in alter table partition by range(xxx) size(xxx) partitions case, should update global index partition attr +*/ +int ObAlterAutoPartAttrOp::alter_global_indexes_auto_part_attribute_offline( + ObAlterTableArg &alter_table_arg, + ObTableSchema &new_index_schema) +{ + int ret = OB_SUCCESS; + ObPartition **part_array = nullptr; + AlterTableSchema &alter_table_schema = alter_table_arg.alter_table_schema_; + const ObPartitionOption &alter_part_option = alter_table_schema.get_part_option(); + + if (!alter_table_arg.alter_auto_partition_attr_) { + // skip. + // in alter table
partition by range() (partition...) case, + // we do not suppose to modify everything about auto split table attr here + LOG_INFO("alter table part attr, auto attr is false, no need to change", + K(alter_table_arg.alter_auto_partition_attr_)); + } else if (!new_index_schema.is_global_index_table()) { + // only for global index table (not global local) + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected index type, here should be modify to global index type", + K(ret), K(new_index_schema)); + } else if (alter_part_option.get_part_func_expr_str().empty()) { + // This code path is specific to the 'alter table partition by range(xxx) size(xxx) (partition...)' syntax, + // indicating a modification of the automatic partitioning rules; + // therefore, if the 'part func' is empty, it is not allowed. + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected alter partition by case here, partition func expr is empty", + K(ret), K(alter_part_option)); + } else if (OB_ISNULL(alter_table_schema.get_part_array())) { + // Similar to the above, if the partitioning rules are empty, it is not permitted. + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected alter partition by case here, partition array is empty", + K(ret), K(alter_table_schema)); + } else if (OB_FAIL(update_global_auto_split_attr(alter_part_option, new_index_schema))) { + LOG_WARN("fail to update global auto split attr", K(ret), K(new_index_schema)); + } + return ret; +} + +/* + description: + Obtain the potential partition type of a non-partitioned table. + 这里如果预分裂键为double,虽然只有1列,但partition_func_type也要变成PARTITION_FUNC_TYPE_RANGE_COLUMNS +*/ +int ObAlterAutoPartAttrOp::extract_potential_partition_func_type( + const ObTableSchema &table_schema, + const ObString &part_func_expr, + ObPartitionFuncType &part_func_type) +{ + int ret = OB_SUCCESS; + if (part_func_expr.empty()) { + if (table_schema.is_index_table()) { // index table + ObArray rowkey_columns; + if (OB_FAIL(table_schema.extract_actual_index_rowkey_columns_name(rowkey_columns))) { + LOG_WARN("fail to extract index rowkey column cnt", K(ret)); + } else if (rowkey_columns.count() > 1) { + part_func_type = PARTITION_FUNC_TYPE_RANGE_COLUMNS; + } else { + part_func_type = PARTITION_FUNC_TYPE_RANGE; + // TODO: if partition key column type is double or float, + // partition func type should change to PARTITION_FUNC_TYPE_RANGE_COLUMNS later + } + } else if (table_schema.is_user_table()) { // user table + const ObRowkeyInfo &part_keys = table_schema.get_rowkey_info(); + if (part_keys.get_size() > 1) { + part_func_type = PARTITION_FUNC_TYPE_RANGE_COLUMNS; + } else { + part_func_type = PARTITION_FUNC_TYPE_RANGE; + // TODO: if partition key column type is double or float, + // partition func type should change to PARTITION_FUNC_TYPE_RANGE_COLUMNS later + } + } + } else { // part_func_expr is not empty + ObString tmp_part_func_expr = part_func_expr; + ObArray expr_strs; + if (OB_FAIL(split_on(tmp_part_func_expr, ',', expr_strs))) { + LOG_WARN("fail to split func expr", K(ret), K(tmp_part_func_expr)); + } else if (expr_strs.count() > 1) { // multi partition column + part_func_type = PARTITION_FUNC_TYPE_RANGE_COLUMNS; + } else { + part_func_type = PARTITION_FUNC_TYPE_RANGE; + // TODO: if partition key column type is double or float, + // partition func type should change to PARTITION_FUNC_TYPE_RANGE_COLUMNS later + } + } + return ret; +} +/* +description: +The following scenarios exist for modifications to global indexes: + 1. For a global non-partitioned index table, if it is being modified to an auto-partitioned global non-partitioned table, + it is necessary to change the auto_part and auto_part_size. The part_func_type should be modified to 'range' or 'range columns' based on the actual number of index keys. + 2. For a global partitioned index table, if it is being modified to an auto-partitioned global partitioned table, + it is necessary to change the auto_part and auto_part_size. + 3. For a global auto-partitioned non-partitioned index table, if it is being modified to a non-auto-partitioned non-partitioned table, + it is necessary to change the auto_part and auto_part_size, set the part_func_type to default, and modify the part_func_expr to null. + 4. For a global auto-partitioned partitioned index table, if it is being modified to a non-auto-partitioned non-partitioned table, + it is necessary to change the auto_part and auto_part_size. +*/ +int ObAlterAutoPartAttrOp::update_global_auto_split_attr( + const ObPartitionOption &alter_part_option, + ObTableSchema &new_index_schema) +{ + int ret = OB_SUCCESS; + bool enable_auto_split = alter_part_option.get_auto_part(); + ObPartitionOption &new_index_option = new_index_schema.get_part_option(); + if (new_index_schema.get_part_level() == PARTITION_LEVEL_ZERO) { + if (enable_auto_split) { + if (new_index_option.get_part_func_expr_str().empty()) { + ObString empty_part_func_expr; + ObPartitionFuncType part_func_type; + if (OB_FAIL(extract_potential_partition_func_type(new_index_schema, empty_part_func_expr, part_func_type))) { + LOG_WARN("fail to extract partition func type", K(ret), K(new_index_schema)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("none partition table and partition func expr not empty is not expected in global table", + K(ret), K(new_index_schema)); + } + } + } else if (new_index_schema.get_part_level() == PARTITION_LEVEL_ONE) { + // if user is turning on auto split attr, and index table is partition table, + // we should check partition key is satisfied prefixed of index rowkey key + if (enable_auto_split) { + if (OB_FAIL(new_index_schema.is_partition_key_match_rowkey_prefix(enable_auto_split))) { + LOG_WARN("fail to check partition key match rowkey prefix", K(ret)); + } else if (!new_index_schema.is_range_part()) { + // none range part table is not support, here we not set auto split attr + enable_auto_split = false; + } + } + } else { // not support + enable_auto_split = false; + } + if (OB_SUCC(ret)) { + if (enable_auto_split) { + if (OB_FAIL(new_index_schema.enable_auto_partition(alter_part_option.get_auto_part_size()))) { + LOG_WARN("fail to enable auto partition", K(ret), K(alter_part_option)); + } + } else { + new_index_schema.forbid_auto_partition(); + } + } + return ret; +} + +/* +description: + check unique local index if main table is none partition table, but open auto split partition property +*/ +int ObAlterAutoPartAttrOp::check_auto_part_table_unique_index( + const ObTableSchema &table_schema, + ObString &alter_table_part_func_expr, + ObSchemaGetterGuard &schema_guard) +{ + int ret = OB_SUCCESS; + const int64_t tenant_id = table_schema.get_tenant_id(); + const int64_t table_id = table_schema.get_table_id(); + bool has_unique_local_index = false; + if (OB_UNLIKELY(tenant_id == OB_INVALID_TENANT_ID || table_id == OB_INVALID_ID)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument.", K(ret), K(tenant_id), K(table_id)); + } else if (table_schema.get_part_level() > PARTITION_LEVEL_ZERO) { + // skip + } else if (!table_schema.is_user_table()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not support none user table do auto part attr modification", K(ret)); + } else if (OB_FAIL(schema_guard.check_has_local_unique_index( + tenant_id, table_id, has_unique_local_index))) { + LOG_WARN("fail to check has local unique index of main table", K(tenant_id), K(table_id)); + } else if (!has_unique_local_index) { + // skip + } else { + // get index table id + ObSEArray simple_index_infos; + if (OB_FAIL(table_schema.get_simple_index_infos(simple_index_infos))) { + LOG_WARN("get simple_index_infos failed", KR(ret), K(tenant_id), K(table_id)); + } + const ObTableSchema *index_schema = nullptr; + int64_t index_table_id = OB_INVALID_ID; + ObArray rowkey_name_columns; + for (int64_t i = 0; OB_SUCC(ret) && i < simple_index_infos.count(); ++i) { + index_table_id = simple_index_infos.at(i).table_id_; + if (OB_FAIL(schema_guard.get_table_schema(tenant_id, index_table_id, index_schema))) { + LOG_WARN("fail to get to_table_schema schema", K(ret)); + } else if (OB_ISNULL(index_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("index_schema is null", K(ret)); + } else if (!index_schema->is_local_unique_index_table()){ + // skip + } else if (OB_FAIL(index_schema->extract_actual_index_rowkey_columns_name(rowkey_name_columns))) { + LOG_WARN("fail to extract actual index rowkey columns", K(ret), K(*index_schema)); + } else { + // check main table partition key is included in unique local index key. + ObArray alter_part_column_array; + if (OB_FAIL(split_on(alter_table_part_func_expr, ',', alter_part_column_array))) { + LOG_WARN("fail to split func expr", K(ret), K(alter_table_part_func_expr)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < alter_part_column_array.count(); ++i) { + if (!has_exist_in_array(rowkey_name_columns, alter_part_column_array.at(i).trim())) { + ret = OB_EER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF; + LOG_WARN("unique local index rowkey key not include all table partition key.", + K(ret), K(alter_table_part_func_expr), K(rowkey_name_columns)); + LOG_USER_ERROR(OB_EER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF, "UNIQUE INDEX"); + } + } + } + } + } + } + return ret; +} diff --git a/src/storage/ddl/ob_ddl_alter_auto_part_attr.h b/src/storage/ddl/ob_ddl_alter_auto_part_attr.h new file mode 100644 index 000000000..547426ec9 --- /dev/null +++ b/src/storage/ddl/ob_ddl_alter_auto_part_attr.h @@ -0,0 +1,96 @@ +/** + * 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_DDL_ALTER_AUTO_PART_ATTR_H_ +#define OCEANBASE_STORAGE_OB_DDL_ALTER_AUTO_PART_ATTR_H_ + +#include "share/ob_rpc_struct.h" +#include "share/schema/ob_schema_getter_guard.h" +#include "rootserver/ob_ddl_operator.h" + +namespace oceanbase +{ +namespace storage +{ + +class ObAlterAutoPartAttrOp final +{ +public: + ObAlterAutoPartAttrOp(rootserver::ObDDLService &ddl_service); + virtual ~ObAlterAutoPartAttrOp() = default; + + int alter_table_auto_part_attr_if_need( + const obrpc::ObAlterTableArg &alter_table_arg, + const share::ObDDLType ddl_type, + share::schema::ObSchemaGetterGuard &schema_guard, + ObTableSchema &table_schema, + rootserver::ObDDLOperator &ddl_operator, + common::ObMySQLTransaction &trans); + int alter_global_indexes_auto_part_attribute_offline( + obrpc::ObAlterTableArg &alter_table_arg, + ObTableSchema &new_index_schema); + void switch_ddl_type_if_need( + const obrpc::ObAlterTableArg &alter_table_arg, + share::ObDDLType &ddl_type); + int check_alter_table_partition_attr( + const obrpc::ObAlterTableArg &alter_table_arg, + const share::schema::ObTableSchema &orig_table_schema, + const bool is_oracle_mode, + share::ObDDLType &ddl_type); + int alter_table_partition_attr( + obrpc::ObAlterTableArg &alter_table_arg, + const share::schema::ObTableSchema &orig_table_schema, + share::schema::ObTableSchema &new_table_schema); +private: + int get_part_key_column_ids( + const ObTableSchema &table_schema, + ObIArray &part_key_ids); + int check_part_key_column_type( + const ObTableSchema &table_schema, + const ObPartitionOption &alter_part_option, + bool &is_valid_part_column); + int check_and_set_table_auto_part_func( + const ObPartitionOption &alter_part_option, + ObTableSchema &table_schema); + int alter_global_indexes_auto_part_attribute_online( + const ObPartitionOption &part_option, + const ObTableSchema &table_schema, + ObSchemaGetterGuard &schema_guard, + rootserver::ObDDLOperator &ddl_operator, + ObMySQLTransaction &trans); + int check_auto_part_table_unique_index( + const ObTableSchema &table_schema, + ObString &alter_table_part_func_expr, + ObSchemaGetterGuard &schema_guard); + int update_global_auto_split_attr( + const ObPartitionOption &alter_part_option, + ObTableSchema &new_index_schema); + int extract_potential_partition_func_type( + const ObTableSchema &table_schema, + const ObString &part_func_expr, + ObPartitionFuncType &part_func_type); + int switch_global_local_index_type( + const ObTableSchema &index_schema, + ObIndexType& index_type); + int lock_for_modify_auto_part_size( + const ObTableSchema &table_schema, + ObSchemaGetterGuard &schema_guard, + ObMySQLTransaction &trans); +private: + rootserver::ObDDLService *ddl_service_; +}; + + +} // end namespace storage +} // end namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_DDL_ALTER_AUTO_PART_ATTR_H_ diff --git a/src/storage/ddl/ob_ddl_clog.cpp b/src/storage/ddl/ob_ddl_clog.cpp index eb046911d..defba90fa 100644 --- a/src/storage/ddl/ob_ddl_clog.cpp +++ b/src/storage/ddl/ob_ddl_clog.cpp @@ -590,5 +590,133 @@ int ObDDLFinishClogCb::on_failure() } #endif +ObTabletSplitInfo::ObTabletSplitInfo() + : rowkey_allocator_("SplitRangeClog"), + table_id_(OB_INVALID_ID), lob_table_id_(OB_INVALID_ID), + schema_version_(0), task_id_(0), + source_tablet_id_(), dest_tablets_id_(), + compaction_scn_(0), data_format_version_(0), consumer_group_id_(0), + can_reuse_macro_block_(false), + lob_col_idxs_(), parallel_datum_rowkey_list_() +{ } + +int ObTabletSplitInfo::assign(const ObTabletSplitInfo &info) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(info)); + } else if (OB_FAIL(dest_tablets_id_.assign(info.dest_tablets_id_))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(parallel_datum_rowkey_list_.assign(info.parallel_datum_rowkey_list_))) { + // shallow copy enough. + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(lob_col_idxs_.assign(info.lob_col_idxs_))) { + LOG_WARN("assign failed", K(ret)); + } else { + table_id_ = info.table_id_; + lob_table_id_ = info.lob_table_id_; + schema_version_ = info.schema_version_; + task_id_ = info.task_id_; + source_tablet_id_ = info.source_tablet_id_; + compaction_scn_ = info.compaction_scn_; + data_format_version_ = info.data_format_version_; + consumer_group_id_ = info.consumer_group_id_; + can_reuse_macro_block_ = info.can_reuse_macro_block_; + } + return ret; } + +bool ObTabletSplitInfo::is_valid() const +{ + bool is_valid = OB_INVALID_ID != table_id_ + && schema_version_ > 0 && task_id_ > 0 + && source_tablet_id_.is_valid() && dest_tablets_id_.count() > 0 + && compaction_scn_ > 0 + && data_format_version_ > 0 && consumer_group_id_ >= 0 + && parallel_datum_rowkey_list_.count() > 0; + if (!lob_col_idxs_.empty()) { + is_valid = is_valid && (OB_INVALID_ID != lob_table_id_); + } + return is_valid; +} + +int ObTabletSplitStartLog::assign(const ObTabletSplitStartLog &log) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!log.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(log)); + } else if (OB_FAIL(basic_info_.assign(log.basic_info_))) { + LOG_WARN("assign failed", K(ret), K(log)); + } + return ret; +} + +int ObTabletSplitFinishLog::assign(const ObTabletSplitFinishLog &log) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!log.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(log)); + } else if (OB_FAIL(basic_info_.assign(log.basic_info_))) { + LOG_WARN("assign failed", K(ret), K(log)); + } + return ret; +} + +int ObTabletFreezeLog::assign(const ObTabletFreezeLog &log) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!log.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(log)); + } else { + tablet_id_ = log.tablet_id_; + } + return ret; +} + +OB_DEF_SERIALIZE(ObTabletSplitInfo) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_ENCODE, table_id_, lob_table_id_, schema_version_, + task_id_, source_tablet_id_, dest_tablets_id_, + compaction_scn_, data_format_version_, consumer_group_id_, + can_reuse_macro_block_, split_sstable_type_, lob_col_idxs_, + parallel_datum_rowkey_list_); + return ret; +} + +OB_DEF_DESERIALIZE(ObTabletSplitInfo) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, table_id_, lob_table_id_, schema_version_, + task_id_, source_tablet_id_, dest_tablets_id_, + compaction_scn_, data_format_version_, consumer_group_id_, + can_reuse_macro_block_, split_sstable_type_, lob_col_idxs_); + if (FAILEDx(ObSplitUtil::deserializ_parallel_datum_rowkey( + rowkey_allocator_, buf, data_len, pos, parallel_datum_rowkey_list_))) { + LOG_WARN("deserialzie parallel info failed", K(ret)); + } + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObTabletSplitInfo) +{ + int64_t len = 0; + LST_DO_CODE(OB_UNIS_ADD_LEN, table_id_, lob_table_id_, schema_version_, + task_id_, source_tablet_id_, dest_tablets_id_, + compaction_scn_, data_format_version_, consumer_group_id_, + can_reuse_macro_block_, split_sstable_type_, lob_col_idxs_, + parallel_datum_rowkey_list_); + return len; +} + +OB_SERIALIZE_MEMBER(ObTabletSplitStartLog, basic_info_); +OB_SERIALIZE_MEMBER(ObTabletSplitFinishLog, basic_info_); +OB_SERIALIZE_MEMBER(ObTabletFreezeLog, tablet_id_); + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/ddl/ob_ddl_clog.h b/src/storage/ddl/ob_ddl_clog.h index a5a115dc1..a2e33a41b 100644 --- a/src/storage/ddl/ob_ddl_clog.h +++ b/src/storage/ddl/ob_ddl_clog.h @@ -14,6 +14,7 @@ #define OCEANBASE_STORAGE_OB_DDL_CLOG_H_ #include "storage/ob_i_table.h" +#include "share/ob_rpc_struct.h" #include "storage/blocksstable/ob_block_sstable_struct.h" #include "storage/blocksstable/index_block/ob_index_block_builder.h" #include "storage/ddl/ob_ddl_struct.h" @@ -330,6 +331,86 @@ public: common::ObSArray hidden_tablet_ids_; }; +// === Log for tablet split start === +class ObTabletSplitInfo final +{ + OB_UNIS_VERSION_V(1); +public: + ObTabletSplitInfo(); + ~ObTabletSplitInfo() = default; + int assign(const ObTabletSplitInfo &info); + bool is_valid() const; + TO_STRING_KV(K_(table_id), K_(lob_table_id), K_(schema_version), + K_(task_id), K_(source_tablet_id), K_(dest_tablets_id), + K_(compaction_scn), K_(data_format_version), K_(consumer_group_id), + K_(can_reuse_macro_block), K_(split_sstable_type), K_(lob_col_idxs), + K_(parallel_datum_rowkey_list)); +public: + common::ObArenaAllocator rowkey_allocator_; // alloc buf for datum rowkey. + uint64_t table_id_; // scan rows needed, index table id or main table id. + uint64_t lob_table_id_; // scan rows needed, valid when split lob tablet. + int64_t schema_version_; // report replica build status needed. + int64_t task_id_; // report replica build status needed. + common::ObTabletID source_tablet_id_; + common::ObSArray dest_tablets_id_; + int64_t compaction_scn_; + int64_t data_format_version_; + uint64_t consumer_group_id_; + bool can_reuse_macro_block_; + share::ObSplitSSTableType split_sstable_type_; + common::ObSEArray lob_col_idxs_; + common::ObSArray parallel_datum_rowkey_list_; +}; + +struct ObTabletSplitStartLog final +{ + OB_UNIS_VERSION_V(1); +public: + ObTabletSplitStartLog() + : basic_info_() + { } + ~ObTabletSplitStartLog() = default; + int assign(const ObTabletSplitStartLog &log); + bool is_valid() const { return basic_info_.is_valid(); } + const common::ObTabletID &get_source_tablet_id() const { return basic_info_.source_tablet_id_; } + TO_STRING_KV(K_(basic_info)); +public: + ObTabletSplitInfo basic_info_; +}; + +struct ObTabletSplitFinishLog final +{ + OB_UNIS_VERSION(1); +public: + ObTabletSplitFinishLog() + : basic_info_() + { } + ~ObTabletSplitFinishLog() = default; + int assign(const ObTabletSplitFinishLog &log); + bool is_valid() const { return basic_info_.is_valid(); } + const common::ObTabletID &get_source_tablet_id() const { return basic_info_.source_tablet_id_; } + TO_STRING_KV(K_(basic_info)); +public: + ObTabletSplitInfo basic_info_; +}; +// === Log for tablet split end === + +struct ObTabletFreezeLog final +{ + OB_UNIS_VERSION(1); +public: + ObTabletFreezeLog() + : tablet_id_(common::ObTabletID::INVALID_TABLET_ID) + { } + ~ObTabletFreezeLog() = default; + int assign(const ObTabletFreezeLog &log); + bool is_valid() const { return tablet_id_.is_valid(); } + const common::ObTabletID &get_source_tablet_id() const { return tablet_id_; } + TO_STRING_KV(K(tablet_id_)); +public: + common::ObTabletID tablet_id_; +}; + } // namespace storage } // namespace oceanbase #endif diff --git a/src/storage/ddl/ob_ddl_lock.cpp b/src/storage/ddl/ob_ddl_lock.cpp index e672feb5c..d46609f30 100644 --- a/src/storage/ddl/ob_ddl_lock.cpp +++ b/src/storage/ddl/ob_ddl_lock.cpp @@ -236,6 +236,180 @@ int ObDDLLock::unlock_for_rebuild_index( return ret; } +int ObDDLLock::lock_for_split_partition( + const ObTableSchema &table_schema, + const ObLSID *ls_id, + const ObIArray *src_tablet_ids, + const ObIArray &dst_tablet_ids, + const ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + const bool lock_src_and_dst_od = nullptr == ls_id && nullptr != src_tablet_ids; + const bool lock_dst_table_lock = nullptr != ls_id && nullptr == src_tablet_ids && ls_id->is_valid(); + if (OB_UNLIKELY(!(lock_src_and_dst_od ^ lock_dst_table_lock))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KPC(ls_id), KPC(src_tablet_ids), K(dst_tablet_ids)); + } else if (table_schema.is_global_index_table()) { + if (lock_src_and_dst_od) { + if (OB_FAIL(ObOnlineDDLLock::lock_table(tenant_id, table_id, ROW_SHARE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets(tenant_id, *src_tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock tablets", K(ret)); + } else if (OB_FAIL(do_table_lock(tenant_id, table_schema.get_data_table_id(), ROW_SHARE, lock_owner, timeout_us, true/*is_lock*/, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets(tenant_id, dst_tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock tablets", K(ret)); + } + } + } else if (need_lock(table_schema)) { + if (lock_src_and_dst_od) { + if (OB_FAIL(ObOnlineDDLLock::lock_table(tenant_id, table_id, ROW_SHARE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets(tenant_id, *src_tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock tablets", K(ret)); + } else if (OB_FAIL(do_table_lock(tenant_id, table_id, *src_tablet_ids, ROW_EXCLUSIVE, lock_owner, timeout_us, true/*is_lock*/, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::lock_tablets(tenant_id, dst_tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans))) { + LOG_WARN("failed to lock tablets", K(ret)); + } + } else { + // performance crucial + ObLockAloneTabletRequest arg; + arg.lock_mode_ = ROW_EXCLUSIVE; + arg.op_type_ = ObTableLockOpType::OUT_TRANS_LOCK; + arg.owner_id_ = lock_owner; + arg.timeout_us_ = timeout_us; + arg.ls_id_ = *ls_id; + ObInnerSQLConnection *iconn = nullptr; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else if (OB_FAIL(append(arg.tablet_ids_, dst_tablet_ids))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(ObInnerConnectionLockUtil::lock_tablet(tenant_id, arg, iconn))) { + LOG_WARN("failed to lock tablet", K(ret), K(arg)); + } + } + } else { + LOG_INFO("skip ddl lock", K(ret), K(table_id)); + } + return ret; +} + +int ObDDLLock::unlock_for_split_partition( + const ObTableSchema &table_schema, + const ObIArray &src_tablet_ids, + const ObIArray &dst_tablet_ids, + const ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + bool some_lock_not_exist = false; + ObArray tablet_ids; + if (OB_FAIL(append(tablet_ids, src_tablet_ids))) { + LOG_WARN("failed to append", K(ret)); + } else if (OB_FAIL(append(tablet_ids, dst_tablet_ids))) { + LOG_WARN("failed to append", K(ret)); + } + + if (OB_FAIL(ret)) { + } else if (table_schema.is_global_index_table()) { + if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, table_id, ROW_SHARE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_tablets(tenant_id, tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock tablets", K(ret)); + } else if (OB_FAIL(do_table_lock(tenant_id, table_schema.get_data_table_id(), ROW_SHARE, lock_owner, timeout_us, false/*is_lock*/, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } + } else if (need_lock(table_schema)) { + if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, table_id, ROW_SHARE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_tablets(tenant_id, tablet_ids, EXCLUSIVE, lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock tablets", K(ret)); + } else if (OB_FAIL(do_table_lock(tenant_id, table_id, tablet_ids, ROW_EXCLUSIVE, lock_owner, timeout_us, false/*is_lock*/, trans))) { + LOG_WARN("failed to lock data tablets", K(ret)); + } + } else { + LOG_INFO("skip ddl lock", K(ret), K(table_id)); + } + return ret; +} + +int ObDDLLock::replace_lock_for_split_partition( + const share::schema::ObTableSchema &table_schema, + const ObIArray &src_tablet_ids, + const ObIArray &dst_tablet_ids, + const transaction::tablelock::ObTableLockOwnerID old_lock_owner, + const transaction::tablelock::ObTableLockOwnerID new_lock_owner, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = table_schema.get_tenant_id(); + const uint64_t table_id = table_schema.get_table_id(); + const int64_t timeout_us = DEFAULT_TIMEOUT; + bool some_lock_not_exist = false; + ObArray tablet_ids; + if (OB_FAIL(append(tablet_ids, src_tablet_ids))) { + LOG_WARN("failed to append", K(ret)); + } else if (OB_FAIL(append(tablet_ids, dst_tablet_ids))) { + LOG_WARN("failed to append", K(ret)); + } + + if (OB_FAIL(ret)) { + } else if (table_schema.is_global_index_table()) { + if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, table_id, ROW_SHARE, old_lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock data table", K(ret), K(tenant_id), K(table_id), K(old_lock_owner), K(timeout_us)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_tablets(tenant_id, tablet_ids, EXCLUSIVE, old_lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock tablets", K(ret), K(tenant_id), K(tablet_ids), K(old_lock_owner), K(timeout_us)); + } else if (OB_FAIL(replace_table_lock(tenant_id, table_schema.get_data_table_id(), ROW_SHARE, old_lock_owner, EXCLUSIVE, new_lock_owner, timeout_us, trans))) { + LOG_WARN("failed to replace table lock", K(ret), K(tenant_id), K(table_schema.get_data_table_id()), K(old_lock_owner), K(new_lock_owner), K(timeout_us)); + } + } else if (need_lock(table_schema)) { + if (OB_FAIL(ObOnlineDDLLock::unlock_table(tenant_id, table_id, ROW_SHARE, old_lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(ObOnlineDDLLock::unlock_tablets(tenant_id, tablet_ids, EXCLUSIVE, old_lock_owner, timeout_us, trans, some_lock_not_exist))) { + LOG_WARN("failed to lock tablets", K(ret)); + /*wait split source tablets trans end, split source tablets table lock will be unlocked in unlock_for_offline_ddl function*/ + } else if (OB_FAIL(replace_table_lock(tenant_id, table_id, tablet_ids, ROW_EXCLUSIVE, old_lock_owner, EXCLUSIVE, new_lock_owner, timeout_us, trans))) { + LOG_WARN("failed to replace table lock", K(ret), K(tenant_id), K(table_id), K(tablet_ids), K(old_lock_owner), K(new_lock_owner), K(timeout_us)); + } + } else { + LOG_INFO("skip ddl lock", K(ret), K(table_id)); + } + return ret; +} + +int ObDDLLock::lock_for_modify_auto_part_size_in_trans( + const uint64_t tenant_id, + const uint64_t data_table_id, + const ObIArray &global_index_table_ids, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const ObArray no_tablet_ids; + const int64_t timeout_us = DEFAULT_TIMEOUT; + if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, data_table_id, EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock data table", K(ret)); + } else if (OB_FAIL(lock_table_lock_in_trans(tenant_id, data_table_id, no_tablet_ids, ROW_SHARE, timeout_us, trans))) { + LOG_WARN("failed to lock tablet", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < global_index_table_ids.count(); i++) { + const uint64_t table_id = global_index_table_ids.at(i); + if (OB_FAIL(ObOnlineDDLLock::lock_table_in_trans(tenant_id, table_id, EXCLUSIVE, timeout_us, trans))) { + LOG_WARN("failed to lock data table tablets", K(ret)); + } + } + } + return ret; +} + int ObDDLLock::lock_for_add_lob_in_trans( const ObTableSchema &data_table_schema, ObMySQLTransaction &trans) @@ -398,6 +572,7 @@ int ObDDLLock::lock_for_offline_ddl( int ObDDLLock::unlock_for_offline_ddl( const uint64_t tenant_id, const uint64_t table_id, + const ObIArray *hidden_tablet_ids_alone, const ObTableLockOwnerID lock_owner, ObMySQLTransaction &trans) { @@ -405,6 +580,10 @@ int ObDDLLock::unlock_for_offline_ddl( const int64_t timeout_us = DEFAULT_TIMEOUT; if (OB_FAIL(do_table_lock(tenant_id, table_id, EXCLUSIVE, lock_owner, timeout_us, false/*is_lock*/, trans))) { LOG_WARN("failed to lock table lock", K(ret)); + } else if (nullptr != hidden_tablet_ids_alone) { + if (OB_FAIL(do_table_lock(tenant_id, OB_INVALID_ID/*table_id*/, *hidden_tablet_ids_alone, EXCLUSIVE, lock_owner, timeout_us, false/*is_lock*/, trans))) { + LOG_WARN("failed to unlock tablets", K(ret), K(tenant_id), KPC(hidden_tablet_ids_alone), K(lock_owner)); + } } return ret; } @@ -611,6 +790,139 @@ int ObDDLLock::check_tablet_in_same_ls( return ret; } +int ObDDLLock::replace_table_lock( + const uint64_t tenant_id, + const uint64_t table_id, + const transaction::tablelock::ObTableLockMode old_lock_mode, + const transaction::tablelock::ObTableLockOwnerID old_lock_owner, + const transaction::tablelock::ObTableLockMode new_lock_mode, + const transaction::tablelock::ObTableLockOwnerID new_lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const ObTableLockOpType op_type = ObTableLockOpType::OUT_TRANS_UNLOCK; + ObInnerSQLConnection *iconn = nullptr; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else { + ObUnLockTableRequest unlock_arg; + unlock_arg.table_id_ = table_id; + unlock_arg.owner_id_ = old_lock_owner; + unlock_arg.lock_mode_ = old_lock_mode; + unlock_arg.op_type_ = OUT_TRANS_UNLOCK; + unlock_arg.timeout_us_ = timeout_us; + ObReplaceLockRequest replace_lock_arg; + replace_lock_arg.unlock_req_ = &unlock_arg; + replace_lock_arg.new_lock_mode_ = new_lock_mode; + replace_lock_arg.new_lock_owner_ = new_lock_owner; + if (OB_FAIL(ObInnerConnectionLockUtil::replace_lock(tenant_id, replace_lock_arg, iconn))) { + LOG_WARN("failed to replace lock", K(ret), K(tenant_id), K(replace_lock_arg)); + } + } + return ret; +} + +int ObDDLLock::replace_table_lock( + const uint64_t tenant_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const transaction::tablelock::ObTableLockMode old_lock_mode, + const transaction::tablelock::ObTableLockOwnerID old_lock_owner, + const transaction::tablelock::ObTableLockMode new_lock_mode, + const transaction::tablelock::ObTableLockOwnerID new_lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + const ObTableLockOpType op_type = ObTableLockOpType::OUT_TRANS_UNLOCK; + ObInnerSQLConnection *iconn = nullptr; + ObArray unlock_args; + if (OB_ISNULL(iconn = static_cast(trans.get_connection()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid conn", K(ret)); + } else if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || OB_INVALID_ID == table_id || tablet_ids.count() < 1)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(table_id), K(tablet_ids.count())); + } else if (OB_FAIL(get_unlock_alone_tablet_request_args(tenant_id, old_lock_mode, old_lock_owner, timeout_us, tablet_ids, unlock_args, trans))) { + LOG_WARN("fail to get unlock alone tablet request args", K(ret), K(tenant_id), K(old_lock_mode), K(old_lock_owner), K(timeout_us), K(tablet_ids)); + } else { + int64_t arg_count = unlock_args.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < arg_count; i++) { + ObReplaceLockRequest replace_req; + replace_req.new_lock_mode_ = new_lock_mode; + replace_req.new_lock_owner_ = new_lock_owner; + replace_req.unlock_req_ = &unlock_args[i]; + if (OB_FAIL(ObInnerConnectionLockUtil::replace_lock(tenant_id, replace_req, iconn))) { + LOG_WARN("failed to replace lock", K(ret), K(tenant_id), K(replace_req)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(replace_table_lock(tenant_id, table_id, old_lock_mode, old_lock_owner, new_lock_mode, new_lock_owner, timeout_us, trans))) { + LOG_WARN("failed to replace table lock", K(ret), K(tenant_id), K(table_id), K(old_lock_mode), K(old_lock_owner), K(new_lock_owner), K(timeout_us)); + } + } + } + return ret; +} + +int ObDDLLock::get_unlock_alone_tablet_request_args( + const uint64_t tenant_id, + const transaction::tablelock::ObTableLockMode lock_mode, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + const ObIArray &tablet_ids, + ObArray &unlock_args, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + unlock_args.reset(); + const ObTableLockOpType op_type = ObTableLockOpType::OUT_TRANS_UNLOCK; + if (OB_UNLIKELY(OB_INVALID_TENANT_ID == tenant_id || tablet_ids.count() < 1)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tenant_id), K(tablet_ids.count())); + } else { + ObArray ls_ids; + int64_t arg_count = 0; + if (OB_FAIL(share::ObTabletToLSTableOperator::batch_get_ls(trans, tenant_id, tablet_ids, ls_ids))) { + LOG_WARN("failed to get tablet ls", K(ret)); + } else if (OB_UNLIKELY(ls_ids.count() != tablet_ids.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls ids count", K(ret), K(ls_ids.count()), K(tablet_ids.count())); + } + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_ids.count(); i++) { + const ObLSID &ls_id = ls_ids[i]; + int64_t j = 0; + for (; j < unlock_args.count(); j++) { + const ObLSID &tmp_ls_id = unlock_args[j].ls_id_; + if (tmp_ls_id == ls_id) { + break; + } + } + arg_count = unlock_args.count(); + if (j == arg_count) { + ObUnLockAloneTabletRequest unlock_arg; + unlock_arg.owner_id_ = lock_owner; + unlock_arg.lock_mode_ = lock_mode; + unlock_arg.op_type_ = op_type; + unlock_arg.timeout_us_ = timeout_us; + unlock_arg.ls_id_ = ls_id; + if (OB_FAIL(unlock_args.push_back(unlock_arg))) { + LOG_WARN("failed to push back modify arg", K(ret)); + } + } + if (OB_SUCC(ret)) { + ObLockAloneTabletRequest &arg = unlock_args.at(j); + if (OB_FAIL(arg.tablet_ids_.push_back(tablet_ids.at(i)))) { + LOG_WARN("failed to push back", K(ret)); + } + } + } + } + return ret; +} + int ObOnlineDDLLock::lock_for_transfer_in_trans( const uint64_t tenant_id, const uint64_t table_id, diff --git a/src/storage/ddl/ob_ddl_lock.h b/src/storage/ddl/ob_ddl_lock.h index 6cecfca4a..a0e7227b4 100644 --- a/src/storage/ddl/ob_ddl_lock.h +++ b/src/storage/ddl/ob_ddl_lock.h @@ -59,6 +59,33 @@ public: const transaction::tablelock::ObTableLockOwnerID lock_owner, ObMySQLTransaction &trans); + static int lock_for_split_partition( + const share::schema::ObTableSchema &table_schema, + const share::ObLSID *ls_id, + const ObIArray *src_tablet_ids, + const ObIArray &dst_tablet_ids, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans); + static int unlock_for_split_partition( + const share::schema::ObTableSchema &table_schema, + const ObIArray &src_tablet_ids, + const ObIArray &dst_tablet_ids, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + ObMySQLTransaction &trans); + static int replace_lock_for_split_partition( + const share::schema::ObTableSchema &table_schema, + const ObIArray &src_tablet_ids, + const ObIArray &dst_tablet_ids, + const transaction::tablelock::ObTableLockOwnerID old_lock_owner, + const transaction::tablelock::ObTableLockOwnerID new_lock_owner, + ObMySQLTransaction &trans); + + static int lock_for_modify_auto_part_size_in_trans( + const uint64_t tenant_id, + const uint64_t data_table_id, + const ObIArray &global_index_table_ids, + ObMySQLTransaction &trans); + static int lock_for_add_lob_in_trans( const share::schema::ObTableSchema &data_table_schema, ObMySQLTransaction &trans); @@ -93,6 +120,7 @@ public: static int unlock_for_offline_ddl( const uint64_t tenant_id, const uint64_t table_id, + const ObIArray *hidden_tablet_ids_alone, const transaction::tablelock::ObTableLockOwnerID lock_owner, ObMySQLTransaction &trans); @@ -125,6 +153,33 @@ private: const share::schema::ObTableSchema &lhs_schema, const share::schema::ObTableSchema &rhs_schema, ObMySQLTransaction &trans); + static int replace_table_lock( + const uint64_t tenant_id, + const uint64_t table_id, + const transaction::tablelock::ObTableLockMode old_lock_mode, + const transaction::tablelock::ObTableLockOwnerID old_lock_owner, + const transaction::tablelock::ObTableLockMode new_lock_mode, + const transaction::tablelock::ObTableLockOwnerID new_lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans); + static int replace_table_lock( + const uint64_t tenant_id, + const uint64_t table_id, + const ObIArray &tablet_ids, + const transaction::tablelock::ObTableLockMode old_lock_mode, + const transaction::tablelock::ObTableLockOwnerID old_lock_owner, + const transaction::tablelock::ObTableLockMode new_lock_mode, + const transaction::tablelock::ObTableLockOwnerID new_lock_owner, + const int64_t timeout_us, + ObMySQLTransaction &trans); + static int get_unlock_alone_tablet_request_args( + const uint64_t tenant_id, + const transaction::tablelock::ObTableLockMode lock_mode, + const transaction::tablelock::ObTableLockOwnerID lock_owner, + const int64_t timeout_us, + const ObIArray &tablet_ids, + ObArray &unlock_args, + ObMySQLTransaction &trans); static constexpr int64_t DEFAULT_TIMEOUT = 0; }; diff --git a/src/storage/ddl/ob_ddl_redo_log_replayer.cpp b/src/storage/ddl/ob_ddl_redo_log_replayer.cpp index cbfbc10bc..79b4bd9e8 100644 --- a/src/storage/ddl/ob_ddl_redo_log_replayer.cpp +++ b/src/storage/ddl/ob_ddl_redo_log_replayer.cpp @@ -133,6 +133,25 @@ int ObDDLRedoLogReplayer::replay_finish(const ObDDLFinishLog &log, const SCN &sc } #endif +int ObDDLRedoLogReplayer::replay_split_start(const ObTabletSplitStartLog &log, const share::SCN &scn) +{ + int ret = OB_SUCCESS; + ObSplitStartReplayExecutor replay_executor; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); + } else if (OB_FAIL(replay_executor.init(ls_, log, scn))) { + LOG_WARN("failed to init ddl commit log replay executor", K(ret)); + } else if (OB_FAIL(replay_executor.execute(scn, ls_->get_ls_id(), log.basic_info_.source_tablet_id_))) { + if (OB_NO_NEED_UPDATE == ret || OB_TASK_EXPIRED == ret) { + ret = OB_SUCCESS; + } else if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay split start log", K(ret), K(scn), K(log), K(ls_->get_ls_id())); + } + } + return ret; +} + int ObDDLRedoLogReplayer::replay_inc_start(const ObDDLIncStartLog &log, const share::SCN &scn) { int ret = OB_SUCCESS; @@ -155,6 +174,46 @@ int ObDDLRedoLogReplayer::replay_inc_start(const ObDDLIncStartLog &log, const sh return ret; } +int ObDDLRedoLogReplayer::replay_split_finish(const ObTabletSplitFinishLog &log, const share::SCN &scn) +{ + int ret = OB_SUCCESS; + ObSplitFinishReplayExecutor replay_executor; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); + } else if (OB_FAIL(replay_executor.init(ls_, log, scn))) { + LOG_WARN("failed to init ddl commit log replay executor", K(ret)); + } else if (OB_FAIL(replay_executor.execute(scn, ls_->get_ls_id(), log.basic_info_.source_tablet_id_))) { + if (OB_NO_NEED_UPDATE == ret || OB_TASK_EXPIRED == ret) { + ret = OB_SUCCESS; + } else if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay split finish log", K(ret), K(scn), K(log), K(ls_->get_ls_id())); + } + } + return ret; +} + +int ObDDLRedoLogReplayer::replay_tablet_freeze(const ObTabletFreezeLog &log, const share::SCN &scn) +{ + int ret = OB_SUCCESS; + ObTabletFreezeReplayExecutor replay_executor; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); + } else if (OB_FAIL(replay_executor.init(ls_, log, scn))) { + LOG_WARN("failed to init tablet freeze log replay executor", K(ret)); + } else if (OB_FAIL(replay_executor.execute(scn, ls_->get_ls_id(), log.tablet_id_))) { + if (OB_NO_NEED_UPDATE == ret || OB_TASK_EXPIRED == ret) { + ret = OB_SUCCESS; + } else if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay tablet freeze log", K(ret), K(scn), K(log), K(ls_->get_ls_id())); + } + } + return ret; +} + int ObDDLRedoLogReplayer::replay_inc_commit(const ObDDLIncCommitLog &log, const SCN &scn) { int ret = OB_SUCCESS; diff --git a/src/storage/ddl/ob_ddl_redo_log_replayer.h b/src/storage/ddl/ob_ddl_redo_log_replayer.h index d429680a1..c7bd6ea43 100644 --- a/src/storage/ddl/ob_ddl_redo_log_replayer.h +++ b/src/storage/ddl/ob_ddl_redo_log_replayer.h @@ -35,6 +35,9 @@ public: int replay_start(const ObDDLStartLog &log, const share::SCN &scn); int replay_redo(const ObDDLRedoLog &log, const share::SCN &scn); int replay_commit(const ObDDLCommitLog &log, const share::SCN &scn); + int replay_split_start(const ObTabletSplitStartLog &log, const share::SCN &scn); + int replay_split_finish(const ObTabletSplitFinishLog &log, const share::SCN &scn); + int replay_tablet_freeze(const ObTabletFreezeLog &log, const share::SCN &scn); #ifdef OB_BUILD_SHARED_STORAGE int replay_finish(const ObDDLFinishLog &log, const share::SCN &scn); #endif diff --git a/src/storage/ddl/ob_ddl_redo_log_writer.cpp b/src/storage/ddl/ob_ddl_redo_log_writer.cpp index 453d4c879..a5492a912 100644 --- a/src/storage/ddl/ob_ddl_redo_log_writer.cpp +++ b/src/storage/ddl/ob_ddl_redo_log_writer.cpp @@ -995,6 +995,126 @@ if (OB_ISNULL(buffer = static_cast(ob_malloc(buffer_size, ObMemAttr(MTL_ return ret; } +template +int ObDDLRedoLogWriter::write_auto_split_log( + const share::ObLSID &ls_id, + const ObDDLClogType &clog_type, + const ObReplayBarrierType &replay_barrier_type, + const T &log) +{ + int ret = OB_SUCCESS; + ObArenaAllocator tmp_arena("SplitLogBuf", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + logservice::ObLogBaseHeader base_header(logservice::ObLogBaseType::DDL_LOG_BASE_TYPE, + replay_barrier_type); + ObDDLClogHeader ddl_header(clog_type); + const int64_t buffer_size = base_header.get_serialize_size() + + ddl_header.get_serialize_size() + + log.get_serialize_size(); + char *buffer = nullptr; // stack space avoided, to avoid too muck stack size. + int64_t pos = 0; + ObDDLClogCb *cb = nullptr; + + palf::LSN lsn; + const bool need_nonblock= false; + SCN scn = SCN::min_scn(); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + logservice::ObLogHandler *log_handler = nullptr; + if (OB_UNLIKELY(!ls_id.is_valid()) || + OB_UNLIKELY(ObDDLClogType::DDL_TABLET_SPLIT_START_LOG != clog_type && + ObDDLClogType::DDL_TABLET_SPLIT_FINISH_LOG != clog_type && + ObDDLClogType::DDL_TABLET_FREEZE_LOG != clog_type) || + OB_UNLIKELY(!log.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_id), K(clog_type), K(log)); + } else if (OB_ISNULL(buffer = static_cast(tmp_arena.alloc(buffer_size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc failed", K(ret), K(buffer_size)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("get ls failed", K(ret), K(log)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls should not be null", K(ret)); + } else if (OB_ISNULL(log_handler = ls->get_log_handler())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get log handler failed", K(ret), K(log)); + } else if (OB_ISNULL(cb = op_alloc(ObDDLClogCb))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc memory", K(ret)); + } else if (OB_FAIL(base_header.serialize(buffer, buffer_size, pos))) { + LOG_WARN("failed to serialize log base header", K(ret)); + } else if (OB_FAIL(ddl_header.serialize(buffer, buffer_size, pos))) { + LOG_WARN("fail to seriaize ddl start log", K(ret)); + } else if (OB_FAIL(log.serialize(buffer, buffer_size, pos))) { + LOG_WARN("fail to seriaize ddl start log", K(ret)); + } else if (OB_FAIL(log_handler->append(buffer, + buffer_size, + SCN::min_scn(), + need_nonblock, + false/*allow_compression*/, + cb, + lsn, + scn))) { + LOG_WARN("fail to submit ddl start log", K(ret), K(buffer_size)); + if (ObDDLUtil::need_remote_write(ret)) { + ret = OB_NOT_MASTER; + LOG_INFO("overwrite return to OB_NOT_MASTER"); + } + } else { + ObDDLClogCb *tmp_cb = cb; + cb = nullptr; + bool finish = false; + const int64_t start_time = ObTimeUtility::current_time(); + while (OB_SUCC(ret) && !finish) { + if (tmp_cb->is_success()) { + finish = true; + } else if (tmp_cb->is_failed()) { + ret = OB_NOT_MASTER; + } + if (OB_SUCC(ret) && !finish) { + const int64_t current_time = ObTimeUtility::current_time(); + if (current_time - start_time > ObDDLRedoLogHandle::DDL_REDO_LOG_TIMEOUT) { + ret = OB_TIMEOUT; + LOG_WARN("write auto split log timeout", K(ret), K(log)); + } else { + ob_usleep(ObDDLRedoLogHandle::CHECK_DDL_REDO_LOG_FINISH_INTERVAL); + } + } + } + tmp_cb->try_release(); // release the memory no matter succ or not + } + if (OB_FAIL(ret)) { + if (nullptr != cb) { + op_free(cb); + cb = nullptr; + } + } + tmp_arena.reset(); + buffer = nullptr; + SERVER_EVENT_ADD("ddl", "write_split_log", + "ret", ret, + "tenant_id", MTL_ID(), + "src_tablet_id", log.get_source_tablet_id().id(), + "clog_type", clog_type, + "scn", scn, + "trace_id", *ObCurTraceId::get_trace_id()); + LOG_INFO("write split log finished", K(ret), K(ls_id), K(clog_type), K(scn)); + return ret; +} + +template int ObDDLRedoLogWriter::write_auto_split_log(const share::ObLSID &ls_id, + const ObDDLClogType &clog_type, + const ObReplayBarrierType &replay_barrier_type, + const ObTabletSplitStartLog &log); +template int ObDDLRedoLogWriter::write_auto_split_log(const share::ObLSID &ls_id, + const ObDDLClogType &clog_type, + const ObReplayBarrierType &replay_barrier_type, + const ObTabletSplitFinishLog &log); +template int ObDDLRedoLogWriter::write_auto_split_log(const share::ObLSID &ls_id, + const ObDDLClogType &clog_type, + const ObReplayBarrierType &replay_barrier_type, + const ObTabletFreezeLog &log); + bool ObDDLRedoLogWriter::need_retry(int ret_code) { return OB_NOT_MASTER == ret_code; diff --git a/src/storage/ddl/ob_ddl_redo_log_writer.h b/src/storage/ddl/ob_ddl_redo_log_writer.h index 67caa9af9..94642aeed 100644 --- a/src/storage/ddl/ob_ddl_redo_log_writer.h +++ b/src/storage/ddl/ob_ddl_redo_log_writer.h @@ -317,6 +317,11 @@ public: share::SCN &commit_scn, bool &is_remote_write, uint32_t &lock_tid); + template + static int write_auto_split_log(const share::ObLSID &ls_id, + const ObDDLClogType &clog_type, + const logservice::ObReplayBarrierType &replay_barrier_type, + const T &log); int write_commit_log_with_retry( const bool allow_remote_write, const ObITable::TableKey &table_key, diff --git a/src/storage/ddl/ob_ddl_replay_executor.cpp b/src/storage/ddl/ob_ddl_replay_executor.cpp index 6c6c63650..57a3d3bf9 100644 --- a/src/storage/ddl/ob_ddl_replay_executor.cpp +++ b/src/storage/ddl/ob_ddl_replay_executor.cpp @@ -18,6 +18,7 @@ #include "storage/ls/ob_ls.h" #include "storage/compaction/ob_schedule_dag_func.h" #include "storage/ddl/ob_tablet_ddl_kv_mgr.h" +#include "storage/tx_storage/ob_tenant_freezer.h" #include "storage/ddl/ob_direct_insert_sstable_ctx_new.h" #include "storage/tablet/ob_tablet.h" #include "storage/meta_store/ob_tenant_storage_meta_service.h" @@ -178,12 +179,12 @@ int ObDDLStartReplayExecutor::init( int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; - LOG_WARN("init twice", KR(ret), K_(is_inited)); + LOG_WARN("init twice", K(ret), K_(is_inited)); } else if (OB_ISNULL(ls) || OB_UNLIKELY(!log.is_valid()) || OB_UNLIKELY(!scn.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", KP(ls), K(log), K(scn), K(ret)); + LOG_WARN("invalid arguments", K(ret), KPC(ls), K(log), K(scn)); } else { ls_ = ls; log_ = &log; @@ -325,12 +326,12 @@ int ObDDLRedoReplayExecutor::init( int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; - LOG_WARN("init twice", KR(ret), K_(is_inited)); + LOG_WARN("init twice", K(ret), K_(is_inited)); } else if (OB_ISNULL(ls) || OB_UNLIKELY(!log.is_valid()) || OB_UNLIKELY(!scn.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", KP(ls), K(log), K(scn), K(ret)); + LOG_WARN("invalid arguments", K(ret), KPC(ls), K(log), K(scn)); } else { ls_ = ls; log_ = &log; @@ -644,12 +645,12 @@ int ObDDLCommitReplayExecutor::init( int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; - LOG_WARN("init twice", KR(ret), K_(is_inited)); + LOG_WARN("init twice", K(ret), K_(is_inited)); } else if (OB_ISNULL(ls) || OB_UNLIKELY(!log.is_valid()) || OB_UNLIKELY(!scn.is_valid())) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid arguments", KP(ls), K(log), K(scn), K(ret)); + LOG_WARN("invalid arguments", K(ret), KPC(ls), K(log), K(scn)); } else { ls_ = ls; log_ = &log; @@ -747,10 +748,353 @@ int ObDDLCommitReplayExecutor::replay_ddl_commit(ObTabletHandle &tablet_handle) return ret; } +// ObDDLStartReplayExecutor +ObSplitStartReplayExecutor::ObSplitStartReplayExecutor() + : ObDDLReplayExecutor(), log_(nullptr) +{ + +} + +int ObSplitStartReplayExecutor::init( + ObLS *ls, + const ObTabletSplitStartLog &log, + const SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_ISNULL(ls) + || OB_UNLIKELY(!log.is_valid()) + || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KPC(ls), K(log), K(scn)); + } else { + ls_ = ls; + log_ = &log; + scn_ = scn; + is_inited_ = true; + } + return ret; +} + +int ObSplitStartReplayExecutor::prepare_param_from_log( + const share::ObLSID &ls_id, + const ObTabletSplitInfo &info, + ObTabletSplitParam ¶m) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_id.is_valid() || !info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_id), K(info)); + } else { + param.tenant_id_ = MTL_ID(); + param.ls_id_ = ls_id; + param.table_id_ = info.table_id_; + param.schema_version_ = info.schema_version_; + param.task_id_ = info.task_id_; + param.source_tablet_id_ = info.source_tablet_id_; + param.compaction_scn_ = info.compaction_scn_; + param.data_format_version_ = info.data_format_version_; + param.consumer_group_id_ = info.consumer_group_id_; + param.can_reuse_macro_block_ = info.can_reuse_macro_block_; + param.split_sstable_type_ = info.split_sstable_type_; + param.user_parallelism_ = info.parallel_datum_rowkey_list_.count() - 1; + // skip lob_col_idxs. + if (OB_FAIL(ObCompatModeGetter::get_table_compat_mode(param.tenant_id_, param.table_id_, param.compat_mode_))) { + LOG_WARN("failed to get compat mode", K(ret)); + } else if (OB_FAIL(param.parallel_datum_rowkey_list_.assign(info.parallel_datum_rowkey_list_))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(param.dest_tablets_id_.assign(info.dest_tablets_id_))) { + LOG_WARN("assign failed", K(ret), K(info)); + } + } + return ret; +} + +int ObSplitStartReplayExecutor::prepare_param_from_log( + const share::ObLSID &ls_id, + const ObTabletSplitInfo &info, + ObLobSplitParam ¶m) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!ls_id.is_valid() || !info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_id), K(info)); + } else { + param.tenant_id_ = MTL_ID(); + param.ls_id_ = ls_id; + param.source_table_id_ = info.table_id_; + param.dest_schema_id_ = info.lob_table_id_; + param.schema_version_ = info.schema_version_; + param.task_id_ = info.task_id_; + param.ori_lob_meta_tablet_id_ = info.source_tablet_id_; + param.compaction_scn_ = info.compaction_scn_; + param.data_format_version_ = info.data_format_version_; + param.consumer_group_id_ = info.consumer_group_id_; + // skip can_reuse_macro_block + param.split_sstable_type_ = info.split_sstable_type_; + param.parallelism_ = info.parallel_datum_rowkey_list_.count() - 1; + if (OB_FAIL(ObCompatModeGetter::get_table_compat_mode(param.tenant_id_, param.source_table_id_, param.compat_mode_))) { + LOG_WARN("failed to get compat mode", K(ret)); + } else if (OB_FAIL(param.lob_col_idxs_.assign(info.lob_col_idxs_))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(param.parallel_datum_rowkey_list_.assign(info.parallel_datum_rowkey_list_))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(param.new_lob_tablet_ids_.assign(info.dest_tablets_id_))) { + LOG_WARN("assign failed", K(ret), K(info)); + } + } + return ret; +} + + +int ObSplitStartReplayExecutor::do_replay_(ObTabletHandle &handle) +{ + int ret = OB_SUCCESS; + UNUSED(handle); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); + } else if (OB_ISNULL(log_) || OB_UNLIKELY(!log_->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KPC(log_)); + } else if (log_->basic_info_.lob_col_idxs_.count() > 0) { + // lob tablet. + ObLobSplitParam param; + if (OB_FAIL(ObSplitStartReplayExecutor::prepare_param_from_log(ls_->get_ls_id(), log_->basic_info_, param))) { + LOG_WARN("prepare lob split param failed", K(ret), KPC(log_)); + } else if (OB_FAIL(compaction::ObScheduleDagFunc::schedule_lob_tablet_split_dag(param))) { + LOG_WARN("schedule tablet split dag failed, but ignore to wait", K(ret), K(param)); + ret = OB_SUCCESS; + } else { + LOG_INFO("schedule lob tablet split dag successfully", K(ret), K(param)); + } + } else { + ObTabletSplitParam param; + if (OB_FAIL(ObSplitStartReplayExecutor::prepare_param_from_log(ls_->get_ls_id(), log_->basic_info_, param))) { + LOG_WARN("prepare tablet split param failed", K(ret), KPC(log_)); + } else if (OB_FAIL(compaction::ObScheduleDagFunc::schedule_tablet_split_dag(param))) { + LOG_WARN("schedule tablet split dag failed, but ignore to wait", K(ret), K(param)); + ret = OB_SUCCESS; + } else { + LOG_INFO("schedule tablet split dag successfully", K(ret), K(param)); + } + } + LOG_INFO("finish replay tablet split start log", K(ret), K(scn_), KPC(log_)); + return ret; +} + +// ObSplitFinishReplayExecutor +ObSplitFinishReplayExecutor::ObSplitFinishReplayExecutor() + : ObDDLReplayExecutor(), log_(nullptr) +{ + +} + +int ObSplitFinishReplayExecutor::init( + ObLS *ls, + const ObTabletSplitFinishLog &log, + const SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_ISNULL(ls) + || OB_UNLIKELY(!log.is_valid()) + || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KPC(ls), K(log), K(scn)); + } else { + ls_ = ls; + log_ = &log; + scn_ = scn; + is_inited_ = true; + } + + return ret; +} + +int ObSplitFinishReplayExecutor::do_replay_(ObTabletHandle &handle) +{ + UNUSED(handle); + int ret = OB_SUCCESS; + ObLSID ls_id; + ObLobSplitParam lob_split_param; + ObTabletSplitParam data_split_param; + const ObIArray *dest_tablet_ids = nullptr; + const int64_t wait_start_ts = ObTimeUtility::fast_current_time(); + bool is_lob_tablet = false; + bool is_all_majors_existed = false; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); + } else if (OB_ISNULL(log_) || OB_UNLIKELY(!log_->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KPC(log_)); + } else if (OB_ISNULL(dest_tablet_ids = &(log_->basic_info_.dest_tablets_id_))) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("unexpected nullptr of dest_tablet_ids", K(ret), KPC(dest_tablet_ids)); + } else if (OB_FALSE_IT(is_lob_tablet = log_->basic_info_.lob_col_idxs_.count() > 0)) { + } else if (OB_FALSE_IT(ls_id = ls_->get_ls_id())) { + } else if (is_lob_tablet && + OB_FAIL(ObSplitStartReplayExecutor::prepare_param_from_log(ls_id, log_->basic_info_, lob_split_param))) { + LOG_WARN("prepare lob split param failed", K(ret), K(ls_id), KPC(log_)); + } else if (!is_lob_tablet && + OB_FAIL(ObSplitStartReplayExecutor::prepare_param_from_log(ls_id, log_->basic_info_, data_split_param))) { + LOG_WARN("prepare tablet split param failed", K(ret), K(ls_id), KPC(log_)); + } else { + if (is_lob_tablet && OB_FAIL(compaction::ObScheduleDagFunc::schedule_lob_tablet_split_dag(lob_split_param))) { + if (OB_EAGAIN == ret || OB_SIZE_OVERFLOW == ret) { + if (REACH_TIME_INTERVAL(10L * 1000L * 1000L)) { + LOG_INFO("schedule wait lob tablet split end", K(ret), K(lob_split_param)); + } + } else { + LOG_WARN("schedule lob tablet split dag failed", K(ret), K(lob_split_param)); + } + } else if (!is_lob_tablet && OB_FAIL(compaction::ObScheduleDagFunc::schedule_tablet_split_dag(data_split_param))) { + if (OB_EAGAIN == ret || OB_SIZE_OVERFLOW == ret) { + if (REACH_TIME_INTERVAL(10L * 1000L * 1000L)) { + LOG_INFO("schedule wait data tablet split end", K(ret), K(lob_split_param)); + } + } else { + LOG_WARN("schedule data tablet split failed", K(ret), K(data_split_param)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(ls_id, *dest_tablet_ids, is_all_majors_existed))) { + LOG_WARN("check all tablets major exist failed", K(ret), K(ls_id), KPC(dest_tablet_ids)); + } else if (!is_all_majors_existed) { + ret = OB_EAGAIN; + } + } + } + if (OB_TABLET_STATUS_NO_NEED_TO_SPLIT == ret) { + LOG_INFO("skip replaying the tablet split finish log", K(ret), K(is_all_majors_existed), KPC(log_)); + //overwrite ret + ret = OB_SUCCESS; + if (OB_FAIL(modify_tablet_restore_status_if_need(*dest_tablet_ids, handle, ls_))) { + LOG_WARN("failed to modify tablet restore status", K(ret), K(dest_tablet_ids), "src_tablet_handle", handle, KPC(log_)); + } + } else { + LOG_INFO("finish replay tablet split finish log", K(ret), K(is_all_majors_existed), K(scn_), KPC(log_), + "wait_elpased_s", (ObTimeUtility::fast_current_time() - wait_start_ts) / 1000000L); + } + return ret; +} + +// ObTabletFreezeReplayExecutor +ObTabletFreezeReplayExecutor::ObTabletFreezeReplayExecutor() + : ObDDLReplayExecutor(), log_(nullptr) +{ + +} + +int ObSplitFinishReplayExecutor::modify_tablet_restore_status_if_need( + const ObIArray &dest_tablet_ids, + const ObTabletHandle &src_tablet_handle, + ObLS* ls) +{ + int ret = OB_SUCCESS; + ObTablet *src_tablet; + ObTabletRestoreStatus::STATUS src_restore_status = ObTabletRestoreStatus::STATUS::RESTORE_STATUS_MAX; + if (OB_UNLIKELY(dest_tablet_ids.count() <= 0 || !src_tablet_handle.is_valid() || OB_ISNULL(ls))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(dest_tablet_ids), K(src_tablet_handle), KP(ls)); + } else if (OB_ISNULL(src_tablet = src_tablet_handle.get_obj())) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("unexpected nullptr of src_tablet", K(ret), KP(src_tablet)); + } else if (OB_FAIL(src_tablet->get_restore_status(src_restore_status))) { + LOG_WARN("failed to get restore status of tablet", K(ret), K(src_tablet)); + } else if (ObTabletRestoreStatus::STATUS::UNDEFINED == src_restore_status) { + /*skip the split, counting on restoring to fill the destination tablet data*/ + ObTabletHandle des_handle; + ObTablet *tablet; + ObTabletRestoreStatus::STATUS des_restore_status = ObTabletRestoreStatus::STATUS::RESTORE_STATUS_MAX; + for (int64_t i = 0; OB_SUCC(ret) && i < dest_tablet_ids.count(); ++i) { + des_handle.reset(); + const ObTabletID &t_id = dest_tablet_ids.at(i); + if (OB_FAIL(ls->get_tablet(t_id, des_handle))) { + LOG_WARN("failed to get table", K(ret), K(t_id)); + } else if (OB_ISNULL(tablet = des_handle.get_obj())) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("unexpected null ptr of tablet", K(ret), KPC(tablet)); + } else if (OB_FAIL(tablet->get_restore_status(des_restore_status))) { + LOG_WARN("failed to get restore status of tablet", K(ret), K(tablet)); + } else if (ObTabletRestoreStatus::STATUS::FULL != des_restore_status) { + //do nothing + } else if (OB_FAIL(ls->get_tablet_svr()->update_tablet_restore_status(t_id, + ObTabletRestoreStatus::STATUS::EMPTY, false/* need reset transfer flag */))) { + LOG_WARN("failed to update tablet restore status", K(ret), KPC(tablet)); + } else { + LOG_INFO("modify tablet restore status", K(tablet->get_tablet_id()), "old status", des_restore_status, "new status", ObTabletRestoreStatus::STATUS::EMPTY); + } + } + } + return ret; +} + +int ObTabletFreezeReplayExecutor::init( + ObLS *ls, + const ObTabletFreezeLog &log, + const SCN &scn) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret), K_(is_inited)); + } else if (OB_ISNULL(ls) + || OB_UNLIKELY(!log.is_valid()) + || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KPC(ls), K(log), K(scn)); + } else { + ls_ = ls; + log_ = &log; + scn_ = scn; + is_inited_ = true; + } + return ret; +} + +int ObTabletFreezeReplayExecutor::do_replay_(ObTabletHandle &handle) +{ + UNUSED(handle); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObDDLRedoLogReplayer has not been inited", K(ret)); + } else if (OB_ISNULL(log_) || OB_UNLIKELY(!log_->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), KPC(log_)); + } else { + uint64_t tenant_id = MTL_ID(); + const ObTabletID &tablet_id = log_->tablet_id_; + const int64_t abs_timeout_ts = ObClockGenerator::getClock() + 10LL * 1000LL * 1000LL; + const bool need_rewrite_tablet_meta = false; + MTL_SWITCH(tenant_id) { + const ObLSID ls_id = ls_->get_ls_id(); + storage::ObTenantFreezer* freezer = nullptr; + if (OB_ISNULL(freezer = MTL(storage::ObTenantFreezer*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ObTenantFreezer shouldn't be null", K(ret), K(tenant_id)); + } else if (OB_FAIL(freezer->tablet_freeze(ls_id, tablet_id, true/*is_sync*/, abs_timeout_ts, need_rewrite_tablet_meta, ObFreezeSourceFlag::TABLET_SPLIT))) { + LOG_WARN("fail to freeze tablet", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); + } else { + LOG_INFO("succeed to freeze tablet", K(ret), K(tenant_id), K(ls_id), K(tablet_id)); + } + } + } + LOG_INFO("finish replay tablet freeze log", K(ret), KPC(log_)); + return ret; +} + + #ifdef OB_BUILD_SHARED_STORAGE // ObDDLFinishReplayExecutor ObDDLFinishReplayExecutor::ObDDLFinishReplayExecutor() - : ObDDLReplayExecutor(), log_(nullptr) + : ObDDLReplayExecutor(), log_(nullptr) { } @@ -1051,6 +1395,7 @@ int ObDDLIncCommitReplayExecutor::init( return ret; } + int ObDDLIncCommitReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; @@ -1094,7 +1439,7 @@ int ObSchemaChangeReplayExecutor::init( int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; - LOG_WARN("init twice", KR(ret), K_(is_inited)); + LOG_WARN("init twice", K(ret), K_(is_inited)); } else if (OB_UNLIKELY(!log.is_valid()) || OB_UNLIKELY(!scn.is_valid())) { ret = OB_INVALID_ARGUMENT; diff --git a/src/storage/ddl/ob_ddl_replay_executor.h b/src/storage/ddl/ob_ddl_replay_executor.h index 4d332d939..04cecb327 100644 --- a/src/storage/ddl/ob_ddl_replay_executor.h +++ b/src/storage/ddl/ob_ddl_replay_executor.h @@ -18,6 +18,8 @@ #include "storage/ddl/ob_ddl_clog.h" #include "storage/ddl/ob_ddl_inc_clog.h" #include "storage/ddl/ob_ddl_struct.h" +#include "storage/ddl/ob_tablet_split_task.h" +#include "storage/ddl/ob_tablet_lob_split_task.h" #include "storage/ddl/ob_direct_load_struct.h" #include "storage/blocksstable/ob_block_sstable_struct.h" @@ -31,9 +33,8 @@ class ObTabletHandle; class ObDDLReplayExecutor : public logservice::ObTabletReplayExecutor { public: - ObDDLReplayExecutor(); - + ~ObDDLReplayExecutor() = default; protected: bool is_replay_update_tablet_status_() const override final { @@ -79,6 +80,7 @@ class ObDDLStartReplayExecutor final : public ObDDLReplayExecutor { public: ObDDLStartReplayExecutor(); + ~ObDDLStartReplayExecutor() = default; virtual bool is_replay_ddl_control_log_() const override final { return true; } @@ -108,6 +110,7 @@ class ObDDLRedoReplayExecutor final : public ObDDLReplayExecutor { public: ObDDLRedoReplayExecutor(); + ~ObDDLRedoReplayExecutor() = default; int init( ObLS *ls, @@ -120,7 +123,7 @@ protected: // @return OB_EAGAIN, failed to replay, need retry. // @return OB_NO_NEED_UPDATE, this log needs to be ignored. // @return other error codes, failed to replay. - int do_replay_(ObTabletHandle &handle) override; + virtual int do_replay_(ObTabletHandle &handle) override; #ifdef OB_BUILD_SHARED_STORAGE int write_ss_block(blocksstable::ObStorageObjectWriteInfo &write_info, blocksstable::ObStorageObjectHandle ¯o_handle); @@ -146,6 +149,7 @@ class ObDDLCommitReplayExecutor final : public ObDDLReplayExecutor { public: ObDDLCommitReplayExecutor(); + ~ObDDLCommitReplayExecutor() = default; virtual bool is_replay_ddl_control_log_() const override final { return true; } @@ -232,10 +236,93 @@ private: const ObDDLIncCommitLog *log_; }; +class ObSplitStartReplayExecutor final : public ObDDLReplayExecutor +{ +public: + ObSplitStartReplayExecutor(); + ~ObSplitStartReplayExecutor() = default; + + int init( + ObLS *ls, + const ObTabletSplitStartLog &log, + const share::SCN &scn); + static int prepare_param_from_log( + const share::ObLSID &ls_id, + const ObTabletSplitInfo &info, + ObTabletSplitParam ¶m); + static int prepare_param_from_log( + const share::ObLSID &ls_id, + const ObTabletSplitInfo &info, + ObLobSplitParam ¶m); + +protected: + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + virtual int do_replay_(ObTabletHandle &handle) override; + +private: + const ObTabletSplitStartLog *log_; +}; + +class ObSplitFinishReplayExecutor final : public ObDDLReplayExecutor +{ +public: + ObSplitFinishReplayExecutor(); + ~ObSplitFinishReplayExecutor() = default; + + int init( + ObLS *ls, + const ObTabletSplitFinishLog &log, + const share::SCN &scn); + +protected: + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + virtual int do_replay_(ObTabletHandle &handle) override; +private: + static int modify_tablet_restore_status_if_need( + const ObIArray &dest_tablet_ids, + const ObTabletHandle &src_tablet_handle, + ObLS* ls); +private: + const ObTabletSplitFinishLog *log_; +}; + +class ObTabletFreezeReplayExecutor final : public ObDDLReplayExecutor +{ +public: + ObTabletFreezeReplayExecutor(); + ~ObTabletFreezeReplayExecutor() = default; + + int init( + ObLS *ls, + const ObTabletFreezeLog &log, + const share::SCN &scn); + +protected: + // replay to the tablet + // @return OB_SUCCESS, replay successfully, data has written to tablet. + // @return OB_EAGAIN, failed to replay, need retry. + // @return OB_NO_NEED_UPDATE, this log needs to be ignored. + // @return other error codes, failed to replay. + virtual int do_replay_(ObTabletHandle &handle) override; + +private: + const ObTabletFreezeLog *log_; +}; + + class ObSchemaChangeReplayExecutor final : public logservice::ObTabletReplayExecutor { public: ObSchemaChangeReplayExecutor(); + ~ObSchemaChangeReplayExecutor() = default; int init( const ObTabletSchemaVersionChangeLog &log, @@ -253,7 +340,7 @@ protected: // @return OB_NO_NEED_UPDATE, this log needs to be ignored. // @return OB_TASK_EXPIRED, ddl task expired. // @return other error codes, failed to replay. - int do_replay_(ObTabletHandle &handle) override; + virtual int do_replay_(ObTabletHandle &handle) override; virtual bool is_replay_update_mds_table_() const override { diff --git a/src/storage/ddl/ob_tablet_ddl_kv.cpp b/src/storage/ddl/ob_tablet_ddl_kv.cpp index a3970628c..eb722a615 100644 --- a/src/storage/ddl/ob_tablet_ddl_kv.cpp +++ b/src/storage/ddl/ob_tablet_ddl_kv.cpp @@ -16,6 +16,7 @@ #include "storage/ddl/ob_tablet_ddl_kv.h" #include "share/scn.h" #include "storage/blocksstable/ob_block_sstable_struct.h" +#include "storage/blocksstable/index_block/ob_index_block_builder.h" #include "storage/blocksstable/ob_macro_block_struct.h" #include "storage/blocksstable/ob_object_manager.h" #include "share/ob_force_print_log.h" diff --git a/src/storage/ddl/ob_tablet_lob_split_task.cpp b/src/storage/ddl/ob_tablet_lob_split_task.cpp new file mode 100644 index 000000000..f1c8ed7c3 --- /dev/null +++ b/src/storage/ddl/ob_tablet_lob_split_task.cpp @@ -0,0 +1,2183 @@ +/** + * 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_tablet_lob_split_task.h" +#include "share/schema/ob_multi_version_schema_service.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/tx/ob_trans_service.h" +#include "share/ob_ddl_common.h" +#include "storage/compaction/ob_schedule_dag_func.h" +#include "storage/compaction/ob_tenant_tablet_scheduler.h" +#include "storage/tablet/ob_tablet.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/tx_storage/ob_access_service.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" +#include "src/storage/ddl/ob_ddl_merge_task.h" +#include "src/storage/ddl/ob_tablet_split_task.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/tablet/ob_tablet_split_mds_helper.h" + +namespace oceanbase +{ + +using namespace common; +using namespace storage; +using namespace share; +using namespace share::schema; +using namespace sql; +using namespace observer; +using namespace omt; +using namespace name; +using namespace transaction; +using namespace blocksstable; + +namespace storage +{ + +DEFINE_SERIALIZE(ObLobIdItem) +{ + int ret = OB_SUCCESS; + + if (OB_FAIL(serialization::encode_vi64(buf, buf_len, pos, id_.lob_id_))) { + LOG_WARN("Fail to encode key", K(ret)); + } else if (OB_FAIL(serialization::encode_vi64(buf, buf_len, pos, id_.tablet_id_))) { + LOG_WARN("Fail to encode key", K(ret)); + } else if (OB_FAIL(serialization::encode_vi64(buf, buf_len, pos, tablet_idx_))) { + LOG_WARN("Fail to encode key", K(ret)); + } + + return ret; +} + +DEFINE_DESERIALIZE(ObLobIdItem) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(serialization::decode_vi64(buf, data_len, pos, reinterpret_cast(&id_.lob_id_)))) { + LOG_WARN("fail to decode key_", K(ret)); + } else if (OB_FAIL(serialization::decode_vi64(buf, data_len, pos, reinterpret_cast(&id_.tablet_id_)))) { + LOG_WARN("fail to decode key_", K(ret)); + } else if (OB_FAIL(serialization::decode_vi64(buf, data_len, pos, &tablet_idx_))) { + LOG_WARN("fail to decode key_", K(ret)); + } + return ret; +} + +DEFINE_GET_SERIALIZE_SIZE(ObLobIdItem) +{ + int64_t size = 0; + + size += serialization::encoded_length_vi64(id_.lob_id_); + size += serialization::encoded_length_vi64(id_.tablet_id_); + size += serialization::encoded_length_vi64(tablet_idx_); + + return size; +} + +ObLobSplitParam::~ObLobSplitParam() +{ + parallel_datum_rowkey_list_.reset(); + rowkey_allocator_.reset(); +} + +int ObLobSplitParam::assign(const ObLobSplitParam &other) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid param", K(ret), K(other)); + } else { + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + ori_lob_meta_tablet_id_ = other.ori_lob_meta_tablet_id_; + schema_version_ = other.schema_version_; + data_format_version_ = other.data_format_version_; + parallelism_ = other.parallelism_; + compaction_scn_ = other.compaction_scn_; + compat_mode_ = other.compat_mode_; + task_id_ = other.task_id_; + source_table_id_ = other.source_table_id_; + dest_schema_id_ = other.dest_schema_id_; + consumer_group_id_ = other.consumer_group_id_; + split_sstable_type_ = other.split_sstable_type_; + if (OB_FAIL(new_lob_tablet_ids_.assign(other.new_lob_tablet_ids_))) { + LOG_WARN("failed to assign new_lob_tablet_ids_", K(ret)); + } else if (OB_FAIL(lob_col_idxs_.assign(other.lob_col_idxs_))) { + LOG_WARN("failed to assign lob_col_idxs_", K(ret)); + } else if (OB_FAIL(parallel_datum_rowkey_list_.prepare_allocate(other.parallel_datum_rowkey_list_.count()))) { + LOG_WARN("prepare alloc failed", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < other.parallel_datum_rowkey_list_.count(); i++) { + if (OB_FAIL(other.parallel_datum_rowkey_list_.at(i).deep_copy(parallel_datum_rowkey_list_.at(i), rowkey_allocator_))) { + // deep copy needed. + LOG_WARN("alloc range buf failed", K(ret)); + } + } + } + } + return ret; +} + +int ObLobSplitParam::init(const ObLobSplitParam &other) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(assign(other))) { + LOG_WARN("fail to assign from input", K(other)); + } + return ret; +} + +int ObLobSplitParam::init(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid param", K(ret), K(arg)); + } else { + tenant_id_ = arg.tenant_id_; + ls_id_ = arg.ls_id_; + ori_lob_meta_tablet_id_ = arg.source_tablet_id_; + schema_version_ = arg.schema_version_; + data_format_version_ = arg.data_format_version_; + task_id_ = arg.task_id_; + source_table_id_ = arg.source_table_id_; + dest_schema_id_ = arg.dest_schema_id_; + consumer_group_id_ = arg.consumer_group_id_; + split_sstable_type_ = arg.split_sstable_type_; + parallelism_ = arg.parallel_datum_rowkey_list_.count() - 1; + compaction_scn_ = arg.compaction_scn_; + if (OB_FAIL(parallel_datum_rowkey_list_.assign(arg.parallel_datum_rowkey_list_))) { // shallow cpy. + LOG_WARN("assign failed", K(ret), "parall_info", arg.parallel_datum_rowkey_list_); + } else if (OB_FAIL(ObTabletSplitUtil::get_split_dest_tablets_info(ls_id_, ori_lob_meta_tablet_id_, new_lob_tablet_ids_, compat_mode_))) { + LOG_WARN("get split dest tablets failed", K(ret), K(arg)); + } else if (OB_FAIL(lob_col_idxs_.assign(arg.lob_col_idxs_))) { + LOG_WARN("failed to assign lob_col_idxs_", K(ret)); + } + } + return ret; +} + +int ObLobSplitParam::init(const obrpc::ObTabletSplitArg &arg) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid param", K(ret), K(arg)); + } else { + tenant_id_ = MTL_ID(); + ls_id_ = arg.ls_id_; + ori_lob_meta_tablet_id_ = arg.source_tablet_id_; + schema_version_ = arg.schema_version_; + data_format_version_ = arg.data_format_version_; + task_id_ = arg.task_id_; + source_table_id_ = arg.table_id_; + dest_schema_id_ = arg.lob_table_id_; + consumer_group_id_ = arg.consumer_group_id_; + split_sstable_type_ = arg.split_sstable_type_; + parallelism_ = arg.parallel_datum_rowkey_list_.count() - 1; + compaction_scn_ = arg.compaction_scn_; + ObArray unused_tablet_ids; + if (OB_FAIL(ObTabletSplitUtil::get_split_dest_tablets_info(ls_id_, ori_lob_meta_tablet_id_, unused_tablet_ids, compat_mode_))) { + LOG_WARN("get split dest tablets failed", K(ret), K(arg)); + } else if (OB_FAIL(parallel_datum_rowkey_list_.assign(arg.parallel_datum_rowkey_list_))) { // shallow cpy. + LOG_WARN("assign failed", K(ret), "parall_info", arg.parallel_datum_rowkey_list_); + } else if (OB_FAIL(new_lob_tablet_ids_.assign(arg.dest_tablets_id_))) { + LOG_WARN("failed to assign dest_tablets_id_", K(ret)); + } else if (OB_FAIL(lob_col_idxs_.assign(arg.lob_col_idxs_))) { + LOG_WARN("failed to assign lob_col_idxs_", K(ret)); + } + } + return ret; +} + +int ObLobSplitContext::init(const ObLobSplitParam& param) +{ + int ret = OB_SUCCESS; + sub_maps_.set_block_allocator(m_allocator_); + if (OB_UNLIKELY(!param.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid param", K(ret), K(param)); + } else if (OB_FAIL(init_maps(param))) { + LOG_WARN("fail to init sort maps", K(ret), K(param)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(param.ls_id_, ls_handle_, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(param)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle_, + param.ori_lob_meta_tablet_id_, + lob_meta_tablet_handle_, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("get tablet handle failed", K(ret), K(param)); + } else if (OB_FAIL(ObTabletSplitUtil::check_satisfy_split_condition(param.new_lob_tablet_ids_, param.compaction_scn_, lob_meta_tablet_handle_, ls_handle_))) { + if (OB_NEED_RETRY == ret) { + if (REACH_COUNT_INTERVAL(1000L)) { + LOG_WARN("wait to satisfy the data split condition", K(ret), K(param)); + } + } else { + LOG_WARN("check satisfy split condition failed", K(ret), K(param)); + } + } else if (OB_FAIL(get_dst_lob_tablet_ids(param))) { + LOG_WARN("fail to get dst lob tablet ids", K(ret), K(param)); + } else if (OB_FAIL(ObTabletSplitUtil::convert_rowkey_to_range(range_allocator_, param.parallel_datum_rowkey_list_, main_table_ranges_))) { + LOG_WARN("convert to range failed", K(ret), "parall_info", param.parallel_datum_rowkey_list_); + } else { + is_inited_ = true; + LOG_INFO("show main tablet split info", K(param)); + } + if (OB_FAIL(ret)) { + destroy(); + } + return ret; +} + +int ObLobSplitContext::get_dst_lob_tablet_ids(const ObLobSplitParam& param) +{ + int ret = OB_SUCCESS; + // get new lob tablet ids + ObTabletBindingMdsUserData ddl_data; + ObTabletSplitMdsUserData lob_meta_split_data; + if (OB_ISNULL(lob_meta_tablet_handle_.get_obj())) { + ret = OB_ERR_SYS; + LOG_WARN("tablet handle is null", K(ret), K(param)); + } else if (OB_FAIL(lob_meta_tablet_handle_.get_obj()->get_all_tables(lob_meta_table_store_iterator_))) { + LOG_WARN("failed to get all sstables", K(ret), K(param)); + } else if (FALSE_IT(main_tablet_id_ = lob_meta_tablet_handle_.get_obj()->get_tablet_meta().data_tablet_id_)) { + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle_, + main_tablet_id_, + main_tablet_handle_, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("get tablet handle failed", K(ret), K(param)); + } else if (OB_ISNULL(main_tablet_handle_.get_obj())) { + ret = OB_ERR_SYS; + LOG_WARN("tablet handle is null", K(ret), K(param)); + } else if (OB_FAIL(main_tablet_handle_.get_obj()->get_all_tables(main_table_store_iterator_))) { + LOG_WARN("failed to get all sstables", K(ret), K(param)); + } else if (OB_FAIL(main_tablet_handle_.get_obj()->get_ddl_data(share::SCN::max_scn(), ddl_data))) { + LOG_WARN("fail to get ddl data", K(ret), K(main_tablet_handle_)); + } else if (FALSE_IT(is_lob_piece_ = (param.ori_lob_meta_tablet_id_ == ddl_data.lob_piece_tablet_id_))) { + } else if (OB_FAIL(lob_meta_tablet_handle_.get_obj()->get_split_data(lob_meta_split_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(lob_meta_split_data.get_split_dst_tablet_ids(new_lob_tablet_ids_))) { + LOG_WARN("failed to get split dst tablet ids", K(ret)); + } else { + ObTabletHandle dst_lob_tablet_handle; + for (int64_t i = 0; i < new_lob_tablet_ids_.count() && OB_SUCC(ret); i++) { + if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle_, + new_lob_tablet_ids_.at(i), + dst_lob_tablet_handle, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("get tablet handle failed", K(ret), K(new_lob_tablet_ids_), K(i)); + } else if (OB_ISNULL(dst_lob_tablet_handle.get_obj())) { + ret = OB_ERR_SYS; + LOG_WARN("tablet handle is null", K(ret), K(new_lob_tablet_ids_.at(i))); + } else if (OB_FAIL(new_main_tablet_ids_.push_back(dst_lob_tablet_handle.get_obj()->get_tablet_meta().data_tablet_id_))) { + LOG_WARN("fail to push new lob meta tablet ids"); + } + } + } + LOG_INFO("init for get related tablet ids", K(ret), K(main_tablet_id_), K(new_main_tablet_ids_), + K(param.ori_lob_meta_tablet_id_), K(new_lob_tablet_ids_)); + return ret; +} + +int ObLobSplitContext::init_maps(const ObLobSplitParam& param) +{ + int ret = OB_SUCCESS; + ObLobIdMap* submap = nullptr; + const int64_t file_buf_size = ObExternalSortConstant::DEFAULT_FILE_READ_WRITE_BUFFER; + const int64_t expire_timestamp = 0; + const int64_t total_sort_memory_limit = EACH_SORT_MEMORY_LIMIT * param.parallelism_; + const uint64_t tenant_id = param.tenant_id_; + if (OB_ISNULL(total_map_ = reinterpret_cast(allocator_.alloc(sizeof(ObLobIdMap))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc sub map", K(ret)); + } else if (FALSE_IT(total_map_ = new(total_map_)ObLobIdMap(allocator_))) { + } else if (OB_FAIL(total_map_->init(total_sort_memory_limit, file_buf_size, expire_timestamp, tenant_id, &comparer_))) { + LOG_WARN("fail to init external sorter", K(ret)); + } + for (int64_t i = 0; i < param.parallelism_ && OB_SUCC(ret); i++) { + if (OB_ISNULL(submap = reinterpret_cast(allocator_.alloc(sizeof(ObLobIdMap))))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc sub map", K(ret)); + } else if (FALSE_IT(submap = new(submap)ObLobIdMap(allocator_))) { + } else if (OB_FAIL(submap->init(EACH_SORT_MEMORY_LIMIT, file_buf_size, expire_timestamp, tenant_id, &comparer_))) { + LOG_WARN("fail to init external sorter", K(ret)); + } else if (OB_FAIL(sub_maps_.push_back(submap))) { + LOG_WARN("fail to push back sub map", K(ret)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(submap)) { + submap->clean_up(); + allocator_.free(submap); + } + } + return ret; +} + +void ObLobSplitContext::destroy() +{ + ls_handle_.reset(); + if (total_map_ != nullptr) { + total_map_->clean_up(); + allocator_.free(total_map_); + total_map_ = nullptr; + } + for (int64_t i = 0; i < sub_maps_.count(); i++) { + if (sub_maps_.at(i) != nullptr) { + sub_maps_.at(i)->clean_up(); + allocator_.free(sub_maps_.at(i)); + } + } + sub_maps_.reset(); + new_main_tablet_ids_.reset(); + new_lob_tablet_ids_.reset(); + main_table_store_iterator_.reset(); + lob_meta_table_store_iterator_.reset(); + m_allocator_.reset(); + allocator_.reset(); + main_table_ranges_.reset(); + range_allocator_.reset(); +} + +bool ObLobIdItemCompare::operator()(const ObLobIdItem *left, const ObLobIdItem *right) +{ + bool bool_ret = false; + if (OB_UNLIKELY(common::OB_SUCCESS != result_code_)) { + //do nothing + } else if (OB_UNLIKELY(NULL == left) + || OB_UNLIKELY(NULL == right)) { + result_code_ = common::OB_INVALID_ARGUMENT; + LOG_WARN_RET(result_code_, "Invaid argument, ", KP(left), KP(right), K_(result_code)); + } else { + int cmp_ret = left->cmp(*right); + bool_ret = (cmp_ret < 0); + } + return bool_ret; +} + + +ObTabletLobBuildMapTask::ObTabletLobBuildMapTask() + : ObITask(TASK_TYPE_LOB_BUILD_MAP), is_inited_(false), task_id_(0), + rk_cnt_(0), param_(nullptr), ctx_(nullptr), + allocator_("LobBuildMap", OB_MALLOC_NORMAL_BLOCK_SIZE /*8KB*/, MTL_ID()) +{ +} + +ObTabletLobSplitDag::ObTabletLobSplitDag() + : ObIDag(ObDagType::DAG_TYPE_TABLET_SPLIT), is_inited_(false), param_(), context_() +{ +} + +ObTabletLobSplitDag::~ObTabletLobSplitDag() +{ + context_.destroy(); +} + +int ObTabletLobSplitDag::init_by_param(const share::ObIDagInitParam *param) +{ + int ret = OB_SUCCESS; + const ObLobSplitParam *tmp_param = static_cast(param); + if (OB_UNLIKELY(nullptr == tmp_param || !tmp_param->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KPC(tmp_param)); + } else if (OB_FAIL(param_.init(*tmp_param))) { + LOG_WARN("init tablet split param failed", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(param_)); + } else if (OB_FAIL(context_.init(param_))) { + LOG_WARN("init failed", K(ret)); + } else { + consumer_group_id_ = tmp_param->consumer_group_id_; + is_inited_ = true; + } + return ret; +} + +bool ObTabletLobSplitDag::operator==(const ObIDag &other) const +{ + int tmp_ret = OB_SUCCESS; + bool is_equal = false; + if (OB_UNLIKELY(this == &other)) { + is_equal = true; + } else if (get_type() == other.get_type()) { + const ObTabletLobSplitDag &dag = static_cast(other); + if (OB_UNLIKELY(!param_.is_valid() || !dag.param_.is_valid())) { + tmp_ret = OB_ERR_SYS; + LOG_ERROR("invalid argument", K(tmp_ret), K(param_), K(dag.param_)); + } else { + is_equal = (param_.tenant_id_ == dag.param_.tenant_id_) && (param_.ls_id_ == dag.param_.ls_id_) && + (param_.ori_lob_meta_tablet_id_ == dag.param_.ori_lob_meta_tablet_id_); + } + } + return is_equal; +} + +int ObTabletLobSplitDag::calc_total_row_count() { + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("has not been inited ", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(param_)); + } else if (context_.physical_row_count_ != 0) { + // already calc, do nothing. + LOG_TRACE("already calculated", K(context_.physical_row_count_)); + } else if (OB_FAIL(ObDDLUtil::get_tablet_physical_row_cnt( + param_.ls_id_, + param_.ori_lob_meta_tablet_id_, + true, // calc_sstable = true; + false, // calc_memtable = false; because memtable has been frozen. + context_.physical_row_count_))) { + LOG_WARN("failed to get physical row count of tablet", K(ret), K(param_), K(context_)); + } + LOG_INFO("calc row count of the src tablet", K(ret), K(context_)); + return ret; +} +int64_t ObTabletLobSplitDag::hash() const +{ + int tmp_ret = OB_SUCCESS; + int64_t hash_val = 0; + if (OB_UNLIKELY(!is_inited_ || !param_.is_valid())) { + tmp_ret = OB_ERR_SYS; + LOG_ERROR("table schema must not be NULL", K(tmp_ret), K(is_inited_), K(param_)); + } else { + hash_val = param_.tenant_id_ + param_.ls_id_.hash() + + param_.ori_lob_meta_tablet_id_.hash() + ObDagType::DAG_TYPE_TABLET_SPLIT; + } + return hash_val; +} + +int ObTabletLobSplitDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobSplitDag has not been initialized", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(param_.ori_lob_meta_tablet_id_.id()), param_.parallelism_))) { + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + +int ObTabletLobSplitDag::fill_dag_key(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobSplitDag has not been initialized", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid params", K(ret), K(param_)); + } else if (OB_FAIL(databuff_printf(buf, buf_len, + "Regen macro block split: src_tablet_id=%ld, parallelism=%ld, tenant_id=%lu, ls_id=%ld, schema_version=%ld", + param_.ori_lob_meta_tablet_id_.id(), param_.parallelism_, + param_.tenant_id_, param_.ls_id_.id(), param_.schema_version_))) { + LOG_WARN("fail to fill comment", K(ret), K(param_)); + } + return ret; +} + +int ObTabletLobSplitDag::create_first_task() +{ + int ret = OB_SUCCESS; + ObTabletLobBuildMapTask *build_map_task = nullptr; + ObTabletLobMergeMapTask *merge_map_task = nullptr; + ObTabletLobWriteDataTask *write_data_task = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(alloc_task(build_map_task))) { + LOG_WARN("allocate task failed", K(ret)); + } else if (OB_ISNULL(build_map_task)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr task", K(ret)); + } else if (OB_FAIL(build_map_task->init(0, param_, context_))) { + LOG_WARN("init build map task failed", K(ret)); + } else if (OB_FAIL(add_task(*build_map_task))) { + LOG_WARN("add task failed", K(ret)); + } else if (OB_FAIL(alloc_task(merge_map_task))) { + LOG_WARN("alloc task failed", K(ret)); + } else if (OB_ISNULL(merge_map_task)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr task", K(ret)); + } else if (OB_FAIL(merge_map_task->init(param_, context_))) { + LOG_WARN("init merge map task failed", K(ret)); + } else if (OB_FAIL(build_map_task->add_child(*merge_map_task))) { + LOG_WARN("add child task failed", K(ret)); + } else if (OB_FAIL(add_task(*merge_map_task))) { + LOG_WARN("add task failed", K(ret)); + } else if (OB_FAIL(alloc_task(write_data_task))) { + LOG_WARN("alloc task failed", K(ret)); + } else if (OB_ISNULL(write_data_task)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr task", K(ret)); + } else if (OB_FAIL(write_data_task->init(0, param_, context_))) { + LOG_WARN("init write data task failed", K(ret)); + } else if (OB_FAIL(build_map_task->add_child(*write_data_task))) { + LOG_WARN("add child task failed", K(ret)); + } else if (OB_FAIL(add_task(*write_data_task))) { + LOG_WARN("add task failed"); + } + return ret; +} + +bool ObTabletLobSplitDag::ignore_warning() +{ + return OB_EAGAIN == dag_ret_ + || OB_NEED_RETRY == dag_ret_ + || OB_TASK_EXPIRED == dag_ret_; +} + +int ObTabletLobSplitDag::report_lob_split_status() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobSplitDag has not been inited", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid param", K(ret), K(param_)); + } else { + obrpc::ObDDLBuildSingleReplicaResponseArg arg; + ObAddr rs_addr; + arg.tenant_id_ = param_.tenant_id_; + arg.dest_tenant_id_ = param_.tenant_id_; + arg.ls_id_ = param_.ls_id_; + arg.dest_ls_id_ = param_.ls_id_; + arg.tablet_id_ = param_.ori_lob_meta_tablet_id_; + arg.source_table_id_ = param_.source_table_id_; + arg.dest_schema_id_ = context_.main_tablet_id_.id(); // fill ori main tablet id + arg.snapshot_version_ = 1L; // to avoid invalid only. + arg.schema_version_ = param_.schema_version_; + arg.dest_schema_version_ = param_.schema_version_; + arg.ret_code_ = context_.data_ret_; + arg.task_id_ = param_.task_id_; + arg.execution_id_ = 1L; + arg.server_addr_ = GCTX.self_addr(); + arg.row_inserted_ = context_.row_inserted_; + arg.physical_row_count_ = context_.physical_row_count_; + FLOG_INFO("send tablet split response to RS", K(ret), K(context_), K(arg), K(param_)); + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(GCTX.rs_rpc_proxy_) || OB_ISNULL(GCTX.rs_mgr_)) { + ret = OB_ERR_SYS; + LOG_WARN("innner system error, rootserver rpc proxy or rs mgr must not be NULL", K(ret), K(GCTX)); + } else if (OB_FAIL(GCTX.rs_mgr_->get_master_root_server(rs_addr))) { + LOG_WARN("fail to get rootservice address", K(ret)); + } else if (OB_FAIL(GCTX.rs_rpc_proxy_->to(rs_addr).build_ddl_single_replica_response(arg))) { + LOG_WARN("fail to send build split tablet data response", K(ret), K(arg)); + } + SERVER_EVENT_ADD("ddl", "replica_split_resp", + "result", context_.data_ret_, + "tenant_id", param_.tenant_id_, + "source_tablet_id", param_.ori_lob_meta_tablet_id_.id(), + "svr_addr", GCTX.self_addr(), + "physical_row_count", context_.physical_row_count_, + "split_total_rows", context_.row_inserted_, + *ObCurTraceId::get_trace_id()); + } + FLOG_INFO("lob tablet split finished", K(ret), K(context_.data_ret_)); + return ret; +} + +ObTabletLobBuildMapTask::~ObTabletLobBuildMapTask() +{ +} + +int ObTabletLobBuildMapTask::init(const int64_t task_id, ObLobSplitParam ¶m, + ObLobSplitContext &context) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTabletLobBuildMapTask has already been inited", K(ret)); + } else if (task_id < 0 || !param.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(task_id), K(param), K(context)); + } else { + task_id_ = task_id; + param_ = ¶m; + ctx_ = &context; + is_inited_ = true; + } + return ret; +} + +int ObTabletLobBuildMapTask::process() +{ + int ret = OB_SUCCESS; + ObIDag *tmp_dag = get_dag(); + ObTabletLobSplitDag *dag = nullptr; + bool is_all_major_exist = false; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobBuildMapTask has not been inited before", K(ret)); + } else if (OB_ISNULL(tmp_dag)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag is invalid", K(ret), KP(tmp_dag)); + } else if (OB_ISNULL(dag = static_cast(tmp_dag))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KP(tmp_dag), KP(dag)); + } else if (OB_FAIL(dag->calc_total_row_count())) { // only calc row count once time for a task + LOG_WARN("failed to calc task row count", K(ret)); + } else if (OB_SUCCESS != (ctx_->data_ret_)) { + LOG_WARN("build map task has already failed", "ret", ctx_->data_ret_); + } else if (ctx_->is_lob_piece_) { + // lob piece has no data, do nothing + } else if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(param_->ls_id_, param_->new_lob_tablet_ids_, is_all_major_exist))) { + LOG_WARN("check all major exist failed", K(ret)); + } else if (is_all_major_exist) { + LOG_INFO("split task has alreay finished", KPC(param_)); + } else { + ObArray iters; + common::ObArenaAllocator tmp_arena("RowScanIter", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + + if (OB_SUCC(ret)) { + ObTabletSplitMdsUserData split_data; + const ObStorageSchema *main_storage_schema = nullptr; + if (OB_FAIL(ctx_->main_tablet_handle_.get_obj()->get_split_data(split_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("fail to get split data", K(ret), K(ctx_->main_tablet_handle_)); + } else if (OB_FAIL(split_data.get_storage_schema(main_storage_schema))) { + LOG_WARN("failed to get storage schema", K(ret)); + } else if (OB_FAIL(ObTabletLobSplitUtil::generate_col_param(main_storage_schema, rk_cnt_))) { + LOG_WARN("fail to generate col param", K(ret), K(task_id_)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ObTabletLobSplitUtil::open_rowscan_iters(param_->split_sstable_type_, + tmp_arena, + param_->source_table_id_, + ctx_->main_tablet_handle_, + ctx_->main_table_store_iterator_, + ctx_->main_table_ranges_.at(task_id_), + iters))) { + LOG_WARN("fail to open iters", K(ret)); + } else if (OB_FAIL(build_sorted_map(iters))) { + LOG_WARN("fail to do build sub map", K(ret)); + } else { + LOG_INFO("finish the lob build map task", K(ret), K(task_id_)); + } + // close row scan iters + for (int64_t i = 0; i < iters.count(); i++) { + ObRowScan *iter = iters.at(i); + if (OB_NOT_NULL(iter)) { + iter->~ObRowScan(); + } + } + } + if (OB_FAIL(ret) && OB_NOT_NULL(ctx_)) { + ctx_->data_ret_ = ret; + ret = OB_SUCCESS; + } + return ret; +} + +int ObTabletLobBuildMapTask::generate_next_task(ObITask *&next_task) +{ + int ret = OB_SUCCESS; + ObIDag *tmp_dag = get_dag(); + ObTabletLobBuildMapTask *buildmap_task = nullptr; + const int64_t next_task_id = task_id_ + 1; + next_task = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobBuildMapTask has not been inited", K(ret)); + } else if (next_task_id == param_->parallelism_) { + ret = OB_ITER_END; + } else if (OB_ISNULL(tmp_dag)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, dag must not be NULL", K(ret)); + } else if (OB_FAIL(tmp_dag->alloc_task(buildmap_task))) { + LOG_WARN("fail to alloc task", K(ret)); + } else if (OB_FAIL(buildmap_task->init(next_task_id, *param_, *ctx_))) { + LOG_WARN("fail to init lob build map task", K(ret)); + } else { + next_task = buildmap_task; + LOG_INFO("generate next lob build map task", K(ret)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(ctx_)) { + if (OB_ITER_END != ret) { + ctx_->data_ret_ = ret; + } + } + return ret; +} + +int ObTabletLobBuildMapTask::build_sorted_map(ObIArray& iters) +{ + int ret = OB_SUCCESS; + // get new lob tablet ids + ObTabletHandle tablet_handle; + ObTabletSplitMdsUserData src_split_data; + ObSEArray dst_split_datas; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobSplitTask is not inited", K(ret)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ctx_->ls_handle_, + ctx_->main_tablet_id_, + tablet_handle, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("get tablet handle failed", K(ret), K(param)); + } else if (OB_ISNULL(tablet_handle.get_obj())) { + ret = OB_ERR_SYS; + LOG_WARN("tablet handle is null", K(ret), K(tablet_handle)); + } else if (ctx_->sub_maps_.count() <= task_id_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sub maps count is unexpected.", K(ret), K(ctx_->sub_maps_.count()), K(task_id_)); + } else if (OB_ISNULL(ctx_->sub_maps_.at(task_id_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sub maps is null.", K(ret), K(ctx_->sub_maps_), K(task_id_)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::prepare_calc_split_dst( + *ctx_->ls_handle_.get_ls(), + *ctx_->main_tablet_handle_.get_obj(), + ObTimeUtility::current_time() + (1 + ctx_->new_main_tablet_ids_.count()) * ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S, + src_split_data, + dst_split_datas))) { + LOG_WARN("failed to prepare calc split dst", K(ret), K(ctx_->new_main_tablet_ids_)); + } else { + ObLobIdMap* submap = ctx_->sub_maps_.at(task_id_); + for (int64_t i = 0; i < iters.count() && OB_SUCC(ret); i++) { + ObRowScan *curr = iters.at(i); + while (OB_SUCC(ret)) { + const ObDatumRow *tmp_row = nullptr; + if (OB_FAIL(curr->get_next_row(tmp_row))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next row", K(ret)); + } + } else { + LOG_DEBUG("scan get main tablet row", KPC(tmp_row)); + } + // get rowkey from row + ObDatumRowkey rk; + // get dst lob tablet id + ObTabletID dst_tablet_id; + int64_t idx = -1; + int64_t dst_idx = 0; + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(tmp_row)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("get next row is null", K(ret)); + } else if (OB_FAIL(rk.assign(tmp_row->storage_datums_, rk_cnt_))) { + LOG_WARN("fail to assign rowkey", K(ret)); + } else if (OB_FAIL(src_split_data.calc_split_dst(ctx_->main_tablet_handle_.get_obj()->get_rowkey_read_info(), dst_split_datas, rk, dst_tablet_id, dst_idx))) { + LOG_WARN("failed to calc split dst tablet", K(ret)); + } else { + bool is_found = false; + for (int64_t i = 0; OB_SUCC(ret) && !is_found && i < ctx_->new_main_tablet_ids_.count(); i++) { + if (ctx_->new_main_tablet_ids_.at(i) == dst_tablet_id) { + dst_tablet_id = ctx_->new_lob_tablet_ids_.at(i); + idx = i; + is_found = true; + } + } + if (!is_found) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not found dst main tablet in array", K(ret), K(dst_tablet_id), K(ctx_->new_main_tablet_ids_)); + } + } + + for (int64_t i = 0; OB_SUCC(ret) && i < param_->lob_col_idxs_.count(); i++) { + // lob col must not be rowkey, so just add extra rowkey cnt + const uint64_t lob_idx = param_->lob_col_idxs_.at(i) + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + if (lob_idx >= tmp_row->get_column_count()) { + LOG_TRACE("Tail-added column datum did not exist, whose default value must be in row", K(lob_idx), KPC(tmp_row)); + } else { + ObStorageDatum &datum = tmp_row->storage_datums_[lob_idx]; + if (datum.is_nop() || datum.is_null()) { + // do nothing + } else { + const ObLobCommon& lob_common = datum.get_lob_data(); + if (!lob_common.in_row_) { + const ObLobData* lob_data = reinterpret_cast(lob_common.buffer_); + ObLobIdItem item; + item.id_ = lob_data->id_; + item.tablet_idx_ = idx; + if (OB_FAIL(submap->add_item(item))) { + LOG_WARN("fail to add lob item into extern sortmap", K(ret)); + } else { + LOG_DEBUG("push lob id into map", K(item), K(submap), K(lob_idx)); + } + } + } + } + } + } + if (ret == OB_ITER_END) { + ret = OB_SUCCESS; + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(submap->do_sort(false))) { + LOG_WARN("fail to do sort submap", K(ret)); + } else { + LOG_INFO("finish submap sort", K(task_id_), K(param_->ori_lob_meta_tablet_id_), KPC(submap)); + } + } + return ret; +} + + + + +ObTabletLobMergeMapTask::ObTabletLobMergeMapTask() + : ObITask(TASK_TYPE_LOB_MERGE_MAP), is_inited_(false), param_(nullptr), ctx_(nullptr) +{ +} + +ObTabletLobMergeMapTask::~ObTabletLobMergeMapTask() +{ +} + +int ObTabletLobMergeMapTask::init(ObLobSplitParam ¶m, ObLobSplitContext &ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTabletLobBuildMapTask has already been inited", K(ret)); + } else if (!param.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(param), K(ctx)); + } else { + param_ = ¶m; + ctx_ = &ctx; + is_inited_ = true; + } + return ret; +} + +int ObTabletLobMergeMapTask::process() +{ + int ret = OB_SUCCESS; + ObIDag *tmp_dag = get_dag(); + const int64_t file_buf_size = ObExternalSortConstant::DEFAULT_FILE_READ_WRITE_BUFFER; + const int64_t expire_timestamp = 0; + const int64_t buf_limit = SORT_MEMORY_LIMIT; + const uint64_t tenant_id = param_->tenant_id_; + bool is_all_major_exist = false; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobBuildMapTask has not been inited before", K(ret)); + } else if (OB_ISNULL(tmp_dag)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag is invalid", K(ret), KP(tmp_dag)); + } else if (OB_SUCCESS != (ctx_->data_ret_)) { + LOG_WARN("build map task has already failed", "ret", ctx_->data_ret_); + } else if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(param_->ls_id_, param_->new_lob_tablet_ids_, is_all_major_exist))) { + LOG_WARN("check all major exist failed", K(ret)); + } else if (is_all_major_exist) { + LOG_INFO("split task has alreay finished", KPC(param_)); + } else if (ctx_->sub_maps_.count() != param_->parallelism_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("sub map count is wrong", K(ret), K(ctx_->sub_maps_.count()), K(param_->parallelism_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < ctx_->sub_maps_.count(); i++) { + ObLobIdMap* submap = ctx_->sub_maps_.at(i); + if (OB_ISNULL(submap)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("submap is null", K(ret), K(i)); + } else if (OB_FAIL(submap->transfer_final_sorted_fragment_iter(*(ctx_->total_map_)))) { + LOG_WARN("fail to combine into total map", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(ctx_->total_map_->do_sort(true))) { + LOG_WARN("fail to sort total map", K(ret)); + } else { + LOG_INFO("finish merge to total map", KPC(ctx_->total_map_)); + } + } + if (OB_FAIL(ret) && OB_NOT_NULL(ctx_)) { + ctx_->data_ret_ = ret; + ret = OB_SUCCESS; + } + return ret; +} + +ObTabletLobWriteSSTableCtx::ObTabletLobWriteSSTableCtx() + : table_key_(), data_seq_(0), merge_type_(MAJOR_MERGE), meta_(), dst_uncommitted_tx_id_arr_(), dst_major_snapshot_version_(-1) +{ +} + +ObTabletLobWriteSSTableCtx::~ObTabletLobWriteSSTableCtx() +{ +} + +int ObTabletLobWriteSSTableCtx::init(const ObSSTable &org_sstable, const int64_t major_snapshot_version) +{ + int ret = OB_SUCCESS; + if (!org_sstable.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(org_sstable)); + } else { + ObSSTableMetaHandle meta_handle; + table_key_ = org_sstable.get_key(); + if (OB_FAIL(org_sstable.get_meta(meta_handle))) { + LOG_WARN("get sstable meta failed", K(ret)); + } else { + meta_ = meta_handle.get_sstable_meta().get_basic_meta(); + data_seq_ = meta_handle.get_sstable_meta().get_sstable_seq(); + merge_type_ = org_sstable.is_major_sstable() ? compaction::MAJOR_MERGE : compaction::MINOR_MERGE; + dst_uncommitted_tx_id_arr_.reset(); + dst_major_snapshot_version_ = major_snapshot_version; + } + } + return ret; +} + +int ObTabletLobWriteSSTableCtx::assign(const ObTabletLobWriteSSTableCtx &other) +{ + int ret = OB_SUCCESS; + table_key_ = other.table_key_; + data_seq_ = other.data_seq_; + merge_type_ = other.merge_type_; + meta_ = other.meta_; + dst_major_snapshot_version_ = other.dst_major_snapshot_version_; + if (OB_FAIL(dst_uncommitted_tx_id_arr_.assign(other.dst_uncommitted_tx_id_arr_))) { + LOG_WARN("failed to assign", K(ret)); + } + return ret; +} + +ObTabletLobWriteDataTask::ObTabletLobWriteDataTask() + : ObITask(TASK_TYPE_LOB_WRITE_DATA), + allocator_("SplitLobWRow", OB_MALLOC_NORMAL_BLOCK_SIZE /*8KB*/, MTL_ID()), + is_inited_(false), task_id_(0), + rk_cnt_(0), write_sstable_ctx_array_(), param_(nullptr), ctx_(nullptr) +{} + +ObTabletLobWriteDataTask::~ObTabletLobWriteDataTask() +{} + +int ObTabletLobWriteDataTask::init(const int64_t task_id, ObLobSplitParam ¶m, ObLobSplitContext &ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("ObTabletLobBuildMapTask has already been inited", K(ret)); + } else if (task_id < 0 || !param.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(task_id), K(param), K(ctx)); + } else { + task_id_ = task_id; + param_ = ¶m; + ctx_ = &ctx; + is_inited_ = true; + } + return ret; +} + +int ObTabletLobWriteDataTask::process() +{ + int ret = OB_SUCCESS; + ObIDag *tmp_dag = get_dag(); + bool is_all_major_exist = false; + ObTabletCreateDeleteMdsUserData user_data; + ObTabletSplitMdsUserData lob_meta_split_data; + const ObStorageSchema *lob_meta_storage_schema = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobBuildMapTask has not been inited before", K(ret)); + } else if (OB_ISNULL(tmp_dag)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dag is invalid", K(ret), KP(tmp_dag)); + } else if (OB_SUCCESS != (ctx_->data_ret_)) { + LOG_WARN("write data task has already failed", "ret", ctx_->data_ret_); + } else if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(param_->ls_id_, param_->new_lob_tablet_ids_, is_all_major_exist))) { + LOG_WARN("check all major exist failed", K(ret)); + } else if (is_all_major_exist) { + LOG_INFO("split task has alreay finished", KPC(param_)); + } else if (OB_FAIL(ctx_->lob_meta_tablet_handle_.get_obj()->ObITabletMdsInterface::get_tablet_status( + share::SCN::max_scn(), user_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US))) { + LOG_WARN("failed to get tablet status", K(ret), KPC(param_)); + } else if (OB_FAIL(ctx_->lob_meta_tablet_handle_.get_obj()->get_split_data(lob_meta_split_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(lob_meta_split_data.get_storage_schema(lob_meta_storage_schema))) { + LOG_WARN("failed to get storage schema", K(ret)); + } else if (OB_FAIL(ObTabletLobSplitUtil::generate_col_param(lob_meta_storage_schema, rk_cnt_))) { + LOG_WARN("fail to generate col param", K(ret), K(task_id_)); + } else { + const int64_t major_snapshot_version = user_data.start_split_commit_version_; + ObDatumRange query_range; + query_range.set_whole_range(); // no parallel, just set whole range + ObArray iters; + ObArrayArray data_desc_arr; + ObArrayArray macro_block_writer_arr; + ObArrayArray index_builders; + if (OB_SUCC(ret) && (share::ObSplitSSTableType::SPLIT_BOTH == param_->split_sstable_type_ + || share::ObSplitSSTableType::SPLIT_MAJOR == param_->split_sstable_type_)) { + if (OB_FAIL(ObTabletLobSplitUtil::open_snapshot_scan_iters(param_, + ctx_, + param_->dest_schema_id_, + ctx_->lob_meta_tablet_handle_, + ctx_->lob_meta_table_store_iterator_, + query_range, + major_snapshot_version, + iters, + write_sstable_ctx_array_))) { + LOG_WARN("fail to open iters", K(ret)); + } + } + if (OB_SUCC(ret) && (share::ObSplitSSTableType::SPLIT_BOTH == param_->split_sstable_type_ + || share::ObSplitSSTableType::SPLIT_MINOR == param_->split_sstable_type_)) { + if (OB_FAIL(ObTabletLobSplitUtil::open_uncommitted_scan_iters(param_, + ctx_, + param_->dest_schema_id_, + ctx_->lob_meta_tablet_handle_, + ctx_->lob_meta_table_store_iterator_, + query_range, + major_snapshot_version, + iters, + write_sstable_ctx_array_))) { + LOG_WARN("fail to open iters", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(prepare_sstable_writers_and_builders(*lob_meta_storage_schema, data_desc_arr, macro_block_writer_arr, index_builders))) { + LOG_WARN("fail to prepare new tablet writers", K(ret)); + } else if (OB_FAIL(dispatch_rows(iters, macro_block_writer_arr))) { + LOG_WARN("fail to dispatch write row to split dst tablet", K(ret)); + } else if (share::ObSplitSSTableType::SPLIT_BOTH == param_->split_sstable_type_) { + if (OB_FAIL(create_sstables(index_builders, share::ObSplitSSTableType::SPLIT_MINOR))) { + LOG_WARN("create sstable failed", K(ret)); + } else if (OB_FAIL(create_sstables(index_builders, share::ObSplitSSTableType::SPLIT_MAJOR))) { + LOG_WARN("create sstable failed", K(ret)); + } + } else if (OB_FAIL(create_sstables(index_builders, param_->split_sstable_type_))) { + LOG_WARN("create sstable failed", K(ret)); + } + // release sstable writer and index builders + data_desc_arr.reset(); + release_sstable_writers_and_builders(macro_block_writer_arr, index_builders); + // close row scan iters + for (int64_t i = 0; i < iters.count(); i++) { + ObIStoreRowIterator *iter = iters.at(i).iter_; + if (OB_NOT_NULL(iter)) { + iter->~ObIStoreRowIterator(); + ctx_->allocator_.free(iter); + } + } + iters.reset(); + } + if (OB_FAIL(ret) && OB_NOT_NULL(ctx_)) { + ctx_->data_ret_ = ret; + ret = OB_SUCCESS; + } + ObTabletLobSplitDag *dag = static_cast(get_dag()); + int tmp_ret = OB_SUCCESS; + if (OB_NOT_NULL(dag) && + OB_SUCCESS != (tmp_ret = dag->report_lob_split_status())) { + // do not override ret if it has already failed. + ret = OB_SUCCESS == ret ? tmp_ret : ret; + LOG_WARN("fail to report lob tablet split status", K(ret), K(tmp_ret)); + } + return ret; +} + +int ObTabletLobWriteDataTask::generate_next_task(ObITask *&next_task) +{ + int ret = OB_SUCCESS; + ObIDag *tmp_dag = get_dag(); + ObTabletLobWriteDataTask *buildmap_task = nullptr; + const int64_t next_task_id = task_id_ + 1; + next_task = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletLobWriteDataTask has not been inited", K(ret)); + } else if (true || next_task_id == param_->parallelism_) { // not allow para now + ret = OB_ITER_END; + } else if (OB_ISNULL(tmp_dag)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("error unexpected, dag must not be NULL", K(ret)); + } else if (OB_FAIL(tmp_dag->alloc_task(buildmap_task))) { + LOG_WARN("fail to alloc task", K(ret)); + } else if (OB_FAIL(buildmap_task->init(next_task_id, *param_, *ctx_))) { + LOG_WARN("fail to init lob build map task", K(ret)); + } else { + next_task = buildmap_task; + LOG_INFO("generate next lob build map task", K(ret)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(ctx_)) { + if (OB_ITER_END != ret) { + ctx_->data_ret_ = ret; + } + } + return ret; +} + +int ObTabletLobWriteDataTask::prepare_sstable_writers_and_builders( + const ObStorageSchema &storage_schema, + ObArrayArray& data_desc_arr, + ObArrayArray& slice_writers, + ObArrayArray& index_builders) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(slice_writers.reserve(write_sstable_ctx_array_.count()))) { + LOG_WARN("fail to reserve slice writer array", K(ret)); + } else if (OB_FAIL(index_builders.reserve(write_sstable_ctx_array_.count()))) { + LOG_WARN("fail to reserve index builder array", K(ret)); + } else { + for (int64_t i = 0; i < write_sstable_ctx_array_.count() && OB_SUCC(ret); i++) { + if (OB_FAIL(slice_writers.push_back(ObArray()))) { + LOG_WARN("false to init slice_writers array", K(ret)); + } else if (OB_FAIL(index_builders.push_back(ObArray()))) { + LOG_WARN("false to init index_builders array", K(ret)); + } else if (OB_FAIL(data_desc_arr.push_back(ObArray()))) { + LOG_WARN("false to init index_builders array", K(ret)); + } + } + } + for (int64_t i = 0; i < write_sstable_ctx_array_.count() && OB_SUCC(ret); i++) { + for (int64_t j = 0; j < ctx_->new_lob_tablet_ids_.count() && OB_SUCC(ret); j++) { + ObWholeDataStoreDesc data_desc; + ObMacroBlockWriter *new_slice_writer = nullptr; + ObSSTableIndexBuilder *new_index_builder = nullptr; + if (OB_FAIL(data_desc_arr.push_back(i, data_desc))) { + LOG_WARN("fail to push index builder", K(ret)); + } else if (OB_FAIL(prepare_sstable_writer(write_sstable_ctx_array_.at(i), + ctx_->new_lob_tablet_ids_.at(j), + storage_schema, + data_desc_arr.at(i, j), + new_slice_writer, + new_index_builder))) { + LOG_WARN("fail to prepare sstable writers", K(ret), K(i), K(j)); + } else if (OB_FAIL(slice_writers.push_back(i, new_slice_writer))) { + LOG_WARN("fail to push slice writer", K(ret)); + } else if (FALSE_IT(new_slice_writer = nullptr)) { // if slice writer has pushed into array, set null, freed outer + } else if (OB_FAIL(index_builders.push_back(i, new_index_builder))) { + LOG_WARN("fail to push index builder", K(ret)); + } + if (OB_FAIL(ret)) { + release_slice_writer(new_slice_writer); + release_index_builder(new_index_builder); + } + } + } + return ret; +} + +int ObTabletLobWriteDataTask::prepare_sstable_writer(const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const ObTabletID &new_tablet_id, + const ObStorageSchema &storage_schema, + ObWholeDataStoreDesc &data_desc, + ObMacroBlockWriter *&slice_writer, + ObSSTableIndexBuilder *&index_builder) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = param_->tenant_id_; + slice_writer = nullptr; + index_builder = nullptr; + if (!write_sstable_ctx.is_valid() || !new_tablet_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid new tablet id", K(ret), K(write_sstable_ctx), K(new_tablet_id)); + } else if (OB_FAIL(prepare_sstable_index_builder(write_sstable_ctx, + new_tablet_id, + storage_schema, + index_builder))) { + LOG_WARN("fail to prepare index builder", K(ret)); + } else if (OB_FAIL(prepare_sstable_macro_writer(write_sstable_ctx, new_tablet_id, storage_schema, data_desc, index_builder, slice_writer))) { + LOG_WARN("fail to prepare macro writer", K(ret)); + } + return ret; +} + +int ObTabletLobWriteDataTask::prepare_sstable_macro_writer(const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const ObTabletID &new_tablet_id, + const ObStorageSchema &storage_schema, + ObWholeDataStoreDesc &data_desc, + ObSSTableIndexBuilder *index_builder, + ObMacroBlockWriter *&slice_writer) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + ObMacroDataSeq macro_start_seq(0); + ObTabletHandle tablet_handle; + if (OB_UNLIKELY(!new_tablet_id.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid new tablet id", K(ret), K(new_tablet_id)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ctx_->ls_handle_, new_tablet_id, tablet_handle, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("get tablet failed", K(ret), K(new_tablet_id)); + } else if (OB_FAIL(macro_start_seq.set_sstable_seq(write_sstable_ctx.data_seq_))) { + LOG_WARN("set sstable logical seq failed", K(ret)); + } else if (OB_FAIL(macro_start_seq.set_parallel_degree(task_id_))) { + LOG_WARN("set parallel degree failed", K(ret)); + } else { + const ObMergeType merge_type = write_sstable_ctx.merge_type_; + const int64_t snapshot_version = write_sstable_ctx.get_version(); + const bool micro_index_clustered = ctx_->lob_meta_tablet_handle_.get_obj()->get_tablet_meta().micro_index_clustered_; + ObMacroSeqParam macro_seq_param; + macro_seq_param.seq_type_ = ObMacroSeqParam::SEQ_TYPE_INC; + macro_seq_param.start_ = macro_start_seq.macro_data_seq_; + ObPreWarmerParam pre_warm_param; + ObSSTablePrivateObjectCleaner *object_cleaner = nullptr; + if (OB_FAIL(data_desc.init(true/*is_ddl*/, storage_schema, + param_->ls_id_, + new_tablet_id, + merge_type, + snapshot_version, + param_->data_format_version_, + micro_index_clustered, + tablet_handle.get_obj()->get_transfer_seq(), + write_sstable_ctx.table_key_.get_end_scn()))) { + LOG_WARN("fail to init data store desc", K(ret), "dest_tablet_id", new_tablet_id, KPC(param_), KPC(ctx_)); + } else if (FALSE_IT(data_desc.get_desc().sstable_index_builder_ = index_builder)) { + } else if (FALSE_IT(data_desc.get_static_desc().is_ddl_ = true)) { + } else if (OB_ISNULL(buf = ctx_->allocator_.alloc(sizeof(ObMacroBlockWriter)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc mem failed", K(ret)); + } else if (OB_FAIL(pre_warm_param.init(param_->ls_id_, new_tablet_id))) { + LOG_WARN("failed to init pre warm param", K(ret), "ls_id", param_->ls_id_, K(new_tablet_id)); + } else if (OB_FAIL(ObSSTablePrivateObjectCleaner::get_cleaner_from_data_store_desc( + data_desc.get_desc(), + object_cleaner))) { + LOG_WARN("failed to get cleaner from data store desc", K(ret)); + } else if (FALSE_IT(slice_writer = new (buf) ObMacroBlockWriter())) { + } else if (OB_FAIL(slice_writer->open(data_desc.get_desc(), macro_start_seq.get_parallel_idx(), + macro_seq_param, pre_warm_param, *object_cleaner))) { + LOG_WARN("open macro_block_writer failed", K(ret), K(data_desc)); + } + if (OB_FAIL(ret)) { + if (nullptr != slice_writer) { + slice_writer->~ObMacroBlockWriter(); + slice_writer = nullptr; + } + if (nullptr != buf) { + ctx_->allocator_.free(buf); + buf = nullptr; + } + } + } + return ret; +} + +int ObTabletLobWriteDataTask::prepare_sstable_index_builder(const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const ObTabletID &new_tablet_id, + const ObStorageSchema &storage_schema, + ObSSTableIndexBuilder *&index_builder) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObWholeDataStoreDesc data_desc; + ObITable::TableKey dest_table_key = write_sstable_ctx.table_key_; + dest_table_key.tablet_id_ = new_tablet_id; + const ObMergeType merge_type = write_sstable_ctx.merge_type_; + const int64_t snapshot_version = write_sstable_ctx.get_version(); + if (OB_UNLIKELY(!ctx_->lob_meta_tablet_handle_.is_valid())) { + ret = OB_ERR_NULL_VALUE; + LOG_WARN("table is null", K(ret), K(ctx_->lob_meta_tablet_handle_)); + } else if (!new_tablet_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid new tablet id", K(ret), K(new_tablet_id)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ctx_->ls_handle_, new_tablet_id, tablet_handle, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("get tablet failed", K(ret)); + } else if (OB_FAIL(ObTabletDDLUtil::prepare_index_data_desc(*tablet_handle.get_obj(), + dest_table_key, + snapshot_version, + param_->data_format_version_, + nullptr, + &storage_schema, + data_desc))) { + LOG_WARN("prepare index data desc failed", K(ret)); + } else { + void *builder_buf = nullptr; + if (OB_UNLIKELY(!data_desc.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid data store desc", K(ret), K(data_desc)); + } else if (OB_ISNULL(builder_buf = ctx_->allocator_.alloc(sizeof(ObSSTableIndexBuilder)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc memory", K(ret)); + } else if (FALSE_IT(index_builder = new (builder_buf) ObSSTableIndexBuilder(false/*use double write buffer*/))) { + } else if (OB_FAIL(index_builder->init(data_desc.get_desc(), + ObSSTableIndexBuilder::DISABLE))) { + LOG_WARN("failed to init index builder", K(ret), K(data_desc)); + } + if (OB_FAIL(ret)) { + if (nullptr != index_builder) { + index_builder->~ObSSTableIndexBuilder(); + index_builder = nullptr; + } + if (nullptr != builder_buf) { + ctx_->allocator_.free(builder_buf); + builder_buf = nullptr; + } + } + } + return ret; +} + +int ObTabletLobWriteDataTask::dispatch_rows(ObIArray& iters, + ObArrayArray& slice_writers) +{ + int ret = OB_SUCCESS; + // do scan + ObArray is_iter_finish; + ObArray cur_rows; + if (OB_FAIL(cur_rows.reserve(iters.count()))) { + LOG_WARN("fail to reserve ", K(ret)); + } else if (OB_FAIL(is_iter_finish.reserve(iters.count()))) { + LOG_WARN("fail to reserve ", K(ret)); + } else { + for (int64_t i = 0; i < iters.count() && OB_SUCC(ret); i++) { + if (OB_FAIL(is_iter_finish.push_back(false))) { + LOG_WARN("false to init is_iter_finish array", K(ret)); + } else if (OB_FAIL(cur_rows.push_back(nullptr))) { + LOG_WARN("false to init cur_rows array", K(ret)); + } + } + } + const ObLobIdItem *cur_item = nullptr; + while (OB_SUCC(ret)) { + // 1. total map and all iter do get next row if needed + if (OB_ISNULL(cur_item)) { + if (OB_FAIL(ctx_->total_map_->get_next_item(cur_item))) { + if (ret != OB_ITER_END) { + LOG_WARN("fail to get next total map item", K(ret)); + } // map return iter end to finish while + } else { + LOG_DEBUG("scan get next map item", KPC(cur_item)); + } + } + + for (int64_t i = 0; OB_SUCC(ret) && i < iters.count(); i++) { + if (OB_ISNULL(cur_rows.at(i)) && !is_iter_finish.at(i)) { + const ObDatumRow *tmp_row = nullptr; + if (OB_FAIL(iters.at(i).iter_->get_next_row(tmp_row))) { + if (ret == OB_ITER_END) { + is_iter_finish.at(i) = true; + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get next row by iter", K(ret), K(i)); + } + } else { + cur_rows.at(i) = tmp_row; + } + } + } + // 2. traverse cur row, compare to cur map item + bool hit_item = false; + for (int64_t i = 0; OB_SUCC(ret) && i < iters.count(); i++) { + if (!is_iter_finish.at(i)) { + const ObDatumRow *row = cur_rows.at(i); + if (OB_ISNULL(cur_item)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("item is null", K(ret)); + } else if (OB_ISNULL(row)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("row is null", K(ret)); + } else { + ObString data = row->storage_datums_[0].get_string(); + ObLobId *lob_id = reinterpret_cast(data.ptr()); + if (lob_id->lob_id_ == cur_item->id_.lob_id_ && lob_id->tablet_id_ == cur_item->id_.tablet_id_) { + hit_item = true; + LOG_DEBUG("scan lob meta row hit", KPC(row), KPC(lob_id)); + ObTabletID new_lob_tablet_id = ctx_->new_lob_tablet_ids_.at(cur_item->tablet_idx_); + + // fill uncommitted_tx_id for create sstable param + if (OB_SUCC(ret) && is_minor_merge(write_sstable_ctx_array_.at(i).merge_type_) && row->is_uncommitted_row()) { + ObIArray &tx_id_arr = write_sstable_ctx_array_.at(i).dst_uncommitted_tx_id_arr_; + if (OB_UNLIKELY(!row->get_trans_id().is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("uncommitted row with invalid trans id", K(ret)); + } else if (OB_UNLIKELY(cur_item->tablet_idx_ >= tx_id_arr.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("index out of range", K(ret), K(tx_id_arr), KPC(cur_item)); + } else if (0 == tx_id_arr.at(cur_item->tablet_idx_)) { + tx_id_arr.at(cur_item->tablet_idx_) = row->get_trans_id().get_id(); + } + } + + ObMacroBlockWriter *slice_writer = slice_writers.at(i, cur_item->tablet_idx_); + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(slice_writer)) { + ret = OB_ERR_NULL_VALUE; + LOG_WARN("get null macro writer ptr", K(ret), K(i), KPC(cur_item)); + } else if (OB_FAIL(slice_writer->append_row(*row))) { + LOG_WARN("append row failed", K(ret), K(new_lob_tablet_id)); + } else { + LOG_DEBUG("write one row to new lob meta tablet", K(*lob_id), K(new_lob_tablet_id)); + // reset row pos + cur_rows.at(i) = nullptr; + ctx_->row_inserted_++; + } + } else { + // check order + ObLobIdItem src_item; + src_item.id_ = *lob_id; + bool src_item_small = ObLobIdItemCompare(ret)(&src_item, cur_item); + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(src_item_small)) { + ret = OB_ROWKEY_ORDER_ERROR; + LOG_WARN("src lob meta row is smaller than current item", K(ret), K(*lob_id), KPC(cur_item), K(write_sstable_ctx_array_.at(i))); + } + } + } + } + } + + if (OB_SUCC(ret) && !hit_item) { + // set cur_item nullptr to get next map item + cur_item = nullptr; + } + } + if (ret == OB_ITER_END) { + ret = OB_SUCCESS; + } + + // check all src row iters consumed + if (OB_SUCC(ret)) { + for (int64_t i = 0; i < iters.count() && OB_SUCC(ret); i++) { + if (OB_ISNULL(cur_rows.at(i)) && !is_iter_finish.at(i)) { + const ObDatumRow *tmp_row = nullptr; + if (OB_FAIL(iters.at(i).iter_->get_next_row(tmp_row))) { + if (ret == OB_ITER_END) { + is_iter_finish.at(i) = true; + ret = OB_SUCCESS; + } else { + LOG_WARN("fail to get next row by iter", K(ret), K(i)); + } + } else { + cur_rows.at(i) = tmp_row; + } + } + if (OB_SUCC(ret) && nullptr != cur_rows.at(i)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("some lob row not dispatched", K(ret), K(i), K(cur_rows.at(i)), K(write_sstable_ctx_array_.at(i))); + } + } + } + + // close macro writers + for (int64_t i = 0; OB_SUCC(ret) && i < slice_writers.count(); i++) { + for (int64_t j = 0; OB_SUCC(ret) && j < slice_writers.count(i); j++) { + if (OB_ISNULL(slice_writers.at(i, j))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret)); + } else if (OB_FAIL(slice_writers.at(i, j)->close())) { + LOG_WARN("close macro block writer failed", K(ret)); + } + } + } + return ret; +} + +int ObTabletLobWriteDataTask::create_sstables( + ObArrayArray& index_builders, + const share::ObSplitSSTableType split_sstable_type) +{ + int ret = OB_SUCCESS; + int64_t last_minor_idx = -1; + ObFixedArray batch_sstables_handle; + batch_sstables_handle.set_allocator(&allocator_); + if (OB_FAIL(batch_sstables_handle.prepare_allocate(ctx_->new_lob_tablet_ids_.count()))) { + LOG_WARN("init failed", K(ret), K(ctx_->new_lob_tablet_ids_)); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < index_builders.count(); i++) { + ObTabletLobWriteSSTableCtx &write_sstable_ctx = write_sstable_ctx_array_.at(i); + if (is_minor_merge(write_sstable_ctx.merge_type_)) { + last_minor_idx = i; + } + } + + for (int64_t i = 0; i < index_builders.count() && OB_SUCC(ret); i++) { + for (int64_t j = 0; j < index_builders.count(i) && OB_SUCC(ret); j++) { + bool is_major_exist = false; + ObTableHandleV2 new_table_handle; + const ObTabletID &dst_tablet_id = ctx_->new_lob_tablet_ids_.at(j); + ObTabletLobWriteSSTableCtx &write_sstable_ctx = write_sstable_ctx_array_.at(i); + ObSEArray check_major_exist_tablets; + if (OB_FAIL(check_major_exist_tablets.push_back(dst_tablet_id))) { + LOG_WARN("push back failed", K(ret)); + } else if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(param_->ls_id_, check_major_exist_tablets, is_major_exist))) { + LOG_WARN("check major exist failed", K(ret), K(check_major_exist_tablets), KPC(param_)); + } else if (is_major_exist) { + FLOG_INFO("skip to create sstable", K(ret), K(dst_tablet_id)); + } else if (share::ObSplitSSTableType::SPLIT_MINOR == split_sstable_type + && !is_minor_merge(write_sstable_ctx.merge_type_)) { + LOG_DEBUG("skip this sstable", K(split_sstable_type), K(write_sstable_ctx)); + } else if (share::ObSplitSSTableType::SPLIT_MAJOR == split_sstable_type + && !is_major_merge(write_sstable_ctx.merge_type_)) { + LOG_DEBUG("skip this sstable", K(split_sstable_type), K(write_sstable_ctx)); + } else if (OB_FAIL(create_sstable(index_builders.at(i, j), + write_sstable_ctx, + j, + dst_tablet_id, + new_table_handle))) { + LOG_WARN("fail to create sstable", K(ret)); + } else if (OB_FAIL(batch_sstables_handle.at(j).add_table(new_table_handle))) { + LOG_WARN("fail to push back new sstable handle", K(ret)); + } else if (share::ObSplitSSTableType::SPLIT_MINOR == split_sstable_type + && i == last_minor_idx) { + // fill empty minor sstable if scn not contiguous + bool need_fill_empty_sstable = false; + SCN end_scn; + if (OB_FAIL(ObTabletSplitMergeTask::check_need_fill_empty_sstable(ctx_->ls_handle_, + is_minor_merge(write_sstable_ctx.merge_type_), + write_sstable_ctx.table_key_, + dst_tablet_id, + need_fill_empty_sstable, + end_scn))) { + LOG_WARN("failed to check need fill", K(ret)); + } else if (need_fill_empty_sstable) { + new_table_handle.reset(); + if (OB_FAIL(create_empty_sstable(write_sstable_ctx, dst_tablet_id, end_scn, new_table_handle))) { + LOG_WARN("failed to create empty sstable", K(ret)); + } else if (OB_FAIL(batch_sstables_handle.at(j).add_table(new_table_handle))) { + LOG_WARN("fail to push back new sstable handle", K(ret)); + } + } else { + LOG_INFO("no need fill empty sstable", K(dst_tablet_id), K(write_sstable_ctx)); + } + } + } + } + + // update tablet handle table store + for (int64_t i = 0; i < ctx_->new_lob_tablet_ids_.count() && OB_SUCC(ret); i++) { + if (batch_sstables_handle.at(i).empty()) { + FLOG_INFO("already built, skip to update table store", K(ret), "tablet_id", ctx_->new_lob_tablet_ids_.at(i)); + } else if (OB_FAIL(ObTabletSplitMergeTask::update_table_store_with_batch_tables( + ctx_->ls_handle_, + ctx_->lob_meta_tablet_handle_, + ctx_->new_lob_tablet_ids_.at(i), + batch_sstables_handle.at(i), + split_sstable_type))) { + LOG_WARN("update table store with batch tables failed", K(ret), K(batch_sstables_handle.at(i)), K(split_sstable_type)); + } + } + return ret; +} + +int ObTabletLobWriteDataTask::create_empty_sstable(const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const ObTabletID &new_tablet_id, + const SCN &end_scn, + ObTableHandleV2 &new_table_handle) +{ + int ret = OB_SUCCESS; + new_table_handle.reset(); + ObTabletCreateSSTableParam create_sstable_param; + if (OB_FAIL(ObTabletSplitMergeTask::build_create_empty_sstable_param(write_sstable_ctx.meta_, write_sstable_ctx.table_key_, new_tablet_id, end_scn, create_sstable_param))) { + LOG_WARN("failed to build create empty sstable param", K(ret)); + } else { + if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(create_sstable_param, ctx_->allocator_, new_table_handle))) { + LOG_WARN("create sstable failed", K(ret), K(create_sstable_param)); + } + } + return ret; +} + +int ObTabletLobWriteDataTask::create_sstable(ObSSTableIndexBuilder *sstable_index_builder, + const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const int64_t tablet_idx, + const ObTabletID &new_tablet_id, + ObTableHandleV2 &new_table_handle) +{ + int ret = OB_SUCCESS; + const ObITable::TableKey &table_key = write_sstable_ctx.table_key_; + const ObSSTableBasicMeta &basic_meta = write_sstable_ctx.meta_; + const compaction::ObMergeType &merge_type = write_sstable_ctx.merge_type_; + const int64_t dst_major_snapshot_version = write_sstable_ctx.dst_major_snapshot_version_; + new_table_handle.reset(); + SMART_VARS_2((ObSSTableMergeRes, res), (ObTabletCreateSSTableParam, create_sstable_param)) { + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(sstable_index_builder)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg, index builder is null", K(ret)); + } else if (!basic_meta.is_valid() || !table_key.is_valid() || !new_tablet_id.is_valid() + || tablet_idx < 0 || (is_minor_merge(write_sstable_ctx.merge_type_) && tablet_idx >= write_sstable_ctx.dst_uncommitted_tx_id_arr_.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(tablet_idx), K(write_sstable_ctx)); + } else if (OB_FAIL(sstable_index_builder->close(res))) { + LOG_WARN("close sstable index builder failed", K(ret)); + } else { + const int64_t uncommitted_tx_id = is_minor_merge(merge_type) ? write_sstable_ctx.dst_uncommitted_tx_id_arr_.at(tablet_idx) : 0; + create_sstable_param.table_key_ = table_key; + create_sstable_param.table_key_.tablet_id_ = new_tablet_id; + create_sstable_param.uncommitted_tx_id_ = uncommitted_tx_id; + create_sstable_param.schema_version_ = param_->schema_version_; + + // init from basic_meta + create_sstable_param.table_mode_ = basic_meta.table_mode_; + create_sstable_param.index_type_ = static_cast(basic_meta.index_type_); + create_sstable_param.rowkey_column_cnt_ = basic_meta.rowkey_column_count_; + + create_sstable_param.create_snapshot_version_ = is_major_merge(merge_type) ? dst_major_snapshot_version : basic_meta.create_snapshot_version_; + + create_sstable_param.sstable_logic_seq_ = 0; + create_sstable_param.filled_tx_scn_ = basic_meta.filled_tx_scn_; + create_sstable_param.latest_row_store_type_ = basic_meta.latest_row_store_type_; + create_sstable_param.recycle_version_ = basic_meta.recycle_version_; + create_sstable_param.ddl_scn_ = basic_meta.ddl_scn_; + create_sstable_param.progressive_merge_round_ = basic_meta.progressive_merge_round_; + create_sstable_param.progressive_merge_step_ = basic_meta.progressive_merge_step_; + + create_sstable_param.ddl_scn_.set_min(); + + // init from merge_res + create_sstable_param.column_cnt_ = res.data_column_cnt_; + create_sstable_param.max_merged_trans_version_ = res.max_merged_trans_version_; + create_sstable_param.nested_size_ = res.nested_size_; + create_sstable_param.nested_offset_ = res.nested_offset_; + + // ObTabletCreateSSTableParam::inner_init_with_merge_res + ObSSTableMergeRes::fill_addr_and_data(res.root_desc_, + create_sstable_param.root_block_addr_, create_sstable_param.root_block_data_); + ObSSTableMergeRes::fill_addr_and_data(res.data_root_desc_, + create_sstable_param.data_block_macro_meta_addr_, create_sstable_param.data_block_macro_meta_); + create_sstable_param.root_row_store_type_ = res.root_row_store_type_; + create_sstable_param.data_index_tree_height_ = res.root_desc_.height_; + create_sstable_param.index_blocks_cnt_ = res.index_blocks_cnt_; + create_sstable_param.data_blocks_cnt_ = res.data_blocks_cnt_; + create_sstable_param.micro_block_cnt_ = res.micro_block_cnt_; + create_sstable_param.use_old_macro_block_count_ = res.use_old_macro_block_count_; + create_sstable_param.row_count_ = res.row_count_; + create_sstable_param.data_checksum_ = res.data_checksum_; + create_sstable_param.occupy_size_ = res.occupy_size_; + create_sstable_param.original_size_ = res.original_size_; + create_sstable_param.contain_uncommitted_row_ = res.contain_uncommitted_row_; + create_sstable_param.compressor_type_ = res.compressor_type_; + create_sstable_param.encrypt_id_ = res.encrypt_id_; + create_sstable_param.master_key_id_ = res.master_key_id_; + create_sstable_param.is_meta_root_ = res.data_root_desc_.is_meta_root_; + MEMCPY(create_sstable_param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); + if (OB_FAIL(create_sstable_param.data_block_ids_.assign(res.data_block_ids_))) { + LOG_WARN("fail to fill data block ids", K(ret), K(res.data_block_ids_)); + } else if (OB_FAIL(create_sstable_param.other_block_ids_.assign(res.other_block_ids_))) { + LOG_WARN("fail to fill other block ids", K(ret), K(res.other_block_ids_)); + } + + if (OB_SUCC(ret) && table_key.is_major_sstable()) { + if (OB_FAIL(create_sstable_param.column_checksums_.assign(res.data_column_checksums_))) { + LOG_WARN("fill column checksum failed", K(ret), K(res)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(create_sstable_param, ctx_->allocator_, new_table_handle))) { + LOG_WARN("create sstable failed", K(ret), K(create_sstable_param)); + } + } + } + } + return ret; +} + +void ObTabletLobWriteDataTask::release_slice_writer(ObMacroBlockWriter *&slice_writer) +{ + if (OB_NOT_NULL(slice_writer)) { + slice_writer->~ObMacroBlockWriter(); + ctx_->allocator_.free(slice_writer); + slice_writer = nullptr; + } +} + +void ObTabletLobWriteDataTask::release_index_builder(ObSSTableIndexBuilder *&index_builder) +{ + if (nullptr != index_builder) { + index_builder->~ObSSTableIndexBuilder(); + ctx_->allocator_.free(index_builder); + index_builder = nullptr; + } +} + +void ObTabletLobWriteDataTask::release_sstable_writers_and_builders( + ObArrayArray& slice_writers, + ObArrayArray& index_builders) +{ + for (int64_t i = 0; i < slice_writers.count(); i++) { + for (int64_t j = 0; j < slice_writers.count(i); j++) { + release_slice_writer(slice_writers.at(i, j)); + } + } + slice_writers.reset(); + for (int64_t i = 0; i < index_builders.count(); i++) { + for (int64_t j = 0; j < index_builders.count(i); j++) { + release_index_builder(index_builders.at(i, j)); + } + } + index_builders.reset(); +} + +/*****************************ObTabletLobWriteDataTask END****************************************/ + +int ObTabletLobSplitUtil::open_rowscan_iters(const share::ObSplitSSTableType &split_sstable_type, + ObIAllocator &allocator, + int64_t table_id, + const ObTabletHandle &tablet_handle, + const ObTableStoreIterator &const_iterator, + const ObDatumRange &query_range, + ObIArray& iters) +{ + int ret = OB_SUCCESS; + ObTableStoreIterator iterator; + ObTablet *tablet = nullptr; + if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpecter error", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(tablet_handle)); + } else if (OB_FAIL(iterator.assign(const_iterator))) { + LOG_WARN("failed to assign iterator", K(ret)); + } else { + ObITable *table = nullptr; + while (OB_SUCC(ret)) { + if (OB_FAIL(iterator.get_next(table))) { + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next tables", K(ret)); + } + } else if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must not be null", K(ret), K(iterator)); + } else if (!table->is_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must be sstable", K(ret), KPC(table), K(iterator)); + } else if (share::ObSplitSSTableType::SPLIT_MAJOR == split_sstable_type + && table->is_minor_sstable()) { + LOG_DEBUG("ignore to build the minor", KPC(table)); + } else if (share::ObSplitSSTableType::SPLIT_MINOR == split_sstable_type + && table->is_major_sstable()) { + LOG_DEBUG("ignore to build the major", KPC(table)); + } else if (table->is_mds_sstable()) { + LOG_DEBUG("ignore to build mds sstable", KPC(table)); + } else { + LOG_INFO("open one sstable rowscan", KPC(table)); + ObSSTable *sst = static_cast(table); + // preprare row scan iter + if (OB_SUCC(ret)) { + ObSplitScanParam scan_param(table_id, *tablet, query_range); + ObRowScan *new_scanner = nullptr; + void* buff = allocator.alloc(sizeof(ObRowScan)); + if (OB_ISNULL(buff)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc row scan", K(ret)); + } else if (FALSE_IT(new_scanner = new(buff)ObRowScan())) { + } else if (OB_FAIL(new_scanner->init(scan_param, *sst))) { + LOG_WARN("fail to init row scanner", K(ret)); + } else if (OB_FAIL(iters.push_back(new_scanner))) { + LOG_WARN("fail to push back new row scanner", K(ret)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(new_scanner)) { + new_scanner->~ObRowScan(); + allocator.free(new_scanner); + } + } + } + } + if (ret == OB_ITER_END) { + ret = OB_SUCCESS; + } + } + return ret; +} + +int ObTabletLobSplitUtil::open_uncommitted_scan_iters(ObLobSplitParam *param, + ObLobSplitContext *ctx, + int64_t table_id, + const ObTabletHandle &tablet_handle, + const ObTableStoreIterator &const_table_iter, + const ObDatumRange &query_range, + const int64_t major_snapshot_version, + ObIArray &iters, + ObIArray &write_sstable_ctx_array) +{ + int ret = OB_SUCCESS; + ObTableStoreIterator table_iter; + ObTablet *tablet = nullptr; + if (OB_ISNULL(param) || OB_ISNULL(ctx)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("null param or null ctx", K(ret), K(param), K(ctx)); + } else if (!param->is_valid() || !ctx->is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid split param", K(ret), K(*param), K(*ctx)); + } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpecter error", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(tablet_handle)); + } else if (OB_FAIL(table_iter.assign(const_table_iter))) { + LOG_WARN("failed to assign iterator", K(ret)); + } else { + ObITable *table = nullptr; + while (OB_SUCC(ret)) { + if (OB_FAIL(table_iter.get_next(table))) { + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next tables", K(ret)); + } + } else if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must not be null", K(ret), K(table_iter)); + } else if (!table->is_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must be sstable", K(ret), KPC(table), K(table_iter)); + } else if (table->is_minor_sstable()) { + LOG_INFO("open one sstable rowscan", KPC(table)); + ObTabletLobWriteSSTableCtx write_sstable_ctx; + ObSSTable *sst = static_cast(table); + if (OB_FAIL(write_sstable_ctx.init(*sst, major_snapshot_version))) { + LOG_WARN("init write sstable ctx failed", K(ret)); + } else if (OB_FAIL(write_sstable_ctx.dst_uncommitted_tx_id_arr_.prepare_allocate(ctx->new_lob_tablet_ids_.count(), 0))) { + LOG_WARN("failed to prepare allocate", K(ret), K(ctx->new_lob_tablet_ids_)); + } else if (OB_FAIL(write_sstable_ctx_array.push_back(write_sstable_ctx))) { + LOG_WARN("push back write sstable ctx failed", K(ret)); + } else { + ObSplitScanParam scan_param(table_id, *tablet, query_range); + ObUncommittedRowScan *new_scanner = nullptr; + void *buff = ctx->allocator_.alloc(sizeof(ObUncommittedRowScan)); + if (OB_ISNULL(buff)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc row scan", K(ret)); + } else if (FALSE_IT(new_scanner = new(buff)ObUncommittedRowScan())) { + } else if (OB_FAIL(new_scanner->init(scan_param, *sst, major_snapshot_version))) { + LOG_WARN("fail to init row scanner", K(ret)); + } else if (OB_FAIL(iters.push_back(ObIStoreRowIteratorPtr(new_scanner)))) { + LOG_WARN("fail to push back new row scanner", K(ret)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(new_scanner)) { + new_scanner->~ObUncommittedRowScan(); + ctx->allocator_.free(new_scanner); + } + } + } + } + if (ret == OB_ITER_END) { + ret = OB_SUCCESS; + } + } + return ret; +} + +int ObTabletLobSplitUtil::open_snapshot_scan_iters(ObLobSplitParam *param, + ObLobSplitContext *ctx, + int64_t table_id, + const ObTabletHandle &tablet_handle, + const ObTableStoreIterator &const_table_iter, + const ObDatumRange &query_range, + const int64_t major_snapshot_version, + ObIArray &iters, + ObIArray &write_sstable_ctx_array) +{ + int ret = OB_SUCCESS; + ObTableStoreIterator table_iter; + ObTableHandleV2 last_major_table_handle; + ObTablet *tablet = nullptr; + if (OB_ISNULL(param) || OB_ISNULL(ctx)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("null param or null ctx", K(ret), K(param), K(ctx)); + } else if (!param->is_valid() || !ctx->is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid split param", K(ret), K(*param), K(*ctx)); + } else if (OB_UNLIKELY(!tablet_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpecter error", K(ret), K(tablet_handle)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet is null", K(ret), K(tablet_handle)); + } else if (OB_FAIL(table_iter.assign(const_table_iter))) { + LOG_WARN("failed to assign iterator", K(ret)); + } else { + ObTableHandleV2 table_handle; + ObITable *table = nullptr; + while (OB_SUCC(ret)) { + if (OB_FAIL(table_iter.get_next(table_handle))) { + if (OB_ITER_END != ret) { + LOG_WARN("failed to get next tables", K(ret)); + } + } else if (OB_UNLIKELY(!table_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must not be null", K(ret), K(table_handle), K(table_iter)); + } else if (OB_FALSE_IT(table = table_handle.get_table())) { + } else if (!table->is_sstable()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table must be sstable", K(ret), KPC(table), K(table_iter)); + } else if (table->is_major_sstable()) { + if (!last_major_table_handle.is_valid() || table->get_snapshot_version() > last_major_table_handle.get_table()->get_snapshot_version()) { + last_major_table_handle = table_handle; + } + } + } + if (ret == OB_ITER_END) { + ret = OB_SUCCESS; + } + } + + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(!last_major_table_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid last major table", K(ret), K(last_major_table_handle), K(table_iter)); + } else { + HEAP_VAR(ObTableSchema, aux_lob_meta_schema) { + LOG_INFO("open one sstable rowscan", K(last_major_table_handle)); + const bool is_oracle_mode = lib::Worker::CompatMode::ORACLE == param->compat_mode_; + ObArray col_descs; + ObTabletLobWriteSSTableCtx write_sstable_ctx; + ObSSTable *sst = static_cast(last_major_table_handle.get_table()); + if (OB_FAIL(write_sstable_ctx.init(*sst, major_snapshot_version))) { + LOG_WARN("init write sstable ctx failed", K(ret)); + } else if (OB_FAIL(write_sstable_ctx_array.push_back(write_sstable_ctx))) { + LOG_WARN("push back write sstable ctx failed", K(ret)); + } else if (OB_FAIL(ObInnerTableSchema::all_column_aux_lob_meta_schema(aux_lob_meta_schema))) { + LOG_WARN("get lob meta schema failed", K(ret)); + } else if (OB_FAIL(aux_lob_meta_schema.get_store_column_ids(col_descs))) { + LOG_WARN("failed to get store column ids", K(ret)); + } else { + ObSplitScanParam scan_param(table_id, *tablet, query_range); + ObSnapshotRowScan *new_scanner = nullptr; + void *buff = ctx->allocator_.alloc(sizeof(ObSnapshotRowScan)); + if (OB_ISNULL(buff)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc row scan", K(ret)); + } else if (FALSE_IT(new_scanner = new(buff)ObSnapshotRowScan())) { + } else if (OB_FAIL(new_scanner->init(scan_param, + col_descs, + aux_lob_meta_schema.get_column_count(), + aux_lob_meta_schema.get_rowkey_column_num(), + is_oracle_mode, + tablet_handle, + major_snapshot_version))) { + LOG_WARN("fail to init row scanner", K(ret)); + } else if (OB_FAIL(iters.push_back(ObIStoreRowIteratorPtr(new_scanner)))) { + LOG_WARN("fail to push back new row scanner", K(ret)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(new_scanner)) { + new_scanner->~ObSnapshotRowScan(); + ctx->allocator_.free(new_scanner); + } + } + } + } + return ret; +} + + +int ObTabletLobSplitUtil::generate_col_param(const ObMergeSchema *schema, + int64_t& rk_cnt) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("schema is null", K(ret)); + } else { + rk_cnt = schema->get_rowkey_column_num(); + } + return ret; +} + +int ObTabletLobSplitUtil::process_write_split_start_log_request( + const ObTabletSplitArg &arg) +{ + int ret = OB_SUCCESS; + ObLobSplitParam lob_split_param; + ObTabletSplitParam data_split_param; + const share::ObLSID &ls_id = arg.ls_id_; + const bool is_start_request = true; + const bool is_lob_tablet = arg.lob_col_idxs_.count() > 0; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else if (is_lob_tablet) { + if (OB_FAIL(lob_split_param.init(arg))) { + LOG_WARN("init param failed", K(ret)); + } else if (OB_FAIL(ObTabletLobSplitUtil::write_split_log(is_lob_tablet, is_start_request, ls_id, &lob_split_param))) { + LOG_WARN("write split log failed", K(ret)); + } + } else { + if (OB_FAIL(data_split_param.init(arg))) { + LOG_WARN("init param failed", K(ret)); + } else if (OB_FAIL(ObTabletLobSplitUtil::write_split_log(is_lob_tablet, is_start_request, ls_id, &data_split_param))) { + LOG_WARN("write split log failed", K(ret)); + } + } + LOG_INFO("write tablet split log finish", K(ret), K(is_lob_tablet), K(lob_split_param), K(data_split_param)); + return ret; +} + + +int ObTabletLobSplitUtil::process_tablet_split_request( + const bool is_lob_tablet, + const bool is_start_request, + const void *request_arg, + void *request_res) +{ + int ret = OB_SUCCESS; + share::ObLSID ls_id; + ObLobSplitParam lob_split_param; + ObTabletSplitParam data_split_param; + share::ObIDagInitParam *dag_param = nullptr; + + ObIDag *stored_dag = nullptr; + ObTabletLobSplitDag *lob_split_dag = nullptr; + ObTabletSplitDag *data_split_dag = nullptr; + if (OB_UNLIKELY(nullptr == request_arg || nullptr == request_res)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KP(request_arg), KP(request_res)); + } else if (is_lob_tablet) { + if (is_start_request && OB_FAIL(lob_split_param.init(*static_cast(request_arg)))) { + LOG_WARN("init param failed", K(ret)); + } else if (!is_start_request && OB_FAIL(lob_split_param.init(*static_cast(request_arg)))) { + LOG_WARN("init param failed", K(ret)); + } else if (OB_FAIL(compaction::ObScheduleDagFunc::schedule_and_get_lob_tablet_split_dag(lob_split_param, lob_split_dag))) { + LOG_WARN("failed to schedule dag", K(ret)); + } + ls_id = lob_split_param.ls_id_; + dag_param = &lob_split_param; + stored_dag = lob_split_dag; + } else { + // data tablet, index tablet. + if (is_start_request && OB_FAIL(data_split_param.init(*static_cast(request_arg)))) { + LOG_WARN("init param failed", K(ret)); + } else if (!is_start_request && OB_FAIL(data_split_param.init(*static_cast(request_arg)))) { + LOG_WARN("init param failed", K(ret)); + } else if (OB_FAIL(compaction::ObScheduleDagFunc::schedule_and_get_tablet_split_dag(data_split_param, data_split_dag))) { + LOG_WARN("failed to schedule dag", K(ret)); + } + ls_id = data_split_param.ls_id_; + dag_param = &data_split_param; + stored_dag = data_split_dag; + } + + if (OB_SUCC(ret) && !is_start_request) { + if (OB_FAIL(ObTabletLobSplitUtil::write_split_log(is_lob_tablet, is_start_request, ls_id, dag_param))) { + LOG_WARN("write split log failed", K(ret)); + } + } + + if (OB_SUCC(ret)) { + // try add dag, and get progress. + // FIXME (YIREN), to return progress. + int64_t unused_row_inserted = 0; + int64_t unused_phy_row_cnt = 0; + int64_t &row_inserted = is_start_request ? + static_cast(request_res)->row_inserted_ : unused_row_inserted; + int64_t &physical_row_count = is_start_request ? + static_cast(request_res)->physical_row_count_ : unused_phy_row_cnt; + if (is_lob_tablet) { + if (OB_FAIL(add_dag_and_get_progress(lob_split_dag, row_inserted, physical_row_count))) { + if (OB_EAGAIN == ret) { // dag exists. + ret = OB_SUCCESS; + } else if (OB_SIZE_OVERFLOW == ret) { // add dag failed. + ret = OB_EAGAIN; + } else { + LOG_WARN("add dag and get progress failed", K(ret)); + } + } else { + stored_dag = nullptr; // to avoid free. + } + } else { + if (OB_FAIL(add_dag_and_get_progress(data_split_dag, row_inserted, physical_row_count))) { + if (OB_EAGAIN == ret) { + ret = OB_SUCCESS; + } else if (OB_SIZE_OVERFLOW == ret) { + ret = OB_EAGAIN; + } else { + LOG_WARN("add dag and get progress failed", K(ret)); + } + } else { + stored_dag = nullptr; // to avoid free. + } + } + } + + if (OB_NOT_NULL(stored_dag)) { + // to free dag. + MTL(ObTenantDagScheduler*)->free_dag(*stored_dag); + stored_dag = nullptr; + } + LOG_INFO("process tablet split request finish", K(ret), K(is_start_request), K(is_lob_tablet), K(lob_split_param), K(data_split_param), + K(data_split_dag), K(lob_split_dag)); + return ret; +} + +int ObTabletLobSplitUtil::write_split_log( + const bool is_lob_tablet, + const bool is_start_request, + const share::ObLSID &ls_id, + const share::ObIDagInitParam *input_param) +{ + int ret = OB_SUCCESS; + ObTabletSplitStartLog split_start_log; + ObTabletSplitFinishLog split_finish_log; + ObTabletSplitInfo &split_info = is_start_request ? split_start_log.basic_info_ : split_finish_log.basic_info_; + if (OB_UNLIKELY(!ls_id.is_valid() || nullptr == input_param)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(ls_id), KP(input_param)); + } else if (is_lob_tablet) { + const ObLobSplitParam *param = static_cast(input_param); + if (OB_UNLIKELY(!param->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KPC(param)); + } else { + split_info.table_id_ = param->source_table_id_; // rely on it to scan data table rows. + split_info.lob_table_id_ = param->dest_schema_id_; + split_info.schema_version_ = param->schema_version_; + split_info.task_id_ = param->task_id_; + split_info.source_tablet_id_ = param->ori_lob_meta_tablet_id_; + split_info.compaction_scn_ = param->compaction_scn_; + split_info.data_format_version_ = param->data_format_version_; + split_info.consumer_group_id_ = param->consumer_group_id_; + split_info.can_reuse_macro_block_ = false; + split_info.split_sstable_type_ = param->split_sstable_type_; + if (OB_FAIL(split_info.lob_col_idxs_.assign(param->lob_col_idxs_))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(split_info.parallel_datum_rowkey_list_.assign(param->parallel_datum_rowkey_list_))) { + LOG_WARN("assign failed", K(ret), KPC(param)); + } else if (OB_FAIL(split_info.dest_tablets_id_.assign(param->new_lob_tablet_ids_))) { + LOG_WARN("assign failed", K(ret), KPC(param)); + } + } + } else { + const ObTabletSplitParam *param = static_cast(input_param); + if (OB_UNLIKELY(!param->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KPC(param)); + } else { + split_info.table_id_ = param->table_id_; + split_info.lob_table_id_ = OB_INVALID_ID; + split_info.schema_version_ = param->schema_version_; + split_info.task_id_ = param->task_id_; + split_info.source_tablet_id_ = param->source_tablet_id_; + split_info.compaction_scn_ = param->compaction_scn_; + split_info.data_format_version_ = param->data_format_version_; + split_info.consumer_group_id_ = param->consumer_group_id_; + split_info.can_reuse_macro_block_ = param->can_reuse_macro_block_; + split_info.split_sstable_type_ = param->split_sstable_type_; + // skip lob col idxs. + if (OB_FAIL(split_info.parallel_datum_rowkey_list_.assign(param->parallel_datum_rowkey_list_))) { + LOG_WARN("assign failed", K(ret), KPC(param)); + } else if (OB_FAIL(split_info.dest_tablets_id_.assign(param->dest_tablets_id_))) { + LOG_WARN("assign failed", K(ret), KPC(param)); + } + } + } + + if (OB_SUCC(ret)) { + if (is_start_request) { + if (OB_FAIL(ObDDLRedoLogWriter::write_auto_split_log( + ls_id, ObDDLClogType::DDL_TABLET_SPLIT_START_LOG, + logservice::ObReplayBarrierType::PRE_BARRIER, split_start_log))) { + LOG_WARN("write tablet split start log failed", K(ret), K(split_start_log)); + } + } else { + if (OB_FAIL(ObDDLRedoLogWriter::write_auto_split_log( + ls_id, ObDDLClogType::DDL_TABLET_SPLIT_FINISH_LOG, + logservice::ObReplayBarrierType::STRICT_BARRIER, split_finish_log))) { + LOG_WARN("write tablet split finish log failed", K(ret), K(split_finish_log)); + } + } + LOG_INFO("write split log finish", K(ret), K(is_start_request), K(is_lob_tablet), K(split_start_log), K(split_finish_log)); + } + return ret; +} + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/ddl/ob_tablet_lob_split_task.h b/src/storage/ddl/ob_tablet_lob_split_task.h new file mode 100644 index 000000000..e70501014 --- /dev/null +++ b/src/storage/ddl/ob_tablet_lob_split_task.h @@ -0,0 +1,411 @@ +/** + * 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 STORAGE_AUTO_SPLIT_OB_TABLET_LOB_SPLIT_TASK_H_ +#define STORAGE_AUTO_SPLIT_OB_TABLET_LOB_SPLIT_TASK_H_ + +#include "share/scheduler/ob_tenant_dag_scheduler.h" +#include "storage/ob_i_table.h" +#include "storage/ob_parallel_external_sort.h" +#include "storage/ddl/ob_complement_data_task.h" +#include "storage/ddl/ob_tablet_split_task.h" + +namespace oceanbase +{ + +namespace storage +{ + +struct ObIStoreRowIteratorPtr +{ +public: + ObIStoreRowIteratorPtr() : iter_(nullptr) {} + ObIStoreRowIteratorPtr(ObIStoreRowIterator *iter) : iter_(iter) {} + ~ObIStoreRowIteratorPtr() = default; + TO_STRING_KV(KP_(iter)); +public: + ObIStoreRowIterator *iter_; +}; + +struct ObLobIdItem final +{ +public: + ObLobIdItem() : id_(), tablet_idx_(-1) {} + ~ObLobIdItem() {} + int cmp(const ObLobIdItem& other) const + { + return MEMCMP(&id_, &other.id_, sizeof(ObLobId)); + } + int64_t get_deep_copy_size() const + { + return 0; + } + int deep_copy(const ObLobIdItem &src, char *buf, int64_t len, int64_t &pos) + { + UNUSED(buf); + UNUSED(len); + UNUSED(pos); + id_ = src.id_; + tablet_idx_ = src.tablet_idx_; + return OB_SUCCESS; + } + bool is_valid() const { return id_.is_valid() && tablet_idx_ >= 0; } + void reset() { + id_.reset(); + tablet_idx_ = -1L; + } + TO_STRING_KV(K_(id), K_(tablet_idx)); + NEED_SERIALIZE_AND_DESERIALIZE; +public: + ObLobId id_; + int64_t tablet_idx_; +}; + +class ObLobIdItemCompare +{ +public: + ObLobIdItemCompare(int &sort_ret) : result_code_(sort_ret) {} + bool operator()(const ObLobIdItem *left, const ObLobIdItem *right); +public: + int &result_code_; +}; + +typedef ObExternalSort ObLobIdMap; + +struct ObLobSplitParam : public share::ObIDagInitParam +{ +public: + ObLobSplitParam() : + rowkey_allocator_("LobSplitRowkey", OB_MALLOC_NORMAL_BLOCK_SIZE /*8KB*/, MTL_ID()), + tenant_id_(common::OB_INVALID_TENANT_ID), ls_id_(share::ObLSID::INVALID_LS_ID), + ori_lob_meta_tablet_id_(ObTabletID::INVALID_TABLET_ID), + new_lob_tablet_ids_(), schema_version_(0), + data_format_version_(0), parallelism_(0), compaction_scn_(), + compat_mode_(lib::Worker::CompatMode::INVALID), task_id_(0), + source_table_id_(OB_INVALID_ID), dest_schema_id_(OB_INVALID_ID), consumer_group_id_(0), + lob_col_idxs_(), split_sstable_type_(share::ObSplitSSTableType::SPLIT_BOTH) + {} + virtual ~ObLobSplitParam(); + int init(const ObLobSplitParam &other); + int init(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg); + int init(const obrpc::ObTabletSplitArg &arg); + bool is_valid() const { + return OB_INVALID_ID != tenant_id_ && ls_id_.is_valid() && ori_lob_meta_tablet_id_.is_valid() + && new_lob_tablet_ids_.count() > 0 && schema_version_ > 0 + && data_format_version_ > 0 && parallelism_ > 0 && compaction_scn_ > 0 + && compat_mode_ != lib::Worker::CompatMode::INVALID + && task_id_ > 0 && OB_INVALID_ID != source_table_id_ && OB_INVALID_ID != dest_schema_id_ + && consumer_group_id_ >= 0 && lob_col_idxs_.count() > 0 && parallel_datum_rowkey_list_.count() > 0; + } + int assign(const ObLobSplitParam &other); + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(ori_lob_meta_tablet_id), + K_(new_lob_tablet_ids), K_(schema_version), K_(data_format_version), + K_(parallelism), K_(compaction_scn), K_(compat_mode), K_(task_id), + K_(source_table_id), K_(dest_schema_id), K_(lob_col_idxs), K_(consumer_group_id), + K_(lob_col_idxs), K_(split_sstable_type), K_(parallel_datum_rowkey_list)); +private: + common::ObArenaAllocator rowkey_allocator_; // for DatumRowkey. +public: + uint64_t tenant_id_; + share::ObLSID ls_id_; + ObTabletID ori_lob_meta_tablet_id_; + ObArray new_lob_tablet_ids_; + int64_t schema_version_; + int64_t data_format_version_; + int64_t parallelism_; // dop + int64_t compaction_scn_; + lib::Worker::CompatMode compat_mode_; + int64_t task_id_; + int64_t source_table_id_; // src_main_table_id + int64_t dest_schema_id_; // src_lob_meta_table_id + uint64_t consumer_group_id_; + ObSArray lob_col_idxs_; + share::ObSplitSSTableType split_sstable_type_; + common::ObSArray parallel_datum_rowkey_list_; // calc by main table. +}; + +struct ObLobSplitContext final +{ +public: + ObLobSplitContext() : + range_allocator_("LobSplitRange", OB_MALLOC_NORMAL_BLOCK_SIZE /*8KB*/, MTL_ID()), + is_inited_(false), data_ret_(0), is_lob_piece_(false), + ls_handle_(), main_tablet_id_(ObTabletID::INVALID_TABLET_ID), + allocator_(common::ObModIds::OB_LOB_ACCESS_BUFFER, OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()), + main_tablet_handle_(), lob_meta_tablet_handle_(), + m_allocator_(allocator_), new_main_tablet_ids_(OB_MALLOC_NORMAL_BLOCK_SIZE, m_allocator_), + new_lob_tablet_ids_(OB_MALLOC_NORMAL_BLOCK_SIZE, m_allocator_), + cmp_ret_(0), comparer_(cmp_ret_), total_map_(nullptr), sub_maps_(), + row_inserted_(0), physical_row_count_(0) + {} + ~ObLobSplitContext() { destroy(); } + int init(const ObLobSplitParam& param); + int get_dst_lob_tablet_ids(const ObLobSplitParam& param); + int init_maps(const ObLobSplitParam& param); + inline bool is_valid() const { return is_inited_; } + void destroy(); + TO_STRING_KV(K_(is_inited), K_(data_ret), K_(is_lob_piece), + K_(ls_handle), K_(main_tablet_id), K_(main_tablet_handle), + K_(lob_meta_tablet_handle), K_(new_main_tablet_ids), + K_(new_lob_tablet_ids), KPC_(total_map), K_(sub_maps), K_(main_table_ranges), K_(row_inserted), K_(physical_row_count)); +private: + common::ObArenaAllocator range_allocator_; // for datum range. +public: + static const int64_t EACH_SORT_MEMORY_LIMIT = 8L * 1024L * 1024L; // 8MB + bool is_inited_; + int data_ret_; + bool is_lob_piece_; + ObLSHandle ls_handle_; + ObTabletID main_tablet_id_; + common::ObArenaAllocator allocator_; + ObTabletHandle main_tablet_handle_; + ObTabletHandle lob_meta_tablet_handle_; + ObTableStoreIterator main_table_store_iterator_; + ObTableStoreIterator lob_meta_table_store_iterator_; + common::ModulePageAllocator m_allocator_; + ObArray new_main_tablet_ids_; + ObArray new_lob_tablet_ids_; + int cmp_ret_; + ObLobIdItemCompare comparer_; + ObLobIdMap* total_map_; + ObArray sub_maps_; + ObSEArray main_table_ranges_; + int64_t row_inserted_; + int64_t physical_row_count_; +}; + + +class ObTabletLobSplitDag final : public share::ObIDag +{ +public: + ObTabletLobSplitDag(); + virtual ~ObTabletLobSplitDag(); + virtual int init_by_param(const share::ObIDagInitParam *param) override; + int64_t hash() const; + bool operator ==(const share::ObIDag &other) const; + bool is_inited() const { return is_inited_; } + ObLobSplitParam &get_param() { return param_; } + ObLobSplitContext &get_context() { return context_; } + void handle_init_failed_ret_code(int ret) { context_.data_ret_ = ret; } + int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; + int fill_dag_key(char *buf, const int64_t buf_len) const override; + virtual lib::Worker::CompatMode get_compat_mode() const override + { return param_.compat_mode_; } + virtual uint64_t get_consumer_group_id() const override + { return consumer_group_id_; } + virtual int create_first_task() override; + virtual bool ignore_warning() override; + virtual bool is_ha_dag() const override { return false; } + // report lob tablet split status to RS. + int report_lob_split_status(); + int calc_total_row_count(); +private: + bool is_inited_; + ObLobSplitParam param_; + ObLobSplitContext context_; + DISALLOW_COPY_AND_ASSIGN(ObTabletLobSplitDag); +}; + + +class ObTabletLobBuildMapTask : public share::ObITask +{ +public: + ObTabletLobBuildMapTask(); + virtual ~ObTabletLobBuildMapTask(); + int init(const int64_t task_id, ObLobSplitParam ¶m, ObLobSplitContext &ctx); + virtual int process() override; +private: + // int prepare_context(); + int generate_next_task(ObITask *&next_task); + int build_sorted_map(ObIArray& iters); +private: + bool is_inited_; + int64_t task_id_; + int64_t rk_cnt_; + ObLobSplitParam *param_; + ObLobSplitContext *ctx_; + common::ObArenaAllocator allocator_; +}; + +class ObTabletLobMergeMapTask : public share::ObITask +{ +public: + ObTabletLobMergeMapTask(); + virtual ~ObTabletLobMergeMapTask(); + int init(ObLobSplitParam ¶m, ObLobSplitContext &ctx); + virtual int process() override; +private: + static const int64_t SORT_MEMORY_LIMIT = 32L * 1024L * 1024L; + bool is_inited_; + ObLobSplitParam *param_; + ObLobSplitContext *ctx_; +}; + +struct ObTabletLobWriteSSTableCtx final +{ +public: + ObTabletLobWriteSSTableCtx(); + ~ObTabletLobWriteSSTableCtx(); + int init(const ObSSTable &org_sstable, const int64_t major_snapshot_version); + int assign(const ObTabletLobWriteSSTableCtx &other); + int64_t get_version() const { return table_key_.is_major_sstable() ? dst_major_snapshot_version_ : table_key_.get_end_scn().get_val_for_tx(); } + bool is_valid() const { return table_key_.is_valid() && data_seq_ > -1 && meta_.is_valid() && dst_major_snapshot_version_ >= 0; } + TO_STRING_KV(K_(table_key), K_(data_seq), K_(merge_type), K_(meta), K_(dst_uncommitted_tx_id_arr), K_(dst_major_snapshot_version)); +public: + ObITable::TableKey table_key_; + int64_t data_seq_; + compaction::ObMergeType merge_type_; + ObSSTableBasicMeta meta_; // for major split, it's src lob tablet's last major sstable's meta + ObArray dst_uncommitted_tx_id_arr_; // first uncommitted row's tx id for each split dst minor sstable + int64_t dst_major_snapshot_version_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletLobWriteSSTableCtx); +}; + +class ObTabletLobWriteDataTask : public share::ObITask +{ +public: + ObTabletLobWriteDataTask(); + virtual ~ObTabletLobWriteDataTask(); + int init(const int64_t task_id, ObLobSplitParam ¶m, ObLobSplitContext &ctx); + virtual int process() override; +private: + int generate_next_task(ObITask *&next_task); + int prepare_sstable_writers_and_builders(const ObStorageSchema &storage_schema, + ObArrayArray& data_desc_arr, + ObArrayArray& slice_writers, + ObArrayArray& index_builders); + int prepare_sstable_writer(const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const ObTabletID &new_tablet_id, + const ObStorageSchema &storage_schema, + ObWholeDataStoreDesc &data_desc, + ObMacroBlockWriter *&slice_writer, + ObSSTableIndexBuilder *&index_builder); + int prepare_sstable_macro_writer(const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const ObTabletID &new_tablet_id, + const ObStorageSchema &storage_schema, + ObWholeDataStoreDesc &data_desc, + ObSSTableIndexBuilder *index_builder, + ObMacroBlockWriter *&slice_writer); + int prepare_sstable_index_builder(const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const ObTabletID &new_tablet_id, + const ObStorageSchema &storage_schema, + ObSSTableIndexBuilder *&index_builder); + int dispatch_rows(ObIArray& iters, + ObArrayArray& slice_writers); + int create_sstables(ObArrayArray& index_builders, + const share::ObSplitSSTableType split_sstable_type); + int create_empty_sstable(const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const ObTabletID &new_tablet_id, + const share::SCN &end_scn, + ObTableHandleV2 &new_table_handle); + int create_sstable(ObSSTableIndexBuilder *sstable_index_builder, + const ObTabletLobWriteSSTableCtx &write_sstable_ctx, + const int64_t tablet_idx, + const ObTabletID &new_tablet_id, + ObTableHandleV2 &new_table_handle); + void release_slice_writer(ObMacroBlockWriter *&slice_writer); + void release_index_builder(ObSSTableIndexBuilder *&index_builder); + void release_sstable_writers_and_builders(ObArrayArray& slice_writers, + ObArrayArray& index_builders); +private: + common::ObArenaAllocator allocator_; + bool is_inited_; + int64_t task_id_; + int64_t rk_cnt_; + ObArray write_sstable_ctx_array_; + ObLobSplitParam *param_; + ObLobSplitContext *ctx_; +}; + +class ObTabletLobSplitUtil final +{ +public: + static int open_rowscan_iters(const share::ObSplitSSTableType &split_sstable_type, + ObIAllocator &allocator, + int64_t table_id, + const ObTabletHandle &tablet_handle, + const ObTableStoreIterator &table_store_iterator, + const ObDatumRange &query_range, + ObIArray &iters); + static int open_uncommitted_scan_iters(ObLobSplitParam *param, + ObLobSplitContext *ctx, + int64_t table_id, + const ObTabletHandle &tablet_handle, + const ObTableStoreIterator &table_iter, + const ObDatumRange &query_range, + const int64_t major_snapshot_version, + ObIArray &iters, + ObIArray &write_sstable_ctx_array); + static int open_snapshot_scan_iters(ObLobSplitParam *param, + ObLobSplitContext *ctx, + int64_t table_id, + const ObTabletHandle &tablet_handle, + const ObTableStoreIterator &table_iter, + const ObDatumRange &query_range, + const int64_t major_snapshot_version, + ObIArray &iters, + ObIArray &write_sstable_ctx_array); + static int generate_col_param(const ObMergeSchema *schema, + int64_t& rk_cnt); + + static int process_write_split_start_log_request( + const ObTabletSplitArg &arg); + static int process_tablet_split_request( + const bool is_lob_tablet, + const bool is_start_request, + const void *request_arg, + void *request_res); + static int write_split_log( + const bool is_lob_tablet, + const bool is_start_request, + const share::ObLSID &ls_id, + const share::ObIDagInitParam *input_param); +}; + +class ObSingleRowIterWrapper: public ObIStoreRowIterator +{ +public: + ObSingleRowIterWrapper() : row_(nullptr), iter_end_(false) {} + ObSingleRowIterWrapper(const blocksstable::ObDatumRow *row) : row_(row), iter_end_(false) {} + virtual ~ObSingleRowIterWrapper() {} + + void set_row(const blocksstable::ObDatumRow *row) { row_ = row; } + virtual int get_next_row(const blocksstable::ObDatumRow *&row); + virtual void reset() { iter_end_ = false; } +private: + // disallow copy + DISALLOW_COPY_AND_ASSIGN(ObSingleRowIterWrapper); +private: + // data members + const blocksstable::ObDatumRow *row_; + bool iter_end_; +}; + +inline int ObSingleRowIterWrapper::get_next_row(const blocksstable::ObDatumRow *&row) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(row_)) { + ret = OB_NOT_INIT; + } else if (iter_end_) { + ret = OB_ITER_END; + } else { + row = row_; + iter_end_ = true; + } + return ret; +} + +} // namespace storage +} // namespace oceanbase + +#endif diff --git a/src/storage/ddl/ob_tablet_split_task.cpp b/src/storage/ddl/ob_tablet_split_task.cpp new file mode 100644 index 000000000..ebaef8e00 --- /dev/null +++ b/src/storage/ddl/ob_tablet_split_task.cpp @@ -0,0 +1,2503 @@ +/** + * 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_tablet_split_task.h" +#include "logservice/ob_log_service.h" +#include "share/ob_ddl_common.h" +#include "share/scn.h" +#include "storage/ob_i_store.h" +#include "storage/ob_partition_range_spliter.h" +#include "storage/ddl/ob_ddl_merge_task.h" +#include "storage/ddl/ob_ddl_clog.h" +#include "storage/tablet/ob_tablet_create_sstable_param.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/tablet/ob_tablet_split_mds_helper.h" +#include "share/scheduler/ob_dag_warning_history_mgr.h" + +namespace oceanbase +{ +using namespace common; +using namespace storage; +using namespace compaction; +using namespace share; +using namespace share::schema; +using namespace blocksstable; + +namespace storage +{ + +ObTabletSplitParam::ObTabletSplitParam() + : rowkey_allocator_("SplitRangePar", OB_MALLOC_NORMAL_BLOCK_SIZE /*8KB*/, MTL_ID()), + is_inited_(false), + tenant_id_(OB_INVALID_ID), ls_id_(), table_id_(OB_INVALID_ID), + schema_version_(0), task_id_(0), source_tablet_id_(), + dest_tablets_id_(), compaction_scn_(0), user_parallelism_(0), + compat_mode_(lib::Worker::CompatMode::INVALID), data_format_version_(0), consumer_group_id_(0), + can_reuse_macro_block_(false), split_sstable_type_(share::ObSplitSSTableType::SPLIT_BOTH), + parallel_datum_rowkey_list_() +{ +} + +ObTabletSplitParam::~ObTabletSplitParam() +{ + parallel_datum_rowkey_list_.reset(); + rowkey_allocator_.reset(); +} + +bool ObTabletSplitParam::is_valid() const +{ + return OB_INVALID_ID != tenant_id_ && ls_id_.is_valid() && OB_INVALID_ID != table_id_ + && schema_version_ > 0 && task_id_ > 0 && source_tablet_id_.is_valid() + && dest_tablets_id_.count() > 0 && compaction_scn_ > 0 && user_parallelism_ > 0 + && compat_mode_ != lib::Worker::CompatMode::INVALID && data_format_version_ > 0 && consumer_group_id_ >= 0 + && parallel_datum_rowkey_list_.count() > 0; +} + +int ObTabletSplitParam::init( + const ObTabletSplitParam ¶m) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(param)); + } else if (OB_FAIL(dest_tablets_id_.assign(param.dest_tablets_id_))) { + LOG_WARN("assign failed", K(ret)); + } else if (OB_FAIL(parallel_datum_rowkey_list_.prepare_allocate(param.parallel_datum_rowkey_list_.count()))) { + LOG_WARN("prepare alloc failed", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < param.parallel_datum_rowkey_list_.count(); i++) { + if (OB_FAIL(param.parallel_datum_rowkey_list_.at(i).deep_copy(parallel_datum_rowkey_list_.at(i), rowkey_allocator_))) { + // deep copy needed. + LOG_WARN("alloc range buf failed", K(ret)); + } + } + } + if (OB_SUCC(ret)) { + tenant_id_ = param.tenant_id_; + ls_id_ = param.ls_id_; + table_id_ = param.table_id_; + schema_version_ = param.schema_version_; + task_id_ = param.task_id_; + source_tablet_id_ = param.source_tablet_id_; + compaction_scn_ = param.compaction_scn_; + user_parallelism_ = param.user_parallelism_; + compat_mode_ = param.compat_mode_; + data_format_version_ = param.data_format_version_; + consumer_group_id_ = param.consumer_group_id_; + split_sstable_type_ = param.split_sstable_type_; + can_reuse_macro_block_ = param.can_reuse_macro_block_; + lib::ob_sort(dest_tablets_id_.begin(), dest_tablets_id_.end()); + is_inited_ = true; + } + return ret; +} + +int ObTabletSplitParam::init(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else { + tenant_id_ = MTL_ID(); + ls_id_ = arg.ls_id_; + table_id_ = arg.dest_schema_id_; + schema_version_ = arg.schema_version_; + task_id_ = arg.task_id_; + source_tablet_id_ = arg.source_tablet_id_; + compaction_scn_ = arg.compaction_scn_; + user_parallelism_ = arg.parallel_datum_rowkey_list_.count() - 1; + data_format_version_ = arg.data_format_version_; + consumer_group_id_ = arg.consumer_group_id_; + split_sstable_type_ = arg.split_sstable_type_; + can_reuse_macro_block_ = arg.can_reuse_macro_block_; + if (OB_FAIL(parallel_datum_rowkey_list_.assign(arg.parallel_datum_rowkey_list_))) { // shallow cpy. + LOG_WARN("convert to range failed", K(ret), "parall_info", arg.parallel_datum_rowkey_list_); + } else if (OB_FAIL(ObTabletSplitUtil::get_split_dest_tablets_info(ls_id_, source_tablet_id_, dest_tablets_id_, compat_mode_))) { + LOG_WARN("get split dest tablets failed", K(ret), K(arg)); + } + } + return ret; +} + +int ObTabletSplitParam::init(const obrpc::ObTabletSplitArg &arg) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else { + tenant_id_ = MTL_ID(); + ls_id_ = arg.ls_id_; + table_id_ = arg.table_id_; + schema_version_ = arg.schema_version_; + task_id_ = arg.task_id_; + source_tablet_id_ = arg.source_tablet_id_; + compaction_scn_ = arg.compaction_scn_; + user_parallelism_ = arg.parallel_datum_rowkey_list_.count() - 1; + data_format_version_ = arg.data_format_version_; + consumer_group_id_ = arg.consumer_group_id_; + split_sstable_type_ = arg.split_sstable_type_; + can_reuse_macro_block_ = arg.can_reuse_macro_block_; + ObArray unused_tablet_ids; + if (OB_FAIL(ObTabletSplitUtil::get_split_dest_tablets_info(ls_id_, source_tablet_id_, unused_tablet_ids, compat_mode_))) { + LOG_WARN("get split dest tablets failed", K(ret), K(arg)); + } else if (OB_FAIL(parallel_datum_rowkey_list_.assign(arg.parallel_datum_rowkey_list_))) { // shallow cpy. + LOG_WARN("convert to range failed", K(ret), "parall_info", arg.parallel_datum_rowkey_list_); + } else if (OB_FAIL(dest_tablets_id_.assign(arg.dest_tablets_id_))) { + LOG_WARN("assign failed", K(ret), K(arg)); + } + } + return ret; +} + +ObTabletSplitCtx::ObTabletSplitCtx() + : range_allocator_("SplitRangeCtx", OB_MALLOC_NORMAL_BLOCK_SIZE /*8KB*/, MTL_ID()), + is_inited_(false), complement_data_ret_(OB_SUCCESS), ls_handle_(), tablet_handle_(), + index_builder_map_(), + allocator_("SplitCtx", OB_MALLOC_NORMAL_BLOCK_SIZE /*8KB*/, MTL_ID()), + row_inserted_(0), physical_row_count_(0) +{ +} + +ObTabletSplitCtx::~ObTabletSplitCtx() +{ + int ret = OB_SUCCESS; + is_inited_ = false; + complement_data_ret_ = OB_SUCCESS; + ls_handle_.reset(); + tablet_handle_.reset(); + // destroy constructed sstable index builder. + GetMapItemKeyFn get_map_item_key_fn; + if (index_builder_map_.created() + && OB_FAIL(index_builder_map_.foreach_refactored(get_map_item_key_fn))) { + LOG_ERROR("foreach refactored failed", K(ret)); + } + for (int64_t i = 0; i < get_map_item_key_fn.map_keys_.count(); i++) { + // ignore ret_code is expected, try to release more entries' memory. + ObSSTableIndexBuilder *sstable_index_builder = nullptr; + const ObSplitSSTableTaskKey &key = get_map_item_key_fn.map_keys_.at(i); + if (OB_FAIL(index_builder_map_.get_refactored(key, sstable_index_builder))) { + LOG_ERROR("get refactored failed", K(ret), K(key)); + } else if (OB_FAIL(index_builder_map_.erase_refactored(key))) { + LOG_ERROR("erase refactored failed", K(ret), K(key)); + } + if (OB_NOT_NULL(sstable_index_builder)) { + sstable_index_builder->~ObSSTableIndexBuilder(); + allocator_.free(sstable_index_builder); + sstable_index_builder = nullptr; + } + } + index_builder_map_.destroy(); + table_store_iterator_.reset(); + allocator_.reset(); + data_split_ranges_.reset(); + range_allocator_.reset(); +} + +bool ObTabletSplitCtx::is_valid() const +{ + return is_inited_ && ls_handle_.is_valid() && tablet_handle_.is_valid(); +} + +int ObTabletSplitCtx::init(const ObTabletSplitParam ¶m) +{ + int ret = OB_SUCCESS; + ObTabletMemberWrapper table_store_wrapper; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(param)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(param.ls_id_, ls_handle_, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(param)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle_, + param.source_tablet_id_, tablet_handle_, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("get tablet failed", K(ret)); + } else if (OB_FAIL(ObTabletSplitUtil::check_satisfy_split_condition(param.dest_tablets_id_, param.compaction_scn_, tablet_handle_, ls_handle_))) { + if (OB_NEED_RETRY == ret) { + if (REACH_COUNT_INTERVAL(1000L)) { + LOG_WARN("wait to satisfy the data split condition", K(ret), K(param)); + } + } else { + LOG_WARN("check satisfy split condition failed", K(ret), K(param)); + } + } else if (OB_FAIL(tablet_handle_.get_obj()->get_all_tables(table_store_iterator_))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(ObTabletSplitUtil::convert_rowkey_to_range(range_allocator_, param.parallel_datum_rowkey_list_, data_split_ranges_))) { + LOG_WARN("convert to range failed", K(ret), K(param)); + } + + if (OB_SUCC(ret)) { + complement_data_ret_ = OB_SUCCESS; + is_inited_ = true; + } + return ret; +} + +int ObTabletSplitCtx::prepare_index_builder( + const ObTabletSplitParam ¶m) +{ + int ret = OB_SUCCESS; + const int64_t bucket_num = 16; + ObSEArray sstables; + ObTabletSplitMdsUserData split_data; + const ObStorageSchema *storage_schema = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(param)); + } else if (OB_UNLIKELY(index_builder_map_.created())) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_FAIL(index_builder_map_.create(bucket_num, "SplitSstIdxMap"))) { + LOG_WARN("create sstable record map failed", K(ret)); + } else if (OB_FAIL(ObTabletSplitUtil::get_participants(param.split_sstable_type_, table_store_iterator_, sstables))) { + LOG_WARN("get participant sstables failed", K(ret)); + } else if (OB_FAIL(tablet_handle_.get_obj()->get_split_data(split_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(split_data.get_storage_schema(storage_schema))) { + LOG_WARN("failed to get storage schema", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); i++) { + ObSSTable *sstable = static_cast(sstables.at(i)); + for (int64_t j = 0; OB_SUCC(ret) && j < param.dest_tablets_id_.count(); j++) { + void *buf = nullptr; + ObWholeDataStoreDesc data_desc; + ObSSTableIndexBuilder *sstable_index_builder = nullptr; + ObSplitSSTableTaskKey key; + ObITable::TableKey dest_table_key = sstable->get_key(); + dest_table_key.tablet_id_ = param.dest_tablets_id_.at(j); + key.src_sst_key_ = sstable->get_key(); + key.dest_tablet_id_ = param.dest_tablets_id_.at(j); + ObTabletHandle tablet_handle; + const ObMergeType merge_type = sstable->is_major_sstable() ? MAJOR_MERGE : MINOR_MERGE; + const int64_t snapshot_version = sstable->is_major_sstable() ? + sstable->get_snapshot_version() : sstable->get_end_scn().get_val_for_tx(); + if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle_, param.dest_tablets_id_.at(j), tablet_handle))) { + LOG_WARN("get tablet failed", K(ret)); + } else if (OB_FAIL(ObTabletDDLUtil::prepare_index_data_desc(*tablet_handle.get_obj(), + dest_table_key, snapshot_version, param.data_format_version_, + nullptr/*first_ddl_sstable*/, storage_schema, data_desc))) { + LOG_WARN("prepare index data desc failed", K(ret)); + } else if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObSSTableIndexBuilder)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory failed", K(ret)); + } else if (FALSE_IT(sstable_index_builder = new (buf) ObSSTableIndexBuilder(false/*use double write buffer*/))) { + } else if (OB_FAIL(sstable_index_builder->init(data_desc.get_desc(), ObSSTableIndexBuilder::DISABLE))) { + LOG_WARN("init sstable index builder failed", K(ret)); + } else if (OB_FAIL(index_builder_map_.set_refactored(key, sstable_index_builder))) { + LOG_WARN("set refactored failed", K(ret)); + } + + if (OB_FAIL(ret)) { + // other newly-allocated sstable index builders will be deconstructed when deconstruct the ctx. + if (nullptr != sstable_index_builder) { + sstable_index_builder->~ObSSTableIndexBuilder(); + sstable_index_builder = nullptr; + } + if (nullptr != buf) { + allocator_.free(buf); + buf = nullptr; + } + } + } + } + } + return ret; +} + +ObTabletSplitDag::ObTabletSplitDag() + : ObIDag(ObDagType::DAG_TYPE_TABLET_SPLIT), is_inited_(false), param_(), context_() +{ +} + +ObTabletSplitDag::~ObTabletSplitDag() +{ +} + + +int ObTabletSplitDag::calc_total_row_count() { + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("has not been inited ", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(param_)); + } else if (context_.physical_row_count_ != 0) { + ret = OB_INIT_TWICE; + LOG_WARN("has calculated the row_count", K(ret), K(context_.physical_row_count_)); + } else if (OB_FAIL(ObDDLUtil::get_tablet_physical_row_cnt( + param_.ls_id_, + param_.source_tablet_id_, + true, // calc_sstable = true; + false, // calc_memtable = false; because memtable has been frozen. + context_.physical_row_count_))) { + LOG_WARN("failed to get physical row count of tablet", K(ret), K(param_), K(context_)); + } + LOG_INFO("calc row count of the src tablet", K(ret), K(context_)); + return ret; +} + +int ObTabletSplitDag::init_by_param(const share::ObIDagInitParam *param) +{ + int ret = OB_SUCCESS; + const ObTabletSplitParam *tmp_param = static_cast(param); + if (OB_UNLIKELY(nullptr == tmp_param || !tmp_param->is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KPC(tmp_param)); + } else if (OB_FAIL(param_.init(*tmp_param))) { + LOG_WARN("init tablet split param failed", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(param_)); + } else if (OB_FAIL(context_.init(param_))) { + LOG_WARN("init failed", K(ret)); + } else { + consumer_group_id_ = tmp_param->consumer_group_id_; + is_inited_ = true; + } + return ret; +} + +int ObTabletSplitDag::create_first_task() +{ + int ret = OB_SUCCESS; + int64_t task_id = 0; + ObSEArray source_sstables; + ObTabletSplitPrepareTask *prepare_task = nullptr; + ObTabletSplitMergeTask *merge_task = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(ObTabletSplitUtil::get_participants( + param_.split_sstable_type_, context_.table_store_iterator_, source_sstables))) { + LOG_WARN("get all sstables failed", K(ret)); + } else if (OB_FAIL(alloc_task(prepare_task))) { + LOG_WARN("allocate task failed", K(ret)); + } else if (OB_ISNULL(prepare_task)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr task", K(ret)); + } else if (OB_FAIL(prepare_task->init(param_, context_))) { + LOG_WARN("init prepare task failed", K(ret)); + } else if (OB_FAIL(add_task(*prepare_task))) { + LOG_WARN("add task failed", K(ret)); + } else if (OB_FAIL(alloc_task(merge_task))) { + LOG_WARN("alloc task failed", K(ret)); + } else if (OB_ISNULL(merge_task)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr task", K(ret)); + } else if (OB_FAIL(merge_task->init(param_, context_))) { + LOG_WARN("init merge task failed", K(ret)); + } else if (OB_FAIL(add_task(*merge_task))) { + LOG_WARN("add task failed", K(ret)); + } else if (param_.can_reuse_macro_block_) { + // concurrent cnt equals to the count of sstables. + for (int64_t i = 0; OB_SUCC(ret) && i < source_sstables.count(); i++) { + ObTabletSplitWriteTask *write_task = nullptr; + if (OB_ISNULL(source_sstables.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr sstable", K(ret), K(param_)); + } else if (OB_FAIL(alloc_task(write_task))) { + LOG_WARN("alloc task failed", K(ret)); + } else if (OB_ISNULL(write_task)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr task", K(ret)); + } else if (OB_FAIL(write_task->init(task_id++, param_, context_, source_sstables.at(i)))) { + LOG_WARN("init write task failed", K(ret)); + } else if (OB_FAIL(prepare_task->add_child(*write_task))) { + LOG_WARN("add child task failed", K(ret)); + } else if (OB_FAIL(add_task(*write_task))) { + LOG_WARN("add task failed", K(ret)); + } else if (OB_FAIL(write_task->add_child(*merge_task))) { + LOG_WARN("add child task failed", K(ret)); + } + } + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < source_sstables.count(); i++) { + if (OB_ISNULL(source_sstables.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", K(ret), "sstable", source_sstables.at(i)); + } else { + ObTabletSplitWriteTask *write_task = nullptr; + if (OB_FAIL(alloc_task(write_task))) { + LOG_WARN("alloc task failed", K(ret)); + } else if (OB_ISNULL(write_task)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected nullptr task", K(ret)); + } else if (OB_FAIL(write_task->init(0 /*task_id*/, param_, context_, source_sstables.at(i)))) { + LOG_WARN("init write task failed", K(ret)); + } else if (OB_FAIL(prepare_task->add_child(*write_task))) { + LOG_WARN("add child task failed", K(ret)); + } else if (OB_FAIL(add_task(*write_task))) { + LOG_WARN("add task failed", K(ret)); + } else if (OB_FAIL(write_task->add_child(*merge_task))) { + LOG_WARN("add child task failed", K(ret)); + } + } + } + } + FLOG_INFO("create first task finish", K(ret), + "can_reuse_macro_block", param_.can_reuse_macro_block_, "sstables_count", source_sstables.count(), K(param_), K(context_)); + return ret; +} + +int64_t ObTabletSplitDag::hash() const +{ + int tmp_ret = OB_SUCCESS; + int64_t hash_val = 0; + if (OB_UNLIKELY(!is_inited_ || !param_.is_valid())) { + tmp_ret = OB_ERR_SYS; + LOG_ERROR("invalid argument", K(tmp_ret), K(is_inited_), K(param_)); + } else { + hash_val = param_.tenant_id_ + param_.ls_id_.hash() + + param_.table_id_ + param_.schema_version_ + + param_.source_tablet_id_.hash() + ObDagType::DAG_TYPE_TABLET_SPLIT; + } + return hash_val; +} + +bool ObTabletSplitDag::operator==(const ObIDag &other) const +{ + int tmp_ret = OB_SUCCESS; + bool is_equal = false; + if (OB_UNLIKELY(this == &other)) { + is_equal = true; + } else if (get_type() == other.get_type()) { + const ObTabletSplitDag &dag = static_cast(other); + if (OB_UNLIKELY(!param_.is_valid() || !dag.param_.is_valid())) { + tmp_ret = OB_ERR_SYS; + LOG_ERROR("invalid argument", K(tmp_ret), K(param_), K(dag.param_)); + } else { + is_equal = param_.tenant_id_ == dag.param_.tenant_id_ + && param_.ls_id_ == dag.param_.ls_id_ + && param_.schema_version_ == dag.param_.schema_version_ + && param_.source_tablet_id_ == dag.param_.source_tablet_id_; + } + } + return is_equal; +} + +int ObTabletSplitDag::fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObComplementDataDag has not been initialized", K(ret)); + } else if (OB_FAIL(ADD_DAG_WARN_INFO_PARAM(out_param, allocator, get_type(), + static_cast(param_.source_tablet_id_.id()), param_.user_parallelism_))) { + LOG_WARN("failed to fill info param", K(ret)); + } + return ret; +} + +int ObTabletSplitDag::fill_dag_key(char *buf, const int64_t buf_len) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletSplitDag has not been initialized", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid params", K(ret), K(param_)); + } else if (param_.can_reuse_macro_block_) { + if (OB_FAIL(databuff_printf(buf, buf_len, + "Reuse macro block split: src_tablet_id=%ld, parallelism=%ld, tenant_id=%lu, ls_id=%ld, schema_version=%ld", + param_.source_tablet_id_.id(), param_.user_parallelism_, + param_.tenant_id_, param_.ls_id_.id(), param_.schema_version_))) { + LOG_WARN("fail to fill comment", K(ret), K(param_)); + } + } else { + if (OB_FAIL(databuff_printf(buf, buf_len, + "Regen macro block split: src_tablet_id=%ld, parallelism=%ld, tenant_id=%lu, ls_id=%ld, schema_version=%ld", + param_.source_tablet_id_.id(), param_.user_parallelism_, + param_.tenant_id_, param_.ls_id_.id(), param_.schema_version_))) { + LOG_WARN("fail to fill comment", K(ret), K(param_)); + } + } + return ret; +} + +int ObTabletSplitDag::report_replica_build_status() +{ + int ret = OB_SUCCESS; + obrpc::ObDDLBuildSingleReplicaResponseArg arg; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("ObTabletSplitDag has not been inited", K(ret)); + } else if (OB_UNLIKELY(!param_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid param", K(ret), K(param_)); + } else { +#ifdef ERRSIM + if (OB_SUCC(ret)) { + ret = OB_E(EventTable::EN_DDL_REPORT_REPLICA_BUILD_STATUS_FAIL) OB_SUCCESS; + LOG_INFO("report replica build status errsim", K(ret)); + } +#endif + ObAddr rs_addr; + arg.tenant_id_ = param_.tenant_id_; + arg.dest_tenant_id_ = param_.tenant_id_; + arg.ls_id_ = param_.ls_id_; + arg.dest_ls_id_ = param_.ls_id_; + arg.tablet_id_ = param_.source_tablet_id_; + arg.source_table_id_ = param_.table_id_; + arg.dest_schema_id_ = context_.tablet_handle_.get_obj()->get_tablet_meta().data_tablet_id_.id(); // to fetch DDL Task. + arg.ret_code_ = context_.complement_data_ret_; + arg.snapshot_version_ = 1L; + arg.schema_version_ = param_.schema_version_; + arg.dest_schema_version_ = param_.schema_version_; + arg.task_id_ = param_.task_id_; + arg.execution_id_ = 1L; /*execution_id*/ + arg.server_addr_ = GCTX.self_addr(); + arg.row_inserted_ = context_.row_inserted_; + arg.physical_row_count_ = context_.physical_row_count_; + if (OB_FAIL(ret)) { + } else if (OB_ISNULL(GCTX.rs_rpc_proxy_) || OB_ISNULL(GCTX.rs_mgr_)) { + ret = OB_ERR_SYS; + LOG_WARN("inner system error, rootserver rpc proxy or rs mgr must not be NULL", K(ret), K(GCTX)); + } else if (OB_FAIL(GCTX.rs_mgr_->get_master_root_server(rs_addr))) { + LOG_WARN("fail to get rootservice address", K(ret)); + } else if (OB_FAIL(GCTX.rs_rpc_proxy_->to(rs_addr).build_ddl_single_replica_response(arg))) { + LOG_WARN("fail to send build ddl single replica response", K(ret), K(arg)); + } + SERVER_EVENT_ADD("ddl", "replica_split_resp", + "result", context_.complement_data_ret_, + "tenant_id", param_.tenant_id_, + "source_tablet_id", param_.source_tablet_id_.id(), + "svr_addr", GCTX.self_addr(), + "physical_row_count", context_.physical_row_count_, + "split_total_rows", context_.row_inserted_, + *ObCurTraceId::get_trace_id()); + } + FLOG_INFO("send tablet split response to RS", K(ret), K(context_), K(arg)); + return ret; +} + +int ObTabletSplitPrepareTask::init( + ObTabletSplitParam ¶m, ObTabletSplitCtx &ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid() || !ctx.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(param), K(ctx)); + } else { + param_ = ¶m; + context_ = &ctx; + is_inited_ = true; + } + return ret; +} + +int ObTabletSplitPrepareTask::prepare_context() +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(context_->prepare_index_builder(*param_))) { + LOG_WARN("prepare index builder failed", K(ret), KPC_(param)); + } + return ret; +} + +int ObTabletSplitPrepareTask::process() +{ + int ret = OB_SUCCESS; + DEBUG_SYNC(BEFORE_TABLET_SPLIT_PREPARE_TASK); + bool is_all_major_exist = false; + ObIDag *tmp_dag = get_dag(); + ObTabletSplitDag *dag = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(tmp_dag) || ObDagType::DAG_TYPE_TABLET_SPLIT != tmp_dag->get_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KP(tmp_dag)); + } else if (OB_ISNULL(dag = static_cast(tmp_dag))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KP(tmp_dag), KP(dag)); + } else if (OB_SUCCESS != (context_->complement_data_ret_)) { + LOG_WARN("complement data has already failed", KPC(context_)); + } else if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(param_->ls_id_, param_->dest_tablets_id_, is_all_major_exist))) { + LOG_WARN("check all major exist failed", K(ret)); + } else if (is_all_major_exist) { + LOG_INFO("split task has alreay finished", KPC(param_)); + } else if (OB_FAIL(prepare_context())) { + LOG_WARN("prepare index builder map failed", K(ret), KPC(param_)); + } else if (OB_FAIL(dag->calc_total_row_count())) { // only calc row count once time for a task + LOG_WARN("failed to calc task row count", K(ret)); + } + + if (OB_FAIL(ret)) { + context_->complement_data_ret_ = ret; + ret = OB_SUCCESS; + } + return ret; +} + +ObTabletSplitWriteTask::ObTabletSplitWriteTask() + : ObITask(TASK_TYPE_DDL_SPLIT_WRITE), is_inited_(false), + param_(nullptr), context_(nullptr), sstable_(nullptr), + rowkey_read_info_(nullptr), + write_row_(), default_row_(), task_id_(0), + allocator_("SplitWriteRow", OB_MALLOC_NORMAL_BLOCK_SIZE /*8KB*/, MTL_ID()) +{ + +} + +ObTabletSplitWriteTask::~ObTabletSplitWriteTask() +{ + write_row_.reset(); + default_row_.reset(); + allocator_.reset(); +} + +int ObTabletSplitWriteTask::init( + const int64_t task_id, + ObTabletSplitParam ¶m, + ObTabletSplitCtx &ctx, + storage::ObITable *sstable) +{ + int ret = OB_SUCCESS; + int64_t column_cnt = 0; + ObTabletSplitMdsUserData split_data; + const ObStorageSchema *storage_schema = nullptr; + ObArray multi_version_cols_desc; + ObArenaAllocator tmp_arena("TmpInitSplitW"); + ObDatumRow tmp_default_row; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(task_id < 0 || !param.is_valid() || !ctx.is_valid() || nullptr == sstable)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(task_id), K(param), K(ctx), KP(sstable)); + } else if (OB_FAIL(ctx.tablet_handle_.get_obj()->get_split_data(split_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(split_data.get_storage_schema(storage_schema))) { + LOG_WARN("failed to get storage schema", K(ret)); + } else if (OB_FAIL(storage_schema->get_multi_version_column_descs(multi_version_cols_desc))) { + LOG_WARN("get multi version column descs failed", K(ret)); + } else if (OB_FAIL(write_row_.init(allocator_, multi_version_cols_desc.count()))) { + LOG_WARN("Fail to init write row", K(ret)); + } else if (OB_FAIL(tmp_default_row.init(tmp_arena, multi_version_cols_desc.count()))) { // tmp arena to alloc, and reset after. + LOG_WARN("init tmp default row failed", K(ret)); + } else if (OB_FAIL(default_row_.init(allocator_, multi_version_cols_desc.count()))) { + LOG_WARN("init default row failed", K(ret)); + } else if (OB_FAIL(storage_schema->get_orig_default_row(multi_version_cols_desc, true/*need_trim*/, tmp_default_row))) { + LOG_WARN("init default row failed", K(ret)); + } else if (OB_FAIL(default_row_.deep_copy(tmp_default_row/*src*/, allocator_))) { + LOG_WARN("failed to deep copy default row", K(ret)); + } else if (OB_FAIL(ObLobManager::fill_lob_header(allocator_, multi_version_cols_desc, default_row_))) { + LOG_WARN("fail to fill lob header for default row", K(ret)); + } else { + task_id_ = task_id; + param_ = ¶m; + context_ = &ctx; + sstable_ = static_cast(sstable); + rowkey_read_info_ = &context_->tablet_handle_.get_obj()->get_rowkey_read_info(); + is_inited_ = true; + LOG_INFO("init write task successfully", K(ret), + "end_scn", sstable_->get_end_scn(), K(default_row_), KPC(storage_schema)); + } + return ret; +} + +int ObTabletSplitWriteTask::generate_next_task(ObITask *&next_task) +{ + int ret = OB_SUCCESS; + next_task = nullptr; + ObIDag *tmp_dag = get_dag(); + ObTabletSplitDag *dag = nullptr; + ObTabletSplitWriteTask *next_write_task = nullptr; + const int64_t next_task_id = task_id_ + 1; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(nullptr == tmp_dag || ObDagType::DAG_TYPE_TABLET_SPLIT != tmp_dag->get_type())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KPC(tmp_dag)); + } else if (FALSE_IT(dag = static_cast (tmp_dag))) { + } else if (param_->can_reuse_macro_block_) { + ret = OB_ITER_END; + } else if (next_task_id == context_->data_split_ranges_.count()) { + ret = OB_ITER_END; + } else if (OB_FAIL(dag->alloc_task(next_write_task))) { + LOG_WARN("alloc task failed", K(ret)); + } else if (OB_FAIL(next_write_task->init(next_task_id, *param_, *context_, sstable_))) { + LOG_WARN("init next write task failed", K(ret), K(next_task_id), KPC(param_)); + } else { + next_task = next_write_task; + } + + if (OB_FAIL(ret) && OB_NOT_NULL(context_)) { + if (OB_ITER_END != ret) { + context_->complement_data_ret_ = ret; + } + } + return ret; +} + +int ObTabletSplitWriteTask::process() +{ + int ret = OB_SUCCESS; + DEBUG_SYNC(BEFORE_TABLET_SPLIT_WRITE_TASK); + bool is_all_major_exist = false; + ObFixedArray data_desc_arr; + ObFixedArray macro_block_writer_arr; + data_desc_arr.set_allocator(&allocator_); + macro_block_writer_arr.set_allocator(&allocator_); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_SUCCESS != (context_->complement_data_ret_)) { + LOG_WARN("complement data has already failed", KPC(context_)); + } else if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(param_->ls_id_, param_->dest_tablets_id_, is_all_major_exist))) { + LOG_WARN("check all major exist failed", K(ret)); + } else if (is_all_major_exist) { + LOG_INFO("split task has alreay finished", KPC(param_)); + } else if (OB_FAIL(data_desc_arr.init(param_->dest_tablets_id_.count()))) { + LOG_WARN("init failed", K(ret)); + } else if (OB_FAIL(macro_block_writer_arr.init(param_->dest_tablets_id_.count()))) { + LOG_WARN("init failed", K(ret)); + } else if (OB_FAIL(prepare_macro_block_writer(data_desc_arr, macro_block_writer_arr))) { + LOG_WARN("prepare macro block writer failed", K(ret)); + } else if (param_->can_reuse_macro_block_ + && OB_FAIL(process_reuse_macro_block_task(macro_block_writer_arr))) { + LOG_WARN("complement data for reuse macro block task failed", K(ret)); + } else if (!param_->can_reuse_macro_block_ + && OB_FAIL(process_rewrite_macro_block_task(macro_block_writer_arr))) { + LOG_WARN("complement data for rewrite macro block task failed", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < macro_block_writer_arr.count(); i++) { + if (OB_ISNULL(macro_block_writer_arr.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret)); + } else if (OB_FAIL(macro_block_writer_arr.at(i)->close())) { + LOG_WARN("close macro block writer failed", K(ret)); + } + } + } + if (OB_FAIL(ret) && OB_NOT_NULL(context_)) { + context_->complement_data_ret_ = ret; + ret = OB_SUCCESS; + } + // free. + for (int64_t i = 0; i < macro_block_writer_arr.count(); i++) { + if (nullptr != macro_block_writer_arr.at(i)) { + macro_block_writer_arr.at(i)->~ObMacroBlockWriter(); + allocator_.free(macro_block_writer_arr.at(i)); + macro_block_writer_arr.at(i) = nullptr; + } + } + macro_block_writer_arr.reset(); + data_desc_arr.reset(); + + if (OB_FAIL(ret) && OB_NOT_NULL(context_)) { + context_->complement_data_ret_ = ret; + ret = OB_SUCCESS; + } + return ret; +} + +int ObTabletSplitWriteTask::prepare_macro_block_writer( + ObIArray &data_desc_arr, + ObIArray ¯o_block_writer_arr) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObMacroDataSeq macro_start_seq(0); + ObSSTableMetaHandle meta_handle; + ObTabletSplitMdsUserData split_data; + const ObStorageSchema *storage_schema = nullptr; + meta_handle.reset(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(param_->ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("get ls failed", K(ret), KPC(param_)); + } else if (OB_FAIL(sstable_->get_meta(meta_handle))) { + LOG_WARN("get sstable meta failed", K(ret)); + } else if (OB_FAIL(macro_start_seq.set_sstable_seq(meta_handle.get_sstable_meta().get_sstable_seq()))) { + LOG_WARN("set sstable logical seq failed", K(ret), "sst_meta", meta_handle.get_sstable_meta()); + } else if (OB_FAIL(macro_start_seq.set_parallel_degree(task_id_))) { + LOG_WARN("set parallel degree failed", K(ret)); + } else if (OB_FAIL(context_->tablet_handle_.get_obj()->get_split_data(split_data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(split_data.get_storage_schema(storage_schema))) { + LOG_WARN("failed to get storage schema", K(ret)); + } else { + ObMacroSeqParam macro_seq_param; + macro_seq_param.seq_type_ = ObMacroSeqParam::SEQ_TYPE_INC; + macro_seq_param.start_ = macro_start_seq.macro_data_seq_; + const bool micro_index_clustered = context_->tablet_handle_.get_obj()->get_tablet_meta().micro_index_clustered_; + for (int64_t i = 0; OB_SUCC(ret) && i < param_->dest_tablets_id_.count(); i++) { + ObPreWarmerParam pre_warm_param; + ObSSTablePrivateObjectCleaner *object_cleaner = nullptr; + void *buf = nullptr; + ObWholeDataStoreDesc data_desc; + ObTabletHandle tablet_handle; + ObMacroBlockWriter *macro_block_writer = nullptr; + ObSSTableIndexBuilder *sst_idx_builder = nullptr; + const ObTabletID &dst_tablet_id = param_->dest_tablets_id_.at(i); + ObSplitSSTableTaskKey task_key(sstable_->get_key(), dst_tablet_id); + const ObMergeType merge_type = sstable_->is_major_sstable() ? MAJOR_MERGE : MINOR_MERGE; + const int64_t snapshot_version = sstable_->is_major_sstable() ? + sstable_->get_snapshot_version() : sstable_->get_end_scn().get_val_for_tx(); + if (OB_FAIL(context_->index_builder_map_.get_refactored(task_key, sst_idx_builder))) { + LOG_WARN("get refactored failed", K(ret)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, dst_tablet_id, tablet_handle))) { + LOG_WARN("get tablet failed", K(ret)); + } else if (OB_ISNULL(storage_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", K(ret), K(dst_tablet_id)); + } else if (OB_FAIL(data_desc.init(true/*is_ddl*/, *storage_schema, + param_->ls_id_, + dst_tablet_id, + merge_type, + snapshot_version, + param_->data_format_version_, + micro_index_clustered, + tablet_handle.get_obj()->get_transfer_seq(), + sstable_->get_end_scn()))) { + LOG_WARN("fail to init data store desc", K(ret), K(dst_tablet_id), KPC(param_)); + } else if (FALSE_IT(data_desc.get_desc().sstable_index_builder_ = sst_idx_builder)) { + } else if (FALSE_IT(data_desc.get_static_desc().is_ddl_ = true)) { + } else if (OB_FAIL(data_desc_arr.push_back(data_desc))) { // copy_and_assign. + LOG_WARN("push back data store desc failed", K(ret)); + } else if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObMacroBlockWriter)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc mem failed", K(ret)); + } else if (FALSE_IT(macro_block_writer = new (buf) ObMacroBlockWriter())) { + } else if (OB_FAIL(pre_warm_param.init(param_->ls_id_, dst_tablet_id))) { + LOG_WARN("failed to init pre warm param", K(ret), K(dst_tablet_id), KPC(param_)); + } else if (OB_FAIL(ObSSTablePrivateObjectCleaner::get_cleaner_from_data_store_desc( + data_desc.get_desc(), + object_cleaner))) { + LOG_WARN("failed to get cleaner from data store desc", K(ret)); + } else if (OB_FAIL(macro_block_writer->open(data_desc_arr.at(i).get_desc(), macro_start_seq.get_parallel_idx(), + macro_seq_param, pre_warm_param, *object_cleaner))) { + LOG_WARN("open macro_block_writer failed", K(ret), K(data_desc)); + } else if (OB_FAIL(macro_block_writer_arr.push_back(macro_block_writer))) { + LOG_WARN("push back failed", K(ret)); + } + if (OB_FAIL(ret)) { + // allocated memory in array will be freed by the caller. + if (nullptr != macro_block_writer) { + macro_block_writer->~ObMacroBlockWriter(); + macro_block_writer = nullptr; + } + if (nullptr != buf) { + allocator_.free(buf); + buf = nullptr; + } + } + } + } + return ret; +} + +// TODO yiren, remove it when mds prepared. +int ObTabletSplitWriteTask::prepare_sorted_high_bound_pair( + common::ObSArray &tablet_bound_arr) +{ + int ret = OB_SUCCESS; + tablet_bound_arr.reset(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(!param_->can_reuse_macro_block_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), KPC(param_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < param_->dest_tablets_id_.count(); i++) { + ObDatumRowkey high_bound; + const common::ObTabletID &tablet_id = param_->dest_tablets_id_.at(i); + ObTabletHandle tablet_handle; + ObTabletSplitMdsUserData data; + ObDatumRowkey data_tablet_end_partkey; + if (OB_FAIL(ObDDLUtil::ddl_get_tablet(context_->ls_handle_, tablet_id, tablet_handle, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(data.get_end_partkey(data_tablet_end_partkey))) { + LOG_WARN("failed to get end partkey", K(ret), K(tablet_handle.get_obj()->get_tablet_meta())); + } else if (OB_FAIL(data_tablet_end_partkey.deep_copy(high_bound, allocator_))) { + LOG_WARN("failed to deep copy", K(ret)); + } else if (OB_FAIL(tablet_bound_arr.push_back(std::make_pair(tablet_id, high_bound)))) { + LOG_WARN("push back failed", K(ret), K(tablet_id), K(high_bound)); + } + } + } + + if (OB_SUCC(ret)) { + // check in ASC rowkey order. + for (int64_t i = 1; OB_SUCC(ret) && i < tablet_bound_arr.count(); i++) { + int cmp_ret = 0; + ObDatumRowkey &prev_bound = tablet_bound_arr.at(i-1).second; + if (OB_FAIL(tablet_bound_arr.at(i).second.compare(prev_bound, rowkey_read_info_->get_datum_utils(), cmp_ret))) { + LOG_WARN("failed to compare", K(ret)); + } else if (OB_UNLIKELY(cmp_ret < 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet bound arr not in asc order", K(ret)); + } + } + } + return ret; +} + +int ObTabletSplitWriteTask::process_reuse_macro_block_task( + const ObIArray ¯o_block_writer_arr) +{ + int ret = OB_SUCCESS; + ObSArray tablet_bound_arr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(macro_block_writer_arr.count() != param_->dest_tablets_id_.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), "writer count", macro_block_writer_arr.count(), KPC(param_)); + } else if (OB_FAIL(prepare_sorted_high_bound_pair(tablet_bound_arr))) { + LOG_WARN("get split dest tablets info failed", K(ret)); + } else { + // iterate all macro blocks in sstable. + SMART_VAR(ObDualMacroMetaIterator, meta_iter) { + int64_t dest_tablet_index = 0; + ObDatumRange whole_range; + whole_range.set_whole_range(); + const bool is_small_sstable = sstable_->is_small_sstable(); + if (OB_FAIL(meta_iter.open( + *sstable_, whole_range, *rowkey_read_info_, allocator_))) { + LOG_WARN("open dual macro meta iter failed", K(ret), K(*sstable_)); + } else { + while (OB_SUCC(ret)) { + ObDataMacroBlockMeta macro_meta; + ObMacroBlockDesc data_macro_desc; + data_macro_desc.reset(); + data_macro_desc.macro_meta_ = ¯o_meta; + int cmp_ret = 0; + ObDatumRowkey macro_end_key; + if (OB_FAIL(meta_iter.get_next_macro_block(data_macro_desc))) { + if (OB_ITER_END != ret) { + LOG_WARN("get data macro meta failed", K(ret)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (!is_small_sstable) { + const ObDatumRowkey &high_bound = tablet_bound_arr.at(dest_tablet_index).second; + if (OB_FAIL(data_macro_desc.macro_meta_->get_rowkey(macro_end_key))) { + LOG_WARN("get macro block end key failed", K(ret), K(data_macro_desc)); + } else if (OB_FAIL(macro_end_key.compare(high_bound, rowkey_read_info_->get_datum_utils(), cmp_ret))) { + LOG_WARN("compare failed", K(ret), K(macro_end_key), K(high_bound)); + } + } + + if (FAILEDx(!is_small_sstable && cmp_ret < 0)) { + // reuse whole macro block. + const ObMicroBlockData *micro_block_data = nullptr; + if (data_macro_desc.is_clustered_index_tree_ && OB_FAIL(meta_iter.get_current_clustered_index_info(micro_block_data))) { + LOG_WARN("get micro data failed", K(ret)); + } else if (OB_FAIL(macro_block_writer_arr.at(dest_tablet_index)->append_macro_block(data_macro_desc, micro_block_data))) { + LOG_WARN("append macro row failed", K(ret)); + } else { + (void) ATOMIC_AAFx(&context_->row_inserted_, data_macro_desc.row_count_, 0/*unused id*/); + LOG_INFO("process current macro block finish", K(ret), K(dest_tablet_index), K(data_macro_desc), + K(tablet_bound_arr)); + } + } else if (OB_FAIL(process_rows_for_reuse_task( + tablet_bound_arr, macro_block_writer_arr, data_macro_desc, dest_tablet_index))) { + LOG_WARN("process rows for rewrite macro block failed", K(ret), K(data_macro_desc)); + } + } + } + } + } + return ret; +} + +// rewrite macro block task like split local index. +int ObTabletSplitWriteTask::process_rewrite_macro_block_task( + const ObIArray ¯o_block_writer_arr) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else { + if (OB_UNLIKELY(task_id_ >= context_->data_split_ranges_.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(task_id_), KPC(param_)); + } else if (OB_FAIL(process_rows_for_rewrite_task(macro_block_writer_arr, context_->data_split_ranges_.at(task_id_)))) { + LOG_WARN("process each row of rewrite task failed", K(ret), K(task_id_), "query_range", context_->data_split_ranges_.at(task_id_), KPC(context_)); + } + } + return ret; +} + +int ObTabletSplitWriteTask::process_rows_for_reuse_task( + const ObIArray &tablet_bound_arr, + const ObIArray ¯o_block_writer_arr, + const ObMacroBlockDesc &data_macro_desc, + int64_t &dest_tablet_index) +{ + int ret = OB_SUCCESS; + ObRowScan row_scan_iter; + ObDataStoreDesc data_desc; + int64_t rewrite_row_cnt = 0; + ObDatumRange whole_range; + whole_range.set_whole_range(); + ObSplitScanParam row_scan_param(param_->table_id_, *(context_->tablet_handle_.get_obj()), whole_range); + if (OB_FAIL(row_scan_iter.init(row_scan_param, data_macro_desc, *sstable_))) { + LOG_WARN("init row scan iterator failed", K(ret), K(data_macro_desc)); + } else { + while (OB_SUCC(ret)) { // exit when iter row end. + ObDatumRowkey cur_row_key; + const ObDatumRow *cur_row = nullptr; + if (OB_FAIL(row_scan_iter.get_next_row(cur_row))) { + if (OB_ITER_END != ret) { + LOG_WARN("get next row failed", K(ret), K(dest_tablet_index), K(data_macro_desc), KPC(sstable_)); + } else { + ret = OB_SUCCESS; + LOG_INFO("process the rewrite macro block finished", K(ret), K(rewrite_row_cnt)); + break; + } + } else if (OB_FAIL(cur_row_key.assign(cur_row->storage_datums_, cur_row->get_column_count()))) { + LOG_WARN("construct datum rowkey failed", K(ret)); + } else { + int cmp_ret = 0; + bool is_row_append = false; + while (OB_SUCC(ret) && !is_row_append && dest_tablet_index < tablet_bound_arr.count()) { + const ObDatumRowkey &high_bound = tablet_bound_arr.at(dest_tablet_index).second; + if (OB_FAIL(cur_row_key.compare(high_bound, rowkey_read_info_->get_datum_utils(), cmp_ret))) { + LOG_WARN("compare failed", K(ret), K(cur_row_key), K(high_bound)); + } else if (cmp_ret < 0) { + // find the dest tablet the row belongs to. + if (OB_FAIL(fill_tail_column_datums(*cur_row))) { + LOG_WARN("fill tail column datums failed", K(ret)); + } else if (OB_FAIL(macro_block_writer_arr.at(dest_tablet_index)->append_row(write_row_))) { + LOG_WARN("append row failed", K(ret), KPC(cur_row), K(write_row_), K(data_desc)); + } + + if (OB_SUCC(ret)) { + if (++rewrite_row_cnt % 100 == 0) { + (void) ATOMIC_AAFx(&context_->row_inserted_, 100, 0/*unused id*/); + } + is_row_append = true; + LOG_INFO("append row successfully", "tablet_id", tablet_bound_arr.at(dest_tablet_index).first, + "row_count", rewrite_row_cnt, "row_inserted_", context_->row_inserted_, + KPC(cur_row), K(write_row_), K(default_row_)); + } + } else { + // switch to next dest tablet. + LOG_INFO("prepare to switch to next tablet", K(ret), K(dest_tablet_index), + "tablet_id", tablet_bound_arr.at(dest_tablet_index).first, K(rewrite_row_cnt)); + dest_tablet_index++; + if (rewrite_row_cnt != 0) { + (void) ATOMIC_AAFx(&context_->row_inserted_, rewrite_row_cnt % 100, 0/*unused id*/); + rewrite_row_cnt = 0; + } + } + } + if (rewrite_row_cnt != 0) { + (void) ATOMIC_AAFx(&context_->row_inserted_, rewrite_row_cnt % 100, 0/*unused id*/); + rewrite_row_cnt = 0; + } + if (!is_row_append) { + ret = OB_SUCC(ret) ? OB_ERR_UNEXPECTED : ret; + LOG_WARN("row not append", K(ret), KPC(cur_row)); + } + } + } + } + return ret; +} + +int ObTabletSplitWriteTask::process_rows_for_rewrite_task( + const ObIArray ¯o_block_writer_arr, + const ObDatumRange &query_range) +{ + int ret = OB_SUCCESS; + const ObIArray &dest_tablets_id = param_->dest_tablets_id_; + const ObITableReadInfo &rowkey_read_info = context_->tablet_handle_.get_obj()->get_rowkey_read_info(); + const int64_t schema_rowkey_cnt = context_->tablet_handle_.get_obj()->get_rowkey_read_info().get_schema_rowkey_count(); + ObTabletSplitMdsUserData src_split_data; + ObSEArray dst_split_datas; + if (OB_UNLIKELY(dest_tablets_id.count() != macro_block_writer_arr.count() || !query_range.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(dest_tablets_id), K(macro_block_writer_arr), K(query_range)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::prepare_calc_split_dst( + *context_->ls_handle_.get_ls(), + *context_->tablet_handle_.get_obj(), + ObTimeUtility::current_time() + (1 + dest_tablets_id.count()) * ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S, + src_split_data, + dst_split_datas))) { + LOG_WARN("failed to prepare calc split dst", K(ret), K(dest_tablets_id)); + } else { + // rewrite each row. + ObRowScan row_scan_iter; + ObSplitScanParam row_scan_param(param_->table_id_, *(context_->tablet_handle_.get_obj()), query_range); + if (OB_FAIL(row_scan_iter.init(row_scan_param, *sstable_))) { + LOG_WARN("init row scan iterator failed", K(ret)); + } else { + ObArenaAllocator new_row_allocator; + int64_t tmp_row_inserted = 0; + while (OB_SUCC(ret)) { // exit when iter row end. + new_row_allocator.reuse(); + const ObDatumRow *datum_row = nullptr; + ObDatumRowkey rowkey; + ObTabletID tablet_id; + int64_t dst_idx = 0; + if (OB_FAIL(row_scan_iter.get_next_row(datum_row))) { + if (OB_ITER_END != ret) { + LOG_WARN("get next row failed", K(ret)); + } else { + ret = OB_SUCCESS; + break; + } + } else if (OB_FAIL(rowkey.assign(datum_row->storage_datums_, schema_rowkey_cnt))) { + LOG_WARN("Failed to assign rowkey", K(ret), K(schema_rowkey_cnt)); + } else if (OB_FAIL(src_split_data.calc_split_dst(rowkey_read_info, dst_split_datas, rowkey, tablet_id, dst_idx))) { + LOG_WARN("failed to calc split dst tablet", K(ret)); + } else { + bool is_row_append = false; + for (int64_t i = 0; OB_SUCC(ret) && !is_row_append && i < dest_tablets_id.count(); i++) { + if (dest_tablets_id.at(i) == tablet_id) { + if (OB_FAIL(fill_tail_column_datums(*datum_row))) { + LOG_WARN("fill tail column datums failed", K(ret)); + } else if (OB_FAIL(macro_block_writer_arr.at(i)->append_row(write_row_))) { + LOG_WARN("append row failed", K(ret), KPC(datum_row), K(write_row_)); + } + + if (OB_SUCC(ret)) { + is_row_append = true; + } + } + } + if (!is_row_append) { + // defensive code. + ret = OB_SUCC(ret) ? OB_ERR_UNEXPECTED : ret; + LOG_WARN("append row failed", K(ret), K(tablet_id), K(write_row_), KPC(datum_row)); + } else if (++tmp_row_inserted % 100 == 0) { + (void) ATOMIC_AAFx(&context_->row_inserted_, 100, 0/*placeholder*/); + } + } + } + (void) ATOMIC_AAFx(&context_->row_inserted_, tmp_row_inserted % 100, 0/*unused id*/); + } + } + return ret; +} + +int ObTabletSplitWriteTask::fill_tail_column_datums(const blocksstable::ObDatumRow &scan_row) +{ + int ret = OB_SUCCESS; + write_row_.reuse(); + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(!scan_row.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(scan_row)); + } else if (OB_UNLIKELY(scan_row.get_column_count() > default_row_.get_column_count() + || default_row_.get_column_count() != write_row_.get_column_count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(scan_row), K(default_row_), K(write_row_)); + } else if (OB_FAIL(write_row_.copy_attributes_except_datums(scan_row))) { + LOG_WARN("copy attribute except storage datums failed", K(ret), K(scan_row)); + } else { + write_row_.count_ = default_row_.get_column_count(); + for (int64_t i = 0; OB_SUCC(ret) && i < default_row_.get_column_count(); i++) { + if (i < scan_row.get_column_count()) { + // scan columns number exceeds columns number of the macro block, the scanner + // will return default NOP datums. + const ObStorageDatum &scan_datum = scan_row.storage_datums_[i]; + if (sstable_->is_major_sstable() && scan_datum.is_nop()) { + write_row_.storage_datums_[i] = default_row_.storage_datums_[i]; + } else { + write_row_.storage_datums_[i] = scan_datum; + } + } else if (sstable_->is_major_sstable()) { + write_row_.storage_datums_[i] = default_row_.storage_datums_[i]; + } else { + write_row_.storage_datums_[i].set_nop(); + } + } + } + return ret; +} + +int ObTabletSplitMergeTask::init( + ObTabletSplitParam ¶m, ObTabletSplitCtx &ctx) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid() || !ctx.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(param), K(ctx)); + } else { + param_ = ¶m; + context_ = &ctx; + is_inited_ = true; + } + return ret; +} + +int ObTabletSplitMergeTask::process() +{ + int ret = OB_SUCCESS; + DEBUG_SYNC(BEFORE_TABLET_SPLIT_MERGE_TASK); + bool is_all_major_exist = false; + ObIDag *tmp_dag = get_dag(); + ObTabletSplitDag *dag = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_ISNULL(tmp_dag) || ObDagType::DAG_TYPE_TABLET_SPLIT != tmp_dag->get_type()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KP(tmp_dag)); + } else if (OB_ISNULL(dag = static_cast(tmp_dag))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KP(tmp_dag), KP(dag)); + } else if (OB_SUCCESS != (context_->complement_data_ret_)) { + LOG_WARN("complement data has already failed", KPC(context_)); + } else if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(param_->ls_id_, param_->dest_tablets_id_, is_all_major_exist))) { + LOG_WARN("check all major exist failed", K(ret)); + } else if (is_all_major_exist) { + LOG_INFO("split task has alreay finished", KPC(param_)); + } else if (OB_SUCCESS != (context_->complement_data_ret_)) { + LOG_WARN("complement data has already failed", "ret", context_->complement_data_ret_); + } else if (share::ObSplitSSTableType::SPLIT_BOTH == param_->split_sstable_type_) { + if (OB_FAIL(create_sstable(share::ObSplitSSTableType::SPLIT_MINOR))) { + LOG_WARN("create sstable failed", K(ret)); + } else if (OB_FAIL(create_sstable(share::ObSplitSSTableType::SPLIT_MAJOR))) { + LOG_WARN("create sstable failed", K(ret)); + } + } else if (OB_FAIL(create_sstable(param_->split_sstable_type_))) { + LOG_WARN("create sstable failed", K(ret)); + } + if (OB_FAIL(ret) && OB_NOT_NULL(context_)) { + context_->complement_data_ret_ = ret; + ret = OB_SUCCESS; + } + DEBUG_SYNC(AFTER_TABLET_SPLIT_MERGE_TASK); + if (OB_NOT_NULL(dag) && OB_FAIL(dag->report_replica_build_status())) { + // do not worry about the error code overrided here, which is useless. + LOG_WARN("report replica build status failed", K(ret), KPC(context_)); + } + return ret; +} + +int ObTabletSplitMergeTask::create_sstable( + const share::ObSplitSSTableType &split_sstable_type) +{ + int ret = OB_SUCCESS; + ObSEArray participants; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(share::ObSplitSSTableType::SPLIT_MAJOR != split_sstable_type + && share::ObSplitSSTableType::SPLIT_MINOR != split_sstable_type)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(split_sstable_type), KPC(param_)); + } else if (OB_FAIL(ObTabletSplitUtil::get_participants(split_sstable_type, context_->table_store_iterator_, participants))) { + LOG_WARN("get participants failed", K(ret)); + } else { + ObArenaAllocator tmp_arena("PartSplitSchema"); + const int64_t multi_version_start = context_->tablet_handle_.get_obj()->get_multi_version_start(); + for (int64_t i = 0; OB_SUCC(ret) && i < param_->dest_tablets_id_.count(); i++) { + bool is_major_exist = false; + const ObTabletID &dest_tablet_id = param_->dest_tablets_id_.at(i); + ObSEArray check_major_exist_tablets; + if (OB_FAIL(check_major_exist_tablets.push_back(dest_tablet_id))) { + LOG_WARN("push back failed", K(ret)); + } else if (OB_FAIL(ObTabletSplitUtil::check_major_sstables_exist(param_->ls_id_, check_major_exist_tablets, is_major_exist))) { + LOG_WARN("check major exist failed", K(ret), K(check_major_exist_tablets), KPC(param_)); + } else if (is_major_exist) { + FLOG_INFO("skip to create sstable", K(ret), K(dest_tablet_id)); + } else { + const int64_t src_table_cnt = participants.count(); + ObTablesHandleArray batch_sstables_handle; + for (int64_t j = 0; OB_SUCC(ret) && j < src_table_cnt; j++) { // keep destination sstable commit versions incremental. + const ObSSTable *src_sstable = static_cast(participants.at(j)); + if (OB_ISNULL(src_sstable)) { + ret = OB_ERR_SYS; + LOG_WARN("Error sys", K(ret), K(dest_tablet_id), K(participants)); + } else { + ObSplitSSTableTaskKey key; + key.dest_tablet_id_ = dest_tablet_id; + key.src_sst_key_ = src_sstable->get_key(); + ObSSTableIndexBuilder *index_builder = nullptr; + ObTabletCreateSSTableParam create_sstable_param; + ObTableHandleV2 table_handle; + table_handle.reset(); + if (OB_FAIL(context_->index_builder_map_.get_refactored(key, index_builder))) { + LOG_WARN("get refactored failed", K(ret), K(key)); + } else if (OB_FAIL(build_create_sstable_param( + *src_sstable, key.dest_tablet_id_, index_builder, create_sstable_param))) { + LOG_WARN("build create sstable param failed", K(ret)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(create_sstable_param, context_->allocator_, table_handle))) { + LOG_WARN("create sstable failed", K(ret), K(create_sstable_param)); + } else if (OB_FAIL(batch_sstables_handle.add_table(table_handle))) { + LOG_WARN("add table failed", K(ret)); + } + } + // fill empty minor sstable if scn not continous + if (OB_SUCC(ret) && j == src_table_cnt - 1 && share::ObSplitSSTableType::SPLIT_MINOR == split_sstable_type) { + bool need_fill_empty_sstable = false; + SCN end_scn; + if (OB_FAIL(check_need_fill_empty_sstable(context_->ls_handle_, src_sstable->is_minor_sstable(), src_sstable->get_key(), dest_tablet_id, need_fill_empty_sstable, end_scn))) { + LOG_WARN("failed to check need fill", K(ret)); + } else if (need_fill_empty_sstable) { + ObTabletCreateSSTableParam create_sstable_param; + ObTableHandleV2 table_handle; + table_handle.reset(); + ObSSTableMetaHandle meta_handle; + if (OB_FAIL(src_sstable->get_meta(meta_handle))) { + LOG_WARN("get meta failed", K(ret)); + } else if (OB_FAIL(build_create_empty_sstable_param(meta_handle.get_sstable_meta().get_basic_meta(), src_sstable->get_key(), dest_tablet_id, end_scn, create_sstable_param))) { + LOG_WARN("failed to build create empty sstable param", K(ret)); + } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(create_sstable_param, context_->allocator_, table_handle))) { + LOG_WARN("create sstable failed", K(ret), K(create_sstable_param)); + } else if (OB_FAIL(batch_sstables_handle.add_table(table_handle))) { + LOG_WARN("add table failed", K(ret)); + } + } + } + } + if (OB_SUCC(ret) && src_table_cnt > 0) { + if (OB_FAIL(ObTabletSplitMergeTask::update_table_store_with_batch_tables( + context_->ls_handle_, + context_->tablet_handle_, + dest_tablet_id, + batch_sstables_handle, + split_sstable_type))) { + LOG_WARN("update table store with batch tables failed", K(ret), K(batch_sstables_handle), K(split_sstable_type)); + } + } + } + } + } + return ret; +} + +int ObTabletSplitMergeTask::build_create_sstable_param( + const ObSSTable &src_table, // source table. + const ObTabletID &dst_tablet_id, // dest tablet id. + ObSSTableIndexBuilder *index_builder, + ObTabletCreateSSTableParam &create_sstable_param) +{ + int ret = OB_SUCCESS; + ObSSTableMetaHandle meta_handle; + meta_handle.reset(); + ObSSTableMergeRes res; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_UNLIKELY(nullptr == index_builder || !src_table.is_valid() || !dst_tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), KP(index_builder), K(src_table), K(dst_tablet_id)); + } else if (OB_FAIL(index_builder->close(res))) { + LOG_WARN("close sstable index builder failed", K(ret)); + } else if (OB_FAIL(src_table.get_meta(meta_handle))) { + LOG_WARN("get sstable meta failed", K(ret)); + } else { + const ObSSTableBasicMeta &basic_meta = meta_handle.get_sstable_meta().get_basic_meta(); + create_sstable_param.table_key_ = src_table.get_key(); + create_sstable_param.table_key_.tablet_id_ = dst_tablet_id; + create_sstable_param.sstable_logic_seq_ = 0; + create_sstable_param.filled_tx_scn_ = basic_meta.filled_tx_scn_; + create_sstable_param.table_mode_ = basic_meta.table_mode_; + create_sstable_param.index_type_ = static_cast (basic_meta.index_type_); + create_sstable_param.rowkey_column_cnt_ = basic_meta.rowkey_column_count_; + create_sstable_param.latest_row_store_type_ = basic_meta.latest_row_store_type_; + create_sstable_param.recycle_version_ = basic_meta.recycle_version_; + create_sstable_param.schema_version_ = param_->schema_version_; // use new schema version. + create_sstable_param.create_snapshot_version_ = basic_meta.create_snapshot_version_; + create_sstable_param.ddl_scn_ = basic_meta.ddl_scn_; + create_sstable_param.progressive_merge_round_ = basic_meta.progressive_merge_round_; + create_sstable_param.progressive_merge_step_ = basic_meta.progressive_merge_step_; + + ObSSTableMergeRes::fill_addr_and_data(res.root_desc_, + create_sstable_param.root_block_addr_, create_sstable_param.root_block_data_); + ObSSTableMergeRes::fill_addr_and_data(res.data_root_desc_, + create_sstable_param.data_block_macro_meta_addr_, create_sstable_param.data_block_macro_meta_); + create_sstable_param.is_meta_root_ = res.data_root_desc_.is_meta_root_; + create_sstable_param.root_row_store_type_ = res.root_row_store_type_; + create_sstable_param.data_index_tree_height_ = res.root_desc_.height_; + create_sstable_param.index_blocks_cnt_ = res.index_blocks_cnt_; + create_sstable_param.data_blocks_cnt_ = res.data_blocks_cnt_; + create_sstable_param.micro_block_cnt_ = res.micro_block_cnt_; + create_sstable_param.use_old_macro_block_count_ = res.use_old_macro_block_count_; + create_sstable_param.row_count_ = res.row_count_; + create_sstable_param.column_cnt_ = res.data_column_cnt_; + create_sstable_param.data_checksum_ = res.data_checksum_; + create_sstable_param.occupy_size_ = res.occupy_size_; + create_sstable_param.original_size_ = res.original_size_; + create_sstable_param.max_merged_trans_version_ = res.max_merged_trans_version_; + create_sstable_param.contain_uncommitted_row_ = res.contain_uncommitted_row_; + create_sstable_param.compressor_type_ = res.compressor_type_; + create_sstable_param.encrypt_id_ = res.encrypt_id_; + create_sstable_param.master_key_id_ = res.master_key_id_; + create_sstable_param.nested_size_ = res.nested_size_; + create_sstable_param.nested_offset_ = res.nested_offset_; + create_sstable_param.data_block_ids_ = res.data_block_ids_; + create_sstable_param.other_block_ids_ = res.other_block_ids_; + create_sstable_param.ddl_scn_.set_min(); + MEMCPY(create_sstable_param.encrypt_key_, res.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); + if (src_table.is_major_sstable()) { + if (OB_FAIL(create_sstable_param.column_checksums_.assign(res.data_column_checksums_))) { + LOG_WARN("fill column checksum failed", K(ret), K(res)); + } + } + } + return ret; +} + +int ObTabletSplitMergeTask::check_need_fill_empty_sstable( + ObLSHandle &ls_handle, + const bool is_minor_sstable, + const ObITable::TableKey &table_key, + const ObTabletID &dst_tablet_id, + bool &need_fill_empty_sstable, + SCN &end_scn) +{ + int ret = OB_SUCCESS; + ObTabletHandle dst_tablet_handle; + ObTabletMemberWrapper table_store_handle; + ObTabletCreateSSTableParam create_sstable_param; + need_fill_empty_sstable = false; + end_scn.reset(); + if (is_minor_sstable) { + if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, dst_tablet_id, dst_tablet_handle, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("get tablet failed", K(ret)); + } else if (OB_FAIL(dst_tablet_handle.get_obj()->fetch_table_store(table_store_handle))) { + LOG_WARN("failed to fetch table store", K(ret)); + } else { + ObITable *first_dst_table = table_store_handle.get_member()->get_minor_sstables().get_boundary_table(false/*is_last*/); + const SCN dst_start_scn = nullptr != first_dst_table ? first_dst_table->get_key().get_start_scn() + : dst_tablet_handle.get_obj()->get_tablet_meta().clog_checkpoint_scn_; + if (table_key.get_end_scn() < dst_start_scn) { + need_fill_empty_sstable = true; + end_scn = dst_start_scn; + } + } + } + return ret; +} + +int ObTabletSplitMergeTask::build_create_empty_sstable_param( + const ObSSTableBasicMeta &meta, + const ObITable::TableKey &table_key, + const ObTabletID &dst_tablet_id, + const SCN &end_scn, + ObTabletCreateSSTableParam &create_sstable_param) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!meta.is_valid() || !table_key.is_valid() || !dst_tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(meta), K(table_key), K(dst_tablet_id)); + } else { + const ObSSTableBasicMeta &basic_meta = meta; + + create_sstable_param.table_key_.table_type_ = ObITable::TableType::MINOR_SSTABLE; + create_sstable_param.table_key_.tablet_id_ = dst_tablet_id; + create_sstable_param.table_key_.scn_range_.start_scn_ = table_key.get_end_scn(); + create_sstable_param.table_key_.scn_range_.end_scn_ = end_scn; + create_sstable_param.max_merged_trans_version_ = 0; + + create_sstable_param.schema_version_ = basic_meta.schema_version_; + create_sstable_param.progressive_merge_round_ = basic_meta.progressive_merge_round_; + create_sstable_param.progressive_merge_step_ = basic_meta.progressive_merge_step_; + create_sstable_param.sstable_logic_seq_ = basic_meta.sstable_logic_seq_; + create_sstable_param.filled_tx_scn_ = basic_meta.filled_tx_scn_; + create_sstable_param.table_mode_ = basic_meta.table_mode_; + create_sstable_param.index_type_ = static_cast (basic_meta.index_type_); + create_sstable_param.rowkey_column_cnt_ = basic_meta.rowkey_column_count_; + create_sstable_param.latest_row_store_type_ = basic_meta.latest_row_store_type_; + create_sstable_param.recycle_version_ = basic_meta.recycle_version_; + create_sstable_param.schema_version_ = basic_meta.schema_version_; + create_sstable_param.create_snapshot_version_ = basic_meta.create_snapshot_version_; + create_sstable_param.ddl_scn_ = basic_meta.ddl_scn_; + create_sstable_param.progressive_merge_round_ = basic_meta.progressive_merge_round_; + create_sstable_param.progressive_merge_step_ = basic_meta.progressive_merge_step_; + create_sstable_param.column_cnt_ = basic_meta.column_cnt_; + create_sstable_param.master_key_id_ = basic_meta.master_key_id_; + MEMCPY(create_sstable_param.encrypt_key_, basic_meta.encrypt_key_, share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH); + + create_sstable_param.root_block_addr_.set_none_addr(); + create_sstable_param.data_block_macro_meta_addr_.set_none_addr(); + create_sstable_param.root_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + create_sstable_param.latest_row_store_type_ = ObRowStoreType::FLAT_ROW_STORE; + create_sstable_param.data_index_tree_height_ = 0; + create_sstable_param.index_blocks_cnt_ = 0; + create_sstable_param.data_blocks_cnt_ = 0; + create_sstable_param.micro_block_cnt_ = 0; + create_sstable_param.use_old_macro_block_count_ = 0; + create_sstable_param.data_checksum_ = 0; + create_sstable_param.occupy_size_ = 0; + create_sstable_param.ddl_scn_.set_min(); + create_sstable_param.filled_tx_scn_ = end_scn; + create_sstable_param.original_size_ = 0; + create_sstable_param.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; + } + return ret; +} + +int ObTabletSplitMergeTask::update_table_store_with_batch_tables( + const ObLSHandle &ls_handle, + const ObTabletHandle &src_tablet_handle, + const ObTabletID &dst_tablet_id, + const ObTablesHandleArray &tables_handle, + const share::ObSplitSSTableType &split_sstable_type) +{ + int ret = OB_SUCCESS; + ObBatchUpdateTableStoreParam param; + param.reset(); + ObSEArray batch_tables; + if (OB_UNLIKELY(!ls_handle.is_valid() + || !src_tablet_handle.is_valid() + || !dst_tablet_id.is_valid() + || tables_handle.empty() + || (share::ObSplitSSTableType::SPLIT_MAJOR != split_sstable_type + && share::ObSplitSSTableType::SPLIT_MINOR != split_sstable_type))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_handle), K(src_tablet_handle), K(dst_tablet_id), K(tables_handle), K(split_sstable_type)); + } else if (OB_FAIL(tables_handle.get_tables(batch_tables))) { + LOG_WARN("get batch sstables failed", K(ret)); + } else if (share::ObSplitSSTableType::SPLIT_MINOR == split_sstable_type) { + if (OB_FAIL(param.tables_handle_.assign(tables_handle))) { + LOG_WARN("assign failed", K(ret), K(batch_tables)); + } + } else { + // ATTENTION, Meta major sstable should be placed at the end of the array. + ObTableHandleV2 meta_major_handle; + for (int64_t i = 0; OB_SUCC(ret) && i < batch_tables.count(); i++) { + const ObITable *table = batch_tables.at(i); + ObTableHandleV2 table_handle; + if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", K(ret), K(i), K(batch_tables)); + } else if (OB_UNLIKELY(table->is_meta_major_sstable())) { + if (OB_UNLIKELY(meta_major_handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("more than 1 meta major", K(ret), K(meta_major_handle), K(batch_tables)); + } else if (OB_FAIL(tables_handle.get_table(i, meta_major_handle))) { + LOG_WARN("get handle failed", K(ret), K(i), K(batch_tables)); + } + } else if (OB_FAIL(tables_handle.get_table(i, table_handle))) { + LOG_WARN("get handle failed", K(ret)); + } else if (OB_FAIL(param.tables_handle_.add_table(table_handle))) { + LOG_WARN("add table failed", K(ret)); + } + } + if (OB_SUCC(ret) && meta_major_handle.is_valid()) { + if (OB_FAIL(param.tables_handle_.add_table(meta_major_handle))) { + LOG_WARN("add table failed", K(ret)); + } + } + } + + if (OB_SUCC(ret)) { + param.tablet_split_param_.snapshot_version_ = src_tablet_handle.get_obj()->get_tablet_meta().snapshot_version_; + param.tablet_split_param_.multi_version_start_ = src_tablet_handle.get_obj()->get_multi_version_start(); + param.tablet_split_param_.update_with_major_tables_ = share::ObSplitSSTableType::SPLIT_MAJOR == split_sstable_type; + param.rebuild_seq_ = ls_handle.get_ls()->get_rebuild_seq(); + if (OB_FAIL(ls_handle.get_ls()->build_tablet_with_batch_tables(dst_tablet_id, param))) { + LOG_WARN("failed to update tablet table store", K(ret), K(dst_tablet_id), K(param)); + } + FLOG_INFO("update batch sstables", K(ret), K(dst_tablet_id), K(batch_tables), K(param)); + } + return ret; +} + +ObRowScan::ObRowScan() : is_inited_(false), row_iter_(nullptr), ctx_(), + access_ctx_(), rowkey_read_info_(nullptr), access_param_(), allocator_("SplitScanRow") +{} + +ObRowScan::~ObRowScan() +{ + if (OB_NOT_NULL(row_iter_)) { + row_iter_->~ObSSTableRowWholeScanner(); + row_iter_ = nullptr; + } + allocator_.reset(); +} + +//construct table access param +int ObRowScan::construct_access_param( + const ObSplitScanParam ¶m) +{ + int ret = OB_SUCCESS; + ObTabletTableIterator table_iter; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(param)); + } else { + // The life is held by the tablet_handle_ in context_. + rowkey_read_info_ = ¶m.src_tablet_.get_rowkey_read_info(); + if (OB_FAIL(access_param_.init_merge_param( + param.table_id_, param.src_tablet_.get_tablet_meta().tablet_id_, *rowkey_read_info_, false/*is_multi_version_minor_merge*/))) { + LOG_WARN("init table access param failed", K(ret), KPC(rowkey_read_info_), K(param)); + } + } + LOG_INFO("construct table access param finished", K(ret), K(access_param_)); + return ret; +} + +// construct version range and ctx +int ObRowScan::construct_access_ctx( + const share::ObLSID &ls_id, + const ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + const int64_t snapshot_version = INT64_MAX; + ObQueryFlag query_flag(ObQueryFlag::Forward, + true, /*is daily merge scan*/ + true, /*is read multiple macro block*/ + true, /*sys task scan, read one macro block in single io*/ + false /*is full row scan?*/, + false, + false); + query_flag.is_bare_row_scan_ = true; // output mult-version rows without do_compact. + common::ObVersionRange trans_version_range; + trans_version_range.snapshot_version_ = snapshot_version; + trans_version_range.multi_version_start_ = 1; + trans_version_range.base_version_ = 0; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(!ls_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_id)); + } else if (OB_FAIL(ctx_.init_for_read(ls_id, + tablet_id, + INT64_MAX, + -1, + SCN::max_scn()))) { + LOG_WARN("fail to init store ctx", K(ret), K(ls_id)); + } else if (OB_FAIL(access_ctx_.init(query_flag, + ctx_, + allocator_, + allocator_, + trans_version_range))) { + LOG_WARN("fail to init accesss ctx", K(ret)); + } + LOG_INFO("construct access ctx finished", K(ret), K(access_ctx_)); + return ret; +} + +int ObRowScan::init( + const ObSplitScanParam ¶m, + ObSSTable &sstable) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid() || !sstable.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(param), K(sstable)); + } else if (OB_FAIL(construct_access_param(param))) { + LOG_WARN("construct access param failed", K(ret), K(param)); + } else if (OB_FAIL(construct_access_ctx(param.src_tablet_.get_tablet_meta().ls_id_, param.src_tablet_.get_tablet_meta().tablet_id_))) { + LOG_WARN("construct access param failed", K(ret), K(param)); + } else if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObSSTableRowWholeScanner)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc mem failed", K(ret)); + } else if (FALSE_IT(row_iter_ = new(buf)ObSSTableRowWholeScanner())) { + } else if (OB_FAIL(row_iter_->init(access_param_.iter_param_, + access_ctx_, + &sstable, + param.query_range_))) { + LOG_WARN("construct iterator failed", K(ret)); + } else { + is_inited_ = true; + } + if (OB_FAIL(ret)) { + if (nullptr != row_iter_) { + row_iter_->~ObSSTableRowWholeScanner(); + row_iter_ = nullptr; + } + if (nullptr != buf) { + allocator_.free(buf); + buf = nullptr; + } + } + return ret; +} + +int ObRowScan::init( + const ObSplitScanParam ¶m, + const blocksstable::ObMacroBlockDesc ¯o_desc, + ObSSTable &sstable) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid() || !macro_desc.is_valid() || !sstable.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(param), K(macro_desc), K(sstable)); + } else if (OB_FAIL(construct_access_param(param))) { + LOG_WARN("construct access param failed", K(ret), K(param)); + } else if (OB_FAIL(construct_access_ctx(param.src_tablet_.get_tablet_meta().ls_id_, param.src_tablet_.get_tablet_meta().tablet_id_))) { + LOG_WARN("construct access param failed", K(ret), K(param)); + } else if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObSSTableRowWholeScanner)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc mem failed", K(ret)); + } else if (FALSE_IT(row_iter_ = new(buf)ObSSTableRowWholeScanner())) { + } else if (OB_FAIL(row_iter_->open(access_param_.iter_param_, + access_ctx_, *param.query_range_, macro_desc, sstable))) { + LOG_WARN("constrtuct stored row iterator failed", K(ret), K(access_param_), K(access_ctx_), K(macro_desc), K(sstable)); + } else { + is_inited_ = true; + } + if (OB_FAIL(ret)) { + if (nullptr != row_iter_) { + row_iter_->~ObSSTableRowWholeScanner(); + row_iter_ = nullptr; + } + if (nullptr != buf) { + allocator_.free(buf); + buf = nullptr; + } + } + return ret; +} + +int ObRowScan::get_next_row(const ObDatumRow *&tmp_row) +{ + int ret = OB_SUCCESS; + tmp_row = nullptr; + const ObDatumRow *row = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(row_iter_->get_next_row(row))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next row", K(ret)); + } + } else if (OB_UNLIKELY(nullptr == row || !row->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected datum row", K(ret), KPC(row)); + } else { + tmp_row = row; + } + return ret; +} + +ObSnapshotRowScan::ObSnapshotRowScan() : is_inited_(false), allocator_("SplitSnapScan"), snapshot_version_(0), + range_(), read_info_(), write_row_(), out_cols_projector_(), access_param_(), ctx_(), access_ctx_(), get_table_param_(), scan_merge_(nullptr) +{ + reset(); +} + +ObSnapshotRowScan::~ObSnapshotRowScan() +{ + reset(); +} + +void ObSnapshotRowScan::reset() +{ + is_inited_ = false; + if (OB_NOT_NULL(scan_merge_)) { + scan_merge_->~ObMultipleScanMerge(); + allocator_.free(scan_merge_); + scan_merge_ = nullptr; + } + get_table_param_.reset(); + access_ctx_.reset(); + ctx_.reset(); + access_param_.reset(); + out_cols_projector_.reset(); + write_row_.reset(); + read_info_.reset(); + range_.reset(); + snapshot_version_ = 0; + allocator_.reset(); +} + +int ObSnapshotRowScan::init( + const ObSplitScanParam ¶m, + const ObIArray &schema_store_col_descs, + const int64_t schema_column_cnt, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode, + const ObTabletHandle &tablet_handle, + const int64_t snapshot_version) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + LOG_WARN("init twice", K(ret)); + } else { + const ObTabletID &tablet_id = param.src_tablet_.get_tablet_meta().tablet_id_; + const ObLSID &ls_id = param.src_tablet_.get_tablet_meta().ls_id_; + ObQueryFlag query_flag(ObQueryFlag::Forward, + false, /* daily merge*/ + true, /* use *optimize */ + false, /* use whole macro scan*/ + false, /* not full row*/ + false, /* not index_back*/ + false);/* query stat */ + query_flag.disable_cache(); + ObTabletTableIterator table_iter; + snapshot_version_ = snapshot_version; + schema_rowkey_cnt_ = schema_rowkey_cnt; + range_.set_whole_range(); + if (OB_FAIL(table_iter.set_tablet_handle(tablet_handle))) { + LOG_WARN("failed to set tablet handle", K(ret)); + } else if (OB_FAIL(table_iter.refresh_read_tables_from_tablet(snapshot_version, + false/*allow_no_ready_read*/, + false/*major_sstable_only*/, + false/*need_split_src_table*/, + false/*need_split_dst_table*/))) { + LOG_WARN("failed to get read tables", K(ret), K(param)); + } else if (OB_FAIL(read_info_.init(allocator_, + schema_column_cnt, + schema_rowkey_cnt, + is_oracle_mode, + schema_store_col_descs, + nullptr/*storage_cols_index*/))) { + LOG_WARN("failed to init read info", K(ret), K(schema_column_cnt), K(schema_rowkey_cnt), K(schema_store_col_descs)); + } else if (OB_FAIL(write_row_.init(allocator_, read_info_.get_columns_desc().count() + storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt()))) { + LOG_WARN("Fail to init write row", K(ret)); + } else if (OB_FALSE_IT(write_row_.row_flag_.set_flag(ObDmlFlag::DF_INSERT))) { + } else if (OB_FAIL(construct_access_param(param.table_id_, tablet_id, read_info_))) { + LOG_WARN("failed to init access param", K(ret), K(param)); + } else if (OB_FAIL(construct_range_ctx(query_flag, ls_id))) { + LOG_WARN("failed to init access ctx", K(ret)); + } else if (OB_FAIL(construct_multiple_scan_merge(table_iter, range_))) { + LOG_WARN("failed to init scan merge", K(ret), K(table_iter)); + } else { + is_inited_ = true; + } + } + if (OB_FAIL(ret)) { + reset(); + } + return ret; +} + +int ObSnapshotRowScan::construct_access_param( + const uint64_t table_id, + const common::ObTabletID &tablet_id, + const ObITableReadInfo &read_info) +{ + int ret = OB_SUCCESS; + const int64_t column_cnt = read_info.get_columns_desc().count(); + out_cols_projector_.reset(); + if (OB_FAIL(out_cols_projector_.prepare_allocate(column_cnt, 0))) { + LOG_WARN("failed to prepare allocate", K(ret), K(column_cnt)); + } else { + for (int64_t i = 0; i < out_cols_projector_.count(); i++) { + out_cols_projector_[i] = i; + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(access_param_.init_merge_param(table_id, + tablet_id, + read_info, + false/*is_multi_version_minor_merge*/))) { + LOG_WARN("failed to init access param", K(ret)); + } else { + access_param_.iter_param_.out_cols_project_ = &out_cols_projector_; + } + return ret; +} + +int ObSnapshotRowScan::construct_range_ctx( + ObQueryFlag &query_flag, + const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + common::ObVersionRange trans_version_range; + trans_version_range.snapshot_version_ = snapshot_version_; + trans_version_range.multi_version_start_ = snapshot_version_; + trans_version_range.base_version_ = 0; + SCN tmp_scn; + if (OB_FAIL(tmp_scn.convert_for_tx(snapshot_version_))) { + LOG_WARN("convert fail", K(ret), K(ls_id), K_(snapshot_version)); + } else if (OB_FAIL(ctx_.init_for_read(ls_id, + access_param_.iter_param_.tablet_id_, + INT64_MAX, + -1, + tmp_scn))) { + LOG_WARN("fail to init store ctx", K(ret), K(ls_id)); + } else if (OB_FAIL(access_ctx_.init(query_flag, ctx_, allocator_, allocator_, trans_version_range))) { + LOG_WARN("fail to init accesss ctx", K(ret)); + } else if (OB_NOT_NULL(access_ctx_.lob_locator_helper_)) { + access_ctx_.lob_locator_helper_->update_lob_locator_ctx(access_param_.iter_param_.table_id_, + access_param_.iter_param_.tablet_id_.id(), + 0/*tx_id*/); + } + return ret; +} + +int ObSnapshotRowScan::construct_multiple_scan_merge( + const ObTabletTableIterator &table_iter, + const ObDatumRange &range) +{ + int ret = OB_SUCCESS; + void *buf = nullptr; + if (OB_FAIL(get_table_param_.tablet_iter_.assign(table_iter))) { + LOG_WARN("fail to assign tablet iterator", K(ret)); + } else if (OB_ISNULL(buf = allocator_.alloc(sizeof(ObMultipleScanMerge)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to alloc memory for ObMultipleScanMerge", K(ret)); + } else if (FALSE_IT(scan_merge_ = new(buf)ObMultipleScanMerge())) { + } else if (OB_FAIL(scan_merge_->init(access_param_, access_ctx_, get_table_param_))) { + LOG_WARN("fail to init scan merge", K(ret), K(access_param_), K(access_ctx_)); + } else if (OB_FAIL(scan_merge_->open(range))) { + LOG_WARN("fail to open scan merge", K(ret), K(access_param_), K(access_ctx_), K(range)); + } else { + scan_merge_->disable_padding(); + scan_merge_->disable_fill_virtual_column(); + } + return ret; +} + +int ObSnapshotRowScan::add_extra_rowkey(const ObDatumRow &row) +{ + int ret = OB_SUCCESS; + const int64_t rowkey_column_count = schema_rowkey_cnt_; + const int64_t extra_rowkey_cnt = storage::ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); + if (OB_UNLIKELY(write_row_.get_capacity() < row.count_ + extra_rowkey_cnt || + row.count_ < rowkey_column_count)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("Unexpected row", K(ret), K(write_row_), K(row.count_), K(rowkey_column_count)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < row.count_; i++) { + if (i < rowkey_column_count) { + write_row_.storage_datums_[i] = row.storage_datums_[i]; + } else { + write_row_.storage_datums_[i + extra_rowkey_cnt] = row.storage_datums_[i]; + } + } + write_row_.storage_datums_[rowkey_column_count].set_int(-snapshot_version_); + write_row_.storage_datums_[rowkey_column_count + 1].set_int(0); + write_row_.count_ = row.count_ + extra_rowkey_cnt; + } + return ret; +} + +int ObSnapshotRowScan::get_next_row(const ObDatumRow *&out_row) +{ + int ret = OB_SUCCESS; + out_row = nullptr; + ObDatumRow *row = nullptr; + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not init", K(ret)); + } else if (OB_FAIL(scan_merge_->get_next_row(row))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next row", K(ret)); + } + } else if (OB_UNLIKELY(nullptr == row || !row->is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected datum row", K(ret), KPC(row)); + } else if (OB_FAIL(add_extra_rowkey(*row))) { + LOG_WARN("failed to add extra rowkey", K(ret)); + } else { + out_row = static_cast(&write_row_); + } + return ret; +} + +ObUncommittedRowScan::ObUncommittedRowScan() + : row_scan_(), major_snapshot_version_(OB_INVALID_TIMESTAMP), trans_version_col_idx_(0) +{ +} + +ObUncommittedRowScan::~ObUncommittedRowScan() +{ +} + +int ObUncommittedRowScan::init( + const ObSplitScanParam param, + ObSSTable &src_sstable, + const int64_t major_snapshot_version) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(row_scan_.init(param, src_sstable))) { + LOG_WARN("failed to init", K(ret)); + } else { + major_snapshot_version_ = major_snapshot_version; + trans_version_col_idx_ = ObMultiVersionRowkeyHelpper::get_trans_version_col_store_index( + row_scan_.get_rowkey_read_info()->get_schema_rowkey_count(), true); + } + return ret; +} + +int ObUncommittedRowScan::get_next_row(const ObDatumRow *&res_row) +{ + int ret = OB_SUCCESS; + const ObDatumRow *row = nullptr; + bool can_skip = true; + res_row = nullptr; + while (OB_SUCC(ret) && can_skip) { + if (OB_FAIL(row_scan_.get_next_row(row))) { + if (OB_UNLIKELY(OB_ITER_END != ret)) { + LOG_WARN("fail to get next row", K(ret)); + } + } else if (OB_FAIL(check_can_skip(*row, can_skip))) { + LOG_WARN("failed to check can skip", K(ret)); + } + } + if (OB_SUCC(ret)) { + res_row = row; + } + return ret; +}; + +int ObUncommittedRowScan::check_can_skip(const ObDatumRow &row, bool &can_skip) +{ + int ret = OB_SUCCESS; + SCN scn_commit_trans_version = SCN::max_scn(); + int64_t commit_version = OB_INVALID_VERSION; + if (OB_INVALID_TIMESTAMP == major_snapshot_version_) { + can_skip = false; + } else if (row.mvcc_row_flag_.is_uncommitted_row()) { + SCN major_snapshot_scn; + storage::ObTxTableGuards &tx_table_guards = row_scan_.get_tx_table_guards(); + bool can_read = false; + int64_t state = ObTxData::MAX_STATE_CNT; + const transaction::ObTransID &read_trans_id = row.trans_id_; + if (OB_FAIL(major_snapshot_scn.convert_for_tx(major_snapshot_version_))) { + LOG_WARN("failed to convert major snapshot version", K(ret), K(major_snapshot_version_)); + } else if (OB_FAIL(tx_table_guards.get_tx_state_with_scn( + read_trans_id, major_snapshot_scn, state, scn_commit_trans_version))) { + LOG_WARN("get transaction status failed", K(ret), K(read_trans_id), K(state)); + } else if (ObTxData::RUNNING == state) { + can_skip = false; + } else if (ObTxData::COMMIT == state || ObTxData::ELR_COMMIT == state || ObTxData::ABORT == state) { + can_skip = true; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("unexpected row state", K(ret)); + } + } else { + if (OB_UNLIKELY(trans_version_col_idx_ >= row.get_column_count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("trans version column index out of range", K(ret), K(trans_version_col_idx_), K(row)); + } else { + const int64_t row_commit_version = -(row.storage_datums_[trans_version_col_idx_].get_int()); + can_skip = row_commit_version <= major_snapshot_version_; + } + } + if (OB_SUCC(ret) && can_skip) { + LOG_DEBUG("skip row", K(row)); + } + return ret; +} + +// For split util. +// get all sstables that need to split. +int ObTabletSplitUtil::get_participants( + const share::ObSplitSSTableType &split_sstable_type, + const ObTableStoreIterator &const_table_store_iter, + ObIArray &participants) +{ + int ret = OB_SUCCESS; + ObTablet *tablet = nullptr; + participants.reset(); + ObTableStoreIterator table_store_iter; + if (OB_FAIL(table_store_iter.assign(const_table_store_iter))) { + LOG_WARN("failed to assign table store iter", K(ret)); + } else { + while (OB_SUCC(ret)) { + ObITable *table = nullptr; + ObSSTableMetaHandle sstable_meta_hdl; + if (OB_FAIL(table_store_iter.get_next(table))) { + if (OB_UNLIKELY(OB_ITER_END == ret)) { + ret = OB_SUCCESS; + break; + } else { + LOG_WARN("get next table failed", K(ret), K(table_store_iter)); + } + } else if (OB_UNLIKELY(nullptr == table || !table->is_sstable())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KPC(table)); + } else if (table->is_minor_sstable()) { + if (share::ObSplitSSTableType::SPLIT_MAJOR == split_sstable_type) { + // Split with major only. + } else if (OB_FAIL(participants.push_back(table))) { + LOG_WARN("push back failed", K(ret)); + } + } else if (table->is_major_sstable()) { + if (share::ObSplitSSTableType::SPLIT_MINOR == split_sstable_type) { + // Split with minor only. + } else if (OB_FAIL(participants.push_back(table))) { + LOG_WARN("push back major failed", K(ret)); + } + } else if (table->is_mds_sstable()) { + // skip + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KPC(table)); + } + } + } + return ret; +} + +int ObTabletSplitUtil::split_task_ranges( + ObIAllocator &allocator, + const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const int64_t user_parallelism, + const int64_t schema_tablet_size, + ObIArray ¶llel_datum_rowkey_list) +{ + int ret = OB_SUCCESS; + parallel_datum_rowkey_list.reset(); + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObTableStoreIterator table_store_iterator; + ObSEArray store_ranges; + ObSEArray tables; + common::ObArenaAllocator tmp_arena("SplitRange", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); + if (OB_UNLIKELY(!ls_id.is_valid() || !tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(ls_id)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, + tablet_id, tablet_handle, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("get tablet failed", K(ret), K(ls_id), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->get_all_sstables(table_store_iterator))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(ObTabletSplitUtil::get_participants( + share::ObSplitSSTableType::SPLIT_BOTH, table_store_iterator, tables))) { + LOG_WARN("get participants failed", K(ret)); + } else { + const ObITableReadInfo &rowkey_read_info = tablet_handle.get_obj()->get_rowkey_read_info(); + const int64_t tablet_size = std::max(schema_tablet_size, 128 * 1024 * 1024L/*128MB*/); + ObRangeSplitInfo range_info; + ObPartitionRangeSpliter range_spliter; + ObStoreRange whole_range; + whole_range.set_whole_range(); + if (OB_FAIL(range_spliter.get_range_split_info(tables, + rowkey_read_info, whole_range, range_info))) { + LOG_WARN("init range split info failed", K(ret)); + } else if (OB_FALSE_IT(range_info.parallel_target_count_ + = MAX(1, MIN(user_parallelism, (range_info.total_size_ + tablet_size - 1) / tablet_size)))) { + } else if (OB_FAIL(range_spliter.split_ranges(range_info, + tmp_arena, false /*for_compaction*/, store_ranges))) { + LOG_WARN("split ranges failed", K(ret), K(range_info)); + } else if (OB_UNLIKELY(store_ranges.count() <= 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", K(ret), K(range_info)); + } else { + const int64_t rowkey_arr_cnt = store_ranges.count() + 1; // with min and max. + if (OB_FAIL(parallel_datum_rowkey_list.prepare_allocate(rowkey_arr_cnt))) { + LOG_WARN("reserve failed", K(ret), K(rowkey_arr_cnt), K(store_ranges)); + } else { + ObDatumRowkey tmp_key; + for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_arr_cnt; i++) { + if (i == 0) { + tmp_key.set_min_rowkey(); + if (OB_FAIL(tmp_key.deep_copy(parallel_datum_rowkey_list.at(i), allocator))) { + LOG_WARN("failed to push min rowkey", K(ret)); + } + } else if (OB_FAIL(tmp_key.from_rowkey(store_ranges.at(i - 1).get_end_key().get_rowkey(), tmp_arena))) { + LOG_WARN("failed to shallow copy from obj", K(ret)); + } else if (OB_FAIL(tmp_key.deep_copy(parallel_datum_rowkey_list.at(i), allocator))) { + LOG_WARN("failed to deep copy end key", K(ret), K(i), "src_key", store_ranges.at(i - 1).get_end_key()); + } + } + } + } + LOG_INFO("prepare task split ranges finished", K(ret), K(user_parallelism), K(schema_tablet_size), K(tablet_id), + K(parallel_datum_rowkey_list), K(range_info)); + } + tmp_arena.reset(); + return ret; +} + +int ObTabletSplitUtil::convert_rowkey_to_range( + ObIAllocator &allocator, + const ObIArray ¶llel_datum_rowkey_list, + ObIArray &datum_ranges_array) +{ + int ret = OB_SUCCESS; + datum_ranges_array.reset(); + ObDatumRange schema_rowkey_range; + ObDatumRange multi_version_range; + schema_rowkey_range.set_left_open(); + schema_rowkey_range.set_right_closed(); + for (int64_t i = 0; OB_SUCC(ret) && i < parallel_datum_rowkey_list.count() - 1; i++) { + schema_rowkey_range.start_key_ = parallel_datum_rowkey_list.at(i); // shallow copy. + schema_rowkey_range.end_key_ = parallel_datum_rowkey_list.at(i + 1); // shallow copy. + multi_version_range.reset(); + if (OB_FAIL(schema_rowkey_range.to_multi_version_range(allocator, multi_version_range))) { // deep copy necessary, to hold datum buffer. + LOG_WARN("failed to convert multi_version range", K(ret), K(schema_rowkey_range)); + } else if (OB_FAIL(datum_ranges_array.push_back(multi_version_range))) { // buffer is kept by the to_multi_version_range. + LOG_WARN("failed to push back merge range to array", K(ret), K(multi_version_range)); + } + } + LOG_INFO("change to datum range array finished", K(ret), K(parallel_datum_rowkey_list), K(datum_ranges_array)); + return ret; +} + +// check whether the major ssts of all dst tablets exist. +int ObTabletSplitUtil::check_major_sstables_exist( + const share::ObLSID &ls_id, + const ObIArray &check_tablets_id, + bool &is_all_major_exist) +{ + int ret = OB_SUCCESS; + is_all_major_exist = true; + if (OB_UNLIKELY(!ls_id.is_valid() || check_tablets_id.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_id), K(check_tablets_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && is_all_major_exist && i < check_tablets_id.count(); i++) { + const ObTabletID &tablet_id = check_tablets_id.at(i); + const ObSSTable *latest_major_sst = nullptr; + ObTabletMemberWrapper unused_table_store_wrapper; + if (OB_FAIL(ObTabletDDLUtil::check_and_get_major_sstable(ls_id, + tablet_id, latest_major_sst, unused_table_store_wrapper))) { + LOG_WARN("check and get major sst failed", K(ret), K(ls_id), K(tablet_id)); + } else { + is_all_major_exist &= (nullptr != latest_major_sst); + } + } + } + return ret; +} + +int ObTabletSplitUtil::check_satisfy_split_condition( + const ObArray &dest_tablets_id, + const int64_t compaction_scn, + const ObTabletHandle &source_tablet_handle, + const ObLSHandle &ls_handle) +{ + int ret = OB_SUCCESS; + UNUSED(compaction_scn); + ObArray memtable_handles; + ObSSTable *latest_major; + ObTablet *tablet = nullptr; + ObTabletMemberWrapper table_store_wrapper; + bool is_tablet_status_need_to_split = false; + if (OB_UNLIKELY(!source_tablet_handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(source_tablet_handle)); + } else if (OB_ISNULL(tablet = source_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(source_tablet_handle)); + } else if (OB_FAIL(check_tablet_restore_status(dest_tablets_id, ls_handle, source_tablet_handle, is_tablet_status_need_to_split))) { + LOG_WARN("failed to check tablet status", K(ret), K(source_tablet_handle)); + } else if (OB_UNLIKELY(!is_tablet_status_need_to_split)) { + ret = OB_TABLET_STATUS_NO_NEED_TO_SPLIT; + LOG_WARN("there is no need to split, because of the special restore status of src tablet or des tablets", K(ret), K(source_tablet_handle), K(dest_tablets_id)); + } else if (OB_FAIL(tablet->get_all_memtables(memtable_handles))) { + LOG_WARN("failed to get_memtable_mgr for get all memtable", K(ret), KPC(tablet)); + } else if (!memtable_handles.empty()) { + ret = OB_NEED_RETRY; + if (REACH_COUNT_INTERVAL(1000L)) { + LOG_INFO("should wait memtable dump", K(ret), "tablet_id", tablet->get_tablet_meta().tablet_id_, K(memtable_handles)); + } + } else if (MTL_TENANT_ROLE_CACHE_IS_RESTORE()) { + LOG_INFO("dont check compaction in restore progress", K(ret), "tablet_id", tablet->get_tablet_meta().tablet_id_); + } else { + const ObMediumCompactionInfoList *medium_list = nullptr; + ObArenaAllocator tmp_allocator("SplitGetMedium", OB_MALLOC_NORMAL_BLOCK_SIZE, MTL_ID()); // for load medium info + if (OB_FAIL(tablet->read_medium_info_list(tmp_allocator, medium_list))) { + LOG_WARN("failed to load medium info list", K(ret), K(tablet)); + } else if (medium_list->size() > 0) { + ret = OB_NEED_RETRY; + if (REACH_COUNT_INTERVAL(1000L)) { + LOG_INFO("should wait compact end", K(ret), "tablet_id", tablet->get_tablet_meta().tablet_id_, KPC(medium_list)); + } + } + } + return ret; +} + +int ObTabletSplitUtil::get_split_dest_tablets_info( + const share::ObLSID &ls_id, + const ObTabletID &source_tablet_id, + ObIArray &dest_tablets_id, + lib::Worker::CompatMode &compat_mode) +{ + int ret = OB_SUCCESS; + dest_tablets_id.reset(); + compat_mode = lib::Worker::CompatMode::INVALID; + ObTabletSplitMdsUserData data; + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + if (OB_UNLIKELY(!ls_id.is_valid() || !source_tablet_id.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(ls_id), K(source_tablet_id)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(ls_id, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(ls_id)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, + source_tablet_id, + tablet_handle, + ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + LOG_WARN("get tablet handle failed", K(ret), K(ls_id), K(source_tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(data.get_split_dst_tablet_ids(dest_tablets_id))) { + LOG_WARN("failed to get split dst tablet ids", K(ret)); + } else if (OB_UNLIKELY(dest_tablets_id.count() < 2)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected mds data", K(ret), K(ls_id), K(source_tablet_id), K(dest_tablets_id)); + } else { + compat_mode = tablet_handle.get_obj()->get_tablet_meta().compat_mode_; + } + return ret; +} + +int ObTabletSplitUtil::check_medium_compaction_info_list_cnt( + const obrpc::ObCheckMediumCompactionInfoListArg &arg, + obrpc::ObCheckMediumCompactionInfoListResult &result) +{ + int ret = OB_SUCCESS; + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(arg)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(arg.ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(arg)); + } else if (OB_FAIL(ObDDLUtil::ddl_get_tablet(ls_handle, + arg.tablet_id_, tablet_handle, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("get tablet handle failed", K(ret), K(arg)); + } else if (OB_ISNULL(tablet = tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null", K(ret), K(arg)); + } else { + common::ObArenaAllocator allocator; + ObTableStoreIterator table_store_iterator; + ObSEArray major_tables; + const compaction::ObMediumCompactionInfoList *medium_info_list = nullptr; + if (OB_FAIL(tablet->read_medium_info_list(allocator, medium_info_list))) { + LOG_WARN("failed to get mediumn info list", K(ret)); + } else if (medium_info_list->size() > 0) { + // compaction still ongoing + result.info_list_cnt_ = medium_info_list->size(); + result.primary_compaction_scn_ = -1; + } else if (OB_FAIL(tablet->get_all_sstables(table_store_iterator))) { + LOG_WARN("fail to fetch table store", K(ret)); + } else if (OB_FAIL(ObTabletSplitUtil::get_participants(ObSplitSSTableType::SPLIT_MAJOR, table_store_iterator, major_tables))) { + LOG_WARN("get participant sstables failed", K(ret)); + } else { + result.info_list_cnt_ = 0; + result.primary_compaction_scn_ = -1; + ObSSTable *sstable = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < major_tables.count(); i++) { + if (OB_ISNULL(sstable = static_cast(major_tables.at(i)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), KPC(sstable)); + } else { + const int64_t snapshot_version = sstable->get_snapshot_version(); + result.primary_compaction_scn_ = MAX(result.primary_compaction_scn_, snapshot_version); + } + } + if (OB_SUCC(ret) && -1 == result.primary_compaction_scn_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error", K(ret), K(major_tables)); + } + } + } + LOG_INFO("receive check medium compaction info list", K(ret), K(arg), K(result)); + return ret; +} + +int ObTabletSplitUtil::check_tablet_restore_status( + const ObArray &dest_tablets_id, + const ObLSHandle &ls_handle, + const ObTabletHandle &source_tablet_handle, + bool &is_tablet_status_need_to_split) +{ + int ret = OB_SUCCESS; + is_tablet_status_need_to_split = true; + ObTablet *source_tablet = nullptr; + ObTabletRestoreStatus::STATUS source_restore_status = ObTabletRestoreStatus::STATUS::RESTORE_STATUS_MAX; + ObLS *ls = nullptr; + if (OB_UNLIKELY(dest_tablets_id.count() <= 0 || !ls_handle.is_valid() || !source_tablet_handle.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(dest_tablets_id), K(source_tablet_handle), K(ls_handle)); + } else if (OB_ISNULL(source_tablet = source_tablet_handle.get_obj()) || OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("unexpected nullptr", K(ret), KP(source_tablet), KP(ls)); + } else if (OB_FAIL(source_tablet->get_restore_status(source_restore_status))) { + LOG_WARN("failed to get restore status", K(ret), KP(source_tablet)); + } else if (OB_UNLIKELY(ObTabletRestoreStatus::STATUS::UNDEFINED == source_restore_status + || ObTabletRestoreStatus::STATUS::EMPTY == source_restore_status || ObTabletRestoreStatus::STATUS::REMOTE == source_restore_status)) { + is_tablet_status_need_to_split = false; + ObTabletHandle t_handle; + ObTabletRestoreStatus::STATUS des_restore_status = ObTabletRestoreStatus::STATUS::RESTORE_STATUS_MAX; + ObArray des_tablet_status; + ObTablet *tablet = nullptr; + for (int64_t i = 0; OB_SUCC(ret) && i < dest_tablets_id.count(); ++i) { + t_handle.reset(); + const ObTabletID &t_id = dest_tablets_id.at(i); + if (OB_FAIL(ls->get_tablet(t_id, t_handle))) { + LOG_WARN("failed to get table", K(ret), K(t_id)); + } else if (OB_ISNULL(tablet = t_handle.get_obj())) { + ret = OB_NULL_CHECK_ERROR; + LOG_WARN("unexpected null ptr of tablet", K(ret), KPC(tablet)); + } else if (OB_FAIL(tablet->get_restore_status(des_restore_status))) { + LOG_WARN("failed to get restore status of tablet", K(ret), K(tablet)); + } else if (OB_FAIL(des_tablet_status.push_back(des_restore_status))) { + LOG_WARN("failed to push back into des_tablet_status", K(ret), K(i), K(des_tablet_status)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(des_tablet_status.count() != dest_tablets_id.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("the count of des_tablet_status doesn't equal to the count of dest_tablets_id", + K(ret), K(des_tablet_status.count()), K(dest_tablets_id.count())); + } else if (((ObTabletRestoreStatus::STATUS::EMPTY == source_restore_status)) + || (ObTabletRestoreStatus::STATUS::REMOTE == source_restore_status)) { + for (int64_t i = 0; OB_SUCC(ret) && i < des_tablet_status.count() && !is_tablet_status_need_to_split; ++i) { + ObTabletRestoreStatus::STATUS &des_res_sta = des_tablet_status.at(i); + if (ObTabletRestoreStatus::STATUS::FULL == des_res_sta) { + is_tablet_status_need_to_split = true; + } + } + } + if (OB_SUCC(ret) && !is_tablet_status_need_to_split) { + LOG_INFO("tablets' resotre status are unexpected:", "src_tablet_id", source_tablet_handle.get_obj()->get_tablet_id(), K(dest_tablets_id), + K(source_restore_status), "dst_tablet_restore_status", des_tablet_status); + } + } + return ret; +} + +} //end namespace stroage +} //end namespace oceanbase diff --git a/src/storage/ddl/ob_tablet_split_task.h b/src/storage/ddl/ob_tablet_split_task.h new file mode 100644 index 000000000..850ccca7a --- /dev/null +++ b/src/storage/ddl/ob_tablet_split_task.h @@ -0,0 +1,434 @@ +/** + * 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_TABLET_SPLIT_TASK_H +#define OCEANBASE_STORAGE_OB_TABLET_SPLIT_TASK_H + +#include "share/ob_ddl_common.h" +#include "share/scheduler/ob_tenant_dag_scheduler.h" +#include "share/schema/ob_table_param.h" +#include "storage/access/ob_table_access_context.h" +#include "storage/access/ob_store_row_iterator.h" +#include "storage/access/ob_sstable_row_whole_scanner.h" +#include "storage/blocksstable/index_block/ob_index_block_builder.h" +#include "storage/ddl/ob_complement_data_task.h" +#include "storage/ddl/ob_ddl_merge_task.h" + +namespace oceanbase +{ +namespace storage +{ +struct ObSplitSSTableTaskKey final +{ +public: + ObSplitSSTableTaskKey() + : src_sst_key_(), dest_tablet_id_() { } + ObSplitSSTableTaskKey(const ObITable::TableKey &src_key, const ObTabletID &dst_tablet_id) + : src_sst_key_(src_key), dest_tablet_id_(dst_tablet_id) + { } + ~ObSplitSSTableTaskKey() = default; + int64_t hash() const { return src_sst_key_.hash() + dest_tablet_id_.hash(); } + int hash(uint64_t &hash_val) const { hash_val = hash(); return OB_SUCCESS; } + bool operator== (const ObSplitSSTableTaskKey &other) const { + return src_sst_key_ == other.src_sst_key_ && dest_tablet_id_ == other.dest_tablet_id_; + } + bool is_valid() const { return src_sst_key_.is_valid() && dest_tablet_id_.is_valid(); } + TO_STRING_KV(K_(src_sst_key), K_(dest_tablet_id)); +public: + ObITable::TableKey src_sst_key_; + ObTabletID dest_tablet_id_; +}; + +typedef std::pair TabletBoundPair; + +struct ObTabletSplitParam : public share::ObIDagInitParam +{ +public: + ObTabletSplitParam(); + virtual ~ObTabletSplitParam(); + bool is_valid() const; + int init(const ObTabletSplitParam ¶m); + int init(const obrpc::ObDDLBuildSingleReplicaRequestArg &arg); + int init(const obrpc::ObTabletSplitArg &arg); + TO_STRING_KV(K_(is_inited), K_(tenant_id), K_(ls_id), K_(table_id), K_(schema_version), + K_(task_id), K_(source_tablet_id), K_(dest_tablets_id), K_(compaction_scn), K_(user_parallelism), + K_(compat_mode), K_(data_format_version), K_(consumer_group_id), + K_(can_reuse_macro_block), K_(split_sstable_type), K_(parallel_datum_rowkey_list)); +private: + common::ObArenaAllocator rowkey_allocator_; // for DatumRowkey. +public: + bool is_inited_; + uint64_t tenant_id_; + share::ObLSID ls_id_; + int64_t table_id_; + int64_t schema_version_; // always the data table schema version + int64_t task_id_; // ddl task id. + ObTabletID source_tablet_id_; + ObArray dest_tablets_id_; + int64_t compaction_scn_; + int64_t user_parallelism_; + lib::Worker::CompatMode compat_mode_; + int64_t data_format_version_; + uint64_t consumer_group_id_; + bool can_reuse_macro_block_; + share::ObSplitSSTableType split_sstable_type_; + common::ObSArray parallel_datum_rowkey_list_; + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitParam); +}; + +struct ObTabletSplitCtx final +{ +public: + ObTabletSplitCtx(); + ~ObTabletSplitCtx(); + int init(const ObTabletSplitParam ¶m); + bool is_valid() const; + TO_STRING_KV(K_(is_inited), K_(data_split_ranges), K_(complement_data_ret), K_(row_inserted), K_(physical_row_count)); + +private: + struct GetMapItemKeyFn final + { + public: + GetMapItemKeyFn() : map_keys_(), ret_code_(OB_SUCCESS) {} + ~GetMapItemKeyFn() = default; + int operator() (common::hash::HashMapPair &entry) + { + int ret = ret_code_; // for LOG_WARN + if (OB_LIKELY(OB_SUCCESS == ret_code_) && OB_SUCCESS != (ret_code_ = map_keys_.push_back(entry.first))) { + ret = ret_code_; + LOG_WARN("push back map item key failed", K(ret_code_), K(entry.first)); + } + return ret_code_; + } + public: + ObArray map_keys_; + int ret_code_; + }; +public: + // generate index tree. + int prepare_index_builder(const ObTabletSplitParam ¶m); +private: + common::ObArenaAllocator range_allocator_; // for datum range. +public: + typedef common::hash::ObHashMap< + ObSplitSSTableTaskKey, ObSSTableIndexBuilder*> INDEX_BUILDER_MAP; + bool is_inited_; + ObSEArray data_split_ranges_; + int complement_data_ret_; + ObLSHandle ls_handle_; + ObTabletHandle tablet_handle_; // is important, rowkey_read_info, source_tables rely on it. + ObTableStoreIterator table_store_iterator_; + // for rewrite macro block task. + INDEX_BUILDER_MAP index_builder_map_; // map between source sstable and dest sstables. + common::ObArenaAllocator allocator_; + int64_t row_inserted_; + int64_t physical_row_count_; + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitCtx); +}; + +class ObTabletSplitDag final: public share::ObIDag +{ +public: + ObTabletSplitDag(); + virtual ~ObTabletSplitDag(); + virtual int init_by_param(const share::ObIDagInitParam *param) override; + virtual int create_first_task() override; + int64_t hash() const; + bool operator ==(const share::ObIDag &other) const; + bool is_inited() const { return is_inited_; } + ObTabletSplitCtx &get_context() { return context_; } + void handle_init_failed_ret_code(int ret) { context_.complement_data_ret_ = ret; } + int fill_info_param(compaction::ObIBasicInfoParam *&out_param, ObIAllocator &allocator) const override; + int fill_dag_key(char *buf, const int64_t buf_len) const override; + virtual lib::Worker::CompatMode get_compat_mode() const override + { return param_.compat_mode_; } + virtual uint64_t get_consumer_group_id() const override + { return consumer_group_id_; } + virtual bool is_ha_dag() const override { return false; } + int report_replica_build_status(); + int calc_total_row_count(); +private: + bool is_inited_; + ObTabletSplitParam param_; + ObTabletSplitCtx context_; + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitDag); +}; + +class ObTabletSplitPrepareTask final : public share::ObITask +{ +public: + ObTabletSplitPrepareTask() + : ObITask(TASK_TYPE_DDL_SPLIT_PREPARE), is_inited_(false), param_(nullptr), context_(nullptr) + { } + virtual ~ObTabletSplitPrepareTask() = default; + int init(ObTabletSplitParam ¶m, ObTabletSplitCtx &ctx); + virtual int process() override; +private: + int prepare_context(); +private: + bool is_inited_; + ObTabletSplitParam *param_; + ObTabletSplitCtx *context_; + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitPrepareTask); +}; + +class ObTabletSplitWriteTask final : public share::ObITask +{ +public: + ObTabletSplitWriteTask(); + virtual ~ObTabletSplitWriteTask(); + int init(const int64_t task_id, + ObTabletSplitParam ¶m, ObTabletSplitCtx &ctx, storage::ObITable *table); + virtual int process() override; +private: + int generate_next_task(ObITask *&next_task); + // fill nop for minor, and fill orig default value for major. + int fill_tail_column_datums( + const blocksstable::ObDatumRow &scan_row); + int prepare_macro_block_writer( + ObIArray &data_desc_arr, + ObIArray ¯o_block_writer_arr); + // for reuse macro block task. + int prepare_sorted_high_bound_pair( + common::ObSArray &tablet_bound_arr); + int process_reuse_macro_block_task( + const ObIArray ¯o_block_writer_arr); + int process_rows_for_reuse_task( + const ObIArray &tablet_bound_arr, + const ObIArray ¯o_block_writer_arr, + const ObMacroBlockDesc &data_macro_desc, + int64_t &dest_tablet_index); + // for rewrite macro block task. + int process_rewrite_macro_block_task( + const ObIArray ¯o_block_writer_arr); + int process_rows_for_rewrite_task( + const ObIArray ¯o_block_writer_arr, + const ObDatumRange &query_range); +private: + static const int64_t MAP_BUCKET_NUM = 100; + bool is_inited_; + ObTabletSplitParam *param_; + ObTabletSplitCtx *context_; + ObSSTable *sstable_; // split source sstable. + const ObITableReadInfo *rowkey_read_info_; + blocksstable::ObDatumRow write_row_; + blocksstable::ObDatumRow default_row_; + + // for rewrite macro block task. + int64_t task_id_; + common::ObArenaAllocator allocator_; + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitWriteTask); +}; + +class ObTabletSplitMergeTask final : public share::ObITask +{ +public: + ObTabletSplitMergeTask() + : ObITask(TASK_TYPE_DDL_SPLIT_MERGE), is_inited_(false), param_(nullptr), context_(nullptr) + { } + virtual ~ObTabletSplitMergeTask() = default; + int init(ObTabletSplitParam ¶m, ObTabletSplitCtx &ctx); + virtual int process() override; + static int check_need_fill_empty_sstable( + ObLSHandle &ls_handle, + const bool is_minor_sstable, + const ObITable::TableKey &table_key, + const ObTabletID &dst_tablet_id, + bool &need_fill_empty_sstable, + SCN &end_scn); + static int build_create_empty_sstable_param( + const ObSSTableBasicMeta &meta, + const ObITable::TableKey &table_key, + const ObTabletID &dst_tablet_id, + const SCN &end_scn, + ObTabletCreateSSTableParam &create_sstable_param); + static int update_table_store_with_batch_tables( + const ObLSHandle &ls_handle, + const ObTabletHandle &src_tablet_handle, + const ObTabletID &dst_tablet_id, + const ObTablesHandleArray &tables_handle, + const share::ObSplitSSTableType &split_sstable_type); +private: + int create_sstable( + const share::ObSplitSSTableType &split_sstable_type); + int build_create_sstable_param( + const ObSSTable &src_table, + const ObTabletID &dst_tablet_id, + ObSSTableIndexBuilder *index_builder, + ObTabletCreateSSTableParam &create_sstable_param); +private: + bool is_inited_; + ObTabletSplitParam *param_; + ObTabletSplitCtx *context_; + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitMergeTask); +}; + +struct ObSplitScanParam final +{ +public: + ObSplitScanParam( + const int64_t table_id, + ObTablet &src_tablet, + const ObDatumRange &query_range) : + table_id_(table_id), src_tablet_(src_tablet), query_range_(&query_range) + { } + ~ObSplitScanParam() = default; + bool is_valid() const { + return table_id_ > 0 && src_tablet_.is_valid() && nullptr != query_range_; + } + TO_STRING_KV(K_(table_id), K_(src_tablet), KPC_(query_range)); +public: + int64_t table_id_; + ObTablet &src_tablet_; // split source tablet. + const ObDatumRange *query_range_; // whole_range for sstable scan. +}; + +class ObRowScan : public ObIStoreRowIterator +{ +public: + ObRowScan(); + virtual ~ObRowScan(); + // to scan the sstable with the specified query_range. + int init( + const ObSplitScanParam ¶m, + ObSSTable &sstable); + + // to scan the specified whole macro block. + int init( + const ObSplitScanParam ¶m, + const blocksstable::ObMacroBlockDesc ¯o_desc, + ObSSTable &sstable); + + virtual int get_next_row(const blocksstable::ObDatumRow *&tmp_row) override; + + const ObITableReadInfo *get_rowkey_read_info() const { return rowkey_read_info_; } + storage::ObTxTableGuards &get_tx_table_guards() { return ctx_.mvcc_acc_ctx_.get_tx_table_guards(); } + + TO_STRING_KV(K_(is_inited), K_(ctx), K_(access_ctx), KPC_(rowkey_read_info), K_(access_param)); +private: + int construct_access_param( + const ObSplitScanParam ¶m); + int construct_access_ctx( + const share::ObLSID &ls_id, + const ObTabletID &tablet_id); +private: + bool is_inited_; + ObSSTableRowWholeScanner *row_iter_; + ObStoreCtx ctx_; + ObTableAccessContext access_ctx_; + const ObITableReadInfo *rowkey_read_info_; // with extra rowkey. + ObTableAccessParam access_param_; + common::ObArenaAllocator allocator_; +}; + +class ObSnapshotRowScan final : public ObIStoreRowIterator +{ +public: + ObSnapshotRowScan(); + virtual ~ObSnapshotRowScan(); + void reset(); + int init( + const ObSplitScanParam ¶m, + const ObIArray &schema_store_col_descs, + const int64_t schema_column_cnt, + const int64_t schema_rowkey_cnt, + const bool is_oracle_mode, + const ObTabletHandle &tablet_handle, + const int64_t snapshot_version); + int construct_access_param( + const uint64_t table_id, + const common::ObTabletID &tablet_id, + const ObITableReadInfo &read_info); + int construct_range_ctx(ObQueryFlag &query_flag, const share::ObLSID &ls_id); + int construct_multiple_scan_merge(const ObTabletTableIterator &table_iter, const ObDatumRange &range); + int add_extra_rowkey(const ObDatumRow &row); + virtual int get_next_row(const blocksstable::ObDatumRow *&tmp_row) override; + TO_STRING_KV(K_(is_inited)); +private: + bool is_inited_; + common::ObArenaAllocator allocator_; + int64_t snapshot_version_; + int64_t schema_rowkey_cnt_; + ObDatumRange range_; + ObTableReadInfo read_info_; + ObDatumRow write_row_; + ObArray out_cols_projector_; + ObTableAccessParam access_param_; + ObStoreCtx ctx_; + ObTableAccessContext access_ctx_; + ObGetTableParam get_table_param_; + ObMultipleScanMerge *scan_merge_; +}; + +class ObUncommittedRowScan : public ObIStoreRowIterator +{ +public: + ObUncommittedRowScan(); + virtual ~ObUncommittedRowScan(); + int init( + const ObSplitScanParam param, + ObSSTable &src_sstable, + const int64_t major_snapshot_version); + virtual int get_next_row(const blocksstable::ObDatumRow *&tmp_row) override; +private: + int check_can_skip(const blocksstable::ObDatumRow &row, bool &can_skip); +private: + ObRowScan row_scan_; + int64_t major_snapshot_version_; + int64_t trans_version_col_idx_; +}; + +struct ObTabletSplitUtil final +{ +public: + static int get_participants( + const share::ObSplitSSTableType &split_sstable_type, + const ObTableStoreIterator &table_store_iterator, + ObIArray &participants); + static int split_task_ranges( + ObIAllocator &allocator, + const share::ObLSID &ls_id, + const ObTabletID &tablet_id, + const int64_t user_parallelism, + const int64_t schema_tablet_size, + ObIArray ¶llel_datum_rowkey_list); + static int convert_rowkey_to_range( + ObIAllocator &allocator, + const ObIArray ¶llel_datum_rowkey_list, + ObIArray &datum_ranges_array); + static int check_major_sstables_exist( + const share::ObLSID &ls_id, + const ObIArray &check_tablets_id, + bool &is_all_major_exists); + static int check_satisfy_split_condition( + const ObArray &dest_tablets_id, + const int64_t compaction_scn, + const ObTabletHandle &source_tablet_handle, + const ObLSHandle &ls_handle); + static int get_split_dest_tablets_info( + const share::ObLSID &ls_id, + const ObTabletID &source_tablet_id, + ObIArray &dest_tablets_id, + lib::Worker::CompatMode &compat_mode); + static int check_medium_compaction_info_list_cnt( + const obrpc::ObCheckMediumCompactionInfoListArg &arg, + obrpc::ObCheckMediumCompactionInfoListResult &result); + static int check_tablet_restore_status( + const ObArray &dest_tablets_id, + const ObLSHandle &ls_handle, + const ObTabletHandle &source_tablet_handle, + bool &is_tablet_status_need_to_split); +}; + +} // end namespace storage +} // end namespace oceanbase +#endif // OCEANBASE_STORAGE_OB_TABLET_SPLIT_TASK_H diff --git a/src/storage/direct_load/ob_direct_load_origin_table.cpp b/src/storage/direct_load/ob_direct_load_origin_table.cpp index ef9f6751a..030866df1 100644 --- a/src/storage/direct_load/ob_direct_load_origin_table.cpp +++ b/src/storage/direct_load/ob_direct_load_origin_table.cpp @@ -118,7 +118,7 @@ int ObDirectLoadOriginTable::prepare_tables() table_iter_.reset(); if (OB_FAIL(table_iter_.set_tablet_handle(tablet_handle_))) { LOG_WARN("Failed to set tablet handle to tablet table iter", K(ret)); - } else if (OB_FAIL(table_iter_.refresh_read_tables_from_tablet(INT64_MAX, false /*allow_not_ready*/))) { + } else if (OB_FAIL(table_iter_.refresh_read_tables_from_tablet(INT64_MAX, false /*allow_not_ready*/, false /*major_sstable_only*/, false /*need_split_src_table*/, false/*need_split_dst_table*/))) { LOG_WARN("fail to get read tables", KR(ret), K(tablet_handle_)); } // find major sstable or ddl sstables @@ -375,7 +375,7 @@ int ObDirectLoadOriginTableScanner::init_get_table_param() int ret = OB_SUCCESS; if (OB_FAIL(get_table_param_.tablet_iter_.set_tablet_handle(origin_table_->get_tablet_handle()))) { LOG_WARN("Failed to set tablet handle to tablet table iter", K(ret)); - } else if (OB_FAIL(get_table_param_.tablet_iter_.refresh_read_tables_from_tablet(INT64_MAX, false /*allow_not_ready*/))) { + } else if (OB_FAIL(get_table_param_.tablet_iter_.refresh_read_tables_from_tablet(INT64_MAX, false /*allow_not_ready*/, false /*major_sstable_only*/, false /*need_split_src_table*/, false /*need_split_dst_table*/))) { LOG_WARN("fail to copy table iter", KR(ret)); } return ret; diff --git a/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp b/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp index e9585dfd5..c7fd43633 100644 --- a/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp +++ b/src/storage/high_availability/ob_storage_ha_tablet_builder.cpp @@ -2756,7 +2756,7 @@ int ObStorageHATabletBuilderUtil::inner_update_tablet_table_store_with_minor_( if (OB_FAIL(update_table_store_param.tables_handle_.assign(tables_handle))) { LOG_WARN("failed to assign tables handle", K(ret), K(tables_handle)); - } else if (OB_FAIL(ls->build_ha_tablet_new_table_store(tablet_id, update_table_store_param))) { + } else if (OB_FAIL(ls->build_tablet_with_batch_tables(tablet_id, update_table_store_param))) { LOG_WARN("failed to build ha tablet new table store", K(ret), K(tablet_id), KPC(tablet), KPC(src_tablet_meta), K(update_table_store_param)); } } diff --git a/src/storage/high_availability/ob_storage_ha_utils.cpp b/src/storage/high_availability/ob_storage_ha_utils.cpp index ab559df26..74ecfd7ac 100644 --- a/src/storage/high_availability/ob_storage_ha_utils.cpp +++ b/src/storage/high_availability/ob_storage_ha_utils.cpp @@ -287,7 +287,8 @@ int ObStorageHAUtils::check_tablet_is_deleted( LOG_WARN("failed to get latest tablet status", K(ret), KPC(tablet)); } } else if (ObTabletStatus::DELETED == data.tablet_status_ - || ObTabletStatus::TRANSFER_OUT_DELETED == data.tablet_status_) { + || ObTabletStatus::TRANSFER_OUT_DELETED == data.tablet_status_ + || ObTabletStatus::SPLIT_SRC_DELETED == data.tablet_status_) { is_deleted = true; } return ret; diff --git a/src/storage/high_availability/ob_transfer_backfill_tx.cpp b/src/storage/high_availability/ob_transfer_backfill_tx.cpp index d3cefa5a4..3202e1bf6 100644 --- a/src/storage/high_availability/ob_transfer_backfill_tx.cpp +++ b/src/storage/high_availability/ob_transfer_backfill_tx.cpp @@ -1667,7 +1667,7 @@ int ObTransferReplaceTableTask::transfer_replace_tables_( "has_transfer_table", tablet->get_tablet_meta().has_transfer_table()); #endif - if (FAILEDx(ls->build_ha_tablet_new_table_store(tablet_info.tablet_id_, param))) { + if (FAILEDx(ls->build_tablet_with_batch_tables(tablet_info.tablet_id_, param))) { LOG_WARN("failed to build ha tablet new table store", K(ret), K(param), K(tablet_info)); } else { LOG_INFO("[TRANSFER_BACKFILL]succ transfer replace tables", K(ret), K(param), K(tablet_info), KPC_(ctx)); diff --git a/src/storage/lob/ob_ext_info_callback.cpp b/src/storage/lob/ob_ext_info_callback.cpp index 5db3148cb..8f2f4557f 100644 --- a/src/storage/lob/ob_ext_info_callback.cpp +++ b/src/storage/lob/ob_ext_info_callback.cpp @@ -128,7 +128,6 @@ memtable::MutatorType ObExtInfoCallback::get_mutator_type() const return memtable::MutatorType::MUTATOR_ROW_EXT_INFO; } - int ObExtInfoCallback::log_submitted(const SCN scn, storage::ObIMemtable *&last_mt) { return release_resource(); @@ -227,6 +226,33 @@ int ObExtInfoCallback::set( return ret; } +int ObExtInfoCbRegister::alloc_seq_no( + transaction::ObTxDesc *tx_desc, + const transaction::ObTxSEQ &parent_seq_no, + const int64_t data_size, + transaction::ObTxSEQ &seq_no_st, + int64_t &seq_no_cnt) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(tx_desc)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("tx desc is null", K(ret)); + } else if (data_size <= 0) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("data_size is invalid", K(ret), K(data_size)); + } else { + if (data_size % OB_EXT_INFO_LOG_BLOCK_MAX_SIZE > 0) { + seq_no_cnt = data_size / OB_EXT_INFO_LOG_BLOCK_MAX_SIZE + 1; + } else { + seq_no_cnt = data_size / OB_EXT_INFO_LOG_BLOCK_MAX_SIZE; + } + if (OB_FAIL(tx_desc->get_and_inc_tx_seq(parent_seq_no.get_branch(), seq_no_cnt, seq_no_st))) { + LOG_WARN("alloc seq_no fail", K(ret), K(parent_seq_no), KPC(tx_desc)); + } + } + return ret; +} + ObExtInfoCbRegister::~ObExtInfoCbRegister() { if (OB_NOT_NULL(lob_param_)) { @@ -238,7 +264,6 @@ ObExtInfoCbRegister::~ObExtInfoCbRegister() // date_iter is alloc from ObLobManager::query // that use ob_malloc alloc memory, so here use ob_delete data_iter_->reset(); - data_iter_->~ObLobQueryIter(); OB_DELETE(ObLobQueryIter, "unused", data_iter_); data_iter_ = nullptr; } @@ -248,55 +273,49 @@ int ObExtInfoCbRegister::register_cb( memtable::ObIMvccCtx *ctx, const int64_t timeout, const blocksstable::ObDmlFlag dml_flag, - transaction::ObTxDesc *tx_desc, - transaction::ObTxSEQ &parent_seq_no, - blocksstable::ObStorageDatum &index_data, - ObObjType &type, + const transaction::ObTxSEQ &seq_no_st, + const int64_t seq_no_cnt, + const ObExtInfoLogHeader &header, ObObj &ext_info_data) { int ret = OB_SUCCESS; ext_info_data_ = ext_info_data; timeout_ = timeout; + seq_no_st_ = seq_no_st; + seq_no_cnt_ = seq_no_cnt; + header_ = header; ObLobManager *lob_mngr = MTL(ObLobManager*); if (OB_ISNULL(lob_mngr)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("[STORAGE_LOB]get lob manager instance failed.", K(ret)); - } else if (OB_ISNULL(tx_desc)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tx_desc is null", K(ret)); } else if (ext_info_data.is_null()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("data is empty", K(ret), K(ext_info_data)); } else if (OB_ISNULL(mvcc_ctx_ = ctx)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("data is empty", K(ret), K(ext_info_data)); - } else if (OB_FAIL(init_header(type))) { - LOG_WARN("init_header_ fail", K(ret), K(ext_info_data)); } else if (OB_FAIL(build_data_iter(ext_info_data))) { LOG_WARN("build data iter fail", K(ret)); - } else if (FALSE_IT(seq_no_cnt_ = data_size_/OB_EXT_INFO_LOG_BLOCK_MAX_SIZE + 1)) { - } else if (OB_FAIL(tx_desc->get_and_inc_tx_seq(parent_seq_no.get_branch(), - seq_no_cnt_, - seq_no_st_))) { - LOG_WARN("get and inc tx seq failed", K(ret), K_(seq_no_cnt)); } else { transaction::ObTxSEQ seq_no_cur = seq_no_st_; ObString data; int cb_cnt = 0; while (OB_SUCC(ret) && OB_SUCC(get_data(data))) { storage::ObExtInfoCallback *cb = nullptr; - if (OB_ISNULL(cb = mvcc_ctx_->alloc_ext_info_callback())) { + if (cb_cnt >= seq_no_cnt_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("seq no alloc too small", K(ret), K(seq_no_cnt_), K(cb_cnt), K(data_size_)); + } else if (OB_ISNULL(cb = mvcc_ctx_->alloc_ext_info_callback())) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("alloc row callback failed", K(ret)); + } else if (OB_FAIL(cb->set(tmp_allocator_, dml_flag, seq_no_cur, data))) { + LOG_WARN("set row callback failed", K(ret), K(*cb)); + } else if (OB_FAIL(mvcc_ctx_->append_callback(cb))) { + LOG_WARN("register ext info callback failed", K(ret), K(*this),K(*cb)); } else { - cb->set(tmp_allocator_, dml_flag, seq_no_cur, data); seq_no_cur = seq_no_cur + 1; - if (OB_FAIL(mvcc_ctx_->append_callback(cb))) { - LOG_ERROR("register ext info callback failed", K(ret), K(*this),K(*cb)); - } else { - ++cb_cnt; - LOG_DEBUG("register ext info callback success", K(*cb)); - } + ++cb_cnt; + LOG_DEBUG("register ext info callback success", K(*cb)); } if (OB_FAIL(ret) && OB_NOT_NULL(cb)) { mvcc_ctx_->free_ext_info_callback(cb); @@ -305,61 +324,15 @@ int ObExtInfoCbRegister::register_cb( if (OB_ITER_END == ret) { ret = OB_SUCCESS; } - if (OB_FAIL(ret)) { - } else if (OB_FALSE_IT(seq_no_cnt_ = cb_cnt)) { - } else if (OB_FAIL(set_index_data(index_data, type))) { - LOG_WARN("set_index_data fail", K(ret)); + + if (OB_SUCC(ret) && cb_cnt != seq_no_cnt_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("seq_no used is not match", K(ret), K(seq_no_cnt_), K(cb_cnt), K(data_size_)); } } return ret; } -int ObExtInfoCbRegister::init_header(ObObjType &type) -{ - int ret = OB_SUCCESS; - header_.type_ = get_type(type); - return ret; -} - -int ObExtInfoCbRegister::set_index_data(blocksstable::ObStorageDatum &index_data, ObObjType &type) -{ - int ret = OB_SUCCESS; - if (is_lob_storage(type)) { - if (OB_FAIL(set_outrow_ctx_seq_no(index_data))) { - LOG_WARN("set_outrow_ctx_seq_no fail", K(ret)); - } - } else { - ret = OB_NOT_SUPPORTED; - LOG_WARN("not support type", K(ret), K(index_data)); - } - return ret; -} - -int ObExtInfoCbRegister::set_outrow_ctx_seq_no(blocksstable::ObStorageDatum& index_data) -{ - int ret = OB_SUCCESS; - ObLobLocatorV2 locator; - ObLobCommon *lob_common = nullptr; - ObString str_data = index_data.get_string(); - if (str_data.empty()) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("index lob data is empty", K(ret), K(index_data)); - } else if (OB_ISNULL(lob_common = reinterpret_cast(str_data.ptr()))) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("lob_common is null", K(ret), K(index_data)); - } else if (! lob_common->is_valid() || lob_common->in_row_ || lob_common->is_mem_loc_ || ! lob_common->is_init_ ) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid lob", K(ret), K(*lob_common)); - } else { - ObLobData *lob_data = reinterpret_cast(lob_common->buffer_); - ObLobDataOutRowCtx *lob_data_outrow_ctx = reinterpret_cast(lob_data->buffer_); - lob_data_outrow_ctx->seq_no_st_ = seq_no_st_.cast_to_int(); - lob_data_outrow_ctx->seq_no_cnt_ = seq_no_cnt_; - lob_data_outrow_ctx->modified_len_ = data_size_ + header_.get_serialize_size(); - } - return ret; -} - int ObExtInfoCbRegister::build_data_iter(ObObj &ext_info_data) { int ret = OB_SUCCESS; diff --git a/src/storage/lob/ob_ext_info_callback.h b/src/storage/lob/ob_ext_info_callback.h index bd6b8fdaf..d22065f8b 100644 --- a/src/storage/lob/ob_ext_info_callback.h +++ b/src/storage/lob/ob_ext_info_callback.h @@ -43,6 +43,10 @@ struct ObExtInfoLogHeader type_(0) {} + ObExtInfoLogHeader(const ObExtInfoLogType type): + type_(type) + {} + ObExtInfoLogType get_type() const { return static_cast(type_); } bool is_json_diff() const { return get_type() == OB_JSON_DIFF_EXT_INFO_LOG; } @@ -101,7 +105,6 @@ public: virtual memtable::MutatorType get_mutator_type() const override; virtual transaction::ObTxSEQ get_seq_no() const override { return seq_no_cur_; } virtual int64_t get_data_size() override { return mutator_row_len_; }; - virtual int log_submitted(const SCN scn, storage::ObIMemtable *&last_mt); virtual int release_resource(); @@ -131,6 +134,14 @@ public: static const int32_t OB_EXT_INFO_LOG_HEADER_LEN = 1; static const int64_t OB_EXT_INFO_LOG_BLOCK_MAX_SIZE; +public: + static int alloc_seq_no( + transaction::ObTxDesc *tx_desc, + const transaction::ObTxSEQ &parent_seq_no, + const int64_t data_size, /*include header size*/ + transaction::ObTxSEQ &seq_no_st, + int64_t &seq_no_cnt); + public: ObExtInfoCbRegister(): tmp_allocator_(lib::ObMemAttr(MTL_ID(), "ExtInfoLogReg")), @@ -153,37 +164,17 @@ public: memtable::ObIMvccCtx *ctx, const int64_t timeout, const blocksstable::ObDmlFlag dml_flag, - transaction::ObTxDesc *tx_desc, - transaction::ObTxSEQ &parent_seq_no, - blocksstable::ObStorageDatum &index_data, - ObObjType &type, + const transaction::ObTxSEQ &seq_no_st, + const int64_t seq_no_cnt, + const ObExtInfoLogHeader &header, ObObj &ext_info_data); private: - static ObExtInfoLogType get_type(ObObjType &obj_type) - { - ObExtInfoLogType res = OB_INVALID_EXT_INFO_LOG; - switch (obj_type) - { - case ObJsonType: - res = OB_JSON_DIFF_EXT_INFO_LOG; - break; - default: - break; - } - return res; - } - int build_data_iter(ObObj &ext_info_data); - int set_index_data(blocksstable::ObStorageDatum &index_data, ObObjType &type); - int set_outrow_ctx_seq_no(blocksstable::ObStorageDatum& index_data); - int get_data(ObString &data); - int init_header(ObObjType &type); - public: TO_STRING_KV(K(timeout_), K(data_size_), K(seq_no_st_), K(seq_no_cnt_), K(header_writed_)); diff --git a/src/storage/lob/ob_lob_locator_struct.cpp b/src/storage/lob/ob_lob_locator_struct.cpp new file mode 100644 index 000000000..524333072 --- /dev/null +++ b/src/storage/lob/ob_lob_locator_struct.cpp @@ -0,0 +1,207 @@ +/** + * 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/lob/ob_lob_manager.h" + +namespace oceanbase +{ +using namespace common; +using namespace share; +namespace storage +{ + +int ObLobDiskLocatorWrapper::get_char_len(const ObLobLocatorV2 &locator, uint64_t &char_len) +{ + int ret = OB_SUCCESS; + ObString disk_locator; + if (OB_FAIL(locator.get_disk_locator(disk_locator))) { + LOG_WARN("failed to get lob common from lob locator", K(ret), K(locator)); + } else if (disk_locator.length() != ObLobManager::LOB_OUTROW_FULL_SIZE) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("disk locator invalid", K(ret), K(locator)); + } else { + ObLobCommon *lob_common = reinterpret_cast(disk_locator.ptr()); + ObLobData *lob_data = reinterpret_cast(lob_common->buffer_); + ObLobDataOutRowCtx *outrow_ctx = reinterpret_cast(lob_data->buffer_); + uint64_t *char_len_ptr = reinterpret_cast(outrow_ctx + 1); + char_len = *char_len_ptr; + } + return ret; +} + +bool ObLobDiskLocatorWrapper::is_valid() const +{ + return nullptr != lob_common_ && nullptr != lob_data_ && nullptr != outrow_ctx_ && nullptr != char_len_ptr_; +} + +int ObLobDiskLocatorWrapper::init(char *ptr, const int64_t len) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(check_disk_locator_length(len))) { + LOG_WARN("check_disk_locator_length fail", K(ret), K(len), KP(ptr)); + } else if (OB_ISNULL(lob_common_ = reinterpret_cast(ptr))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("lob common is null", K(ret), K(len), KP(ptr)); + } else if (lob_common_->in_row_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("can not be inrow", K(ret), KPC_(lob_common), K(len), KP(ptr)); + } else { + lob_data_ = reinterpret_cast(lob_common_->buffer_); + outrow_ctx_ = reinterpret_cast(lob_data_->buffer_); + char_len_ptr_ = reinterpret_cast(outrow_ctx_ + 1); + } + return ret; +} + +int ObLobDiskLocatorWrapper::reset_for_dml() +{ + int ret = OB_SUCCESS; + + lob_data_->byte_size_ = 0; + + outrow_ctx_->seq_no_st_ = 0; + outrow_ctx_->seq_no_cnt_ = 0; + outrow_ctx_->del_seq_no_cnt_ = 0; + + uint64_t char_len = *char_len_ptr_; + if (char_len != UINT64_MAX) { + *char_len_ptr_ = 0; + } + + return ret; +} + + +int ObLobDiskLocatorWrapper::check_disk_locator_length(const int64_t len) const +{ + int ret = OB_SUCCESS; + if (len != ObLobManager::LOB_OUTROW_FULL_SIZE) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid disk locator length", K(ret), K(len)); + } + return ret; +} + + +int ObLobDiskLocatorWrapper::check_for_dml(ObLobDiskLocatorWrapper &other) const +{ + int ret = OB_SUCCESS; + if (! is_valid() || ! other.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid state", K(ret), K(other), KPC(this)); + } else if (lob_common_->in_row_ || ! lob_common_->is_init_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob_common is not outrow", K(ret), K(other), KPC(this)); + } else if (get_lob_id() != other.get_lob_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob id is not match", K(ret), K(other), KPC(this)); + } else if (get_byte_size() != other.get_byte_size()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob byte size is not match", K(ret), K(other), KPC(this)); + } else if (get_char_len() != other.get_char_len()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob char len is not match", K(ret), K(other), KPC(this)); + // if op is sql, means not register ext info log callback + // so seq no shuold be same + } else if (ObLobDataOutRowCtx::OpType::SQL == outrow_ctx_->op_ && outrow_ctx_->op_ == other.outrow_ctx_->op_ && + (outrow_ctx_->seq_no_st_ != other.outrow_ctx_->seq_no_st_ || outrow_ctx_->seq_no_cnt_ != other.outrow_ctx_->seq_no_cnt_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("seq no is not match", K(ret), K(other), KPC(this)); + } + return ret; +} + +int ObLobDiskLocatorBuilder::init(ObIAllocator &allocator) +{ + int ret = OB_SUCCESS; + const int64_t locator_len = ObLobManager::LOB_OUTROW_FULL_SIZE; + char *ptr = nullptr; + if (OB_ISNULL(ptr = static_cast(allocator.alloc(locator_len)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc buf fail", K(ret), K(locator_len)); + } else { + ptr_ = ptr; + len_ = locator_len; + lob_common_ = new(ptr)ObLobCommon(); + lob_common_->in_row_ = 0; + lob_common_->is_init_ = 1; + lob_data_ = new(lob_common_->buffer_)ObLobData(); + outrow_ctx_ = new(lob_data_->buffer_)ObLobDataOutRowCtx(); + outrow_ctx_->is_full_ = 1; + char_len_ptr_ = reinterpret_cast(outrow_ctx_ + 1); + *char_len_ptr_ = 0; + } + return ret; +} + +int ObLobDiskLocatorBuilder::set_lob_id(const ObLobId& lob_id) +{ + int ret = OB_SUCCESS; + lob_data_->id_ = lob_id; + return ret; +} + +int ObLobDiskLocatorBuilder::set_byte_len(const uint64_t &byte_len) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(lob_data_) || 0 == byte_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob data is invalid", K(ret), K(byte_len), KPC(this)); + } else { + lob_data_->byte_size_ = byte_len; + } + return ret; +} + +int ObLobDiskLocatorBuilder::set_char_len(const uint64_t &char_len) +{ + int ret = OB_SUCCESS; + *char_len_ptr_ = char_len; + return ret; +} + +int ObLobDiskLocatorBuilder::set_seq_no(const ObLobDataOutRowCtx::OpType type, transaction::ObTxSEQ &seq_no_st, const uint32_t seq_no_cnt) +{ + int ret = OB_SUCCESS; + outrow_ctx_->op_ = type; + outrow_ctx_->seq_no_st_ = seq_no_st.cast_to_int(); + outrow_ctx_->seq_no_cnt_ = seq_no_cnt; + return ret; +} + +int ObLobDiskLocatorBuilder::set_chunk_size(const int64_t lob_chunk_size) +{ + int ret = OB_SUCCESS; + outrow_ctx_->chunk_size_ = lob_chunk_size / ObLobDataOutRowCtx::OUTROW_LOB_CHUNK_SIZE_UNIT; + return ret; +} +int ObLobDiskLocatorBuilder::set_ext_info_log_length(const int64_t len) +{ + int ret = OB_SUCCESS; + outrow_ctx_->modified_len_ = len; + return ret; +} + +int ObLobDiskLocatorBuilder::to_locator(ObLobLocatorV2 &locator) const +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(ptr_) || 0 == len_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("buffer is empty", K(ret), KPC(this)); + } else { + locator.assign_buffer(ptr_, len_); + } + return ret; +} + +}; // end namespace storage +}; // end namespace oceanbase \ No newline at end of file diff --git a/src/storage/lob/ob_lob_locator_struct.h b/src/storage/lob/ob_lob_locator_struct.h new file mode 100644 index 000000000..5c6629aba --- /dev/null +++ b/src/storage/lob/ob_lob_locator_struct.h @@ -0,0 +1,120 @@ +/** + * 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_LOB_LOCATOR_STRUCT_H_ +#define OCEANBASE_STORAGE_OB_LOB_LOCATOR_STRUCT_H_ + + +namespace oceanbase +{ +namespace storage +{ + + +class ObLobDiskLocatorWrapper +{ +public: + static int get_char_len(const ObLobLocatorV2 &src_data_locator, uint64_t &char_len); + +public: + ObLobDiskLocatorWrapper(): + lob_common_(nullptr), + lob_data_(nullptr), + outrow_ctx_(nullptr), + char_len_ptr_(nullptr) + {} + + + int init(char *ptr, const int64_t len); + int reset_for_dml(); + + bool is_valid() const; + + ObLobCommon* get_lob_common() { return lob_common_; } + ObLobId get_lob_id() const { return lob_data_->id_; } + uint64_t get_byte_size() const { return lob_data_->byte_size_; } + ObLobDataOutRowCtx *get_outrow_ctx() { return outrow_ctx_; } + uint64_t get_char_len() const { return *char_len_ptr_; } + + transaction::ObTxSEQ get_seq_no_st() const { return transaction::ObTxSEQ::cast_from_int(outrow_ctx_->seq_no_st_); } + int64_t get_seq_no_cnt() const { return outrow_ctx_->seq_no_cnt_; } + bool is_ext_info_log() const { return ObLobDataOutRowCtx::OpType::EXT_INFO_LOG == outrow_ctx_->op_; } + + int check_for_dml(ObLobDiskLocatorWrapper &other) const; + +private: + int check_disk_locator_length(const int64_t len) const; + +public: + TO_STRING_KV( + KPC_(lob_common), + KPC_(lob_data), + KPC_(outrow_ctx), + KP_(char_len_ptr), + "char_len", (nullptr == char_len_ptr_ ? 0 : *char_len_ptr_) + ); + +private: + ObLobCommon* lob_common_; + ObLobData *lob_data_; + ObLobDataOutRowCtx *outrow_ctx_; + uint64_t *char_len_ptr_; + +}; + +class ObLobDiskLocatorBuilder +{ +public: + ObLobDiskLocatorBuilder(): + ptr_(nullptr), + len_(0), + lob_common_(nullptr), + lob_data_(nullptr), + outrow_ctx_(nullptr), + char_len_ptr_(nullptr) + {} + + int init(ObIAllocator &allocator); + int set_lob_id(const ObLobId& lob_id); + int set_byte_len(const uint64_t &byte_len); + int set_char_len(const uint64_t &char_len); + int set_seq_no(const ObLobDataOutRowCtx::OpType type, transaction::ObTxSEQ &seq_no_st, const uint32_t seq_no_cnt); + int set_chunk_size(const int64_t lob_chunk_size); + int set_ext_info_log_length(const int64_t len); + int to_locator(ObLobLocatorV2 &locator) const; + +public: + TO_STRING_KV( + KP_(ptr), + K_(len), + KPC_(lob_common), + KPC_(lob_data), + KPC_(outrow_ctx), + KP_(char_len_ptr), + "char_len", (nullptr == char_len_ptr_ ? 0 : *char_len_ptr_) + ); + +private: + // locator data + char *ptr_; + int64_t len_; + // locator field + ObLobCommon* lob_common_; + ObLobData *lob_data_; + ObLobDataOutRowCtx *outrow_ctx_; + uint64_t *char_len_ptr_; +}; + +} // end namespace storage +} // end namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_LOB_LOCATOR_STRUCT_H_ \ No newline at end of file diff --git a/src/storage/lob/ob_lob_manager.cpp b/src/storage/lob/ob_lob_manager.cpp index 7431e699d..f69a84251 100644 --- a/src/storage/lob/ob_lob_manager.cpp +++ b/src/storage/lob/ob_lob_manager.cpp @@ -21,6 +21,8 @@ #include "sql/engine/expr/ob_expr_util.h" #include "sql/das/ob_das_utils.h" #include "storage/lob/ob_lob_persistent_iterator.h" +#include "storage/lob/ob_lob_locator_struct.h" +#include "storage/lob/ob_lob_tablet_dml.h" namespace oceanbase { @@ -269,6 +271,9 @@ int ObLobManager::build_tmp_delta_lob_locator(ObIAllocator &allocator, if (OB_ISNULL(persist) || !persist->is_persist_lob()) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid persist lob locator", K(ret), KPC(persist)); + } else if (persist->has_inrow_data()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("inrow should not build delta lob", K(ret), KPC(persist)); } else { // calc res len uint64_t res_len = ObLobLocatorV2::MEM_LOB_COMMON_HEADER_LEN; @@ -1727,7 +1732,7 @@ int ObLobManager::init_out_row_ctx( out_row_ctx->is_full_ = 0; } out_row_ctx->offset_ = param.offset_; - out_row_ctx->check_sum_ = param.checksum_; + out_row_ctx->check_sum_ = 0; out_row_ctx->seq_no_cnt_ = param.used_seq_cnt_; out_row_ctx->del_seq_no_cnt_ = param.used_seq_cnt_; // for sql update, first delete then insert out_row_ctx->op_ = static_cast(op); @@ -1749,25 +1754,6 @@ int ObLobManager::update_out_ctx( } else { // update seq no out_row_ctx->seq_no_cnt_ = param.used_seq_cnt_; - // update checksum - ObBatchChecksum bc; - if (old_info != nullptr) { - bc.fill(&out_row_ctx->check_sum_, sizeof(out_row_ctx->check_sum_)); - bc.fill(&old_info->lob_id_, sizeof(old_info->lob_id_)); - bc.fill(old_info->seq_id_.ptr(), old_info->seq_id_.length()); - bc.fill(old_info->lob_data_.ptr(), old_info->lob_data_.length()); - out_row_ctx->check_sum_ = bc.calc(); - bc.reset(); - } - bc.fill(&out_row_ctx->check_sum_, sizeof(out_row_ctx->check_sum_)); - bc.fill(&new_info.lob_id_, sizeof(new_info.lob_id_)); - bc.fill(new_info.seq_id_.ptr(), new_info.seq_id_.length()); - bc.fill(new_info.lob_data_.ptr(), new_info.lob_data_.length()); - out_row_ctx->check_sum_ = bc.calc(); - // update modified_len - int64_t old_meta_len = (old_info == nullptr) ? 0 : old_info->byte_len_; - int64_t new_meta_len = (new_info.byte_len_); - out_row_ctx->modified_len_ += std::abs(new_meta_len - old_meta_len); } return ret; } @@ -2694,9 +2680,9 @@ int ObLobManager::write_inrow_inner(ObLobAccessParam& param, ObString& data, ObS MEMSET(buf, 0x00, res_len); } else { uint32_t space_len = space.length(); - if (res_len%space_len != 0) { + if (space_len == 0 || res_len%space_len != 0) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("invalid res-len", K(ret), K(res_len), K(space_len)); + LOG_WARN("invalid space_len or res-len", K(ret), K(res_len), K(space_len)); } else if (space_len > 1) { for (int i = 0; i < res_len/space_len; i++) { MEMCPY(buf + i * space_len, space.ptr(), space_len); @@ -3758,6 +3744,202 @@ int ObLobManager::erase_process_meta_info(ObLobAccessParam& param, const int64_t return ret; } +int ObLobManager::insert(ObLobAccessParam& param, const ObLobLocatorV2 &src_data_locator, ObArray &lob_meta_list) +{ + int ret = OB_SUCCESS; + int64_t new_byte_len = 0; + if (OB_FAIL(src_data_locator.get_lob_data_byte_len(new_byte_len))) { + LOG_WARN("fail to get lob byte len", K(ret), K(src_data_locator)); + } else if (OB_ISNULL(param.lob_common_)) { + ret = OB_ERR_NULL_VALUE; + LOG_WARN("null lob common", K(ret), K(param)); + } else if (! param.lob_common_->is_init_) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob common not init", K(ret), KPC(param.lob_common_), K(param)); + } else if (OB_ISNULL(param.lob_data_ = reinterpret_cast(param.lob_common_->buffer_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob_data_ is null", KR(ret), K(param)); + } else if (OB_FAIL(init_out_row_ctx(param, new_byte_len, param.op_type_))) { + LOG_WARN("init lob data out row ctx failed", K(ret)); + } else { + ObLobSimplePersistInsertIter insert_iter(¶m, param.allocator_, lob_meta_list); + if (OB_FAIL(insert_iter.init())) { + LOG_WARN("init iter fail", K(ret), K(param)); + } else if (OB_FAIL(lob_ctx_.lob_meta_mngr_->batch_insert(param, insert_iter))) { + LOG_WARN("write lob meta row failed.", K(ret)); + } + } + return ret; +} + +int ObLobManager::prepare_insert_task( + ObLobAccessParam& param, + bool &is_outrow, + ObLobDataInsertTask &task) +{ + int ret = OB_SUCCESS; + // old inrow | new inrow --> alloc new locator and but no need lob id + // old inrow | new outrow --> alloc new locator and need new lob id + // old outrow | new inrow --> alloc new locator, but no need lob id + // old outrow | new outrow --> keep locator + + const int64_t lob_inrow_threshold = param.get_inrow_threshold(); + int64_t new_byte_len = 0; + if (OB_FAIL(task.src_data_locator_.get_lob_data_byte_len(new_byte_len))) { + LOG_WARN("fail to get lob byte len", K(ret), K(task)); + } else if (new_byte_len <= lob_inrow_threshold) { + // skip if inrow store + } else if (OB_FAIL(prepare_outrow_locator(param, task))) { + LOG_WARN("prepare_outrow_locator fail", K(ret), K(task), K(param)); + } else { + is_outrow = true; + } + return ret; +} + +int ObLobManager::prepare_outrow_locator(ObLobAccessParam& param, ObLobDataInsertTask &task) +{ + int ret = OB_SUCCESS; + const ObLobLocatorV2 &src_data_locator = task.src_data_locator_; + ObLobDiskLocatorBuilder locator_builder; + int64_t new_byte_len = 0; + const int64_t lob_chunk_size = param.get_schema_chunk_size(); + if (OB_FAIL(src_data_locator.get_lob_data_byte_len(new_byte_len))) { + LOG_WARN("fail to get lob byte len", K(ret), K(src_data_locator)); + } else if (OB_FAIL(locator_builder.init(*param.allocator_))) { + LOG_WARN("prepare_locator fail", K(ret), K(param)); + } else if (OB_FAIL(prepare_lob_id(param, locator_builder))) { + LOG_WARN("prepare_lob_id fail", K(ret), K(param)); + } else if (OB_FAIL(locator_builder.set_chunk_size(lob_chunk_size))) { + LOG_WARN("set chunk size fail", K(ret), K(param)); + } else if (OB_FAIL(locator_builder.set_byte_len(new_byte_len))) { + LOG_WARN("set byte len fail", K(ret), K(new_byte_len), K(locator_builder), K(param)); + } else if (OB_FAIL(prepare_char_len(param, locator_builder, task))) { + LOG_WARN("prepare_char_len fail", K(ret), K(locator_builder), K(param)); + } else if (OB_FAIL(prepare_seq_no(param, locator_builder, task))) { + LOG_WARN("prepare_seq_no fail", K(ret), K(locator_builder)); + } else if (OB_FAIL(locator_builder.to_locator(task.cur_data_locator_))) { + LOG_WARN("to locator fail", K(ret), K(locator_builder), K(param)); + } else { + LOG_DEBUG("prepare disk lob locator success", K(locator_builder)); + } + return ret; +} + +int ObLobManager::prepare_char_len(ObLobAccessParam& param, ObLobDiskLocatorBuilder &locator_builder, ObLobDataInsertTask &task) +{ + int ret = OB_SUCCESS; + const ObLobLocatorV2 &src_data_locator = task.src_data_locator_; + int64_t new_byte_len = 0; + uint64_t char_len = 0; + const int64_t lob_chunk_size = param.get_schema_chunk_size(); + if (OB_FAIL(src_data_locator.get_lob_data_byte_len(new_byte_len))) { + LOG_WARN("fail to get lob byte len", K(ret), K(src_data_locator)); + } else if (OB_FAIL(is_store_char_len(param, lob_chunk_size, new_byte_len))) { + LOG_WARN("calc is_store_char_len failed.", K(ret), K(new_byte_len), K(param)); + } else if (! param.is_store_char_len_) { + char_len = UINT64_MAX; + } else if (param.is_blob()) { + // blob char_len is equal byte_len + char_len = new_byte_len; + } else { + ObString inrow_data; + ObInRowLobDataSpliter spilter(task.lob_meta_list_); + if (! src_data_locator.has_inrow_data()) { + if (OB_FAIL(ObLobDiskLocatorWrapper::get_char_len(src_data_locator, char_len))) { + LOG_WARN("get_char_len fail", K(ret), K(src_data_locator)); + } + } else if (OB_FAIL(src_data_locator.get_inrow_data(inrow_data))) { + LOG_WARN("get inrow data fail", K(ret), K(src_data_locator)); + } else if (inrow_data.length() != new_byte_len) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("byte len is not match", K(ret), K(new_byte_len), "inrow_data_length", inrow_data.length()); + } else if (OB_FAIL(spilter.split(param.coll_type_, param.get_schema_chunk_size(), inrow_data))) { + LOG_WARN("init spilter fail", K(ret), K(src_data_locator)); + } else { + char_len = spilter.char_pos(); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(locator_builder.set_char_len(char_len))) { + LOG_WARN("set char_len fail", K(ret), K(char_len), K(locator_builder), K(param)); + } + return ret; +} + +int ObLobManager::prepare_lob_id(ObLobAccessParam& param, ObLobDiskLocatorBuilder &locator_builder) +{ + int ret = OB_SUCCESS; + ObLobId lob_id; + if (OB_ISNULL(param.lob_common_)) { + if (OB_FAIL(alloc_lob_id(param, lob_id))) { + LOG_WARN("alloc_lob_id fail", K(ret)); + } + } else { + const ObLobCommon *lob_common = param.lob_common_; + if (lob_common->in_row_ || ! lob_common->is_init_) { + if (OB_FAIL(alloc_lob_id(param, lob_id))) { + LOG_WARN("alloc_lob_id fail", K(ret)); + } + } else { + const ObLobData *lob_data = reinterpret_cast(lob_common->buffer_); + lob_id = lob_data->id_; + } + } + + if (OB_FAIL(ret)) { + } else if (! lob_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob id is invalid", K(ret), K(lob_id), K(param)); + } else if (OB_FAIL(locator_builder.set_lob_id(lob_id))) { + LOG_WARN("set lob id fail", K(ret), K(lob_id), K(locator_builder), K(param)); + } + return ret; +} + +int ObLobManager::alloc_lob_id(ObLobAccessParam& param, ObLobId &lob_id) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(lob_ctx_.lob_meta_mngr_->fetch_lob_id(param, lob_id.lob_id_))) { + LOG_WARN("get lob id failed.", K(ret), K(param)); + } else if (! param.lob_meta_tablet_id_.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob_meta_tablet_id is invalid", K(ret), K(param)); + } else { + lob_id.tablet_id_ = param.lob_meta_tablet_id_.id(); + // used for lob order + transform_lob_id(lob_id.lob_id_, lob_id.lob_id_); + } + return ret; +} + +int ObLobManager::prepare_seq_no(ObLobAccessParam& param, ObLobDiskLocatorBuilder &locator_builder, ObLobDataInsertTask &task) +{ + int ret = OB_SUCCESS; + ObLobDataOutRowCtx::OpType type = ObLobDataOutRowCtx::OpType::EXT_INFO_LOG; + int64_t seq_no_cnt = 1; + transaction::ObTxSEQ seq_no_st; + int64_t new_byte_len = 0; + const int64_t lob_chunk_size = param.get_schema_chunk_size(); + if (OB_FAIL(task.src_data_locator_.get_lob_data_byte_len(new_byte_len))) { + LOG_WARN("fail to get lob byte len", K(ret), K(task)); + } else if (new_byte_len < lob_chunk_size && (OB_ISNULL(param.lob_common_) || param.lob_common_->in_row_)) { + // means insert, not update + type = ObLobDataOutRowCtx::OpType::SQL; + } else if (OB_FAIL(locator_builder.set_ext_info_log_length(ObLobManager::LOB_OUTROW_FULL_SIZE + 1 /*ext info log type*/))) { + LOG_WARN("set_ext_info_log_length fail", K(ret), K(locator_builder)); + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(param.tx_desc_->get_and_inc_tx_seq(param.parent_seq_no_.get_branch(), seq_no_cnt, seq_no_st))) { + LOG_WARN("alloc seq_no fail", K(ret), K(seq_no_cnt), K(param)); + } else if (OB_FAIL(locator_builder.set_seq_no(type, seq_no_st, seq_no_cnt))) { + LOG_WARN("set seq_no fail", K(ret), K(param)); + } + return ret; +} + /*************ObLobQueryIter*****************/ int ObLobQueryIter::open(ObString &data, uint32_t byte_offset, uint32_t byte_len, ObCollationType cs, bool is_reverse) { diff --git a/src/storage/lob/ob_lob_manager.h b/src/storage/lob/ob_lob_manager.h index 0c1201fac..cd8007716 100644 --- a/src/storage/lob/ob_lob_manager.h +++ b/src/storage/lob/ob_lob_manager.h @@ -24,6 +24,9 @@ namespace oceanbase namespace storage { +class ObLobDiskLocatorBuilder; +class ObLobDataInsertTask; + struct ObLobCtx { ObLobCtx() : lob_meta_mngr_(nullptr), lob_piece_mngr_(nullptr) {} @@ -353,6 +356,11 @@ public: inline bool can_write_inrow(uint64_t len, int64_t inrow_threshold) { return len <= inrow_threshold; } + int insert(ObLobAccessParam& param, const ObLobLocatorV2 &src_data_locator, ObArray &lob_meta_list); + int prepare_insert_task( + ObLobAccessParam& param, + bool &is_outrow, + ObLobDataInsertTask &task); static void transform_lob_id(uint64_t src, uint64_t &dst); private: @@ -443,6 +451,11 @@ private: ObLobQueryResult &result, ObString &write_data_buffer); + int prepare_outrow_locator(ObLobAccessParam& param, ObLobDataInsertTask &task); + int prepare_char_len(ObLobAccessParam& param, ObLobDiskLocatorBuilder &locator_builder, ObLobDataInsertTask &task); + int prepare_lob_id(ObLobAccessParam& param, ObLobDiskLocatorBuilder &locator_builder); + int alloc_lob_id(ObLobAccessParam& param, ObLobId &lob_id); + int prepare_seq_no(ObLobAccessParam& param, ObLobDiskLocatorBuilder &locator_builder, ObLobDataInsertTask &task); private: static const int64_t DEFAULT_LOB_META_BUCKET_CNT = 1543; const uint64_t tenant_id_; diff --git a/src/storage/lob/ob_lob_meta.cpp b/src/storage/lob/ob_lob_meta.cpp index e2b8520d6..6995e6655 100644 --- a/src/storage/lob/ob_lob_meta.cpp +++ b/src/storage/lob/ob_lob_meta.cpp @@ -1169,5 +1169,55 @@ int ObLobMetaSingleGetter::get_next_row(ObString &seq_id, ObLobMetaInfo &info) return ret; } +int ObInRowLobDataSpliter::split(ObCollationType cs_type, const int64_t chunk_size, const ObString &inrow_data) +{ + int ret = OB_SUCCESS; + cs_type_ = cs_type; + chunk_size_ = chunk_size; + inrow_data_ = inrow_data; + ObLobMetaInfo info; + while(OB_SUCC(ret) && OB_SUCC(get_next_row(info))) { + if (OB_FAIL(lob_meta_list_.push_back(info))) { + LOG_WARN("push back fail", K(ret), "count", lob_meta_list_.count()); + } + } + if (OB_ITER_END == ret) { + ret = OB_SUCCESS; + } + if (OB_FAIL(ret)) { + } else if (byte_pos() != inrow_data.length()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("byte len is not match", K(ret), "inrow_data_length", inrow_data.length(), "spilter_byte_pos", byte_pos()); + } + return ret; +} + +int ObInRowLobDataSpliter::get_next_row(ObLobMetaInfo &info) +{ + int ret = OB_SUCCESS; + int64_t char_len = 0; + int64_t byte_len = 0; + if (byte_pos_ == inrow_data_.length()) { + ret = OB_ITER_END; + } else if (byte_pos_ > inrow_data_.length()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("byte_pos is larger than data length", K(ret), K(byte_pos_), "data_length", inrow_data_.length()); + } else { + byte_len = ObCharset::max_bytes_charpos(cs_type_, inrow_data_.ptr() + byte_pos_, inrow_data_.length() - byte_pos_, chunk_size_, char_len); + if (byte_len <= 0 || char_len <= 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("no data can be return when has remain data", K(ret), K(byte_pos_), "data_length", inrow_data_.length()); + } else { + info.byte_len_ = byte_len; + info.char_len_ = char_len; + info.piece_id_ = ObLobMetaUtil::LOB_META_INLINE_PIECE_ID; + info.lob_data_.assign_ptr(inrow_data_.ptr() + byte_pos_, byte_len); + byte_pos_ += byte_len; + char_pos_ += char_len; + } + } + return ret; +} + } } diff --git a/src/storage/lob/ob_lob_meta.h b/src/storage/lob/ob_lob_meta.h index 707dfd844..e16014b31 100644 --- a/src/storage/lob/ob_lob_meta.h +++ b/src/storage/lob/ob_lob_meta.h @@ -330,6 +330,33 @@ public: ObTableScanIterator *scan_iter_; }; +class ObInRowLobDataSpliter +{ +public: + ObInRowLobDataSpliter(ObArray &lob_meta_list): + cs_type_(ObCollationType::CS_TYPE_INVALID), + chunk_size_(0), + inrow_data_(), + byte_pos_(0), + char_pos_(0), + lob_meta_list_(lob_meta_list) + {} + + int split(ObCollationType cs_type, const int64_t chunk_size, const ObString &inrow_data); + int64_t byte_pos() const { return byte_pos_; } + int64_t char_pos() const { return char_pos_; } + +protected: + int get_next_row(ObLobMetaInfo &info); + +private: + ObCollationType cs_type_; + int64_t chunk_size_; + ObString inrow_data_; + int64_t byte_pos_; + int64_t char_pos_; + ObArray &lob_meta_list_; +}; } // storage } // oceanbase diff --git a/src/storage/lob/ob_lob_persistent_adaptor.cpp b/src/storage/lob/ob_lob_persistent_adaptor.cpp index b5e33b485..5c3d008ca 100644 --- a/src/storage/lob/ob_lob_persistent_adaptor.cpp +++ b/src/storage/lob/ob_lob_persistent_adaptor.cpp @@ -24,6 +24,7 @@ #include "share/schema/ob_tenant_schema_service.h" #include "storage/tx_storage/ob_access_service.h" #include "share/ob_tablet_autoincrement_service.h" +#include "storage/tablet/ob_tablet_split_mds_helper.h" #include "storage/tx_storage/ob_ls_service.h" #include "storage/tx_storage/ob_ls_handle.h" @@ -291,9 +292,10 @@ int ObPersistentLobApator::fetch_lob_id(ObLobAccessParam& param, uint64_t &lob_i int ret = OB_SUCCESS; common::ObTabletID lob_meta_tablet_id; common::ObTabletID lob_piece_tablet_id; - if (OB_FAIL(get_lob_tablets_id(param, lob_meta_tablet_id, lob_piece_tablet_id))) { + if (OB_FAIL(prepare_lob_tablet_id(param))) { LOG_WARN("get lob tablet id failed.", K(ret), K(param)); } else { + lob_meta_tablet_id = param.lob_meta_tablet_id_; uint64_t tenant_id = param.tenant_id_; share::ObTabletAutoincrementService &auto_inc = share::ObTabletAutoincrementService::get_instance(); if (OB_FAIL(auto_inc.get_autoinc_seq(tenant_id, lob_meta_tablet_id, lob_id))) { @@ -301,6 +303,42 @@ int ObPersistentLobApator::fetch_lob_id(ObLobAccessParam& param, uint64_t &lob_i } else { LOG_DEBUG("get lob_id succ", K(lob_id), K(tenant_id), K(lob_meta_tablet_id)); } + + if (OB_TABLET_IS_SPLIT_SRC == ret) { + if (OB_FAIL(fetch_lob_id_for_split_src(param, lob_meta_tablet_id, lob_id))) { + LOG_WARN("get lob_id for split src fail", K(ret), K(tenant_id), K(lob_meta_tablet_id)); + } + } + } + return ret; +} + +int ObPersistentLobApator::fetch_lob_id_for_split_src(const ObLobAccessParam& param, const ObTabletID &lob_tablet_id, uint64_t &lob_id) +{ + int ret = OB_SUCCESS; + const uint64_t tenant_id = param.tenant_id_; + ObLSHandle ls_handle; + ObTabletHandle tablet_handle; + ObTabletID dst_tablet_id; + share::ObTabletAutoincrementService &auto_inc = share::ObTabletAutoincrementService::get_instance(); + if (OB_ISNULL(param.data_row_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid data row", K(ret), K(lob_tablet_id)); + } else if (OB_FAIL(MTL(ObLSService *)->get_ls(param.ls_id_, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("failed to get log stream", K(ret), K(param.ls_id_)); + } else if (OB_ISNULL(ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls should not be null", K(ret)); + } else if (OB_FAIL(ls_handle.get_ls()->get_tablet_with_timeout(lob_tablet_id, + tablet_handle, + param.timeout_, + ObMDSGetTabletMode::READ_ALL_COMMITED, + share::SCN::max_scn()))) { + LOG_WARN("fail to get tablet handle", K(ret), K(lob_tablet_id), K(param)); + } else if (OB_FAIL(ObTabletSplitMdsHelper::calc_split_dst_lob(*ls_handle.get_ls(), *tablet_handle.get_obj(), *param.data_row_, param.timeout_, dst_tablet_id))) { + LOG_WARN("failed to calc split dst tablet", K(ret)); + } else if (OB_FAIL(auto_inc.get_autoinc_seq(tenant_id, dst_tablet_id, lob_id))) { + LOG_WARN("get lob_id fail", K(ret), K(tenant_id), K(dst_tablet_id)); } return ret; } @@ -359,6 +397,7 @@ int ObPersistentLobApator::build_lob_meta_table_dml( dml_base_param.sql_mode_ = SMO_DEFAULT; dml_base_param.encrypt_meta_ = &dml_base_param.encrypt_meta_legacy_; dml_base_param.check_schema_version_ = false; // lob tablet should not check schema version + dml_base_param.data_row_for_lob_ = param.data_row_; dml_base_param.schema_version_ = 0; dml_base_param.store_ctx_guard_ = store_ctx_guard; dml_base_param.write_flag_.set_is_insert_up(); @@ -459,6 +498,7 @@ int ObPersistentLobApator::build_lob_piece_table_dml( dml_base_param.tz_info_ = NULL; dml_base_param.sql_mode_ = SMO_DEFAULT; dml_base_param.encrypt_meta_ = &dml_base_param.encrypt_meta_legacy_; + dml_base_param.data_row_for_lob_ = param.data_row_; HEAP_VAR(ObTableSchema, tbl_schema, param.allocator_) { ObTableSchema* table_schema = param.piece_table_schema_; @@ -818,7 +858,17 @@ int ObPersistentLobApator::inner_get_tablet( param.timeout_, ObMDSGetTabletMode::READ_READABLE_COMMITED, param.snapshot_.core_.version_))) { - LOG_WARN("fail to get tablet handle", K(ret), K(tablet_id), K(param)); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + if (OB_FAIL(ls_handle.get_ls()->get_tablet_with_timeout(tablet_id, + handle, + param.timeout_, + ObMDSGetTabletMode::READ_ALL_COMMITED, + share::SCN::max_scn()))) { + LOG_WARN("fail to get tablet handle", K(ret), K(tablet_id), K(param)); + } + } else { + LOG_WARN("fail to get tablet handle", K(ret), K(tablet_id), K(param)); + } } return ret; } diff --git a/src/storage/lob/ob_lob_persistent_adaptor.h b/src/storage/lob/ob_lob_persistent_adaptor.h index 1fc4d719d..eab90e40f 100644 --- a/src/storage/lob/ob_lob_persistent_adaptor.h +++ b/src/storage/lob/ob_lob_persistent_adaptor.h @@ -166,6 +166,7 @@ private: int prepare_piece_table_param( const ObLobAccessParam ¶m, ObTableScanParam &scan_param); + int fetch_lob_id_for_split_src(const ObLobAccessParam& param, const ObTabletID &lob_tablet_id, uint64_t &lob_id); int prepare_lob_tablet_id(ObLobAccessParam& param); int set_dml_seq_no(ObLobAccessParam ¶m); diff --git a/src/storage/lob/ob_lob_persistent_iterator.cpp b/src/storage/lob/ob_lob_persistent_iterator.cpp index bdfc804e5..8084ec61e 100644 --- a/src/storage/lob/ob_lob_persistent_iterator.cpp +++ b/src/storage/lob/ob_lob_persistent_iterator.cpp @@ -231,6 +231,42 @@ int ObLobPersistDeleteIter::get_next_row(blocksstable::ObDatumRow *&row) return ret; } +int ObLobSimplePersistInsertIter::init() +{ + int ret = OB_SUCCESS; + if (OB_FAIL(new_row_.init(ObLobMetaUtil::LOB_META_COLUMN_CNT))) { + LOG_WARN("init new datum row failed", K(ret)); + } + return ret; +} + +int ObLobSimplePersistInsertIter::get_next_row(blocksstable::ObDatumRow *&row) +{ + int ret = OB_SUCCESS; + if (pos_ >= lob_meta_list_.count()) { + ret = OB_ITER_END; + } else { + ObLobMetaInfo &info = lob_meta_list_[pos_]; + ObString cur_seq_id; + if (OB_FAIL(seq_id_.get_next_seq_id(cur_seq_id))) { + LOG_WARN("get_next_seq_id fail", K(ret)); + } else if (OB_FALSE_IT(info.lob_id_ = param_->lob_data_->id_)) { + } else if (OB_FALSE_IT(info.seq_id_ = cur_seq_id)) { + } else if (OB_FAIL(update_seq_no())) { + LOG_WARN("update_seq_no fail", K(ret)); + } else if (OB_FAIL(ObLobManager::update_out_ctx(*param_, nullptr, info))) { // new row + LOG_WARN("failed update checksum.", K(ret)); + } else if (OB_FAIL(inc_lob_size(info))) { + LOG_WARN("inc_lob_size fail", K(ret)); + } else { + ++pos_; + ObPersistentLobApator::set_lob_meta_row(new_row_, info); + row = &new_row_; + LOG_TRACE("row", K(info)); + } + } + return ret; +} } // storage } // oceanbase diff --git a/src/storage/lob/ob_lob_persistent_iterator.h b/src/storage/lob/ob_lob_persistent_iterator.h index 19598dfdf..8a72bc5fc 100644 --- a/src/storage/lob/ob_lob_persistent_iterator.h +++ b/src/storage/lob/ob_lob_persistent_iterator.h @@ -154,8 +154,32 @@ private: ObLobMetaScanResult result_; }; +class ObLobSimplePersistInsertIter : public ObLobPersistWriteIter +{ +public: + ObLobSimplePersistInsertIter(ObLobAccessParam *param, ObIAllocator *allocator, ObArray &lob_meta_list): + allocator_(allocator), + seq_id_(allocator), + lob_meta_list_(lob_meta_list), + pos_(0) + { + param_ = param; + } + + int init(); + + virtual int get_next_row(blocksstable::ObDatumRow *&row); + virtual void reset() {} + +private: + ObIAllocator *allocator_; + ObLobSeqId seq_id_; + ObArray &lob_meta_list_; + int pos_; + blocksstable::ObDatumRow new_row_; +}; } // storage } // oceanbase -#endif \ No newline at end of file +#endif diff --git a/src/storage/lob/ob_lob_tablet_dml.cpp b/src/storage/lob/ob_lob_tablet_dml.cpp new file mode 100644 index 000000000..198d7900f --- /dev/null +++ b/src/storage/lob/ob_lob_tablet_dml.cpp @@ -0,0 +1,552 @@ +/** + * 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_lob_tablet_dml.h" +#include "storage/lob/ob_lob_manager.h" +#include "storage/lob/ob_lob_locator_struct.h" +#include "storage/ob_dml_running_ctx.h" + +namespace oceanbase +{ +using namespace common; +namespace storage +{ + +ObLobTabletDmlCtx::~ObLobTabletDmlCtx() +{ +} + +int ObLobTabletDmlHelper::build_common_lob_param_for_dml( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + ObString &disk_lob_locator, + ObLobAccessParam &lob_param) +{ + int ret = OB_SUCCESS; + + ObLobCommon *lob_common = reinterpret_cast(disk_lob_locator.ptr()); + if (OB_NOT_NULL(lob_common)) { + lob_param.lob_common_ = lob_common; + lob_param.handle_size_ = disk_lob_locator.length(); + lob_param.byte_size_ = lob_common->get_byte_size(disk_lob_locator.length()); + } + + lob_param.tx_desc_ = run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_; + lob_param.parent_seq_no_ = run_ctx.store_ctx_.mvcc_acc_ctx_.tx_scn_; + lob_param.tx_id_ = lob_param.tx_desc_->get_tx_id(); + + lob_param.sql_mode_ = run_ctx.dml_param_.sql_mode_; + lob_param.is_total_quantity_log_ = run_ctx.dml_param_.is_total_quantity_log_; + lob_param.ls_id_ = run_ctx.store_ctx_.ls_id_; + lob_param.tablet_id_ = run_ctx.relative_table_.get_tablet_id(); + lob_param.lob_meta_tablet_id_ = run_ctx.lob_dml_ctx_.lob_meta_tablet_id_; + lob_param.lob_piece_tablet_id_ = run_ctx.lob_dml_ctx_.lob_piece_tablet_id_; + lob_param.coll_type_ = ObLobCharsetUtil::get_collation_type(column.col_type_.get_type(), column.col_type_.get_collation_type()); + lob_param.allocator_ = &run_ctx.dml_param_.lob_allocator_; + lob_param.timeout_ = run_ctx.dml_param_.timeout_; + lob_param.scan_backward_ = false; + lob_param.offset_ = 0; + lob_param.data_row_ = &data_row; + + if (OB_FAIL(set_lob_storage_params(run_ctx, column, lob_param))) { + LOG_WARN("set_lob_storage_params fail", K(ret), K(column)); + } else if (OB_FAIL(lob_param.snapshot_.assign(run_ctx.dml_param_.snapshot_))) { + LOG_WARN("assign snapshot fail", K(ret)); + } else if (lob_param.snapshot_.is_none_read()) { + // NOTE: + // // lob_insert need table_scan, the snapshot already generated in + // // run_ctx.store_ctx, use it as an LS ReadSnapshot + lob_param.snapshot_.init_ls_read(run_ctx.store_ctx_.ls_id_, + run_ctx.store_ctx_.mvcc_acc_ctx_.snapshot_); + } + return ret; +} + +int ObLobTabletDmlHelper::process_lob_column_before_insert( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &row, + const ObColDesc &column, + const int16_t row_idx, + const int16_t col_idx, + blocksstable::ObStorageDatum &datum) +{ + int ret = OB_SUCCESS; + ObString old_disk_locator; + bool need_do_write = false; + if (OB_FAIL(prepare_lob_write(run_ctx, row, column, row_idx, col_idx, old_disk_locator, datum, need_do_write))) { + LOG_WARN("prepare_lob_write fail", K(ret), K(column), K(row_idx), K(col_idx), K(datum), K(row)); + } else if (! need_do_write) { + } else if(OB_FAIL(insert_lob_col(run_ctx, row, column, datum, nullptr, old_disk_locator/*empty data*/))) { + LOG_WARN("insert_lob_col fail", K(ret), K(column), K(row_idx), K(col_idx), K(datum), K(row)); + } + return ret; +} + +int ObLobTabletDmlHelper::process_lob_column_after_insert( + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &row, + const ObColDesc &column, + ObLobDataInsertTask &info) +{ + int ret = OB_SUCCESS; + blocksstable::ObStorageDatum datum; + datum.set_string(info.src_data_locator_.ptr_, info.src_data_locator_.size_); + if (info.src_data_locator_.has_lob_header_)datum.set_has_lob_header(); + + ObString locator_data(info.cur_data_locator_.size_, info.cur_data_locator_.ptr_); + // dup locator + char buf[ObLobManager::LOB_OUTROW_FULL_SIZE]; + MEMCPY(static_cast(buf), info.cur_data_locator_.ptr_, ObLobManager::LOB_OUTROW_FULL_SIZE); + ObString dup_locator_data(ObLobManager::LOB_OUTROW_FULL_SIZE, buf); + + ObLobDiskLocatorWrapper lob_disk_locator; + ObLobAccessParam del_param; + if (OB_FAIL(lob_disk_locator.init(info.cur_data_locator_.ptr_, info.cur_data_locator_.size_))) { + LOG_WARN("init disk locator fail", K(ret), K(info)); + } else if (! lob_disk_locator.is_ext_info_log()) { + del_param.seq_no_st_ = lob_disk_locator.get_seq_no_st(); + del_param.total_seq_cnt_ = lob_disk_locator.get_seq_no_cnt(); + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(lob_disk_locator.reset_for_dml())) { + LOG_WARN("reset_for_dml fail", K(ret), K(lob_disk_locator)); + } else if(OB_FAIL(insert_lob_col(run_ctx, row, column, datum, &del_param, locator_data, &info.lob_meta_list_))) { + LOG_WARN("insert_lob_col fail", K(ret), K(column), K(datum), K(info), K(row)); + } else if (datum.get_string().ptr() != locator_data.ptr() || datum.get_string().length() != locator_data.length()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob locator memory is changed", K(ret), KP(datum.get_string().ptr()), K(datum.get_string().length()), KP(locator_data.ptr()), K(locator_data.length())); + } else if (OB_FAIL(register_ext_info_commit_cb(run_ctx, column, dup_locator_data, locator_data))) { + LOG_WARN("register_ext_info_commit_cb fail", K(ret), K(column), K(datum), K(info)); + } + return ret; +} + +int ObLobTabletDmlHelper::process_lob_column_before_update( + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + const bool data_tbl_rowkey_change, + const ObColDesc &column, + const int16_t row_idx, + const int16_t col_idx, + blocksstable::ObStorageDatum &old_datum, + blocksstable::ObStorageDatum &new_datum) +{ + int ret = OB_SUCCESS; + bool need_do_write = false; + ObString old_disk_locator = (old_datum.is_null() || old_datum.is_nop_value()) ? ObString() : old_datum.get_string(); + if (OB_FAIL(ObLobTabletDmlHelper::prepare_lob_write(run_ctx, new_row, column, row_idx, col_idx, old_disk_locator, new_datum, need_do_write))) { + LOG_WARN("prepare_lob_write fail", K(ret), K(column), K(row_idx), K(col_idx), K(new_datum)); + } else if (! need_do_write) { + } else if (OB_FAIL(ObLobTabletDmlHelper::update_lob_col(run_ctx, old_row, new_row, data_tbl_rowkey_change, column, old_datum, new_datum))) { + LOG_WARN("[STORAGE_LOB]failed to to update lob col", K(ret), K(column), K(row_idx), K(col_idx), K(new_datum)); + } + return ret; +} + +int ObLobTabletDmlHelper::process_lob_column_after_update( + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + const bool data_tbl_rowkey_change, + const ObColDesc &column, + ObLobDataInsertTask &info) +{ + int ret = OB_SUCCESS; + blocksstable::ObStorageDatum new_datum; + new_datum.set_string(info.src_data_locator_.ptr_, info.src_data_locator_.size_); + if (info.src_data_locator_.has_lob_header_)new_datum.set_has_lob_header(); + + blocksstable::ObStorageDatum &old_datum = old_row.storage_datums_[info.col_idx_]; + + ObString locator_data(info.cur_data_locator_.size_, info.cur_data_locator_.ptr_); + // dup locator + char buf[ObLobManager::LOB_OUTROW_FULL_SIZE]; + MEMCPY(static_cast(buf), info.cur_data_locator_.ptr_, ObLobManager::LOB_OUTROW_FULL_SIZE); + ObString dup_locator_data(ObLobManager::LOB_OUTROW_FULL_SIZE, buf); + + ObLobAccessParam lob_param; + ObLobCommon *old_lob_common = nullptr; + ObLobCommon *new_lob_common = nullptr; + + ObLobDiskLocatorWrapper lob_disk_locator; + if (OB_FAIL(info.src_data_locator_.get_lob_data_byte_len(lob_param.update_len_))) { + LOG_WARN("fail to get new lob byte len", K(ret), K(info)); + } else if (OB_FAIL(delete_lob_col(run_ctx, old_row, column, old_datum, old_lob_common, lob_param))) { + LOG_WARN("[STORAGE_LOB]failed to erase old lob col", K(ret), K(old_row)); + } else if (OB_FAIL(lob_disk_locator.init(info.cur_data_locator_.ptr_, info.cur_data_locator_.size_))) { + LOG_WARN("init disk locator fail", K(ret), K(info)); + } else if (! lob_disk_locator.is_ext_info_log() && lob_param.seq_no_st_.is_valid() && lob_param.used_seq_cnt_ > 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("should be ext info log", K(ret), K(info), K(lob_disk_locator), K(lob_param)); + } else if (! lob_disk_locator.is_ext_info_log()) { + lob_param.seq_no_st_ = lob_disk_locator.get_seq_no_st(); + lob_param.total_seq_cnt_ = lob_disk_locator.get_seq_no_cnt(); + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(lob_disk_locator.reset_for_dml())) { + LOG_WARN("reset_for_dml fail", K(ret), K(lob_disk_locator)); + } else if (OB_ISNULL(new_lob_common = lob_disk_locator.get_lob_common())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("new lob common is null", K(ret), K(lob_disk_locator)); + } else if (data_tbl_rowkey_change) { + if (OB_FAIL(insert_lob_col(run_ctx, new_row, column, new_datum, nullptr, locator_data, &info.lob_meta_list_))) { // no need del_param + LOG_WARN("[STORAGE_LOB]failed to insert new lob col.", K(ret), K(new_row)); + } + } else if (OB_FAIL(insert_lob_col(run_ctx, new_row, column, new_datum, &lob_param, locator_data, &info.lob_meta_list_))) { + LOG_WARN("[STORAGE_LOB]failed to insert new lob col.", K(ret), K(new_row)); + } + + if (OB_FAIL(ret)) { + } else if (new_datum.get_string().ptr() != locator_data.ptr() || new_datum.get_string().length() != locator_data.length()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob locator memory is changed", K(ret), KP(new_datum.get_string().ptr()), K(new_datum.get_string().length()), KP(locator_data.ptr()), K(locator_data.length())); + } else if (OB_FAIL(register_ext_info_commit_cb(run_ctx, column, dup_locator_data, locator_data))) { + LOG_WARN("register_ext_info_commit_cb fail", K(ret), K(column), K(new_datum), K(info)); + } + return ret; +} + +int ObLobTabletDmlHelper::insert_lob_col( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + blocksstable::ObStorageDatum &datum, + ObLobAccessParam *del_param, + ObString &disk_locator_data, + ObArray *lob_meta_list) +{ + int ret = OB_SUCCESS; + ObLobManager *lob_mngr = MTL(ObLobManager*); + ObLobAccessParam lob_param; + if (OB_ISNULL(lob_mngr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[STORAGE_LOB]failed to get lob manager handle.", K(ret)); + } else if (!column.col_type_.is_lob_storage() || datum.is_nop_value() || datum.is_null()) { + // do nothing + } else if (OB_FAIL(build_common_lob_param_for_dml(run_ctx, data_row, column, disk_locator_data, lob_param))) { + LOG_WARN("build_common_lob_param_for_dml fail", K(ret), K(column)); + } else { + if (OB_NOT_NULL(del_param)) { // for obcdc lob + lob_param.total_seq_cnt_ = del_param->total_seq_cnt_; + lob_param.used_seq_cnt_ = del_param->used_seq_cnt_; + lob_param.seq_no_st_ = del_param->seq_no_st_; + } + ObString raw_data = datum.get_string(); + // for not strict sql mode, will insert empty string without lob header + bool has_lob_header = datum.has_lob_header() && raw_data.length() > 0; + ObLobLocatorV2 loc(raw_data, has_lob_header); + if (nullptr != lob_meta_list && lob_meta_list->count() > 0 ) { + if (OB_FAIL(lob_mngr->insert(lob_param, loc, *lob_meta_list))) { + LOG_WARN("[STORAGE_LOB]lob insert failed.", K(ret)); + } else { + datum.set_lob_data(*lob_param.lob_common_, lob_param.handle_size_); + LOG_DEBUG("[STORAGE_LOB]write ob lob data.", K(lob_param), KPC(lob_param.lob_common_), + K(lob_param.handle_size_), K(column.col_type_.get_collation_type())); + } + } else if (OB_FAIL(lob_mngr->append(lob_param, loc))) { + LOG_WARN("[STORAGE_LOB]lob append failed.", K(ret)); + } else { + datum.set_lob_data(*lob_param.lob_common_, lob_param.handle_size_); + LOG_DEBUG("[STORAGE_LOB]write ob lob data.", K(lob_param), KPC(lob_param.lob_common_), + K(lob_param.handle_size_), K(column.col_type_.get_collation_type())); + } + } + return ret; +} + +int ObLobTabletDmlHelper::delete_lob_col( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + blocksstable::ObStorageDatum &datum, + ObLobCommon *&lob_common, + ObLobAccessParam &lob_param) +{ + int ret = OB_SUCCESS; + ObLobManager *lob_mngr = MTL(ObLobManager*); + if (OB_ISNULL(lob_mngr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[STORAGE_LOB]get lob manager instance failed.", K(ret)); + } else if (!column.col_type_.is_lob_storage() || datum.is_nop_value() || datum.is_null() || + !run_ctx.is_old_row_valid_for_lob_) { + // do nothing + } else { + ObString data = datum.get_string(); + ObLobLocatorV2 locator(data, datum.has_lob_header()); + char *buf = nullptr; + if (data.length() < sizeof(ObLobCommon)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[STORAGE_LOB]Invalid Lob data.", K(ret), K(datum), K(data)); + } else if (locator.is_inrow()) { + // delete inrow lob no need to use the lob manager + } else if (OB_ISNULL(buf = static_cast(run_ctx.dml_param_.lob_allocator_.alloc(data.length())))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to deep copy lob data.", K(ret), K(data)); + } else { + MEMCPY(buf, data.ptr(), data.length()); + lob_common = reinterpret_cast(buf); + ObString dup_data = ObString(data.length(), buf); + if (OB_FAIL(build_common_lob_param_for_dml(run_ctx, data_row, column, dup_data, lob_param))) { + LOG_WARN("build_common_lob_param_for_dml fail", K(ret), K(column), K(datum), K(data)); + } else if (lob_param.byte_size_ < 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("calc byte size is negative.", K(ret), K(data), K(lob_param)); + // use byte size to delete all + } else if (OB_FALSE_IT(lob_param.len_ = lob_param.byte_size_)) { + } else if (OB_FAIL(lob_mngr->erase(lob_param))) { + LOG_WARN("[STORAGE_LOB]lob erase failed.", K(ret), K(lob_param)); + } + } + } + return ret; +} + +int ObLobTabletDmlHelper::update_lob_col( + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + const bool data_tbl_rowkey_change, + const ObColDesc &column, + blocksstable::ObStorageDatum &old_datum, + blocksstable::ObStorageDatum &new_datum) +{ + int ret = OB_SUCCESS; + ObLobAccessParam lob_param; + ObLobCommon *lob_common = nullptr; + ObString new_lob_str = (new_datum.is_null() || new_datum.is_nop_value()) + ? ObString(0, nullptr) : new_datum.get_string(); + ObLobLocatorV2 new_lob(new_lob_str, new_datum.has_lob_header()); + ObString disk_locator_data; + if (OB_FAIL(new_lob.get_lob_data_byte_len(lob_param.update_len_))) { + LOG_WARN("fail to get new lob byte len", K(ret), K(new_lob)); + } else if (OB_FAIL(delete_lob_col(run_ctx, old_row, column, old_datum, lob_common, lob_param))) { + LOG_WARN("[STORAGE_LOB]failed to erase old lob col", K(ret), K(old_row)); + } else if (data_tbl_rowkey_change) { + if (OB_FAIL(insert_lob_col(run_ctx, new_row, column, new_datum, nullptr, disk_locator_data/*empty data*/))) { // no need del_param + LOG_WARN("[STORAGE_LOB]failed to insert new lob col.", K(ret), K(new_row)); + } + } else if (OB_FALSE_IT(disk_locator_data.assign_ptr(reinterpret_cast(lob_common), lob_param.handle_size_))) { + } else if (OB_FAIL(insert_lob_col(run_ctx, new_row, column, new_datum, &lob_param, disk_locator_data))) { + LOG_WARN("[STORAGE_LOB]failed to insert new lob col.", K(ret), K(new_row)); + } + return ret; +} + +int ObLobTabletDmlHelper::process_delta_lob( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + blocksstable::ObStorageDatum &old_datum, + ObLobLocatorV2 &delta_lob, + blocksstable::ObStorageDatum &datum) +{ + int ret = OB_SUCCESS; + ObLobManager *lob_mngr = MTL(ObLobManager*); + if (OB_ISNULL(lob_mngr)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[STORAGE_LOB]failed to get lob manager handle.", K(ret)); + } else if (!delta_lob.is_delta_temp_lob()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[STORAGE_LOB] invalid lob type", K(ret), K(delta_lob)); + } else { + ObLobAccessParam lob_param; + // should use old datum + ObLobLocatorV2 old_lob; + ObString old_disk_lob; + old_datum.get_mem_lob(old_lob); + if (!old_lob.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("old lob locator is invalid.", K(ret)); + } else if (OB_FAIL(old_lob.get_disk_locator(old_disk_lob))) { + LOG_WARN("fail to get old lob disk locator.", K(ret)); + // TODO copy old + } else if (OB_FAIL(build_common_lob_param_for_dml(run_ctx, data_row, column, old_disk_lob, lob_param))) { + LOG_WARN("build_common_lob_param_for_dml fail", K(ret), K(column), K(datum), K(old_disk_lob)); + } else if (OB_FAIL(lob_mngr->process_delta(lob_param, delta_lob))) { + LOG_WARN("failed to process delta lob.", K(ret), K(lob_param), K(delta_lob)); + } else { + // update datum with new disk locator + datum.set_lob_data(*lob_param.lob_common_, lob_param.handle_size_); + if (! lob_param.ext_info_log_.is_null() + && OB_FAIL(register_ext_info_commit_cb(run_ctx, datum, lob_param.ext_info_log_))) { + LOG_WARN("register_ext_info_commit_cb fail", K(ret), K(lob_param)); + } + } + } + return ret; +} + +int ObLobTabletDmlHelper::prepare_lob_write( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + const int16_t row_idx, + const int16_t col_idx, + ObString &old_disk_locator, + blocksstable::ObStorageDatum &new_datum, + bool &need_do_write) +{ + int ret = OB_SUCCESS; + uint64_t data_version = 0; + if (is_sys_table(run_ctx.relative_table_.get_table_id())) { + // sys table just write + need_do_write = true; + } else if (OB_FAIL(GET_MIN_DATA_VERSION(MTL_ID(), data_version))) { + LOG_WARN("failed to get data version", K(ret)); + } else if (data_version < DATA_VERSION_4_3_4_0) { + need_do_write = true; + LOG_DEBUG("before 4.3.4", K(data_version), K(column), K(row_idx), K(col_idx)); + } else { + ObString raw_data = (new_datum.is_null() || new_datum.is_nop_value()) + ? ObString(0, nullptr) : new_datum.get_string(); + bool has_lob_header = new_datum.has_lob_header() && raw_data.length() > 0; + ObLobLocatorV2 src_data_locator(raw_data, has_lob_header); + bool is_outrow = false; + ObLobAccessParam lob_param; + ObLobDataInsertTask info; + ObLobManager *lob_mngr = MTL(ObLobManager*); + info.src_data_locator_ = src_data_locator; + if (OB_FAIL(build_common_lob_param_for_dml(run_ctx, data_row, column, old_disk_locator, lob_param))) { + LOG_WARN("build_common_lob_param_for_dml fail", K(ret), K(column), K(src_data_locator)); + } else if (OB_FAIL(lob_mngr->prepare_insert_task(lob_param, is_outrow, info))) { + LOG_WARN("prepare_insert_task fail", K(ret), K(column), K(src_data_locator)); + } else if (is_outrow) { + if (lob_param.lob_meta_tablet_id_.is_valid() && lob_param.lob_piece_tablet_id_.is_valid()) { + run_ctx.lob_dml_ctx_.lob_meta_tablet_id_ = lob_param.lob_meta_tablet_id_; + run_ctx.lob_dml_ctx_.lob_piece_tablet_id_ = lob_param.lob_piece_tablet_id_; + } + // outrow sholud insert after row + // here only construct outrow lob locator + info.col_idx_ = col_idx; + info.row_idx_ = row_idx; + if (OB_FAIL(run_ctx.lob_dml_ctx_.insert_data_info_.push_back(info))) { + LOG_WARN("push back fail", K(ret)); + } else { + new_datum.set_string(info.cur_data_locator_.ptr_, info.cur_data_locator_.size_); + need_do_write = false; + } + } else { + need_do_write = true; + } + } + return ret; +} + +int ObLobTabletDmlHelper::register_ext_info_commit_cb( + ObDMLRunningCtx &run_ctx, + ObDatum &col_data, + ObObj &ext_info_data) +{ + int ret = OB_SUCCESS; + ObLobDiskLocatorWrapper lob_disk_locator; + ObLobDataOutRowCtx *lob_data_outrow_ctx = nullptr; + transaction::ObTxSEQ seq_no_st; + int64_t seq_no_cnt = 0; + ObExtInfoLogHeader header(OB_JSON_DIFF_EXT_INFO_LOG); + const int64_t data_size = ext_info_data.get_string_len() + header.get_serialize_size(); + memtable::ObMvccWriteGuard guard(false); + if (ext_info_data.is_null()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ext_info_log is null", K(ret), K(ext_info_data)); + } else if (OB_FAIL(lob_disk_locator.init(const_cast(col_data.get_string().ptr()), col_data.get_string().length()))) { + LOG_WARN("init disk locator fail", K(ret), K(col_data)); + } else if (OB_ISNULL(lob_data_outrow_ctx = lob_disk_locator.get_outrow_ctx())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("lob_data_outrow_ctx is null", K(ret), K(lob_disk_locator)); + } else if (OB_FAIL(ObExtInfoCbRegister::alloc_seq_no( + run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_, run_ctx.store_ctx_.mvcc_acc_ctx_.tx_scn_, + data_size, seq_no_st, seq_no_cnt))) { + LOG_WARN("alloc_seq_no fail", K(ret)); + } else if (OB_FAIL(guard.write_auth(run_ctx.store_ctx_))) { + LOG_WARN("write_auth fail", K(ret), K(run_ctx.store_ctx_)); + } else if (OB_FAIL(run_ctx.store_ctx_.mvcc_acc_ctx_.mem_ctx_->register_ext_info_commit_cb( + run_ctx.dml_param_.timeout_, run_ctx.dml_flag_, + seq_no_st, seq_no_cnt, header, ext_info_data))) { + LOG_WARN("register_ext_info_commit_cb fail", K(ret), K(run_ctx.store_ctx_), K(col_data), K(ext_info_data)); + } else { + lob_data_outrow_ctx->seq_no_st_ = seq_no_st.cast_to_int(); + lob_data_outrow_ctx->seq_no_cnt_ = seq_no_cnt; + lob_data_outrow_ctx->modified_len_ = data_size; + } + return ret; +} + +int ObLobTabletDmlHelper::register_ext_info_commit_cb( + ObDMLRunningCtx &run_ctx, + const ObColDesc &column, + ObString &index_data, + ObString &data) +{ + int ret = OB_SUCCESS; + ObDatum index_datum; + index_datum.set_string(index_data); + ObObj ext_info_data; + ext_info_data.set_raw(data); + ObLobDiskLocatorWrapper index_lob_disk_locator; + ObLobDiskLocatorWrapper data_lob_disk_locator; + transaction::ObTxSEQ seq_no_st; + int64_t seq_no_cnt = 0; + ObExtInfoLogHeader header(OB_OUTROW_DISK_LOB_LOCATOR_EXT_INFO_LOG); + memtable::ObMvccWriteGuard guard(false); + if (OB_FAIL(index_lob_disk_locator.init(index_data.ptr(), index_data.length()))) { + LOG_WARN("init disk locator fail", K(ret), K(index_data), K(column)); + } else if (OB_FAIL(data_lob_disk_locator.init(data.ptr(), data.length()))) { + LOG_WARN("init disk locator fail", K(ret), K(data), K(column)); + } else if (OB_FAIL(data_lob_disk_locator.check_for_dml(index_lob_disk_locator))) { + LOG_WARN("check_for_dml fail", K(ret), K(data_lob_disk_locator), K(index_lob_disk_locator)); + } else if (! index_lob_disk_locator.is_ext_info_log()) { + LOG_DEBUG("not ext info log", K(index_lob_disk_locator)); + } else if (OB_FALSE_IT(seq_no_st = index_lob_disk_locator.get_seq_no_st())) { + } else if (OB_FALSE_IT(seq_no_cnt = index_lob_disk_locator.get_seq_no_cnt())) { + } else if (OB_FAIL(guard.write_auth(run_ctx.store_ctx_))) { + LOG_WARN("write_auth fail", K(ret), K(run_ctx.store_ctx_)); + } else if (OB_FAIL(run_ctx.store_ctx_.mvcc_acc_ctx_.mem_ctx_->register_ext_info_commit_cb( + run_ctx.dml_param_.timeout_, + run_ctx.dml_flag_, + seq_no_st, + seq_no_cnt, + header, + ext_info_data))) { + LOG_WARN("register_ext_info_commit_cb fail", K(ret), K(run_ctx.store_ctx_), K(seq_no_st), K(seq_no_cnt), K(index_datum), K(ext_info_data)); + } + return ret; +} + +int ObLobTabletDmlHelper::set_lob_storage_params( + ObDMLRunningCtx &run_ctx, + const ObColDesc &column, + ObLobAccessParam &lob_param) +{ + int ret = OB_SUCCESS; + const ObTableDMLParam *table_param = run_ctx.dml_param_.table_param_; + const ObColumnParam *column_param = nullptr; + if (OB_ISNULL(table_param)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table_param is null", K(ret)); + } else if (OB_ISNULL(column_param = table_param->get_data_table().get_column(column.col_id_))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("column_param is null", K(ret), K(table_param)); + } else { + lob_param.inrow_threshold_ = table_param->get_data_table().get_lob_inrow_threshold(); + lob_param.schema_chunk_size_ = column_param->get_lob_chunk_size(); + } + return ret; +} + + +} // end namespace storage +} // end namespace oceanbase diff --git a/src/storage/lob/ob_lob_tablet_dml.h b/src/storage/lob/ob_lob_tablet_dml.h new file mode 100644 index 000000000..7415b6f7c --- /dev/null +++ b/src/storage/lob/ob_lob_tablet_dml.h @@ -0,0 +1,177 @@ +/** + * 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_LOB_TABLET_DML_H_ +#define OCEANBASE_STORAGE_OB_LOB_TABLET_DML_H_ + +#include "storage/lob/ob_lob_util.h" + +namespace oceanbase +{ +namespace storage +{ + +struct ObLobDataInsertTask +{ + + ObLobDataInsertTask(): + src_data_locator_(), + cur_data_locator_(), + col_idx_(0), + row_idx_(0) + {} + + ObLobLocatorV2 src_data_locator_; + ObLobLocatorV2 cur_data_locator_; + int16_t col_idx_; + int16_t row_idx_; + ObArray lob_meta_list_; + + TO_STRING_KV(K_(col_idx), K_(row_idx), K_(src_data_locator), K_(cur_data_locator)); +}; + +struct ObLobTabletDmlCtx +{ + ObLobTabletDmlCtx(): + insert_data_info_() + {} + + ~ObLobTabletDmlCtx(); + + bool is_all_task_done() const { return insert_data_info_.count() != 0; } + + int64_t task_count() const { return insert_data_info_.count(); } + + ObLobDataInsertTask& task(const int64_t idx) { return insert_data_info_[idx]; } + + void reuse() { insert_data_info_.reuse(); } + + common::ObTabletID lob_meta_tablet_id_; + common::ObTabletID lob_piece_tablet_id_; + ObArray insert_data_info_; + + TO_STRING_KV(K_(lob_meta_tablet_id), K_(lob_piece_tablet_id), K_(insert_data_info)); + +}; + +class ObLobTabletDmlHelper +{ + +public: + // insert + static int process_lob_column_before_insert( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &row, + const ObColDesc &column, + const int16_t row_idx, + const int16_t col_idx, + blocksstable::ObStorageDatum &datum); + + static int process_lob_column_after_insert( + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &row, + const ObColDesc &column, + ObLobDataInsertTask &info); + + // update + static int process_lob_column_before_update( + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + const bool data_tbl_rowkey_change, + const ObColDesc &column, + const int16_t row_idx, + const int16_t col_idx, + blocksstable::ObStorageDatum &old_datum, + blocksstable::ObStorageDatum &new_datum); + + static int process_lob_column_after_update( + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + const bool data_tbl_rowkey_change, + const ObColDesc &column, + ObLobDataInsertTask &info); + + static int insert_lob_col( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + blocksstable::ObStorageDatum &datum, + ObLobAccessParam *del_param, + ObString &disk_locator_data, + ObArray *lob_meta_list = nullptr); + static int delete_lob_col( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + blocksstable::ObStorageDatum &datum, + ObLobCommon *&lob_common, + ObLobAccessParam &lob_param); + static int update_lob_col( + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + bool data_tbl_rowkey_change, + const ObColDesc &column, + blocksstable::ObStorageDatum &old_datum, + blocksstable::ObStorageDatum &new_datum); + + // partial update + static int process_delta_lob( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + blocksstable::ObStorageDatum &old_datum, + ObLobLocatorV2 &delta_lob, + blocksstable::ObStorageDatum &datum); + +private: + + static int build_common_lob_param_for_dml( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + ObString &disk_lob_locator, + ObLobAccessParam &lob_param); + + static int prepare_lob_write( + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &data_row, + const ObColDesc &column, + const int16_t row_idx, + const int16_t col_idx, + ObString &old_disk_locator, + blocksstable::ObStorageDatum &new_datum, + bool &need_do_write); + + static int register_ext_info_commit_cb( + ObDMLRunningCtx &run_ctx, + ObDatum &col_data, + ObObj &ext_info_data); + static int register_ext_info_commit_cb( + ObDMLRunningCtx &run_ctx, + const ObColDesc &column, + ObString &index_data, + ObString &data); + + static int set_lob_storage_params( + ObDMLRunningCtx &run_ctx, + const ObColDesc &column, + ObLobAccessParam &lob_param); +}; + +} // end namespace storage +} // end namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_LOB_TABLET_DML_H_ diff --git a/src/storage/lob/ob_lob_util.h b/src/storage/lob/ob_lob_util.h index 7147cb2b3..e908ccee4 100644 --- a/src/storage/lob/ob_lob_util.h +++ b/src/storage/lob/ob_lob_util.h @@ -76,7 +76,7 @@ public: parent_seq_no_(), seq_no_st_(), used_seq_cnt_(0), total_seq_cnt_(0), checksum_(0), update_len_(0), op_type_(ObLobDataOutRowCtx::OpType::SQL), is_fill_zero_(false), from_rpc_(false), inrow_read_nocopy_(false), inrow_threshold_(OB_DEFAULT_LOB_INROW_THRESHOLD), schema_chunk_size_(OB_DEFAULT_LOB_CHUNK_SIZE), - access_ctx_(nullptr), is_store_char_len_(true), lob_id_geneator_(nullptr), remote_query_ctx_(nullptr) + access_ctx_(nullptr), is_store_char_len_(true), lob_id_geneator_(nullptr), remote_query_ctx_(nullptr), data_row_(nullptr) {} ~ObLobAccessParam(); @@ -93,6 +93,7 @@ public: int set_lob_locator(common::ObLobLocatorV2 *lob_locator); int is_timeout(); bool is_char() { return coll_type_ != common::ObCollationType::CS_TYPE_BINARY; } + bool is_blob() { return coll_type_ == common::ObCollationType::CS_TYPE_BINARY; } // chunk size can be changed online. // that means lob data that has been writed may have different chunk size with schema @@ -116,7 +117,7 @@ public: K_(coll_type), K_(scan_backward), K_(offset), K_(len), K_(parent_seq_no), K_(seq_no_st), K_(used_seq_cnt), K_(total_seq_cnt), K_(checksum), K_(update_len), K_(op_type), K_(is_fill_zero), K_(from_rpc), K_(snapshot), K_(tx_id), K_(read_latest), K_(inrow_read_nocopy), K_(schema_chunk_size), K_(inrow_threshold), K_(is_store_char_len), KP_(remote_query_ctx), - KP_(access_ctx), KPC_(lob_id_geneator)); + KP_(access_ctx), KPC_(lob_id_geneator), KPC_(data_row)); private: ObIAllocator *tmp_allocator_; @@ -176,6 +177,7 @@ public: share::ObTabletCacheInterval *lob_id_geneator_; // remote query ctx void *remote_query_ctx_; + const blocksstable::ObDatumRow *data_row_; // for tablet split private: DISALLOW_COPY_AND_ASSIGN(ObLobAccessParam); diff --git a/src/storage/ls/ob_ls.cpp b/src/storage/ls/ob_ls.cpp index c90171309..ac01fe510 100755 --- a/src/storage/ls/ob_ls.cpp +++ b/src/storage/ls/ob_ls.cpp @@ -1013,6 +1013,7 @@ int ObLS::register_common_service() REGISTER_TO_LOGSERVICE(MEDIUM_COMPACTION_LOG_BASE_TYPE, &medium_compaction_clog_handler_); REGISTER_TO_LOGSERVICE(TRANSFER_HANDLER_LOG_BASE_TYPE, &transfer_handler_); REGISTER_TO_LOGSERVICE(LS_BLOCK_TX_SERVICE_LOG_BASE_TYPE, &block_tx_service_); + REGISTER_TO_LOGSERVICE(TABLE_LOCK_LOG_BASE_TYPE, &lock_table_); #ifdef OB_BUILD_SHARED_STORAGE if (GCTX.is_shared_storage_mode()) { REGISTER_TO_LOGSERVICE(SHARED_STORAGE_PRE_WARM_LOG_BASE_TYPE, &ls_prewarm_handler_); @@ -1146,6 +1147,7 @@ void ObLS::unregister_common_service_() UNREGISTER_FROM_LOGSERVICE(MEDIUM_COMPACTION_LOG_BASE_TYPE, &medium_compaction_clog_handler_); UNREGISTER_FROM_LOGSERVICE(TRANSFER_HANDLER_LOG_BASE_TYPE, &transfer_handler_); UNREGISTER_FROM_LOGSERVICE(LS_BLOCK_TX_SERVICE_LOG_BASE_TYPE, &block_tx_service_); + UNREGISTER_FROM_LOGSERVICE(TABLE_LOCK_LOG_BASE_TYPE, &lock_table_); #ifdef OB_BUILD_SHARED_STORAGE if (GCTX.is_shared_storage_mode()) { UNREGISTER_FROM_LOGSERVICE(SHARED_STORAGE_PRE_WARM_LOG_BASE_TYPE, &ls_prewarm_handler_); @@ -1780,7 +1782,7 @@ int ObLS::update_tablet_table_store( return ret; } -int ObLS::build_ha_tablet_new_table_store( +int ObLS::build_tablet_with_batch_tables( const ObTabletID &tablet_id, const ObBatchUpdateTableStoreParam ¶m) { @@ -1798,7 +1800,7 @@ int ObLS::build_ha_tablet_new_table_store( ret = OB_EAGAIN; LOG_WARN("build ha tablet new table store rebuild seq not same, need retry", K(ret), K(ls_id), K(tablet_id), K(rebuild_seq), K(param)); - } else if (OB_FAIL(ls_tablet_svr_.build_ha_tablet_new_table_store(tablet_id, param))) { + } else if (OB_FAIL(ls_tablet_svr_.build_tablet_with_batch_tables(tablet_id, param))) { LOG_WARN("failed to update tablet table store", K(ret), K(ls_id), K(tablet_id), K(param)); } return ret; @@ -1967,17 +1969,14 @@ int ObLS::replay_get_tablet( ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet should not be NULL", K(ret), KP(tablet), K(tablet_id), K(scn)); } else if (tablet->is_empty_shell()) { - ObTabletStatus::Status tablet_status = ObTabletStatus::MAX; if (OB_FAIL(tablet->get_latest_tablet_status(data, is_committed))) { LOG_WARN("failed to get latest tablet status", K(ret), KPC(tablet)); } else if (!is_committed) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet is empty shell but user data is uncommitted, unexpected", K(ret), KPC(tablet)); - } else if (FALSE_IT(tablet_status = data.get_tablet_status())) { - } else if (ObTabletStatus::DELETED != tablet_status - && ObTabletStatus::TRANSFER_OUT_DELETED != tablet_status) { + } else if (OB_UNLIKELY(!data.tablet_status_.is_deleted_for_gc())) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("tablet is empty shell but user data is unexpected", K(ret), KPC(tablet)); + LOG_WARN("tablet is empty shell but user data is unexpected", K(ret), K(data), KPC(tablet)); } else { ret = OB_OBSOLETE_CLOG_NEED_SKIP; LOG_INFO("tablet is already deleted, need skip", KR(ret), K(ls_id), K(tablet_id), K(scn)); @@ -1993,7 +1992,8 @@ int ObLS::replay_get_tablet( } } else if (!is_committed) { if ((ObTabletStatus::NORMAL == data.tablet_status_ && data.create_commit_version_ == ObTransVersion::INVALID_TRANS_VERSION) - || ObTabletStatus::TRANSFER_IN == data.tablet_status_) { + || ObTabletStatus::TRANSFER_IN == data.tablet_status_ + || ObTabletStatus::SPLIT_DST == data.tablet_status_) { ret = OB_EAGAIN; LOG_INFO("latest transaction has not committed yet, should retry", KR(ret), K(ls_id), K(tablet_id), K(scn), "clog_checkpoint_scn", tablet->get_clog_checkpoint_scn(), K(data)); diff --git a/src/storage/ls/ob_ls.h b/src/storage/ls/ob_ls.h index 8f3db22cf..0ccfcc9ab 100644 --- a/src/storage/ls/ob_ls.h +++ b/src/storage/ls/ob_ls.h @@ -632,18 +632,25 @@ public: // const ObTableLockOp &lock_op, // ObTxIDSet &conflict_tx_set); DELEGATE_WITH_RET(lock_table_, check_lock_conflict, int); - // lock a object + // lock an object // @param[in] ctx, store ctx for trans. // @param[in] param, contain the lock id, lock type and so on. // int lock(ObStoreCtx &ctx, // const transaction::tablelock::ObLockParam ¶m); DELEGATE_WITH_RET(lock_table_, lock, int); - // unlock a object + // unlock an object // @param[in] ctx, store ctx for trans. // @param[in] param, contain the lock id, lock type and so on. // int unlock(ObStoreCtx &ctx, // const transaction::tablelock::ObLockParam ¶m); DELEGATE_WITH_RET(lock_table_, unlock, int); + // replace the lock of an object + // @param[in] ctx, store ctx for trans. + // @param[in] param, contain the lock id, lock type and so on of the previous lock, and new owner_id, + // lock_mode of new lock + // int replace(ObStoreCtx &ctx, + // const transaction::tablelock::ObReplaceLockParam ¶m); + DELEGATE_WITH_RET(lock_table_, replace_lock, int); // admin remove a lock op // @param[in] op_info, contain the lock id, lock type and so on. // void admin_remove_lock_op(const ObTableLockOp &op_info); @@ -983,7 +990,7 @@ public: const int64_t ls_rebuild_seq, const ObTabletHandle &old_tablet_handle, const ObIArray &tables); - int build_ha_tablet_new_table_store( + int build_tablet_with_batch_tables( const ObTabletID &tablet_id, const ObBatchUpdateTableStoreParam ¶m); int build_new_tablet_from_mds_table( diff --git a/src/storage/ls/ob_ls_ddl_log_handler.cpp b/src/storage/ls/ob_ls_ddl_log_handler.cpp index 162547fbf..95fd1d961 100644 --- a/src/storage/ls/ob_ls_ddl_log_handler.cpp +++ b/src/storage/ls/ob_ls_ddl_log_handler.cpp @@ -300,6 +300,18 @@ int ObLSDDLLogHandler::replay(const void *buffer, ret = replay_ddl_start_log_(log_buf, buf_size, tmp_pos, log_scn); break; } + case ObDDLClogType::DDL_TABLET_SPLIT_START_LOG: { + ret = replay_tablet_split_start_log_(log_buf, buf_size, tmp_pos, log_scn); + break; + } + case ObDDLClogType::DDL_TABLET_SPLIT_FINISH_LOG: { + ret = replay_tablet_split_finish_log_(log_buf, buf_size, tmp_pos, log_scn); + break; + } + case ObDDLClogType::DDL_TABLET_FREEZE_LOG: { + ret = replay_tablet_freeze_log_(log_buf, buf_size, tmp_pos, log_scn); + break; + } #ifdef OB_BUILD_SHARED_STORAGE case ObDDLClogType::DDL_FINISH_LOG: { ret = replay_ddl_finish_log_(log_buf, buf_size, tmp_pos, log_scn); @@ -588,6 +600,24 @@ int ObLSDDLLogHandler::replay_ddl_start_log_(const char *log_buf, return ret; } +int ObLSDDLLogHandler::replay_tablet_split_start_log_(const char *log_buf, + const int64_t buf_size, + int64_t pos, + const SCN &log_scn) +{ + int ret = OB_SUCCESS; + ObTabletSplitStartLog log; + if (OB_FAIL(log.deserialize(log_buf, buf_size, pos))) { + LOG_WARN("deserialize tablet split start log failed", K(ret)); + } else if (OB_FAIL(ddl_log_replayer_.replay_split_start(log, log_scn))) { + if (OB_TABLET_NOT_EXIST != ret && OB_EAGAIN != ret) { + LOG_WARN("replay tablet split start log failed", K(ret), K(log)); + ret = OB_EAGAIN; + } + } + return ret; +} + void ObLSDDLLogHandler::add_ddl_event(const int ret, const ObString &ddl_event_stmt) { SERVER_EVENT_ADD("ddl", ddl_event_stmt.ptr(), @@ -606,6 +636,24 @@ int ObLSDDLLogHandler::add_tablet(const ObTabletID &tablet_id) return ret; } +int ObLSDDLLogHandler::replay_tablet_split_finish_log_(const char *log_buf, + const int64_t buf_size, + int64_t pos, + const SCN &log_scn) +{ + int ret = OB_SUCCESS; + ObTabletSplitFinishLog log; + if (OB_FAIL(log.deserialize(log_buf, buf_size, pos))) { + LOG_WARN("deserialize tablet split start log failed", K(ret)); + } else if (OB_FAIL(ddl_log_replayer_.replay_split_finish(log, log_scn))) { + if (OB_TABLET_NOT_EXIST != ret && OB_EAGAIN != ret) { + LOG_WARN("replay tablet split finish log failed", K(ret), K(log)); + ret = OB_EAGAIN; + } + } + return ret; +} + int ObLSDDLLogHandler::del_tablets(const common::ObIArray &tablet_ids) { int ret = OB_SUCCESS; @@ -624,5 +672,23 @@ int ObLSDDLLogHandler::get_tablets(common::ObIArray &tablet_ids) return ret; } +int ObLSDDLLogHandler::replay_tablet_freeze_log_(const char *log_buf, + const int64_t buf_size, + int64_t pos, + const SCN &log_scn) +{ + int ret = OB_SUCCESS; + ObTabletFreezeLog log; + if (OB_FAIL(log.deserialize(log_buf, buf_size, pos))) { + LOG_WARN("deserialize tablet freeze log failed", K(ret)); + } else if (OB_FAIL(ddl_log_replayer_.replay_tablet_freeze(log, log_scn))) { + if (OB_TABLET_NOT_EXIST != ret && OB_EAGAIN != ret) { + LOG_WARN("replay tablet freeze log failed", K(ret), K(log)); + ret = OB_EAGAIN; + } + } + return ret; } -} + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/ls/ob_ls_ddl_log_handler.h b/src/storage/ls/ob_ls_ddl_log_handler.h index 08dabf2d6..ef85df701 100644 --- a/src/storage/ls/ob_ls_ddl_log_handler.h +++ b/src/storage/ls/ob_ls_ddl_log_handler.h @@ -99,6 +99,9 @@ private: int replay_ddl_commit_log_(const char *log_buf, const int64_t buf_size, int64_t pos, const share::SCN &scn); int replay_ddl_tablet_schema_version_change_log_(const char *log_buf, const int64_t buf_size, int64_t pos, const share::SCN &scn); int replay_ddl_start_log_(const char *log_buf, const int64_t buf_size, int64_t pos, const share::SCN &scn); + int replay_tablet_split_start_log_(const char *log_buf, const int64_t buf_size, int64_t pos, const share::SCN &scn); + int replay_tablet_split_finish_log_(const char *log_buf, const int64_t buf_size, int64_t pos, const share::SCN &scn); + int replay_tablet_freeze_log_(const char *log_buf, const int64_t buf_size, int64_t pos, const share::SCN &scn); #ifdef OB_BUILD_SHARED_STORAGE int replay_ddl_finish_log_(const char *log_buf, const int64_t buf_size, int64_t pos, const share::SCN &scn); #endif diff --git a/src/storage/ls/ob_ls_sync_tablet_seq_handler.cpp b/src/storage/ls/ob_ls_sync_tablet_seq_handler.cpp index 96060f2b9..2c2c0349b 100644 --- a/src/storage/ls/ob_ls_sync_tablet_seq_handler.cpp +++ b/src/storage/ls/ob_ls_sync_tablet_seq_handler.cpp @@ -72,6 +72,7 @@ int ObLSSyncTabletSeqHandler::replay(const void *buffer, } else if (OB_FAIL(autoinc_seq_handler.replay_update_tablet_autoinc_seq(ls_, log.get_tablet_id(), log.get_autoinc_seq(), + base_header.need_pre_replay_barrier(), scn))) { LOG_WARN("failed to update tablet auto inc seq", K(ret), K(log)); } diff --git a/src/storage/ls/ob_ls_tablet_service.cpp b/src/storage/ls/ob_ls_tablet_service.cpp index 7817b61f5..f60154cbf 100644 --- a/src/storage/ls/ob_ls_tablet_service.cpp +++ b/src/storage/ls/ob_ls_tablet_service.cpp @@ -62,6 +62,7 @@ #include "storage/tablet/ob_tablet_persister.h" #include "storage/tablet/ob_tablet_service_clog_replay_executor.h" #include "storage/tablet/ob_tablet_status.h" +#include "storage/tablet/ob_tablet_split_mds_helper.h" #include "storage/tablet/ob_tablet_persister.h" #include "storage/tx/ob_trans_define.h" #include "storage/tx/ob_trans_part_ctx.h" @@ -72,11 +73,18 @@ #include "storage/slog/ob_storage_log_struct.h" #include "storage/slog/ob_storage_logger.h" #include "share/ob_lob_access_utils.h" +#include "storage/lob/ob_lob_tablet_dml.h" +#include "observer/table_load/ob_table_load_table_ctx.h" +#include "observer/table_load/ob_table_load_coordinator.h" #include "observer/table_load/ob_table_load_service.h" #include "observer/table_load/ob_table_load_store.h" #include "observer/table_load/ob_table_load_store_trans_px_writer.h" #include "observer/ob_server_event_history_table_operator.h" #include "storage/high_availability/ob_storage_ha_utils.h" +#include "share/ob_partition_split_query.h" +#include "storage/slog_ckpt/ob_tenant_checkpoint_slog_handler.h" +#include "storage/concurrency_control/ob_data_validation_service.h" +#include "share/scheduler/ob_partition_auto_split_helper.h" #include "storage/blocksstable/ob_object_manager.h" #include "storage/meta_store/ob_tenant_storage_meta_service.h" #include "storage/concurrency_control/ob_data_validation_service.h" @@ -1037,6 +1045,7 @@ int ObLSTabletService::update_tablet_table_store( { int ret = OB_SUCCESS; common::ObArenaAllocator allocator(common::ObMemAttr(MTL_ID(), "UpTabStore")); + ObTabletHandle new_tablet_hdl; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("ls tablet svr hasn't been inited", K(ret)); @@ -1067,7 +1076,6 @@ int ObLSTabletService::update_tablet_table_store( } else { time_guard.click("GetTablet"); ObTabletHandle tmp_tablet_hdl; - ObTabletHandle new_tablet_hdl; ObTablet *tmp_tablet = nullptr; const share::ObLSID &ls_id = ls_->get_ls_id(); const ObTabletMapKey key(ls_id, tablet_id); @@ -1091,6 +1099,13 @@ int ObLSTabletService::update_tablet_table_store( } } } + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + ObServerAutoSplitScheduler &auto_split_scheduler = ObServerAutoSplitScheduler::get_instance(); + if (OB_TMP_FAIL(auto_split_scheduler.push_task(new_tablet_hdl, *ls_))) { + LOG_WARN("fail to push auto split task", K(tmp_ret)); + } + } return ret; } @@ -1157,6 +1172,14 @@ int ObLSTabletService::update_tablet_table_store( } } } + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + ObServerAutoSplitScheduler &auto_split_scheduler= ObServerAutoSplitScheduler::get_instance(); + if (OB_TMP_FAIL(auto_split_scheduler.push_task(new_tablet_hdl, *ls_))) { + LOG_WARN("fail to push auto split task", K(ret)); + } + + } return ret; } @@ -1291,7 +1314,7 @@ int ObLSTabletService::build_new_tablet_from_mds_table( ObTabletHandle tmp_tablet_hdl; ObTabletHandle new_tablet_handle; const blocksstable::ObSSTable *mds_sstable = nullptr; - ObTimeGuard time_guard("ObLSTabletService::build_new_tablet_from_mds_table_with_mini", 50_ms); + ObTimeGuard time_guard("ObLSTabletService::build_new_tablet_from_mds_table_with_mini", 30_ms); if (IS_NOT_INIT) { ret = OB_NOT_INIT; @@ -1659,6 +1682,12 @@ int ObLSTabletService::update_tablet_restore_status( LOG_WARN("fail to update tablet", K(ret), K(key), K(disk_addr)); } else { LOG_INFO("succeeded to build new tablet", K(ret), K(key), K(disk_addr), K(restore_status), K(need_reset_transfer_flag), K(tablet_handle)); +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("storage_ha", "update_tablet_restore_status", + "tablet_id", tablet_id.id(), + "old_restore_status", current_status, + "new_restore_status", restore_status); +#endif } if (OB_FAIL(ret)) { @@ -2127,6 +2156,8 @@ int ObLSTabletService::replay_create_tablet( ObTransService *tx_svr = MTL(ObTransService*); ObFreezer *freezer = ls_->get_freezer(); const ObLSID &ls_id = ls_->get_ls_id(); + common::ObArenaAllocator allocator(common::ObMemAttr(MTL_ID(), "ReplayCreate")); + ObTabletHandle tablet_hdl; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); @@ -2137,9 +2168,7 @@ int ObLSTabletService::replay_create_tablet( LOG_ERROR("restart replay tablet should not exist", K(ret), K(ls_id), K(tablet_id)); } else { ObTimeGuard time_guard("ObLSTabletService::replay_create_tablet", 1_s); - common::ObArenaAllocator allocator(common::ObMemAttr(MTL_ID(), "ReplayCreate")); const ObTabletMapKey key(ls_id, tablet_id); - ObTabletHandle tablet_hdl; ObTablet *tablet = nullptr; int64_t pos = 0; ObMetaDiskAddr old_addr; @@ -2204,6 +2233,13 @@ int ObLSTabletService::replay_create_tablet( } } } + if (OB_SUCC(ret)) { + int tmp_ret = OB_SUCCESS; + ObServerAutoSplitScheduler &auto_split_scheduler= ObServerAutoSplitScheduler::get_instance(); + if (OB_TMP_FAIL(auto_split_scheduler.push_task(tablet_hdl, *ls_))) { + LOG_WARN("fail to push auto split task", K(ret)); + } + } return ret; } @@ -2334,16 +2370,17 @@ int ObLSTabletService::inner_table_scan( const int64_t snapshot_version = store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(); const int64_t current_time = ObClockGenerator::getClock(); const int64_t timeout = param.timeout_ - current_time; + bool need_split_dst_table = true; if (OB_UNLIKELY(timeout <= 0)) { ret = OB_TIMEOUT; LOG_WARN("table scan timeout", K(ret), K(current_time), "table_scan_param_timeout", param.timeout_, K(lbt())); - } else if (OB_FAIL(tablet_handle.get_obj()->check_snapshot_readable_with_cache(snapshot_version, param.schema_version_, timeout))) { + } else if (OB_FAIL(tablet_handle.get_obj()->check_snapshot_readable_with_cache(snapshot_version, param.schema_version_, timeout, need_split_dst_table))) { LOG_WARN("failed to check snapshot readable", K(ret), K(snapshot_version), K(param.schema_version_), K(timeout)); } else if (param.need_switch_param_) { - if (OB_FAIL(iter.switch_param(param, tablet_handle))) { + if (OB_FAIL(iter.switch_param(param, tablet_handle, need_split_dst_table))) { LOG_WARN("failed to init table scan iterator, ", K(ret)); } - } else if (OB_FAIL(iter.init(param, tablet_handle))) { + } else if (OB_FAIL(iter.init(param, tablet_handle, need_split_dst_table))) { LOG_WARN("failed to init table scan iterator, ", K(ret)); } } @@ -2382,6 +2419,7 @@ int ObLSTabletService::create_tablet( const ObCreateTabletSchema &create_tablet_schema, const lib::Worker::CompatMode &compat_mode, const bool need_create_empty_major_sstable, + const share::SCN &clog_checkpoint_scn, const bool micro_index_clustered, const bool has_cs_replica, ObTabletHandle &tablet_handle) @@ -2411,8 +2449,7 @@ int ObLSTabletService::create_tablet( ret = OB_ERR_UNEXPECTED; LOG_ERROR("new tablet is null", K(ret), KP(tablet), KP(allocator), K(tablet_handle)); } else if (OB_FAIL(tablet->init_for_first_time_creation(*allocator, ls_id, tablet_id, data_tablet_id, - create_scn, snapshot_version, create_tablet_schema, need_create_empty_major_sstable, micro_index_clustered, - need_generate_cs_replica_cg_array, has_cs_replica, freezer))) { + create_scn, snapshot_version, create_tablet_schema, need_create_empty_major_sstable, clog_checkpoint_scn, micro_index_clustered, need_generate_cs_replica_cg_array, has_cs_replica, freezer))) { LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(create_scn), K(snapshot_version), K(create_tablet_schema)); } else if (OB_FAIL(tablet->get_updating_tablet_pointer_param(param))) { @@ -2450,6 +2487,9 @@ int ObLSTabletService::create_inner_tablet( ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; + uint64_t compat_version = 0; + const uint64_t tenant_id = MTL_ID(); + bool need_create_empty_major_old_version = true; common::ObArenaAllocator allocator(common::ObMemAttr(MTL_ID(), "LSCreateTab")); ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); ObTransService *tx_svr = MTL(ObTransService*); @@ -2460,6 +2500,7 @@ int ObLSTabletService::create_inner_tablet( ObMetaDiskAddr disk_addr; const ObTabletPersisterParam param(ls_id, ls_->get_ls_epoch(), tablet_id, ObTabletTransferInfo::TRANSFER_INIT_SEQ); ObTimeGuard time_guard("ObLSTabletService::create_inner_tablet", 10_ms); + const share::SCN clog_checkpoint_scn = ObTabletMeta::INIT_CLOG_CHECKPOINT_SCN; ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash()); if (OB_FAIL(ObTabletCreateDeleteHelper::create_tmp_tablet(key, allocator, tmp_tablet_hdl))) { @@ -2469,8 +2510,7 @@ int ObLSTabletService::create_inner_tablet( LOG_ERROR("new tablet is null", K(ret), KPC(tmp_tablet), K(tmp_tablet_hdl)); } else if (FALSE_IT(time_guard.click("CreateTablet"))) { } else if (OB_FAIL(tmp_tablet->init_for_first_time_creation(allocator, ls_id, tablet_id, data_tablet_id, - create_scn, snapshot_version, create_tablet_schema, true/*need_create_empty_major_sstable*/, - false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, freezer))) { + create_scn, snapshot_version, create_tablet_schema, true/*need_create_empty_major_sstable*/, clog_checkpoint_scn, false/*micro_index_clustered*/, false/*need_generate_cs_replica_cg_array*/, false/*has_cs_replica*/, freezer))) { LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(create_scn), K(snapshot_version), K(create_tablet_schema)); } else if (FALSE_IT(time_guard.click("InitTablet"))) { @@ -2744,10 +2784,14 @@ int ObLSTabletService::create_memtable( if (for_replay) { } else if (OB_FAIL(old_tablet.ObITabletMdsInterface::get_latest_tablet_status(user_data, is_committed))) { LOG_WARN("fail to get latest tablet status", K(ret)); - } else if (!is_committed || (user_data.tablet_status_ != ObTabletStatus::NORMAL - && user_data.tablet_status_ != ObTabletStatus::TRANSFER_IN)) { + } else if (is_committed && ObTabletStatus::SPLIT_SRC == user_data.tablet_status_) { + ret = OB_TABLET_IS_SPLIT_SRC; + LOG_WARN("tablet is split src, not allow to create new memtable", K(ret), K(user_data)); + } else if (!is_committed || !user_data.tablet_status_.is_writable_for_dml()) { ret = OB_EAGAIN; - LOG_WARN("tablet status not allow create new memtable", K(ret), K(is_committed), K(user_data)); + if (REACH_TIME_INTERVAL(10000)) { + LOG_WARN("tablet status not allow create new memtable", K(ret), K(is_committed), K(user_data)); + } } if (FAILEDx(old_tablet.create_memtable(schema_version, clog_checkpoint_scn, for_direct_load, for_replay))) { if (OB_MINOR_FREEZE_NOT_ALLOW != ret) { @@ -2792,7 +2836,29 @@ int ObLSTabletService::get_read_tables( // snapshot used for filter tables in table_store const int64_t snapshot_version_for_tables, ObTabletTableIterator &iter, - const bool allow_no_ready_read) + const bool allow_no_ready_read, + const bool need_split_src_table, + const bool need_split_dst_table) +{ + int ret = inner_get_read_tables(tablet_id, timeout_us, snapshot_version_for_tablet, snapshot_version_for_tables, iter, allow_no_ready_read, need_split_src_table, false/*need_split_dst_table*/, ObMDSGetTabletMode::READ_READABLE_COMMITED); + if (OB_TABLET_IS_SPLIT_SRC == ret && need_split_dst_table) { + if (OB_FAIL(inner_get_read_tables_for_split_src(tablet_id, timeout_us, snapshot_version_for_tables, iter, allow_no_ready_read))) { + LOG_WARN("failed to inner get read tables", K(ret)); + } + } + return ret; +} + +int ObLSTabletService::inner_get_read_tables( + const common::ObTabletID tablet_id, + const int64_t timeout_us, + const int64_t snapshot_version_for_tablet, + const int64_t snapshot_version_for_tables, + ObTabletTableIterator &iter, + const bool allow_no_ready_read, + const bool need_split_src_table, + const bool need_split_dst_table, + const ObMDSGetTabletMode mode) { int ret = OB_SUCCESS; ObTabletHandle &handle = iter.tablet_handle_; @@ -2817,7 +2883,7 @@ int ObLSTabletService::get_read_tables( } else if (FALSE_IT(key.ls_id_ = ls_->get_ls_id())) { } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, timeout_us, - ObMDSGetTabletMode::READ_READABLE_COMMITED, + mode, snapshot_version_for_tablet))) { if (OB_TABLET_NOT_EXIST != ret) { LOG_WARN("fail to check and get tablet", K(ret), K(key), K(timeout_us), @@ -2826,7 +2892,7 @@ int ObLSTabletService::get_read_tables( } else if (OB_UNLIKELY(!handle.is_valid())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected error, invalid tablet handle", K(ret), K(handle)); - } else if (OB_FAIL(handle.get_obj()->get_read_tables(snapshot_version_for_tables, iter, allow_no_ready_read))) { + } else if (OB_FAIL(handle.get_obj()->get_read_tables(snapshot_version_for_tables, iter, allow_no_ready_read, need_split_src_table, need_split_dst_table))) { LOG_WARN("fail to get read tables", K(ret), K(handle), K(tablet_id), K(snapshot_version_for_tablet), K(snapshot_version_for_tables), K(iter), K(allow_no_ready_read)); @@ -2834,6 +2900,50 @@ int ObLSTabletService::get_read_tables( return ret; } +// Caller guarantees snapshot version checks has been passed, e.g., snapshot_version >= tablet's create_commit_version_. +// Because split src tablets can only be accessed using READ_ALL_COMMITED with INT64_MAX snapshot_version. +int ObLSTabletService::inner_get_read_tables_for_split_src( + const common::ObTabletID tablet_id, + const int64_t timeout_us, + const int64_t snapshot_version, + ObTabletTableIterator &iter, + const bool allow_no_ready_read) +{ + int ret = OB_SUCCESS; + ObTabletHandle &handle = iter.tablet_handle_; + iter.reset(); + ObTabletMapKey key; + key.tablet_id_ = tablet_id; + + if (OB_UNLIKELY(!is_inited_)) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!tablet_id.is_valid() || snapshot_version < 0)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(snapshot_version)); + } else if (FALSE_IT(key.ls_id_ = ls_->get_ls_id())) { + } else if (OB_FAIL(ObTabletCreateDeleteHelper::check_and_get_tablet(key, handle, + timeout_us, + ObMDSGetTabletMode::READ_ALL_COMMITED, + INT64_MAX))) { + if (OB_TABLET_NOT_EXIST != ret) { + LOG_WARN("fail to check and get tablet", K(ret), K(key), K(timeout_us), K(snapshot_version)); + } + } else if (OB_UNLIKELY(!handle.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected error, invalid tablet handle", K(ret), K(handle)); + } else if (OB_FAIL(handle.get_obj()->get_read_tables( + snapshot_version, + iter, + allow_no_ready_read, + false/*need_split_src_table*/, + true/*need_split_dst_table*/))) { + LOG_WARN("fail to get read tables", K(ret), K(handle), K(tablet_id), K(snapshot_version), + K(iter), K(allow_no_ready_read)); + } + return ret; +} + int ObLSTabletService::set_tablet_status( const common::ObTabletID &tablet_id, const ObTabletCreateDeleteMdsUserData &tablet_status, @@ -3097,6 +3207,11 @@ int ObLSTabletService::insert_rows( if (OB_ITER_END == ret) { ret = OB_SUCCESS; } + if (OB_SUCC(ret) && run_ctx.lob_dml_ctx_.is_all_task_done()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("lob data may not be insert", K(ret), K(run_ctx.lob_dml_ctx_)); + } + } if (OB_SUCC(ret)) { LOG_DEBUG("succeeded to insert rows", K(ret), K(afct_num)); @@ -3168,19 +3283,20 @@ int ObLSTabletService::direct_insert_rows( int ObLSTabletService::get_storage_row( const ObDatumRow &sql_row, const ObIArray &column_ids, + const ObColDescIArray &column_descs, ObSingleRowGetter &row_getter, - ObDMLRunningCtx &run_ctx, + ObRelativeTable &data_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, ObDatumRow *&out_row, bool use_fuse_row_cache) { int ret = OB_SUCCESS; ObDatumRowkey datum_rowkey; ObDatumRowkeyHelper rowkey_helper; - ObRelativeTable &data_table = run_ctx.relative_table_; - const ObColDescIArray &column_descs = *run_ctx.col_descs_; if (OB_FAIL(rowkey_helper.prepare_datum_rowkey(sql_row, data_table.get_rowkey_column_num(), column_descs, datum_rowkey))) { LOG_WARN("failed to prepare rowkey", K(ret), K(sql_row), K(column_descs)); - } else if (OB_FAIL(init_single_row_getter(row_getter, run_ctx, column_ids, data_table, true))) { + } else if (OB_FAIL(init_single_row_getter(row_getter, store_ctx, dml_param, column_ids, data_table, true))) { LOG_WARN("failed to init single row getter", K(ret), K(column_ids)); } else if (OB_FAIL(row_getter.open(datum_rowkey, use_fuse_row_cache))) { LOG_WARN("failed to open storage row", K(ret), K(datum_rowkey)); @@ -3264,10 +3380,14 @@ int ObLSTabletService::insert_row( // However, under circumstances where an exception may unexpectedly // prevent us from reading the conflicting rows within statements, // at such times, it becomes necessary for us to mock the rows. - if (OB_TMP_FAIL(get_conflict_rows(tablet_handle, - run_ctx, + if (OB_TMP_FAIL(get_conflict_rows_wrap(tablet_handle, + run_ctx.dml_param_.data_row_for_lob_, + run_ctx.relative_table_, + run_ctx.store_ctx_, + run_ctx.dml_param_, flag, duplicated_column_ids, + *run_ctx.col_descs_, row, duplicated_rows))) { LOG_WARN("failed to get conflict row(s)", K(ret), K(duplicated_column_ids), K(row)); @@ -3288,6 +3408,11 @@ int ObLSTabletService::insert_row( EVENT_INC(STORAGE_INSERT_ROW_COUNT); } } + if (OB_SUCC(ret) && run_ctx.lob_dml_ctx_.is_all_task_done()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("lob data may not be insert", K(ret), K(run_ctx.lob_dml_ctx_)); + } + } return ret; } @@ -3428,6 +3553,8 @@ int ObLSTabletService::update_rows( // dispose these two rows together, otherwise, when total_quantity_log is false, // row_iter2 doesn't contain old rows, and old_datum_row is a dummy param in process_new_row while (OB_SUCC(ret) && OB_SUCC(row_iter2.get_next_row(new_datum_row))) { + // need to be called just after get_next_row to ensure that previous row's LOB memoroy is valid if get_next_row accesses it + dml_param.lob_allocator_.reuse(); // Let ObStorageTableGuard refresh retired memtable, should not hold origin tablet handle // outside the while loop. if (tmp_handle.get_obj() != run_ctx.relative_table_.tablet_iter_.get_tablet_handle().get_obj()) { @@ -3448,6 +3575,13 @@ int ObLSTabletService::update_rows( tbl_rowkey_change))) { LOG_WARN("check data table rowkey change failed", K(ret), K(old_datum_row), K(new_datum_row), K(data_tbl_rowkey_len)); + } else if (OB_FAIL(process_lob_before_update(tmp_handle, + run_ctx, + update_idx, + old_datum_row, + new_datum_row, + tbl_rowkey_change))) { + LOG_WARN("process_lob_before_update fail", K(ret), K(old_datum_row), K(old_datum_row)); } else if (OB_FAIL(process_new_row(tmp_handle, run_ctx, update_idx, @@ -3455,6 +3589,13 @@ int ObLSTabletService::update_rows( new_datum_row, tbl_rowkey_change))) { LOG_WARN("fail to process new row", K(ret), K(old_datum_row), K(new_datum_row)); + } else if (OB_FAIL(process_lob_after_update(tablet_handle, + run_ctx, + update_idx, + old_datum_row, + new_datum_row, + tbl_rowkey_change))) { + LOG_WARN("process_lob_after_update fail", K(ret), K(old_datum_row), K(new_datum_row)); } timeguard.click("Process"); } @@ -3465,6 +3606,10 @@ int ObLSTabletService::update_rows( if (OB_ITER_END == ret) { ret = OB_SUCCESS; } + if (OB_SUCC(ret) && run_ctx.lob_dml_ctx_.is_all_task_done()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("lob data may not be insert", K(ret), K(run_ctx.lob_dml_ctx_)); + } old_datum_row.reset(); if (OB_SUCC(ret)) { affected_rows = afct_num; @@ -3555,6 +3700,10 @@ int ObLSTabletService::put_rows( if (OB_ITER_END == ret) { ret = OB_SUCCESS; } + if (OB_SUCC(ret) && run_ctx.lob_dml_ctx_.is_all_task_done()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("lob data may not be insert", K(ret), K(run_ctx.lob_dml_ctx_)); + } } if (OB_SUCC(ret)) { LOG_DEBUG("succeeded to put rows", K(ret)); @@ -3699,13 +3848,13 @@ int ObLSTabletService::lock_rows( int64_t cur_time = ObClockGenerator::getClock(); LOG_WARN("query timeout", K(cur_time), K(dml_param), K(ret)); } else if (GCONF.enable_defensive_check() - && OB_FAIL(check_old_row_legitimacy(datum_utils.get_cmp_funcs(), tmp_handle, run_ctx, *row))) { + && OB_FAIL(check_old_row_legitimacy_wrap(datum_utils.get_cmp_funcs(), tmp_handle, run_ctx, *row))) { LOG_WARN("check row legitimacy failed", K(ret), KPC(row)); } else if (GCONF.enable_defensive_check() && OB_FAIL(check_datum_row_nullable_value(col_desc, relative_table, *row))) { LOG_WARN("check lock row nullable failed", K(ret)); } else if (FALSE_IT(timeguard.click("Check"))) { - } else if (OB_FAIL(tmp_handle.get_obj()->lock_row(run_ctx.relative_table_, ctx, col_desc, *row))) { + } else if (OB_FAIL(lock_row_wrap(tmp_handle, dml_param.data_row_for_lob_, run_ctx.relative_table_, ctx, col_desc, *row))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret) { LOG_WARN("failed to lock row", K(*row), K(ret)); } @@ -3759,7 +3908,7 @@ int ObLSTabletService::lock_row( ret = OB_TIMEOUT; int64_t cur_time = ObClockGenerator::getClock(); LOG_WARN("query timeout", K(cur_time), K(dml_param), K(ret)); - } else if (OB_FAIL(tablet_handle.get_obj()->lock_row(run_ctx.relative_table_, ctx, col_desc, row))) { + } else if (OB_FAIL(lock_row_wrap(tablet_handle, dml_param.data_row_for_lob_, run_ctx.relative_table_, ctx, col_desc, row))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret) { LOG_WARN("failed to lock row", K(row), K(ret)); } @@ -3898,7 +4047,7 @@ int ObLSTabletService::rebuild_create_tablet( return ret; } -int ObLSTabletService::build_ha_tablet_new_table_store( +int ObLSTabletService::build_tablet_with_batch_tables( const ObTabletID &tablet_id, const ObBatchUpdateTableStoreParam ¶m) { @@ -4080,32 +4229,38 @@ int ObLSTabletService::safe_create_cas_empty_shell( int ObLSTabletService::check_old_row_legitimacy( const ObStoreCmpFuncs &cmp_funcs, ObTabletHandle &data_tablet_handle, - ObDMLRunningCtx &run_ctx, - blocksstable::ObDatumRow &old_row) + ObRelativeTable &data_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, + const ObIArray *column_ids_ptr, + const ObColDescIArray *col_descs_ptr, + const bool is_need_check_old_row, + const bool is_udf, + const blocksstable::ObDmlFlag &dml_flag, + const blocksstable::ObDatumRow &old_row) { int ret = OB_SUCCESS; // usage: // alter system set_tp tp_no=9,match=3221487629,error_code=4377,frequency=1 // where session_id is 3221487629 - const int inject_err = OB_E(EventTable::EN_9, run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_->get_session_id()) OB_SUCCESS; + const int inject_err = OB_E(EventTable::EN_9, store_ctx.mvcc_acc_ctx_.tx_desc_->get_session_id()) OB_SUCCESS; if (OB_ERR_DEFENSIVE_CHECK == inject_err) { ret = OB_ERR_DEFENSIVE_CHECK; } - ObRelativeTable &data_table = run_ctx.relative_table_; if (OB_FAIL(ret)) { - } else if (OB_UNLIKELY(data_table.get_rowkey_column_num() > old_row.count_) || OB_ISNULL(run_ctx.column_ids_)) { + } else if (OB_UNLIKELY(data_table.get_rowkey_column_num() > old_row.count_) || OB_ISNULL(column_ids_ptr)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("old row is invalid", K(ret), K(old_row), K(data_table.get_rowkey_column_num()), KP(run_ctx.column_ids_)); - } else if (run_ctx.is_need_check_old_row_) { + LOG_WARN("old row is invalid", K(ret), K(old_row), K(data_table.get_rowkey_column_num()), KP(column_ids_ptr)); + } else if (is_need_check_old_row) { //the vertical partition is no longer maintained, //and the defense check skips the vertical partition function ObArenaAllocator scan_allocator(common::ObMemAttr(MTL_ID(), ObModIds::OB_TABLE_SCAN_ITER)); ObSingleRowGetter storage_row_getter(scan_allocator, *data_tablet_handle.get_obj()); ObDatumRow *storage_old_row = nullptr; - const ObIArray &column_ids = *run_ctx.column_ids_; - const ObColDescIArray &column_descs = *run_ctx.col_descs_; + const ObIArray &column_ids = *column_ids_ptr; + const ObColDescIArray &column_descs = *col_descs_ptr; uint64_t err_col_id = OB_INVALID_ID; - if (OB_FAIL(get_storage_row(old_row, column_ids, storage_row_getter, run_ctx, storage_old_row, true))) { + if (OB_FAIL(get_storage_row(old_row, column_ids, column_descs, storage_row_getter, data_table, store_ctx, dml_param, storage_old_row, true))) { if (OB_ITER_END == ret) { ret = OB_ERR_DEFENSIVE_CHECK; FLOG_WARN("old row in storage is not exists", K(ret), K(old_row)); @@ -4150,31 +4305,31 @@ int ObLSTabletService::check_old_row_legitimacy( } } - if (OB_ERR_DEFENSIVE_CHECK == ret && run_ctx.dml_param_.is_batch_stmt_) { + if (OB_ERR_DEFENSIVE_CHECK == ret && dml_param.is_batch_stmt_) { // 批量删除的时候可能索引表的删除在主表前边,所以所有的表在batch删除的时候出现4377,都可能是重复删导致的 ret = OB_BATCHED_MULTI_STMT_ROLLBACK; LOG_TRACE("batch stmt execution has a correctness error, needs rollback", K(ret), "column_id", column_ids, KPC(storage_old_row), "sql_old_row", old_row, - "dml_param", run_ctx.dml_param_, - "dml_type", run_ctx.dml_flag_); + K(dml_param), + "dml_type", dml_flag); } if (OB_ERR_DEFENSIVE_CHECK == ret) { int tmp_ret = OB_SUCCESS; bool is_virtual_gen_col = false; - if (OB_TMP_FAIL(check_real_leader_for_4377_(run_ctx.store_ctx_.ls_id_))) { + if (OB_TMP_FAIL(check_real_leader_for_4377_(store_ctx.ls_id_))) { ret = tmp_ret; LOG_WARN("check real leader for 4377 found exception", K(ret), K(old_row), K(data_table)); - } else if (nullptr != run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_ - && OB_TMP_FAIL(check_need_rollback_in_transfer_for_4377_(run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_, + } else if (nullptr != store_ctx.mvcc_acc_ctx_.tx_desc_ + && OB_TMP_FAIL(check_need_rollback_in_transfer_for_4377_(store_ctx.mvcc_acc_ctx_.tx_desc_, data_tablet_handle))) { ret = tmp_ret; LOG_WARN("check need rollback in transfer for 4377 found exception", K(ret), K(old_row), K(data_table)); - } else if (OB_TMP_FAIL(check_parts_tx_state_in_transfer_for_4377_(run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_))) { + } else if (OB_TMP_FAIL(check_parts_tx_state_in_transfer_for_4377_(store_ctx.mvcc_acc_ctx_.tx_desc_))) { ret = tmp_ret; LOG_WARN("check need rollback in transfer for 4377 found exception", K(ret), K(old_row), K(data_table)); - } else if (run_ctx.is_udf_) { + } else if (is_udf) { ret = OB_ERR_INDEX_KEY_NOT_FOUND; LOG_WARN("index key not found on udf column", K(ret), K(old_row)); } else if (data_table.is_index_table() && OB_TMP_FAIL(check_is_gencol_check_failed(data_table, err_col_id, is_virtual_gen_col))) { @@ -4193,16 +4348,16 @@ int ObLSTabletService::check_old_row_legitimacy( "column_id", column_ids, KPC(storage_old_row), "sql_old_row", old_row, - "dml_param", run_ctx.dml_param_, - "dml_flag", run_ctx.dml_flag_, - "store_ctx", run_ctx.store_ctx_, - "relative_table", run_ctx.relative_table_); + K(dml_param), + K(dml_flag), + K(store_ctx), + "relative_table", data_table); LOG_DBA_ERROR_V2(OB_STORAGE_DEFENSIVE_CHECK_FAIL, OB_ERR_DEFENSIVE_CHECK, "Fatal Error!!! Catch a defensive error!"); - concurrency_control::ObDataValidationService::set_delay_resource_recycle(run_ctx.store_ctx_.ls_id_); + concurrency_control::ObDataValidationService::set_delay_resource_recycle(store_ctx.ls_id_); LOG_ERROR("Dump data table info", K(ret), K(data_table)); - run_ctx.store_ctx_.force_print_trace_log(); + store_ctx.force_print_trace_log(); } } } @@ -4337,10 +4492,12 @@ int ObLSTabletService::insert_rows_to_tablet( } } else if (OB_FAIL(insert_vector_index_rows(tablet_handle, run_ctx, rows, row_count))) { LOG_WARN("failed to process vector index rows", K(ret)); - } else if (OB_FAIL(insert_lob_tablet_rows(tablet_handle, run_ctx, rows, row_count))) { - LOG_WARN("failed to insert rows to lob tablet", K(ret)); + } else if (OB_FAIL(process_lob_before_insert(tablet_handle, run_ctx, rows, row_count))) { + LOG_WARN("process_lob_before_insert fail", K(ret), K(row_count)); } else if (OB_FAIL(insert_tablet_rows(row_count, tablet_handle, run_ctx, rows, rows_info))) { LOG_WARN("failed to insert rows to data tablet", K(ret)); + } else if (OB_FAIL(process_lob_after_insert(tablet_handle, run_ctx, rows, row_count))) { + LOG_WARN("process_lob_after_insert fail", K(ret), K(row_count)); } else { afct_num = afct_num + row_count; } @@ -4372,8 +4529,8 @@ int ObLSTabletService::insert_tablet_rows( // would be more efficient and elegant to completely merge the uniqueness // constraint and write conflict checking. // - // if (check_exists && OB_FAIL(tablet_handle.get_obj()->rowkeys_exists(run_ctx.store_ctx_, table, - // rows_info, exists))) { + // if (check_exists && OB_FAIL(rowkeys_exists_wrap(tablet_handle, run_ctx.dml_param_.data_row_for_lob_, table, run_ctx.store_ctx_, + // rows_info, exists))) { // LOG_WARN("Failed to check the uniqueness constraint", K(ret), K(rows_info)); // } else if (exists) { // ret = OB_ERR_PRIMARY_KEY_DUPLICATE; @@ -4385,7 +4542,7 @@ int ObLSTabletService::insert_tablet_rows( // Check write conflict in memtable + sstable. // Check uniqueness constraint in sstable only. if (OB_SUCC(ret)) { - if (OB_FAIL(tablet_handle.get_obj()->insert_rows(table, run_ctx.store_ctx_, rows, rows_info, + if (OB_FAIL(insert_rows_wrap(tablet_handle, run_ctx.dml_param_.data_row_for_lob_, table, run_ctx.store_ctx_, rows, rows_info, check_exists, *run_ctx.col_descs_, row_count, run_ctx.dml_param_.encrypt_meta_))) { if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret) { blocksstable::ObDatumRowkey &duplicate_rowkey = rows_info.get_conflict_rowkey(); @@ -4475,7 +4632,7 @@ int ObLSTabletService::put_tablet_rows( // 2. Insert rows with write conflict checking. // Check write conflict in memtable + sstable. if (OB_SUCC(ret)) { - if (OB_FAIL(tablet_handle.get_obj()->insert_rows(table, run_ctx.store_ctx_, rows, rows_info, + if (OB_FAIL(insert_rows_wrap(tablet_handle, run_ctx.dml_param_.data_row_for_lob_, table, run_ctx.store_ctx_, rows, rows_info, false /* check_exists */, *run_ctx.col_descs_, row_count, run_ctx.dml_param_.encrypt_meta_))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret) { LOG_WARN("Failed to insert rows to tablet", K(ret), K(rows_info)); @@ -4485,77 +4642,11 @@ int ObLSTabletService::put_tablet_rows( return ret; } -int ObLSTabletService::insert_lob_col( +int ObLSTabletService::process_lob_before_insert( + ObTabletHandle &tablet_handle, ObDMLRunningCtx &run_ctx, - const ObColDesc &column, - blocksstable::ObStorageDatum &datum, - ObLobAccessParam *del_param, - ObLobCommon *lob_common) -{ - int ret = OB_SUCCESS; - uint64_t lob_id; - ObLobManager *lob_mngr = MTL(ObLobManager*); - if (OB_ISNULL(lob_mngr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[STORAGE_LOB]failed to get lob manager handle.", K(ret)); - } else if (!column.col_type_.is_lob_storage() || datum.is_nop_value() || datum.is_null()) { - // do nothing - } else { - // init lob access param - ObLobAccessParam lob_param; - lob_param.tx_desc_ = run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_; - lob_param.parent_seq_no_ = run_ctx.store_ctx_.mvcc_acc_ctx_.tx_scn_; - lob_param.is_total_quantity_log_ = run_ctx.dml_param_.is_total_quantity_log_; - if (OB_FAIL(lob_param.snapshot_.assign(run_ctx.dml_param_.snapshot_))) { - LOG_WARN("assign snapshot fail", K(ret)); - } else if (lob_param.snapshot_.is_none_read()) { - // NOTE: - // lob_insert need table_scan, the snapshot already generated in - // run_ctx.store_ctx, use it as an LS ReadSnapshot - lob_param.snapshot_.init_ls_read(run_ctx.store_ctx_.ls_id_, - run_ctx.store_ctx_.mvcc_acc_ctx_.snapshot_); - } - lob_param.tx_id_ = lob_param.tx_desc_->get_tx_id(); - lob_param.sql_mode_ = run_ctx.dml_param_.sql_mode_; - lob_param.ls_id_ = run_ctx.store_ctx_.ls_id_; - lob_param.tablet_id_ = run_ctx.relative_table_.get_tablet_id(); - lob_param.coll_type_ = ObLobCharsetUtil::get_collation_type(column.col_type_.get_type(), column.col_type_.get_collation_type()); - lob_param.allocator_ = &run_ctx.dml_param_.lob_allocator_; - lob_param.lob_common_ = lob_common; - if (OB_NOT_NULL(del_param)) { - lob_param.handle_size_ = del_param->handle_size_; - lob_param.checksum_ = del_param->checksum_; - lob_param.total_seq_cnt_ = del_param->total_seq_cnt_; - lob_param.used_seq_cnt_ = del_param->used_seq_cnt_; - lob_param.seq_no_st_ = del_param->seq_no_st_; - } - lob_param.timeout_ = run_ctx.dml_param_.timeout_; - lob_param.scan_backward_ = false; - lob_param.offset_ = 0; - // Notice: currently only inrow data - ObString raw_data = datum.get_string(); - ObString data; - // for not strict sql mode, will insert empty string without lob header - bool has_lob_header = datum.has_lob_header() && raw_data.length() > 0; - ObLobLocatorV2 loc(raw_data, has_lob_header); - if (FAILEDx(set_lob_storage_params(run_ctx, column, lob_param))) { - LOG_WARN("set_lob_storage_params fail", K(ret), K(column)); - } else if (OB_FAIL(lob_mngr->append(lob_param, loc))) { - LOG_WARN("[STORAGE_LOB]lob append failed.", K(ret)); - } else { - ObLobCommon *res_lob_common = lob_param.lob_common_; - datum.set_lob_data(*res_lob_common, lob_param.handle_size_); - LOG_DEBUG("[STORAGE_LOB]write ob lob data.", K(lob_param), KPC(res_lob_common), - K(lob_param.handle_size_), K(column.col_type_.get_collation_type())); - } - } - return ret; -} - -int ObLSTabletService::insert_lob_tablet_row( - ObTabletHandle &data_tablet, - ObDMLRunningCtx &run_ctx, - blocksstable::ObDatumRow &datum_row) + blocksstable::ObDatumRow &datum_row, + const int16_t row_idx) { int ret = OB_SUCCESS; int64_t col_cnt = run_ctx.col_descs_->count(); @@ -4580,8 +4671,8 @@ int ObLSTabletService::insert_lob_tablet_row( if (datum.is_null() || datum.is_nop_value()) { // do nothing } else if (column.col_type_.is_lob_storage()) { - if (OB_FAIL(insert_lob_col(run_ctx, column, datum, nullptr, nullptr))) { - LOG_WARN("[STORAGE_LOB]failed to insert lob col.", K(ret), K(datum_row), K(i)); + if (OB_FAIL(ObLobTabletDmlHelper::process_lob_column_before_insert(tablet_handle, run_ctx, datum_row, column, row_idx, i, datum))) { + LOG_WARN("process_lob_column_before_insert fail", K(ret), K(column), K(i), K(datum), K(datum_row)); } } } @@ -4616,8 +4707,8 @@ int update_lob_meta_table_seq_no(ObDMLRunningCtx &run_ctx, int64_t row_count) return ret; } -int ObLSTabletService::insert_lob_tablet_rows( - ObTabletHandle &data_tablet, +int ObLSTabletService::process_lob_before_insert( + ObTabletHandle &tablet_handle, ObDMLRunningCtx &run_ctx, blocksstable::ObDatumRow *rows, int64_t row_count) @@ -4633,8 +4724,8 @@ int ObLSTabletService::insert_lob_tablet_rows( } else { int64_t col_cnt = run_ctx.col_descs_->count(); for (int64_t k = 0; OB_SUCC(ret) && k < row_count; k++) { - if (OB_FAIL(insert_lob_tablet_row(data_tablet, run_ctx, rows[k]))) { - LOG_WARN("[STORAGE_LOB]failed to insert lob row.", K(ret)); + if (OB_FAIL(process_lob_before_insert(tablet_handle, run_ctx, rows[k], k))) { + LOG_WARN("[STORAGE_LOB]failed to insert lob row.", K(ret), K(k)); } } } @@ -4898,129 +4989,13 @@ int ObLSTabletService::check_rowkey_value_change( return ret; } -int ObLSTabletService::process_delta_lob( - ObDMLRunningCtx &run_ctx, - const ObColDesc &column, - ObStorageDatum &old_datum, - ObLobLocatorV2 &delta_lob, - ObStorageDatum &datum) -{ - int ret = OB_SUCCESS; - ObLobManager *lob_mngr = MTL(ObLobManager*); - if (OB_ISNULL(lob_mngr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[STORAGE_LOB]failed to get lob manager handle.", K(ret)); - } else if (!delta_lob.is_delta_temp_lob()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[STORAGE_LOB] invalid lob type", K(ret), K(delta_lob)); - } else { - ObLobAccessParam lob_param; - // init lob param - lob_param.tx_desc_ = run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_; - lob_param.parent_seq_no_ = run_ctx.store_ctx_.mvcc_acc_ctx_.tx_scn_; - if (OB_FAIL(lob_param.snapshot_.assign(run_ctx.dml_param_.snapshot_))) { - LOG_WARN("assign snapshot fail", K(ret)); - } else if (lob_param.snapshot_.is_none_read()) { - // NOTE: - // lob_insert need table_scan, the snapshot already generated in - // run_ctx.store_ctx, use it as an LS ReadSnapshot - lob_param.snapshot_.init_ls_read(run_ctx.store_ctx_.ls_id_, - run_ctx.store_ctx_.mvcc_acc_ctx_.snapshot_); - } - lob_param.tx_id_ = lob_param.tx_desc_->get_tx_id(); - lob_param.sql_mode_ = run_ctx.dml_param_.sql_mode_; - lob_param.ls_id_ = run_ctx.store_ctx_.ls_id_; - lob_param.tablet_id_ = run_ctx.relative_table_.get_tablet_id(); - lob_param.coll_type_ = ObLobCharsetUtil::get_collation_type(column.col_type_.get_type(), column.col_type_.get_collation_type()); - lob_param.allocator_ = &run_ctx.dml_param_.lob_allocator_; - // should use old obj lob - ObLobLocatorV2 old_lob; - ObString old_disk_lob; - if (FAILEDx(set_lob_storage_params(run_ctx, column, lob_param))) { - LOG_WARN("set_lob_storage_params fail", K(ret), K(column)); - } else if (FALSE_IT(old_datum.get_mem_lob(old_lob))) { - } else if (!old_lob.is_valid()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("old lob locator is invalid.", K(ret)); - } else if (OB_FAIL(old_lob.get_disk_locator(old_disk_lob))) { - LOG_WARN("fail to get old lob disk locator.", K(ret)); - } else { - lob_param.lob_locator_ = nullptr; - lob_param.lob_common_ = reinterpret_cast(old_disk_lob.ptr()); - lob_param.handle_size_ = old_disk_lob.length(); - lob_param.byte_size_ = lob_param.lob_common_->get_byte_size(lob_param.handle_size_); - - lob_param.timeout_ = run_ctx.dml_param_.timeout_; - lob_param.scan_backward_ = false; - if (OB_FAIL(lob_mngr->process_delta(lob_param, delta_lob))) { - LOG_WARN("failed to process delta lob.", K(ret), K(lob_param), K(delta_lob)); - } else { - // update obj with new disk locator - datum.set_lob_data(*(lob_param.lob_common_), lob_param.handle_size_); - if (! lob_param.ext_info_log_.is_null() - && OB_FAIL(register_ext_info_commit_cb(run_ctx, datum, column.col_type_.get_type(), lob_param.ext_info_log_))) { - LOG_WARN("register_ext_info_commit_cb fail", K(ret), K(lob_param)); - } - } - } - } - return ret; -} - -int ObLSTabletService::register_ext_info_commit_cb( - ObDMLRunningCtx &run_ctx, - ObStorageDatum &col_data, - ObObjType type, - ObObj &ext_info_data) -{ - int ret = OB_SUCCESS; - memtable::ObMvccWriteGuard guard(false); - if (ext_info_data.is_null()) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ext_info_log is null", K(ret), K(ext_info_data)); - } else if (OB_FAIL(guard.write_auth(run_ctx.store_ctx_))) { - LOG_WARN("write_auth fail", K(ret), K(run_ctx.store_ctx_)); - } else if (OB_FAIL(run_ctx.store_ctx_.mvcc_acc_ctx_.mem_ctx_->register_ext_info_commit_cb( - run_ctx.dml_param_.timeout_, - run_ctx.dml_flag_, - run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_, - run_ctx.store_ctx_.mvcc_acc_ctx_.tx_scn_, - col_data, - type, - ext_info_data))) { - LOG_WARN("register_ext_info_commit_cb fail", K(ret), K(run_ctx.store_ctx_), K(col_data), K(type), K(ext_info_data)); - } - return ret; -} - -int ObLSTabletService::set_lob_storage_params( - ObDMLRunningCtx &run_ctx, - const ObColDesc &column, - ObLobAccessParam &lob_param) -{ - int ret = OB_SUCCESS; - const ObTableDMLParam *table_param = run_ctx.dml_param_.table_param_; - const ObColumnParam *column_param = nullptr; - if (OB_ISNULL(table_param)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("table_param is null", K(ret)); - } else if (OB_ISNULL(column_param = table_param->get_data_table().get_column(column.col_id_))) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("column_param is null", K(ret), K(table_param)); - } else { - lob_param.inrow_threshold_ = table_param->get_data_table().get_lob_inrow_threshold(); - lob_param.schema_chunk_size_ = column_param->get_lob_chunk_size(); - } - return ret; -} - -int ObLSTabletService::process_lob_row( +int ObLSTabletService::process_lob_before_update( ObTabletHandle &tablet_handle, ObDMLRunningCtx &run_ctx, const ObIArray &update_idx, - bool data_tbl_rowkey_change, - ObDatumRow &old_row, - ObDatumRow &new_row) + blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + bool data_tbl_rowkey_change) { int ret = OB_SUCCESS; if (OB_UNLIKELY(old_row.count_ != new_row.count_)) { @@ -5040,7 +5015,8 @@ int ObLSTabletService::process_lob_row( } for (int64_t i = 0; OB_SUCC(ret) && i < old_row.count_; ++i) { - if (run_ctx.col_descs_->at(i).col_type_.is_lob_storage()) { + const ObColDesc &column = run_ctx.col_descs_->at(i); + if (column.col_type_.is_lob_storage()) { ObStorageDatum &old_datum = old_row.storage_datums_[i]; ObStorageDatum &new_datum = new_row.storage_datums_[i]; bool is_update = false; @@ -5062,17 +5038,11 @@ int ObLSTabletService::process_lob_row( new_lob.is_full_temp_lob() || new_lob.is_persist_lob() || (new_lob.is_lob_disk_locator() && new_lob.has_inrow_data())) { - ObLobCommon *lob_common = nullptr; - ObLobAccessParam lob_param; - if (OB_FAIL(new_lob.get_lob_data_byte_len(lob_param.update_len_))) { - LOG_WARN("fail to get new lob byte len", K(ret), K(new_lob), K(i)); - } else if (OB_FAIL(delete_lob_col(run_ctx, run_ctx.col_descs_->at(i), old_datum, lob_common, lob_param))) { - LOG_WARN("[STORAGE_LOB]failed to erase old lob col", K(ret), K(old_row), K(i)); - } else if (OB_FAIL(insert_lob_col(run_ctx, run_ctx.col_descs_->at(i), new_datum, &lob_param, lob_common))) { - LOG_WARN("[STORAGE_LOB]failed to insert new lob col.", K(ret), K(new_row), K(i)); + if (OB_FAIL(ObLobTabletDmlHelper::process_lob_column_before_update(run_ctx, old_row, new_row, data_tbl_rowkey_change, column, 0/*row_idx*/, i, old_datum, new_datum))) { + LOG_WARN("process_lob_column_before_update fail", K(ret), K(column), K(i), K(new_datum), K(new_lob)); } } else if (new_lob.is_delta_temp_lob()) { - if (OB_FAIL(process_delta_lob(run_ctx, run_ctx.col_descs_->at(i), old_datum, new_lob, new_datum))) { + if (OB_FAIL(ObLobTabletDmlHelper::process_delta_lob(run_ctx, old_row, column, old_datum, new_lob, new_datum))) { LOG_WARN("failed to process delta lob.", K(ret), K(i)); } } else { @@ -5090,14 +5060,12 @@ int ObLSTabletService::process_lob_row( ObString val_str = old_datum.get_string(); ObLobCommon *lob_common = reinterpret_cast(val_str.ptr()); if (!lob_common->in_row_ && data_tbl_rowkey_change) { - ObLobAccessParam lob_param; if (val_str.length() < ObLobManager::LOB_WITH_OUTROW_CTX_SIZE) { ret = OB_ERR_UNEXPECTED; LOG_WARN("not enough space for lob header", K(ret), K(val_str), K(i)); - } else if (OB_FAIL(delete_lob_col(run_ctx, run_ctx.col_descs_->at(i), old_datum, lob_common, lob_param))) { - LOG_WARN("[STORAGE_LOB]failed to erase old lob col", K(ret), K(old_row), K(i)); - } else if (OB_FAIL(insert_lob_col(run_ctx, run_ctx.col_descs_->at(i), new_datum, nullptr, nullptr))) { // no need del_param - LOG_WARN("[STORAGE_LOB]failed to insert new lob col.", K(ret), K(new_row), K(i)); + } else if (OB_FAIL(ObLobTabletDmlHelper::process_lob_column_before_update( + run_ctx, old_row, new_row, data_tbl_rowkey_change, column, 0/*row_idx*/, i, old_datum, new_datum))) { + LOG_WARN("process_lob_column_before_update fail", K(ret), K(column), K(i), K(new_datum)); } } else { new_datum.reuse(); @@ -5155,13 +5123,6 @@ int ObLSTabletService::update_row_to_tablet( } } else if (OB_FAIL(insert_vector_index_rows(tablet_handle, run_ctx, &new_datum_row, 1))) { LOG_WARN("failed to process vector index insert", K(ret), K(new_datum_row)); - } else if (OB_FAIL(process_lob_row(tablet_handle, - run_ctx, - update_idx, - data_tbl_rowkey_change, - old_datum_row, - new_datum_row))) { - LOG_WARN("failed to process lob col change", K(ret), K(old_datum_row), K(new_datum_row)); } else if (delay_new && lib::is_oracle_mode()) { // if total quantity log is needed, we should cache both new row and old row, // and the sequence is new_row1, old_row1, new_row2, old_row2...., @@ -5176,6 +5137,13 @@ int ObLSTabletService::update_row_to_tablet( } else { LOG_DEBUG("add row store for delay new", K(old_datum_row), K(new_datum_row)); } + } else if (OB_FAIL(process_lob_before_update(tablet_handle, + run_ctx, + update_idx, + old_datum_row, + new_datum_row, + data_tbl_rowkey_change))) { + LOG_WARN("process_lob_before_update fail", K(ret), K(old_datum_row), K(new_datum_row)); } else if (OB_FAIL(process_new_row(tablet_handle, run_ctx, update_idx, @@ -5185,6 +5153,13 @@ int ObLSTabletService::update_row_to_tablet( if (OB_TRY_LOCK_ROW_CONFLICT != ret && OB_TRANSACTION_SET_VIOLATION != ret) { LOG_WARN("fail to process new row", K(new_datum_row), K(ret)); } + } else if (OB_FAIL(process_lob_after_update(tablet_handle, + run_ctx, + update_idx, + old_datum_row, + new_datum_row, + data_tbl_rowkey_change))) { + LOG_WARN("process_lob_after_update fail", K(ret), K(old_datum_row), K(new_datum_row)); } return ret; @@ -5210,7 +5185,7 @@ int ObLSTabletService::process_old_row( || !datum_row.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(store_ctx), KP(run_ctx.col_descs_), K(datum_row), K(is_delete_total_quantity_log)); - } else if (OB_FAIL(check_old_row_legitimacy(run_ctx.cmp_funcs_, tablet_handle, run_ctx, datum_row))) { + } else if (OB_FAIL(check_old_row_legitimacy_wrap(run_ctx.cmp_funcs_, tablet_handle, run_ctx, datum_row))) { if (OB_ERR_DEFENSIVE_CHECK == ret) { dump_diag_info_for_old_row_loss(run_ctx, datum_row); } @@ -5227,7 +5202,7 @@ int ObLSTabletService::process_old_row( bool locked = false; if (OB_FAIL(rowkey_helper.prepare_datum_rowkey(datum_row, rowkey_size, col_descs, datum_rowkey))) { LOG_WARN("Failed to prepare rowkey", K(ret), K(datum_row), K(rowkey_size), K(datum_rowkey)); - } else if (OB_FAIL(check_row_locked_by_myself(tablet_handle, relative_table, store_ctx, datum_rowkey, locked))) { + } else if (OB_FAIL(check_row_locked_by_myself_wrap(tablet_handle, run_ctx.dml_param_.data_row_for_lob_, relative_table, store_ctx, datum_rowkey, locked))) { LOG_WARN("fail to check row locked", K(ret), K(datum_row), K(datum_rowkey)); } else if (!locked) { ret = OB_ERR_ROW_NOT_LOCKED; @@ -5246,13 +5221,15 @@ int ObLSTabletService::process_old_row( } else if (OB_FAIL(new_row.shallow_copy(datum_row))) { LOG_WARN("failed to shallow copy datum row", K(ret), K(datum_row), K(new_row)); } else if (FALSE_IT(new_row.row_flag_.set_flag(ObDmlFlag::DF_DELETE))) { - } else if (OB_FAIL(tablet_handle.get_obj()->update_row(relative_table, - run_ctx.store_ctx_, - col_descs, - update_idx, - del_row, - new_row, - run_ctx.dml_param_.encrypt_meta_))) { + } else if (OB_FAIL(update_row_wrap(tablet_handle, + run_ctx.dml_param_.data_row_for_lob_, + relative_table, + run_ctx.store_ctx_, + col_descs, + update_idx, + del_row, + new_row, + run_ctx.dml_param_.encrypt_meta_))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret && OB_TRANSACTION_SET_VIOLATION != ret) { LOG_WARN("failed to write data tablet row", K(ret), K(del_row), K(new_row)); } @@ -5261,7 +5238,7 @@ int ObLSTabletService::process_old_row( // need to lock main table rows that don't need to be deleted if (OB_FAIL(rowkey_helper.prepare_datum_rowkey(datum_row, rowkey_size, col_descs, datum_rowkey))) { LOG_WARN("Failed to prepare rowkey", K(ret), K(datum_row), K(rowkey_size)); - } else if (OB_FAIL(tablet_handle.get_obj()->lock_row(relative_table, store_ctx, datum_rowkey))) { + } else if (OB_FAIL(lock_row_wrap(tablet_handle, run_ctx.dml_param_.data_row_for_lob_, relative_table, store_ctx, datum_rowkey))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret && OB_TRANSACTION_SET_VIOLATION != ret) { LOG_WARN("lock row failed", K(ret), K(table_id), K(datum_row), K(rowkey_size), K(datum_rowkey)); } @@ -5345,7 +5322,7 @@ int ObLSTabletService::process_data_table_row( (old_row.storage_datums_[i]).set_nop(); } } - if (OB_FAIL(data_tablet.get_obj()->update_row(relative_table, + if (OB_FAIL(update_row_wrap(data_tablet, run_ctx.dml_param_.data_row_for_lob_, relative_table, ctx, col_descs, update_idx, old_row, new_datum_row, run_ctx.dml_param_.encrypt_meta_))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret && OB_TRANSACTION_SET_VIOLATION != ret) { LOG_WARN("failed to update to row", K(ret), K(old_row), K(new_datum_row)); @@ -5354,12 +5331,14 @@ int ObLSTabletService::process_data_table_row( } } else { const bool check_exist = !relative_table.is_storage_index_table() || relative_table.is_unique_index(); - if (OB_FAIL(data_tablet.get_obj()->insert_row_without_rowkey_check(relative_table, - ctx, - check_exist, - col_descs, - new_datum_row, - run_ctx.dml_param_.encrypt_meta_))) { + if (OB_FAIL(insert_row_without_rowkey_check_wrap(data_tablet, + run_ctx.dml_param_.data_row_for_lob_, + relative_table, + ctx, + check_exist, + col_descs, + new_datum_row, + run_ctx.dml_param_.encrypt_meta_))) { if (OB_ERR_PRIMARY_KEY_DUPLICATE == ret) { char buffer[OB_TMP_BUF_SIZE_256]; ObDatumRowkey rowkey; @@ -5554,9 +5533,12 @@ int ObLSTabletService::check_row_locked_by_myself( int ObLSTabletService::get_conflict_rows( ObTabletHandle &tablet_handle, - ObDMLRunningCtx &run_ctx, + ObRelativeTable &data_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, const ObInsertFlag flag, const common::ObIArray &out_col_ids, + const ObColDescIArray &col_descs, blocksstable::ObDatumRow &row, blocksstable::ObDatumRowIterator *&duplicated_rows) { @@ -5570,7 +5552,7 @@ int ObLSTabletService::get_conflict_rows( if (OB_ISNULL(data_tablet)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet is null", K(ret), K(tablet_handle)); - } else if (OB_FAIL(get_storage_row(row, out_col_ids, storage_row_getter, run_ctx, out_row))) { + } else if (OB_FAIL(get_storage_row(row, out_col_ids, col_descs, storage_row_getter, data_table, store_ctx, dml_param, out_row))) { if (OB_ITER_END != ret) { LOG_WARN("get next row from single row getter failed", K(ret)); } else { @@ -5592,7 +5574,8 @@ int ObLSTabletService::get_conflict_rows( int ObLSTabletService::init_single_row_getter( ObSingleRowGetter &row_getter, - ObDMLRunningCtx &run_ctx, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, const ObIArray &out_col_ids, ObRelativeTable &relative_table, bool skip_read_lob) @@ -5601,9 +5584,9 @@ int ObLSTabletService::init_single_row_getter( if (OB_FAIL(row_getter.init_dml_access_param(relative_table, out_col_ids, skip_read_lob))) { LOG_WARN("init dml access param failed", K(ret)); - } else if (OB_FAIL(row_getter.prepare_cached_iter_node(run_ctx.dml_param_))) { + } else if (OB_FAIL(row_getter.prepare_cached_iter_node(dml_param))) { LOG_WARN("prepare cached iter node failed", K(ret)); - } else if (OB_FAIL(row_getter.init_dml_access_ctx(run_ctx.store_ctx_, skip_read_lob))) { + } else if (OB_FAIL(row_getter.init_dml_access_ctx(store_ctx, skip_read_lob))) { LOG_WARN("init dml access ctx failed", K(ret)); } @@ -5700,11 +5683,13 @@ int ObLSTabletService::insert_row_to_tablet( LOG_WARN("check new row legitimacy failed", K(ret), K(datum_row)); } else if (OB_FAIL(insert_vector_index_rows(tablet_handle, run_ctx, &datum_row, 1))) { LOG_WARN("failed to process vector index rows", K(ret)); - } else if (OB_FAIL(insert_lob_tablet_row(tablet_handle, run_ctx, datum_row))) { - LOG_WARN("failed to write lob tablets rows", K(ret)); + } else if (OB_FAIL(process_lob_before_insert(tablet_handle, run_ctx, &datum_row, 1/*row_count*/))) { + LOG_WARN("process_lob_before_insert fail", K(ret), K(datum_row)); } else { const ObColDescIArray &col_descs = *run_ctx.col_descs_; - if (OB_FAIL(tablet_handle.get_obj()->insert_row_without_rowkey_check( + if (OB_FAIL(insert_row_without_rowkey_check_wrap( + tablet_handle, + run_ctx.dml_param_.data_row_for_lob_, relative_table, store_ctx, check_exist /*check_exist*/, @@ -5716,6 +5701,8 @@ int ObLSTabletService::insert_row_to_tablet( "table id", relative_table.get_table_id(), K(col_descs), K(datum_row)); } + } else if (OB_FAIL(process_lob_after_insert(tablet_handle, run_ctx, &datum_row, 1/*row_count*/))) { + LOG_WARN("process_lob_after_insert fail", K(ret), K(datum_row)); } } @@ -5781,7 +5768,7 @@ int ObLSTabletService::process_old_row_lob_col( } } } else { - if (OB_FAIL(table_refresh_row(data_tablet_handle, run_ctx, datum_row))) { + if (OB_FAIL(table_refresh_row_wrap(data_tablet_handle, run_ctx, datum_row))) { LOG_WARN("[STORAGE_LOB]re-read lob col failed", K(ret)); } } @@ -5791,25 +5778,29 @@ int ObLSTabletService::process_old_row_lob_col( int ObLSTabletService::table_refresh_row( ObTabletHandle &data_tablet_handle, - ObDMLRunningCtx &run_ctx, - blocksstable::ObDatumRow &datum_row) + ObRelativeTable &data_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, + const ObColDescIArray &col_descs, + ObIAllocator &lob_allocator, + blocksstable::ObDatumRow &datum_row, + bool &is_old_row_valid_for_lob) { int ret = OB_SUCCESS; ObArenaAllocator scan_allocator(common::ObMemAttr(MTL_ID(), ObModIds::OB_LOB_ACCESS_BUFFER)); ObSingleRowGetter storage_row_getter(scan_allocator, *data_tablet_handle.get_obj()); - ObRelativeTable &data_table = run_ctx.relative_table_; - int64_t col_cnt = run_ctx.col_descs_->count(); + int64_t col_cnt = col_descs.count(); ObSEArray out_col_ids; for (int i = 0; OB_SUCC(ret) && i < col_cnt; ++i) { - if (OB_FAIL(out_col_ids.push_back(run_ctx.col_descs_->at(i).col_id_))) { + if (OB_FAIL(out_col_ids.push_back(col_descs.at(i).col_id_))) { LOG_WARN("push col id failed.", K(ret), K(i)); } } if (OB_FAIL(ret)) { } else { ObDatumRow *new_row = nullptr; - if (OB_FAIL(get_storage_row(datum_row, out_col_ids, storage_row_getter, run_ctx, new_row))) { + if (OB_FAIL(get_storage_row(datum_row, out_col_ids, col_descs, storage_row_getter, data_table, store_ctx, dml_param, new_row))) { if (ret == OB_ITER_END) { LOG_DEBUG("re-read old row not exist", K(ret), K(datum_row)); ret = OB_SUCCESS; @@ -5826,12 +5817,12 @@ int ObLSTabletService::table_refresh_row( LOG_DEBUG("get new row success.", K(datum_row), KPC(new_row)); // only write cells, not write row for (int64_t i = 0; OB_SUCC(ret) && i < new_row->count_; ++i) { - if (OB_FAIL(datum_row.storage_datums_[i].deep_copy(new_row->storage_datums_[i], run_ctx.dml_param_.lob_allocator_))) { + if (OB_FAIL(datum_row.storage_datums_[i].deep_copy(new_row->storage_datums_[i], lob_allocator))) { LOG_WARN("copy storage datum error", K(ret), K(i), K(new_row->storage_datums_[i])); } } if (OB_SUCC(ret)) { - run_ctx.is_old_row_valid_for_lob_ = true; + is_old_row_valid_for_lob = true; } } } @@ -5850,14 +5841,14 @@ int ObLSTabletService::delete_row_in_tablet( ObSEArray update_idx; // update_idx is a dummy param here datum_row.row_flag_.set_flag(ObDmlFlag::DF_DELETE); - if (OB_FAIL(check_old_row_legitimacy(run_ctx.cmp_funcs_, tablet_handle, run_ctx, datum_row))) { + if (OB_FAIL(check_old_row_legitimacy_wrap(run_ctx.cmp_funcs_, tablet_handle, run_ctx, datum_row))) { if (OB_ERR_DEFENSIVE_CHECK == ret) { dump_diag_info_for_old_row_loss(run_ctx, datum_row); } LOG_WARN("check old row legitimacy failed", K(ret), K(datum_row)); } else if (OB_FAIL(process_old_row_lob_col(tablet_handle, run_ctx, datum_row))) { LOG_WARN("failed to process old row lob col", K(ret), K(datum_row)); - } else if (OB_FAIL(delete_lob_tablet_rows(run_ctx, tablet_handle, datum_row))) { + } else if (OB_FAIL(delete_lob_tablet_rows(tablet_handle, run_ctx, datum_row))) { LOG_WARN("failed to delete lob rows.", K(ret), K(datum_row)); } else { update_idx.reset(); // update_idx is a dummy param here @@ -5866,7 +5857,7 @@ int ObLSTabletService::delete_row_in_tablet( if (OB_FAIL(new_datum_row.shallow_copy(datum_row))) { LOG_WARN("failed to shallow copy datum row", K(ret), K(datum_row), K(new_datum_row)); } else if (FALSE_IT(new_datum_row.row_flag_.set_flag(ObDmlFlag::DF_DELETE))) { - } else if (OB_FAIL(tablet_handle.get_obj()->update_row(relative_table, ctx, + } else if (OB_FAIL(update_row_wrap(tablet_handle, run_ctx.dml_param_.data_row_for_lob_, relative_table, ctx, *run_ctx.col_descs_, update_idx, datum_row, new_datum_row, dml_param.encrypt_meta_))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret && OB_TRANSACTION_SET_VIOLATION != ret) { LOG_WARN("failed to set row", K(ret), K(*run_ctx.col_descs_), K(datum_row), K(new_datum_row)); @@ -5879,74 +5870,9 @@ int ObLSTabletService::delete_row_in_tablet( return ret; } -int ObLSTabletService::delete_lob_col( - ObDMLRunningCtx &run_ctx, - const ObColDesc &column, - blocksstable::ObStorageDatum &datum, - ObLobCommon *&lob_common, - ObLobAccessParam &lob_param) -{ - int ret = OB_SUCCESS; - ObLobManager *lob_mngr = MTL(ObLobManager*); - if (OB_ISNULL(lob_mngr)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[STORAGE_LOB]get lob manager instance failed.", K(ret)); - } else if (!column.col_type_.is_lob_storage() || datum.is_nop_value() || datum.is_null() || - !run_ctx.is_old_row_valid_for_lob_) { - // do nothing - } else { - ObString data = datum.get_string(); - ObLobLocatorV2 locator(data, datum.has_lob_header()); - if (data.length() < sizeof(ObLobCommon)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("[STORAGE_LOB]Invalid Lob data.", K(ret), K(datum), K(data)); - } else if (locator.is_inrow()) { - // deelete inrow lob no need to use the lob manager - } else if (OB_FAIL(set_lob_storage_params(run_ctx, column, lob_param))) { - LOG_WARN("set_lob_storage_params fail", K(ret), K(column)); - } else { - void *buf = run_ctx.dml_param_.lob_allocator_.alloc(data.length()); - if (OB_ISNULL(buf)) { - ret = OB_ALLOCATE_MEMORY_FAILED; - LOG_WARN("failed to deep copy lob data.", K(ret), K(data)); - } else { - MEMCPY(buf, data.ptr(), data.length()); - lob_common = reinterpret_cast(buf); - lob_param.tx_desc_ = run_ctx.store_ctx_.mvcc_acc_ctx_.tx_desc_; - lob_param.parent_seq_no_ = run_ctx.store_ctx_.mvcc_acc_ctx_.tx_scn_; - lob_param.tx_id_ = lob_param.tx_desc_->get_tx_id(); - lob_param.sql_mode_ = run_ctx.dml_param_.sql_mode_; - lob_param.is_total_quantity_log_ = run_ctx.dml_param_.is_total_quantity_log_; - lob_param.ls_id_ = run_ctx.store_ctx_.ls_id_; - lob_param.tablet_id_ = run_ctx.relative_table_.get_tablet_id(); - lob_param.coll_type_ = ObLobCharsetUtil::get_collation_type(column.col_type_.get_type(), column.col_type_.get_collation_type()); - lob_param.allocator_ = &run_ctx.dml_param_.lob_allocator_; - lob_param.lob_common_ = lob_common; - lob_param.handle_size_ = data.length(); - lob_param.byte_size_ = lob_param.lob_common_->get_byte_size(data.length()); - lob_param.timeout_ = run_ctx.dml_param_.timeout_; - lob_param.scan_backward_ = false; - lob_param.offset_ = 0; - // use byte size to delete all - lob_param.len_ = lob_param.byte_size_; //ObCharset::strlen_char(lob_param.coll_type_, sql_data.ptr(), sql_data.length()); - - if (OB_FAIL(lob_param.snapshot_.assign(run_ctx.dml_param_.snapshot_))) { - LOG_WARN("assign snapshot fail", K(ret)); - } else if (lob_param.byte_size_ < 0) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("calc byte size is negative.", K(ret), K(data), K(lob_param)); - } else if (OB_FAIL(lob_mngr->erase(lob_param))) { - LOG_WARN("[STORAGE_LOB]lob erase failed.", K(ret), K(lob_param)); - } - } - } - } - return ret; -} - int ObLSTabletService::delete_lob_tablet_rows( - ObDMLRunningCtx &run_ctx, ObTabletHandle &data_tablet, + ObDMLRunningCtx &run_ctx, blocksstable::ObDatumRow &datum_row) { int ret = OB_SUCCESS; @@ -5963,7 +5889,7 @@ int ObLSTabletService::delete_lob_tablet_rows( if (column.col_type_.is_lob_storage()) { blocksstable::ObStorageDatum &datum = datum_row.storage_datums_[i]; ObLobAccessParam lob_param; - if (OB_FAIL(delete_lob_col(run_ctx, column, datum, lob_common, lob_param))) { + if (OB_FAIL(ObLobTabletDmlHelper::delete_lob_col(run_ctx, datum_row, column, datum, lob_common, lob_param))) { LOG_WARN("[STORAGE_LOB]failed to erase lob col.", K(ret), K(i), K(datum_row)); } } @@ -6255,16 +6181,28 @@ int ObLSTabletService::get_multi_ranges_cost( if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(get_read_tables(tablet_id, timeout_us, max_snapshot_version, max_snapshot_version, iter))) { + } else if (OB_FAIL(get_read_tables(tablet_id, timeout_us, max_snapshot_version, max_snapshot_version, iter, false/*allow_no_ready_read*/, true/*need_split_src_table*/, true/*need_split_dst_table*/))) { LOG_WARN("fail to get all read tables", K(ret), K(tablet_id), K(max_snapshot_version)); } else { - ObPartitionMultiRangeSpliter spliter; - if (OB_FAIL(spliter.get_multi_range_size( - ranges, - iter.get_tablet()->get_rowkey_read_info(), - *iter.table_iter(), - total_size))) { - LOG_WARN("fail to get multi ranges cost", K(ret), K(ranges)); + ObPartitionSplitQuery split_query; + ObSEArray new_ranges; + ObArenaAllocator allocator; + const ObTabletHandle &tablet_handle = iter.get_tablet_handle(); + bool is_splited_range = false; + if (OB_FAIL(split_query.split_multi_ranges_if_need(ranges, new_ranges, + allocator, + tablet_handle, + is_splited_range))) { + LOG_WARN("fail to split ranges", K(ret), K(ranges)); + } else { + ObPartitionMultiRangeSpliter spliter; + if (OB_FAIL(spliter.get_multi_range_size( + is_splited_range ? new_ranges : ranges, + iter.get_tablet()->get_rowkey_read_info(), + *iter.table_iter(), + total_size))) { + LOG_WARN("fail to get multi ranges cost", K(ret), K(ranges)); + } } } return ret; @@ -6281,25 +6219,34 @@ int ObLSTabletService::split_multi_ranges( int ret = OB_SUCCESS; ObTabletTableIterator iter; const int64_t max_snapshot_version = INT64_MAX; - if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret)); - } else if (OB_FAIL(get_read_tables(tablet_id, timeout_us, max_snapshot_version, max_snapshot_version, iter))) { + } else if (OB_FAIL(get_read_tables(tablet_id, timeout_us, max_snapshot_version, max_snapshot_version, iter, false/*allow_no_ready_read*/, true/*need_split_src_table*/, true/*need_split_dst_table*/))) { LOG_WARN("fail to get all read tables", K(ret), K(tablet_id), K(max_snapshot_version)); } else { - ObPartitionMultiRangeSpliter spliter; - if (OB_FAIL(spliter.get_split_multi_ranges( - ranges, - expected_task_count, - iter.get_tablet()->get_rowkey_read_info(), - *iter.table_iter(), + ObPartitionSplitQuery split_query; + ObSEArray new_ranges; + const ObTabletHandle &tablet_handle = iter.get_tablet_handle(); + bool is_splited_range = false; + if (OB_FAIL(split_query.split_multi_ranges_if_need(ranges, new_ranges, allocator, - multi_range_split_array))) { - LOG_WARN("fail to get splitted ranges", K(ret), K(ranges), K(expected_task_count)); + tablet_handle, + is_splited_range))) { + LOG_WARN("fail to split ranges", K(ret), K(ranges)); + } else { + ObPartitionMultiRangeSpliter spliter; + if (OB_FAIL(spliter.get_split_multi_ranges( + is_splited_range ? new_ranges : ranges, + expected_task_count, + iter.get_tablet()->get_rowkey_read_info(), + *iter.table_iter(), + allocator, + multi_range_split_array))) { + LOG_WARN("fail to get splitted ranges", K(ret), K(ranges), K(expected_task_count)); + } } } - return ret; } @@ -6326,7 +6273,7 @@ int ObLSTabletService::estimate_row_count( } else { const int64_t snapshot_version = -1 == param.frozen_version_ ? GET_BATCH_ROWS_READ_SNAPSHOT_VERSION : param.frozen_version_; - if (OB_FAIL(get_read_tables(param.tablet_id_, timeout_us, snapshot_version, snapshot_version, tablet_iter, false))) { + if (OB_FAIL(get_read_tables(param.tablet_id_, timeout_us, snapshot_version, snapshot_version, tablet_iter, false/*allow_no_ready_read*/, true/*need_split_src_table*/, true/*need_split_dst_table*/))) { if (OB_TABLET_NOT_EXIST != ret) { LOG_WARN("failed to get tablet_iter", K(ret), K(snapshot_version), K(param)); } @@ -6371,9 +6318,8 @@ int ObLSTabletService::estimate_row_count( return ret; } -int ObLSTabletService::estimate_block_count_and_row_count( - const common::ObTabletID &tablet_id, - const int64_t timeout_us, +int ObLSTabletService::inner_estimate_block_count_and_row_count( + ObTabletTableIterator &tablet_iter, int64_t ¯o_block_count, int64_t µ_block_count, int64_t &sstable_row_count, @@ -6382,21 +6328,12 @@ int ObLSTabletService::estimate_block_count_and_row_count( common::ObIArray &cg_micro_cnt_arr) { int ret = OB_SUCCESS; + ObITable *table = nullptr; + ObSSTable *sstable = nullptr; macro_block_count = 0; micro_block_count = 0; sstable_row_count = 0; memtable_row_count = 0; - ObTabletTableIterator tablet_iter; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("not inited", K(ret), K_(is_inited)); - } else if (OB_FAIL(get_read_tables(tablet_id, timeout_us, INT64_MAX, INT64_MAX, tablet_iter, false/*allow_no_ready_read*/))) { - LOG_WARN("failed to get read tables", K(ret)); - } - - ObITable *table = nullptr; - ObSSTable *sstable = nullptr; cg_macro_cnt_arr.reset(); cg_micro_cnt_arr.reset(); @@ -6466,6 +6403,228 @@ int ObLSTabletService::estimate_block_count_and_row_count( return ret; } +int ObLSTabletService::estimate_block_count_and_row_count_for_split_extra( + const ObTabletID &tablet_id, + const int64_t split_cnt, + const ObMDSGetTabletMode mode, + const int64_t timeout_us, + int64_t ¯o_block_count, + int64_t µ_block_count, + int64_t &sstable_row_count, + int64_t &memtable_row_count, + common::ObIArray &cg_macro_cnt_arr, + common::ObIArray &cg_micro_cnt_arr) +{ + int ret = OB_SUCCESS; + /* To calculate tables block count for sample in tablet spliting, we should multiple a split ratio + * for src tablet tables block count, because the src tablet is only part of new tablet. So here + * we should calculate block count of src and new tablet respectively */ + ObTabletTableIterator tablet_iter; + int64_t tmp_tablet_macro_block_cnt = 0; + int64_t tmp_tablet_micro_block_cnt = 0; + int64_t tmp_tablet_sstable_row_cnt = 0; + int64_t tmp_tablet_memtable_row_cnt = 0; + ObArray tmp_tablet_cg_macro_cnt_arr; + ObArray tmp_tablet_cg_micro_cnt_arr; + if (OB_FAIL(inner_get_read_tables( + tablet_id, + timeout_us, + INT64_MAX, + INT64_MAX, + tablet_iter, + true/*allow_no_ready_read*/, + false/*need_split_src_table*/, + false/*need_split_dst_table*/, + mode))) { + LOG_WARN("fail to get read tables", K(ret), K(tablet_id)); + } else if (OB_FAIL(inner_estimate_block_count_and_row_count( // origin tablet + tablet_iter, + tmp_tablet_macro_block_cnt, + tmp_tablet_micro_block_cnt, + tmp_tablet_sstable_row_cnt, + tmp_tablet_memtable_row_cnt, + tmp_tablet_cg_macro_cnt_arr, + tmp_tablet_cg_micro_cnt_arr))) { + LOG_WARN("fail to inner estimate block count", K(ret)); + } else { + /* estimate block count is using total range of tablet, so here no need to cut range. + Specifilly, if local index table, we should estimate whole range of origin tablet. + but for main table, we should multiple split_ratio to estimate origin block cnt */ + tmp_tablet_macro_block_cnt = tmp_tablet_macro_block_cnt / split_cnt; + tmp_tablet_micro_block_cnt = tmp_tablet_micro_block_cnt / split_cnt; + tmp_tablet_sstable_row_cnt = tmp_tablet_sstable_row_cnt / split_cnt; + tmp_tablet_memtable_row_cnt = tmp_tablet_memtable_row_cnt / split_cnt; + for (int64_t i = 0; i < tmp_tablet_cg_macro_cnt_arr.count(); i++) { + tmp_tablet_cg_macro_cnt_arr.at(i) = tmp_tablet_cg_macro_cnt_arr.at(i) / split_cnt; + } + for (int64_t i = 0; i < tmp_tablet_cg_micro_cnt_arr.count(); i++) { + tmp_tablet_cg_micro_cnt_arr.at(i) = tmp_tablet_cg_micro_cnt_arr.at(i) / split_cnt; + } + macro_block_count += tmp_tablet_macro_block_cnt; + micro_block_count += tmp_tablet_micro_block_cnt; + sstable_row_count += tmp_tablet_sstable_row_cnt; + memtable_row_count += tmp_tablet_memtable_row_cnt; + if (OB_SUCC(ret)) { + ObIArray &arr = cg_macro_cnt_arr; + ObIArray &inc_arr = tmp_tablet_cg_macro_cnt_arr; + if (!inc_arr.empty()) { + if (arr.empty()) { + if (OB_FAIL(append(arr, inc_arr))) { + LOG_WARN("failed to append", K(ret)); + } + } else { + int64_t cnt = std::min(arr.count(), inc_arr.count()); + for (int64_t i = 0; i < cnt; i++) { + arr.at(i) += inc_arr.at(i); + } + } + } + } + if (OB_SUCC(ret)) { + ObIArray &arr = cg_micro_cnt_arr; + ObIArray &inc_arr = tmp_tablet_cg_micro_cnt_arr; + if (!inc_arr.empty()) { + if (arr.empty()) { + if (OB_FAIL(append(arr, inc_arr))) { + LOG_WARN("failed to append", K(ret)); + } + } else { + int64_t cnt = std::min(arr.count(), inc_arr.count()); + for (int64_t i = 0; i < cnt; i++) { + arr.at(i) += inc_arr.at(i); + } + } + } + } + } + return ret; +} + +int ObLSTabletService::estimate_block_count_and_row_count( + const common::ObTabletID &tablet_id, + const int64_t timeout_us, + int64_t ¯o_block_count, + int64_t µ_block_count, + int64_t &sstable_row_count, + int64_t &memtable_row_count, + common::ObIArray &cg_macro_cnt_arr, + common::ObIArray &cg_micro_cnt_arr) +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTabletTableIterator tablet_iter; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("not inited", K(ret), K_(is_inited)); + } else if (OB_FAIL(inner_get_read_tables( + tablet_id, + timeout_us, + INT64_MAX, + INT64_MAX, + tablet_iter, + false/*allow_no_ready_read*/, + false/*need_split_src_table*/, + false/*need_split_dst_table*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED))) { + LOG_WARN("failed to get read tables", K(ret)); + } else if (OB_FAIL(inner_estimate_block_count_and_row_count( + tablet_iter, + macro_block_count, + micro_block_count, + sstable_row_count, + memtable_row_count, + cg_macro_cnt_arr, + cg_micro_cnt_arr))) { + LOG_WARN("fail to inner estimate block count", K(ret)); + } + + if (OB_TABLET_IS_SPLIT_SRC == ret) { + tablet_iter.reset(); + if (OB_FAIL(inner_get_read_tables( + tablet_id, + timeout_us, + INT64_MAX, + INT64_MAX, + tablet_iter, + false/*allow_no_ready_read*/, + false/*need_split_src_table*/, + true/*need_split_dst_table*/, + ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("failed to get read tables for split src", K(ret)); + } else if (OB_FAIL(inner_estimate_block_count_and_row_count( + tablet_iter, + macro_block_count, + micro_block_count, + sstable_row_count, + memtable_row_count, + cg_macro_cnt_arr, + cg_micro_cnt_arr))) { + LOG_WARN("fail to inner estimate block count", K(ret)); + } + } else if (OB_REPLICA_NOT_READABLE == ret) { + const int orig_ret = ret; + ObTabletID src_tablet_id; + ObTabletSplitMdsUserData split_data; + ObTabletSplitMdsUserData src_split_data; + ObTabletHandle tablet_handle; + ObTabletHandle src_tablet_handle; + int64_t split_cnt = 0; + tablet_iter.reset(); + if (OB_FAIL(ls_->get_tablet(tablet_id, tablet_handle, timeout_us, ObMDSGetTabletMode::READ_READABLE_COMMITED))) { + LOG_WARN("failed to get tablet", K(ret), K(src_tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(split_data, timeout_us))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_UNLIKELY(!split_data.is_split_dst())) { + ret = orig_ret; + LOG_WARN("maybe not split dst or split task finish", K(ret)); + } else if (OB_FAIL(inner_get_read_tables( + tablet_id, + timeout_us, + INT64_MAX, + INT64_MAX, + tablet_iter, + true/*allow_no_ready_read*/, + false/*need_split_src_table*/, + false/*need_split_dst_table*/, + ObMDSGetTabletMode::READ_READABLE_COMMITED))) { + LOG_WARN("failed to get read tables", K(ret)); + } else if (OB_FAIL(inner_estimate_block_count_and_row_count( + tablet_iter, + macro_block_count, + micro_block_count, + sstable_row_count, + memtable_row_count, + cg_macro_cnt_arr, + cg_micro_cnt_arr))) { + LOG_WARN("fail to inner estimate block count", K(ret)); + } else if (OB_UNLIKELY(0 == tablet_iter.tablet_handle_.get_obj()->get_major_table_count())) { + if (OB_FAIL(split_data.get_split_src_tablet_id(src_tablet_id))) { + LOG_WARN("failed to get split src tablet id", K(ret)); + } else if (OB_FAIL(ls_->get_tablet(src_tablet_id, src_tablet_handle, timeout_us, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("failed to get tablet", K(ret), K(src_tablet_id)); + } else if (OB_FAIL(src_tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(src_split_data, timeout_us))) { + LOG_WARN("failed to get split data", K(ret), K(src_tablet_id)); + } else if (OB_FAIL(src_split_data.get_split_dst_tablet_cnt(split_cnt))) { + LOG_WARN("failed to get split cnt", K(ret), K(src_tablet_id), K(src_split_data)); + } else if (OB_FAIL(estimate_block_count_and_row_count_for_split_extra( + src_tablet_id, + split_cnt, + ObMDSGetTabletMode::READ_ALL_COMMITED, + timeout_us, + macro_block_count, + micro_block_count, + sstable_row_count, + memtable_row_count, + cg_macro_cnt_arr, + cg_micro_cnt_arr))) { + LOG_WARN("failed to estimate block count and row count for split extra tablets", K(ret)); + } + } + } + return ret; +} + int ObLSTabletService::get_tx_data_memtable_mgr(ObMemtableMgrHandle &mgr_handle) { mgr_handle.reset(); @@ -7221,6 +7380,368 @@ int ObLSTabletService::offline_gc_tablet_for_create_or_transfer_in_abort_() return ret; } +int ObLSTabletService::ObDmlSplitCtx::prepare_write_dst( + const ObTabletID &src_tablet_id, + const ObTabletID &dst_tablet_id, + ObStoreCtx &store_ctx, + const ObRelativeTable &relative_table) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!src_tablet_id.is_valid() || !dst_tablet_id.is_valid()) || OB_ISNULL(store_ctx.ls_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(src_tablet_id), K(dst_tablet_id)); + } else if (OB_FAIL(store_ctx.ls_->get_tablet_svr()->get_tablet_with_timeout( + dst_tablet_id, dst_tablet_handle_, store_ctx.timeout_, ObMDSGetTabletMode::READ_READABLE_COMMITED, share::SCN::max_scn()))) { + LOG_WARN("failed to get tablet", K(ret)); + } else if (OB_FAIL(dst_relative_table_.init(relative_table.get_schema_param(), + dst_tablet_handle_.get_obj()->get_tablet_meta().tablet_id_, + relative_table.allow_not_ready()))) { + LOG_WARN("fail to init dst_relative_table_", K(ret), K(relative_table), K(dst_tablet_handle_.get_obj()->get_tablet_meta())); + } else if (OB_FAIL(dst_relative_table_.tablet_iter_.set_tablet_handle(dst_tablet_handle_))) { + LOG_WARN("fail to set tablet handle to iter", K(ret), K(dst_relative_table_.tablet_iter_)); + } else if (OB_FAIL(dst_relative_table_.tablet_iter_.refresh_read_tables_from_tablet( + store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), + dst_relative_table_.allow_not_ready(), + false/*major_sstable_only*/, + true/*need_split_src_table*/, + false/*need_split_dst_table*/))) { + LOG_WARN("failed to get relative table read tables", K(ret)); + } + LOG_INFO("prepare write dst", K(ret), K(src_tablet_id), K(dst_tablet_id)); + return ret; +} + +int ObLSTabletService::ObDmlSplitCtx::prepare_write_dst( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObStoreCtx &store_ctx, + const ObRelativeTable &relative_table, + const ObDatumRowkey &rowkey) +{ + int ret = OB_SUCCESS; + ObTabletID dst_tablet_id; + const bool is_lob = nullptr != data_row_for_lob; + const int64_t abs_timeout_us = store_ctx.timeout_; + if (OB_ISNULL(store_ctx.ls_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ls", K(ret)); + } else if (is_lob) { + if (OB_FAIL(ObTabletSplitMdsHelper::calc_split_dst_lob(*store_ctx.ls_, *tablet_handle.get_obj(), *data_row_for_lob, abs_timeout_us, dst_tablet_id))) { + LOG_WARN("failed to calc split dst lob", K(ret)); + } + } else { + if (OB_FAIL(ObTabletSplitMdsHelper::calc_split_dst(*store_ctx.ls_, *tablet_handle.get_obj(), rowkey, abs_timeout_us, dst_tablet_id))) { + LOG_WARN("failed to calc split dst tablet", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(prepare_write_dst(tablet_handle.get_obj()->get_tablet_meta().tablet_id_, dst_tablet_id, store_ctx, relative_table))) { + LOG_WARN("failed to prepare write dst", K(ret)); + } + return ret; +} + +int ObLSTabletService::ObDmlSplitCtx::prepare_write_dst( + ObTabletHandle &tablet_handle, + const ObDatumRow *data_row_for_lob, + ObStoreCtx &store_ctx, + const ObRelativeTable &relative_table, + const ObDatumRow &new_row) +{ + int ret = OB_SUCCESS; + const int64_t rowkey_column_cnt = relative_table.get_rowkey_column_num(); + ObDatumRowkey rowkey; + if (OB_FAIL(rowkey.assign(new_row.storage_datums_, rowkey_column_cnt))) { + LOG_WARN("failed to from rowkey", K(ret)); + } else if (OB_FAIL(prepare_write_dst(tablet_handle, data_row_for_lob, store_ctx, relative_table, rowkey))) { + LOG_WARN("failed to prepare write dst", K(ret)); + } + return ret; +} + +void ObLSTabletService::ObDmlSplitCtx::reuse() +{ + dst_tablet_handle_.reset(); + dst_relative_table_.destroy(); + allocator_.reuse(); +} + +int ObLSTabletService::lock_row_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const ObDatumRowkey &rowkey) +{ + int ret = tablet_handle.get_obj()->lock_row(relative_table, store_ctx, rowkey); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObDmlSplitCtx dml_split_ctx; + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, data_row_for_lob, store_ctx, relative_table, rowkey))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(dml_split_ctx.dst_tablet_handle_.get_obj()->lock_row(dml_split_ctx.dst_relative_table_, store_ctx, rowkey))) { + LOG_WARN("failed to lock row", K(ret)); + } + } + return ret; +} + +int ObLSTabletService::lock_row_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + ObColDescArray &col_descs, + blocksstable::ObDatumRow &row) +{ + int ret = tablet_handle.get_obj()->lock_row(relative_table, store_ctx, col_descs, row); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObDmlSplitCtx dml_split_ctx; + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, data_row_for_lob, store_ctx, relative_table, row))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(dml_split_ctx.dst_tablet_handle_.get_obj()->lock_row(dml_split_ctx.dst_relative_table_, store_ctx, col_descs, row))) { + LOG_WARN("failed to lock row", K(ret)); + } + } + return ret; +} + +// split by new_row, because in minimal mode old row's pk are nop +int ObLSTabletService::update_row_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + storage::ObStoreCtx &store_ctx, + const ObIArray &col_descs, + const ObIArray &update_idx, + const blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + const ObIArray *encrypt_meta_arr) +{ + int ret = tablet_handle.get_obj()->update_row(relative_table, store_ctx, col_descs, update_idx, old_row, new_row, encrypt_meta_arr); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObDmlSplitCtx dml_split_ctx; + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, data_row_for_lob, store_ctx, relative_table, new_row))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(dml_split_ctx.dst_tablet_handle_.get_obj()->update_row(dml_split_ctx.dst_relative_table_, store_ctx, col_descs, update_idx, old_row, new_row, encrypt_meta_arr))) { + LOG_WARN("failed to update row", K(ret)); + } + } + return ret; +} + +int ObLSTabletService::batch_calc_split_dst_rows( + ObLS &ls, + ObTabletHandle &tablet_handle, + ObRelativeTable &relative_table, + ObDatumRow *rows, + const int64_t row_count, + const int64_t abs_timeout_us, + ObIArray &dst_tablet_ids, + ObIArray> &dst_rows) +{ + int ret = OB_SUCCESS; + ObTabletSplitMdsUserData src_split_data; + ObSEArray dst_split_datas; + ObTabletHandle dst_tablet_handle; + const ObITableReadInfo &rowkey_read_info = tablet_handle.get_obj()->get_rowkey_read_info(); + dst_rows.reset(); + if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(src_split_data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(src_split_data.get_split_dst_tablet_ids(dst_tablet_ids))) { + LOG_WARN("failed to get split dst tablet ids", K(ret)); + } else if (OB_FAIL(dst_split_datas.prepare_allocate(dst_tablet_ids.count()))) { + LOG_WARN("failed to prepare allocate", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < dst_tablet_ids.count(); i++) { + dst_tablet_handle.reset(); + if (OB_FAIL(ls.get_tablet_with_timeout(dst_tablet_ids.at(i), dst_tablet_handle, abs_timeout_us))) { + LOG_WARN("failed to get split dst tablet", K(ret)); + } else if (OB_FAIL(dst_tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(dst_split_datas.at(i), abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to part key compare", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(dst_rows.prepare_allocate(dst_tablet_ids.count()))) { + LOG_WARN("failed to prepare allocate", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < row_count; i++) { + const int64_t rowkey_column_cnt = relative_table.get_rowkey_column_num(); + ObDatumRowkey rowkey; + ObTabletID dst_tablet_id; + int64_t dst_idx = 0; + if (OB_FAIL(rowkey.assign(rows[i].storage_datums_, rowkey_column_cnt))) { + LOG_WARN("failed to from rowkey", K(ret)); + } else if (OB_FAIL(src_split_data.calc_split_dst(rowkey_read_info, dst_split_datas, rowkey, dst_tablet_id, dst_idx))) { + LOG_WARN("failed to calc split dst tablet", K(ret)); + } else if (OB_UNLIKELY(dst_idx >= dst_rows.count() || dst_idx >= dst_tablet_ids.count() || dst_tablet_ids.at(dst_idx) != dst_tablet_id)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("dst idx out of range", K(ret), K(dst_idx), K(dst_rows.count()), K(dst_tablet_id), K(dst_tablet_ids)); + } else if (OB_FAIL(dst_rows.at(dst_idx).push_back(&rows[i]))) { + LOG_WARN("failed to push back", K(ret)); + } + } + return ret; +} + +int ObLSTabletService::insert_rows_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + ObDatumRow *rows, + ObRowsInfo &rows_info, + const bool check_exist, + const ObColDescIArray &col_descs, + const int64_t row_count, + const common::ObIArray *encrypt_meta_arr) +{ + int ret = tablet_handle.get_obj()->insert_rows(relative_table, store_ctx, rows, rows_info, check_exist, col_descs, row_count, encrypt_meta_arr); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ret = OB_SUCCESS; + ObDmlSplitCtx dml_split_ctx; + if (nullptr != data_row_for_lob) { + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, data_row_for_lob, store_ctx, relative_table, *data_row_for_lob))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(dml_split_ctx.dst_tablet_handle_.get_obj()->insert_rows( + dml_split_ctx.dst_relative_table_, store_ctx, rows, rows_info, check_exist, col_descs, row_count, encrypt_meta_arr))) { + LOG_WARN("failed to update row", K(ret)); + } + } else { + ObSEArray dst_tablet_ids; + ObSEArray, 2> dst_rows; + const ObITableReadInfo &rowkey_read_info = tablet_handle.get_obj()->get_rowkey_read_info(); + if (OB_FAIL(batch_calc_split_dst_rows(*store_ctx.ls_, tablet_handle, relative_table, rows, row_count, store_ctx.timeout_, dst_tablet_ids, dst_rows))) { + LOG_WARN("failed to batch calc split dst rows", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < dst_rows.count(); i++) { + if (!dst_rows[i].empty()) { + SMART_VAR(ObRowsInfo, rows_info) { + ObDatumRow *dst_tbl_rows = nullptr; + const int64_t dst_row_count = dst_rows[i].count(); + dml_split_ctx.reuse(); + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle.get_obj()->get_tablet_meta().tablet_id_, dst_tablet_ids.at(i), store_ctx, relative_table))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(ObDatumRowUtils::ob_create_rows_shallow_copy(dml_split_ctx.allocator_, dst_rows[i], dst_tbl_rows))) { + LOG_WARN("failed to create rows", K(ret)); + } else if (OB_FAIL(rows_info.init(col_descs, dml_split_ctx.dst_relative_table_, store_ctx, rowkey_read_info))) { + LOG_WARN("Failed to init rows info", K(ret), K(dml_split_ctx.dst_relative_table_)); + } else if (OB_FAIL(rows_info.check_duplicate(dst_tbl_rows, dst_row_count, dml_split_ctx.dst_relative_table_))) { + LOG_WARN("failed to check duplicate", K(ret)); + } else if (OB_FAIL(dml_split_ctx.dst_tablet_handle_.get_obj()->insert_rows( + dml_split_ctx.dst_relative_table_, store_ctx, dst_tbl_rows, rows_info, check_exist, col_descs, dst_row_count, encrypt_meta_arr))) { + LOG_WARN("failed to insert tablet rows", K(ret), K(check_exist)); + } + } + } + } + } + } + return ret; +} + +int ObLSTabletService::insert_row_without_rowkey_check_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const bool check_exists, + const ObIArray &col_descs, + ObDatumRow &row, + const ObIArray *encrypt_meta_arr) +{ + int ret = tablet_handle.get_obj()->insert_row_without_rowkey_check(relative_table, store_ctx, check_exists, col_descs, row, encrypt_meta_arr); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObDmlSplitCtx dml_split_ctx; + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, data_row_for_lob, store_ctx, relative_table, row))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(dml_split_ctx.dst_tablet_handle_.get_obj()->insert_row_without_rowkey_check( + dml_split_ctx.dst_relative_table_, store_ctx, check_exists, col_descs, row, encrypt_meta_arr))) { + LOG_WARN("failed to do insert to in dst tablet", K(ret)); + } + } + return ret; +} + +int ObLSTabletService::check_row_locked_by_myself_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const ObDatumRowkey &rowkey, + bool &locked) +{ + int ret = check_row_locked_by_myself(tablet_handle, relative_table, store_ctx, rowkey, locked); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObDmlSplitCtx dml_split_ctx; + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, data_row_for_lob, store_ctx, relative_table, rowkey))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(check_row_locked_by_myself(dml_split_ctx.dst_tablet_handle_, dml_split_ctx.dst_relative_table_, store_ctx, rowkey, locked))) { + LOG_WARN("failed to check row locked", K(ret)); + } + } + return ret; +} + +int ObLSTabletService::get_conflict_rows_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, + const ObInsertFlag flag, + const ObIArray &out_col_ids, + const ObColDescIArray &col_descs, + ObDatumRow &row, + ObDatumRowIterator *&duplicated_rows) +{ + int ret = get_conflict_rows(tablet_handle, relative_table, store_ctx, dml_param, flag, out_col_ids, col_descs, row, duplicated_rows); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObDmlSplitCtx dml_split_ctx; + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, data_row_for_lob, store_ctx, relative_table, row))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(get_conflict_rows(dml_split_ctx.dst_tablet_handle_, dml_split_ctx.dst_relative_table_, store_ctx, dml_param, flag, out_col_ids, col_descs, row, duplicated_rows))) { + LOG_WARN("failed to get conflict rows", K(ret)); + } + } + return ret; +} + +int ObLSTabletService::table_refresh_row_wrap( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &row) +{ + int ret = table_refresh_row(tablet_handle, run_ctx.relative_table_, run_ctx.store_ctx_, run_ctx.dml_param_, *run_ctx.col_descs_, run_ctx.dml_param_.lob_allocator_, row, run_ctx.is_old_row_valid_for_lob_); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObDmlSplitCtx dml_split_ctx; + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, run_ctx.dml_param_.data_row_for_lob_, run_ctx.store_ctx_, run_ctx.relative_table_, row))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(table_refresh_row(dml_split_ctx.dst_tablet_handle_, dml_split_ctx.dst_relative_table_, run_ctx.store_ctx_, run_ctx.dml_param_, *run_ctx.col_descs_, run_ctx.dml_param_.lob_allocator_, row, run_ctx.is_old_row_valid_for_lob_))) { + LOG_WARN("failed to table refresh row", K(ret)); + } + } + return ret; +} + +int ObLSTabletService::check_old_row_legitimacy_wrap( + const ObStoreCmpFuncs &cmp_funcs, + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &old_row) +{ + int ret = check_old_row_legitimacy(cmp_funcs, tablet_handle, run_ctx.relative_table_, run_ctx.store_ctx_, run_ctx.dml_param_, run_ctx.column_ids_, run_ctx.col_descs_, run_ctx.is_need_check_old_row_, run_ctx.is_udf_, run_ctx.dml_flag_, old_row); + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObDmlSplitCtx dml_split_ctx; + if (OB_FAIL(dml_split_ctx.prepare_write_dst(tablet_handle, run_ctx.dml_param_.data_row_for_lob_, run_ctx.store_ctx_, run_ctx.relative_table_, old_row))) { + LOG_WARN("failed to prepare split dml ctx", K(ret)); + } else if (OB_FAIL(check_old_row_legitimacy(cmp_funcs, dml_split_ctx.dst_tablet_handle_, dml_split_ctx.dst_relative_table_, run_ctx.store_ctx_, run_ctx.dml_param_, run_ctx.column_ids_, run_ctx.col_descs_, run_ctx.is_need_check_old_row_, run_ctx.is_udf_, run_ctx.dml_flag_, old_row))) { + LOG_WARN("failed to check old row legitimacy", K(ret)); + } + } + return ret; +} + int ObLSTabletService::check_rollback_tablet_is_same_( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, @@ -7249,5 +7770,56 @@ int ObLSTabletService::check_rollback_tablet_is_same_( return ret; } +int ObLSTabletService::process_lob_after_insert( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow *rows, + int64_t row_count) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < run_ctx.lob_dml_ctx_.task_count(); ++i) { + ObLobDataInsertTask &task = run_ctx.lob_dml_ctx_.task(i); + const ObColDesc &column = run_ctx.col_descs_->at(task.col_idx_); + blocksstable::ObDatumRow &datum_row = rows[task.row_idx_]; + if (task.col_idx_ >= run_ctx.col_descs_->count() || task.row_idx_ >= row_count) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("col idx or row idx is invalid", K(ret), K(task), KPC(run_ctx.col_descs_), K(row_count)); + } else if (OB_FAIL(ObLobTabletDmlHelper::process_lob_column_after_insert(run_ctx, datum_row, column, task))) { + LOG_WARN("process_lob_column_after_insert fail", K(ret), K(column), K(i), K(task), K(datum_row)); + } + } + + if (OB_SUCC(ret)) { + run_ctx.lob_dml_ctx_.reuse(); + } + return ret; +} + +int ObLSTabletService::process_lob_after_update( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + const ObIArray &update_idx, + blocksstable::ObDatumRow &old_datum_row, + blocksstable::ObDatumRow &new_datum_row, + const bool data_tbl_rowkey_change) +{ + int ret = OB_SUCCESS; + for (int64_t i = 0; OB_SUCC(ret) && i < run_ctx.lob_dml_ctx_.task_count(); ++i) { + ObLobDataInsertTask &task = run_ctx.lob_dml_ctx_.task(i); + const ObColDesc &column = run_ctx.col_descs_->at(task.col_idx_); + if (task.col_idx_ >= run_ctx.col_descs_->count() || task.row_idx_ != 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("col idx or row idx is invalid", K(ret), K(task), KPC(run_ctx.col_descs_)); + } else if (OB_FAIL(ObLobTabletDmlHelper::process_lob_column_after_update( + run_ctx, old_datum_row, new_datum_row, data_tbl_rowkey_change, column, task))) { + LOG_WARN("process_lob_column_after_update fail", K(ret), K(column), K(i), K(task)); + } + } + if (OB_SUCC(ret)) { + run_ctx.lob_dml_ctx_.reuse(); + } + return ret; +} + } // namespace storage } // namespace oceanbase diff --git a/src/storage/ls/ob_ls_tablet_service.h b/src/storage/ls/ob_ls_tablet_service.h index e8a9d1db2..14552628c 100644 --- a/src/storage/ls/ob_ls_tablet_service.h +++ b/src/storage/ls/ob_ls_tablet_service.h @@ -21,6 +21,7 @@ #include "logservice/palf/palf_callback.h" #include "share/schema/ob_table_schema.h" #include "storage/ob_dml_common.h" +#include "storage/ob_relative_table.h" #include "storage/slog/ob_storage_log.h" #include "storage/high_availability/ob_tablet_ha_status.h" #include "storage/tablelock/ob_lock_memtable_mgr.h" @@ -58,11 +59,14 @@ namespace blocksstable { class ObMigrationSSTableParam; struct ObDatumRowkey; +enum ObDmlFlag; class ObDatumRowStore; } namespace compaction { +struct ObMulSourceDataNotifyArg; +struct ObEncryptMetaCache; class ObTabletMergeCtx; } namespace sql @@ -166,6 +170,7 @@ public: const ObCreateTabletSchema &create_tablet_schema, const lib::Worker::CompatMode &compat_mode, const bool need_create_empty_major_sstable, + const share::SCN &clog_checkpoint_scn, const bool micro_index_clustered, const bool has_cs_replica, ObTabletHandle &tablet_handle); @@ -302,7 +307,9 @@ public: // filter the unnecessary tables and confirm the OB_SNAPSHOT_DISCARDED const int64_t snapshot_version_for_tables, ObTabletTableIterator &iter, - const bool allow_no_ready_read = false); + const bool allow_no_ready_read, + const bool need_split_src_table, + const bool need_split_dst_table); int check_allow_to_read(); int set_tablet_status( const common::ObTabletID &tablet_id, @@ -406,6 +413,14 @@ public: common::ObIArray &est_records, int64_t &logical_row_count, int64_t &physical_row_count); + int inner_estimate_block_count_and_row_count( + ObTabletTableIterator &tablet_iter, + int64_t ¯o_block_count, + int64_t µ_block_count, + int64_t &sstable_row_count, + int64_t &memtable_row_count, + common::ObIArray &cg_macro_cnt_arr, + common::ObIArray &cg_micro_cnt_arr); int estimate_block_count_and_row_count( const common::ObTabletID &tablet_id, const int64_t timeout_us, @@ -438,7 +453,7 @@ public: int create_or_update_migration_tablet( const ObMigrationTabletParam &mig_tablet_param, const bool is_transfer); - int build_ha_tablet_new_table_store( + int build_tablet_with_batch_tables( const ObTabletID &tablet_id, const ObBatchUpdateTableStoreParam ¶m); void enable_to_read(); @@ -500,6 +515,34 @@ private: const share::SCN ddl_commit_scn_; DISALLOW_COPY_AND_ASSIGN(ObUpdateDDLCommitSCN); }; + class ObDmlSplitCtx final { + public: + ObDmlSplitCtx() : allocator_(), dst_tablet_handle_(), dst_relative_table_() {} + ~ObDmlSplitCtx() = default; + int prepare_write_dst( + const ObTabletID &src_tablet_id, + const ObTabletID &dst_tablet_id, + ObStoreCtx &store_ctx, + const ObRelativeTable &relative_table); + int prepare_write_dst( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObStoreCtx &store_ctx, + const ObRelativeTable &relative_table, + const ObDatumRowkey &rowkey); + int prepare_write_dst( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObStoreCtx &store_ctx, + const ObRelativeTable &relative_table, + const blocksstable::ObDatumRow &new_row); + void reuse(); + public: + ObArenaAllocator allocator_; + ObTabletHandle dst_tablet_handle_; + ObRelativeTable dst_relative_table_; + DISALLOW_COPY_AND_ASSIGN(ObDmlSplitCtx); + }; private: static int refresh_memtable_for_ckpt( const ObMetaDiskAddr &old_addr, @@ -550,6 +593,24 @@ private: const int64_t snapshot_version, const ObCreateTabletSchema &create_tablet_schema, ObTabletHandle &tablet_handle); + int inner_estimate_block_count_and_row_count( + ObTabletTableIterator &tablet_iter, + int64_t ¯o_block_count, + int64_t µ_block_count, + int64_t &sstable_row_count, + int64_t &memtable_row_count); + int estimate_block_count_and_row_count_for_split_extra( + const ObTabletID &tablet_id, + const int64_t split_cnt, + const ObMDSGetTabletMode mode, + const int64_t timeout_us, + int64_t ¯o_block_count, + int64_t µ_block_count, + int64_t &sstable_row_count, + int64_t &memtable_row_count, + common::ObIArray &cg_macro_cnt_arr, + common::ObIArray &cg_micro_cnt_arr); + int refresh_tablet_addr( const share::ObLSID &ls_id, const common::ObTabletID &tablet_id, @@ -577,6 +638,24 @@ private: int offline_build_tablet_without_memtable_(); int offline_gc_tablet_for_create_or_transfer_in_abort_(); int offline_destroy_memtable_and_mds_table_(); + + int inner_get_read_tables( + const common::ObTabletID tablet_id, + const int64_t timeout_us, + const int64_t snapshot_version_for_tablet, + const int64_t snapshot_version_for_tables, + ObTabletTableIterator &iter, + const bool allow_no_ready_read, + const bool need_split_src_table, + const bool need_split_dst_table, + const ObMDSGetTabletMode mode); + int inner_get_read_tables_for_split_src( + const common::ObTabletID tablet_id, + const int64_t timeout_us, + const int64_t snapshot_version, + ObTabletTableIterator &iter, + const bool allow_no_ready_read); + int mock_duplicated_rows_(blocksstable::ObDatumRowIterator *&duplicated_rows); private: static int replay_create_inner_tablet( @@ -595,8 +674,15 @@ private: static int check_old_row_legitimacy( const blocksstable::ObStoreCmpFuncs &cmp_funcs, ObTabletHandle &data_tablet_handle, - ObDMLRunningCtx &run_ctx, - blocksstable::ObDatumRow &old_row); + ObRelativeTable &data_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, + const ObIArray *column_ids, + const ObColDescIArray *col_descs_ptr, + const bool is_need_check_old_row, + const bool is_udf, + const blocksstable::ObDmlFlag &dml_flag, + const blocksstable::ObDatumRow &old_row); static int check_new_row_legitimacy( ObDMLRunningCtx &run_ctx, const blocksstable::ObDatumRow &datum_row); @@ -629,6 +715,7 @@ private: ObRowsInfo &rows_info); static int insert_lob_col( ObDMLRunningCtx &run_ctx, + const ObNewRow &data_row, const ObColDesc &column, blocksstable::ObStorageDatum &datum, ObLobAccessParam *del_param, @@ -679,29 +766,6 @@ private: const int64_t rowkey_len, const blocksstable::ObStorageDatumUtils &rowkey_datum_utils, bool &rowkey_change); - static int process_delta_lob( - ObDMLRunningCtx &run_ctx, - const ObColDesc &column, - ObStorageDatum &old_datum, - ObLobLocatorV2 &delta_lob, - ObStorageDatum &datum); - static int register_ext_info_commit_cb( - ObDMLRunningCtx &run_ctx, - ObStorageDatum &col_data, - ObObjType type, - ObObj &ext_info_data); - static int set_lob_storage_params( - ObDMLRunningCtx &run_ctx, - const ObColDesc &column, - ObLobAccessParam &lob_param); - - static int process_lob_row( - ObTabletHandle &tablet_handle, - ObDMLRunningCtx &run_ctx, - const ObIArray &update_idx, - bool data_tbl_rowkey_change, - ObDatumRow &old_row, - ObDatumRow &new_row); static int update_row_to_tablet( ObTabletHandle &tablet_handle, ObDMLRunningCtx &run_ctx, @@ -750,14 +814,18 @@ private: bool &locked); static int get_conflict_rows( ObTabletHandle &tablet_handle, - ObDMLRunningCtx &run_ctx, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, const ObInsertFlag flag, const common::ObIArray &out_col_ids, + const ObColDescIArray &col_descs, blocksstable::ObDatumRow &row, blocksstable::ObDatumRowIterator *&duplicated_rows); static int init_single_row_getter( ObSingleRowGetter &row_getter, - ObDMLRunningCtx &run_ctx, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, const ObIArray &out_col_ids, ObRelativeTable &relative_table, bool skip_read_lob = false); @@ -780,21 +848,20 @@ private: blocksstable::ObDatumRow &datum_row); static int table_refresh_row( ObTabletHandle &data_tablet_handle, - ObDMLRunningCtx &run_ctx, - blocksstable::ObDatumRow &datum_row); + ObRelativeTable &data_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, + const ObColDescIArray &col_descs, + ObIAllocator &lob_allocator, + blocksstable::ObDatumRow &row, + bool &is_old_row_valid_for_lob); static int delete_row_in_tablet( ObTabletHandle &tablet_handle, ObDMLRunningCtx &run_ctx, blocksstable::ObDatumRow &datum_row); - static int delete_lob_col( - ObDMLRunningCtx &run_ctx, - const ObColDesc &column, - blocksstable::ObStorageDatum &datum, - ObLobCommon *&lob_common, - ObLobAccessParam &lob_param); static int delete_lob_tablet_rows( + ObTabletHandle &tablet_handle, ObDMLRunningCtx &run_ctx, - ObTabletHandle &data_tablet, blocksstable::ObDatumRow &datum_row); static int prepare_scan_table_param( ObTableScanParam ¶m, @@ -812,6 +879,38 @@ private: const common::ObTabletID &tablet_id, const share::SCN &transfer_start_scn, bool &is_same); + + // for lob tablet dml + static int process_lob_before_insert( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow *rows, + int64_t row_count); + static int process_lob_before_insert( + ObTabletHandle &data_tablet, + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &row, + const int16_t row_idx); + static int process_lob_after_insert( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow *rows, + int64_t row_count); + static int process_lob_before_update( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + const ObIArray &update_idx, + blocksstable::ObDatumRow &old_datum_row, + blocksstable::ObDatumRow &new_datum_row, + const bool data_tbl_rowkey_change); + static int process_lob_after_update( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + const ObIArray &update_idx, + blocksstable::ObDatumRow &old_datum_row, + blocksstable::ObDatumRow &new_datum_row, + const bool data_tbl_rowkey_change); + private: int direct_insert_rows(const uint64_t table_id, const int64_t px_task_id, @@ -820,15 +919,97 @@ private: const common::ObIArray &column_ids, blocksstable::ObDatumRowIterator *row_iter, int64_t &affected_rows); - static int get_storage_row(const ObDatumRow &sql_row, + static int get_storage_row(const blocksstable::ObDatumRow &sql_row, const ObIArray &column_ids, + const ObColDescIArray &column_descs, ObSingleRowGetter &row_getter, - ObDMLRunningCtx &run_ctx, - ObDatumRow *&out_row, + ObRelativeTable &data_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, + blocksstable::ObDatumRow *&out_row, bool use_fuse_row_cache = false); static int check_is_gencol_check_failed(const ObRelativeTable &data_table, uint64_t error_col_id, bool &is_virtual_gencol); + static int lock_row_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const blocksstable::ObDatumRowkey &rowkey); + static int lock_row_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + ObColDescArray &col_descs, + blocksstable::ObDatumRow &row); + static int update_row_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const ObIArray &col_descs, + const ObIArray &update_idx, + const blocksstable::ObDatumRow &old_row, + blocksstable::ObDatumRow &new_row, + const ObIArray *encrypt_meta_arr); + static int batch_calc_split_dst_rows( + ObLS &ls, + ObTabletHandle &tablet_handle, + ObRelativeTable &relative_table, + blocksstable::ObDatumRow *rows, + const int64_t row_count, + const int64_t abs_timeout_us, + ObIArray &dst_tablet_ids, + ObIArray> &dst_rows); + static int insert_rows_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + blocksstable::ObDatumRow *rows, + ObRowsInfo &rows_info, + const bool check_exist, + const ObColDescIArray &col_descs, + const int64_t row_count, + const ObIArray *encrypt_meta_arr); + static int insert_row_without_rowkey_check_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const bool check_exists, + const ObIArray &col_descs, + blocksstable::ObDatumRow &row, + const ObIArray *encrypt_meta_arr); + static int check_row_locked_by_myself_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const blocksstable::ObDatumRowkey &rowkey, + bool &locked); + static int get_conflict_rows_wrap( + ObTabletHandle &tablet_handle, + const blocksstable::ObDatumRow *data_row_for_lob, + ObRelativeTable &relative_table, + ObStoreCtx &store_ctx, + const ObDMLBaseParam &dml_param, + const ObInsertFlag flag, + const ObIArray &out_col_ids, + const ObColDescIArray &col_descs, + blocksstable::ObDatumRow &row, + blocksstable::ObDatumRowIterator *&duplicated_rows); + static int table_refresh_row_wrap( + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + blocksstable::ObDatumRow &row); + static int check_old_row_legitimacy_wrap( + const blocksstable::ObStoreCmpFuncs &cmp_funcs, + ObTabletHandle &tablet_handle, + ObDMLRunningCtx &run_ctx, + const blocksstable::ObDatumRow &old_row); private: friend class ObLSTabletIterator; diff --git a/src/storage/memtable/mvcc/ob_mvcc_ctx.cpp b/src/storage/memtable/mvcc/ob_mvcc_ctx.cpp index 33b297f5e..37419a6a9 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_ctx.cpp +++ b/src/storage/memtable/mvcc/ob_mvcc_ctx.cpp @@ -267,16 +267,15 @@ void ObIMvccCtx::check_row_callback_registration_between_stmt_() int ObIMvccCtx::register_ext_info_commit_cb( const int64_t timeout, const blocksstable::ObDmlFlag dml_flag, - transaction::ObTxDesc *tx_desc, - transaction::ObTxSEQ &parent_seq_no, - blocksstable::ObStorageDatum &index_data, - ObObjType &type, + const transaction::ObTxSEQ &seq_no_st, + const int64_t seq_no_cnt, + const ObExtInfoLogHeader &header, ObObj &ext_info_data) { int ret = OB_SUCCESS; storage::ObExtInfoCbRegister cb_register; - if (OB_FAIL(cb_register.register_cb(this, timeout, dml_flag, tx_desc, parent_seq_no, index_data, type, ext_info_data))) { - TRANS_LOG(ERROR, "register ext info callback failed", K(ret), K(cb_register), K(*this)); + if (OB_FAIL(cb_register.register_cb(this, timeout, dml_flag, seq_no_st, seq_no_cnt, header, ext_info_data))) { + TRANS_LOG(WARN, "register ext info callback failed", K(ret), K(cb_register), K(*this)); } return ret; } diff --git a/src/storage/memtable/mvcc/ob_mvcc_ctx.h b/src/storage/memtable/mvcc/ob_mvcc_ctx.h index c52ce42fe..8d3d39093 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_ctx.h +++ b/src/storage/memtable/mvcc/ob_mvcc_ctx.h @@ -46,6 +46,7 @@ namespace storage class ObLsmtTransNode; class ObFreezer; class ObExtInfoCallback; +class ObExtInfoLogHeader; } using namespace transaction::tablelock; @@ -176,10 +177,9 @@ public: int register_ext_info_commit_cb( const int64_t timeout, const blocksstable::ObDmlFlag dml_flag, - transaction::ObTxDesc *tx_desc, - transaction::ObTxSEQ &parent_seq_no, - blocksstable::ObStorageDatum &index_data, - ObObjType &type, + const transaction::ObTxSEQ &seq_no_st, + const int64_t seq_no_cnt, + const storage::ObExtInfoLogHeader &header, ObObj &ext_info_data); public: virtual void reset() diff --git a/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.cpp b/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.cpp index 9155e0e39..66393f34f 100644 --- a/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.cpp +++ b/src/storage/memtable/mvcc/ob_mvcc_trans_ctx.cpp @@ -116,7 +116,7 @@ void ObITransCallback::after_append_cb(const bool is_replay) (void)after_append(is_replay); } -int ObITransCallback::log_submitted_cb(const SCN scn, ObIMemtable *&last_mt) +int ObITransCallback::log_submitted_cb(const SCN scn, storage::ObIMemtable *&last_mt) { int ret = OB_SUCCESS; if (need_submit_log_) { @@ -799,7 +799,7 @@ int ObTransCallbackMgr::get_log_guard(const transaction::ObTxSEQ &write_seq, } else if (FALSE_IT(pending_too_large = list->pending_log_too_large(GCONF._private_buffer_size * 10))) { } else if (!check_list_has_min_epoch_(list_idx, my_epoch, pending_too_large, min_epoch, min_epoch_idx)) { ret = OB_EAGAIN; - ObIMemtable *to_log_memtable = list->get_log_cursor()->get_memtable(); + storage::ObIMemtable *to_log_memtable = list->get_log_cursor()->get_memtable(); if (TC_REACH_TIME_INTERVAL(1_s)) { TRANS_LOG(WARN, "has smaller epoch unlogged", KPC(this), K(list_idx), K(write_seq), K(my_epoch), K(min_epoch), K(min_epoch_idx), KP(to_log_memtable)); @@ -1101,7 +1101,7 @@ inline bool check_dup_tablet_(ObITransCallback *callback_ptr) int ObTransCallbackMgr::log_submitted(const ObCallbackScopeArray &callbacks, share::SCN scn, int &submitted) { int ret = OB_SUCCESS; - ObIMemtable *last_mt = NULL; + storage::ObIMemtable *last_mt = NULL; ARRAY_FOREACH(callbacks, i) { ObCallbackScope scope = callbacks.at(i); if (!scope.is_empty()) { @@ -1445,7 +1445,7 @@ void ObMvccRowCallback::after_append(const bool is_replay) // do nothing } -int ObMvccRowCallback::log_submitted(const SCN scn, ObIMemtable *&last_mt) +int ObMvccRowCallback::log_submitted(const SCN scn, storage::ObIMemtable *&last_mt) { int ret = OB_SUCCESS; if (OB_NOT_NULL(memtable_)) { @@ -1509,7 +1509,7 @@ int ObMvccRowCallback::del() } if (need_submit_log_) { - ObIMemtable *last_mt = NULL; + storage::ObIMemtable *last_mt = NULL; log_submitted(share::SCN(), last_mt); } @@ -1531,12 +1531,12 @@ const common::ObTabletID &ObMvccRowCallback::get_tablet_id() const return memtable_->get_key().get_tablet_id(); } -bool ObMvccRowCallback::on_memtable(const ObIMemtable * const memtable) +bool ObMvccRowCallback::on_memtable(const storage::ObIMemtable * const memtable) { return memtable == memtable_; } -ObIMemtable *ObMvccRowCallback::get_memtable() const +storage::ObIMemtable *ObMvccRowCallback::get_memtable() const { return memtable_; }; diff --git a/src/storage/memtable/ob_memtable_iterator.cpp b/src/storage/memtable/ob_memtable_iterator.cpp index 70e2afe05..3f4e679ce 100644 --- a/src/storage/memtable/ob_memtable_iterator.cpp +++ b/src/storage/memtable/ob_memtable_iterator.cpp @@ -70,7 +70,7 @@ ObMemtableGetIterator::~ObMemtableGetIterator() int ObMemtableGetIterator::init( const storage::ObTableIterParam ¶m, storage::ObTableAccessContext &context, - ObIMemtable &memtable) + storage::ObIMemtable &memtable) { int ret = OB_SUCCESS; char *trans_info_ptr = nullptr; @@ -194,7 +194,7 @@ ObMemtableScanIterator::~ObMemtableScanIterator() while(ITER_END != scan_iter.get_next_row()); */ int ObMemtableScanIterator::init( - ObIMemtable* memtable, + storage::ObIMemtable* memtable, const storage::ObTableIterParam ¶m, storage::ObTableAccessContext &context) { diff --git a/src/storage/meta_mem/ob_tablet_handle.cpp b/src/storage/meta_mem/ob_tablet_handle.cpp index 1ad3fb33a..f6ef285de 100644 --- a/src/storage/meta_mem/ob_tablet_handle.cpp +++ b/src/storage/meta_mem/ob_tablet_handle.cpp @@ -240,6 +240,32 @@ int ObTabletTableIterator::assign(const ObTabletTableIterator& other) } } } + + if (OB_FAIL(ret)) { + } else { + if (OB_UNLIKELY(nullptr != other.split_extra_tablet_handles_)) { + if (nullptr == split_extra_tablet_handles_) { + void *tablet_hdl_buf = ob_malloc(sizeof(SplitExtraTabletHandleArray), ObMemAttr(MTL_ID(), "PartSplitTblH")); + if (OB_ISNULL(tablet_hdl_buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocator memory for handle", K(ret)); + } else { + split_extra_tablet_handles_ = new (tablet_hdl_buf) SplitExtraTabletHandleArray(); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(split_extra_tablet_handles_->assign(*other.split_extra_tablet_handles_))) { + LOG_WARN("failed to assign", K(ret)); + } + } + } else { + if (nullptr != split_extra_tablet_handles_) { + split_extra_tablet_handles_->~ObIArray(); + ob_free(split_extra_tablet_handles_); + split_extra_tablet_handles_ = nullptr; + } + } + } } return ret; } @@ -284,23 +310,46 @@ int ObTabletTableIterator::set_transfer_src_tablet_handle(const ObTabletHandle & return ret; } +int ObTabletTableIterator::add_split_extra_tablet_handle(const ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + if (nullptr == split_extra_tablet_handles_) { + void *tablet_hdl_buf = ob_malloc(sizeof(SplitExtraTabletHandleArray), ObMemAttr(MTL_ID(), "PartSplitTblH")); + if (OB_ISNULL(tablet_hdl_buf)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("fail to allocator memory for handles", K(ret)); + } else { + split_extra_tablet_handles_ = new (tablet_hdl_buf) SplitExtraTabletHandleArray(); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(split_extra_tablet_handles_->push_back(tablet_handle))) { + LOG_WARN("failed to push back", K(ret)); + } + } + return ret; +} + int ObTabletTableIterator::refresh_read_tables_from_tablet( const int64_t snapshot_version, const bool allow_no_ready_read, - const bool major_sstable_only) + const bool major_sstable_only, + const bool need_split_src_table, + const bool need_split_dst_table) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!tablet_handle_.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("try to refresh tables in tablet table iter with invalid tablet handle", K(ret)); } else if (major_sstable_only) { - if (OB_FAIL(tablet_handle_.get_obj()->get_read_major_sstable(snapshot_version, *this))) { + if (OB_FAIL(tablet_handle_.get_obj()->get_read_major_sstable( + snapshot_version, *this, need_split_src_table))) { LOG_WARN("failed to get read major sstable from tablet", - K(ret), K(snapshot_version), K_(tablet_handle)); + K(ret), K(snapshot_version), K_(tablet_handle)); } } else { if (OB_FAIL(tablet_handle_.get_obj()->get_read_tables( - snapshot_version, *this, allow_no_ready_read))) { + snapshot_version, *this, allow_no_ready_read, need_split_src_table, need_split_dst_table))) { LOG_WARN("failed to get read tables from tablet", K(ret), K_(tablet_handle)); } } @@ -327,10 +376,12 @@ int ObTabletTableIterator::get_read_tables_from_tablet( const int64_t snapshot_version, const bool allow_no_ready_read, const bool major_sstable_only, + const bool need_split_src_table, + const bool need_split_dst_table, ObIArray &tables) { int ret = OB_SUCCESS; - if (OB_FAIL(refresh_read_tables_from_tablet(snapshot_version, allow_no_ready_read, major_sstable_only))) { + if (OB_FAIL(refresh_read_tables_from_tablet(snapshot_version, allow_no_ready_read, major_sstable_only, need_split_src_table, need_split_dst_table))) { LOG_WARN("failed to refresh read tables", K(ret), K(snapshot_version), K(allow_no_ready_read), K(major_sstable_only), KPC(this)); } else { while(OB_SUCC(ret)) { diff --git a/src/storage/meta_mem/ob_tablet_handle.h b/src/storage/meta_mem/ob_tablet_handle.h index c8e531c8e..4442098f5 100644 --- a/src/storage/meta_mem/ob_tablet_handle.h +++ b/src/storage/meta_mem/ob_tablet_handle.h @@ -72,9 +72,10 @@ class ObTabletTableIterator final { friend class ObTablet; friend class ObLSTabletService; + typedef ObSEArray SplitExtraTabletHandleArray; public: - ObTabletTableIterator() : tablet_handle_(), table_store_iter_(), transfer_src_handle_(nullptr) {} - explicit ObTabletTableIterator(const bool is_reverse) : tablet_handle_(), table_store_iter_(is_reverse), transfer_src_handle_(nullptr) {} + ObTabletTableIterator() : tablet_handle_(), table_store_iter_(), transfer_src_handle_(nullptr), split_extra_tablet_handles_(nullptr) {} + explicit ObTabletTableIterator(const bool is_reverse) : tablet_handle_(), table_store_iter_(is_reverse), transfer_src_handle_(nullptr), split_extra_tablet_handles_(nullptr) {} int assign(const ObTabletTableIterator& other); ~ObTabletTableIterator() { reset(); } void reset() @@ -86,6 +87,11 @@ public: ob_free(transfer_src_handle_); transfer_src_handle_ = nullptr; } + if (nullptr != split_extra_tablet_handles_) { + split_extra_tablet_handles_->~ObIArray(); + ob_free(split_extra_tablet_handles_); + split_extra_tablet_handles_ = nullptr; + } } bool is_valid() const { return tablet_handle_.is_valid() || table_store_iter_.is_valid(); } ObTableStoreIterator *table_iter(); @@ -96,28 +102,34 @@ public: const ObTabletHandle *get_tablet_handle_ptr() const { return &tablet_handle_; } int set_tablet_handle(const ObTabletHandle &tablet_handle); int set_transfer_src_tablet_handle(const ObTabletHandle &tablet_handle); + int add_split_extra_tablet_handle(const ObTabletHandle &tablet_handle); int refresh_read_tables_from_tablet( const int64_t snapshot_version, const bool allow_no_ready_read, - const bool major_sstable_only = false); + const bool major_sstable_only, + const bool need_split_src_table, + const bool need_split_dst_table); int get_mds_sstables_from_tablet(const int64_t snapshot_version); int get_read_tables_from_tablet( const int64_t snapshot_version, const bool allow_no_ready_read, const bool major_sstable_only, + const bool need_split_src_table, + const bool need_split_dst_table, ObIArray &tables); TO_STRING_KV(K_(tablet_handle), K_(transfer_src_handle), K_(table_store_iter)); private: ObTabletHandle tablet_handle_; ObTableStoreIterator table_store_iter_; ObTabletHandle *transfer_src_handle_; + ObIArray *split_extra_tablet_handles_; DISALLOW_COPY_AND_ASSIGN(ObTabletTableIterator); }; struct ObGetTableParam final { public: - ObGetTableParam() : frozen_version_(-1), sample_info_(), tablet_iter_(), refreshed_merge_(nullptr) {} + ObGetTableParam() : frozen_version_(-1), sample_info_(), tablet_iter_(), refreshed_merge_(nullptr), need_split_dst_table_(true) {} ~ObGetTableParam() { reset(); } bool is_valid() const { return tablet_iter_.is_valid(); } void reset() @@ -126,8 +138,9 @@ public: sample_info_.reset(); tablet_iter_.reset(); refreshed_merge_ = nullptr; + need_split_dst_table_ = true; } - TO_STRING_KV(K_(frozen_version), K_(sample_info), K_(tablet_iter)); + TO_STRING_KV(K_(frozen_version), K_(sample_info), K_(tablet_iter), K_(need_split_dst_table)); public: int64_t frozen_version_; common::SampleInfo sample_info_; @@ -136,6 +149,10 @@ public: // when tablet has been refreshed, to notify other ObMultipleMerge in ObTableScanIterator re-inited // before rescan. void *refreshed_merge_; + + // true means maybe need split dst table, which is always safe because get_read_tables will check by mds again; + // false means no need split dst table, which is for optimization and UNSAFE + bool need_split_dst_table_; DISALLOW_COPY_AND_ASSIGN(ObGetTableParam); }; diff --git a/src/storage/meta_mem/ob_tablet_pointer.cpp b/src/storage/meta_mem/ob_tablet_pointer.cpp index f2a63ecce..33d2abde1 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.cpp +++ b/src/storage/meta_mem/ob_tablet_pointer.cpp @@ -53,10 +53,11 @@ ObTabletPointer::ObTabletPointer() mds_lock_(), mds_table_handler_(), old_version_chain_(nullptr), - attr_() + attr_(), + auto_part_size_(OB_INVALID_SIZE) { #if defined(__x86_64__) && !defined(ENABLE_OBJ_LEAK_CHECK) - static_assert(sizeof(ObTabletPointer) == 352, "The size of ObTabletPointer will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); + static_assert(sizeof(ObTabletPointer) == 360, "The size of ObTabletPointer will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); #endif } @@ -72,7 +73,9 @@ ObTabletPointer::ObTabletPointer( flying_(false), ddl_kv_mgr_lock_(), mds_table_handler_(), - old_version_chain_(nullptr) + old_version_chain_(nullptr), + attr_(), + auto_part_size_(OB_INVALID_SIZE) { } @@ -95,6 +98,7 @@ void ObTabletPointer::reset() reset_obj(); phy_addr_.reset(); ls_handle_.reset(); + auto_part_size_ = OB_INVALID_SIZE; flying_ = false; } @@ -736,6 +740,16 @@ int ObTabletPointer::set_tablet_attr(const ObTabletAttr &attr) return ret; } +int64_t ObTabletPointer::get_auto_part_size() const +{ + return ATOMIC_LOAD(&auto_part_size_); +} + +void ObTabletPointer::set_auto_part_size(const int64_t auto_part_size) +{ + ATOMIC_STORE(&auto_part_size_, auto_part_size); +} + int64_t ObITabletFilterOp::total_skip_cnt_ = 0; int64_t ObITabletFilterOp::total_tablet_cnt_ = 0; int64_t ObITabletFilterOp::not_in_mem_tablet_cnt_ = 0; diff --git a/src/storage/meta_mem/ob_tablet_pointer.h b/src/storage/meta_mem/ob_tablet_pointer.h index eda3cf4fd..2af62acb5 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.h +++ b/src/storage/meta_mem/ob_tablet_pointer.h @@ -198,6 +198,8 @@ public: int set_tablet_attr(const ObTabletAttr &attr); bool is_old_version_chain_empty() const { return OB_ISNULL(old_version_chain_); } bool is_attr_valid() const { return attr_.is_valid(); } + int64_t get_auto_part_size() const; + void set_auto_part_size(const int64_t auto_part_size); private: int scan_all_tablets_on_chain(const ObFunction &op);// must be called under t3m bucket lock's protection int wash_obj(); @@ -221,7 +223,8 @@ private: mds::ObMdsTableHandler mds_table_handler_;// 48B ObTablet *old_version_chain_; // 8B ObTabletAttr attr_; // 32B // protected by rw lock of tablet_map_ - DISALLOW_COPY_AND_ASSIGN(ObTabletPointer); // 352B + int64_t auto_part_size_; // 8B + DISALLOW_COPY_AND_ASSIGN(ObTabletPointer); // 360B }; struct ObTabletResidentInfo final diff --git a/src/storage/multi_data_source/compile_utility/mds_register.h b/src/storage/multi_data_source/compile_utility/mds_register.h index 9e684f56a..658e4a0b6 100644 --- a/src/storage/multi_data_source/compile_utility/mds_register.h +++ b/src/storage/multi_data_source/compile_utility/mds_register.h @@ -62,6 +62,8 @@ #include "src/storage/tablet/ob_tablet_delete_mds_helper.h" #include "src/storage/tablet/ob_tablet_binding_helper.h" #include "src/storage/tablet/ob_tablet_binding_mds_user_data.h" + #include "src/storage/tablet/ob_tablet_split_mds_helper.h" + #include "src/storage/tablet/ob_tablet_split_mds_user_data.h" #include "src/share/ob_tablet_autoincrement_param.h" #include "src/storage/compaction/ob_medium_compaction_info.h" #include "src/storage/tablet/ob_tablet_start_transfer_mds_helper.h" @@ -164,10 +166,10 @@ _GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION_(HELPER_CLASS, BUFFER_CTX_TYPE, ID, ENU ::oceanbase::storage::mds::MdsCtx,\ 30,\ CHANGE_TABLET_TO_TABLE_MDS) - // GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletSplitMdsHelper,\ - // ::oceanbase::storage::mds::MdsCtx,\ - // 31,\ - // TABLET_SPLIT) + GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletSplitMdsHelper,\ + ::oceanbase::storage::mds::MdsCtx,\ + 31,\ + TABLET_SPLIT) // GENERATE_MDS_FRAME_CODE_FOR_TRANSACTION(::oceanbase::storage::ObTabletAbortTransferHelper,\ // ::oceanbase::storage::mds::ObAbortTransferInMdsCtx,\ // 32,\ @@ -245,9 +247,9 @@ _GENERATE_MDS_UNIT_(KEY_TYPE, VALUE_TYPE, NEED_MULTI_VERSION) GENERATE_MDS_UNIT(::oceanbase::compaction::ObMediumCompactionInfoKey,\ ::oceanbase::compaction::ObMediumCompactionInfo,\ false) - // GENERATE_MDS_UNIT(::oceanbase::storage::mds::DummyKey,\ - // ::oceanbase::storage::ObTabletSplitMdsUserData,\ - // false) + GENERATE_MDS_UNIT(::oceanbase::storage::mds::DummyKey,\ + ::oceanbase::storage::ObTabletSplitMdsUserData,\ + false) // # 余留位置(此行之前占位) #endif diff --git a/src/storage/multi_data_source/ob_mds_table_merge_task.cpp b/src/storage/multi_data_source/ob_mds_table_merge_task.cpp index 8d924ca93..4105b9e49 100644 --- a/src/storage/multi_data_source/ob_mds_table_merge_task.cpp +++ b/src/storage/multi_data_source/ob_mds_table_merge_task.cpp @@ -73,7 +73,7 @@ int ObMdsTableMergeTask::init() int ObMdsTableMergeTask::process() { - TIMEGUARD_INIT(STORAGE, 10_ms); + TIMEGUARD_INIT(STORAGE, 30_ms); int ret = OB_SUCCESS; ObTabletMergeCtx *ctx_ptr = nullptr; DEBUG_SYNC(AFTER_EMPTY_SHELL_TABLET_CREATE); @@ -124,7 +124,7 @@ int ObMdsTableMergeTask::process() } else if (OB_ISNULL(tablet = ctx.get_tablet())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet is null", K(ret), K(ls_id), K(tablet_id)); - } else if (OB_FAIL(tablet->get_mds_table_for_dump(mds_table))) { + } else if (CLICK_FAIL(tablet->get_mds_table_for_dump(mds_table))) { LOG_WARN("fail to get mds table", K(ret), K(ls_id), K(tablet_id)); } else if (OB_UNLIKELY(!mds_table.get_mds_table_ptr()->is_construct_sequence_matched(mds_construct_sequence))) { ret = OB_NO_NEED_MERGE; @@ -141,7 +141,7 @@ int ObMdsTableMergeTask::process() } else if (FALSE_IT(ctx.static_desc_.tablet_transfer_seq_ = tablet->get_transfer_seq())) { } else if (MDS_FAIL(build_mds_sstable(ctx, mds_construct_sequence, table_handle))) { LOG_WARN("fail to build mds sstable", K(ret), K(ls_id), K(tablet_id), KPC(mds_merge_dag_)); - } else if (MDS_FAIL(ls->build_new_tablet_from_mds_table( + } else if (CLICK_FAIL(ls->build_new_tablet_from_mds_table( ctx, tablet_id, table_handle, diff --git a/src/storage/ob_dml_running_ctx.cpp b/src/storage/ob_dml_running_ctx.cpp index 41b3f56cc..6b9ba11d8 100644 --- a/src/storage/ob_dml_running_ctx.cpp +++ b/src/storage/ob_dml_running_ctx.cpp @@ -21,6 +21,7 @@ #include "storage/access/ob_dml_param.h" #include "storage/tablet/ob_tablet.h" #include "storage/tablet/ob_tablet_binding_helper.h" +#include "storage/tablet/ob_tablet_split_mds_helper.h" #include "storage/ob_value_row_iterator.h" #include "storage/memtable/ob_memtable_context.h" @@ -50,6 +51,7 @@ ObDMLRunningCtx::ObDMLRunningCtx( is_old_row_valid_for_lob_(false), is_need_check_old_row_(is_need_row_datum_utils), is_udf_(false), + lob_dml_ctx_(), schema_guard_(share::schema::ObSchemaMgrItem::MOD_RELATIVE_TABLE), is_need_row_datum_utils_(is_need_row_datum_utils), is_inited_(false) @@ -144,13 +146,18 @@ int ObDMLRunningCtx::prepare_relative_table( const SCN &read_snapshot) { int ret = OB_SUCCESS; + bool need_get_src_split_tables = false; if (OB_FAIL(relative_table_.init(&schema, tablet_handle.get_obj()->get_tablet_meta().tablet_id_, schema.is_storage_index_table() && !schema.can_read_index()))) { LOG_WARN("fail to init relative_table_", K(ret), K(tablet_handle), K(schema.get_index_status())); } else if (OB_FAIL(relative_table_.tablet_iter_.set_tablet_handle(tablet_handle))) { LOG_WARN("fail to set tablet handle to iter", K(ret), K(relative_table_.tablet_iter_)); } else if (OB_FAIL(relative_table_.tablet_iter_.refresh_read_tables_from_tablet( - read_snapshot.get_val_for_tx(), relative_table_.allow_not_ready()))) { + read_snapshot.get_val_for_tx(), + relative_table_.allow_not_ready(), + false/*major_sstable_only*/, + true/*need_split_src_table*/, + false/*need_split_dst_table*/))) { LOG_WARN("failed to get relative table read tables", K(ret)); } return ret; @@ -292,6 +299,24 @@ int ObDMLRunningCtx::check_schema_version( } else if (OB_ISNULL(table_schema)) { ret = OB_SCHEMA_ERROR; LOG_WARN("failed to get schema", K(ret)); + } else if (table_schema->is_auto_partitioned_table()) { + // Online partition split allows dml with old schema to continue executing, + // so checkings must be done case by case. + if (table_version > table_schema->get_schema_version()) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("table version mismatch", K(ret), K(table_id), K(table_version), K(table_schema->get_schema_version())); + } else if (table_version < table_schema->get_schema_version()) { + // 1. check for wait trans end's check_schema_version_elapsed + int64_t data_max_schema_version = 0; + if (OB_FAIL(tablet_handle.get_obj()->get_max_schema_version(data_max_schema_version))) { + LOG_WARN("failed to get max schema version", K(ret)); + } else if (table_version < data_max_schema_version) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("table version mismatch", K(ret), K(table_id), K(table_version), K(data_max_schema_version), K(table_schema->get_schema_version())); + } else { + FLOG_INFO("allow table version mismatch", K(table_id), K(table_version), K(data_max_schema_version), K(table_schema->get_schema_version())); + } + } } else if (table_version != table_schema->get_schema_version()) { ret = OB_SCHEMA_EAGAIN; LOG_WARN("table version mismatch", K(ret), K(table_id), K(table_version), K(table_schema->get_schema_version())); diff --git a/src/storage/ob_dml_running_ctx.h b/src/storage/ob_dml_running_ctx.h index 8af46f265..b941ac72e 100644 --- a/src/storage/ob_dml_running_ctx.h +++ b/src/storage/ob_dml_running_ctx.h @@ -17,6 +17,7 @@ #include "storage/ob_i_store.h" #include "storage/ob_relative_table.h" #include "share/scn.h" +#include "storage/lob/ob_lob_tablet_dml.h" namespace oceanbase { @@ -94,6 +95,7 @@ public: bool is_old_row_valid_for_lob_; bool is_need_check_old_row_; bool is_udf_; + ObLobTabletDmlCtx lob_dml_ctx_; private: share::schema::ObSchemaGetterGuard schema_guard_; diff --git a/src/storage/ob_i_table.h b/src/storage/ob_i_table.h index 1086b6f5a..8a87f6ceb 100644 --- a/src/storage/ob_i_table.h +++ b/src/storage/ob_i_table.h @@ -179,7 +179,8 @@ public: return *this; } - TO_STRING_KV(K_(tablet_id), K_(column_group_idx), "table_type", get_table_type_name(table_type_), K_(scn_range)); + TO_STRING_KV(K_(tablet_id), K_(column_group_idx), "table_type", get_table_type_name(table_type_), + K_(scn_range)); public: common::ObTabletID tablet_id_; diff --git a/src/storage/ob_micro_block_handle_mgr.h b/src/storage/ob_micro_block_handle_mgr.h new file mode 100644 index 000000000..3594b1aa4 --- /dev/null +++ b/src/storage/ob_micro_block_handle_mgr.h @@ -0,0 +1,95 @@ +/** + * 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_MICRO_BLOCK_HANDLE_MGR_H_ +#define OB_MICRO_BLOCK_HANDLE_MGR_H_ + +#include "blocksstable/ob_block_manager.h" +#include "blocksstable/ob_block_sstable_struct.h" +#include "blocksstable/ob_imicro_block_reader.h" +#include "blocksstable/ob_macro_block_reader.h" +#include "blocksstable/ob_micro_block_cache.h" +#include "blocksstable/index_block/ob_index_block_row_scanner.h" +#include "storage/ob_handle_mgr.h" + +namespace oceanbase { +namespace storage { + +struct ObSSTableMicroBlockState { + enum ObSSTableMicroBlockStateEnum { + UNKNOWN_STATE = 0, + IN_BLOCK_CACHE, + IN_BLOCK_IO + }; +}; + + +struct ObMicroBlockDataHandle { + ObMicroBlockDataHandle(); + virtual ~ObMicroBlockDataHandle(); + void reset(); + + int get_data_block_data( + blocksstable::ObMacroBlockReader &block_reader, + blocksstable::ObMicroBlockData &block_data); + int get_index_block_data(blocksstable::ObMicroBlockData &index_block); + int get_cached_index_block_data(blocksstable::ObMicroBlockData &index_block); + TO_STRING_KV(K_(tenant_id), K_(macro_block_id), K_(micro_info), + K_(block_state), K_(block_index), K_(cache_handle), K_(io_handle)); + uint64_t tenant_id_; + blocksstable::MacroBlockId macro_block_id_; + int32_t block_state_; + int32_t block_index_; + blocksstable::ObMicroBlockInfo micro_info_; + blocksstable::ObMicroBlockDesMeta des_meta_; + char encrypt_key_[share::OB_MAX_TABLESPACE_ENCRYPT_KEY_LENGTH]; + blocksstable::ObMicroBlockBufferHandle cache_handle_; + blocksstable::ObMacroBlockHandle io_handle_; + ObIAllocator *allocator_; + blocksstable::ObMicroBlockData loaded_index_block_data_; + bool is_loaded_index_block_; + +private: + int get_loaded_block_data(blocksstable::ObMicroBlockData &block_data); + void try_release_loaded_index_block(); +}; + +class ObMicroBlockHandleMgr : public ObHandleMgr +{ +public: + ObMicroBlockHandleMgr(); + virtual ~ObMicroBlockHandleMgr() = default; + void reset(); + + int init(const bool is_multi, const bool is_ordered, common::ObIAllocator &allocator); + int get_micro_block_handle( + const uint64_t tenant_id, + const blocksstable::ObMicroIndexInfo &index_block_info, + const bool is_data_block, + ObMicroBlockDataHandle µ_block_handle); + int put_micro_block_handle( + const uint64_t tenant_id, + const blocksstable::MacroBlockId ¯o_id, + const blocksstable::ObIndexBlockRowHeader &idx_header, + ObMicroBlockDataHandle µ_block_handle); + int reset_handle_cache(); +private: + // allocator for index micro block prefetch failed and async io + common::ObFIFOAllocator allocator_; +}; + +} +} + +#endif /* OB_MICRO_BLOCK_HANDLE_MGR_H_ */ diff --git a/src/storage/ob_partition_pre_split.cpp b/src/storage/ob_partition_pre_split.cpp new file mode 100644 index 000000000..50b09caf6 --- /dev/null +++ b/src/storage/ob_partition_pre_split.cpp @@ -0,0 +1,1474 @@ +/** + * 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_partition_pre_split.h" +#include "lib/oblog/ob_log_module.h" +#include "lib/utility/ob_print_utils.h" +#include "storage/tx_storage/ob_ls_handle.h" +#include "storage/tx_storage/ob_ls_service.h" +#include "storage/meta_mem/ob_tablet_handle.h" +#include "pl/sys_package/ob_dbms_space.h" +#include "share/scheduler/ob_partition_auto_split_helper.h" +#include "sql/resolver/ob_resolver_utils.h" +#include "share/ob_index_builder_util.h" + + +namespace oceanbase +{ +using namespace share; +using namespace rootserver; +using namespace common; +using namespace obrpc; +using namespace pl; + +namespace storage +{ + +ObPartitionPreSplit::ObPartitionPreSplit(rootserver::ObDDLService &ddl_service) + : ddl_service_(&ddl_service) +{ +} + +ObPartitionPreSplit::ObPartitionPreSplit() +{ + ddl_service_ = nullptr; +} + +void ObPartitionPreSplit::reset() +{ + split_ranges_.reset(); + ddl_service_ = nullptr; +} + +void ObPartitionPreSplit::get_split_num( + const int64_t tablet_size, + const int64_t split_size, + int64_t &split_num) +{ + int ret = OB_SUCCESS; + split_num = 0; + if (split_size > 0 && tablet_size > split_size) { + split_num = (tablet_size % split_size) == 0 ? + (tablet_size / split_size) : + (tablet_size / split_size + 1); + split_num = split_num < MAX_SPLIT_RANGE_NUM ? + split_num : + MAX_SPLIT_RANGE_NUM; + } + LOG_DEBUG("[PRE_SPLIT] get tablet split num", K(split_num)); +} + +/* + function description: + 1. rebuild none partition index table + 2. create partition/none partition index table + 3. alter main none partition table +*/ +int ObPartitionPreSplit::build_new_partition_table_schema( + const ObTableSchema &ori_table_schema, + ObTableSchema &inc_partition_schema, + ObTableSchema &new_table_schema) +{ + int ret = OB_SUCCESS; + if (inc_partition_schema.get_partition_num() <= 0) { + // skip // no new add partitions + } else if (OB_ISNULL(ddl_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid ddl service", K(ret), KP(ddl_service_)); + } else if (OB_FAIL(ddl_service_->fill_part_name(ori_table_schema, inc_partition_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build split table schema", K(ret), K(inc_partition_schema)); + } else if (OB_FAIL(build_new_table_schema( + ori_table_schema, + inc_partition_schema, + new_table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build new table schema", K(ret), K(inc_partition_schema)); + } else { + LOG_DEBUG("success to build new partition table schema", + K(ret), K(inc_partition_schema), K(ori_table_schema), K(new_table_schema)); + } + return ret; +} + +int ObPartitionPreSplit::rebuild_partition_table_schema( + const ObIArray &split_tablet_ids, + const ObTableSchema &ori_table_schema, + const ObTableSchema &inc_partition_schema, + ObTableSchema &all_partition_schema, + ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + if (split_tablet_ids.count() > 0) { // has split tablets. + if (inc_partition_schema.get_partition_num()<= 0) { + // no new parts, skip. + } else if (OB_FAIL(generate_all_partition_schema( // gen part idx + split_tablet_ids, + ori_table_schema, + inc_partition_schema, + all_partition_schema))) { + LOG_WARN("[PRE_SPLIT] fail to fill full tablet partition schema", + K(ret), K(ori_table_schema), K(inc_partition_schema)); + } else if (OB_FAIL(build_new_table_schema( + ori_table_schema, + all_partition_schema, + table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build new table schema", K(ret), K(all_partition_schema)); + } else { + LOG_DEBUG("success to rebuild partition table schema", + K(ret), K(split_tablet_ids), K(inc_partition_schema), + K(all_partition_schema), K(table_schema)); + } + } + return ret; +} + +/* + * get table column ids. +*/ +int ObPartitionPreSplit::extract_table_columns_id( + const ObTableSchema &table_schema, + ObIArray &column_ids) +{ + int ret = OB_SUCCESS; + column_ids.reset(); + ObTableSchema::const_column_iterator col_iter = table_schema.column_begin(); + ObTableSchema::const_column_iterator col_end = table_schema.column_end(); + for (; OB_SUCC(ret) && col_iter != col_end; ++col_iter) { + const ObColumnSchemaV2 *column_schema = *col_iter; + if (OB_ISNULL(column_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid column schema", K(column_schema)); + } else if (OB_FAIL(column_ids.push_back(column_schema->get_column_id()))) { + LOG_WARN("[PRE_SPLIT] fail to push back data column id.", K(ret), K(column_schema)); + } + } + return ret; +} + +// not support pre-split global index table in none partition main table. +int ObPartitionPreSplit::get_data_table_part_ids( + const ObTableSchema &data_table_schema, + ObIArray &part_ids) +{ + int ret = OB_SUCCESS; + part_ids.reset(); + ObPartition **part_array = data_table_schema.get_part_array(); + ObPartitionLevel part_level = data_table_schema.get_part_level(); + const int64_t partition_num = data_table_schema.get_partition_num(); + if (0 == partition_num || PARTITION_LEVEL_ZERO == part_level) { + // auto partition none partition table is support, partition num maybe zero + if (OB_FAIL(part_ids.push_back(data_table_schema.get_table_id()))) { + LOG_WARN("[PRE_SPLIT] fail to push back table id.", K(ret)); + } + } else if (OB_ISNULL(part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid part array", K(ret), KP(part_array)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < partition_num; ++i) { + ObPartition *part = part_array[i]; + if (OB_ISNULL(part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid partition", K(ret), KP(part)); + } else if (OB_FAIL(part_ids.push_back(part->get_part_id()))) { + LOG_WARN("[PRE_SPLIT] fail to push back part id.", K(ret), K(part)); + } + } + } + return ret; +} + +// only for global index +int ObPartitionPreSplit::get_estimated_table_size( + const ObTableSchema &data_table_schema, + const ObTableSchema &index_table_schema, + int64_t &table_size) +{ + int ret = OB_SUCCESS; + + ObSEArray column_ids; + ObSEArray part_sizes; + ObSEArray part_ids; + table_size = 0; // reset + + if (OB_FAIL(index_table_schema.get_column_ids(column_ids))) { + LOG_WARN("[PRE_SPLIT] fail to get mapping column ids.", K(ret)); + } else if (OB_FAIL(get_data_table_part_ids(data_table_schema, part_ids))) { + LOG_WARN("[PRE_SPLIT] fail to get data table part id.", K(ret), K(data_table_schema)); + } else { + common::ObMySQLProxy *sql_proxy = GCTX.sql_proxy_; + ObDbmsSpace::IndexCostInfo cost_info; + if (OB_FAIL(cost_info.part_ids_.assign(part_ids))) { + LOG_WARN("[PRE_SPLIT] fail to assign cost info part id.", K(ret), K(part_ids)); + } else if (OB_FAIL(cost_info.column_ids_.assign(column_ids))) { + LOG_WARN("[PRE_SPLIT] fail to assign cost info column id.", K(ret), K(column_ids)); + } else if (FALSE_IT(cost_info.tenant_id_ = OB_SYS_TENANT_ID)) { + } else if (FALSE_IT(cost_info.table_id_ = data_table_schema.get_table_id())) { + } else if (FALSE_IT(cost_info.table_tenant_id_ = data_table_schema.get_tenant_id())) { + } else if (OB_ISNULL(sql_proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid sql proxy.", KP(sql_proxy)); + } else if (OB_FAIL(ObDbmsSpace::estimate_index_table_size( + sql_proxy, + &data_table_schema, + cost_info, + part_sizes))) { + LOG_WARN("[PRE_SPLIT] fail to estimate index table size", K(ret), K(cost_info)); + } else if (part_sizes.count() != part_ids.count()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] return count not match", K(ret), K(part_sizes.count()), K(part_ids.count())); + } else { + for (int64_t i = 0; i < part_sizes.count(); ++i) { + table_size += part_sizes.at(i); + } + } + } + return ret; +} +/* + description: + 1. exist main table + 2. exist global table +*/ +int ObPartitionPreSplit::get_exist_table_size( + const ObTableSchema &table_schema, + ObIArray &tablet_size) +{ + int ret = OB_SUCCESS; + tablet_size.reset(); + common::ObMySQLProxy *sql_proxy = GCTX.sql_proxy_; + if (OB_ISNULL(sql_proxy)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid sql proxy.", KP(sql_proxy)); + } else if (OB_FAIL(ObDbmsSpace::get_each_tablet_size( + sql_proxy, + &table_schema, + tablet_size))) { + LOG_WARN("[PRE_SPLIT] fail to get each tablet size"); + } + return ret; +} + +int ObPartitionPreSplit::get_global_index_pre_split_schema_if_need( + const int64_t tenant_id, + const int64_t session_id, + const ObString &database_name, + const ObString &table_name, + common::ObIArray &index_arg_list) +{ + int ret = OB_SUCCESS; + const share::schema::ObTableSchema *data_table_schema = NULL; + schema::ObSchemaGetterGuard schema_guard; + schema_guard.set_session_id(session_id); + uint64_t current_data_version = 0; + if (tenant_id == OB_INVALID_TENANT_ID || database_name.empty() || table_name.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] unexpected database name or table name", K(tenant_id), K(database_name), K(table_name)); + } else if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, current_data_version))) { + LOG_WARN("[PRE_SPLIT] failed to get data version", K(ret)); + } else if (current_data_version < DATA_VERSION_4_3_4_0) { + LOG_INFO("[PRE_SPLIT] current data version less than 4.3.4.0 is not support", K(ret), K(current_data_version)); + } else if (OB_FAIL(ObMultiVersionSchemaService::get_instance().get_tenant_schema_guard(tenant_id, schema_guard))) { + LOG_WARN("[PRE_SPLIT] fail to get tenant schema guard", K(ret), K(tenant_id)); + } else if (OB_FALSE_IT(schema_guard.set_session_id(session_id))) { + } else if (schema_guard.get_table_schema(tenant_id, database_name, table_name, false/*is_index*/, data_table_schema)) { + LOG_WARN("[PRE_SPLIT] fail to get table schema", K(ret), K(tenant_id), K(database_name), K(table_name)); + } else if (OB_ISNULL(data_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] table schema null pointer", K(ret), KP(data_table_schema)); + } else if (!data_table_schema->is_auto_partitioned_table() || + data_table_schema->is_mysql_tmp_table()) { + LOG_INFO("[PRE_SPLIT] not support auto split table type", K(ret), K(data_table_schema)); + } else { + // alter table add global index + for (int64_t i = 0; OB_SUCC(ret) && i < index_arg_list.count(); ++i) { + ObIndexArg *index_arg = index_arg_list.at(i); + if (index_arg->index_action_type_ == ObIndexArg::ADD_INDEX) { + HEAP_VAR(ObTableSchema, index_schema) { + ObCreateIndexArg *create_index_arg = static_cast(index_arg); + if (OB_FAIL(index_schema.assign(create_index_arg->index_schema_))) { + LOG_WARN("fail to assign index schema", K(ret)); + } else if (OB_FALSE_IT(index_schema.set_tenant_id(data_table_schema->get_tenant_id()))) { + } else if (OB_FALSE_IT(index_schema.set_data_table_id(data_table_schema->get_table_id()))) { + } else if (index_schema.get_column_count() == 0 && + OB_FAIL(ObIndexBuilderUtil::set_index_table_columns(*create_index_arg, *data_table_schema, index_schema))) { + LOG_WARN("[PRE_SPLIT] fail to set index table columns", K(ret)); + } else if (OB_FAIL(check_table_can_do_pre_split(index_schema))) { + LOG_WARN("[PRE_SPLIT] fail to check table info", K(ret), K(index_schema)); + } else if (OB_FAIL(do_pre_split_global_index(database_name, *data_table_schema, index_schema, index_schema))) { + LOG_WARN("[PRE_SPLIT] fail to get new index table split range", K(ret), K(tenant_id), K(database_name)); + } else { + LOG_DEBUG("[PRE_SPLIT] success pre split index schema", K(index_schema)); + } + if (OB_SUCC(ret) && index_schema.is_partitioned_table()) { + if (OB_FAIL(create_index_arg->index_schema_.assign(index_schema))) { + LOG_WARN("[PRE_SPLIT] fail to assign index schema", K(ret), K(index_schema)); + } + } else if (ret == OB_NOT_SUPPORTED) { + ret = OB_SUCCESS; + LOG_INFO("[PRE_SPLIT] not support pre-split schema. do nothing", K(ret), K(index_schema)); + } + } + } + } + } + return ret; +} + +/* + 1. 在预分裂创建全局索引的场景,外层ddl_type可以不传,其他场景需要传 + 2. 在预分裂主表或者已存在的全局索引表时,外层传入的data_table_schema可以是主表和全局索引表的的new_table_schema +*/ +int ObPartitionPreSplit::do_table_pre_split_if_need( + const ObString &db_name, + const ObDDLType ddl_type, + const bool is_building_global_index, + const ObTableSchema &data_table_schema, + const ObTableSchema &ori_table_schema, + ObTableSchema &new_table_schema) +{ + int ret = OB_SUCCESS; + const int64_t tenant_id = new_table_schema.get_tenant_id(); + uint64_t current_data_version = 0; + if (OB_FAIL(GET_MIN_DATA_VERSION(tenant_id, current_data_version))) { + LOG_WARN("failed to get data version", K(ret)); + } else if (current_data_version < DATA_VERSION_4_3_4_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("current data version less than 4.4.0.0 is not support", K(ret), K(current_data_version)); + } else if (!data_table_schema.is_auto_partitioned_table()) { + // skip // not auto split partition table + ret = OB_NOT_SUPPORTED; + LOG_DEBUG("[PRE_SPLIT] table is not auto part table, no need to pre split", K(ret)); + } else if (OB_UNLIKELY(db_name.empty() || OB_INVALID_ID == tenant_id || ddl_type > ObDDLType::DDL_MAX)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[PRE_SPLIT] invalid argument", K(ret), K(db_name), K(tenant_id), K(ddl_type)); + } else if (OB_FAIL(check_table_can_do_pre_split(new_table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to check table info", K(ret), K(new_table_schema)); + } + if (OB_FAIL(ret)) { + if (ret == OB_NOT_SUPPORTED) { + ret = OB_SUCCESS; // some ddl type no need to do pre split, just return success. + LOG_INFO("not support pre-split schema. do nothing", K(ret), K(new_table_schema)); + } + } else if (is_building_global_index) { + // 1. create index global (partition or not partition table) + // 2. alter table add index global (partition or not partition table) + ObTableSchema ori_index_table_schema; + if (OB_FAIL(ori_index_table_schema.assign(new_table_schema))) { + LOG_WARN("fail to assign schema", K(ret), K(new_table_schema)); + } else if (OB_FAIL(do_pre_split_global_index(db_name, data_table_schema, ori_index_table_schema, new_table_schema))) { + LOG_WARN("fail to do pre split global index", K(ret), + K(db_name), K(data_table_schema), K(ori_index_table_schema), K(new_table_schema)); + } + } else { + // 1. alter main table + // 2. rebuild global index partition/ none partition table, ddl_type will be DDL_CREATE_INDEX + bool need_pre_split = false; + bool is_global_index = new_table_schema.is_global_local_index_table() || new_table_schema.is_global_index_table(); + if (is_global_index && ddl_type == DDL_CREATE_INDEX) { + need_pre_split = true; + } else if (OB_FALSE_IT(need_pre_split = is_supported_pre_split_ddl_type(ddl_type))) { + LOG_WARN("[PRE_SPLIT] fail to check need pre split partition", K(ret), K(ddl_type), K(new_table_schema)); + } + if (!need_pre_split) { + // do nothing + LOG_INFO("[PRE_SPLIT] no need to do pre split type", K(ddl_type), K(new_table_schema)); + } else if (OB_FAIL(do_pre_split_main_table(db_name, ori_table_schema, new_table_schema))) { + LOG_WARN("fail to do pre split global index", K(ret), + K(db_name), K(ori_table_schema), K(new_table_schema)); + } + } + return ret; +} + +/* + description: + 1. create index global (partition or not partition table) + 2. alter table add index global (partition or not partition table) +*/ +int ObPartitionPreSplit::do_pre_split_global_index( + const ObString &db_name, + const ObTableSchema &data_table_schema, + const ObTableSchema &ori_index_schema, + ObTableSchema &new_index_schema) +{ + int ret = OB_SUCCESS; + ObTableSchema inc_partition_schema; + ObArray tablets_size_array; + ObTabletID source_tablet_id(OB_INVALID_ID); + int64_t physical_size = 0; + int64_t data_table_physical_size = 0; + int64_t split_num = 0; + int64_t split_size = new_index_schema.get_part_option().get_auto_part_size(); + const int64_t tenant_id = new_index_schema.get_tenant_id(); + const bool need_generate_part_name = true; +#ifdef ERRSIM + split_size = 30; +#endif + DEBUG_SYNC(START_DDL_PRE_SPLIT_PARTITION); + if (OB_FAIL(get_estimated_table_size(data_table_schema, new_index_schema, physical_size))) { // estimate global index table size + LOG_WARN("[PRE_SPLIT] fail to get create table size", K(ret), K(new_index_schema)); + } else if (OB_FAIL(get_exist_table_size(data_table_schema, tablets_size_array))) { // get data table size + LOG_WARN("[PRE_SPLIT] fail to get data table size", K(ret), K(data_table_schema)); + } + if (OB_SUCC(ret)) { + // calculate data table size. + for (int64_t i = 0; i < tablets_size_array.count(); ++i) { + data_table_physical_size += tablets_size_array[i].second; + } + } + LOG_DEBUG("[PRE_SPLIT] size for create global index", + K(ret), K(split_size), K(data_table_physical_size), K(physical_size), K(tablets_size_array)); + + if (OB_FAIL(ret)) { + } else if (FALSE_IT(get_split_num(physical_size, split_size, split_num))) { + } else if (split_num < 2) { + // do nothing + LOG_DEBUG("[PRE_SPLIT] tablet physical size no reach split limited, no need to split", + K(physical_size), K(split_size), K(split_num), K(tablets_size_array)); + } else if (OB_FAIL(build_global_index_pre_split_ranges( // none partition table, partition key should be rowkey + tenant_id, + data_table_physical_size, + split_num, + db_name, + new_index_schema, + data_table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build pre split ranges", + K(ret), K(source_tablet_id), K(tenant_id), K(physical_size)); + } else if (OB_FAIL(build_split_tablet_partition_schema( + tenant_id, + source_tablet_id, + need_generate_part_name, + inc_partition_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build one split tablet part schema", K(ret), K(tenant_id), K(source_tablet_id)); + } else if (OB_FAIL(build_new_table_schema( + ori_index_schema, + inc_partition_schema, + new_index_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build new table schema", K(ret), K(inc_partition_schema)); + } + return ret; +} +/* + description: + 1. alter main table + 2. rebuild global index partition/ none partition table, ddl_type will be DDL_CREATE_INDEX +*/ +int ObPartitionPreSplit::do_pre_split_main_table( + const ObString &db_name, + const ObTableSchema &ori_table_schema, + ObTableSchema &new_table_schema) +{ + int ret = OB_SUCCESS; + const int64_t tenant_id = new_table_schema.get_tenant_id(); + int64_t split_size = new_table_schema.get_part_option().get_auto_part_size(); +#ifdef ERRSIM + split_size = 200; +#endif + DEBUG_SYNC(START_DDL_PRE_SPLIT_PARTITION); + if (OB_FAIL(build_table_pre_split_schema( + tenant_id, + split_size, + db_name, + ori_table_schema, + new_table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build split table schema", K(ret), + K(tenant_id), K(ori_table_schema), K(new_table_schema)); + } + LOG_DEBUG("[PRE_SPLIT] finish do pre split", K(ret), K(ori_table_schema), K(new_table_schema)); + return ret; +} + +/* + function description: + constraint check: + 1. should be range partition and partition level > 0, or table is auto split partition table (auto split partition table / auto split none partition table) + 2. not support interval partition + 3. not support none user table/global index + 4. partition key is prefix of rowkey +*/ +int ObPartitionPreSplit::check_table_can_do_pre_split( + const ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + const ObPartitionOption &part_option = table_schema.get_part_option(); + const bool is_user_table = table_schema.is_user_table(); + const bool is_global_index_table = + table_schema.is_global_local_index_table() || table_schema.is_global_index_table(); + + if (OB_UNLIKELY(table_schema.is_heap_table())) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("[PRE_SPLIT] not support heap table", K(ret), K(table_schema)); + } else if (OB_UNLIKELY(!is_user_table && !is_global_index_table)) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("[PRE_SPLIT] not support none user table/global index", K(ret), K(is_user_table), K(is_global_index_table)); + } else if (table_schema.get_part_level() > PARTITION_LEVEL_ONE) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("[PRE_SPLIT] not support part level > 1 currently", K(ret), K(table_schema.get_part_level())); + } else if (part_option.is_interval_part()) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("[PRE_SPLIT] not support interval partition", K(ret), K(part_option)); + } else if (!part_option.is_range_part()) { // partiton by range/range columns type + if (is_global_index_table && part_option.is_hash_part()) { + /* case: create index idx1 on t1(c1), default partition type is hash */ + LOG_INFO("[pre_split] support global index table without partition by", K(part_option)); + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("[PRE_SPLIT] not support none range partition table", K(ret), K(part_option)); + } + } + if (OB_SUCC(ret)) { + // if user/global table is auto split table, partition level may be zero but partition key not null + // like: + // 1. alter table xxx partition by range(xxx) size(), partition key should be include in rowkey + // 2. alter table xxx partition by range() size(), partition key is rowkey by default. + // For these two scenarios of altering automatic partition properties, the preceding RS has already performed the verification, + // so it's unnecessary to check the primary key prefix again here. + // but the following case should be checked, like: + // 3. alter table t1 partition by range(xxx) (partitions...) + // 4. alter table t1 add index idx1(xxx) partition by range(xxx) (partitions...) + // For scenarios involving modifying the main table partition or creating an index table partition, + // it is necessary to verify whether the partition key is a prefix of the primary key. + bool is_prefix = true; + if (table_schema.is_partitioned_table() && + OB_FAIL(table_schema.is_partition_key_match_rowkey_prefix(is_prefix))) { + LOG_WARN("[PRE_SPLIT] fail to check partition key match prefix rowkey", K(ret)); + } else if (!is_prefix) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("[PRE_SPLIT] partition key not prefix of rowkey is not support", K(ret)); + } + } + LOG_WARN("[PRE_SPLIT] table is partition", K(table_schema.is_partitioned_table())); + return ret; +} + +int ObPartitionPreSplit::generate_tablet_and_part_id(ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(ddl_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid ddl service", K(ret), KP(ddl_service_)); + } else if (OB_FAIL(ddl_service_->generate_object_id_for_partition_schema(table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to generate object_id for partition schema", K(ret), K(table_schema)); + } else if (OB_FAIL(ddl_service_->generate_tablet_id(table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to fetch new table id", K(table_schema), K(ret)); + } + return ret; +} + +int ObPartitionPreSplit::build_table_pre_split_schema( + const int64_t tenant_id, + const int64_t split_size, + const ObString &db_name, + const ObTableSchema &ori_table_schema, + ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + ObArray tablet_size_array; + + if (OB_UNLIKELY(tenant_id == OB_INVALID_TENANT_ID || split_size <= 0 || db_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[PRE_SPLIT] invalid argument.", K(ret), K(tenant_id), K(split_size), K(db_name)); + } else if (OB_FAIL(get_exist_table_size(ori_table_schema, tablet_size_array))) { + LOG_WARN("[PRE_SPLIT] fail to get exist table size.", K(ret), K(ori_table_schema)); + } else if (tablet_size_array.count() <= 0) { + // do nothing + } else { + HEAP_VAR(ObTableSchema, inc_partition_schema) { + HEAP_VAR(ObTableSchema, all_partition_schema) { + ObArray split_tablet_ids; + int64_t split_num = 0; + bool has_modify_partition_rule = false; + + if (OB_FAIL(check_is_modify_partition_rule(table_schema, ori_table_schema, has_modify_partition_rule))) { + LOG_WARN("[PRE_SPLIT] fail to check modify partition rule", K(ret)); + // 1. pre split all table partitions + } else if (has_modify_partition_rule) { + const bool need_generate_part_name = true; + int64_t data_table_phycical_size = 0; + ObTabletID split_source_id(OB_INVALID_ID); + for (int64_t i = 0; i < tablet_size_array.count(); ++i) { + data_table_phycical_size += tablet_size_array[i].second; + } + ObSplitSampler range_builder; + ObArray tmp_ranges; + ObArray part_columns_range; + ObArray part_columns_name; + ObRowkey src_l_bound_val; + ObRowkey src_h_bound_val; + ObObj obj_l_buf[OB_MAX_ROWKEY_COLUMN_NUMBER]; + ObObj obj_h_buf[OB_MAX_ROWKEY_COLUMN_NUMBER]; + + if (FALSE_IT(get_split_num(data_table_phycical_size, split_size, split_num))) { + } else if (split_num < 2) { + LOG_DEBUG("[PRE_SPLIT] tablet physical size no reach split limited, no need to split", + K(data_table_phycical_size), K(split_size), K(split_num)); + } else if (OB_FAIL(get_partition_columns_name(table_schema, part_columns_name))) { + LOG_WARN("[PRE_SPLIT] fail to get partition columns name", K(ret)); + } else if (OB_FAIL(get_partition_columns_range(table_schema, part_columns_name.count(), part_columns_range))) { + LOG_WARN("[PRE_SPLIT] fail to get partition ranges", K(ret)); + } else if (OB_FAIL(range_builder.query_ranges(tenant_id, db_name, ori_table_schema, + part_columns_name, + part_columns_range, + split_num, + data_table_phycical_size, + allocator_, + tmp_ranges))) { + LOG_WARN("[PRE_SPLIT] fail to query ranges", K(ret), K(part_columns_name), K(part_columns_range)); + } else if (OB_FAIL(get_table_partition_bounder(table_schema, part_columns_name.size(), + src_l_bound_val, src_h_bound_val, obj_l_buf, obj_h_buf))) { + } else if (OB_FAIL(check_and_get_split_range( + src_l_bound_val, src_h_bound_val, part_columns_name.size(), tmp_ranges))) { + LOG_WARN("[PRE_SPLIT] fail to check split range.", K(ret), K(tmp_ranges)); + } else if (OB_FAIL(build_split_tablet_partition_schema( + tenant_id, + split_source_id, + need_generate_part_name, + inc_partition_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build one split tablet part schema", K(ret), K(tenant_id)); + } + LOG_DEBUG("[PRE_SPLIT] pre split info", + K(ret), K(data_table_phycical_size), K(split_size), K(split_num), K(tmp_ranges)); + } else { + const bool need_generate_part_name = false; + // 2. pre split every single tablet + for (int64_t i = 0; OB_SUCC(ret) && i < tablet_size_array.count(); ++i) { + const ObTabletID &tablet_id = tablet_size_array[i].first; + const uint64_t physical_size = tablet_size_array[i].second; + if (FALSE_IT(get_split_num(physical_size, split_size, split_num))) { + } else if (split_num < 2) { // do nothing + LOG_DEBUG("[PRE_SPLIT] tablet physical size no reach split limited, no need to split", + K(tablet_id), K(physical_size), K(split_num)); + } else if (!tablet_id.is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid tablet id.", K(ret), K(tablet_id)); + } else if (OB_FAIL(build_tablet_pre_split_ranges( + tenant_id, + physical_size, + split_num, + tablet_id, + db_name, + ori_table_schema, + table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build pre split ranges", + K(ret), K(tablet_id), K(tenant_id), K(physical_size)); + } else if (OB_FAIL(build_split_tablet_partition_schema( + tenant_id, + tablet_id, + need_generate_part_name, + inc_partition_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build one split tablet part schema", K(ret), K(tenant_id), K(tablet_id)); + } else if (split_ranges_.count() > 0 && OB_FAIL(split_tablet_ids.push_back(tablet_id))) { + LOG_WARN("[PRE_SPLIT] fail to push split tablet id to array", K(ret), K(tablet_id)); + } else { + LOG_DEBUG("[PRE_SPLIT] pre split info", + K(ret), K(tablet_id), K(physical_size), K(split_size), K(split_num), K(split_ranges_), K(inc_partition_schema)); + } + } + } + // generate new part id / part idx / tablet id ... + if (OB_SUCC(ret)) { + if (!ori_table_schema.is_partitioned_table() || has_modify_partition_rule) { + // 1. alter main none partition table or rebuild global index none partition table + // 2. modify partition rule, we have to rebuild all partition schema + if (OB_FAIL(build_new_partition_table_schema( + ori_table_schema, + inc_partition_schema, + table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build new index table schema.", K(ret), K(table_schema)); + } + } else { + if (OB_FAIL(rebuild_partition_table_schema( + // 1. alter main partition table or rebuild global index partition table + split_tablet_ids, + ori_table_schema, + inc_partition_schema, + all_partition_schema, + table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to fill full tablet partition schema", + K(ret), K(ori_table_schema), K(inc_partition_schema)); + } + } + } + } + } + } + + return ret; +} +/* +function description: + 1. merge old part and inc part + 2. generate all partition new sort part idx. + 3. generate all parititon new part name + +ATTENTION!! + due to part_idx is indicated sort order of val of all partitions, like part idx 0 high bound is + part idx 1 low bound and so on : + + |-- part idx0 --|---part idx 1 --|-- part idx 2 --| + low0 high0/low1 high1/low2 high2 + + so part idx should be keep in order even thought there are have be splited. + for example, if we have three partitions like partition a/b/c, part idx is 1/2/3,if partition b split into + two partition like b1 and b2,and b1 range is smaller than b2, than the part idx after pre-split + should be like : a->1, b1->2, b2->3, c->4 +*/ +int ObPartitionPreSplit::generate_all_partition_schema( + const ObIArray &split_tablet_ids, + const ObTableSchema &ori_table_schema, + const ObPartitionSchema &inc_partition_schema, + ObPartitionSchema &all_partition_schema) +{ + int ret = OB_SUCCESS; + + ObPartition **ori_part_array = ori_table_schema.get_part_array(); + ObPartition **inc_part_array = inc_partition_schema.get_part_array(); + int64_t ori_part_num = ori_table_schema.get_partition_num(); + int64_t inc_part_num = inc_partition_schema.get_partition_num(); + int64_t split_tablet_num = split_tablet_ids.count(); + int64_t all_part_num = ori_part_num + inc_part_num - split_tablet_num; + + if (OB_ISNULL(ori_part_array) || OB_ISNULL(inc_part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] part array is null", K(ret), K(ori_table_schema), K(inc_partition_schema)); + } else { + int64_t cur_part_idx = 0; + for (int64_t i = 0; OB_SUCC(ret) && i < ori_part_num && cur_part_idx < all_part_num; ++i) { // origin + ObPartition *ori_part = ori_part_array[i]; + if (OB_ISNULL(ori_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid partition.", K(ret), KP(ori_part)); + } else { + const ObTabletID &source_tablet_id = ori_part->get_tablet_id(); + // check this partition is in spliting + PartLowBound low_bound_array; + for (int64_t j = 0; OB_SUCC(ret) && j < inc_part_num; ++j) { // find split part of source_tablet_id + ObPartition *inc_part = inc_part_array[j]; + if (OB_ISNULL(inc_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid part", K(ret), KP(inc_part)); + } else if (source_tablet_id == inc_part->get_split_source_tablet_id()) { + const ObRowkey &low_bound_val = inc_part->get_low_bound_val(); + if (OB_FAIL(low_bound_array.push_back(std::pair(low_bound_val, inc_part)))) { + LOG_WARN("fail to push part to array", K(ret)); + } + } + } + if (OB_SUCC(ret)) { + if (low_bound_array.count() > 0) { // ori_part have been split + lib::ob_sort(low_bound_array.begin(), low_bound_array.end(), PartRangeCmpFunc()); // sort part + for (int64_t k = 0; OB_SUCC(ret) && k < low_bound_array.count(); ++k) { + ObPartition *part = low_bound_array.at(k).second; // inc partition + part->set_part_idx(cur_part_idx); + if (OB_FAIL(all_partition_schema.add_partition(*part))) { + LOG_WARN("[PRE_SPLIT] fail to add new partition", K(ret)); + } else { + cur_part_idx++; + } + } + } else { // ori_part not been split + ObPartition tmp_part; + if (OB_FAIL(tmp_part.assign(*ori_part))) { + LOG_WARN("[PRE_SPLIT] fail to assign original part", K(ret), K(cur_part_idx)); + } else if (FALSE_IT(tmp_part.set_part_idx(cur_part_idx))){ + } else if (FALSE_IT(tmp_part.set_is_empty_partition_name(true))) { // generate new name for not split part + } else if (OB_FAIL(all_partition_schema.add_partition(tmp_part))) { + LOG_WARN("[PRE_SPLIT] fail to add new partition", K(ret), K(tmp_part), K(cur_part_idx)); + } else { + cur_part_idx++; + } + } + } + } + } + // verify max part idx + if (OB_SUCC(ret)) { + if (cur_part_idx != all_part_num) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] fail to gen part idx, max part idx not equal to all part num", + K(ret), K(cur_part_idx), K(all_part_num), K(all_partition_schema)); + } else if (all_part_num != all_partition_schema.get_partition_num()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] fail to gen part idx, partition num not match", + K(ret), K(all_part_num), K(all_partition_schema)); + } + } + // generate all part name + if (OB_SUCC(ret)) { + if (OB_ISNULL(ddl_service_)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid ddl service", K(ret), KP(ddl_service_)); + } else if (OB_FAIL(ddl_service_->fill_part_name(ori_table_schema, all_partition_schema))) { + LOG_WARN("[PRE_SPLIT] fail to build split table schema", K(ret), K(all_partition_schema)); + } + } + } + + return ret; +} + +int ObPartitionPreSplit::get_and_set_part_column_info( + ObTableSchema &table_schema, + char *rowkey_column_buf, + int64_t &buf_pos, + int64_t &column_cnt) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(OB_ISNULL(rowkey_column_buf) || buf_pos != 0 )) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[PRE_SPLIT] invalid argument.", K(ret), K(rowkey_column_buf), K(buf_pos)); + } else { + column_cnt = 0; + int64_t part_key_pos = 0; + const ObRowkeyInfo &rowkey_info = table_schema.get_rowkey_info(); + for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_info.get_size(); i++) { + const ObRowkeyColumn *rowkey_column = rowkey_info.get_column(i); + const int64_t column_id = rowkey_column->column_id_; + ObColumnSchemaV2 *col_schema = nullptr; + if (OB_ISNULL(col_schema = table_schema.get_column_schema(column_id))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] col_schema is nullptr", K(ret), K(column_id), K(table_schema)); + } else if (table_schema.is_index_table() && col_schema->get_index_position() <= 0) { + // skip rowkey column from duplicate main table rowkey. + } else if (OB_FAIL(table_schema.add_partition_key(col_schema->get_column_name_str()))) { + LOG_WARN("[PRE_SPLIT] Failed to add partition key", K(ret), K(col_schema->get_column_name_str())); + } else { + const ObString &column_name = col_schema->get_column_name_str(); + if (column_name.empty()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] column name null, unexpected", K(ret), K(column_name)); + } else if (0 == i && OB_FAIL(databuff_printf( + rowkey_column_buf, + OB_MAX_SQL_LENGTH, + buf_pos, + "%.*s", + static_cast(column_name.length()), + column_name.ptr()))) { + LOG_WARN("[PRE_SPLIT] fail to printf rowkey_column_buf", K(ret), K(i), K(column_name)); + } else if (0 != i && OB_FAIL(databuff_printf( + rowkey_column_buf, + OB_MAX_SQL_LENGTH, + buf_pos, + ", %.*s", + static_cast(column_name.length()), + column_name.ptr()))) { + LOG_WARN("[PRE_SPLIT] fail to printf rowkey_column_buf", K(ret), K(i), K(column_name)); + } else { + column_cnt++; + } + } + } + } + return ret; +} + +/* + 预分裂后,因为会分裂为多个分区,new_table_schema 一定要填分区键 + 如果分区键是double/float等类型,需要把分区类型改成 range column +*/ +int ObPartitionPreSplit::build_new_table_schema( + const ObTableSchema &ori_table_schema, + ObPartitionSchema &partition_schema, + ObTableSchema &new_table_schema) +{ + int ret = OB_SUCCESS; + ObPartitionOption &part_option = partition_schema.get_part_option(); + const ObPartitionLevel ori_part_level = new_table_schema.get_part_level(); + const ObPartitionOption &ori_part_option = new_table_schema.get_part_option(); + const int64_t partition_num = partition_schema.get_partition_num(); + // origin table is not partition table. we should build new partition option + // including main table and global index table. + const bool need_to_modify_partition = partition_num > 0; + if (need_to_modify_partition) { + if (OB_FAIL(part_option.assign(ori_part_option))) { + LOG_WARN("[PRE_SPLIT] fail to assign part option", K(ret), K(ori_part_option)); + } else if (!ori_table_schema.is_partitioned_table()) { + if (!part_option.get_part_func_expr_str().empty()) { + // skip // part func expr is ready + } else { // extract partition func expr from new table + ObString part_func_expr_str; + char *rowkey_column_buf = nullptr; + int64_t rowkey_str_buf_len = 0; + int64_t actual_rowkey_column_cnt = 0; // rowkey column cnt expect duplicate main table rowkey + if (OB_ISNULL(rowkey_column_buf = static_cast(allocator_.alloc(OB_MAX_SQL_LENGTH)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("[PRE_SPLIT] fail to alloc new_part_func_expr", K(ret)); + } else if (OB_FAIL(get_and_set_part_column_info(new_table_schema, + rowkey_column_buf, + rowkey_str_buf_len, + actual_rowkey_column_cnt))) { + LOG_WARN("[PRE_SPLIT] fail to get rowkey column buf.", K(ret)); + } else if (FALSE_IT(part_func_expr_str.assign_ptr( + rowkey_column_buf, + static_cast(rowkey_str_buf_len)))) { + } else if (OB_FAIL(part_option.set_part_expr(part_func_expr_str))) { + LOG_WARN("[PRE_SPLIT] set part expr failed", K(ret), K(part_func_expr_str)); + } else { + ObPartitionFuncType part_type = actual_rowkey_column_cnt > 1 ? + PARTITION_FUNC_TYPE_RANGE_COLUMNS : + PARTITION_FUNC_TYPE_RANGE; + part_option.set_part_func_type(part_type); + } + } + if (OB_SUCC(ret)) { + partition_schema.set_part_level(PARTITION_LEVEL_ONE); + } + } else { // set ori partition level + partition_schema.set_part_level(ori_part_level); + } + if (OB_FAIL(ret)) { + } else if (FALSE_IT(part_option.set_part_num(partition_num))) { + } else if (OB_FAIL(new_table_schema.assign_partition_schema(partition_schema))) { // cover old + LOG_WARN("[PRE_SPLIT] fail to assign partition schema", K(ret), K(partition_schema)); + } else if (OB_FAIL(modify_partition_func_type_if_need(new_table_schema))) { + LOG_WARN("[PRE_SPLIT] fail to modify partition type", K(ret), K(new_table_schema)); + } + LOG_DEBUG("[PRE_SPLIT] build new schema finish", K(ori_table_schema), K(new_table_schema)); + } + return ret; +} + +/* + 如果分区键包含double等类型,需要把分区类型改成range column +*/ +int ObPartitionPreSplit::modify_partition_func_type_if_need(ObTableSchema &new_table_schema) +{ + int ret = OB_SUCCESS; + if (!new_table_schema.is_partitioned_table()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected, is should be partition table here", K(ret), K(new_table_schema)); + } else { + ObArray part_key_ids; + const ObPartitionKeyInfo &partition_keys = new_table_schema.get_partition_key_info(); + if (partition_keys.is_valid() && OB_FAIL(partition_keys.get_column_ids(part_key_ids))) { + LOG_WARN("fail to get column ids from partition keys", K(ret)); + } else { + const ObColumnSchemaV2 *column_schema = NULL; + ObPartitionFuncType part_type = part_key_ids.count() > 1 ? + PARTITION_FUNC_TYPE_RANGE_COLUMNS : + PARTITION_FUNC_TYPE_RANGE; + for (int64_t i = 0; OB_SUCC(ret) && part_type != PARTITION_FUNC_TYPE_RANGE_COLUMNS + && i < part_key_ids.count(); ++i) { + uint64_t part_key_id = part_key_ids.at(i); + if (part_key_id >= OB_MIN_SHADOW_COLUMN_ID || part_key_id < OB_APP_MIN_COLUMN_ID) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected part key id", K(ret), K(part_key_id)); + } else if (OB_FALSE_IT(column_schema = new_table_schema.get_column_schema(part_key_id))) { + } else if (OB_ISNULL(column_schema)) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("column schema not exist", K(ret), K(new_table_schema), K(part_key_id)); + } else { + ObObjType column_type = column_schema->get_data_type(); + if (ObResolverUtils::is_partition_range_column_type(column_type)) { + part_type = PARTITION_FUNC_TYPE_RANGE_COLUMNS; + new_table_schema.get_part_option().set_part_func_type(part_type); + } + } + } + } + } + return ret; +} + +int ObPartitionPreSplit::build_split_tablet_partition_schema( + const int64_t tenant_id, + const ObTabletID &source_tablet_id, + const bool need_generate_part_name, + ObPartitionSchema &inc_partition_schema) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(tenant_id == OB_INVALID_TENANT_ID)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[PRE_SPLIT] invalid argument", K(ret), K(tenant_id)); + } else if (split_ranges_.count() <= 0) { + // skip // empty split range + } else { + int64_t partition_count = split_ranges_.count(); + share::schema::ObPartition new_partition; + int64_t max_part_id = OB_MAX_PARTITION_NUM_MYSQL; + char part_name[OB_MAX_PARTITION_NAME_LENGTH]; + ObString part_name_str; + for (int64_t idx = 0; OB_SUCC(ret) && idx < partition_count; ++idx) { + const ObRowkey& low_bound_val = split_ranges_.at(idx).get_start_key(); + const ObRowkey& high_bound_val = split_ranges_.at(idx).get_end_key(); + if (low_bound_val > high_bound_val) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] fail to build split table schema", K(ret), K(low_bound_val), K(high_bound_val)); + } else if (OB_FAIL(new_partition.set_high_bound_val(high_bound_val))) { + LOG_WARN("[PRE_SPLIT] failed to set high_bound_val", K(ret)); + } else if (OB_FAIL(new_partition.set_low_bound_val(low_bound_val))) { + LOG_WARN("[PRE_SPLIT] failed to set low_bound_val", K(ret)); + } else { + new_partition.set_is_empty_partition_name(true); // generate new part name for split part + new_partition.set_tenant_id(tenant_id); + new_partition.set_split_source_tablet_id(source_tablet_id); + new_partition.set_partition_type(PartitionType::PARTITION_TYPE_NORMAL); + new_partition.set_part_idx(idx); // change later + if (need_generate_part_name) { + int64_t pos = 0; + if (OB_FAIL(databuff_printf(part_name, OB_MAX_PARTITION_NAME_LENGTH, pos, "P%ld", ++max_part_id))) { + LOG_WARN("failed to constrate partition name", K(ret), K(max_part_id)); + } else if (OB_FALSE_IT(part_name_str.assign(part_name, static_cast(pos)))) { + } else if (OB_FAIL(new_partition.set_part_name(part_name_str))) { + LOG_WARN("failed to set partition name", K(ret), K(part_name_str)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(inc_partition_schema.add_partition(new_partition))) { + LOG_WARN("[PRE_SPLIT] failed to add partition", K(ret), K(tenant_id), K(source_tablet_id)); + } + } + } + } + return ret; +} +/* + description: + 1. build index split range + Attention: + index_schema should be old index schema, because new index schema + has not been created in create index case +*/ +int ObPartitionPreSplit::build_global_index_pre_split_ranges( + const int64_t tenant_id, + const int64_t data_table_phycical_size, + const int64_t split_num, + const ObString &db_name, + const ObTableSchema &index_schema, + const ObTableSchema &table_schema) +{ + int ret = OB_SUCCESS; + split_ranges_.reset(); // reset range + if (OB_UNLIKELY(tenant_id == OB_INVALID_TENANT_ID + || data_table_phycical_size <= 0 + || split_num <= 0 + || db_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[PRE_SPLIT] invalid argument.", + K(ret), K(tenant_id), K(data_table_phycical_size), K(split_num), K(db_name)); + } else if (index_schema.get_data_table_id() != table_schema.get_table_id()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] table id not equal.", + K(ret), K(index_schema.get_data_table_id()), K(table_schema.get_table_id())); + } else { + ObSplitSampler range_builder; + ObArray tmp_ranges; + ObArray part_columns_range; + ObArray part_columns_name; + ObRowkey src_l_bound_val; + ObRowkey src_h_bound_val; + ObObj obj_l_buf[OB_MAX_ROWKEY_COLUMN_NUMBER]; + ObObj obj_h_buf[OB_MAX_ROWKEY_COLUMN_NUMBER]; + if (OB_FAIL(get_partition_columns_name(index_schema, part_columns_name))) { + LOG_WARN("[PRE_SPLIT] fail to get partition columns range", K(ret)); + } else if (OB_FAIL(get_partition_columns_range(index_schema, part_columns_name.count(), part_columns_range))) { + LOG_WARN("[PRE_SPLIT] fail to get partition ranges", K(ret)); + } else if (OB_FAIL(range_builder.query_ranges(tenant_id, db_name, table_schema, + part_columns_name, + part_columns_range, + split_num, + data_table_phycical_size, + allocator_, + tmp_ranges))) { + } else if (tmp_ranges.count() <= 0) { + // empty range, do nothing + } else if (OB_FAIL(get_table_partition_bounder(index_schema, part_columns_name.count(), + src_l_bound_val, src_h_bound_val, obj_l_buf, obj_h_buf))) { + LOG_WARN("[PRE_SPLIT] fail ti get table partition bounder", K(ret), K(table_schema)); + } else if (OB_FAIL(check_and_get_split_range( + src_l_bound_val, src_h_bound_val, part_columns_name.size(), tmp_ranges))) { + LOG_WARN("[PRE_SPLIT] fail to check split range.", K(ret), K(tmp_ranges)); + } + } + return ret; +} + +/* + 需要按照table_schema的分区范围,指定每个column的范围(table_schema的分区键可能有多列, + 并且最后一个分区的范围可能是[maxvalue, 100] 或者 [100, maxvalue]这种形式,需要考虑到。 +*/ +int ObPartitionPreSplit::get_partition_columns_range( + const ObTableSchema &table_schema, + const int64_t part_columns_cnt, + ObIArray &part_range) +{ + int ret = OB_SUCCESS; + ObArray orig_part_range; + if (table_schema.is_partitioned_table() + && OB_FAIL(get_partition_ranges(table_schema, orig_part_range))) { + LOG_WARN("fail to get partition ranges", K(ret), K(table_schema)); + } else if (orig_part_range.count() < 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected partition range", K(ret), K(table_schema)); + } + if (OB_SUCC(ret)) { + const int64_t ori_part_range_cnt = orig_part_range.count(); + for (int64_t i = 0; OB_SUCC(ret) && i < part_columns_cnt; ++i) { + const int64_t part_key_length = 1; + ObNewRange tmp_range; + ObRowkey low_key_bound; + ObRowkey high_key_bound; + if (ori_part_range_cnt > 0) { + ObNewRange &last_part_range = orig_part_range.at(ori_part_range_cnt - 1); + high_key_bound.assign(&last_part_range.end_key_.get_obj_ptr()[i], part_key_length); + } else { + high_key_bound.set_max_row(); + high_key_bound.set_length(part_key_length); + } + low_key_bound.set_min_row(); + low_key_bound.set_length(part_key_length); + tmp_range.start_key_ = low_key_bound; + tmp_range.end_key_ = high_key_bound; + tmp_range.border_flag_.set_inclusive_start(); + tmp_range.border_flag_.unset_inclusive_end(); + if (OB_FAIL(part_range.push_back(tmp_range))) { + LOG_WARN("[PRE_SPLIT] fail to push back part column range", K(ret)); + } + } + } + LOG_DEBUG("get partition columns range", K(ret), K(part_range)); + return ret; +} + +int ObPartitionPreSplit::get_partition_ranges( + const ObTableSchema &table_schema, + ObIArray &part_range) +{ + int ret = OB_SUCCESS; + ObPartition **part_array = table_schema.get_part_array(); + const int64_t partition_num = table_schema.get_partition_num(); + if (OB_ISNULL(part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] part array is null, not expected", K(ret), K(table_schema)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < partition_num; ++i) { // find split part of source_tablet_id + ObPartition *partition = part_array[i]; + if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid part", K(ret), KP(partition), K(table_schema)); + } else { + ObNewRange tmp_range; + tmp_range.start_key_ = partition->get_low_bound_val(); + tmp_range.end_key_ = partition->get_high_bound_val(); + if (OB_FAIL(part_range.push_back(tmp_range))) { + LOG_WARN("[PRE_SPLIT] fail to push back part range", K(ret), K(tmp_range), K(table_schema)); + } + } + } + } + return ret; +} +/* +description + 1. if partition column is double or float, dont not support yet +*/ +int ObPartitionPreSplit::get_partition_columns_name( + const ObTableSchema &table_schema, + ObIArray &part_columns) +{ + int ret = OB_SUCCESS; + uint64_t rowkey_col_id = OB_INVALID_ID; + part_columns.reset(); + + if (table_schema.get_part_option().get_part_func_expr_str().empty()) { + const common::ObRowkeyInfo &rowkey_info = table_schema.get_rowkey_info(); + const share::schema::ObColumnSchemaV2 *column_schema = NULL; + for (int64_t i = 0; OB_SUCC(ret) && i < rowkey_info.get_size(); ++i) { + if (OB_FAIL(rowkey_info.get_column_id(i, rowkey_col_id))) { + LOG_WARN("[PRE_SPLIT] failed to column id"); + } else if (rowkey_col_id >= OB_MIN_SHADOW_COLUMN_ID + || rowkey_col_id < OB_APP_MIN_COLUMN_ID) { + continue; + } else if (OB_ISNULL(column_schema = table_schema.get_column_schema(rowkey_col_id))) { + ret = OB_ENTRY_NOT_EXIST; + LOG_WARN("[PRE_SPLIT] column schema not exist", K(ret), K(table_schema), K(rowkey_col_id)); + } else if (table_schema.is_index_table() && column_schema->get_index_position() <= 0) { + // if table is index table, ignore duplicate rowkey from main table rowkey column + } else if (OB_FAIL(part_columns.push_back(column_schema->get_column_name_str()))) { + LOG_WARN("[PRE_SPLIT] failed to add string", K(ret)); + } + } + } else { + ObString tmp_part_func_expr = table_schema.get_part_option().get_part_func_expr_str(); + ObArray part_expr_strs; + if (OB_FAIL(split_on(tmp_part_func_expr, ',', part_expr_strs))) { + LOG_WARN("[PRE_SPLIT] fail to split func expr", K(ret), K(tmp_part_func_expr)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < part_expr_strs.count(); ++i) { + if (OB_FAIL(part_columns.push_back(part_expr_strs.at(i).trim()))) { + LOG_WARN("[PRE_SPLIT] fail to push back part func str.", K(ret), K(part_expr_strs)); + } + } + } + } + return ret; +} + +/* + 获取分区表的特定tablet的边界,需要保证预分裂时原表的分区规则没发生变更的情况下,才需要走这个函数。 +*/ +int ObPartitionPreSplit::get_partition_table_tablet_bounder( + const ObTableSchema &table_schema, + const ObTabletID &source_tablet_id, + ObRowkey &l_bound_val, + ObRowkey &h_bound_val) +{ + int ret = OB_SUCCESS; + ObPartition **part_array = table_schema.get_part_array(); + const int64_t partition_num = table_schema.get_partition_num(); + if (OB_ISNULL(part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] part array is null, not expected", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < partition_num; ++i) { // find split part of source_tablet_id + ObPartition *partition = part_array[i]; + if (OB_ISNULL(partition)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] invalid part", K(ret), KP(partition)); + } else if (source_tablet_id == partition->get_tablet_id()) { + if (partition->get_high_bound_val().is_valid()) { + h_bound_val = partition->get_high_bound_val(); + } + const int64_t part_idx = partition->get_part_idx(); + const int64_t subpart_idx = OB_INVALID_ID; + if (part_idx >= 1) { + ObBasePartition *last_part = NULL; + if (OB_FAIL(table_schema.get_part_by_idx(part_idx - 1, subpart_idx, last_part))) { + LOG_WARN("[PRE_SPLIT] fail to get part by idx", K(ret), K(part_idx)); + } else if (OB_ISNULL(last_part)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] fail to get part by idx, null pointer", K(ret), KP(last_part)); + } else if (!last_part->get_high_bound_val().is_valid()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] fail to get part by idx, invalid high bound", K(ret), KPC(last_part)); + } else { + l_bound_val = last_part->get_high_bound_val(); + } + } + } + } + } + return ret; +} + +/* + if ddl is modifing partition rules, we will redefinition partition based on the low and high limited user had set. + but the finial partition rules may be diff from user setting after pre-split +*/ +int ObPartitionPreSplit::check_is_modify_partition_rule( + const ObTableSchema &new_table_schema, + const ObTableSchema &old_table_schema, + bool &has_modify_partition_rule) +{ + int ret = OB_SUCCESS; + + has_modify_partition_rule = false; + ObArray new_part_names; + ObArray old_part_names; + ObArray new_part_ranges; + ObArray old_part_ranges; + if (!new_table_schema.is_partitioned_table()) { + // skip, only partition table should be check, new table is not partition table means not modifing partition rule + } else if (!old_table_schema.is_partitioned_table()) { + // ori table is auto split none partition table, and new table is auto split partition table, + // so is must be modified partition rule + has_modify_partition_rule = true; + } else if (OB_FAIL(get_partition_columns_name(new_table_schema, new_part_names))) { + LOG_WARN("[PRE_SPLIT] fail to get partition column name", K(ret)); + } else if (OB_FAIL(get_partition_columns_name(old_table_schema, old_part_names))) { + LOG_WARN("[PRE_SPLIT] fail to get partition column name", K(ret)); + } else if (OB_FAIL(get_partition_ranges(new_table_schema, new_part_ranges))) { + LOG_WARN("[PRE_SPLIT] fail to get partition range", K(ret)); + } else if (OB_FAIL(get_partition_ranges(old_table_schema, old_part_ranges))) { + LOG_WARN("[PRE_SPLIT] fail to get partition range", K(ret)); + } else { + // check modify partition rule + if (new_part_names.count() != old_part_names.count()) { + has_modify_partition_rule = true; + } else if (new_part_ranges.count() != old_part_ranges.count()) { + has_modify_partition_rule = true; + } else { + for (int64_t i = 0; !has_modify_partition_rule && i < new_part_ranges.count(); ++i) { + if (new_part_ranges.at(i).start_key_ != old_part_ranges.at(i).start_key_) { + has_modify_partition_rule = true; + } else if (new_part_ranges.at(i).end_key_ != old_part_ranges.at(i).end_key_) { + has_modify_partition_rule = true; + } + } + } + LOG_DEBUG("[PRE_SPLIT] check partition rule changed", + K(ret), K(has_modify_partition_rule), + K(old_part_names), K(new_part_names), K(old_part_ranges), K(new_part_ranges)); + } + return ret; +} +/* + function description: + get tablet split range, ensure every range is in order + Atention!!!! + 1. split range should be left close right open, like: [1, 10) + 2. as to auto split none partition table, range_builder.query_ranges should sample according to table primary key + 3. 采样时,如果此时new table schema 的分区键比 old table schema的分区键多,那么多出来的分区键的range,使用min_rowkey和max_rowkey填充,采样时会根据新分区键range范围采样过滤。 + 4. part_columns 和 part_columns_range 一一对应,采样会根据range过滤,如果不想采样过滤则填min和max +*/ +int ObPartitionPreSplit::build_tablet_pre_split_ranges( + const int64_t tenant_id, + const int64_t tablet_phycical_size, + const int64_t split_num, + const ObTabletID &source_tablet_id, + const ObString &db_name, + const ObTableSchema &old_table_schema, + const ObTableSchema &new_table_schema) +{ + int ret = OB_SUCCESS; + + ObSplitSampler range_builder; + ObArray tmp_ranges; + ObArray part_columns_name; + if (OB_UNLIKELY(tenant_id == OB_INVALID_TENANT_ID || tablet_phycical_size <= 0 + || split_num <= 0 + || !source_tablet_id.is_valid() + || db_name.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[PRE_SPLIT] invalid argument.", K(ret), K(tenant_id), + K(source_tablet_id), K(split_num), K(db_name), K(tablet_phycical_size)); + } else if (OB_FAIL(range_builder.query_ranges(tenant_id, db_name, old_table_schema, + source_tablet_id, + split_num, + tablet_phycical_size, + allocator_, + tmp_ranges))) { + LOG_WARN("[PRE_SPLIT] fail to get query ranges.", K(ret), K(tenant_id), K(source_tablet_id), K(old_table_schema)); + } else if (tmp_ranges.count() <= 0) { + // empty range, do nothing + LOG_DEBUG("[PRE_SPLIT] query ranges result is none, no need to split"); + } else if (OB_FAIL(get_partition_columns_name(new_table_schema, part_columns_name))) { + LOG_WARN("[PRE_SPLIT] fail to get rowkey column name.", K(ret), K(part_columns_name)); + } else { + /* if table is partition table, then get bounder. if not, regard bounder as min or max */ + ObRowkey src_l_bound_val; + ObRowkey src_h_bound_val; + ObObj obj_l_buf[OB_MAX_ROWKEY_COLUMN_NUMBER]; + ObObj obj_h_buf[OB_MAX_ROWKEY_COLUMN_NUMBER]; + if (old_table_schema.is_partitioned_table()) { + if (OB_FAIL(get_partition_table_tablet_bounder(old_table_schema, source_tablet_id, + src_l_bound_val, + src_h_bound_val))) { + LOG_WARN("[PRE_SPLIT] fail to get partition table tablet bounder", K(ret), K(source_tablet_id)); + } + } else { + if (OB_FAIL(get_table_partition_bounder(new_table_schema, part_columns_name.count(), + src_l_bound_val, src_h_bound_val, obj_l_buf, obj_h_buf))) { + LOG_WARN("[PRE_SPLIT] fail to get partition bounder", K(ret), K(new_table_schema)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(check_and_get_split_range( + src_l_bound_val, src_h_bound_val, part_columns_name.count(), tmp_ranges))) { + LOG_WARN("[PRE_SPLIT] fail to check and get split range.", + K(ret), K(tmp_ranges), K(src_l_bound_val), K(src_h_bound_val)); + } + } + return ret; +} + +/* + 获取表的分区上下限,如果表是分区表,则获取min和max,如果不是分区表,则按预分裂的分区键数量构造min和max。 +*/ +int ObPartitionPreSplit::get_table_partition_bounder( + const ObTableSchema &table_schema, + const int64_t part_key_length, + ObRowkey &src_l_bound_val, + ObRowkey &src_h_bound_val, + ObObj *obj_l_buf, + ObObj *obj_h_buf) +{ + int ret = OB_SUCCESS; + ObArray partition_ranges; + if (OB_ISNULL(obj_l_buf) || OB_ISNULL(obj_h_buf)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("[PRE_SPLIT] invalid argument", K(ret), KP(obj_l_buf), KP(obj_h_buf)); + } else if (table_schema.is_partitioned_table() && + OB_FAIL(get_partition_ranges(table_schema, partition_ranges))) { + LOG_WARN("[PRE_SPLIT] fail to get partition ranges", K(ret), K(table_schema)); + } else if (partition_ranges.count() > 0) { + src_l_bound_val = partition_ranges[partition_ranges.count()-1].start_key_; + src_h_bound_val = partition_ranges[partition_ranges.count()-1].end_key_; + } else { + for (int64_t i = 0; i < part_key_length; ++i) { + ObObj tmp_l_buf; + ObObj tmp_h_buf; + tmp_l_buf.set_min_value(); + tmp_h_buf.set_max_value(); + obj_l_buf[i] = tmp_l_buf; + obj_h_buf[i] = tmp_h_buf; + } + src_l_bound_val.assign(obj_l_buf, part_key_length); + src_h_bound_val.assign(obj_h_buf, part_key_length); + } + return ret; +} + +/* + 1. 需要考虑每个ranges之间除了首尾之外没有交集 + 2. 需要确认每个range是否只有一个high bound val,如果这种场景则需要保证tmp_split_ranges的range是有序递增的。 +*/ +int ObPartitionPreSplit::check_and_get_split_range( + const ObRowkey &src_l_bound_val, + const ObRowkey &src_h_bound_val, + const int64_t part_key_length, + ObIArray &tmp_split_ranges) +{ + int ret = OB_SUCCESS; + split_ranges_.reset(); // reset range + + for (int64_t idx = 0; OB_SUCC(ret) && idx < tmp_split_ranges.count(); ++idx) { + ObNewRange &tmp_range = tmp_split_ranges.at(idx); + const ObRowkey& l_bound_val = tmp_range.get_start_key(); + const ObRowkey& h_bound_val = tmp_range.get_end_key(); + if (l_bound_val > h_bound_val) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] fail to check and get split range, invalid split range", + K(ret), K(l_bound_val), K(h_bound_val)); + } else if ((l_bound_val.is_valid() && src_l_bound_val.is_valid() && l_bound_val < src_l_bound_val) + || (h_bound_val.is_valid() && src_h_bound_val.is_valid() && h_bound_val > src_h_bound_val)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("[PRE_SPLIT] fail to check and get split range, out of source range.", + K(ret), + K(l_bound_val), K(h_bound_val), + K(src_l_bound_val), K(src_h_bound_val)); + } else { + // ensure that there is no intersection between the two ranges except the beginning and the end + for (int64_t next_idx = idx + 1; OB_SUCC(ret) && next_idx < tmp_split_ranges.count(); ++next_idx) { + const ObNewRange &tmp_next_range = tmp_split_ranges.at(next_idx); + const ObRowkey& next_l_bound_val = tmp_next_range.get_start_key(); + const ObRowkey& next_h_bound_val = tmp_next_range.get_end_key(); + if (l_bound_val >= next_h_bound_val || h_bound_val <= next_l_bound_val) { + continue; // is vaild range + } + ret = OB_ERR_UNEXPECTED; // invalid range + LOG_WARN("[PRE_SPLIT] fail to check split range, ranges is illegal", K(ret), + K(l_bound_val), K(h_bound_val), + K(next_l_bound_val), K(next_h_bound_val)); + } + if (OB_SUCC(ret)) { + if (OB_FAIL(split_ranges_.push_back(tmp_split_ranges.at(idx)))) { + LOG_WARN("[PRE_SPLIT] fail to push back range to split range array", K(ret)); + } + } + } + } + return ret; +} + +} // end oceanbase +} // end storage diff --git a/src/storage/ob_partition_pre_split.h b/src/storage/ob_partition_pre_split.h new file mode 100644 index 000000000..21c2ab99e --- /dev/null +++ b/src/storage/ob_partition_pre_split.h @@ -0,0 +1,219 @@ +/** + * 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_PARTITION_PRE_SPLIT_H +#define OB_PARTITION_PRE_SPLIT_H + +#include "lib/string/ob_string.h" +#include "share/ob_rpc_struct.h" +#include "share/ob_ddl_common.h" +#include "share/schema/ob_table_schema.h" +#include "common/ob_range.h" +#include "lib/container/ob_array.h" +#include "rootserver/ob_ddl_service.h" + + +namespace oceanbase +{ +namespace rootserver +{ +class ObDDLService; +} +namespace storage +{ +class ObPartitionPreSplit final +{ +public: + typedef std::pair TabletIDSize; + const static int MAX_SPLIT_RANGE_NUM = 128; + +public: + explicit ObPartitionPreSplit(rootserver::ObDDLService &ddl_service); + ObPartitionPreSplit(); + ~ObPartitionPreSplit() = default; + void reset(); + + int get_global_index_pre_split_schema_if_need( + const int64_t tenant_id, + const int64_t session_id, + const ObString &database_name, + const ObString &table_name, + common::ObIArray &index_arg_list); + + int do_table_pre_split_if_need( + const ObString &db_name, + const ObDDLType ddl_type, + const bool is_building_global_index, + const ObTableSchema &data_table_schema, + const ObTableSchema &ori_table_schema, + ObTableSchema &new_table_schema); + +private: + void get_split_num( + const int64_t tablet_size, + const int64_t split_size, + int64_t &split_num); + + int do_pre_split_main_table( + const ObString &db_name, + const ObTableSchema &ori_table_schema, + ObTableSchema &new_table_schema); + + int do_pre_split_global_index( + const ObString &db_name, + const ObTableSchema &data_table_schema, + const ObTableSchema &ori_index_schema, + ObTableSchema &new_index_schema); + + int generate_tablet_and_part_id(ObTableSchema &new_table_schema); + int check_table_can_do_pre_split(const ObTableSchema &ori_table_schema); + + int build_tablet_pre_split_ranges( + const int64_t tenant_id, + const int64_t tablet_phycical_size, + const int64_t split_num, + const ObTabletID &tablet_id, + const ObString &db_name, + const ObTableSchema &old_table_schema, + const ObTableSchema &new_table_schema); + + int build_global_index_pre_split_ranges( + const int64_t tenant_id, + const int64_t data_table_phycical_size, + const int64_t split_num, + const ObString &db_name, + const ObTableSchema &index_schema, + const ObTableSchema &table_schema); + + int build_split_tablet_partition_schema( + const int64_t tenant_id, + const ObTabletID &source_tablet_id, + const bool need_generate_part_name, + ObPartitionSchema &new_partition_schema); + + int build_table_pre_split_schema( + const int64_t tenant_id, + const int64_t split_size, + const ObString &db_name, + const ObTableSchema &ori_table_schema, + ObTableSchema &table_schema); + + int generate_all_partition_schema( + const ObIArray &split_tablet_ids, + const ObTableSchema &ori_table_schema, + const ObPartitionSchema &inc_partition_schema, + ObPartitionSchema &all_partition_schema); + + int rebuild_partition_table_schema( + const ObIArray &split_tablet_ids, + const ObTableSchema &ori_table_schema, + const ObTableSchema &inc_partition_schema, + ObTableSchema &all_partition_schema, + ObTableSchema &table_schema); + + int build_new_partition_table_schema( + const ObTableSchema &ori_table_schema, + ObTableSchema &inc_partition_schema, + ObTableSchema &new_table_schema); + + int build_new_table_schema( + const ObTableSchema &ori_table_schema, + ObPartitionSchema &partition_schema, + ObTableSchema &new_table_schema); + + int get_and_set_part_column_info( + ObTableSchema &table_schema, + char *rowkey_column_buf, + int64_t &buf_pos, + int64_t &column_cnt); + + int extract_table_columns_id( + const ObTableSchema &table_schema, + ObIArray &column_ids); + + int get_data_table_part_ids( + const ObTableSchema &data_table_schema, + ObIArray &part_ids); + + int get_estimated_table_size( + const ObTableSchema &data_table_schema, + const ObTableSchema &index_table_schema, + int64_t &table_size); + + int get_exist_table_size( + const ObTableSchema &table_schema, + ObIArray &tablet_size); + + int get_table_partition_bounder( + const ObTableSchema &table_schema, + const int64_t part_key_length, + ObRowkey &src_l_bound_val, + ObRowkey &src_h_bound_val, + ObObj *obj_l_buf, + ObObj *obj_h_buf); + int check_and_get_split_range( + const ObRowkey &src_low_bound_val, + const ObRowkey &src_high_bound_val, + const int64_t part_key_length, + ObIArray &tmp_split_ranges); + + int get_partition_table_tablet_bounder( + const ObTableSchema &table_schema, + const ObTabletID &source_tablet_id, + ObRowkey &low_bound_val, + ObRowkey &high_bound_val); + + int get_partition_columns_name( + const ObTableSchema &table_schema, + ObIArray &rowkey_columns); + + int get_partition_ranges( + const ObTableSchema &table_schema, + ObIArray &part_range); + + int get_partition_columns_range( + const ObTableSchema &table_schema, + const int64_t part_columns_cnt, + ObIArray &part_range); + + int check_is_modify_partition_rule( + const ObTableSchema &new_table_schema, + const ObTableSchema &old_table_schema, + bool &has_modify_partition_rule); + + int modify_partition_func_type_if_need(ObTableSchema &new_table_schema); + +private: + typedef common::ObArray > PartLowBound; + class PartRangeCmpFunc + { + public: + PartRangeCmpFunc() {} + ~PartRangeCmpFunc() {} + + bool operator()(const std::pair &left, + const std::pair &right) const + { + return left.first < right.first; + } + }; + +private: + rootserver::ObDDLService *ddl_service_; + common::ObArenaAllocator allocator_; // use as ranges allocator + ObArray split_ranges_; +}; + +} +} + +#endif diff --git a/src/storage/ob_storage_struct.cpp b/src/storage/ob_storage_struct.cpp index db068f066..8a5595e14 100644 --- a/src/storage/ob_storage_struct.cpp +++ b/src/storage/ob_storage_struct.cpp @@ -591,6 +591,7 @@ ObBatchUpdateTableStoreParam::ObBatchUpdateTableStoreParam() start_scn_(SCN::min_scn()), tablet_meta_(nullptr), restore_status_(ObTabletRestoreStatus::FULL), + tablet_split_param_(), need_replace_remote_sstable_(false) { } @@ -603,6 +604,7 @@ void ObBatchUpdateTableStoreParam::reset() start_scn_.set_min(); tablet_meta_ = nullptr; restore_status_ = ObTabletRestoreStatus::FULL; + tablet_split_param_.reset(); need_replace_remote_sstable_ = false; } @@ -658,6 +660,31 @@ int ObBatchUpdateTableStoreParam::get_max_clog_checkpoint_scn(SCN &clog_checkpoi return ret; } +ObSplitTableStoreParam::ObSplitTableStoreParam() + : snapshot_version_(-1), + multi_version_start_(-1), + update_with_major_tables_(false) +{ +} + +ObSplitTableStoreParam::~ObSplitTableStoreParam() +{ + reset(); +} + +bool ObSplitTableStoreParam::is_valid() const +{ + return snapshot_version_ > -1 + && multi_version_start_ >= 0; +} + +void ObSplitTableStoreParam::reset() +{ + snapshot_version_ = -1; + multi_version_start_ = -1; + update_with_major_tables_ = false; +} + ObPartitionReadableInfo::ObPartitionReadableInfo() : min_log_service_ts_(0), min_trans_service_ts_(0), @@ -697,6 +724,51 @@ void ObPartitionReadableInfo::reset() force_ = false; } +ObTabletSplitTscInfo::ObTabletSplitTscInfo() + : start_partkey_(), + end_partkey_(), + src_tablet_handle_(), + split_cnt_(0), + split_type_(ObTabletSplitType::MAX_TYPE), + partkey_is_rowkey_prefix_(false) +{ +} + +bool ObTabletSplitTscInfo::is_valid() const +{ + return start_partkey_.is_valid() + && end_partkey_.is_valid() + && src_tablet_handle_.is_valid() + && split_type_ < ObTabletSplitType::MAX_TYPE; +} + +void ObTabletSplitTscInfo::reset() +{ + start_partkey_.reset(); + end_partkey_.reset(); + src_tablet_handle_.reset(); + split_type_ = ObTabletSplitType::MAX_TYPE; + split_cnt_ = 0; + partkey_is_rowkey_prefix_ = false; +} + +int ObTabletSplitTscInfo::assign(const ObTabletSplitTscInfo ¶m) +{ + int ret = OB_SUCCESS; + if (!param.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(param)); + } else { + start_partkey_ = param.start_partkey_; + end_partkey_ = param.end_partkey_; + src_tablet_handle_ = param.src_tablet_handle_; + split_type_ = param.split_type_; + split_cnt_ = param.split_cnt_; + partkey_is_rowkey_prefix_ = param.partkey_is_rowkey_prefix_; + } + return ret; +} + int ObCreateSSTableParamExtraInfo::assign(const ObCreateSSTableParamExtraInfo &other) { int ret = OB_SUCCESS; diff --git a/src/storage/ob_storage_struct.h b/src/storage/ob_storage_struct.h index 4cb024942..8fc47513d 100644 --- a/src/storage/ob_storage_struct.h +++ b/src/storage/ob_storage_struct.h @@ -29,6 +29,7 @@ #include "storage/ddl/ob_ddl_struct.h" #include "storage/high_availability/ob_tablet_ha_status.h" #include "storage/blocksstable/ob_major_checksum_info.h" +#include "storage/meta_mem/ob_tablet_handle.h" namespace oceanbase { @@ -469,6 +470,23 @@ struct ObUpdateTableStoreParam const blocksstable::ObSSTable *sstable_; bool allow_duplicate_sstable_; UpdateUpperTransParam upper_trans_param_; // set upper_trans_param_ only when update upper_trans_version + bool need_replace_remote_sstable_; +}; + +struct ObSplitTableStoreParam final +{ +public: + ObSplitTableStoreParam(); + ~ObSplitTableStoreParam(); + bool is_valid() const; + void reset(); + TO_STRING_KV(K_(snapshot_version), K_(multi_version_start), K_(update_with_major_tables)); + +public: + int64_t snapshot_version_; + int64_t multi_version_start_; + bool update_with_major_tables_; + bool need_replace_remote_sstable_; // only true for restore replace sstable. }; struct ObBatchUpdateTableStoreParam final @@ -481,7 +499,7 @@ struct ObBatchUpdateTableStoreParam final int get_max_clog_checkpoint_scn(share::SCN &clog_checkpoint_scn) const; TO_STRING_KV(K_(tables_handle), K_(rebuild_seq), K_(is_transfer_replace), - K_(start_scn), KP_(tablet_meta), K_(restore_status), K_(need_replace_remote_sstable)); + K_(start_scn), KP_(tablet_meta), K_(restore_status), K_(tablet_split_param), K_(need_replace_remote_sstable)); ObTablesHandleArray tables_handle_; #ifdef ERRSIM @@ -492,6 +510,7 @@ struct ObBatchUpdateTableStoreParam final share::SCN start_scn_; const ObMigrationTabletParam *tablet_meta_; ObTabletRestoreStatus::STATUS restore_status_; + ObSplitTableStoreParam tablet_split_param_; bool need_replace_remote_sstable_; DISALLOW_COPY_AND_ASSIGN(ObBatchUpdateTableStoreParam); @@ -600,6 +619,35 @@ private: }; +enum class ObTabletSplitType : int64_t { + RANGE, + NONE_RANGE, + MAX_TYPE, +}; + +struct ObTabletSplitTscInfo final +{ +public: + ObTabletSplitTscInfo(); + ~ObTabletSplitTscInfo() = default; + + bool is_valid() const; + void reset(); + int assign(const ObTabletSplitTscInfo ¶m); + + TO_STRING_KV(K_(start_partkey), + K_(end_partkey), K_(src_tablet_handle), K_(split_type), K_(split_cnt), K_(partkey_is_rowkey_prefix)); + +public: + blocksstable::ObDatumRowkey start_partkey_; + blocksstable::ObDatumRowkey end_partkey_; + ObTabletHandle src_tablet_handle_; + int64_t split_cnt_; + ObTabletSplitType split_type_; + bool partkey_is_rowkey_prefix_; +}; + + class ObBackupRestoreTableSchemaChecker { public: diff --git a/src/storage/ob_storage_table_guard.cpp b/src/storage/ob_storage_table_guard.cpp index 20ea22139..dddffe0f8 100644 --- a/src/storage/ob_storage_table_guard.cpp +++ b/src/storage/ob_storage_table_guard.cpp @@ -128,7 +128,9 @@ int ObStorageTableGuard::refresh_and_protect_memtable_for_write(ObRelativeTable // snapshot_for_tables filters the tables during get_read_tables store_ctx_.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), iter, - relative_table.allow_not_ready()))) { + relative_table.allow_not_ready(), + true/*need_split_src_table*/, + false/*need_split_dst_table*/))) { LOG_WARN("fail to get read tables", K(ret), K(ls_id), K(remain_timeout), "table_id", relative_table.get_table_id()); } else { diff --git a/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp b/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp index c539ab8c5..234591ba4 100644 --- a/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp +++ b/src/storage/ob_tablet_autoinc_seq_rpc_handler.cpp @@ -30,12 +30,13 @@ namespace storage // ObSyncTabletSeqReplayExecutor ObSyncTabletSeqReplayExecutor::ObSyncTabletSeqReplayExecutor() - : ObTabletReplayExecutor(), seq_(0), scn_() + : ObTabletReplayExecutor(), seq_(0), is_tablet_creating_(false), scn_() { } int ObSyncTabletSeqReplayExecutor::init( const uint64_t autoinc_seq, + const bool is_tablet_creating, const SCN &replay_scn) { int ret = OB_SUCCESS; @@ -48,6 +49,7 @@ int ObSyncTabletSeqReplayExecutor::init( LOG_WARN("invalid arguments", K(autoinc_seq), K(replay_scn), K(ret)); } else { seq_ = autoinc_seq; + is_tablet_creating_ = is_tablet_creating; scn_ = replay_scn; is_inited_ = true; } @@ -151,6 +153,7 @@ int ObTabletAutoincSeqRpcHandler::fetch_tablet_autoinc_seq_cache( LOG_WARN("get ls failed", K(ret), K(ls_id)); } else if (OB_FAIL(ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle, THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : obrpc::ObRpcProxy::MAX_RPC_TIMEOUT))) { LOG_WARN("failed to get tablet", KR(ret), K(arg)); + // TODO(lihongqin.lhq): fetch from split dst to avoid retry } else if (OB_FAIL(tablet_handle.get_obj()->fetch_tablet_autoinc_seq_cache( arg.cache_size_, autoinc_interval))) { LOG_WARN("failed to fetch tablet autoinc seq on tablet", K(ret), K(tablet_id)); @@ -248,15 +251,21 @@ int ObTabletAutoincSeqRpcHandler::batch_set_tablet_autoinc_seq( LOG_WARN("follower received FetchTabletsSeq rpc", K(ret), K(ls_id)); } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::OBSERVER_MOD))) { LOG_WARN("get ls failed", K(ret), K(ls_id)); + } else if (OB_FAIL(ls_handle.get_ls()->get_ls_role(role))) { + LOG_WARN("get role failed", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else if (OB_UNLIKELY(ObRole::LEADER != role)) { + ret = OB_NOT_MASTER; + LOG_WARN("ls not leader", K(ret), K(MTL_ID()), K(arg.ls_id_)); } else { for (int64_t i = 0; OB_SUCC(ret) && i < res.autoinc_params_.count(); i++) { int tmp_ret = OB_SUCCESS; ObTabletHandle tablet_handle; share::ObMigrateTabletAutoincSeqParam &autoinc_param = res.autoinc_params_.at(i); ObBucketHashWLockGuard lock_guard(bucket_lock_, autoinc_param.dest_tablet_id_.hash()); - if (OB_TMP_FAIL(ls_handle.get_ls()->get_tablet(autoinc_param.dest_tablet_id_, tablet_handle))) { + if (OB_TMP_FAIL(ls_handle.get_ls()->get_tablet(autoinc_param.dest_tablet_id_, tablet_handle, + ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { LOG_WARN("failed to get tablet", K(tmp_ret), K(autoinc_param)); - } else if (OB_TMP_FAIL(tablet_handle.get_obj()->update_tablet_autoinc_seq(autoinc_param.autoinc_seq_))) { + } else if (OB_TMP_FAIL(tablet_handle.get_obj()->update_tablet_autoinc_seq(autoinc_param.autoinc_seq_, arg.is_tablet_creating_))) { LOG_WARN("failed to update tablet autoinc seq", K(tmp_ret), K(autoinc_param)); } autoinc_param.ret_code_ = tmp_ret; @@ -271,6 +280,7 @@ int ObTabletAutoincSeqRpcHandler::replay_update_tablet_autoinc_seq( const ObLS *ls, const ObTabletID &tablet_id, const uint64_t autoinc_seq, + const bool is_tablet_creating, const share::SCN &replay_scn) { int ret = OB_SUCCESS; @@ -281,8 +291,8 @@ int ObTabletAutoincSeqRpcHandler::replay_update_tablet_autoinc_seq( ObTabletHandle tablet_handle; ObBucketHashWLockGuard guard(bucket_lock_, tablet_id.hash()); ObSyncTabletSeqReplayExecutor replay_executor; - if (OB_FAIL(replay_executor.init(autoinc_seq, replay_scn))) { - LOG_WARN("failed to init tablet auto inc sequence replay executor", K(ret), K(autoinc_seq), K(replay_scn)); + if (OB_FAIL(replay_executor.init(autoinc_seq, is_tablet_creating, replay_scn))) { + LOG_WARN("failed to init tablet auto inc sequence replay executor", K(ret), K(autoinc_seq), K(is_tablet_creating), K(replay_scn)); } else if (OB_FAIL(replay_executor.execute(replay_scn, ls->get_ls_id(), tablet_id))) { if (OB_TABLET_NOT_EXIST == ret) { LOG_INFO("tablet may be deleted, skip this log", K(ret), K(tablet_id), K(replay_scn)); diff --git a/src/storage/ob_tablet_autoinc_seq_rpc_handler.h b/src/storage/ob_tablet_autoinc_seq_rpc_handler.h index 9a0a5afcf..07f28eec7 100644 --- a/src/storage/ob_tablet_autoinc_seq_rpc_handler.h +++ b/src/storage/ob_tablet_autoinc_seq_rpc_handler.h @@ -30,15 +30,17 @@ class ObSyncTabletSeqReplayExecutor final : public logservice::ObTabletReplayExe public: ObSyncTabletSeqReplayExecutor(); int init(const uint64_t autoinc_seq, + const bool is_tablet_creating, const share::SCN &replay_scn); TO_STRING_KV(K_(seq), + K_(is_tablet_creating), K_(scn)); protected: bool is_replay_update_tablet_status_() const override { - return false; + return is_tablet_creating_; } // replay to the tablet @@ -55,6 +57,7 @@ protected: private: uint64_t seq_; + bool is_tablet_creating_; share::SCN scn_; }; @@ -77,6 +80,7 @@ public: const ObLS *ls, const ObTabletID &tablet_id, const uint64_t autoinc_seq, + const bool is_tablet_creating, const share::SCN &replay_scn); private: ObTabletAutoincSeqRpcHandler(); diff --git a/src/storage/restore/ob_ls_restore_task_mgr.cpp b/src/storage/restore/ob_ls_restore_task_mgr.cpp index 4ac71cdf9..42e9af159 100644 --- a/src/storage/restore/ob_ls_restore_task_mgr.cpp +++ b/src/storage/restore/ob_ls_restore_task_mgr.cpp @@ -802,8 +802,7 @@ int ObLSRestoreTaskMgr::check_tablet_is_deleted_( } else { LOG_WARN("failed to get latest tablet status", K(ret), KPC(tablet)); } - } else if (ObTabletStatus::DELETED == data.tablet_status_ - || ObTabletStatus::TRANSFER_OUT_DELETED == data.tablet_status_) { + } else if (data.tablet_status_.is_deleted_for_gc()) { is_deleted = true; } return ret; diff --git a/src/storage/restore/ob_restore_compatibility_util.cpp b/src/storage/restore/ob_restore_compatibility_util.cpp index 175640ad0..e8366d3fc 100644 --- a/src/storage/restore/ob_restore_compatibility_util.cpp +++ b/src/storage/restore/ob_restore_compatibility_util.cpp @@ -309,4 +309,4 @@ ObTabletRestoreAction::ACTION ObRestoreCompatibilityUtil::get_restore_action_pre UNUSED(ls_id); return action; -} \ No newline at end of file +} diff --git a/src/storage/tablelock/ob_lock_func_executor.cpp b/src/storage/tablelock/ob_lock_func_executor.cpp index 0c52470dc..ed38239d2 100644 --- a/src/storage/tablelock/ob_lock_func_executor.cpp +++ b/src/storage/tablelock/ob_lock_func_executor.cpp @@ -522,7 +522,7 @@ int ObLockFuncExecutor::unlock_obj_(ObTxDesc *tx_desc, { int ret = OB_SUCCESS; ObTableLockService *lock_service = MTL(ObTableLockService *); - if (OB_FAIL(lock_service->unlock_obj(*tx_desc, tx_param, arg))) { + if (OB_FAIL(lock_service->unlock(*tx_desc, tx_param, arg))) { LOG_WARN("unlock obj failed", K(ret), KPC(tx_desc), K(arg)); } return ret; @@ -778,7 +778,7 @@ int ObGetLockExecutor::lock_obj_(sql::ObSQLSessionInfo *session, session, LOCK_OBJECT, arg, /*for_dbms_lock*/ false, need_record_to_lock_table))) { LOG_WARN("record_detect_info_to_inner_table failed", K(ret), K(arg)); } else if (need_record_to_lock_table) { - if (OB_FAIL(lock_service->lock_obj(*tx_desc, tx_param, arg))) { + if (OB_FAIL(lock_service->lock(*tx_desc, tx_param, arg))) { LOG_WARN("lock obj failed", K(ret), KPC(tx_desc), K(arg)); } } diff --git a/src/storage/tablelock/ob_lock_inner_connection_util.cpp b/src/storage/tablelock/ob_lock_inner_connection_util.cpp index c38f1460d..8f5a00f2c 100644 --- a/src/storage/tablelock/ob_lock_inner_connection_util.cpp +++ b/src/storage/tablelock/ob_lock_inner_connection_util.cpp @@ -57,6 +57,32 @@ namespace tablelock #define REQUEST_LOCK_4_2(T, operation_type, arg, conn) \ __REQUEST_LOCK_CHECK_VERSION(CLUSTER_VERSION_4_2_0_0, T, operation_type, arg, conn) +#define REPLACE_LOCK(T, arg, conn, replace_req, buf, len, pos) \ + T unlock_req; \ + if (OB_FAIL(unlock_req.deserialize(buf, len, pos))) { \ + LOG_WARN("deserialize unlock_req in replace_req failed", K(ret), K(replace_req)); \ + } else if (FALSE_IT(replace_req.unlock_req_ = &unlock_req)) { \ + } else if (OB_FAIL(replace_lock(arg.get_tenant_id(), replace_req, conn))) { \ + LOG_WARN("replace lock failed", K(ret), K(replace_req)); \ + } \ + break; + +#define CONVERT_TYPE_AND_DO_LOCK(T, arg, tx_desc, tx_param) \ + const T lock_req = static_cast(arg); \ + if (OB_FAIL(MTL(ObTableLockService *)->lock(tx_desc, tx_param, lock_req))) { \ + LOG_WARN("lock failed", K(ret), K(lock_req)); \ + } \ + break; + +#define CONVERT_TYPE_AND_DO_UNLOCK(T, arg, tx_desc, tx_param) \ + const T lock_req = static_cast(arg); \ + T &unlock_req = const_cast(lock_req); \ + unlock_req.set_to_unlock_type(); \ + if (OB_FAIL(MTL(ObTableLockService *)->unlock(tx_desc, tx_param, unlock_req))) { \ + LOG_WARN("unlock failed", K(ret), K(unlock_req)); \ + } \ + break; + int ObInnerConnectionLockUtil::process_lock_rpc( const ObInnerSQLTransmitArg &arg, common::sqlclient::ObISQLConnection *conn) @@ -133,6 +159,12 @@ int ObInnerConnectionLockUtil::process_lock_rpc( REQUEST_LOCK_4_2(ObUnLockAloneTabletRequest, operation_type, arg, inner_conn); break; } + case ObInnerSQLTransmitArg::OPERATION_TYPE_REPLACE_LOCK: { + if (OB_FAIL(process_replace_lock_(arg, inner_conn))) { + LOG_WARN("process lock table failed", K(ret)); + } + break; + } default: { ret = OB_NOT_SUPPORTED; LOG_WARN("Unknown operation type", K(ret), K(operation_type)); @@ -208,6 +240,55 @@ int ObInnerConnectionLockUtil::process_lock_tablet_( return ret; } +int ObInnerConnectionLockUtil::process_replace_lock_( + const ObInnerSQLTransmitArg &arg, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + ObReplaceLockRequest replace_req; + ObUnLockRequest unlock_req; + const char *buf = arg.get_inner_sql().ptr(); + const int64_t data_len = arg.get_inner_sql().length(); + int64_t pos = 0; + int64_t tmp_pos = 0; + // FIXME: change to 431 later + if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_3_0_0) { + ret = OB_NOT_SUPPORTED; + LOG_WARN("cluster version check faild", KR(ret), K(GET_MIN_CLUSTER_VERSION())); + } else if (OB_FAIL(replace_req.deserialize_and_check_header(buf, data_len, pos))) { + LOG_WARN("deserialize and check header of ObReplaceLockRequest failed", K(ret), K(arg), K(pos)); + } else if (OB_FAIL(replace_req.deserialize_new_lock_mode_and_owner(buf, data_len, pos))) { + LOG_WARN("deserialize new_lock_mode and new_lock_owner of ObReplaceLockRequest failed", K(ret), K(arg), K(pos)); + // it's an temporary deserialization to get unlock request type + } else if (FALSE_IT(tmp_pos = pos)) { + } else if (OB_FAIL(unlock_req.deserialize(buf, data_len, tmp_pos))) { + LOG_WARN("deserialize unlock_req failed", K(ret), K(arg), K(tmp_pos)); + } else { + switch (unlock_req.type_) { + case ObLockRequest::ObLockMsgType::LOCK_OBJ_REQ:{ + REPLACE_LOCK(ObUnLockObjsRequest, arg, conn, replace_req, buf, data_len, pos); + } + case ObLockRequest::ObLockMsgType::LOCK_TABLE_REQ: { + REPLACE_LOCK(ObUnLockTableRequest, arg, conn, replace_req, buf, data_len, pos); + } + case ObLockRequest::ObLockMsgType::LOCK_PARTITION_REQ: { + REPLACE_LOCK(ObUnLockPartitionRequest, arg, conn, replace_req, buf, data_len, pos); + } + case ObLockRequest::ObLockMsgType::LOCK_TABLET_REQ: { + REPLACE_LOCK(ObUnLockTabletsRequest, arg, conn, replace_req, buf, data_len, pos); + } + case ObLockRequest::ObLockMsgType::LOCK_ALONE_TABLET_REQ: { + REPLACE_LOCK(ObUnLockAloneTabletRequest, arg, conn, replace_req, buf, data_len, pos); + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("meet not supportted replace request", K(unlock_req), K(arg)); + } + } + } + return ret; +} + int ObInnerConnectionLockUtil::lock_table( const uint64_t tenant_id, const uint64_t table_id, @@ -457,6 +538,97 @@ int ObInnerConnectionLockUtil::unlock_obj( return ret; } +int ObInnerConnectionLockUtil::replace_lock( + const uint64_t tenant_id, + const ObReplaceLockRequest &req, + observer::ObInnerSQLConnection *conn) +{ + int ret = OB_SUCCESS; + observer::ObReqTimeGuard req_timeinfo_guard; + + const bool local_execute = conn->is_local_execute(GCONF.cluster_id, tenant_id); + + SMART_VAR(ObInnerSQLResult, res, conn->get_session()) + { + if (OB_INVALID_ID == tenant_id) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tenant_id)); + } else if (local_execute) { + if (OB_FAIL(conn->switch_tenant(tenant_id))) { + LOG_WARN("set system tenant id failed", K(ret), K(tenant_id)); + } + } else { + LOG_DEBUG("tenant not in server", K(ret), K(tenant_id)); + } + + if (OB_SUCC(ret)) { + if (!conn->is_in_trans()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("inner conn must be already in trans", K(ret)); + } else if (OB_FAIL(res.init(local_execute))) { + LOG_WARN("init result set", K(ret), K(local_execute)); + } else if (local_execute) { + if (OB_FAIL(replace_lock_(tenant_id, req, conn, res))) { + LOG_WARN("replace lock failed", KR(ret), K(req)); + } + } else { + char *tmp_str = nullptr; + int64_t pos = 0; + ObString sql; + if (OB_ISNULL(tmp_str = static_cast(ob_malloc(req.get_serialize_size(), "InnerLock")))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("alloc memory for sql_str failed", K(ret), K(req.get_serialize_size())); + } else if (OB_FAIL(req.serialize(tmp_str, req.get_serialize_size(), pos))) { + LOG_WARN("serialize replace lock table arg failed", K(ret), K(req)); + } else { + sql.assign_ptr(tmp_str, pos); + ret = conn->forward_request(tenant_id, obrpc::ObInnerSQLTransmitArg::OPERATION_TYPE_REPLACE_LOCK, sql, res); + } + + if (OB_NOT_NULL(tmp_str)) { + ob_free(tmp_str); + } + } + } + } + + return ret; +} + +int ObInnerConnectionLockUtil::replace_lock_( + const uint64_t tenant_id, + const ObReplaceLockRequest &req, + observer::ObInnerSQLConnection *conn, + observer::ObInnerSQLResult &res) +{ + int ret = OB_SUCCESS; + transaction::ObTxDesc *tx_desc = nullptr; + + if (OB_ISNULL(conn)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid conn", KR(ret)); + } else if (OB_ISNULL(tx_desc = conn->get_session().get_tx_desc())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("Invalid tx_desc"); + } else { + transaction::ObTxParam tx_param; + tx_param.access_mode_ = transaction::ObTxAccessMode::RW; + tx_param.isolation_ = conn->get_session().get_tx_isolation(); + tx_param.cluster_id_ = GCONF.cluster_id; + conn->get_session().get_tx_timeout(tx_param.timeout_us_); + tx_param.lock_timeout_us_ = conn->get_session().get_trx_lock_timeout(); + + MTL_SWITCH(tenant_id) { + if (OB_FAIL(MTL(ObTableLockService *)->replace_lock(*tx_desc, tx_param, req))) { + LOG_WARN("replace lock failed", K(ret), K(tenant_id), K(req)); + } else if (OB_FAIL(res.close())) { + LOG_WARN("close result set failed", K(ret), K(tenant_id)); + } + } + } + return ret; +} + int ObInnerConnectionLockUtil::create_inner_conn(sql::ObSQLSessionInfo *session_info, common::ObMySQLProxy *sql_proxy, observer::ObInnerSQLConnection *&inner_conn) @@ -615,140 +787,9 @@ int ObInnerConnectionLockUtil::do_obj_lock_( tx_param.lock_timeout_us_ = conn->get_session().get_trx_lock_timeout(); MTL_SWITCH(tenant_id) { - switch (operation_type) { - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { - const ObLockTableRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_table(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock table failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; + if (OB_FAIL(handle_request_by_operation_type_(*tx_desc, tx_param, arg, operation_type))) { + LOG_WARN("handle request by operation_type failed", K(tx_param), K(arg), K(operation_type)); } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE: { - const ObUnLockTableRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_table(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock table failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { - if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_0_0) { - const ObLockTabletRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService *)->lock_tablet(*tx_desc, tx_param, lock_arg))) { - LOG_WARN("lock tablet failed", K(ret), K(tenant_id), K(lock_arg)); - } - } else { - const ObLockTabletsRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService *)->lock_tablet(*tx_desc, tx_param, lock_arg))) { - LOG_WARN("lock tablets failed", K(ret), K(tenant_id), K(lock_arg)); - } - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET: { - if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_0_0) { - const ObUnLockTabletRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService *)->unlock_tablet(*tx_desc, tx_param, lock_arg))) { - LOG_WARN("unlock tablet failed", K(ret), K(tenant_id), K(lock_arg)); - } - } else { - const ObUnLockTabletsRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService *)->unlock_tablet(*tx_desc, tx_param, lock_arg))) { - LOG_WARN("unlock tablets failed", K(ret), K(tenant_id), K(lock_arg)); - } - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART: { - const ObLockPartitionRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_partition(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock partition failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART: { - const ObUnLockPartitionRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_partition(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock partition failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ: { - const ObLockObjRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService *)->lock_obj(*tx_desc, tx_param, lock_arg))) { - LOG_WARN("lock object failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJS: { - const ObLockObjsRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService *)->lock_obj(*tx_desc, tx_param, lock_arg))) { - LOG_WARN("lock objects failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ: { - const ObUnLockObjRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService *)->unlock_obj(*tx_desc, tx_param, lock_arg))) { - LOG_WARN("unlock object failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJS: { - const ObUnLockObjsRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService *)->unlock_obj(*tx_desc, tx_param, lock_arg))) { - LOG_WARN("unlock objects failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART: { - const ObLockPartitionRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_subpartition(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock subpartition failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART: { - const ObUnLockPartitionRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_subpartition(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock subpartition failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_ALONE_TABLET: { - const ObLockAloneTabletRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->lock_tablet(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("lock alone tablet failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_ALONE_TABLET: { - const ObUnLockAloneTabletRequest &lock_arg = static_cast(arg); - if (OB_FAIL(MTL(ObTableLockService*)->unlock_tablet(*tx_desc, - tx_param, - lock_arg))) { - LOG_WARN("unlock alone tablet failed", K(ret), K(tenant_id), K(lock_arg)); - } - break; - } - default: { - LOG_WARN("operation_type is not expected", K(operation_type)); - ret = OB_ERR_UNEXPECTED; - } // default - } // switch if (OB_SUCC(ret) && OB_FAIL(res.close())) { LOG_WARN("close result set failed", K(ret), K(tenant_id)); } @@ -946,6 +987,113 @@ int ObInnerConnectionLockUtil::request_lock_( return ret; } +int ObInnerConnectionLockUtil::handle_request_by_operation_type_( + ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObLockRequest &arg, + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type) +{ + int ret = OB_SUCCESS; + switch (operation_type) { + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLE: { + CONVERT_TYPE_AND_DO_LOCK(ObLockTableRequest, arg, tx_desc, tx_param); + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLE: { + CONVERT_TYPE_AND_DO_UNLOCK(ObUnLockTableRequest, arg, tx_desc, tx_param); + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_TABLET: { + if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_0_0) { + const ObLockTabletRequest &lock_arg = static_cast(arg); + ObLockTabletsRequest new_lock_arg; + if (OB_FAIL(new_lock_arg.assign(lock_arg))) { + LOG_WARN("assign ObLockTabletsRequest failed", K(ret), K(lock_arg)); + } else { + CONVERT_TYPE_AND_DO_LOCK(ObLockTabletsRequest, new_lock_arg, tx_desc, tx_param); + } + } else { + CONVERT_TYPE_AND_DO_LOCK(ObLockTabletsRequest, arg, tx_desc, tx_param); + } + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_TABLET: { + if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_0_0) { + const ObUnLockTabletRequest &lock_arg = static_cast(arg); + ObUnLockTabletsRequest new_lock_arg; + if (OB_FAIL(new_lock_arg.assign(lock_arg))) { + LOG_WARN("assign ObLockTabletsRequest failed", K(ret), K(lock_arg)); + } else { + CONVERT_TYPE_AND_DO_UNLOCK(ObUnLockTabletsRequest, new_lock_arg, tx_desc, tx_param); + } + } else { + CONVERT_TYPE_AND_DO_UNLOCK(ObUnLockTabletsRequest, arg, tx_desc, tx_param); + } + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_PART: + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_SUBPART: { + CONVERT_TYPE_AND_DO_LOCK(ObLockPartitionRequest, arg, tx_desc, tx_param); + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_PART: + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_SUBPART: { + CONVERT_TYPE_AND_DO_UNLOCK(ObUnLockPartitionRequest, arg, tx_desc, tx_param); + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJ: { + const ObLockObjRequest &lock_arg = static_cast(arg); + ObLockObjsRequest new_lock_arg; + if (OB_FAIL(new_lock_arg.assign(lock_arg))) { + LOG_WARN("assign ObLockObjsRequest failed", K(ret), K(lock_arg)); + } else { + CONVERT_TYPE_AND_DO_LOCK(ObLockObjsRequest, new_lock_arg, tx_desc, tx_param); + } + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_OBJS: { + CONVERT_TYPE_AND_DO_LOCK(ObLockObjsRequest, arg, tx_desc, tx_param); + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJ: { + const ObUnLockObjRequest &lock_arg = static_cast(arg); + ObUnLockObjsRequest new_lock_arg; + if (OB_FAIL(new_lock_arg.assign(lock_arg))) { + LOG_WARN("assign ObLockObjsRequest failed", K(ret), K(lock_arg)); + } else { + CONVERT_TYPE_AND_DO_UNLOCK(ObUnLockObjsRequest, new_lock_arg, tx_desc, tx_param); + } + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_OBJS: { + CONVERT_TYPE_AND_DO_UNLOCK(ObUnLockObjsRequest, arg, tx_desc, tx_param); + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_LOCK_ALONE_TABLET: { + CONVERT_TYPE_AND_DO_LOCK(ObLockAloneTabletRequest, arg, tx_desc, tx_param); + } + case ObInnerSQLTransmitArg::OPERATION_TYPE_UNLOCK_ALONE_TABLET: { + CONVERT_TYPE_AND_DO_UNLOCK(ObUnLockAloneTabletRequest, arg, tx_desc, tx_param); + } + default: { + LOG_WARN("operation_type is not expected", K(operation_type)); + ret = OB_ERR_UNEXPECTED; + } + } + return ret; +} + +bool ObInnerConnectionLockUtil::is_unlock_operation(obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType type) +{ + bool is_unlock_operation = false; + switch (type) { + case obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType::OPERATION_TYPE_UNLOCK_TABLE: + case obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType::OPERATION_TYPE_UNLOCK_TABLET: + case obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType::OPERATION_TYPE_UNLOCK_PART: + case obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType::OPERATION_TYPE_UNLOCK_OBJ: + case obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType::OPERATION_TYPE_UNLOCK_SUBPART: + case obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType::OPERATION_TYPE_UNLOCK_ALONE_TABLET: + case obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType::OPERATION_TYPE_UNLOCK_OBJS: { + is_unlock_operation = true; + break; + } + default: { + is_unlock_operation = false; + } + } + return is_unlock_operation; +} + int ObInnerConnectionLockUtil::get_org_cluster_id_(ObSQLSessionInfo *session, int64_t &org_cluster_id) { int ret = OB_SUCCESS; diff --git a/src/storage/tablelock/ob_lock_inner_connection_util.h b/src/storage/tablelock/ob_lock_inner_connection_util.h index 6e7a09bd0..8a813768c 100644 --- a/src/storage/tablelock/ob_lock_inner_connection_util.h +++ b/src/storage/tablelock/ob_lock_inner_connection_util.h @@ -68,6 +68,8 @@ private: const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, const obrpc::ObInnerSQLTransmitArg &arg, observer::ObInnerSQLConnection *conn); + static int process_replace_lock_(const obrpc::ObInnerSQLTransmitArg &arg, + observer::ObInnerSQLConnection *conn); // --------------------- interface for inner connection client ----------------------- public: static int lock_table( @@ -146,6 +148,10 @@ public: const uint64_t tenant_id, const ObUnLockObjsRequest &arg, observer::ObInnerSQLConnection *conn); + static int replace_lock( + const uint64_t tenant_id, + const ObReplaceLockRequest &req, + observer::ObInnerSQLConnection *conn); static int create_inner_conn(sql::ObSQLSessionInfo *session_info, common::ObMySQLProxy *sql_proxy, observer::ObInnerSQLConnection *&inner_conn); @@ -156,12 +162,22 @@ public: static int build_tx_param(sql::ObSQLSessionInfo *session_info, ObTxParam &tx_param, const bool *readonly = nullptr); private: + static int replace_lock_( + const uint64_t tenant_id, + const ObReplaceLockRequest &req, + observer::ObInnerSQLConnection *conn, + observer::ObInnerSQLResult &res); static int do_obj_lock_( const uint64_t tenant_id, const ObLockRequest &arg, const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, observer::ObInnerSQLConnection *conn, observer::ObInnerSQLResult &res); + static int handle_request_by_operation_type_( + ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObLockRequest &arg, + const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type); static int request_lock_( const uint64_t tenant_id, const uint64_t table_id, @@ -175,6 +191,7 @@ private: const ObLockRequest &arg, const obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType operation_type, observer::ObInnerSQLConnection *conn); + static bool is_unlock_operation(obrpc::ObInnerSQLTransmitArg::InnerSQLOperationType type); static int get_org_cluster_id_(sql::ObSQLSessionInfo *session, int64_t &org_cluster_id); static int set_to_mysql_compat_mode_(observer::ObInnerSQLConnection *conn, bool &need_reset_sess_mode, diff --git a/src/storage/tablelock/ob_lock_memtable.cpp b/src/storage/tablelock/ob_lock_memtable.cpp index d458139f7..bb5da796a 100644 --- a/src/storage/tablelock/ob_lock_memtable.cpp +++ b/src/storage/tablelock/ob_lock_memtable.cpp @@ -46,6 +46,156 @@ namespace transaction namespace tablelock { +OB_SERIALIZE_MEMBER(ObLockTableSplitLog, src_tablet_id_, dst_tablet_ids_); + +int ObLockTableSplitLogCb::on_success() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObLockTableSplitLogCb is not init!"); + } else if (!is_logging_) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("should be logging", K(ret)); + } else if (OB_ISNULL(memtable_)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("lock memtable should not be null", K(ret)); + } else if (OB_TMP_FAIL(memtable_->add_split_epoch(last_submit_scn_, dst_tablet_ids_))) { + LOG_WARN("add_split_epoch_to_dst_tablet failed", K(tmp_ret), KPC(this)); + } else { + memtable_->update_rec_and_max_committed_scn(last_submit_scn_); + cb_success_ = true; + FLOG_INFO("table lock split successfully", KPC(this)); + // TODO for @lihongqin.lhq + // notice RS table_lock split successfully + } + + if (OB_FAIL(ret) || OB_FAIL(tmp_ret)) { + cb_success_ = false; + // TODO for @lihongqin.lhq + // notice RS table_lock split failed + } + + is_logging_ = false; + return ret; +} + +int ObLockTableSplitLogCb::on_failure() +{ + // no notice RS and will retry table_lock split + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_ERROR("ObLockTableSplitLogCb is not init!"); + } else { + cb_success_ = false; + is_logging_ = false; + LOG_WARN("ObLockTableSplitLogCb on_failure", K(ret), K(*this)); + } + return ret; +} + +int ObLockTableSplitLogCb::init(ObLockMemtable *memtable, const share::ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("init ObLockTableSplitLogCb twice", KR(ret), K(memtable), K(ls_id)); + } else if (!is_valid_(memtable, ls_id)){ + ret = OB_INVALID_ARGUMENT; + LOG_WARN("the parameters is invalid", K(ret), K(memtable), K(ls_id)); + } else { + memtable_ = memtable; + ls_id_ = ls_id; + is_inited_ = true; + } + return ret; +} + +int ObLockTableSplitLogCb::set(const ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLockTableSplitLogCb is not init", K(ret), K(src_tablet_id), K(dst_tablet_ids)); + } else if (!src_tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("src_tablet_id is invalid", K(ret), K(src_tablet_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < dst_tablet_ids.count(); i++) { + ObTabletID dst_tablet_id = dst_tablet_ids[i]; + if (!dst_tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("dst_tablet_id is invalid", K(ret), K(dst_tablet_id)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(dst_tablet_ids_.assign(dst_tablet_ids))) { + LOG_WARN("assign dst_tablet_id failed", K(ret), K(dst_tablet_ids)); + } else { + src_tablet_id_ = src_tablet_id; + } + } + } + return ret; +} + +bool ObLockTableSplitLogCb::is_valid() +{ + int ret = OB_SUCCESS; + bool is_valid = true; + if (IS_NOT_INIT) { + is_valid = false; + LOG_WARN("ObLockTableSplitLogCb is not init"); + } else { + is_valid = is_valid_(memtable_, ls_id_); + } + return is_valid; +} + +bool ObLockTableSplitLogCb::is_valid_(const ObLockMemtable *memtable, const ObLSID &ls_id) +{ + int ret = OB_SUCCESS; + bool is_valid = true; + if (OB_ISNULL(memtable)) { + is_valid = false; + LOG_WARN("ObLockMemtable in ObLockTableSplitLogCb is null"); + } + if (!ls_id.is_valid()) { + is_valid = false; + LOG_WARN("ObLSID in ObLockTableSplitLogCb is invalid"); + } + return is_valid; +} + +int ObLockTableSplitLog::init(common::ObTabletID &src_tablet_id, const ObSArray &dst_tablet_ids) +{ + int ret = OB_SUCCESS; + if (!src_tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("src_tablet_id is invalid", K(ret), K(src_tablet_id)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < dst_tablet_ids.count(); i++) { + ObTabletID dst_tablet_id = dst_tablet_ids[i]; + if (!dst_tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("dst_tablet_id is invalid", K(ret), K(dst_tablet_id)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(dst_tablet_ids_.assign(dst_tablet_ids))) { + LOG_WARN("assign dst_tablet_id failed", K(ret), K(dst_tablet_ids)); + } else { + src_tablet_id_ = src_tablet_id; + } + } + } + return ret; +} + ObLockMemtable::ObLockMemtable() : ObIMemtable(), is_inited_(false), @@ -58,8 +208,7 @@ ObLockMemtable::ObLockMemtable() need_check_tablet_status_(false), freezer_(nullptr), flush_lock_(common::ObLatchIds::CLOG_CKPT_LOCK) -{ -} +{} ObLockMemtable::~ObLockMemtable() { @@ -106,8 +255,8 @@ void ObLockMemtable::reset() max_committed_scn_.reset(); ObITable::reset(); obj_lock_map_.reset(); - freeze_scn_.reset(); - flushed_scn_.reset(); + freeze_scn_.set_min(); + flushed_scn_.set_min(); is_frozen_ = false; need_check_tablet_status_ = false; freezer_ = nullptr; @@ -239,13 +388,15 @@ int ObLockMemtable::lock_( // TODO: yanyuan.cxf only wait at the first conflict trans now, but we need // wait all the conflict trans to do deadlock detect. ObFunction recheck_f([this, + ¶m, &lock_op, &lock_mode_cnt_in_same_trans](bool &need_wait) -> int { int ret = OB_SUCCESS; ObTxIDSet conflict_tx_set; if (OB_FAIL(this->obj_lock_map_.check_allow_lock(lock_op, lock_mode_cnt_in_same_trans, - conflict_tx_set)) && + conflict_tx_set, + param.expired_time_)) && OB_TRY_LOCK_ROW_CONFLICT != ret) { LOG_WARN("check allow lock failed", K(ret)); } else if (OB_TRY_LOCK_ROW_CONFLICT == ret) { @@ -283,7 +434,6 @@ int ObLockMemtable::check_tablet_write_allow_(const ObTableLockOp &lock_op) ObLSHandle ls_handle; ObLS *ls = nullptr; ObTabletHandle tablet_handle; - ObTabletStatus::Status tablet_status = ObTabletStatus::MAX; ObTabletCreateDeleteMdsUserData data; bool is_commited = false; if (!need_check_tablet_status_) { @@ -307,9 +457,7 @@ int ObLockMemtable::check_tablet_write_allow_(const ObTableLockOp &lock_op) ret = OB_TABLET_NOT_EXIST; LOG_WARN("failed to get CreateDeleteMdsUserData", KR(ret), K(ls->get_ls_id()), K(tablet_id)); } - } else if (FALSE_IT(tablet_status = data.get_tablet_status())) { - } else if (is_commited && (ObTabletStatus::NORMAL == tablet_status - || ObTabletStatus::TRANSFER_IN == tablet_status)) { + } else if (is_commited && data.tablet_status_.is_writable_for_dml()) { // allow } else { ret = OB_TABLET_NOT_EXIST; @@ -498,12 +646,178 @@ int ObLockMemtable::post_obj_lock_conflict_(ObMvccAccessCtx &acc_ctx, return ret; } -int ObLockMemtable::check_lock_conflict( - const ObMemtableCtx *mem_ctx, - const ObTableLockOp &lock_op, - ObTxIDSet &conflict_tx_set, - const bool include_finish_tx, - const bool only_check_dml_lock) +void ObLockMemtable::update_rec_and_max_committed_scn(const share::SCN &commit_scn) +{ + RLockGuard guard(flush_lock_); + if (commit_scn <= freeze_scn_) { + LOG_INFO("meet disordered replay, will dec_update pre_rec_scn_", + K(commit_scn), + K(rec_scn_), + K(pre_rec_scn_), + K(freeze_scn_), + K(ls_id_)); + pre_rec_scn_.dec_update(commit_scn); + } else { + rec_scn_.dec_update(commit_scn); + } + max_committed_scn_.inc_update(commit_scn); +} + +int ObLockMemtable::check_table_lock_split_(const ObTableLockOp &lock_op, + const ObStoreCtx &ctx) +{ + int ret = OB_SUCCESS; + // TODO for @lihongqin.lhq + // get_split_start_trans_id(ObTabletID tablet_id) + // if not splitting, return invalid value + // else return start_trans_id + + // ObTransID split_start_trans_id = get_split_start_trans_id(lock_op.lock_id_.obj_id_); + // // if the tablet split start after the checking, + // // the lock_op will block OUT_TRANS_LOCK from start_split_trans + // // and the lock_op must not be OUT_TRANS_LOCK from start_split_trans + // if (split_start_trans_id.is_valid()) { + // // splitting + // // if the tablet split end after the checking + // // the lock_op also be refused + // // and the lock_op must not be OUT_TRANS_LOCK from start_split_trans + // if (lock_op.is_out_trans_lock_op()) { + // if (ctx.mvcc_acc_ctx_.tx_id_ == split_start_trans_id) { + // // if exist_cannot_split_lock need tablet_split fail + // ObTabletID src_tablet_id(lock_op.lock_id_.obj_id_); + // bool exist_cannot_split_lock = false; + // if (OB_FAIL(check_exist_cannot_split_lock_(src_tablet_id, split_start_trans_id, exist_cannot_split_lock))) { + // // do nothing + // } else if (exist_cannot_split_lock) { + // ret = OB_TRY_LOCK_ROW_CONFLICT; + // } + // } else { + // ret = OB_TRY_LOCK_ROW_CONFLICT; + // } + // } + // } + return ret; +} + +int ObLockMemtable::check_valid_for_table_lock_split_(const common::ObTabletID src_tablet_id, + const ObSArray &dst_tablet_ids) +{ + int ret = OB_SUCCESS; + if (!src_tablet_id.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("src_tablet_id is invalid", K(ret), K(src_tablet_id), K(dst_tablet_ids)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < dst_tablet_ids.count(); i++) { + if (!dst_tablet_ids[i].is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("dst_tablet_id is invalid", K(ret), K(src_tablet_id), K(dst_tablet_ids[i])); + } + } + } + return ret; +} + +int ObLockMemtable::get_split_status_(const ObTabletID tablet_id, + ObTableLockSplitStatus &split_status) +{ + int ret = OB_SUCCESS; + ObLockID lock_id; + share::SCN split_epoch = share::SCN::invalid_scn(); + if (OB_FAIL(get_lock_id(tablet_id, lock_id))) { + LOG_WARN("get_lock_id failed", K(ret), K(tablet_id)); + } else if (OB_FAIL(obj_lock_map_.get_split_epoch(lock_id, split_epoch))) { + // TODO(yangyifei.yyf): we need to check whether the obj_lock of this src_tablet + // is locked here. If it's locked, it's splitting out. + LOG_WARN("get_split_epoch for src_tablet failed", K(ret), K(lock_id)); + } else { + if (!split_epoch.is_valid()) { + split_status = ObTableLockSplitStatus::NO_SPLIT; + } else if (split_epoch.is_max()) { + split_status = ObTableLockSplitStatus::SPLITTED; + } else if (split_epoch.is_min()) { + split_status = ObTableLockSplitStatus::WAIT_FOR_CALLBACK; + } else { + split_status = ObTableLockSplitStatus::SPLITTING_IN; + } + } + return ret; +} + + +int ObLockMemtable::add_split_epoch(const share::SCN &split_epoch, + const ObSArray &tablet_ids, + const bool for_replay) +{ + int ret = OB_SUCCESS; + ObSArray lock_ids; + if (OB_FAIL(get_lock_id(tablet_ids, lock_ids))) { + LOG_WARN("get_lock_id for dst_tablet_ids failed", K(ret), K(tablet_ids)); + } else if (OB_FAIL(obj_lock_map_.add_split_epoch(lock_ids, split_epoch, for_replay))) { + LOG_WARN("add_split_epoch for dst_lock_ids failed", K(ret), K(tablet_ids), K(lock_ids), K(split_epoch)); + } + return ret; +} + +int ObLockMemtable::add_split_epoch(const share::SCN &split_epoch, + const common::ObTabletID &tablet_id, + const bool for_replay) +{ + int ret = OB_SUCCESS; + ObLockID lock_id; + if (OB_FAIL(get_lock_id(tablet_id, lock_id))) { + LOG_WARN("get_lock_id for dst_tablet_ids failed", K(ret), K(tablet_id)); + } else if (OB_FAIL(obj_lock_map_.add_split_epoch(lock_id, split_epoch, for_replay))) { + LOG_WARN("add_split_epoch for dst_lock_ids failed", K(ret), K(tablet_id), K(lock_id), K(split_epoch)); + } + return ret; +} + +int ObLockMemtable::get_split_status(const ObTabletID src_tablet_id, + const ObSArray dst_tablet_ids, + ObTableLockSplitStatus &src_split_status, + ObTableLockSplitStatus &dst_split_status) +{ + int ret = OB_SUCCESS; + bool all_set_epoch = true; + ObLockID src_lock_id; + share::SCN split_epoch = share::SCN::invalid_scn(); + src_split_status = ObTableLockSplitStatus::INVALID_STATE; + dst_split_status = ObTableLockSplitStatus::INVALID_STATE; + // check for src_tablet + if (OB_FAIL(check_valid_for_table_lock_split_(src_tablet_id, dst_tablet_ids))) { + LOG_WARN("the parameters for table lock split is invlaid", K(ret), K(src_tablet_id), K(dst_tablet_ids)); + } else { + if (OB_FAIL(get_split_status_(src_tablet_id, src_split_status))) { + LOG_WARN("get_split_status for src_tablet failed", K(ret), K(src_tablet_id)); + } + + ObTableLockSplitStatus tmp_split_status = ObTableLockSplitStatus::INVALID_STATE; + for (int64_t i = 0; OB_SUCC(ret) && i < dst_tablet_ids.count(); i++) { + if (OB_FAIL(get_split_status_(dst_tablet_ids[i], tmp_split_status))) { + LOG_WARN("get_split_status for dst_tablet failed", K(ret), K(dst_tablet_ids[i])); + } else { + if (ObTableLockSplitStatus::INVALID_STATE == tmp_split_status + || ObTableLockSplitStatus::SPLITTED == tmp_split_status + || ObTableLockSplitStatus::SPLITTING_OUT == tmp_split_status) { + LOG_WARN("meet illeagle state for dst_tablet", K(dst_tablet_ids[i]), K(tmp_split_status)); + break; + } else if (ObTableLockSplitStatus::WAIT_FOR_CALLBACK == tmp_split_status) { + break; + } + // if the split status of dst_tablet is splitting_out, keep check other dst_tablets. + } + } + dst_split_status = tmp_split_status; + } + return ret; +} + +int ObLockMemtable::check_lock_conflict(const ObMemtableCtx *mem_ctx, + const ObTableLockOp &lock_op, + ObTxIDSet &conflict_tx_set, + const int64_t expired_time, + const bool include_finish_tx, + const bool only_check_dml_lock) { int ret = OB_SUCCESS; bool lock_exist = false; @@ -564,6 +878,10 @@ int ObLockMemtable::lock( || OB_UNLIKELY(!lock_op.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(lock_op), K(ctx)); + // } else if (OB_FAIL(check_table_lock_split_(lock_op, + // ctx))) { + // LOG_WARN("can not lock because table lock spliting", + // K(ret), K(param), K(lock_op), K(ctx)); } else if (OB_FAIL(lock_(param, ctx, lock_op))) { if (ret != OB_TRY_LOCK_ROW_CONFLICT) { LOG_WARN("lock failed.", K(ret), K(param), K(lock_op)); @@ -601,6 +919,35 @@ int ObLockMemtable::unlock( return ret; } +int ObLockMemtable::replace(storage::ObStoreCtx &ctx, + const ObReplaceLockParam ¶m, + const ObTableLockOp &unlock_op, + ObTableLockOp &new_lock_op) +{ + int ret = OB_SUCCESS; + LOG_DEBUG("ObLockMemtable::replace ", K(param), K(new_lock_op), K(unlock_op)); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLockMemtable not inited.", K(ret)); + } else if (OB_UNLIKELY(!ctx.is_valid()) + || OB_UNLIKELY(!ctx.is_write()) + || OB_UNLIKELY(!new_lock_op.is_valid()) + || OB_UNLIKELY(!unlock_op.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(new_lock_op), K(unlock_op), K(ctx)); + } else if (OB_FAIL(unlock_(ctx, unlock_op, param.is_try_lock_, param.expired_time_))) { + if (ret != OB_TRY_LOCK_ROW_CONFLICT) { + LOG_WARN("unlock failed.", K(ret), K(param), K(new_lock_op), K(unlock_op)); + } + } else if (OB_FAIL(lock_(param, ctx, new_lock_op))) { + if (ret != OB_TRY_LOCK_ROW_CONFLICT) { + LOG_WARN("lock failed.", K(ret), K(param), K(new_lock_op), K(unlock_op)); + } + } + LOG_DEBUG("ObLockMemtable::replace finish.", K(ret), K(param), K(new_lock_op), K(unlock_op)); + return ret; +} + int ObLockMemtable::remove_tablet_lock(const ObTabletID &tablet_id) { int ret = OB_SUCCESS; @@ -659,16 +1006,7 @@ int ObLockMemtable::update_lock_status( LOG_WARN("update lock status failed.", K(op_info), K(status)); } else if ((OUT_TRANS_LOCK == op_info.op_type_ || OUT_TRANS_UNLOCK == op_info.op_type_) && LOCK_OP_COMPLETE == status) { - RLockGuard guard(flush_lock_); - if (commit_scn <= freeze_scn_) { - LOG_INFO("meet disordered replay, will dec_update pre_rec_scn_", K(ret), - K(op_info), K(commit_scn), K(rec_scn_), K(pre_rec_scn_), - K(freeze_scn_), K(ls_id_)); - pre_rec_scn_.dec_update(commit_scn); - } else { - rec_scn_.dec_update(commit_scn); - } - max_committed_scn_.inc_update(commit_scn); + update_rec_and_max_committed_scn(commit_scn); LOG_INFO("out_trans update_lock_status", K(ret), K(op_info), K(commit_scn), K(status), K(rec_scn_), K(ls_id_)); } LOG_DEBUG("ObLockMemtable::update_lock_status", K(ret), K(op_info), K(commit_scn), K(status)); @@ -687,7 +1025,7 @@ int ObLockMemtable::recover_obj_lock(const ObTableLockOp &op_info) } else if (OB_FAIL(obj_lock_map_.recover_obj_lock(op_info))) { LOG_WARN("recover_obj_lock failed", K(ret), K(op_info)); } - LOG_DEBUG("LockMemtable::recover_obj_lock success", K(op_info), K(ret)); + LOG_DEBUG("LockMemtable::recover_obj_lock success", K(op_info), K(ret), K(this), K(*this)); return ret; } @@ -977,6 +1315,64 @@ int ObLockMemtable::flush(SCN recycle_scn, return ret; } +int ObLockMemtable::replay_split_log(const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const SCN &scn) +{ + int ret = OB_SUCCESS; + if (scn <= flushed_scn_) { + LOG_INFO("no need replay", K(ret), K(scn), K(flushed_scn_)); + } else { + int64_t pos = 0; + ObLockTableSplitLog split_log; + logservice::ObLogBaseHeader base_header; + const char *log_buf = static_cast(buffer); + ObTabletID src_tablet_id; + ObSArray dst_tablet_ids; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLockMemtable not inited", K(ret)); + } else if (OB_ISNULL(log_buf) + || OB_UNLIKELY(nbytes <= 0) + || OB_UNLIKELY(!lsn.is_valid()) + || OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arguments", K(buffer), K(nbytes), K(pos), + K(lsn), K(scn), K(ret)); + } else if (OB_FAIL(base_header.deserialize(log_buf, nbytes, pos))) { + LOG_WARN("log base header deserialize error", + K(ret), KP(buffer), K(nbytes), K(lsn), K(scn)); + } else if (OB_FAIL(split_log.deserialize((char *)buffer, nbytes, pos))) { + LOG_WARN("split_log deserialize error", K(ret)); + } else { + src_tablet_id = split_log.get_src_tablet_id(); + dst_tablet_ids = split_log.get_dst_tablet_ids(); + if (OB_FAIL(check_valid_for_table_lock_split_(src_tablet_id, dst_tablet_ids))) { + LOG_WARN("the parameters for table lock split is invlaid", K(ret), K(src_tablet_id), K(dst_tablet_ids)); + } else if (OB_FAIL(add_split_epoch(share::SCN::max_scn(), src_tablet_id, true))) { + LOG_WARN("add_split_epoch_ to src_tablet failed", + K(ret), K(src_tablet_id)); + } else if(OB_FAIL(add_split_epoch(scn, split_log.get_dst_tablet_ids(), true))) { + LOG_WARN("add_split_epoch_ to dst_tablets failed", + K(ret), K(dst_tablet_ids)); + } else { + LOG_INFO("replay add_split_epoch_to_dst_tablet successfully", + K(scn), + K(dst_tablet_ids)); + update_rec_and_max_committed_scn(scn); + } + } + + if (OB_FAIL(ret)) { + ret = OB_EAGAIN; + } + } + + return ret; +} + int ObLockMemtable::replay_row( storage::ObStoreCtx &ctx, const share::SCN &scn, @@ -1046,10 +1442,32 @@ int ObLockMemtable::replay_lock( LOG_WARN("invalid argument", K(ret), K(mem_ctx), K(lock_op)); } else if (OB_FAIL(replay_lock_(mem_ctx, lock_op, scn))) { LOG_WARN("replay lock failed", K(ret), K(lock_op)); - } else { - // do nothing } - LOG_DEBUG("ObMemtable::replay_lock finish.", K(ret), K(lock_op), K(ls_id_)); + LOG_DEBUG("ObMemtable::replay_lock finish.", K(ret), K(lock_op), K(ls_id_), K(scn)); + return ret; +} + +int ObLockMemtable::table_lock_split(const ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids, + const transaction::ObTransID &trans_id) +{ + int ret = OB_SUCCESS; + ObLockTableSplitLogCb split_cb; + LOG_INFO("start split", K(src_tablet_id), K(dst_tablet_ids)); + + if (OB_FAIL(check_valid_for_table_lock_split_(src_tablet_id, dst_tablet_ids))) { + LOG_WARN( + "the parameters for table lock split is invlaid", K(ret), K(split_cb), K(src_tablet_id), K(dst_tablet_ids)); + } else if (OB_FAIL(split_cb.init(this, ls_id_))) { + LOG_WARN("init ObLockTableSplitLogCb failed", K(ret), K(ls_id_)); + } else if (OB_FAIL(obj_lock_map_.table_lock_split(src_tablet_id, dst_tablet_ids, trans_id, split_cb))) { + LOG_WARN("table lock split failed", K(ret), K(src_tablet_id), K(dst_tablet_ids), K(trans_id), K(split_cb)); + } + + if (!split_cb.cb_success()) { + ret = OB_TABLE_LOCK_SPLIT_FAIL; + LOG_WARN("table lock split failed!", K(ret), K(split_cb)); + } return ret; } diff --git a/src/storage/tablelock/ob_lock_memtable.h b/src/storage/tablelock/ob_lock_memtable.h index 6f8738d45..6ac134145 100644 --- a/src/storage/tablelock/ob_lock_memtable.h +++ b/src/storage/tablelock/ob_lock_memtable.h @@ -17,6 +17,10 @@ #include "storage/memtable/ob_memtable_interface.h" #include "storage/tablelock/ob_obj_lock.h" #include "lib/lock/ob_spin_rwlock.h" +#include "logservice/ob_append_callback.h" +#include "logservice/ob_log_base_type.h" +#include "logservice/ob_log_base_header.h" +#include "logservice/ob_log_handler.h" #include "share/scn.h" namespace oceanbase @@ -40,11 +44,96 @@ namespace tablelock { struct ObLockParam; +class ObLockTableSplitLog final +{ +public: + OB_UNIS_VERSION(1); +public: + ObLockTableSplitLog() { reset(); } + ~ObLockTableSplitLog() { reset(); } + + int init(common::ObTabletID &src_tablet_id, const ObSArray &dst_tablet_ids); + + void reset() { + src_tablet_id_ = 0; + dst_tablet_ids_.reset(); + } + + const ObTabletID &get_src_tablet_id() { return src_tablet_id_; } + ObSArray &get_dst_tablet_ids() { return dst_tablet_ids_; } + TO_STRING_KV(K(src_tablet_id_), K(dst_tablet_ids_)); + +private: + ObTabletID src_tablet_id_; + ObSArray dst_tablet_ids_; +}; + +class ObLockTableSplitLogCb : public logservice::AppendCb +{ +friend class ObOBJLock; +public: + ObLockTableSplitLogCb() + : is_inited_(false), + memtable_(nullptr), + ls_id_(share::ObLSID::INVALID_LS_ID), + src_tablet_id_(OB_INVALID_ID), + dst_tablet_ids_(), + is_logging_(false), + cb_success_(false), + last_submit_log_ts_(OB_INVALID_TIMESTAMP), + last_submit_scn_() {} + virtual ~ObLockTableSplitLogCb() {} + int init(ObLockMemtable *memtable, const share::ObLSID &ls_id); + int set(const ObTabletID &src_tablet_id, const ObSArray &dst_tablet_ids); + bool is_valid(); + bool cb_success() { return cb_success_; }; + // we should ensure that the lock memtable won't be released + // after submit_log, until the callback on_success or on_failure + virtual int on_success() override; + virtual int on_failure() override; + TO_STRING_KV(K(is_inited_), + K(memtable_), + K(ls_id_), + K(src_tablet_id_), + K(dst_tablet_ids_), + K(last_submit_log_ts_), + K(last_submit_scn_), + K(is_logging_), + K(cb_success_)); +private: + bool is_valid_(const ObLockMemtable *memtable, const share::ObLSID &ls_id); +private: + bool is_inited_; + + ObLockMemtable *memtable_; + share::ObLSID ls_id_; + ObTabletID src_tablet_id_; + ObSArray dst_tablet_ids_; + + // To ensure only one writer can append log to LS at the same time, + // and only submit_log will change it to be true. + bool is_logging_; + bool cb_success_; + // params get from the LS + int64_t last_submit_log_ts_; + share::SCN last_submit_scn_; +}; + class ObLockMemtable - : public ObIMemtable, + : public storage::ObIMemtable, public storage::checkpoint::ObCommonCheckpoint { public: + enum ObTableLockSplitStatus + { + INVALID_STATE = 0, + NO_SPLIT = 1, // maybe has splitted into as a dst_tablet + WAIT_FOR_CALLBACK = 2, + SPLITTING_OUT = 3, // for src_tablet only + SPLITTING_IN = 4, // the cb_ has been callbacked + SPLITTED = 5 + }; + ObLockMemtable(); ~ObLockMemtable(); @@ -61,12 +150,17 @@ public: const ObTableLockOp &unlock_op, const bool is_try_lock = true, const int64_t expired_time = 0); + int replace(storage::ObStoreCtx &ctx, + const ObReplaceLockParam ¶m, + const ObTableLockOp &unlock_op, + ObTableLockOp &new_lock_op); // pre_check_lock to reduce useless lock and lock rollback // 1. check_lock_exist in mem_ctx // 2. check_lock_conflict in obj_map int check_lock_conflict(const memtable::ObMemtableCtx *mem_ctx, const ObTableLockOp &lock_op, ObTxIDSet &conflict_tx_set, + const int64_t expired_time, const bool include_finish_tx = true, const bool only_check_dml_lock = false); // remove all the locks of the specified tablet @@ -89,6 +183,7 @@ public: const share::SCN &commit_scn, const ObTableLockOpStatus status); + void update_rec_and_max_committed_scn(const share::SCN &scn); int get_table_lock_store_info(ObIArray &store_arr); // get all the lock id in the lock map @@ -142,6 +237,30 @@ public: const ObTableLockOp &lock_op, const share::SCN &scn); + // ====================== SPLIT TABLE LOCK ====================== + int table_lock_split(const common::ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids, + const transaction::ObTransID &trans_id); + int replay_split_log(const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const share::SCN &scn); + int get_split_status(const ObTabletID src_tablet_id, + const ObSArray dst_tablet_ids, + ObTableLockSplitStatus &src_split_status, + ObTableLockSplitStatus &dst_split_status); + // The split_epoch here is the submit scn of the log of table lock split, + // identifies the time at which table lock split begins. + // The table locks which are generated by dml will be stored in destination + // tablets, until all of them have finished, i.e. the transactions which + // start before this split_epoch have been committed/aborted. + int add_split_epoch(const share::SCN &split_epoch, + const ObSArray &tablet_ids, + const bool for_replay = false); + int add_split_epoch(const share::SCN &split_epoch, + const common::ObTabletID &tablet_id, + const bool for_replay = false); + // ================ NOT SUPPORTED INTERFACE =============== virtual int get(const storage::ObTableIterParam ¶m, @@ -198,6 +317,23 @@ private: const ObTableLockMode &lock_mode, const ObTransID &conflict_tx_id, ObFunction &recheck_f); + // table lock split just support in_trans dml lock, + // table split should be failed when exist_cannot_split_lock + int check_exist_cannot_split_lock_(const common::ObTabletID &src_tablet_id, + const ObTransID &split_start_trans_id, + bool &exist_cannot_split_lock); + int need_split_(const common::ObTabletID &src_tablet_id, + bool &need_split); + int submit_log_(common::ObTabletID src_tablet_id, + const ObSArray &dst_tablet_ids); + // cannot add OUT_TRANS_LOCK when tablet is splitting + // except split_start_transaction + int check_table_lock_split_(const ObTableLockOp &lock_op, + const ObStoreCtx &ctx); + int check_valid_for_table_lock_split_(const common::ObTabletID src_tablet_id, + const ObSArray &dst_tablet_ids); + int get_split_status_(const ObTabletID tablet_id, ObTableLockSplitStatus &split_status); + int register_into_deadlock_detector_(const storage::ObStoreCtx &ctx, const ObTableLockOp &lock_op); int unregister_from_deadlock_detector_(const ObTableLockOp &lock_op); diff --git a/src/storage/tablelock/ob_lock_memtable_mgr.cpp b/src/storage/tablelock/ob_lock_memtable_mgr.cpp index 9a39253ee..6cf62f2eb 100644 --- a/src/storage/tablelock/ob_lock_memtable_mgr.cpp +++ b/src/storage/tablelock/ob_lock_memtable_mgr.cpp @@ -124,8 +124,6 @@ int ObLockMemtableMgr::create_memtable(const CreateMemtableArg &arg) } else if (OB_ISNULL(ls_tx_svr = freezer_->get_ls_tx_svr())) { ret = OB_ERR_UNEXPECTED; LOG_WARN("ls_tx_svr is null", K(ret)); - } else if (OB_FAIL(ls_tx_svr->register_common_checkpoint(checkpoint::LOCK_MEMTABLE_TYPE, memtable))) { - LOG_WARN("lock memtable register_common_checkpoint failed", K(ret), K(ls_id_)); } else { LOG_INFO("create lock memtable successfully", K_(ls_id), K(memtable), KPC(this)); } @@ -136,7 +134,7 @@ int ObLockMemtableMgr::create_memtable(const CreateMemtableArg &arg) const ObLockMemtable *ObLockMemtableMgr::get_memtable_(const int64_t pos) const { int ret = OB_SUCCESS; - const ObIMemtable *imemtable = tables_[get_memtable_idx(pos)]; + const storage::ObIMemtable *imemtable = tables_[get_memtable_idx(pos)]; const ObLockMemtable *memtable = nullptr; if (OB_ISNULL(imemtable)) { ret = OB_NOT_INIT; @@ -174,23 +172,7 @@ int64_t ObLockMemtableMgr::to_string(char *buf, const int64_t buf_len) const return pos; } -int ObLockMemtableMgr::unregister_from_common_checkpoint_(const ObLockMemtable *memtable) -{ - int ret = OB_SUCCESS; - ObLSTxService *ls_tx_svr = nullptr; - if (OB_ISNULL(ls_tx_svr = freezer_->get_ls_tx_svr())) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("ls_tx_svr is null", K(ret)); - } else if (OB_FAIL(ls_tx_svr->unregister_common_checkpoint(checkpoint::LOCK_MEMTABLE_TYPE, - memtable))) { - LOG_WARN("lock memtable unregister_common_checkpoint failed", K(ret), K(ls_id_), K(memtable)); - } else { - LOG_INFO("unregister from common checkpoint successfully", K_(ls_id), K(memtable)); - } - return ret; -} - -int ObLockMemtableMgr::release_head_memtable_(ObIMemtable *imemtable, +int ObLockMemtableMgr::release_head_memtable_(storage::ObIMemtable *imemtable, const bool force) { int ret = OB_SUCCESS; @@ -203,9 +185,6 @@ int ObLockMemtableMgr::release_head_memtable_(ObIMemtable *imemtable, const int64_t idx = get_memtable_idx(memtable_head_); if (nullptr != tables_[idx] && memtable == tables_[idx]) { LOG_INFO("release head memtable", K(ret), K_(ls_id), KP(memtable)); - if (OB_TMP_FAIL(unregister_from_common_checkpoint_(memtable))) { - LOG_WARN("unregister from common checkpoint failed", K(tmp_ret), K_(ls_id), K(memtable)); - } release_head_memtable(); FLOG_INFO("succeed to release head lock table memtable", K(ret), K_(ls_id), KP(imemtable), K(memtable_head_), K(memtable_tail_)); diff --git a/src/storage/tablelock/ob_lock_memtable_mgr.h b/src/storage/tablelock/ob_lock_memtable_mgr.h index 566c13ee3..17765cfa8 100644 --- a/src/storage/tablelock/ob_lock_memtable_mgr.h +++ b/src/storage/tablelock/ob_lock_memtable_mgr.h @@ -68,7 +68,6 @@ private: private: virtual int release_head_memtable_(storage::ObIMemtable *imemtable, const bool force = false) override; - int unregister_from_common_checkpoint_(const ObLockMemtable *memtable); private: share::ObLSID ls_id_; diff --git a/src/storage/tablelock/ob_lock_table.cpp b/src/storage/tablelock/ob_lock_table.cpp index cadd6a29d..0c4b6fcd0 100644 --- a/src/storage/tablelock/ob_lock_table.cpp +++ b/src/storage/tablelock/ob_lock_table.cpp @@ -494,7 +494,8 @@ int ObLockTable::check_lock_conflict( lock_op, unused_conflict_tx_set, include_finish_tx, - only_check_dml_lock))) { + only_check_dml_lock, + param.expired_time_))) { if (ret != OB_TRY_LOCK_ROW_CONFLICT) { LOG_WARN("lock failed.", K(ret), K(lock_op)); } @@ -628,6 +629,52 @@ int ObLockTable::unlock( return ret; } +int ObLockTable::replace_lock( + ObStoreCtx &ctx, + const ObReplaceLockParam ¶m) +{ + int ret = OB_SUCCESS; + ObTableHandleV2 handle; + ObLockMemtable *memtable = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ObLockTable not inited", K(ret)); + } else if (OB_UNLIKELY(!ctx.is_write()) || + OB_UNLIKELY(!param.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(ctx), K(param)); + } else if (OB_FAIL(get_lock_memtable(handle))) { + LOG_WARN("get lock memtable failed", K(ret)); + } else if (OB_FAIL(handle.get_lock_memtable(memtable))) { + LOG_ERROR("get lock memtable from lock handle failed", K(ret)); + } else { + const int64_t unlock_timestamp = ObTimeUtility::current_time(); + ObTableLockOp unlock_op(param.lock_id_, + param.lock_mode_, + param.owner_id_, + ctx.mvcc_acc_ctx_.get_tx_id(), + OUT_TRANS_UNLOCK, + LOCK_OP_DOING, + ctx.mvcc_acc_ctx_.tx_scn_, + unlock_timestamp, + param.schema_version_); + ObTableLockOp lock_op(param.lock_id_, + param.new_lock_mode_, + param.new_owner_id_, + ctx.mvcc_acc_ctx_.get_tx_id(), + OUT_TRANS_LOCK, + LOCK_OP_DOING, + ctx.mvcc_acc_ctx_.tx_scn_, + unlock_timestamp, + param.schema_version_); + + if (OB_FAIL(memtable->replace(ctx, param, unlock_op, lock_op))) { + LOG_WARN("replace failed.", K(ret), K(param), K(unlock_op), K(lock_op)); + } + } + return ret; +} + int ObLockTable::get_lock_id_iter(ObLockIDIterator &iter) { int ret = OB_SUCCESS; @@ -672,6 +719,30 @@ int ObLockTable::get_lock_op_iter(const ObLockID &lock_id, return ret; } +int ObLockTable::replay(const void *buffer, + const int64_t nbytes, + const palf::LSN &lsn, + const share::SCN &scn) +{ + int ret = OB_SUCCESS; + ObTableHandleV2 handle; + ObLockMemtable *memtable = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + TABLELOCK_LOG(WARN, "ObLockTable not inited", K(ret)); + } else if (OB_FAIL(get_lock_memtable(handle))) { + TABLELOCK_LOG(WARN, "get lock memtable failed", K(ret)); + } else if (OB_FAIL(handle.get_lock_memtable(memtable))) { + TABLELOCK_LOG(ERROR, "get lock memtable from lock handle failed", K(ret)); + } else if (OB_FAIL(memtable->replay_split_log(buffer, + nbytes, + lsn, + scn))) { + TABLELOCK_LOG(WARN, "ObLockTable::replay failed", K(ret)); + } + return ret; +} + int ObLockTable::admin_remove_lock_op(const ObTableLockOp &op_info) { int ret = OB_SUCCESS; @@ -768,6 +839,66 @@ int ObLockTable::switch_to_leader() return ret; } +share::SCN ObLockTable::get_rec_scn() +{ + int ret = OB_SUCCESS; + share::SCN rec_scn = share::SCN::max_scn(); + ObTableHandleV2 handle; + ObLockMemtable *memtable = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + TABLELOCK_LOG(WARN, "ObLockTable not inited", K(ret)); + } else if (OB_FAIL(get_lock_memtable(handle))) { + TABLELOCK_LOG(WARN, "get lock memtable failed", K(ret)); + } else if (OB_FAIL(handle.get_lock_memtable(memtable))) { + TABLELOCK_LOG(ERROR, "get lock memtable from lock handle failed", K(ret)); + } else { + rec_scn = memtable->get_rec_scn(); + } + return rec_scn; +} + +int ObLockTable::flush(share::SCN &scn) +{ + int ret = OB_SUCCESS; + ObTableHandleV2 handle; + ObLockMemtable *memtable = nullptr; + int64_t trace_id = storage::checkpoint::INVALID_TRACE_ID; + const share::ObLSID &ls_id = parent_->get_ls_id(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + TABLELOCK_LOG(WARN, "ObLockTable not inited", K(ret)); + } else if (OB_FAIL(get_lock_memtable(handle))) { + TABLELOCK_LOG(WARN, "get lock memtable failed", K(ret)); + } else if (OB_FAIL(handle.get_lock_memtable(memtable))) { + TABLELOCK_LOG(ERROR, "get lock memtable from lock handle failed", K(ret)); + } else if (OB_FAIL(MTL(storage::checkpoint::ObCheckpointDiagnoseMgr*)->acquire_trace_id(ls_id, trace_id))) { + TABLELOCK_LOG(WARN, "acquire trace_id failed", K(ret), K(ls_id)); + } else if (OB_FAIL(memtable->flush(scn, trace_id))) { + TABLELOCK_LOG(WARN, "ObLockTable::flush failed", K(ret), K(scn)); + } + return ret; +} + +int ObLockTable::traversal_flush() +{ + int ret = OB_SUCCESS; + ObTableHandleV2 handle; + ObLockMemtable *memtable = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + TABLELOCK_LOG(WARN, "ObLockTable not inited", K(ret)); + } else if (OB_FAIL(get_lock_memtable(handle))) { + TABLELOCK_LOG(WARN, "get lock memtable failed", K(ret)); + } else if (OB_FAIL(handle.get_lock_memtable(memtable))) { + TABLELOCK_LOG(ERROR, "get lock memtable from lock handle failed", K(ret)); + } else if (OB_FAIL(memtable->flush(SCN::max_scn(), false))) { + TABLELOCK_LOG(WARN, "ObLockTable::traversal_flush failed", K(ret)); + } + return ret; +} + int ObLockTable::enable_check_tablet_status(const bool need_check) { int ret = OB_SUCCESS; @@ -789,6 +920,28 @@ int ObLockTable::enable_check_tablet_status(const bool need_check) return ret; } +int ObLockTable::table_lock_split(const common::ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids, + const transaction::ObTransID &trans_id) +{ + int ret = OB_SUCCESS; + ObTableHandleV2 handle; + ObLockMemtable *memtable = nullptr; + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + TABLELOCK_LOG(WARN, "ObLockTable not inited", K(ret)); + } else if (OB_FAIL(get_lock_memtable(handle))) { + TABLELOCK_LOG(WARN, "get lock memtable failed", K(ret)); + } else if (OB_FAIL(handle.get_lock_memtable(memtable))) { + TABLELOCK_LOG(ERROR, "get lock memtable from lock handle failed", K(ret)); + } else if (OB_FAIL(memtable->table_lock_split(src_tablet_id, + dst_tablet_ids, + trans_id))) { + TABLELOCK_LOG(WARN, "ObLockTable::table_lock_split failed", K(ret), K(src_tablet_id), K(dst_tablet_ids)); + } + return ret; +} + } // tablelock } // transaction } // oceanbase diff --git a/src/storage/tablelock/ob_lock_table.h b/src/storage/tablelock/ob_lock_table.h index 3702bdf99..6fe1440b0 100644 --- a/src/storage/tablelock/ob_lock_table.h +++ b/src/storage/tablelock/ob_lock_table.h @@ -61,6 +61,7 @@ namespace transaction namespace tablelock { struct ObLockParam; +struct ObReplaceLockParam; class ObTableLockOp; class ObLockMemtable; class ObLockMemtableMgr; @@ -103,16 +104,24 @@ public: const ObTableLockOp &lock_op, ObTxIDSet &conflict_tx_set, const bool include_finish_tx = true); - // lock a object + // lock an object // @param[in] ctx, store ctx for trans. // @param[in] param, contain the lock id, lock type and so on. int lock(storage::ObStoreCtx &ctx, const ObLockParam ¶m); - // unlock a object + // unlock an object // @param[in] ctx, store ctx for trans. - // @param[in] unlock_op, contain the lock id, lock type and so on. + // @param[in] param, contain the lock id, lock type and so on. int unlock(storage::ObStoreCtx &ctx, const ObLockParam ¶m); + // replace the lock of an object, + // it is equivalent to unlocking and locking with a new lock_op. + // In addition, the owner of new lock_op can be different with + // previous owner. + // @param[in] ctx, store ctx for trans. + // @param[in] param, contain the lock id, lock type and so on of the previous lock, and new owner_id, + // lock_mode of new lock + int replace_lock(storage::ObStoreCtx &ctx, const ObReplaceLockParam ¶m); // get all the lock id in the lock map // @param[out] iter, the iterator returned. // int get_lock_id_iter(ObLockIDIterator &iter); @@ -143,15 +152,20 @@ public: int replay(const void *buffer, const int64_t nbytes, const palf::LSN &lsn, - const share::SCN &scn) override { return OB_SUCCESS; } + const share::SCN &scn) override; // for checkpoint - share::SCN get_rec_scn() override { return share::SCN::max_scn(); } - int flush(share::SCN &rec_scn) override { return OB_SUCCESS; } + share::SCN get_rec_scn() override; + int flush(share::SCN &rec_scn) override; // for role change void switch_to_follower_forcedly() override{}; int switch_to_leader() override; int switch_to_follower_gracefully() override { return OB_SUCCESS; } int resume_leader() override { return OB_SUCCESS; } + // flush lock_memtable that flush had been failed + int traversal_flush(); + int table_lock_split(const common::ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids, + const transaction::ObTransID &trans_id); int enable_check_tablet_status(const bool need_check); diff --git a/src/storage/tablelock/ob_mem_ctx_table_lock.cpp b/src/storage/tablelock/ob_mem_ctx_table_lock.cpp index bb9ac74e1..70c5c81f4 100644 --- a/src/storage/tablelock/ob_mem_ctx_table_lock.cpp +++ b/src/storage/tablelock/ob_mem_ctx_table_lock.cpp @@ -359,10 +359,14 @@ int ObLockMemCtx::check_lock_exist( //TODO(lihongqin):check it LOG_WARN("invalid argument.", K(ret), K(lock_id), K(owner_id), K(mode)); } else { RDLockGuard guard(list_rwlock_); + int64_t lock_mode_cnt[TABLE_LOCK_MODE_COUNT] = {0}; DLIST_FOREACH(curr, lock_list_) { - if (curr->lock_op_.lock_id_ == lock_id) { + const ObTableLockOp &lock_op = curr->lock_op_; + if (lock_op.lock_id_ == lock_id) { // BE CAREFUL: get all the lock mode curr trans has got. - lock_mode_cnt_in_same_trans[get_index_by_lock_mode(curr->lock_op_.lock_mode_)]++; + if (curr->lock_op_.op_type_ != OUT_TRANS_UNLOCK) { + lock_mode_cnt_in_same_trans[get_index_by_lock_mode(curr->lock_op_.lock_mode_)]++; + } // check exist. if (curr->lock_op_.owner_id_ == owner_id && curr->lock_op_.op_type_ == op_type && /* different op type may lock twice */ diff --git a/src/storage/tablelock/ob_obj_lock.cpp b/src/storage/tablelock/ob_obj_lock.cpp index ed4d70b50..8776eba95 100644 --- a/src/storage/tablelock/ob_obj_lock.cpp +++ b/src/storage/tablelock/ob_obj_lock.cpp @@ -19,11 +19,15 @@ #include "storage/tx/ob_trans_deadlock_adapter.h" #include "storage/tx/ob_trans_define.h" #include "storage/tx/ob_trans_part_ctx.h" +#include "storage/tx/ob_trans_service.h" #include "storage/tablelock/ob_obj_lock.h" #include "storage/tablelock/ob_table_lock_common.h" #include "storage/tablelock/ob_mem_ctx_table_lock.h" #include "storage/tablelock/ob_table_lock_iterator.h" #include "storage/tablelock/ob_table_lock_rpc_struct.h" +#include "storage/tablelock/ob_lock_memtable.h" +#include "storage/tablelock/ob_table_lock_deadlock.h" +#include "storage/tx_storage/ob_ls_service.h" namespace oceanbase { @@ -45,6 +49,7 @@ static const int64_t MAX_LOCK_CNT_IN_BUCKET = 10; static const char *OB_TABLE_LOCK_NODE = "TableLockNode"; static const char *OB_TABLE_LOCK_MAP_ELEMENT = "TableLockMapEle"; static const char *OB_TABLE_LOCK_MAP = "TableLockMap"; +static const int64_t DEFAULT_RWLOCK_TIMEOUT_US = 100L * 1000L; // 100ms bool ObTableLockOpLinkNode::is_complete_outtrans_lock() const { @@ -95,6 +100,7 @@ ObOBJLock::ObOBJLock(const ObLockID &lock_id) : lock_id_(lock_id) is_deleted_ = false; row_share_ = 0; row_exclusive_ = 0; + max_split_epoch_ = SCN::invalid_scn(); memset(map_, 0, sizeof(ObTableLockOpList *) * TABLE_LOCK_MODE_COUNT); } @@ -168,25 +174,37 @@ int ObOBJLock::slow_lock( ObMemAttr attr(tenant_id, "ObTableLockOp"); // 1. check lock conflict. // 2. record lock op. - WRLockGuard guard(rwlock_); - if (is_deleted_) { + // WRLockGuard guard(rwlock_); + + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + if (param.expired_time_ != 0) { + abs_timeout_us = std::min(param.expired_time_, abs_timeout_us); + } + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(param), K(lock_op), K(abs_timeout_us)); + } else if (is_deleted_) { ret = OB_EAGAIN; } else if (OB_FAIL(check_allow_lock_(lock_op, lock_mode_cnt_in_same_trans, conflict_tx_set, - conflict_with_dml_lock))) { + conflict_with_dml_lock, + true, /* include_finish_tx */ + false, /* only_check_dml_lock */ + param.is_for_replace_))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret) { LOG_WARN("check allow lock failed", K(ret), K(lock_op)); } - } else if (OB_FAIL(get_or_create_op_list(lock_op.lock_mode_, - tenant_id, - allocator, - op_list))) { + } else if (OB_FAIL(get_or_create_op_list(lock_op.lock_mode_, tenant_id, allocator, op_list))) { LOG_WARN("get or create owner map failed.", K(ret)); } else if (OB_ISNULL(ptr = allocator.alloc(sizeof(ObTableLockOpLinkNode), attr))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("failed to alllocate ObTableLockOpLinkNode ", K(ret)); - } else if (FALSE_IT(lock_op_node = new(ptr) ObTableLockOpLinkNode())) { + } else if (FALSE_IT(lock_op_node = new (ptr) ObTableLockOpLinkNode())) { // do nothing } else if (OB_FAIL(lock_op_node->init(lock_op))) { LOG_WARN("init lock owner failed.", K(ret), K(lock_op)); @@ -268,29 +286,67 @@ int ObOBJLock::recover_lock( { int ret = OB_SUCCESS; common::ObTimeGuard timeguard("recover_lock", 10 * 1000); - if (OB_UNLIKELY(!lock_op.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument.", K(ret), K(lock_op)); - } else if (FALSE_IT(timeguard.click("start"))) { - } else if (OB_LIKELY(!lock_op.need_record_lock_op())) { - RDLockGuard guard(rwlock_); - timeguard.click("rlock"); - if (is_deleted_) { - // need retry from upper layer. - ret = OB_EAGAIN; - } else if (OB_FAIL(recover_(lock_op, allocator))) { - LOG_WARN("recover lock failed.", K(ret), K(lock_op)); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + if (lock_op.op_type_ == TABLET_SPLIT) { + // WRLockGuard guard(rwlock_); + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(lock_op), K(abs_timeout_us)); + } else { + timeguard.click("wlock"); + LOG_INFO("recover tablet_split lock_op", K(lock_op)); + if (is_deleted_) { + // need retry from upper layer. + ret = OB_EAGAIN; + } else { + max_split_epoch_ = lock_op.commit_scn_; + } } } else { - WRLockGuard guard(rwlock_); - timeguard.click("wlock"); - if (is_deleted_) { - // need retry from upper layer. - ret = OB_EAGAIN; - } else if (OB_FAIL(recover_(lock_op, allocator))) { - LOG_WARN("recover lock failed.", K(ret), K(lock_op)); + if (OB_UNLIKELY(!lock_op.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument.", K(ret), K(lock_op)); + } else if (FALSE_IT(timeguard.click("start"))) { + } else if (OB_LIKELY(!lock_op.need_record_lock_op())) { + // RDLockGuard guard(rwlock_); + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(lock_op), K(abs_timeout_us)); + } else { + timeguard.click("rlock"); + if (is_deleted_) { + // need retry from upper layer. + ret = OB_EAGAIN; + } else if (OB_FAIL(recover_(lock_op, allocator))) { + LOG_WARN("recover lock failed.", K(ret), K(lock_op)); + } + } + } else { + // WRLockGuard guard(rwlock_); + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(lock_op), K(abs_timeout_us)); + } else { + timeguard.click("wlock"); + if (is_deleted_) { + // need retry from upper layer. + ret = OB_EAGAIN; + } else if (OB_FAIL(recover_(lock_op, allocator))) { + LOG_WARN("recover lock failed.", K(ret), K(lock_op)); + } + } } } + LOG_DEBUG("recover table lock", K(ret), K(lock_op)); return ret; } @@ -341,8 +397,15 @@ int ObOBJLock::update_lock_status(const ObTableLockOp &lock_op, } else { { // update the lock status to complete - RDLockGuard guard(rwlock_); - if (is_deleted_) { + // RDLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(lock_op), K(abs_timeout_us)); + } else if (is_deleted_) { // the op is deleted, no need update its status. ret = OB_ERR_UNEXPECTED; LOG_ERROR("the lock should not be deleted while update lock status", K(ret), K(lock_op)); @@ -365,17 +428,20 @@ int ObOBJLock::update_lock_status(const ObTableLockOp &lock_op, if (OB_SUCC(ret) && lock_op.op_type_ == OUT_TRANS_UNLOCK && status == LOCK_OP_COMPLETE) { - WRLockGuard guard(rwlock_); - if (is_deleted_) { + // WRLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(lock_op), K(abs_timeout_us)); + } else if (is_deleted_) { // the op is deleted, no need update its status. LOG_WARN("the lock is deleted, no need do compact", K(lock_op)); - } else if (OB_TMP_FAIL(get_op_list(lock_op.lock_mode_, - op_list))) { + } else if (OB_TMP_FAIL(get_op_list(lock_op.lock_mode_, op_list))) { LOG_WARN("get lock list failed, no need do compact", K(tmp_ret), K(lock_op)); - } else if (OB_TMP_FAIL(compact_tablelock_(lock_op, - op_list, - allocator, - unused_is_compacted))) { + } else if (OB_TMP_FAIL(compact_tablelock_(lock_op, op_list, allocator, unused_is_compacted))) { LOG_WARN("compact tablelock failed", K(tmp_ret), K(lock_op)); } else { drop_op_list_if_empty_(lock_op.lock_mode_, op_list, allocator); @@ -429,13 +495,20 @@ int ObOBJLock::fast_lock( ObTxIDSet &conflict_tx_set) { int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + if (param.expired_time_ != 0) { + abs_timeout_us = std::min(param.expired_time_, abs_timeout_us); + } { // lock first time - RDLockGuard guard(rwlock_); - if (OB_FAIL(try_fast_lock_(lock_op, - lock_mode_cnt_in_same_trans, - conflict_tx_set))) { + // RDLockGuard guard(rwlock_); + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(param), K(lock_op), K(abs_timeout_us)); + } else if (OB_FAIL(try_fast_lock_(lock_op, lock_mode_cnt_in_same_trans, conflict_tx_set))) { if (OB_TRY_LOCK_ROW_CONFLICT != ret && OB_EAGAIN != ret) { LOG_WARN("try fast lock failed", KR(ret), K(lock_op)); } @@ -460,7 +533,10 @@ int ObOBJLock::lock( // 1. lock myself. // 2. try to lock. LOG_DEBUG("ObOBJLock::lock ", K(param), K(lock_op)); - if (OB_UNLIKELY(!lock_op.is_valid())) { + if (OB_UNLIKELY(has_splitted())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("this obj has been splitted as src_tablet, should not get lock request", K(ret), KPC(this)); + } else if (OB_UNLIKELY(!lock_op.is_valid())) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument.", K(ret), K(lock_op)); } else { @@ -515,8 +591,18 @@ int ObOBJLock::unlock( LOG_ERROR("should only slow lock op", K(ret), K(unlock_op)); } else { { - WRLockGuard guard(rwlock_); - if (!is_try_lock && OB_UNLIKELY(ObClockGenerator::getClock() >= expired_time)) { + // WRLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + if (expired_time != 0) { + abs_timeout_us = std::min(expired_time, abs_timeout_us); + } + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(unlock_op), K(abs_timeout_us)); + } else if (!is_try_lock && OB_UNLIKELY(ObClockGenerator::getClock() >= expired_time)) { ret = (ret == OB_SUCCESS ? OB_TIMEOUT : ret); LOG_WARN("unlock is timeout", K(ret), K(unlock_op)); } else if (is_deleted_) { @@ -538,6 +624,7 @@ int ObOBJLock::unlock( return ret; } + void ObOBJLock::remove_lock_op( const ObTableLockOp &lock_op, ObMalloc &allocator) @@ -561,15 +648,22 @@ void ObOBJLock::remove_lock_op( ret = OB_ERR_UNEXPECTED; LOG_WARN("invalid lock mode", K(ret), K(lock_op), K(map_index)); } else { - WRLockGuard guard(rwlock_); - op_list = map_[map_index]; - delete_lock_op_from_list_(lock_op, - op_list, - allocator); - drop_op_list_if_empty_(lock_op.lock_mode_, - op_list, - allocator); - wakeup_waiters_(lock_op); + // WRLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(lock_op), K(abs_timeout_us)); + } else { + op_list = map_[map_index]; + delete_lock_op_from_list_(lock_op, op_list, allocator); + drop_op_list_if_empty_(lock_op.lock_mode_, + op_list, + allocator); + wakeup_waiters_(lock_op); + } } LOG_DEBUG("ObOBJLock::remove_lock_op finish."); } @@ -591,16 +685,25 @@ SCN ObOBJLock::get_min_ddl_lock_committed_scn(const SCN &flushed_scn) const { int ret = OB_SUCCESS; SCN min_rec_scn = SCN::max_scn(); - RDLockGuard guard(rwlock_); - for (int i = 0; i < TABLE_LOCK_MODE_COUNT; i++) { - ObTableLockOpList *op_list = map_[i]; - if (op_list != NULL) { - DLIST_FOREACH(curr, *op_list) { - if (curr->lock_op_.op_type_ == OUT_TRANS_LOCK - && curr->lock_op_.lock_op_status_ == LOCK_OP_COMPLETE - && curr->lock_op_.commit_scn_ > flushed_scn - && curr->lock_op_.commit_scn_ < min_rec_scn) { - min_rec_scn = curr->lock_op_.commit_scn_; + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + // RDLockGuard guard(rwlock_); + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else { + for (int i = 0; i < TABLE_LOCK_MODE_COUNT; i++) { + ObTableLockOpList *op_list = map_[i]; + if (op_list != NULL) { + DLIST_FOREACH(curr, *op_list) { + if (curr->lock_op_.op_type_ == OUT_TRANS_LOCK + && curr->lock_op_.lock_op_status_ == LOCK_OP_COMPLETE + && curr->lock_op_.commit_scn_ > flushed_scn + && curr->lock_op_.commit_scn_ < min_rec_scn) { + min_rec_scn = curr->lock_op_.commit_scn_; + } } } } @@ -613,30 +716,54 @@ int ObOBJLock::get_table_lock_store_info( const SCN &freeze_scn) { int ret = OB_SUCCESS; - RDLockGuard guard(rwlock_); - for (int i = 0; i < TABLE_LOCK_MODE_COUNT; i++) { - ObTableLockOpList *op_list = map_[i]; - if (op_list != NULL) { - DLIST_FOREACH(curr, *op_list) { - if (curr->lock_op_.commit_scn_ <= freeze_scn && - (curr->is_complete_outtrans_lock() || curr->is_complete_outtrans_unlock())) { - ObTableLockOp store_info; - if(OB_FAIL(curr->get_table_lock_store_info(store_info))) { - LOG_WARN("get_table_lock_store_info failed", K(ret)); - } else if (OB_FAIL(store_arr.push_back(store_info))) { - LOG_WARN("failed to push back table lock info arr", K(ret)); + // RDLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else { + for (int i = 0; i < TABLE_LOCK_MODE_COUNT; i++) { + ObTableLockOpList *op_list = map_[i]; + if (op_list != NULL) { + DLIST_FOREACH(curr, *op_list) { + if (curr->lock_op_.commit_scn_ <= freeze_scn && + (curr->is_complete_outtrans_lock() || curr->is_complete_outtrans_unlock())) { + ObTableLockOp store_info; + if(OB_FAIL(curr->get_table_lock_store_info(store_info))) { + LOG_WARN("get_table_lock_store_info failed", K(ret)); + } else if (OB_FAIL(store_arr.push_back(store_info))) { + LOG_WARN("failed to push back table lock info arr", K(ret)); + } + } + + if (ret != OB_SUCCESS) { + break; } } - - if (ret != OB_SUCCESS) { - break; - } + } + if (ret != OB_SUCCESS) { + break; } } - if (ret != OB_SUCCESS) { - break; + } + + if (OB_SUCC(ret)) { + // store split info + SCN max_split_epoch = max_split_epoch_; + if (max_split_epoch.is_valid() && !max_split_epoch.is_min()) { + ObTableLockOp split_store_info; + split_store_info.op_type_ = TABLET_SPLIT; + split_store_info.commit_scn_ = max_split_epoch; + split_store_info.lock_id_ = lock_id_; + if (OB_FAIL(store_arr.push_back(split_store_info))) { + LOG_WARN("failed to push back table lock info arr", K(ret)); + } } } + return ret; } @@ -644,8 +771,15 @@ int ObOBJLock::compact_tablelock(ObMalloc &allocator, bool &is_compacted, const bool is_force) { int ret = OB_SUCCESS; - WRLockGuard guard(rwlock_); - if (OB_FAIL(compact_tablelock_(allocator, is_compacted, is_force))) { + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + // WRLockGuard guard(rwlock_); + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else if (OB_FAIL(compact_tablelock_(allocator, is_compacted, is_force))) { LOG_WARN("compact table lock failed", K(ret), K(is_compacted), K(is_force)); } return ret; @@ -805,7 +939,7 @@ int ObOBJLock::check_op_allow_lock_(const ObTableLockOp &lock_op) // there is no unlock op, else return OB_TRY_LOCK_ROW_CONFLICT. // 2. IN_TRANS lock: // 1) if the lock status is LOCK_OP_DOING, return OB_OBJ_LOCK_EXIST to prevent - // lock twice. + // lock twice (except obj_type is DBMS_LOCK). int map_index = 0; ObTableLockOpList *op_list = NULL; @@ -864,13 +998,67 @@ int ObOBJLock::check_allow_unlock_( return ret; } +int ObOBJLock::eliminate_conflict_caused_by_split_if_need_( + const ObTableLockOp &lock_op, + storage::ObStoreCtx &ctx) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + // WRLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), K(lock_op), KPC(this), K(abs_timeout_us)); + } else if (has_splitted()) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("this obj has been splitted as src_tablet, should not get lock request", K(ret), KPC(this)); + } else if (max_split_epoch_.is_valid()) { + ObTableLockMode curr_lock_mode = ROW_EXCLUSIVE; + int64_t conflict_modes = 0; + if (!request_lock(curr_lock_mode, lock_op.lock_mode_, conflict_modes)) { + bool conflict = true; + ObTransService *txs = NULL; + ObLSTxCtxMgr *ls_tx_ctx_mgr = NULL; + SCN min_scn; + if (OB_ISNULL(txs = MTL(ObTransService*))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("trans_service should not empty"); + } else if (OB_FAIL(txs->get_tx_ctx_mgr().get_ls_tx_ctx_mgr(ctx.ls_id_, + ls_tx_ctx_mgr))) { + LOG_WARN("get_ls_tx_ctx_mgr failed", K(ret)); + } else if (OB_FAIL(ls_tx_ctx_mgr->get_min_start_scn(min_scn))) { + LOG_WARN("get_min_start_scn failed", K(ret)); + } else if (min_scn >= max_split_epoch_) { //ensure active trans over before split + LOG_INFO("reset max_split_epoch_ when active trans over before split", + K(min_scn), K(max_split_epoch_)); + max_split_epoch_ = SCN::invalid_scn(); + conflict = false; + } + if (OB_SUCC(ret) && conflict) { + ret = OB_TRY_LOCK_ROW_CONFLICT; + } + if (OB_NOT_NULL(ls_tx_ctx_mgr)) { + if (OB_TMP_FAIL(txs->get_tx_ctx_mgr().revert_ls_tx_ctx_mgr(ls_tx_ctx_mgr))) { + ret = OB_SUCCESS == ret ? tmp_ret : ret; + LOG_WARN("revert ls tx ctx mgr with ref failed", K(ret), K(tmp_ret)); + } + } + } + } + return ret; +} + int ObOBJLock::check_allow_lock_( const ObTableLockOp &lock_op, const uint64_t lock_mode_cnt_in_same_trans[], ObTxIDSet &conflict_tx_set, bool &conflict_with_dml_lock, const bool include_finish_tx, - const bool only_check_dml_lock) + const bool only_check_dml_lock, + const bool check_for_replace) { int ret = OB_SUCCESS; int64_t conflict_modes = 0; @@ -883,7 +1071,9 @@ int ObOBJLock::check_allow_lock_( LOG_WARN("check_op_allow_lock failed.", K(ret), K(lock_op)); } } else if (OB_FAIL(get_exist_lock_mode_without_curr_trans(lock_mode_cnt_in_same_trans, - curr_lock_mode))) { + curr_lock_mode, + lock_op.create_trans_id_, + check_for_replace))) { LOG_WARN("meet unexpected error during get lock_mode without current trans", K(ret)); } else if (!request_lock(curr_lock_mode, lock_op.lock_mode_, @@ -923,6 +1113,7 @@ int ObOBJLock::check_allow_lock( const uint64_t lock_mode_cnt_in_same_trans[], ObTxIDSet &conflict_tx_set, bool &conflict_with_dml_lock, + const int64_t expired_time, ObMalloc &allocator, const bool include_finish_tx, const bool only_check_dml_lock) @@ -932,91 +1123,78 @@ int ObOBJLock::check_allow_lock( ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument.", K(ret), K(lock_op)); } else { - RDLockGuard guard(rwlock_); - ret = check_allow_lock_(lock_op, - lock_mode_cnt_in_same_trans, - conflict_tx_set, - conflict_with_dml_lock, - include_finish_tx, - only_check_dml_lock); + // RDLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + if (expired_time != 0) { + abs_timeout_us = std::min(expired_time, abs_timeout_us); + } + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(lock_op), K(abs_timeout_us)); + } else { + ret = check_allow_lock_(lock_op, + lock_mode_cnt_in_same_trans, + conflict_tx_set, + conflict_with_dml_lock, + include_finish_tx, + only_check_dml_lock); + } } return ret; } -int ObOBJLock::get_exist_lock_mode_without_curr_trans( - const uint64_t lock_mode_cnt_in_same_trans[], - ObTableLockMode &lock_mode_without_curr_trans) +int ObOBJLock::get_exist_lock_mode_without_curr_trans(const uint64_t lock_mode_cnt_in_same_trans[], + ObTableLockMode &lock_mode_without_curr_trans, + const ObTransID &trans_id, + const bool is_for_replace) { int ret = OB_SUCCESS; - lock_mode_without_curr_trans = 0x0; + ObTableLockMode lock_mode = NO_LOCK; + int64_t lock_mode_cnt[TABLE_LOCK_MODE_COUNT] = {0}; + for (int64_t i = 0; i < TABLE_LOCK_MODE_COUNT; i++) { + // 1. count the number of lock_ops for each lock_mode + lock_mode = get_lock_mode_by_index(i); + lock_mode_cnt[i] = OB_ISNULL(map_[i]) ? 0 : map_[i]->get_size(); + if (ROW_SHARE == lock_mode) { + lock_mode_cnt[i] += row_share_; + } else if (ROW_EXCLUSIVE == lock_mode) { + lock_mode_cnt[i] += row_exclusive_; + } + // 2. remove lock_modes which is held by current transaction + lock_mode_cnt[i] -= lock_mode_cnt_in_same_trans[i]; + // 2.1 recheck for replace + if (is_for_replace) { + LOG_DEBUG("recheck for replace begin", K(lock_mode), K(lock_mode_cnt[i]), K(lock_mode_cnt_in_same_trans[i])); + // Only one case should be recehcked: lock_mode of this obj is exsited, + // but there's no this lock_mode actually becuase current transaction + // has unlocked it in the replace progress. + // It happens because there may be 2 lock_ops with the same lock_mode + // in the replace situation, 1 is lock_op which is completed, and the + // other is unlock_op which is still doing. It means this lock_mode has + // no locks on it now. + if (lock_mode_cnt[i] >= 2) { + bool allow_replace = false; + if (OB_FAIL(check_allow_replace_from_list_(map_[i], trans_id, allow_replace))) { + LOG_WARN("check allow replace failed", K(i)); + } else if (allow_replace) { + lock_mode_cnt[i] = 0; + } + } + LOG_DEBUG("recheck for replace end", K(lock_mode), K(lock_mode_cnt[i]), K(lock_mode_cnt_in_same_trans[i])); + } + // 2.2 check valid for the lock op of current transaction + check_curr_trans_lock_is_valid_(lock_mode_cnt_in_same_trans, lock_mode_cnt); - int row_share_not_in_curr_trans = get_exist_lock_mode_cnt_without_curr_trans_(ROW_SHARE, lock_mode_cnt_in_same_trans); - int row_exclusive_not_in_curr_trans = - get_exist_lock_mode_cnt_without_curr_trans_(ROW_EXCLUSIVE, lock_mode_cnt_in_same_trans); - int share_not_in_curr_trans = get_exist_lock_mode_cnt_without_curr_trans_(SHARE, lock_mode_cnt_in_same_trans); - int share_row_exclusive_not_in_curr_trans = - get_exist_lock_mode_cnt_without_curr_trans_(SHARE_ROW_EXCLUSIVE, lock_mode_cnt_in_same_trans); - int exclusive_not_in_curr_trans = get_exist_lock_mode_cnt_without_curr_trans_(EXCLUSIVE, lock_mode_cnt_in_same_trans); - - if (OB_UNLIKELY(row_share_not_in_curr_trans < 0 || row_exclusive_not_in_curr_trans < 0 || share_not_in_curr_trans < 0 - || share_row_exclusive_not_in_curr_trans < 0 || exclusive_not_in_curr_trans < 0)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("lock_mode count should not be negative", - K(row_share_not_in_curr_trans), - K(row_exclusive_not_in_curr_trans), - K(share_not_in_curr_trans), - K(share_row_exclusive_not_in_curr_trans), - K(exclusive_not_in_curr_trans)); - } else if (OB_UNLIKELY(lock_mode_cnt_in_same_trans[get_index_by_lock_mode(ROW_SHARE)] > 0 - && exclusive_not_in_curr_trans > 0)) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("current trans has rs lock, others should not have x lock", - K(lock_mode_cnt_in_same_trans), - K(exclusive_not_in_curr_trans)); - } else if (OB_UNLIKELY(lock_mode_cnt_in_same_trans[get_index_by_lock_mode(ROW_EXCLUSIVE)] > 0 - && (share_not_in_curr_trans > 0 || share_row_exclusive_not_in_curr_trans > 0 - || exclusive_not_in_curr_trans))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("current trans has rx lock, others should not have s/srx/x lock", - K(share_not_in_curr_trans), - K(share_row_exclusive_not_in_curr_trans), - K(exclusive_not_in_curr_trans)); - } else if (OB_UNLIKELY(lock_mode_cnt_in_same_trans[get_index_by_lock_mode(SHARE)] > 0 - && (row_exclusive_not_in_curr_trans > 0 || share_row_exclusive_not_in_curr_trans > 0 - || exclusive_not_in_curr_trans > 0))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("current trans has s lock, others should not have rx/srx/x lock", - K(row_exclusive_not_in_curr_trans), - K(share_row_exclusive_not_in_curr_trans), - K(exclusive_not_in_curr_trans)); - } else if (OB_UNLIKELY(lock_mode_cnt_in_same_trans[get_index_by_lock_mode(SHARE_ROW_EXCLUSIVE)] > 0 - && (row_exclusive_not_in_curr_trans > 0 || share_not_in_curr_trans > 0 - || share_row_exclusive_not_in_curr_trans > 0 || exclusive_not_in_curr_trans > 0))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("current trans has srx lock, others should not have rx/s/srx/x lock", - K(row_exclusive_not_in_curr_trans), - K(share_not_in_curr_trans), - K(share_row_exclusive_not_in_curr_trans), - K(exclusive_not_in_curr_trans)); - } else if (OB_UNLIKELY(lock_mode_cnt_in_same_trans[get_index_by_lock_mode(EXCLUSIVE)] > 0 - && (row_share_not_in_curr_trans > 0 || row_exclusive_not_in_curr_trans > 0 - || share_not_in_curr_trans > 0 || share_row_exclusive_not_in_curr_trans > 0 - || exclusive_not_in_curr_trans > 0))) { - ret = OB_ERR_UNEXPECTED; - LOG_ERROR("current trans has x lock, others should not have any locks", - K(row_share_not_in_curr_trans), - K(row_exclusive_not_in_curr_trans), - K(share_not_in_curr_trans), - K(share_row_exclusive_not_in_curr_trans), - K(exclusive_not_in_curr_trans)); - } else { - lock_mode_without_curr_trans |= (row_share_not_in_curr_trans == 0 ? 0 : ROW_SHARE); - lock_mode_without_curr_trans |= (row_exclusive_not_in_curr_trans == 0 ? 0 : ROW_EXCLUSIVE); - lock_mode_without_curr_trans |= (share_not_in_curr_trans == 0 ? 0 : SHARE); - lock_mode_without_curr_trans |= (share_row_exclusive_not_in_curr_trans == 0 ? 0 : SHARE_ROW_EXCLUSIVE); - lock_mode_without_curr_trans |= (exclusive_not_in_curr_trans == 0 ? 0 : EXCLUSIVE); + // 3. set the lock_mode without current transaction + lock_mode_without_curr_trans |= (lock_mode_cnt[i] > 0 ? lock_mode : 0); } + LOG_DEBUG("get_exist_lock_mode_without_cur_trans", + K(lock_mode_without_curr_trans), + K(is_for_replace)); return ret; } @@ -1037,8 +1215,18 @@ void ObOBJLock::reset_(ObMalloc &allocator) } void ObOBJLock::reset(ObMalloc &allocator) { - WRLockGuard guard(rwlock_); - reset_(allocator); + int ret = OB_SUCCESS; + // WRLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else { + reset_(allocator); + } } void ObOBJLock::reset_without_lock(ObMalloc &allocator) @@ -1048,8 +1236,18 @@ void ObOBJLock::reset_without_lock(ObMalloc &allocator) void ObOBJLock::print() const { - RDLockGuard guard(rwlock_); - print_(); + // RDLockGuard guard(rwlock_); + int ret = OB_SUCCESS; + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else { + print_(); + } } void ObOBJLock::print_without_lock() const @@ -1075,14 +1273,22 @@ int ObOBJLock::get_lock_op_iter(const ObLockID &lock_id, ObLockOpIterator &iter) const { int ret = OB_SUCCESS; - RDLockGuard guard(rwlock_); - ObTableLockOpList *op_list = NULL; - for (int i = 0; OB_SUCC(ret) && i < TABLE_LOCK_MODE_COUNT; i++) { - op_list = map_[i]; - if (NULL != op_list) { - if (OB_FAIL(get_lock_op_list_iter_(op_list, - iter))) { - TABLELOCK_LOG(WARN, "get lock op list iter failed", K(ret), K(i)); + // RDLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else { + ObTableLockOpList *op_list = NULL; + for (int i = 0; OB_SUCC(ret) && i < TABLE_LOCK_MODE_COUNT; i++) { + op_list = map_[i]; + if (NULL != op_list) { + if (OB_FAIL(get_lock_op_list_iter_(op_list, iter))) { + TABLELOCK_LOG(WARN, "get lock op list iter failed", K(ret), K(i)); + } } } } @@ -1119,6 +1325,221 @@ int ObOBJLock::get_lock_op_iter(const ObLockID &lock_id, return ret; } +int ObOBJLock::reset_split_epoch() +{ + int ret = OB_SUCCESS; + // WRLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else if (OB_FAIL(reset_split_epoch_())) { + LOG_WARN("reset split epoch failed", KPC(this)); + } + return ret; +} + +int ObOBJLockMap::add_split_epoch(const ObLockID &lock_id, + const share::SCN &split_epoch, + const bool for_replay) +{ + int ret = OB_SUCCESS; + ObOBJLock *obj_lock = NULL; + do { + if (OB_FAIL(get_or_create_obj_lock_with_ref_(lock_id, obj_lock))) { + LOG_WARN("get_or_create_obj_lock_with_ref failed", K(ret), K(lock_id)); + } else if (OB_FAIL(obj_lock->set_split_epoch(split_epoch, for_replay))) { + LOG_WARN("set_split_epoch failed", K(lock_id), K(split_epoch), K(ret), K(for_replay)); + } else { + LOG_INFO("add_split_epoch successfully", K(split_epoch), K(lock_id)); + } + + if (OB_NOT_NULL(obj_lock)) { + lock_map_.revert(obj_lock); + } + } while (OB_EAGAIN == ret); + return ret; +} + +int ObOBJLockMap::add_split_epoch(const ObSArray &lock_ids, + const share::SCN &split_epoch, + const bool for_replay) +{ + int ret = OB_SUCCESS; + ObOBJLock *obj_lock = NULL; + ObSArray added_obj_locks; + for (int64_t i = 0; OB_SUCC(ret) && i < lock_ids.count(); i++) { + do { + if (OB_FAIL(get_or_create_obj_lock_with_ref_(lock_ids[i], obj_lock))) { + LOG_WARN("get_or_create_obj_lock_with_ref failed", K(ret), K(lock_ids[i])); + } else if (OB_ISNULL(obj_lock)) { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("obj_lock is null after get_or_create_obj_lock_with_ref_ for tablet", K(ret), K(lock_ids[i])); + } else if (OB_FAIL(obj_lock->set_split_epoch(split_epoch, for_replay))) { + LOG_WARN("the obj_lock is deleted", K(obj_lock), K(split_epoch), K(ret)); + } else if (OB_FAIL(added_obj_locks.push_back(obj_lock))) { + LOG_WARN("add obj_lock into added_obj_locks failed", K(obj_lock), K(added_obj_locks.count())); + if (OB_FAIL(obj_lock->reset_split_epoch())) { + ret = OB_ERR_UNEXPECTED; // the obj_lock with valid max_split_epoch_ should not be deleted + LOG_ERROR("meet fails when push obj_lock to added_obj_locks, and reset it fails", K(ret), K(obj_lock)); + } + } else { + LOG_INFO("add_split_epoch successfully", K(split_epoch), K(lock_ids[i])); + } + // If meet fails, the last obj_lock is not in the added_obj_locks, + // so we shuold revert it individually. + if (OB_FAIL(ret) && OB_NOT_NULL(obj_lock)) { + lock_map_.revert(obj_lock); + } + } while (OB_EAGAIN == ret); + } + + // If meet fails, reset split epoch for all destination + // table locks which has been set before. + if (OB_FAIL(ret)) { + int tmp_ret = OB_SUCCESS; + for (int64_t i = 0; i < added_obj_locks.count(); i++) { + if (OB_ISNULL(obj_lock = added_obj_locks[i])) { + tmp_ret = OB_INVALID_ARGUMENT; + LOG_ERROR("obj_lock is null in added_obj_locks", K(ret), K(tmp_ret), K(i)); + } else if (OB_TMP_FAIL(obj_lock->reset_split_epoch())) { + ret = OB_ERR_UNEXPECTED; // the obj_lock with valid max_split_epoch_ should not be deleted + LOG_ERROR("reset_split_epoch failed", K(ret), K(tmp_ret), KPC(obj_lock), K(split_epoch)); + } + if (OB_NOT_NULL(obj_lock)) { + lock_map_.revert(obj_lock); + } + } + } + + return ret; +} + +int ObOBJLockMap::get_split_epoch(const ObLockID &lock_id, + share::SCN &split_epoch) +{ + int ret = OB_SUCCESS; + ObOBJLock *obj_lock = NULL; + do { + if (OB_FAIL(get_obj_lock_with_ref_(lock_id, obj_lock))) { + LOG_WARN("get_or_create_obj_lock_with_ref failed", K(ret), K(lock_id)); + } else if (OB_FAIL(obj_lock->get_split_epoch(split_epoch))) { + LOG_WARN("the obj_lock is deleted", K(lock_id), K(split_epoch), K(ret)); + } + if (OB_NOT_NULL(obj_lock)) { + lock_map_.revert(obj_lock); + } + } while (OB_EAGAIN == ret); + return ret; +} + +int ObOBJLock::table_lock_split(const ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids, + const transaction::ObTransID &trans_id, + ObLockTableSplitLogCb &callback) +{ + int ret = OB_SUCCESS; + // WRLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + + if (OB_FAIL(ret)) { + if (callback.is_logging_) { + ret = OB_TABLE_LOCK_IS_SPLITTING; + LOG_WARN("table lock of this tablet is splitting", + K(ret), + KPC(this), + K(src_tablet_id), + K(dst_tablet_ids), + K(trans_id), + K(abs_timeout_us)); + } else if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", + K(ret), + KPC(this), + K(src_tablet_id), + K(dst_tablet_ids), + K(trans_id), + K(abs_timeout_us)); + } else { + bool exist_cannot_split_lock = exist_cannot_split_lock_(trans_id); + bool need_split = need_split_(); + + if (!exist_cannot_split_lock && need_split) { + if (OB_FAIL(submit_log_(callback, src_tablet_id, dst_tablet_ids))) { + LOG_WARN("submit log for splitting table lock failed", K(src_tablet_id), K(dst_tablet_ids), K(trans_id)); + } else { + // To ensure the safety of the ObLockTableSplitLogCb in the lock_memtable, + // we should hold the handle of the lock memtable during the callback is logging + // (include submit log and wait for callback on_success or on_failure) + LOG_WARN("finish log, wait for callback"); + while (callback.is_logging_) { + if (REACH_TIME_INTERVAL(3 * 1000 * 1000)) { + LOG_INFO("wait for the table lock split callback", K(ret), K(src_tablet_id), K(dst_tablet_ids)); + } + ob_usleep(1000 * 1000); + } + // table lock split sucessfully on src_tablet, can not be rollbacked later + if (callback.cb_success()) { + set_split_epoch_(share::SCN::max_scn()); + } + } + } + if (exist_cannot_split_lock) { + ret = OB_NOT_SUPPORTED; + print(); + LOG_WARN("exist can not split lock", K(ret), K(lock_id_), K(src_tablet_id)); + } + if (!need_split) { + if (has_splitted()) { + ret = OB_TABLE_LOCK_SPLIT_TWICE; + LOG_WARN("table lock has splitted", K(ret), KPC(this)); + } + LOG_WARN("no need to split table lock", K(ret), KPC(this)); + } + } + return ret; +} + +int ObOBJLock::set_split_epoch(const share::SCN &scn, const bool for_replay) +{ + int ret = OB_SUCCESS; + // WRLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else if (OB_FAIL(set_split_epoch_(scn, for_replay))) { + LOG_WARN("set split epoch failed", KPC(this), K(scn), K(for_replay)); + } + return ret; +} + +int ObOBJLock::get_split_epoch(share::SCN &scn) +{ + int ret = OB_SUCCESS; + // RDLockGuard guard(rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + RDLockGuardWithTimeout guard(rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(this), K(abs_timeout_us)); + } else if (OB_FAIL(get_split_epoch_(scn))) { + LOG_WARN("get split epoch failed", KPC(this)); + } + return ret; +} + int ObOBJLock::size_without_lock() const { int map_size = 0; @@ -1268,6 +1689,53 @@ int ObOBJLock::check_op_allow_lock_from_list_( return ret; } +int ObOBJLock::check_allow_replace_from_list_(ObTableLockOpList *op_list, const ObTransID &trans_id, bool &allow_replace) +{ + int ret = OB_SUCCESS; + hash::ObHashMap lock_op_map; + int32_t lock_op_cnt = op_list->get_size(); + + allow_replace = false; + ObTableLockOwnerID owner_id; + ObTableLockOp *lock_op = nullptr; + + LOG_DEBUG("start check_allow_replace_from_list_", K(lock_op_cnt)); + if (OB_FAIL(lock_op_map.create(10, lib::ObMemAttr(MTL_ID(), "TableLockOpMap")))) { + LOG_WARN("create lock_map for replace check failed", K(ret)); + } else { + DLIST_FOREACH_NORET(curr, *op_list) + { + int64_t owner_id = curr->get_owner_id().id(); + if (FALSE_IT(lock_op = lock_op_map.get(owner_id))) { + } else { + if (OB_ISNULL(lock_op)) { + LOG_DEBUG("lock_op not in the map, will set it", K(curr->lock_op_)); + if (OB_FAIL(lock_op_map.set_refactored(owner_id, curr->lock_op_))) { + LOG_WARN("set lock_op into map failed", K(ret), K(curr->lock_op_)); + } + } else if ((OUT_TRANS_LOCK == lock_op->op_type_ && OUT_TRANS_UNLOCK == curr->lock_op_.op_type_ + && LOCK_OP_COMPLETE == lock_op->lock_op_status_ && LOCK_OP_DOING == curr->lock_op_.lock_op_status_ + && trans_id == curr->lock_op_.create_trans_id_) + || (OUT_TRANS_UNLOCK == lock_op->op_type_ && OUT_TRANS_LOCK == curr->lock_op_.op_type_ + && LOCK_OP_DOING == lock_op->lock_op_status_ + && LOCK_OP_COMPLETE == curr->lock_op_.lock_op_status_ + && trans_id == lock_op->create_trans_id_)) { + LOG_DEBUG("find matched lock_op, will remove them", K(lock_op_cnt), KPC(lock_op), K(curr->lock_op_)); + lock_op_cnt -= 2; + } else { + allow_replace = false; + break; + } + } + } + } + LOG_DEBUG("finsih check_allow_replace_from_list_", K(lock_op_cnt)); + if (OB_SUCC(ret) && 0 == lock_op_cnt) { + allow_replace = true; + } + return ret; +} + void ObOBJLock::delete_lock_op_from_list_( const ObTableLockOp &lock_op, ObTableLockOpList *&op_list, @@ -1521,6 +1989,249 @@ int ObOBJLock::compact_tablelock_(ObMalloc &allocator, return ret; } +int ObOBJLock::register_into_deadlock_detector_(const ObStoreCtx &ctx, + const ObTableLockOp &lock_op) +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + ObTransLockPartID tx_lock_part_id; + ObAddr parent_addr; + const ObLSID &ls_id = ctx.ls_id_; + const int64_t priority = ~(ctx.mvcc_acc_ctx_.tx_desc_->get_active_ts()); + tx_lock_part_id.lock_id_ = lock_op.lock_id_; + tx_lock_part_id.trans_id_ = lock_op.create_trans_id_; + if (OB_FAIL(ObTableLockDeadlockDetectorHelper::register_trans_lock_part( + tx_lock_part_id, ls_id, priority))) { + LOG_WARN("register trans lock part failed", K(ret), K(tx_lock_part_id), + K(ls_id)); + } else if (OB_FAIL(ObTransDeadlockDetectorAdapter::get_trans_scheduler_info_on_participant( + tx_lock_part_id.trans_id_, ls_id, parent_addr))) { + LOG_WARN("get scheduler address failed", K(tx_lock_part_id), K(ls_id)); + } else if (OB_FAIL(ObTableLockDeadlockDetectorHelper::add_parent( + tx_lock_part_id, parent_addr, lock_op.create_trans_id_))) { + LOG_WARN("add parent failed", K(ret), K(tx_lock_part_id)); + } else if (OB_FAIL(ObTableLockDeadlockDetectorHelper::block(tx_lock_part_id, + ls_id, + lock_op))) { + LOG_WARN("add dependency failed", K(ret), K(tx_lock_part_id)); + } else { + LOG_DEBUG("succeed register to the dead lock detector"); + } + if (OB_FAIL(ret)) { + if (OB_SUCCESS != (tmp_ret = ObTableLockDeadlockDetectorHelper:: + unregister_trans_lock_part(tx_lock_part_id))) { + if (tmp_ret != OB_ENTRY_NOT_EXIST) { + LOG_WARN("unregister from deadlock detector failed", K(ret), + K(tx_lock_part_id)); + } + } + } + return ret; +} + +int ObOBJLock::unregister_from_deadlock_detector_(const ObTableLockOp &lock_op) +{ + int ret = OB_SUCCESS; + ObTransLockPartID tx_lock_part_id; + tx_lock_part_id.lock_id_ = lock_op.lock_id_; + tx_lock_part_id.trans_id_ = lock_op.create_trans_id_; + if (OB_FAIL(ObTableLockDeadlockDetectorHelper::unregister_trans_lock_part( + tx_lock_part_id))) { + LOG_WARN("unregister trans lock part failed", K(ret), K(tx_lock_part_id)); + } else { + // do nothing + } + return ret; +} + +bool ObOBJLock::exist_cannot_split_lock_(const ObTransID &split_start_trans_id) const +{ + int ret = OB_SUCCESS; + bool exist_cannot_split_lock = false; + ObTableLockOpList *op_list = NULL; + for (int i = 0; i < TABLE_LOCK_MODE_COUNT; i++) { + op_list = map_[i]; + if (NULL != op_list) { + DLIST_FOREACH_NORET(curr, *op_list) { + if (NULL != curr && + curr->lock_op_.create_trans_id_ != split_start_trans_id) { + exist_cannot_split_lock = true; + break; + } + } + } else { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("op_list of this obj_lock is null!", K(lock_id_)); + } + } + return exist_cannot_split_lock; +} + +bool ObOBJLock::need_split_() const +{ + // The split transaction will lock src_tablet with RX OUT_TRANS_LOCK, so there're + // no share and exclusive locks on the src_tablet. + // So we can only consider about splitting RS and RX locks on the src_tablet. + // In addition, if the max_split_epoch_ is valid but not min_scn, it means that + // we have gotten into splitting process before but it didn't finish, so it still + // needs split. (It may be a continuous splitting scenario.) + // And if the max_split_epoch_ is max_scn, it means that it has been splitted, + // so it doesn't need split. + return (row_exclusive_ != 0) || (row_share_ != 0) + || (max_split_epoch_.is_valid() && !max_split_epoch_.is_min() && !max_split_epoch_.is_max()); +} + +int ObOBJLock::submit_log_(ObLockTableSplitLogCb &callback, + common::ObTabletID src_tablet_id, + const ObSArray &dst_tablet_ids) +{ + int ret = OB_SUCCESS; + ObLSID ls_id; + + if (!callback.is_logging_) { + callback.is_logging_ = true; + ObLockTableSplitLog split_log; + if (OB_FAIL(split_log.init(src_tablet_id, dst_tablet_ids))) { + LOG_WARN("init split_log failed", K(ret), K(src_tablet_id), K(dst_tablet_ids)); + } else if (OB_FAIL(callback.set(src_tablet_id, dst_tablet_ids))) { + LOG_WARN("set split_log_cb failed", K(ret), K(src_tablet_id), K(dst_tablet_ids)); + } else { + char *buffer = nullptr; + int64_t pos = 0; + int64_t buffer_size = split_log.get_serialize_size(); + + logservice::ObLogBaseHeader base_header(logservice::ObLogBaseType::TABLE_LOCK_LOG_BASE_TYPE, + logservice::ObReplayBarrierType::NO_NEED_BARRIER); + buffer_size += base_header.get_serialize_size(); + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + const bool need_nonblock = false; + palf::LSN lsn; + SCN scn; + ObMemAttr attr(MTL_ID(), "SplitLog"); + if (OB_ISNULL(buffer = static_cast(mtl_malloc(buffer_size, attr)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc buffer", K(ret)); + } else if (OB_FAIL(base_header.serialize(buffer, buffer_size, pos))) { + LOG_WARN("failed to serialize split log header", K(ret), K(buffer_size), K(pos)); + } else if (OB_FAIL(split_log.serialize(buffer, buffer_size, pos))) { + LOG_WARN("failed to serialize split log", K(ret), K(buffer_size), K(pos)); + } else if (OB_ISNULL(ls_service = MTL(ObLSService *))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("mtl ObLSService should not be null", K(ret)); + } else if (OB_FAIL(ls_service->get_ls(callback.ls_id_, ls_handle, ObLSGetMod::OBSERVER_MOD))) { + LOG_WARN("failed to get ls", K(ret)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", K(ret)); + } else if (OB_FAIL(ls->append(buffer, buffer_size, SCN::min_scn(), need_nonblock, false/*allow_compression*/, &callback, lsn, scn))) { + LOG_WARN("failed to submit log", K(ret), K(buffer_size), K(pos)); + } else { + // These params should be gotten after append log to LS, + // so we need to use lock to avoid LS can read callback + // before these params have been set into it. + callback.last_submit_scn_ = scn; + callback.last_submit_log_ts_ = ObTimeUtility::current_time(); + LOG_INFO("submit split log success", K(scn), K(callback), K(src_tablet_id), K(dst_tablet_ids)); + } + if (nullptr != buffer) { + mtl_free(buffer); + buffer = nullptr; + } + } + if (OB_FAIL(ret)) { + callback.is_logging_ = false; + } + } else if (callback.last_submit_log_ts_ == OB_INVALID_TIMESTAMP) { + LOG_WARN("callback is logging, but hasn't submitted log", K(ret), K(callback)); + } else if (ObTimeUtility::current_time() - callback.last_submit_log_ts_ > + SUBMIT_LOG_ALARM_INTERVAL && REACH_TIME_INTERVAL(1000L * 1000L)) { + LOG_WARN("maybe submit log callback use too mush time", K(ret), K(callback)); + } + + return ret; +} + +int ObOBJLock::set_split_epoch_(const share::SCN &scn, const bool for_replay) +{ + int ret = OB_SUCCESS; + if (is_deleted_) { + ret = OB_EAGAIN; + LOG_WARN("the obj_lock is_deleted, and need retry", K(ret)); + } else if (!for_replay && max_split_epoch_ > scn) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN( + "the input scn is smaller than max_split_epoch_, so we ignore this set_split_epoch", K(max_split_epoch_), K(scn)); + } else { + max_split_epoch_.inc_update(scn); + } + return ret; +} + +int ObOBJLock::get_split_epoch_(share::SCN &scn) +{ + int ret = OB_SUCCESS; + if (is_deleted_) { + ret = OB_EAGAIN; + LOG_WARN("the obj_lock is_deleted, and need retry", K(ret)); + } else { + scn = max_split_epoch_; + } + return ret; +} + +int ObOBJLock::reset_split_epoch_() +{ + int ret = OB_SUCCESS; + if (is_deleted_) { + ret = OB_EAGAIN; + LOG_WARN("the obj_lock is_deleted, and need retry", K(ret), K(max_split_epoch_)); + } else { + max_split_epoch_ = SCN::invalid_scn(); + } + return ret; +} + +void ObOBJLock::check_curr_trans_lock_is_valid_(const uint64_t lock_mode_cnt_in_same_trans[], const int64_t *lock_mode_cnt) +{ + int err_code = 0; + int64_t exclusive_cnt = lock_mode_cnt[get_index_by_lock_mode(EXCLUSIVE)]; + int64_t share_row_exclusive_cnt = lock_mode_cnt[get_index_by_lock_mode(SHARE_ROW_EXCLUSIVE)]; + int64_t share_cnt = lock_mode_cnt[get_index_by_lock_mode(SHARE)]; + int64_t row_exclusive_cnt = lock_mode_cnt[get_index_by_lock_mode(ROW_EXCLUSIVE)]; + int64_t row_share_cnt = lock_mode_cnt[get_index_by_lock_mode(ROW_SHARE)]; + + if (lock_mode_cnt_in_same_trans[get_index_by_lock_mode(EXCLUSIVE)] > 0) { + if (row_share_cnt > 1 || row_exclusive_cnt > 1 || + share_cnt > 1 || share_row_exclusive_cnt > 1 || exclusive_cnt > 1) { + err_code = 1; + } + } else if (lock_mode_cnt_in_same_trans[get_index_by_lock_mode(SHARE_ROW_EXCLUSIVE)] > 0) { + if (row_exclusive_cnt > 1 || share_cnt > 1 || share_row_exclusive_cnt > 1) { + err_code = 2; + } + } else if (lock_mode_cnt_in_same_trans[get_index_by_lock_mode(SHARE)] > 0) { + if (row_exclusive_cnt > 1 || share_row_exclusive_cnt > 1) { + err_code = 3; + } + } else if (lock_mode_cnt_in_same_trans[get_index_by_lock_mode(ROW_EXCLUSIVE)] > 0) { + if (share_cnt > 1 || share_row_exclusive_cnt > 1) { + err_code = 4; + } + } + if (err_code) { + LOG_ERROR_RET(OB_ERR_UNEXPECTED, + "unexpected error", + K(err_code), + K(row_share_cnt), + K(row_exclusive_cnt), + K(share_cnt), + K(share_row_exclusive_cnt), + K(exclusive_cnt)); + } +} + int ObOBJLock::get_or_create_op_list(const ObTableLockMode mode, const uint64_t tenant_id, ObMalloc &allocator, @@ -1843,11 +2554,8 @@ int ObOBJLockMap::unlock( obj_lock = NULL; if (OB_FAIL(get_obj_lock_with_ref_(lock_op.lock_id_, obj_lock))) { + } else if (OB_FAIL(obj_lock->unlock(lock_op, is_try_lock, expired_time, allocator_))) { LOG_WARN("get lock op list map failed.", K(ret), K(lock_op)); - } else if (OB_FAIL(obj_lock->unlock(lock_op, - is_try_lock, - expired_time, - allocator_))) { if (ret != OB_EAGAIN) { LOG_WARN("create unlock op failed.", K(ret), K(lock_op)); } @@ -1910,14 +2618,23 @@ int ObOBJLockMap::remove_lock(const ObLockID &lock_id) LOG_WARN("get lock map failed.", K(ret), K(lock_id)); } } else { - WRLockGuard guard(obj_lock->rwlock_); - obj_lock->set_deleted(); - obj_lock->reset_without_lock(allocator_); - if (OB_FAIL(lock_map_.del(lock_id, obj_lock))) { - if (ret != OB_ENTRY_NOT_EXIST) { - LOG_WARN("remove lock owner list map failed. ", K(ret), K(lock_id)); - } else { - ret = OB_OBJ_LOCK_NOT_EXIST; + // WRLockGuard guard(obj_lock->rwlock_); + int abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(obj_lock->rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(obj_lock), K(abs_timeout_us)); + } else { + obj_lock->set_deleted(); + obj_lock->reset_without_lock(allocator_); + if (OB_FAIL(lock_map_.del(lock_id, obj_lock))) { + if (ret != OB_ENTRY_NOT_EXIST) { + LOG_WARN("remove lock owner list map failed. ", K(ret), K(lock_id)); + } else { + ret = OB_OBJ_LOCK_NOT_EXIST; + } } } } @@ -2001,6 +2718,7 @@ int ObOBJLockMap::check_allow_lock( const ObTableLockOp &lock_op, const uint64_t lock_mode_cnt_in_same_trans[], ObTxIDSet &conflict_tx_set, + const int64_t expired_time, const bool include_finish_tx, const bool only_check_dml_lock) { @@ -2028,6 +2746,7 @@ int ObOBJLockMap::check_allow_lock( lock_mode_cnt_in_same_trans, conflict_tx_set, conflict_with_dml_lock, + expired_time, allocator_, include_finish_tx, only_check_dml_lock))) { @@ -2044,6 +2763,64 @@ int ObOBJLockMap::check_allow_lock( return ret; } +int ObOBJLockMap::table_lock_split(const ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids, + const transaction::ObTransID &trans_id, + ObLockTableSplitLogCb &callback) +{ + int ret = OB_SUCCESS; + ObLockID src_lock_id; + ObOBJLock *src_obj_lock = nullptr; + if (OB_FAIL(get_lock_id(src_tablet_id, src_lock_id))) { + LOG_WARN("get_lock_id for src_tablet failed", K(ret), K(src_tablet_id)); + } else if (OB_FAIL(get_obj_lock_with_ref_(src_lock_id, src_obj_lock))) { + LOG_WARN("get_obj_lock_with_ref_ for src_tablet failed", K(ret), K(src_lock_id), K(src_tablet_id)); + } else if (src_obj_lock->has_splitted()) { + ret = OB_TABLE_LOCK_SPLIT_TWICE; + LOG_WARN("src_tablet has spliitted", K(ret), K(src_lock_id), K(src_tablet_id)); + } else { + ObSArray dst_lock_ids; + // create obj_lock for dst_tablets if it's not existed, to avoid no memory error during callback + if (OB_FAIL(get_lock_id(dst_tablet_ids, dst_lock_ids))) { + LOG_WARN("get_lock_id for dst_tablets failed", K(ret), K(dst_tablet_ids)); + } else if (OB_FAIL(add_split_epoch(dst_lock_ids, share::SCN::min_scn()))) { + LOG_WARN("add split epoch for dst_lock_ids failed", K(ret), K(dst_lock_ids)); + } else if (OB_FAIL(src_obj_lock->table_lock_split(src_tablet_id, dst_tablet_ids, trans_id, callback))) { + LOG_WARN("submit table lock split log failed", K(ret), K(src_tablet_id), K(dst_tablet_ids), K(trans_id)); + // submit table lock split failed, so we should reset split epoch for all dst_tablets, + // to make sure that GC thread can collect them later. + for (int64_t i = 0; i < dst_lock_ids.count(); i++) { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(reset_split_epoch(dst_lock_ids[i]))) { + LOG_ERROR("reset_split_epoch for dst_tablet failed", K(ret), K(tmp_ret), K(dst_lock_ids[i])); + } + } + } + } + if (OB_NOT_NULL(src_obj_lock)) { + lock_map_.revert(src_obj_lock); + } + return ret; +} + +int ObOBJLockMap::reset_split_epoch(const ObLockID &lock_id) +{ + int ret = OB_SUCCESS; + ObOBJLock *obj_lock = NULL; + do { + if (OB_FAIL(get_obj_lock_with_ref_(lock_id, obj_lock))) { + LOG_WARN("get_or_create_obj_lock_with_ref failed", K(ret), K(lock_id)); + } else if (OB_FAIL(obj_lock->reset_split_epoch())) { + LOG_WARN("reset_split_epoch failed", K(lock_id)); + } + if (OB_NOT_NULL(obj_lock)) { + lock_map_.revert(obj_lock); + } + } while (OB_EAGAIN == ret); + + return ret; +} + void ObOBJLockMap::drop_obj_lock_if_empty_( const ObLockID &lock_id, ObOBJLock *obj_lock) @@ -2057,14 +2834,33 @@ void ObOBJLockMap::drop_obj_lock_if_empty_( LOG_WARN("invalid argument", K(ret), K(obj_lock), K(lock_id)); } else { { - RDLockGuard guard(obj_lock->rwlock_); - is_empty = (obj_lock->size_without_lock() == 0); + // RDLockGuard guard(obj_lock->rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + RDLockGuardWithTimeout guard(obj_lock->rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get read lock of obj failed", K(ret), KPC(obj_lock), K(abs_timeout_us)); + } else { + is_empty = (obj_lock->size_without_lock() == 0 + && (!obj_lock->max_split_epoch_.is_valid() || obj_lock->max_split_epoch_.is_max())); + } } if (is_empty) { - WRLockGuard guard(obj_lock->rwlock_); - // lock and delete flag make sure no one insert a new op. - // but maybe have deleted by another concurrent thread. - if (obj_lock->size_without_lock() == 0 && !obj_lock->is_deleted()) { + // WRLockGuard guard(obj_lock->rwlock_); + int64_t abs_timeout_us = ObTimeUtility::current_time() + DEFAULT_RWLOCK_TIMEOUT_US; + WRLockGuardWithTimeout guard(obj_lock->rwlock_, abs_timeout_us, ret); + if (OB_FAIL(ret)) { + if (OB_TIMEOUT == ret) { + ret = OB_EAGAIN; + } + LOG_WARN("try get write lock of obj failed", K(ret), KPC(obj_lock), K(abs_timeout_us)); + } else if (obj_lock->size_without_lock() == 0 + && (!obj_lock->max_split_epoch_.is_valid() || obj_lock->max_split_epoch_.is_max()) + && !obj_lock->is_deleted()) { + // lock and delete flag make sure no one insert a new op. + // but maybe have deleted by another concurrent thread. obj_lock->set_deleted(); if (OB_FAIL(get_obj_lock_with_ref_(lock_id, recheck_ptr))) { if (ret != OB_OBJ_LOCK_NOT_EXIST) { @@ -2087,7 +2883,6 @@ void ObOBJLockMap::drop_obj_lock_if_empty_( LOG_DEBUG("try remove lock owner list map. ", K(ret), K(is_empty), K(lock_id), K(obj_lock)); } - } } } diff --git a/src/storage/tablelock/ob_obj_lock.h b/src/storage/tablelock/ob_obj_lock.h index 58221e519..fc02dfdd2 100644 --- a/src/storage/tablelock/ob_obj_lock.h +++ b/src/storage/tablelock/ob_obj_lock.h @@ -23,7 +23,6 @@ #include "storage/tablelock/ob_table_lock_common.h" #include "storage/ob_i_store.h" - namespace oceanbase { @@ -49,12 +48,15 @@ class ObTransID; namespace tablelock { struct ObLockParam; +class ObLockTableSplitLogCb; //typedef common::ObSEArray ObTxIDArray; typedef common::hash::ObIteratableHashSet ObTxIDSet; using RWLock = common::TCRWLock; using RDLockGuard = common::TCRLockGuard; using WRLockGuard = common::TCWLockGuard; +using RDLockGuardWithTimeout = common::TCRWLock::RLockGuardWithTimeout; +using WRLockGuardWithTimeout = common::TCRWLock::WLockGuardWithTimeout; class ObTableLockOpLinkNode : public common::ObDLinkBase { @@ -83,6 +85,7 @@ typedef ObDList ObTableLockOpList; class ObOBJLock : public share::ObLightHashLink { public: + static const int64_t SUBMIT_LOG_ALARM_INTERVAL = 100 * 1000; ObOBJLock(const ObLockID &lock_id); int lock( const ObLockParam ¶m, @@ -114,6 +117,7 @@ public: const uint64_t lock_mode_cnt_in_same_trans[], ObTxIDSet &conflict_tx_set, bool &conflict_with_dml_lock, + const int64_t expired_time, ObMalloc &allocator, const bool include_finish_tx = true, const bool only_check_dml_lock = false); @@ -137,17 +141,29 @@ public: const ObLockID &get_lock_id() const { return lock_id_; } void set_lock_id(const ObLockID &lock_id) { lock_id_ = lock_id; } bool contain(const ObLockID &lock_id) { return lock_id_ == lock_id; } - TO_STRING_KV(K_(lock_id), K_(is_deleted), K_(row_share), K_(row_exclusive)); + TO_STRING_KV(K_(lock_id), K_(is_deleted), K_(row_share), K_(row_exclusive), K_(max_split_epoch)); + int table_lock_split(const ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids, + const transaction::ObTransID &trans_id, + ObLockTableSplitLogCb &callback); + bool has_splitted() const { return max_split_epoch_.is_max(); } + int set_split_epoch(const share::SCN &scn, const bool for_replay = false); + int get_split_epoch(share::SCN &scn); + int reset_split_epoch(); private: void print_() const; void reset_(ObMalloc &allocator); + int eliminate_conflict_caused_by_split_if_need_( + const ObTableLockOp &lock_op, + storage::ObStoreCtx &ctx); int check_allow_lock_( const ObTableLockOp &lock_op, const uint64_t lock_mode_cnt_in_same_trans[], ObTxIDSet &conflict_tx_set, bool &conflict_with_dml_lock, const bool include_finish_tx = true, - const bool only_check_dml_lock = false); + const bool only_check_dml_lock = false, + const bool check_for_replace = false); int update_lock_status_( const ObTableLockOp &lock_op, const share::SCN &commit_version, @@ -179,9 +195,10 @@ private: ObMalloc &allocator); int check_allow_unlock_(const ObTableLockOp &unlock_op); int check_op_allow_lock_(const ObTableLockOp &lock_op); - int get_exist_lock_mode_without_curr_trans( - const uint64_t lock_mode_cnt_in_same_trans[], - ObTableLockMode &lock_mode_without_curr_trans); + int get_exist_lock_mode_without_curr_trans(const uint64_t lock_mode_cnt_in_same_trans[], + ObTableLockMode &lock_mode_without_curr_trans, + const ObTransID &trans_id, + const bool is_for_replace = false); void check_need_recover_( const ObTableLockOp &lock_op, const ObTableLockOpList *op_list, @@ -235,6 +252,28 @@ private: ObMalloc &allocator, bool &is_compact, const bool is_force = false); + int register_into_deadlock_detector_( + const storage::ObStoreCtx &ctx, + const ObTableLockOp &lock_op); + int unregister_from_deadlock_detector_(const ObTableLockOp &lock_op); + // Find out if there're table locks that are not generated by dml, + // and return true if there're. + // RS and RX table locks for OUT_TRANS may exist in the source tablet, + // but to avoid the complexity of cascading unlocks, copying these + // locks to the new tablet is not considered for now. + // And other table locks (except for table locks which are generated by + // dml, and RS/RX table locks for OUR_TRANS) is illegal for tablet split, + // so we need to check it by this function. + bool exist_cannot_split_lock_(const ObTransID &split_start_trans_id) const; + bool need_split_() const; + int submit_log_(ObLockTableSplitLogCb &callback, + common::ObTabletID src_tablet_id, + const ObSArray &dst_tablet_ids); + int set_split_epoch_(const share::SCN &scn, const bool for_replay = false); + int get_split_epoch_(share::SCN &scn); + int reset_split_epoch_(); + void check_curr_trans_lock_is_valid_(const uint64_t lock_mode_cnt_in_same_trans[], const int64_t *lock_mode_cnt); + private: int check_op_allow_lock_from_list_( const ObTableLockOp &lock_op, @@ -242,6 +281,7 @@ private: int check_op_allow_unlock_from_list_( const ObTableLockOp &lock_op, const ObTableLockOpList *op_list); + int check_allow_replace_from_list_(ObTableLockOpList *op_list, const ObTransID &trans_id, bool &allow_replace); void lock_row_share_() { ATOMIC_INC(&row_share_); @@ -264,6 +304,16 @@ private: public: RWLock rwlock_; bool is_deleted_; + // indicate dml table lock info from src_tablet when tablet split, + // and persistence by a special table lock op + // case 1: !max_split_epoch_.is_valid(), means that there's no any splitting on the obj_lock; + // case 2: max_split_epoch_.is_min(), means that this obj_lock (or tablet) needs split as + // a dst_tablet, but the callback hasn't been executed; + // case 3: max_split_epoch_.is_max(), means that this obj_lock (or tablet) has splitted or is + // splitting as a src_tablet; + // case 4: max_split_epoch_.is_valid() && !max_split_epoch_.is_min() && !max_split_epoch_.is_max(), + // means that callback has been executed, but the splitting is not completed. + share::SCN max_split_epoch_; private: static constexpr const int64_t OB_LOCK_OP_MAP_VERSION = 1; ObTableLockOpList *map_[TABLE_LOCK_MODE_COUNT]; @@ -333,6 +383,7 @@ public: const ObTableLockOp &lock_op, const uint64_t lock_mode_cnt_in_same_trans[], ObTxIDSet &conflict_tx_set, + const int64_t expired_time, const bool include_finish_tx = true, const bool only_check_dml_lock = false); void print(); @@ -350,6 +401,20 @@ public: ObLockOpIterator &iter); // check all obj locks in the lock map, and clear it if it's empty. int check_and_clear_obj_lock(const bool force_compact); + + int table_lock_split(const ObTabletID &src_tablet_id, + const ObSArray &dst_tablet_ids, + const transaction::ObTransID &trans_id, + ObLockTableSplitLogCb &callback); + int add_split_epoch(const ObLockID &lock_id, + const share::SCN &split_scn, + const bool for_replay = false); + int add_split_epoch(const ObSArray &lock_ids, + const share::SCN &split_epoch, + const bool for_replay = false); + int get_split_epoch(const ObLockID &lock_id, + share::SCN &split_scn); + int reset_split_epoch(const ObLockID &lock_id); private: class LockIDIterFunctor { diff --git a/src/storage/tablelock/ob_table_lock_callback.cpp b/src/storage/tablelock/ob_table_lock_callback.cpp index 6ca15e30f..09854e7b0 100644 --- a/src/storage/tablelock/ob_table_lock_callback.cpp +++ b/src/storage/tablelock/ob_table_lock_callback.cpp @@ -30,12 +30,12 @@ namespace transaction namespace tablelock { -bool ObOBJLockCallback::on_memtable(const ObIMemtable * const memtable) +bool ObOBJLockCallback::on_memtable(const storage::ObIMemtable * const memtable) { return memtable == memtable_; } -ObIMemtable* ObOBJLockCallback::get_memtable() const +storage::ObIMemtable* ObOBJLockCallback::get_memtable() const { return memtable_; } diff --git a/src/storage/tablelock/ob_table_lock_common.cpp b/src/storage/tablelock/ob_table_lock_common.cpp index a3f529cf3..21ff2f6dc 100644 --- a/src/storage/tablelock/ob_table_lock_common.cpp +++ b/src/storage/tablelock/ob_table_lock_common.cpp @@ -154,6 +154,26 @@ int get_lock_id(const ObTabletID &tablet, return ret; } +int get_lock_id(const ObIArray &tablets, + ObIArray &lock_ids) +{ + int ret = OB_SUCCESS; + ObTabletID tablet; + ObLockID lock_id; + for (int64_t i = 0; OB_SUCC(ret) && i < tablets.count(); i++) { + tablet = tablets.at(i); + if (!tablet.is_valid()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument ", K(ret), K(tablet)); + } else if (OB_FAIL(lock_id.set(ObLockOBJType::OBJ_TYPE_TABLET, tablet.id()))) { + LOG_WARN("create lock id failed.", K(ret), K(tablet)); + } else if (OB_FAIL(lock_ids.push_back(lock_id))) { + LOG_WARN("push back lock id failed.", K(ret), K(tablet)); + } + } + return ret; +} + ObTableLockOwnerID ObTableLockOwnerID::default_owner() { ObTableLockOwnerID owner; @@ -294,7 +314,9 @@ void ObTableLockOp::set( bool ObTableLockOp::is_valid() const { bool is_valid = false; - if (is_out_trans_lock_op() && owner_id_.id() == 0) { + if (TABLET_SPLIT == op_type_) { + is_valid = commit_scn_.is_valid() && !commit_scn_.is_min() && lock_id_.is_valid(); + } else if (is_out_trans_lock_op() && owner_id_.id() == 0) { is_valid = false; LOG_ERROR_RET(OB_INVALID_ARGUMENT, "owner_id should not be 0 in out_trans lock", K_(owner_id)); } else { diff --git a/src/storage/tablelock/ob_table_lock_common.h b/src/storage/tablelock/ob_table_lock_common.h index 7b8b48ec6..82c34d1f9 100644 --- a/src/storage/tablelock/ob_table_lock_common.h +++ b/src/storage/tablelock/ob_table_lock_common.h @@ -124,6 +124,12 @@ bool is_lock_mode_valid(const ObTableLockMode lock_mode) return lock_mode < MAX_LOCK_MODE; } +static inline +bool is_need_lock_tablet_mode(const ObTableLockMode &lock_mode) +{ + return SHARE == lock_mode || SHARE_ROW_EXCLUSIVE == lock_mode || EXCLUSIVE == lock_mode; +} + static inline int get_index_by_lock_mode(const ObTableLockMode &lock_mode) { @@ -180,7 +186,7 @@ enum ObTableLockOpType : char { UNKNOWN_TYPE = 0, IN_TRANS_DML_LOCK = 1, // will be unlock if we do callback - OUT_TRANS_LOCK = 2, // will be unlock use OUT_TRANS_UNLOCK + OUT_TRANS_LOCK = 2, // will be unlock use OUT_TRANS_UNLOCK OUT_TRANS_UNLOCK = 3, IN_TRANS_COMMON_LOCK = 4, TABLET_SPLIT = 5, @@ -437,6 +443,8 @@ int get_lock_id(const uint64_t table_id, ObLockID &lock_id); int get_lock_id(const common::ObTabletID &tablet, ObLockID &lock_id); +int get_lock_id(const ObIArray &tablets, + ObIArray &lock_ids); // typedef share::ObCommonID ObTableLockOwnerID; enum class ObLockOwnerType : unsigned char { diff --git a/src/storage/tablelock/ob_table_lock_rpc_processor.cpp b/src/storage/tablelock/ob_table_lock_rpc_processor.cpp index 481d8970d..ddb67380e 100644 --- a/src/storage/tablelock/ob_table_lock_rpc_processor.cpp +++ b/src/storage/tablelock/ob_table_lock_rpc_processor.cpp @@ -47,7 +47,8 @@ int check_exist(const share::ObLSID &ls_id, ObLSHandle &ls_handle) return ret; } -int check_exist(const ObLockTaskBatchRequest &arg, +template +int check_exist(const ObLockTaskBatchRequest &arg, const common::ObTabletID &tablet_id, ObLSHandle ls_handle) { @@ -78,10 +79,11 @@ int check_exist(const ObLockTaskBatchRequest &arg, } else if (FALSE_IT(tablet_status = data.get_tablet_status())) { } else if (ObTabletStatus::NORMAL == tablet_status || ObTabletStatus::TRANSFER_OUT == tablet_status - || ObTabletStatus::TRANSFER_IN == tablet_status) { + || ObTabletStatus::TRANSFER_IN == tablet_status + || ObTabletStatus::SPLIT_SRC == tablet_status + || ObTabletStatus::SPLIT_DST == tablet_status) { // do nothing - } else if (ObTabletStatus::DELETED == tablet_status - || ObTabletStatus::TRANSFER_OUT_DELETED == tablet_status) { + } else if (OB_UNLIKELY(data.tablet_status_.is_deleted_for_gc())) { // tablet shell ret = OB_TABLET_NOT_EXIST; LOG_INFO("tablet is already deleted", KR(ret), K(tablet_id)); @@ -312,6 +314,126 @@ int ObBatchLockTaskP::process() return ret; } +int ObBatchReplaceLockTaskP::process() +{ + int ret = OB_SUCCESS; + int tmp_ret = OB_SUCCESS; + // lock/unlock process: + // 1. get ls + // 2. get store ctx + // 3. lock/unlock + // 4. collect tx exec result. + + if (OB_UNLIKELY(!arg_.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(arg_)); + } else { + ObTransService *tx_srv = MTL(ObTransService *); + switch (arg_.task_type_) { + case ObTableLockTaskType::REPLACE_LOCK_TABLE: { + if (OB_FAIL(process_for_replace_lock_table_(arg_, result_))) { + LOG_WARN("failed to exec replace_obj_lock operation for table", K(ret), K(arg_)); + } + break; + } + case ObTableLockTaskType::REPLACE_LOCK_PARTITION: + case ObTableLockTaskType::REPLACE_LOCK_SUBPARTITION: + case ObTableLockTaskType::REPLACE_LOCK_TABLETS: + case ObTableLockTaskType::REPLACE_LOCK_OBJECTS: + case ObTableLockTaskType::REPLACE_LOCK_ALONE_TABLET: { + if (OB_FAIL(BATCH_PROCESS(arg_, replace_obj_lock, result_))) { + LOG_WARN("failed to exec replace_obj_lock operation", K(ret), K(arg_)); + } + break; + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_ERROR("invalid task type", K(ret), K(arg_)); + break; + } // default + } // switch + + if (OB_SUCCESS != (tmp_ret = tx_srv-> + get_tx_exec_result(*(arg_.tx_desc_), + result_.get_tx_result()))) { + result_.tx_result_ret_code_ = tmp_ret; + LOG_WARN("get trans_result fail", KR(tmp_ret), K(arg_.tx_desc_)); + } + } + + result_.ret_code_ = ret; + LOG_DEBUG("ObBatchReplaceLockTaskP::process", KR(ret), K(result_), K(arg_)); + ret = OB_SUCCESS; + + return ret; +} + +int ObBatchReplaceLockTaskP::process_for_replace_lock_table_(const ObLockTaskBatchRequest &arg, + ObTableLockTaskResult &result) +{ + int ret = OB_SUCCESS; + ObAccessService *access_srv = MTL(ObAccessService *); + ObLSHandle ls_handle; + common::ObTabletID tablet_id; + if (OB_FAIL(check_exist(arg.lsid_, ls_handle))) { + LOG_WARN("check ls failed", K(ret), K(arg)); + if (OB_LS_NOT_EXIST == ret) { + result.can_retry_ = true; + } + } else { + for (int i = 0; i < arg.params_.count() && OB_SUCC(ret); i++) { + if (arg.params_[i].lock_id_.is_tablet_lock()) { + if (OB_FAIL(arg.params_[i].lock_id_.convert_to(tablet_id))) { + LOG_WARN("convert lock id to tablet id failed", K(ret), K(arg.params_[i].lock_id_)); + } else if (OB_FAIL(check_exist(arg, tablet_id, ls_handle))) { + LOG_WARN("check tablet failed", K(ret), K(tablet_id), K(arg.params_[i].expired_time_), K(ls_handle)); + if (OB_TABLET_NOT_EXIST == ret) { + result.can_retry_ = true; + } + } else if (OB_FAIL(replace_lock_for_tablet_in_table_(arg.lsid_, *(arg.tx_desc_), arg.params_[i]))) { + LOG_WARN("failed to replace lock for tablet in table", K(ret), K(arg.params_[i])); + } else if (OB_FAIL(check_exist(arg, tablet_id, ls_handle))) { + LOG_WARN("check tablet failed", K(ret), K(tablet_id), K(arg.params_[i].expired_time_), K(ls_handle)); + } else { + result.success_pos_ = i; + } + } else if (OB_FAIL(access_srv->replace_obj_lock(arg.lsid_, *(arg.tx_desc_), arg.params_[i]))) { + LOG_WARN("failed to replace lock table", K(ret), K(arg.params_[i])); + } + } + } + return ret; +} + +int ObBatchReplaceLockTaskP::replace_lock_for_tablet_in_table_(const share::ObLSID &ls_id, + transaction::ObTxDesc &tx_desc, + const ObReplaceLockParam &lock_param) +{ + int ret = OB_SUCCESS; + ObAccessService *access_srv = MTL(ObAccessService *); + if (is_need_lock_tablet_mode(lock_param.lock_mode_) && !is_need_lock_tablet_mode(lock_param.new_lock_mode_)) { + ret = access_srv->unlock_obj(ls_id, tx_desc, lock_param); + } else if (!is_need_lock_tablet_mode(lock_param.lock_mode_) && is_need_lock_tablet_mode(lock_param.new_lock_mode_)) { + ObLockParam new_lock_param; + // we should set new_owner_id and new_lock_mode to owner_id and lock_mode in lock progress + if (OB_FAIL(new_lock_param.set(lock_param.lock_id_, + lock_param.new_lock_mode_, + lock_param.new_owner_id_, + OUT_TRANS_LOCK, + lock_param.schema_version_, + lock_param.is_deadlock_avoid_enabled_, + lock_param.is_try_lock_, + lock_param.expired_time_))) { + LOG_WARN("set lock_param for replace tablet lock failed", K(ret), K(lock_param)); + } else { + ret = access_srv->lock_obj(ls_id, tx_desc, new_lock_param); + } + } else { + ret = access_srv->replace_obj_lock(ls_id, tx_desc, lock_param); + } + return ret; +} + int ObHighPriorityBatchLockTaskP::process() { int ret = OB_SUCCESS; diff --git a/src/storage/tablelock/ob_table_lock_rpc_processor.h b/src/storage/tablelock/ob_table_lock_rpc_processor.h index 6d42779c1..b90b68398 100644 --- a/src/storage/tablelock/ob_table_lock_rpc_processor.h +++ b/src/storage/tablelock/ob_table_lock_rpc_processor.h @@ -31,6 +31,26 @@ OB_DEFINE_PROCESSOR_S(Srv, OB_HIGH_PRIORITY_TABLE_LOCK_TASK, ObHighPriorityTable OB_DEFINE_PROCESSOR_S(TableLock, OB_OUT_TRANS_LOCK_TABLE, ObOutTransLockTableP); OB_DEFINE_PROCESSOR_S(TableLock, OB_OUT_TRANS_UNLOCK_TABLE, ObOutTransUnlockTableP); +class ObBatchReplaceLockTaskP + : public obrpc::ObRpcProcessor> +{ +public: + explicit ObBatchReplaceLockTaskP(const ObGlobalContext &gctx) : gctx_(gctx) {} + +protected: + int process(); +private: + int process_for_replace_lock_table_( + const transaction::tablelock::ObLockTaskBatchRequest &arg, + transaction::tablelock::ObTableLockTaskResult &result); + int replace_lock_for_tablet_in_table_(const share::ObLSID &ls_id, + transaction::ObTxDesc &tx_desc, + const transaction::tablelock::ObReplaceLockParam &lock_param); + +private: + const ObGlobalContext &gctx_ __maybe_unused; +}; + class ObAdminRemoveLockP : public obrpc::ObRpcProcessor> { public: @@ -52,8 +72,7 @@ protected: private: DISALLOW_COPY_AND_ASSIGN(ObAdminUpdateLockP); }; - -} -} +} // namespace observer +} // namespace oceanbase #endif /* OCEANBASE_STORAGE_TABLELOCK_OB_TABLE_LOCK_RPC_PROCESSOR_H_ */ diff --git a/src/storage/tablelock/ob_table_lock_rpc_proxy.h b/src/storage/tablelock/ob_table_lock_rpc_proxy.h index 12c9439aa..e297d321c 100644 --- a/src/storage/tablelock/ob_table_lock_rpc_proxy.h +++ b/src/storage/tablelock/ob_table_lock_rpc_proxy.h @@ -26,13 +26,14 @@ namespace obrpc RPC_F(OB_TABLE_LOCK_TASK, transaction::tablelock::ObTableLockTaskRequest, transaction::tablelock::ObTableLockTaskResult, ObTableLockProxy); -RPC_F(OB_BATCH_TABLE_LOCK_TASK, transaction::tablelock::ObLockTaskBatchRequest, +RPC_F(OB_BATCH_TABLE_LOCK_TASK, transaction::tablelock::ObLockTaskBatchRequest, transaction::tablelock::ObTableLockTaskResult, ObBatchLockProxy); RPC_F(OB_HIGH_PRIORITY_TABLE_LOCK_TASK, transaction::tablelock::ObTableLockTaskRequest, transaction::tablelock::ObTableLockTaskResult, ObHighPriorityTableLockProxy); -RPC_F(OB_HIGH_PRIORITY_BATCH_TABLE_LOCK_TASK, transaction::tablelock::ObLockTaskBatchRequest, +RPC_F(OB_HIGH_PRIORITY_BATCH_TABLE_LOCK_TASK, transaction::tablelock::ObLockTaskBatchRequest, transaction::tablelock::ObTableLockTaskResult, ObHighPriorityBatchLockProxy); - +RPC_F(OB_BATCH_REPLACE_TABLE_LOCK_TASK, transaction::tablelock::ObLockTaskBatchRequest, + transaction::tablelock::ObTableLockTaskResult, ObBatchReplaceLockProxy); class ObTableLockRpcProxy: public obrpc::ObRpcProxy { public: diff --git a/src/storage/tablelock/ob_table_lock_rpc_struct.cpp b/src/storage/tablelock/ob_table_lock_rpc_struct.cpp index 0c20e4984..787cb4da5 100644 --- a/src/storage/tablelock/ob_table_lock_rpc_struct.cpp +++ b/src/storage/tablelock/ob_table_lock_rpc_struct.cpp @@ -35,6 +35,10 @@ OB_SERIALIZE_MEMBER(ObLockParam, lock_priority_, is_two_phase_lock_); +OB_SERIALIZE_MEMBER_INHERIT(ObReplaceLockParam, ObLockParam, + new_lock_mode_, + new_owner_id_); + OB_SERIALIZE_MEMBER(ObLockRequest, type_, owner_id_, @@ -71,6 +75,11 @@ OB_SERIALIZE_MEMBER_INHERIT(ObLockTabletsRequest, ObLockTableRequest, OB_SERIALIZE_MEMBER_INHERIT(ObLockAloneTabletRequest, ObLockTabletsRequest, ls_id_); +OB_SERIALIZE_MEMBER(ObReplaceLockRequest, + new_lock_mode_, + new_lock_owner_, + *unlock_req_); + OB_SERIALIZE_MEMBER(ObTableLockTaskResult, ret_code_, tx_result_ret_code_, @@ -114,14 +123,13 @@ OB_DEF_SERIALIZE(ObTableLockTaskRequest) OB_DEF_DESERIALIZE(ObTableLockTaskRequest) { int ret = OB_SUCCESS; - ObTransService *txs = MTL(transaction::ObTransService*); LST_DO_CODE(OB_UNIS_DECODE, task_type_, lsid_, param_); if (OB_FAIL(ret)) { // do nothing - } else if (OB_FAIL(txs->acquire_tx(buf, data_len, pos, tx_desc_))) { + } else if (OB_FAIL(TxDescHelper::deserialize_tx_desc(buf, data_len, pos, tx_desc_))) { LOG_WARN("acquire tx by deserialize fail", K(data_len), K(pos), K(ret)); } else { need_release_tx_ = true; @@ -130,71 +138,32 @@ OB_DEF_DESERIALIZE(ObTableLockTaskRequest) return ret; } -OB_DEF_SERIALIZE_SIZE(ObLockTaskBatchRequest) +int TxDescHelper::deserialize_tx_desc(DESERIAL_PARAMS, ObTxDesc *&tx_desc) { - int64_t len = 0; int ret = OB_SUCCESS; - if (OB_ISNULL(tx_desc_)) { + ObTransService *txs = MTL(transaction::ObTransService *); + if (OB_ISNULL(txs)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("tx_desc should not be null", K(ret), KP(tx_desc_)); - } else { - LST_DO_CODE(OB_UNIS_ADD_LEN, - task_type_, - lsid_, - params_, - *tx_desc_); - } - return len; -} - -OB_DEF_SERIALIZE(ObLockTaskBatchRequest) -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(tx_desc_)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("tx_desc should not be null", K(ret), KP(tx_desc_)); - } else { - LST_DO_CODE(OB_UNIS_ENCODE, - task_type_, - lsid_, - params_, - *tx_desc_); - } - return ret; -} - -OB_DEF_DESERIALIZE(ObLockTaskBatchRequest) -{ - int ret = OB_SUCCESS; - ObTransService *txs = MTL(transaction::ObTransService*); - LST_DO_CODE(OB_UNIS_DECODE, - task_type_, - lsid_, - params_); - if (OB_FAIL(ret)) { - // do nothing - } else if (OB_FAIL(txs->acquire_tx(buf, data_len, pos, tx_desc_))) { + LOG_ERROR("ObTransService is null"); + } else if (OB_FAIL(txs->acquire_tx(buf, data_len, pos, tx_desc))) { LOG_WARN("acquire tx by deserialize fail", K(data_len), K(pos), K(ret)); - } else { - need_release_tx_ = true; - LOG_TRACE("deserialize txDesc", KPC_(tx_desc)); } return ret; } -bool is_unlock_request(const ObTableLockTaskType type) +int TxDescHelper::release_tx_desc(ObTxDesc &tx_desc) { - return (UNLOCK_TABLE == type || - UNLOCK_TABLET == type || - UNLOCK_PARTITION == type || - UNLOCK_SUBPARTITION == type || - UNLOCK_OBJECT == type || - UNLOCK_DDL_TABLE == type || - UNLOCK_DDL_TABLET == type || - UNLOCK_ALONE_TABLET == type); + int ret = OB_SUCCESS; + ObTransService *txs = MTL(transaction::ObTransService *); + if (OB_ISNULL(txs)) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ObTransService is null"); + } else if (OB_FAIL(txs->release_tx(tx_desc))) { + LOG_WARN("acquire tx by deserialize fail", K(ret)); + } + return ret; } - void ObLockParam::reset() { lock_id_.reset(); @@ -285,6 +254,53 @@ bool ObLockRequest::is_lock_thread_enabled() const || (min_cluster_version >= CLUSTER_VERSION_4_3_0_0)); } +void ObLockRequest::set_to_unlock_type() +{ + if (is_unlock_request()) { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "it has been unlock request, no need to change", KPC(this)); + } else { + switch (type_) { + case ObLockMsgType::LOCK_OBJ_REQ: { + type_ = ObLockMsgType::UNLOCK_OBJ_REQ; + break; + } + case ObLockMsgType::LOCK_TABLE_REQ: { + type_ = ObLockMsgType::UNLOCK_TABLE_REQ; + break; + } + case ObLockMsgType::LOCK_PARTITION_REQ: { + type_ = ObLockMsgType::UNLOCK_PARTITION_REQ; + break; + } + case ObLockMsgType::LOCK_TABLET_REQ: { + type_ = ObLockMsgType::UNLOCK_TABLET_REQ; + break; + } + case ObLockMsgType::LOCK_ALONE_TABLET_REQ: { + type_ = ObLockMsgType::UNLOCK_ALONE_TABLET_REQ; + break; + } + default: { + LOG_WARN_RET(OB_INVALID_ARGUMENT, "meet unexpected request type", KPC(this)); + } + } + } +} + +void ObReplaceLockParam::reset() +{ + ObLockParam::reset(); + new_owner_id_.reset(); + new_lock_mode_ = NO_LOCK; +} + +bool ObReplaceLockParam::is_valid() const +{ + return (ObLockParam::is_valid() && + is_lock_mode_valid(new_lock_mode_) && + new_owner_id_.is_valid()); +} + void ObLockObjRequest::reset() { ObLockRequest::reset(); @@ -300,13 +316,14 @@ bool ObLockObjRequest::is_valid() const is_valid_id(obj_id_)); } -ObUnLockObjRequest::ObUnLockObjRequest() : ObLockObjRequest() -{ - if (!is_lock_thread_enabled()) { - type_ = ObLockMsgType::LOCK_OBJ_REQ; - } else { - type_ = ObLockMsgType::UNLOCK_OBJ_REQ; - } +ObUnLockObjRequest::ObUnLockObjRequest() : + ObLockObjRequest() + { + if (!is_lock_thread_enabled()) { + type_ = ObLockMsgType::LOCK_OBJ_REQ; + } else { + type_ = ObLockMsgType::UNLOCK_OBJ_REQ; + } } bool ObUnLockObjRequest::is_valid() const @@ -340,6 +357,23 @@ bool ObLockObjsRequest::is_valid() const return is_valid; } +int ObLockObjsRequest::assign(const ObLockObjRequest &arg) +{ + int ret = OB_SUCCESS; + ObLockID lock_id; + owner_id_ = arg.owner_id_; + lock_mode_ = arg.lock_mode_; + op_type_ = arg.op_type_; + timeout_us_ = arg.timeout_us_; + is_from_sql_ = arg.is_from_sql_; + if (OB_FAIL(lock_id.set(arg.obj_type_, arg.obj_id_))) { + LOG_WARN("set lock_id failed", K(ret), K(arg)); + } else if (OB_FAIL(objs_.push_back(lock_id))) { + LOG_WARN("append lock_id into array failed", K(ret), K(arg)); + } + return ret; +} + ObUnLockObjsRequest::ObUnLockObjsRequest() : ObLockObjsRequest() { @@ -479,6 +513,20 @@ bool ObLockTabletsRequest::is_valid() const return is_valid; } +int ObLockTabletsRequest::assign(const ObLockTabletRequest &arg) +{ + int ret = OB_SUCCESS; + owner_id_ = arg.owner_id_; + lock_mode_ = arg.lock_mode_; + op_type_ = arg.op_type_; + timeout_us_ = arg.timeout_us_; + is_from_sql_ = arg.is_from_sql_; + if (OB_FAIL(tablet_ids_.push_back(arg.tablet_id_))) { + LOG_WARN("append tablet_id into array failed", K(arg), K(ret)); + } + return ret; +} + ObUnLockTabletsRequest::ObUnLockTabletsRequest() : ObLockTabletsRequest() { if (!is_lock_thread_enabled()) { @@ -541,6 +589,36 @@ bool ObUnLockAloneTabletRequest::is_valid() const return is_valid; } +void ObReplaceLockRequest::reset() +{ + unlock_req_ = nullptr; + new_lock_mode_ = MAX_LOCK_MODE; + new_lock_owner_.reset(); +} + +bool ObReplaceLockRequest::is_valid() const +{ + return unlock_req_->is_valid() && new_lock_owner_.is_valid() && is_lock_mode_valid(new_lock_mode_); +} + +int ObReplaceLockRequest::deserialize_and_check_header(DESERIAL_PARAMS) +{ + int ret = OB_SUCCESS; + int64_t version = 0; + int64_t len = 0; + OB_UNIS_DECODE(version); + OB_UNIS_DECODE(len); + CHECK_VERSION_LENGTH(ObReplaceLockRequest, version, len); + return ret; +} + +int ObReplaceLockRequest::deserialize_new_lock_mode_and_owner(DESERIAL_PARAMS) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, new_lock_mode_, new_lock_owner_); + return ret; +} + int ObTableLockTaskRequest::set( const ObTableLockTaskType task_type, const share::ObLSID &lsid, @@ -580,11 +658,10 @@ ObTableLockTaskRequest::~ObTableLockTaskRequest() void ObTableLockTaskRequest::reset() { - auto txs = MTL(transaction::ObTransService*); if (OB_NOT_NULL(tx_desc_)) { if (need_release_tx_) { LOG_TRACE("free txDesc", KPC_(tx_desc)); - txs->release_tx(*tx_desc_); + TxDescHelper::release_tx_desc(*tx_desc_); } } task_type_ = INVALID_LOCK_TASK_TYPE; @@ -599,80 +676,6 @@ bool ObTableLockTaskRequest::is_timeout() const return common::ObTimeUtility::current_time() >= param_.expired_time_; } -ObLockTaskBatchRequest::~ObLockTaskBatchRequest() -{ - auto txs = MTL(transaction::ObTransService*); - if (OB_NOT_NULL(tx_desc_)) { - if (need_release_tx_) { - LOG_TRACE("free txDesc", KPC_(tx_desc)); - txs->release_tx(*tx_desc_); - } - } - task_type_ = INVALID_LOCK_TASK_TYPE; - lsid_.reset(); - tx_desc_ = nullptr; - need_release_tx_ = false; - params_.reset(); -} - -int ObLockTaskBatchRequest::init(const ObTableLockTaskType task_type, - const share::ObLSID &lsid, - transaction::ObTxDesc *tx_desc) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!(task_type < MAX_TASK_TYPE)) || - OB_UNLIKELY(!lsid.is_valid()) || - OB_ISNULL(tx_desc)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(task_type), K(lsid), KP(tx_desc)); - } else { - task_type_ = task_type; - lsid_ = lsid; - tx_desc_ = tx_desc; - } - return ret; -} - -bool ObLockTaskBatchRequest::is_inited() const -{ - return (task_type_ < MAX_TASK_TYPE && - lsid_.is_valid() && - OB_NOT_NULL(tx_desc_)); -} - -bool ObLockTaskBatchRequest::is_valid() const -{ - bool valid = true; - if (is_inited()) { - for (int64_t i = 0; valid && i < params_.count(); ++i) { - const ObLockParam ¶m = params_[i]; - if (!param.is_valid()) { - valid = false; - } - } - valid = valid && tx_desc_->is_valid(); - } else { - valid = false; - } - return valid; -} - -int ObLockTaskBatchRequest::assign(const ObLockTaskBatchRequest&arg) -{ - int ret = OB_SUCCESS; - if (OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("arg is invalid", KR(ret), K(arg)); - } else if (OB_FAIL(params_.assign(arg.params_))) { - LOG_WARN("failed to assign params", KR(ret), K(arg)); - } else { - task_type_ = arg.task_type_; - lsid_ = arg.lsid_; - tx_desc_ = arg.tx_desc_; - } - return ret; -} - OB_SERIALIZE_MEMBER(ObOutTransLockTableRequest, table_id_, lock_mode_, lock_owner_, timeout_us_); int ObOutTransLockTableRequest::assign(const ObOutTransLockTableRequest &arg) @@ -793,8 +796,6 @@ bool ObAdminUpdateLockOpArg::is_valid() const commit_version_.is_valid() && commit_scn_.is_valid()); } - - -} + } } } diff --git a/src/storage/tablelock/ob_table_lock_rpc_struct.h b/src/storage/tablelock/ob_table_lock_rpc_struct.h index b4c4234f3..9c3e67eac 100644 --- a/src/storage/tablelock/ob_table_lock_rpc_struct.h +++ b/src/storage/tablelock/ob_table_lock_rpc_struct.h @@ -34,7 +34,7 @@ namespace transaction namespace tablelock { - +class ObReplaceTableLockCtx; enum ObTableLockTaskType { @@ -50,10 +50,10 @@ enum ObTableLockTaskType UNLOCK_SUBPARTITION = 8, LOCK_OBJECT = 9, UNLOCK_OBJECT = 10, - LOCK_DDL_TABLE = 11, - UNLOCK_DDL_TABLE = 12, - LOCK_DDL_TABLET = 13, - UNLOCK_DDL_TABLET = 14, + LOCK_DDL_TABLE = 11, // unused + UNLOCK_DDL_TABLE = 12, // unused + LOCK_DDL_TABLET = 13, // unused + UNLOCK_DDL_TABLET = 14, // unused LOCK_ALONE_TABLET = 15, UNLOCK_ALONE_TABLET = 16, ADD_LOCK_INTO_QUEUE = 17, @@ -66,7 +66,31 @@ enum ObTableLockTaskType MAX_TASK_TYPE, }; -bool is_unlock_request(const ObTableLockTaskType type); +static inline bool is_unlock_task(const ObTableLockTaskType &task_type) +{ + return (UNLOCK_TABLE == task_type || UNLOCK_PARTITION == task_type || UNLOCK_SUBPARTITION == task_type + || UNLOCK_TABLET == task_type || UNLOCK_OBJECT == task_type || UNLOCK_ALONE_TABLET == task_type + || UNLOCK_DDL_TABLE == task_type || UNLOCK_DDL_TABLET == task_type); +} + +static inline bool is_replace_lock_task(const ObTableLockTaskType &task_type) +{ + return (REPLACE_LOCK_TABLE == task_type || REPLACE_LOCK_PARTITION == task_type + || REPLACE_LOCK_SUBPARTITION == task_type || REPLACE_LOCK_TABLETS == task_type + || REPLACE_LOCK_OBJECTS == task_type || REPLACE_LOCK_ALONE_TABLET == task_type); +} + +static inline bool is_tablet_lock_task(const ObTableLockTaskType &task_type) +{ + return (LOCK_TABLET == task_type || UNLOCK_TABLET == task_type || LOCK_ALONE_TABLET == task_type + || UNLOCK_ALONE_TABLET == task_type || REPLACE_LOCK_TABLETS == task_type + || REPLACE_LOCK_ALONE_TABLET == task_type); +} + +static inline bool is_obj_lock_task(const ObTableLockTaskType &task_type) +{ + return (LOCK_OBJECT == task_type || UNLOCK_OBJECT == task_type || REPLACE_LOCK_OBJECTS == task_type); +} struct ObLockParam { @@ -97,10 +121,15 @@ public: const bool is_try_lock = true, const int64_t expired_time = 0); bool is_valid() const; - TO_STRING_KV(K_(lock_id), K_(lock_mode), K_(owner_id), K_(op_type), + TO_STRING_KV(K_(lock_id), + K_(lock_mode), + K_(owner_id), + K_(op_type), K_(is_deadlock_avoid_enabled), - K_(is_try_lock), K_(expired_time), K_(schema_version), K_(is_for_replace)); - + K_(is_try_lock), + K_(expired_time), + K_(schema_version), + K_(is_for_replace)); ObLockID lock_id_; ObTableLockMode lock_mode_; ObTableLockOwnerID owner_id_; @@ -119,6 +148,21 @@ public: bool is_two_phase_lock_; }; +struct ObReplaceLockParam : public ObLockParam +{ + OB_UNIS_VERSION_V(1); + +public: + ObReplaceLockParam() : ObLockParam(), new_lock_mode_(NO_LOCK), new_owner_id_() { is_for_replace_ = true; } + virtual ~ObReplaceLockParam() { reset(); } + void reset(); + bool is_valid() const; + INHERIT_TO_STRING_KV("ObLockParam", ObLockParam, K_(new_lock_mode), K_(new_owner_id)); + + ObTableLockMode new_lock_mode_; + ObTableLockOwnerID new_owner_id_; +}; + struct ObLockRequest { OB_UNIS_VERSION_V(1); @@ -151,6 +195,7 @@ public: virtual ~ObLockRequest() { reset(); } virtual void reset(); virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return INVALID_LOCK_TASK_TYPE; } bool is_lock_thread_enabled() const; bool is_unlock_request() const { @@ -164,8 +209,8 @@ public: { return !is_unlock_request(); } - VIRTUAL_TO_STRING_KV(K_(owner_id), K_(lock_mode), K_(op_type), K_(timeout_us), - K_(is_from_sql)); + void set_to_unlock_type(); + VIRTUAL_TO_STRING_KV(K_(type), K_(owner_id), K_(lock_mode), K_(op_type), K_(timeout_us)); public: ObLockMsgType type_; ObTableLockOwnerID owner_id_; @@ -175,6 +220,7 @@ public: bool is_from_sql_; ObTableLockPriority lock_priority_; }; +using ObUnLockRequest = ObLockRequest; struct ObLockObjRequest : public ObLockRequest { @@ -188,6 +234,7 @@ public: virtual ~ObLockObjRequest() { reset(); } virtual void reset(); virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return LOCK_OBJECT; } INHERIT_TO_STRING_KV("ObLockRequest", ObLockRequest, K_(obj_type), K_(obj_id)); public: // which object should we lock @@ -201,6 +248,7 @@ public: ObUnLockObjRequest(); virtual ~ObUnLockObjRequest() { reset(); } virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return UNLOCK_OBJECT; } }; struct ObLockObjsRequest : public ObLockRequest @@ -216,6 +264,8 @@ public: virtual ~ObLockObjsRequest() { reset(); } virtual void reset(); virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return LOCK_OBJECT; } + int assign(const ObLockObjRequest &arg); INHERIT_TO_STRING_KV("ObLockRequest", ObLockRequest, K_(objs), K_(detect_func_no), K_(detect_param)); public: // which objects should we lock @@ -230,6 +280,7 @@ public: ObUnLockObjsRequest(); virtual ~ObUnLockObjsRequest() { reset(); } virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return UNLOCK_OBJECT; } }; struct ObLockTableRequest : public ObLockRequest @@ -245,6 +296,7 @@ public: virtual ~ObLockTableRequest() { reset(); } virtual void reset(); virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return LOCK_TABLE; } INHERIT_TO_STRING_KV("ObLockRequest", ObLockRequest, K_(table_id)); public: // which table should we lock @@ -259,6 +311,7 @@ public: ObUnLockTableRequest(); virtual ~ObUnLockTableRequest() { reset(); } virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return UNLOCK_TABLE; } }; struct ObLockPartitionRequest : public ObLockTableRequest @@ -270,6 +323,14 @@ public: virtual ~ObLockPartitionRequest() { reset(); } virtual void reset(); virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const + { + if (is_sub_part_) { + return LOCK_SUBPARTITION; + } else { + return LOCK_PARTITION; + } + } INHERIT_TO_STRING_KV("ObLockTableRequest", ObLockTableRequest, K_(part_object_id)); public: uint64_t part_object_id_; @@ -282,6 +343,13 @@ public: ObUnLockPartitionRequest(); virtual ~ObUnLockPartitionRequest() { reset(); } virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { + if (is_sub_part_) { + return UNLOCK_SUBPARTITION; + } else { + return UNLOCK_PARTITION; + } + } }; struct ObLockTabletRequest : public ObLockTableRequest @@ -293,6 +361,7 @@ public: virtual ~ObLockTabletRequest() { reset(); } virtual void reset(); virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return LOCK_TABLET; } INHERIT_TO_STRING_KV("ObLockTableRequest", ObLockTableRequest, K_(tablet_id)); public: common::ObTabletID tablet_id_; @@ -304,6 +373,7 @@ public: ObUnLockTabletRequest(); virtual ~ObUnLockTabletRequest() { reset(); } virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return UNLOCK_TABLET; } }; struct ObLockTabletsRequest : public ObLockTableRequest @@ -315,6 +385,8 @@ public: virtual ~ObLockTabletsRequest() { reset(); } virtual void reset(); virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return LOCK_TABLET; } + int assign(const ObLockTabletRequest &arg); INHERIT_TO_STRING_KV("ObLockTableRequest", ObLockTableRequest, K_(tablet_ids)); public: common::ObTabletIDArray tablet_ids_; @@ -326,6 +398,7 @@ public: ObUnLockTabletsRequest(); virtual ~ObUnLockTabletsRequest() { reset(); } virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return UNLOCK_TABLET; } }; struct ObLockAloneTabletRequest : public ObLockTabletsRequest @@ -337,6 +410,7 @@ public: virtual ~ObLockAloneTabletRequest() { reset(); } virtual void reset(); virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return LOCK_ALONE_TABLET; } INHERIT_TO_STRING_KV("ObLockTabletsRequest", ObLockTabletsRequest, K_(ls_id)); public: share::ObLSID ls_id_; @@ -348,6 +422,28 @@ public: ObUnLockAloneTabletRequest(); virtual ~ObUnLockAloneTabletRequest() { reset(); } virtual bool is_valid() const; + virtual ObTableLockTaskType get_task_type() const { return UNLOCK_ALONE_TABLET; } +}; + +struct ObReplaceLockRequest +{ + OB_UNIS_VERSION_V(1); +public: + public: + ObReplaceLockRequest() : + new_lock_mode_(MAX_LOCK_MODE), new_lock_owner_(), unlock_req_(nullptr) + {} + ~ObReplaceLockRequest() { reset(); } + void reset(); + bool is_valid() const; + int64_t get_timeout_us() const { return unlock_req_->timeout_us_; } + int deserialize_and_check_header(DESERIAL_PARAMS); + int deserialize_new_lock_mode_and_owner(DESERIAL_PARAMS); + VIRTUAL_TO_STRING_KV(K_(new_lock_mode), K_(new_lock_owner), KPC_(unlock_req)); +public: + ObTableLockMode new_lock_mode_; + ObTableLockOwnerID new_lock_owner_; + ObLockRequest *unlock_req_; }; class ObTableLockTaskRequest final @@ -380,7 +476,7 @@ public: } bool is_unlock_request() const { - return ::oceanbase::transaction::tablelock::is_unlock_request(task_type_); + return ::oceanbase::transaction::tablelock::is_unlock_task(task_type_); } bool is_lock_request() const { @@ -399,6 +495,12 @@ private: bool need_release_tx_; }; +struct TxDescHelper +{ + static int deserialize_tx_desc(DESERIAL_PARAMS, ObTxDesc *&tx_desc); + static int release_tx_desc(ObTxDesc &tx_desc); +}; +template class ObLockTaskBatchRequest final { OB_UNIS_VERSION(1); @@ -410,16 +512,68 @@ public: tx_desc_(nullptr), need_release_tx_(false) {} - ~ObLockTaskBatchRequest(); - int init(const ObTableLockTaskType task_type, - const share::ObLSID &lsid, - transaction::ObTxDesc *tx_desc); - bool is_inited() const; - bool is_valid() const; - int assign(const ObLockTaskBatchRequest &arg); + ~ObLockTaskBatchRequest() { reset(); } + void reset() + { + if (OB_NOT_NULL(tx_desc_)) { + if (need_release_tx_) { + TABLELOCK_LOG(TRACE, "free txDesc", KPC_(tx_desc)); + TxDescHelper::release_tx_desc(*tx_desc_); + } + } + task_type_ = INVALID_LOCK_TASK_TYPE; + lsid_.reset(); + tx_desc_ = nullptr; + need_release_tx_ = false; + params_.reset(); + } + int init(const ObTableLockTaskType task_type, const share::ObLSID &lsid, transaction::ObTxDesc *tx_desc) + { + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!(task_type < MAX_TASK_TYPE)) || OB_UNLIKELY(!lsid.is_valid()) || OB_ISNULL(tx_desc)) { + ret = OB_INVALID_ARGUMENT; + TABLELOCK_LOG(WARN, "invalid argument", K(ret), K(task_type), K(lsid), KP(tx_desc)); + } else { + task_type_ = task_type; + lsid_ = lsid; + tx_desc_ = tx_desc; + } + return ret; + } + bool is_inited() const { return (task_type_ < MAX_TASK_TYPE && lsid_.is_valid() && OB_NOT_NULL(tx_desc_)); } + bool is_valid() const + { + bool valid = true; + if (is_inited()) { + for (int64_t i = 0; valid && i < params_.count(); ++i) { + if (!params_[i].is_valid()) { + valid = false; + } + } + valid = valid && tx_desc_->is_valid(); + } else { + valid = false; + } + return valid; + } + int assign(const ObLockTaskBatchRequest &arg) + { + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + TABLELOCK_LOG(WARN, "arg is invalid", KR(ret), K(arg)); + } else if (OB_FAIL(params_.assign(arg.params_))) { + TABLELOCK_LOG(WARN, "failed to assign params", KR(ret), K(arg)); + } else { + task_type_ = arg.task_type_; + lsid_ = arg.lsid_; + tx_desc_ = arg.tx_desc_; + } + return ret; + } bool is_unlock_request() const { - return ::oceanbase::transaction::tablelock::is_unlock_request(task_type_); + return ::oceanbase::transaction::tablelock::is_unlock_task(task_type_); } bool is_lock_request() const { @@ -430,13 +584,61 @@ public: public: ObTableLockTaskType task_type_; share::ObLSID lsid_; // go to which ls to lock. - common::ObSArray params_; + common::ObSArray params_; transaction::ObTxDesc *tx_desc_; private: DISALLOW_COPY_AND_ASSIGN(ObLockTaskBatchRequest); bool need_release_tx_; }; +OB_DEF_SERIALIZE_SIZE(ObLockTaskBatchRequest, template ) +{ + int64_t len = 0; + int ret = OB_SUCCESS; + if (OB_ISNULL(tx_desc_)) { + ret = OB_ERR_UNEXPECTED; + TABLELOCK_LOG(WARN, "tx_desc should not be null", K(ret), KP(tx_desc_)); + } else { + LST_DO_CODE(OB_UNIS_ADD_LEN, + task_type_, + lsid_, + params_, + *tx_desc_); + } + return len; +} + +OB_DEF_SERIALIZE(ObLockTaskBatchRequest, template ) +{ + int ret = OB_SUCCESS; + if (OB_ISNULL(tx_desc_)) { + ret = OB_ERR_UNEXPECTED; + TABLELOCK_LOG(WARN, "tx_desc should not be null", K(ret), KP(tx_desc_)); + } else { + LST_DO_CODE(OB_UNIS_ENCODE, + task_type_, + lsid_, + params_, + *tx_desc_); + } + return ret; +} + +OB_DEF_DESERIALIZE(ObLockTaskBatchRequest, template ) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, task_type_, lsid_, params_); + if (OB_FAIL(ret)) { + // do nothing + } else if (OB_FAIL(TxDescHelper::deserialize_tx_desc(buf, data_len, pos, tx_desc_))) { + TABLELOCK_LOG(WARN, "acquire tx by deserialize fail", K(data_len), K(pos), K(ret)); + } else { + need_release_tx_ = true; + TABLELOCK_LOG(TRACE, "deserialize txDesc", KPC_(tx_desc)); + } + return ret; +} + class ObTableLockTaskResult final { OB_UNIS_VERSION(1); diff --git a/src/storage/tablelock/ob_table_lock_service.cpp b/src/storage/tablelock/ob_table_lock_service.cpp index 05ba584be..088b764b5 100644 --- a/src/storage/tablelock/ob_table_lock_service.cpp +++ b/src/storage/tablelock/ob_table_lock_service.cpp @@ -40,58 +40,28 @@ namespace transaction namespace tablelock { -ObTableLockService::ObTableLockCtx::ObTableLockCtx(const ObTableLockTaskType task_type, - const int64_t origin_timeout_us, - const int64_t timeout_us) - : task_type_(task_type), - is_in_trans_(false), - table_id_(OB_INVALID_ID), - origin_timeout_us_(origin_timeout_us), - timeout_us_(timeout_us), - abs_timeout_ts_(), - trans_state_(), - tx_desc_(nullptr), - current_savepoint_(), - tablet_list_(), - schema_version_(-1), - tx_is_killed_(false), - is_from_sql_(false), - ret_code_before_end_stmt_or_tx_(OB_SUCCESS), - stmt_savepoint_() -{ - abs_timeout_ts_ = (0 == timeout_us) - ? ObTimeUtility::current_time() + DEFAULT_TIMEOUT_US - : ObTimeUtility::current_time() + timeout_us; -} - -ObTableLockService::ObTableLockCtx::ObTableLockCtx(const ObTableLockTaskType task_type, - const uint64_t table_id, - const int64_t origin_timeout_us, - const int64_t timeout_us) - : ObTableLockCtx(task_type, origin_timeout_us, timeout_us) -{ - table_id_ = table_id; -} - -ObTableLockService::ObTableLockCtx::ObTableLockCtx(const ObTableLockTaskType task_type, - const uint64_t table_id, - const uint64_t partition_id, - const int64_t origin_timeout_us, - const int64_t timeout_us) - : ObTableLockCtx(task_type, table_id, origin_timeout_us, timeout_us) -{ - partition_id_ = partition_id; -} - -ObTableLockService::ObTableLockCtx::ObTableLockCtx(const ObTableLockTaskType task_type, - const uint64_t table_id, - const share::ObLSID &ls_id, - const int64_t origin_timeout_us, - const int64_t timeout_us) - : ObTableLockCtx(task_type, table_id, origin_timeout_us, timeout_us) -{ - ls_id_ = ls_id; -} +ObTableLockService::ObTableLockCtx::ObTableLockCtx() : + task_type_(INVALID_LOCK_TASK_TYPE), + is_in_trans_(false), + table_id_(OB_INVALID_ID), + partition_id_(OB_INVALID_ID), + ls_id_(ObLSID::INVALID_LS_ID), + lock_op_type_(UNKNOWN_TYPE), + origin_timeout_us_(-1), + timeout_us_(-1), + abs_timeout_ts_(-1), + trans_state_(), + tx_desc_(nullptr), + tx_param_(), + current_savepoint_(), + tablet_list_(), + obj_list_(), + lock_mode_(MAX_LOCK_MODE), + lock_owner_(), + schema_version_(-1), + tx_is_killed_(false), + is_from_sql_(false) +{} void ObTableLockService::ObRetryCtx::reuse() { @@ -101,6 +71,163 @@ void ObTableLockService::ObRetryCtx::reuse() retry_lock_ids_.reuse(); } +int ObTableLockService::ObTableLockCtx::set_by_lock_req(const ObLockRequest &arg, const bool is_replace_task) +{ + int ret = OB_SUCCESS; + switch (arg.type_) { + case ObLockRequest::ObLockMsgType::LOCK_TABLE_REQ: + case ObLockRequest::ObLockMsgType::UNLOCK_TABLE_REQ: { + const ObLockTableRequest &lock_arg = static_cast(arg); + if (is_replace_task) { + task_type_ = REPLACE_LOCK_TABLE; + } else if (arg.is_unlock_request()) { + task_type_ = UNLOCK_TABLE; + } else { + task_type_ = LOCK_TABLE; + } + table_id_ = lock_arg.table_id_; + break; + } + case ObLockRequest::ObLockMsgType::LOCK_TABLET_REQ: + case ObLockRequest::ObLockMsgType::UNLOCK_TABLET_REQ: { + const ObLockTabletsRequest &lock_arg = static_cast(arg); + if (is_replace_task) { + task_type_ = REPLACE_LOCK_TABLETS; + } else if (arg.is_unlock_request()) { + task_type_ = UNLOCK_TABLET; + } else { + task_type_ = LOCK_TABLET; + } + table_id_ = lock_arg.table_id_; + if (OB_FAIL(set_tablet_id(lock_arg.tablet_ids_))) { + LOG_WARN("set tablet id failed", K(ret), K(lock_arg)); + } + break; + } + case ObLockRequest::ObLockMsgType::LOCK_OBJ_REQ: + case ObLockRequest::ObLockMsgType::UNLOCK_OBJ_REQ: { + const ObLockObjsRequest &lock_arg = static_cast(arg); + if (is_replace_task) { + task_type_ = REPLACE_LOCK_OBJECTS; + } else if (arg.is_unlock_request()) { + task_type_ = UNLOCK_OBJECT; + } else { + task_type_ = LOCK_OBJECT; + } + if (OB_FAIL(set_lock_id(lock_arg.objs_))) { + LOG_WARN("set lock id failed", K(ret), K(lock_arg)); + } + break; + } + case ObLockRequest::ObLockMsgType::LOCK_PARTITION_REQ: + case ObLockRequest::ObLockMsgType::UNLOCK_PARTITION_REQ: { + const ObLockPartitionRequest &lock_arg = static_cast(arg); + if (lock_arg.is_sub_part_) { + if (is_replace_task) { + task_type_ = REPLACE_LOCK_SUBPARTITION; + } else if (arg.is_unlock_request()) { + task_type_ = UNLOCK_SUBPARTITION; + } else { + task_type_ = LOCK_SUBPARTITION; + } + } else { + if (is_replace_task) { + task_type_ = REPLACE_LOCK_PARTITION; + } else if (arg.is_unlock_request()) { + task_type_ = UNLOCK_PARTITION; + } else { + task_type_ = LOCK_PARTITION; + } + } + table_id_ = lock_arg.table_id_; + partition_id_ = lock_arg.part_object_id_; + break; + } + case ObLockRequest::ObLockMsgType::LOCK_ALONE_TABLET_REQ: + case ObLockRequest::ObLockMsgType::UNLOCK_ALONE_TABLET_REQ: { + const ObLockAloneTabletRequest &lock_arg = static_cast(arg); + if (is_replace_task) { + task_type_ = REPLACE_LOCK_ALONE_TABLET; + } else if (arg.is_unlock_request()) { + task_type_ = UNLOCK_ALONE_TABLET; + } else { + task_type_ = LOCK_ALONE_TABLET; + } + table_id_ = lock_arg.table_id_; + ls_id_ = lock_arg.ls_id_; + if (OB_FAIL(set_tablet_id(lock_arg.tablet_ids_))) { + LOG_WARN("set tablet id failed", K(ret), K(lock_arg)); + } + break; + } + default: { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("meet not support request type", K(ret), K(arg)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(set_by_lock_req_common_part(arg))) { + LOG_WARN("set lock_ctx common part failed", K(ret), K(arg)); + } + return ret; +} + +int ObTableLockService::ObTableLockCtx::set_by_lock_req_common_part(const ObLockRequest &arg) +{ + int ret = OB_SUCCESS; + if (INVALID_LOCK_TASK_TYPE == task_type_) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("not set task_type before fill ctx", K(ret), K(arg)); + } else if (((is_unlock_task() || is_replace_task()) && OUT_TRANS_UNLOCK != arg.op_type_) + || (!is_unlock_task() && !is_replace_task() && OUT_TRANS_UNLOCK == arg.op_type_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("lock task_type is not match with lock op_type", K(ret), K(arg), KPC(this)); + } else { + origin_timeout_us_ = arg.timeout_us_; + timeout_us_ = arg.timeout_us_; + abs_timeout_ts_ = (0 == arg.timeout_us_) ? ObTimeUtility::current_time() + DEFAULT_TIMEOUT_US + : ObTimeUtility::current_time() + arg.timeout_us_; + lock_op_type_ = arg.op_type_; + is_from_sql_ = arg.is_from_sql_; + lock_mode_ = arg.lock_mode_; + lock_owner_ = arg.owner_id_; + } + return ret; +} + +int ObTableLockService::ObReplaceTableLockCtx::get_lock_param(const ObLockID &lock_id, + ObReplaceLockParam &lock_param) const +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!is_lock_mode_valid(new_lock_mode_))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(lock_id), K(new_lock_mode_)); + } else if (OB_FAIL(lock_param.set(lock_id, + lock_mode_, + lock_owner_, + lock_op_type_, + schema_version_, + is_deadlock_avoid_enabled(), + is_try_lock(), + abs_timeout_ts_))) { + LOG_WARN("set param for ObLockParam failed", + K(ret), + K(lock_id), + K(lock_mode_), + K(lock_owner_), + K(new_lock_mode_), + K(new_lock_owner_), + K(lock_op_type_), + K(is_try_lock()), + K(abs_timeout_ts_)); + } else { + lock_param.is_for_replace_ = true; + lock_param.new_lock_mode_ = new_lock_mode_; + lock_param.new_owner_id_ = new_lock_owner_; + } + return ret; +} + int64_t ObTableLockService::ObOBJLockGarbageCollector::GARBAGE_COLLECT_PRECISION = 100_ms; int64_t ObTableLockService::ObOBJLockGarbageCollector::GARBAGE_COLLECT_EXEC_INTERVAL = 10_s; int64_t ObTableLockService::ObOBJLockGarbageCollector::GARBAGE_COLLECT_TIMEOUT = 10_min; @@ -477,9 +604,16 @@ int ObTableLockService::lock_table(const uint64_t table_id, if (timeout_us != 0) { retry_timeout_us = abs_timeout_ts - ObTimeUtility::current_time(); } - ObTableLockCtx ctx(LOCK_TABLE, table_id, timeout_us, retry_timeout_us); + ObTableLockCtx ctx; + ctx.task_type_ = LOCK_TABLE; + ctx.table_id_ = table_id; ctx.lock_op_type_ = OUT_TRANS_LOCK; - ret = process_lock_task_(ctx, lock_mode, lock_owner); + ctx.origin_timeout_us_ = timeout_us; + ctx.timeout_us_ = retry_timeout_us; + ctx.abs_timeout_ts_ = abs_timeout_ts; + ctx.lock_mode_ = lock_mode; + ctx.lock_owner_ = lock_owner; + ret = process_lock_task_(ctx); need_retry = need_retry_trans_(ctx, ret); ret_code_before_end_stmt_or_tx = ctx.ret_code_before_end_stmt_or_tx_; } while (need_retry); @@ -516,9 +650,16 @@ int ObTableLockService::unlock_table(const uint64_t table_id, if (timeout_us != 0) { retry_timeout_us = abs_timeout_ts - ObTimeUtility::current_time(); } - ObTableLockCtx ctx(UNLOCK_TABLE, table_id, timeout_us, retry_timeout_us); + ObTableLockCtx ctx; + ctx.task_type_ = UNLOCK_TABLE; + ctx.table_id_ = table_id; ctx.lock_op_type_ = OUT_TRANS_UNLOCK; - ret = process_lock_task_(ctx, lock_mode, lock_owner); + ctx.origin_timeout_us_ = timeout_us; + ctx.timeout_us_ = retry_timeout_us; + ctx.abs_timeout_ts_ = abs_timeout_ts; + ctx.lock_mode_ = lock_mode; + ctx.lock_owner_ = lock_owner; + ret = process_lock_task_(ctx); need_retry = need_retry_trans_(ctx, ret); } while (need_retry); } @@ -557,11 +698,19 @@ int ObTableLockService::lock_tablet(const uint64_t table_id, if (timeout_us != 0) { retry_timeout_us = abs_timeout_ts - ObTimeUtility::current_time(); } - ObTableLockCtx ctx(LOCK_TABLET, table_id, timeout_us, retry_timeout_us); + ObTableLockCtx ctx; + ctx.task_type_ = LOCK_TABLET; + ctx.table_id_ = table_id; ctx.lock_op_type_ = OUT_TRANS_LOCK; + ctx.origin_timeout_us_ = timeout_us; + ctx.timeout_us_ = retry_timeout_us; + ctx.abs_timeout_ts_ = (0 == retry_timeout_us) ? ObTimeUtility::current_time() + DEFAULT_TIMEOUT_US + : ObTimeUtility::current_time() + retry_timeout_us; + ctx.lock_mode_ = lock_mode; + ctx.lock_owner_ = lock_owner; if (OB_FAIL(ctx.set_tablet_id(tablet_id))) { LOG_WARN("set tablet id failed", K(ret), K(tablet_id)); - } else if (OB_FAIL(process_lock_task_(ctx, lock_mode, lock_owner))) { + } else if (OB_FAIL(process_lock_task_(ctx))) { LOG_WARN("process lock task failed", K(ret), K(tablet_id)); } need_retry = need_retry_trans_(ctx, ret); @@ -601,11 +750,18 @@ int ObTableLockService::unlock_tablet(const uint64_t table_id, if (timeout_us != 0) { retry_timeout_us = abs_timeout_ts - ObTimeUtility::current_time(); } - ObTableLockCtx ctx(UNLOCK_TABLET, table_id, timeout_us, retry_timeout_us); + ObTableLockCtx ctx; + ctx.task_type_ = UNLOCK_TABLET; + ctx.table_id_ = table_id; ctx.lock_op_type_ = OUT_TRANS_UNLOCK; + ctx.origin_timeout_us_ = timeout_us; + ctx.timeout_us_ = retry_timeout_us; + ctx.abs_timeout_ts_ = abs_timeout_ts; + ctx.lock_mode_ = lock_mode; + ctx.lock_owner_ = lock_owner; if (OB_FAIL(ctx.set_tablet_id(tablet_id))) { LOG_WARN("set tablet id failed", K(ret), K(tablet_id)); - } else if (OB_FAIL(process_lock_task_(ctx, lock_mode, lock_owner))) { + } else if (OB_FAIL(process_lock_task_(ctx))) { LOG_WARN("process lock task failed", K(ret), K(tablet_id)); } need_retry = need_retry_trans_(ctx, ret); @@ -616,286 +772,9 @@ int ObTableLockService::unlock_tablet(const uint64_t table_id, return ret; } -int ObTableLockService::lock_table(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockTableRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else { - // origin_timeout_us_ and timeout_us_ are both set as timeout_us_, which - // is set by user in the 'WAIT n' option. - // Furthermore, if timeout_us_ is 0, this lock will be judged as a try - // lock semantics. It meets the actual semantics of 'NOWAIT' option. - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(LOCK_TABLE, arg.table_id_, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::unlock_table(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockTableRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid()) || - OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(UNLOCK_TABLE, arg.table_id_, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - ret = rewrite_return_code_(ret, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::lock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockTabletRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(LOCK_TABLET, arg.table_id_, - arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_tablet_id(arg.tablet_id_))) { - LOG_WARN("set tablet id failed", K(ret), K(arg)); - } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { - LOG_WARN("process lock task failed", K(ret), K(arg)); - } - ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::lock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockTabletsRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_2_0_0))) { - LOG_WARN("data version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(LOCK_TABLET, arg.table_id_, - arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_tablet_id(arg.tablet_ids_))) { - LOG_WARN("set tablet id failed", K(ret), K(arg)); - } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { - LOG_WARN("process lock task failed", K(ret), K(arg)); - } - ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::unlock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockTabletRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid()) || - OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(UNLOCK_TABLET, arg.table_id_, - arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_tablet_id(arg.tablet_id_))) { - LOG_WARN("set tablet id failed", K(ret), K(arg)); - } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { - LOG_WARN("process lock task failed", K(ret), K(arg)); - } - ret = rewrite_return_code_(ret, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::unlock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockTabletsRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid()) || - OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_2_0_0))) { - LOG_WARN("data version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(UNLOCK_TABLET, arg.table_id_, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_tablet_id(arg.tablet_ids_))) { - LOG_WARN("set tablet id failed", K(ret), K(arg)); - } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { - LOG_WARN("process lock task failed", K(ret), K(arg)); - } - ret = rewrite_return_code_(ret, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::lock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockAloneTabletRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_2_0_0))) { - LOG_WARN("cluster version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(LOCK_ALONE_TABLET, arg.table_id_, - arg.ls_id_, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_tablet_id(arg.tablet_ids_))) { - LOG_WARN("set tablet id failed", K(ret), K(arg)); - } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { - LOG_WARN("process lock task failed", K(ret), K(arg)); - } - ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::unlock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockAloneTabletRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid()) || - OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_2_0_0))) { - LOG_WARN("cluster version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(UNLOCK_ALONE_TABLET, arg.table_id_, - arg.ls_id_, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_tablet_id(arg.tablet_ids_))) { - LOG_WARN("set tablet id failed", K(ret), K(arg)); - } else if (OB_FAIL(process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_))) { - LOG_WARN("process lock task failed", K(ret), K(arg)); - } - ret = rewrite_return_code_(ret, ctx.is_from_sql_); - } - return ret; -} - int ObTableLockService::lock_partition_or_subpartition(ObTxDesc &tx_desc, const ObTxParam &tx_param, - const ObLockPartitionRequest &arg) + ObLockPartitionRequest &arg) { int ret = OB_SUCCESS; ObPartitionLevel part_level = PARTITION_LEVEL_MAX; @@ -907,300 +786,95 @@ int ObTableLockService::lock_partition_or_subpartition(ObTxDesc &tx_desc, LOG_WARN("can not get table partition level", K(ret), K(arg)); } else { Thread::WaitGuard guard(Thread::WAIT); - switch (part_level) { - case PARTITION_LEVEL_ONE: { - if (OB_FAIL(lock_partition(tx_desc, tx_param, arg))) { - LOG_WARN("lock partition failed", K(ret), K(arg)); + if (PARTITION_LEVEL_TWO == part_level) { + arg.is_sub_part_ = true; + } + if (OB_FAIL(lock(tx_desc, tx_param, arg))) { + LOG_WARN("lock partition failed", K(ret), K(arg)); + } + } + return ret; +} + +int ObTableLockService::lock(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObLockRequest &arg) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("lock service is not inited", K(ret)); + } else if (OB_UNLIKELY(!tx_desc.is_valid()) || + OB_UNLIKELY(!tx_param.is_valid()) || + OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), + K(tx_param.is_valid()), K(arg.is_valid())); + } else { + ObTableLockCtx ctx; + if (OB_FAIL(ctx.set_by_lock_req(arg))) { + LOG_WARN("set ObTableLockCtx failed", K(ret), K(arg)); + } else { + ctx.is_in_trans_ = true; + ctx.tx_desc_ = &tx_desc; + ctx.tx_param_ = tx_param; + if (OB_FAIL(process_lock_task_(ctx))) { + LOG_WARN("process lock task failed", K(ret), K(ctx), K(arg)); + ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); } - break; } - case PARTITION_LEVEL_TWO: { - if (OB_FAIL(lock_subpartition(tx_desc, tx_param, arg))) { - LOG_WARN("lock subpartition failed", K(ret), K(arg)); + } + return ret; +} + +int ObTableLockService::unlock(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObUnLockRequest &arg) +{ + int ret = OB_SUCCESS; + if (!arg.is_unlock_request()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("can not unlock by a lock request", K(ret), K(tx_desc), K(tx_param), K(arg)); + } else if (OB_FAIL(lock(tx_desc, tx_param, arg))) { + LOG_WARN("do unlock request failed", K(ret), K(tx_desc), K(tx_param), K(arg)); + } + return ret; +} + +int ObTableLockService::replace_lock(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObReplaceLockRequest &replace_req) +{ + int ret = OB_SUCCESS; + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("lock service is not inited", K(ret)); + } else if (OB_UNLIKELY(!tx_desc.is_valid()) || + OB_UNLIKELY(!tx_param.is_valid()) || + OB_UNLIKELY(!replace_req.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(tx_desc), K(replace_req), K(tx_desc.is_valid()), + K(tx_param.is_valid()), K(replace_req.is_valid())); + // FIXME: change to 431 later + } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_3_0_0))) { + LOG_WARN("cluster version check failed", K(ret), K(replace_req)); + } else { + ObReplaceTableLockCtx ctx; + if (OB_FAIL(ctx.set_by_lock_req(*replace_req.unlock_req_, true))) { + LOG_WARN("fail to set unlock_ctx", K(ret), K(replace_req)); + } else { + ctx.is_in_trans_ = true; + ctx.tx_desc_ = &tx_desc; + ctx.tx_param_ = tx_param; + ctx.new_lock_mode_ = replace_req.new_lock_mode_; + ctx.new_lock_owner_ = replace_req.new_lock_owner_; + if (OB_FAIL(process_lock_task_(ctx))) { + LOG_WARN("process lock task failed", K(ret), K(ctx), K(replace_req)); + ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); } - break; } - default: { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected partition level", K(ret), K(arg), K(part_level)); - } - } - } - return ret; -} - -int ObTableLockService::lock_partition(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockPartitionRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid()), K(tx_desc), K(tx_param), K(arg)); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_1_0_0))) { - LOG_WARN("cluster version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(LOCK_PARTITION, arg.table_id_, arg.part_object_id_, - arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::unlock_partition(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockPartitionRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid()) || - OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_1_0_0))) { - LOG_WARN("cluster version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(UNLOCK_PARTITION, arg.table_id_, arg.part_object_id_, - arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - ret = rewrite_return_code_(ret, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::lock_subpartition(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockPartitionRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_1_0_0))) { - LOG_WARN("cluster version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(LOCK_SUBPARTITION, arg.table_id_, arg.part_object_id_, - arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::unlock_subpartition(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockPartitionRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid()) || - OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_1_0_0))) { - LOG_WARN("cluster version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(UNLOCK_SUBPARTITION, arg.table_id_, arg.part_object_id_, - arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - ret = rewrite_return_code_(ret, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::lock_obj(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockObjRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_data_version_after_(DATA_VERSION_4_1_0_0))) { - LOG_WARN("data version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(LOCK_OBJECT, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_lock_id(arg.obj_type_, arg.obj_id_))) { - LOG_WARN("set lock id failed", K(ret), K(arg)); - } else { - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - } - ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::unlock_obj(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockObjRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid()) || - OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_data_version_after_(DATA_VERSION_4_1_0_0))) { - LOG_WARN("data version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(UNLOCK_OBJECT, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_lock_id(arg.obj_type_, arg.obj_id_))) { - LOG_WARN("set lock id failed", K(ret), K(arg)); - } else { - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - } - ret = rewrite_return_code_(ret, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::lock_obj(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockObjsRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid())) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_data_version_after_(DATA_VERSION_4_1_0_0))) { - LOG_WARN("data version check failed", K(ret), K(arg)); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_2_0_0))) { - LOG_WARN("cluster version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(LOCK_OBJECT, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_lock_id(arg.objs_))) { - LOG_WARN("set lock id failed", K(ret), K(arg)); - } else { - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - } - ret = rewrite_return_code_(ret, ctx.ret_code_before_end_stmt_or_tx_, ctx.is_from_sql_); - } - return ret; -} - -int ObTableLockService::unlock_obj(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockObjsRequest &arg) -{ - int ret = OB_SUCCESS; - - if (IS_NOT_INIT) { - ret = OB_NOT_INIT; - LOG_WARN("lock service is not inited", K(ret)); - } else if (OB_UNLIKELY(!tx_desc.is_valid()) || - OB_UNLIKELY(!tx_param.is_valid()) || - OB_UNLIKELY(!arg.is_valid()) || - OB_UNLIKELY(ObTableLockOpType::OUT_TRANS_UNLOCK != arg.op_type_)) { - ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid argument", K(ret), K(tx_desc), K(arg), K(tx_desc.is_valid()), - K(tx_param.is_valid()), K(arg.is_valid())); - } else if (OB_FAIL(check_data_version_after_(DATA_VERSION_4_1_0_0))) { - LOG_WARN("data version check failed", K(ret), K(arg)); - } else if (OB_FAIL(check_cluster_version_after_(CLUSTER_VERSION_4_2_0_0))) { - LOG_WARN("cluster version check failed", K(ret), K(arg)); - } else { - Thread::WaitGuard guard(Thread::WAIT); - ObTableLockCtx ctx(UNLOCK_OBJECT, arg.timeout_us_, arg.timeout_us_); - ctx.is_in_trans_ = true; - ctx.tx_desc_ = &tx_desc; - ctx.tx_param_ = tx_param; - ctx.lock_op_type_ = arg.op_type_; - ctx.is_from_sql_ = arg.is_from_sql_; - if (OB_FAIL(ctx.set_lock_id(arg.objs_))) { - LOG_WARN("set lock id failed", K(ret), K(arg)); - } else { - ret = process_lock_task_(ctx, arg.lock_mode_, arg.owner_id_); - } - ret = rewrite_return_code_(ret, ctx.is_from_sql_); } return ret; } @@ -1230,29 +904,28 @@ int ObTableLockService::get_obj_lock_garbage_collector(ObOBJLockGarbageCollector } return ret; } -int ObTableLockService::process_lock_task_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) +int ObTableLockService::process_lock_task_(ObTableLockCtx &ctx) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; + LOG_INFO("[table lock] lock_table", K(ctx)); if (!ctx.is_in_trans_ && OB_FAIL(start_tx_(ctx))) { LOG_WARN("failed to start trans", K(ret)); } else if (ctx.is_in_trans_ && OB_FAIL(start_stmt_(ctx))) { LOG_WARN("start stmt failed", K(ret), K(ctx)); - } else if (LOCK_OBJECT == ctx.task_type_ || UNLOCK_OBJECT == ctx.task_type_) { - if (OB_FAIL(process_obj_lock_task_(ctx, lock_mode, lock_owner))) { - LOG_WARN("lock obj failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + } else if (is_obj_lock_task(ctx.task_type_)) { + if (OB_FAIL(process_obj_lock_task_(ctx))) { + LOG_WARN("lock obj failed", K(ret), K(ctx)); } - } else if (LOCK_ALONE_TABLET == ctx.task_type_ || UNLOCK_ALONE_TABLET == ctx.task_type_) { + } else if (LOCK_ALONE_TABLET == ctx.task_type_ || UNLOCK_ALONE_TABLET == ctx.task_type_ || REPLACE_LOCK_ALONE_TABLET == ctx.task_type_) { // only alone tablet should do like this. - if (OB_FAIL(process_tablet_lock_task_(ctx, lock_mode, lock_owner, nullptr/* schema ptr */))) { - LOG_WARN("process tablet lock task failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + if (OB_FAIL(process_tablet_lock_task_(ctx, nullptr/* schema ptr */))) { + LOG_WARN("process tablet lock task failed", K(ret), K(ctx)); } } else { - if (OB_FAIL(process_table_lock_task_(ctx, lock_mode, lock_owner))) { - LOG_WARN("process table lock task failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + if (OB_FAIL(process_table_lock_task_(ctx))) { + LOG_WARN("process table lock task failed", K(ret), K(ctx)); } } ctx.ret_code_before_end_stmt_or_tx_ = ret; @@ -1273,40 +946,36 @@ int ObTableLockService::process_lock_task_(ObTableLockCtx &ctx, } } - LOG_INFO("[table lock] lock_table", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + LOG_INFO("[table lock] lock_table", K(ret), K(ctx)); return ret; } -int ObTableLockService::process_obj_lock_task_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) +int ObTableLockService::process_obj_lock_task_(ObTableLockCtx &ctx) { int ret = OB_SUCCESS; if (ctx.obj_list_.empty()) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("obj list is empty when lock obj", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + LOG_WARN("obj list is empty when lock obj", K(ret), K(ctx)); } else { if (GET_MIN_CLUSTER_VERSION() < CLUSTER_VERSION_4_2_0_0) { ObLockID lock_id; for (int64_t i = 0; OB_SUCC(ret) && i < ctx.obj_list_.count(); ++i) { lock_id = ctx.obj_list_.at(i); - if (OB_FAIL(process_obj_lock_(ctx, LOCK_SERVICE_LS, lock_id, lock_mode, lock_owner))) { - LOG_WARN("lock obj failed", K(ret), K(ctx), K(LOCK_SERVICE_LS), K(lock_id), K(ctx.task_type_), K(lock_mode)); + if (OB_FAIL(process_obj_lock_(ctx, LOCK_SERVICE_LS, lock_id))) { + LOG_WARN("lock obj failed", K(ret), K(ctx), K(LOCK_SERVICE_LS), K(lock_id)); } } } else { - if (OB_FAIL(process_obj_lock_(ctx, LOCK_SERVICE_LS, ctx.obj_list_, lock_mode, lock_owner))) { - LOG_WARN("lock obj failed", K(ret), K(ctx), K(LOCK_SERVICE_LS), K(ctx.obj_list_), K(ctx.task_type_), K(lock_mode)); + if (OB_FAIL(process_obj_lock_(ctx, LOCK_SERVICE_LS, ctx.obj_list_))) { + LOG_WARN("lock obj failed", K(ret), K(ctx), K(LOCK_SERVICE_LS), K(ctx.obj_list_)); } } } return ret; } -int ObTableLockService::process_table_lock_task_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) +int ObTableLockService::process_table_lock_task_(ObTableLockCtx &ctx) { int ret = OB_SUCCESS; const uint64_t tenant_id = MTL_ID(); @@ -1316,8 +985,8 @@ int ObTableLockService::process_table_lock_task_(ObTableLockCtx &ctx, ctx.schema_version_ = 0; - if (OB_FAIL(process_table_lock_(ctx, lock_mode, lock_owner))) { - LOG_WARN("lock table failed", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + if (OB_FAIL(process_table_lock_(ctx))) { + LOG_WARN("lock table failed", K(ret), K(ctx)); } else if (OB_FAIL(ObSchemaUtils::get_latest_table_schema( *sql_proxy_, allocator, @@ -1335,8 +1004,6 @@ int ObTableLockService::process_table_lock_task_(ObTableLockCtx &ctx, ret = OB_OP_NOT_ALLOW; LOG_WARN("lock table not allowed now", K(ret), K(ctx)); } else if (OB_FAIL(process_tablet_lock_task_(ctx, - lock_mode, - lock_owner, table_schema))) { LOG_WARN("failed to lock table tablet", K(ret), K(ctx)); } @@ -1344,8 +1011,6 @@ int ObTableLockService::process_table_lock_task_(ObTableLockCtx &ctx, } int ObTableLockService::process_tablet_lock_task_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, const ObSimpleTableSchemaV2 *table_schema) { int ret = OB_SUCCESS; @@ -1359,19 +1024,15 @@ int ObTableLockService::process_tablet_lock_task_(ObTableLockCtx &ctx, ctx.schema_version_ = table_schema->get_schema_version(); } - if (OB_FAIL(get_process_tablets_(lock_mode, table_schema, ctx))) { + if (OB_FAIL(get_process_tablets_(table_schema, ctx))) { LOG_WARN("failed to get parts", K(ret), K(ctx)); // lock_map and ls_lock_map are the map of lock which is generated with tablet_id } else if (OB_FAIL(get_ls_lock_map_(ctx, ctx.tablet_list_, lock_map, ls_lock_map))) { LOG_WARN("fail to get ls lock map", K(ret), K(ctx.get_tablet_cnt())); } else if (OB_FAIL(pre_check_lock_(ctx, - lock_mode, - lock_owner, ls_lock_map))) { - LOG_WARN("failed to pre_check_lock_", K(ret), K(ctx), K(lock_mode), K(lock_owner)); + LOG_WARN("failed to pre_check_lock_", K(ret), K(ctx)); } else if (OB_FAIL(process_table_tablet_lock_(ctx, - lock_mode, - lock_owner, lock_map, ls_lock_map))) { LOG_WARN("failed to lock table tablet", K(ret), K(ctx)); @@ -1384,7 +1045,9 @@ bool ObTableLockService::is_part_table_lock_(const ObTableLockTaskType task_type return (LOCK_TABLET == task_type || UNLOCK_TABLET == task_type || LOCK_PARTITION == task_type || UNLOCK_PARTITION == task_type || LOCK_SUBPARTITION == task_type || UNLOCK_SUBPARTITION == task_type || - LOCK_ALONE_TABLET == task_type || UNLOCK_ALONE_TABLET == task_type); + LOCK_ALONE_TABLET == task_type || UNLOCK_ALONE_TABLET == task_type || + REPLACE_LOCK_TABLETS == task_type || REPLACE_LOCK_ALONE_TABLET == task_type || + REPLACE_LOCK_PARTITION == task_type || REPLACE_LOCK_SUBPARTITION == task_type); } int ObTableLockService::get_table_lock_mode_(const ObTableLockTaskType task_type, @@ -1590,16 +1253,13 @@ int ObTableLockService::handle_parallel_rpc_response_(RpcProxy &proxy_batch, return ret; } -int ObTableLockService::pre_check_lock_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, - const ObLSLockMap &ls_lock_map) +int ObTableLockService::pre_check_lock_(ObTableLockCtx &ctx, const ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; if (GET_MIN_CLUSTER_VERSION() > CLUSTER_VERSION_4_0_0_0) { - ret = batch_pre_check_lock_(ctx, lock_mode, lock_owner, ls_lock_map); + ret = batch_pre_check_lock_(ctx, ls_lock_map); } else { - ret = pre_check_lock_old_version_(ctx, lock_mode, lock_owner, ls_lock_map); + ret = pre_check_lock_old_version_(ctx, ls_lock_map); } return ret; } @@ -1608,10 +1268,7 @@ int ObTableLockService::pre_check_lock_(ObTableLockCtx &ctx, template int ObTableLockService::parallel_batch_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, - const ObTableLockTaskType lock_task_type, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) + const ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; constexpr static int64_t MAP_NUM = 2; @@ -1636,10 +1293,7 @@ int ObTableLockService::parallel_batch_rpc_handle_(RpcProxy &proxy_batch, LOG_WARN("reuse retry map failed", K(ret)); } else if (OB_FAIL(parallel_batch_rpc_handle_(proxy_batch, ctx, - lock_task_type, *in_map, - lock_mode, - lock_owner, can_retry, *retry_map))) { LOG_WARN("process rpc failed", KR(ret), K(can_retry), K(ctx), K(retry_times)); @@ -1663,10 +1317,7 @@ int ObTableLockService::parallel_batch_rpc_handle_(RpcProxy &proxy_batch, template int ObTableLockService::parallel_send_rpc_task_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, - const ObTableLockTaskType lock_task_type, const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, ObRetryCtx &retry_ctx) { int ret = OB_SUCCESS; @@ -1683,8 +1334,6 @@ int ObTableLockService::parallel_send_rpc_task_(RpcProxy &proxy_batch, ctx, ls_id, lock_ids, - lock_mode, - lock_owner, retry_ctx))) { LOG_WARN("send rpc task failed", K(ret)); } @@ -1705,10 +1354,7 @@ int ObTableLockService::parallel_send_rpc_task_(RpcProxy &proxy_batch, template int ObTableLockService::parallel_batch_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, - const ObTableLockTaskType lock_task_type, const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, bool &can_retry, ObLSLockMap &retry_ls_lock_map) { @@ -1720,10 +1366,7 @@ int ObTableLockService::parallel_batch_rpc_handle_(RpcProxy &proxy_batch, // send async rpc parallel if (OB_FAIL(parallel_send_rpc_task_(proxy_batch, ctx, - lock_task_type, ls_lock_map, - lock_mode, - lock_owner, retry_ctx))) { can_retry = false; (void)collect_rollback_info_(retry_ctx.rpc_ls_array_, proxy_batch, ctx); @@ -1752,8 +1395,6 @@ int ObTableLockService::parallel_batch_rpc_handle_(RpcProxy &proxy_batch, } int ObTableLockService::batch_pre_check_lock_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, const ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; @@ -1775,10 +1416,7 @@ int ObTableLockService::batch_pre_check_lock_(ObTableLockCtx &ctx, } else { ret = parallel_batch_rpc_handle_(proxy_batch, ctx, - PRE_CHECK_TABLET, - ls_lock_map, - lock_mode, - lock_owner); + ls_lock_map); // the process process may be timeout because left time not enough, // just rewrite it to OB_ERR_EXCLUSIVE_LOCK_CONFLICT if (is_timeout_ret_code_(ret)) { @@ -1809,8 +1447,7 @@ int ObTableLockService::batch_pre_check_lock_(ObTableLockCtx &ctx, } } } while (need_retry); // retry task level - LOG_DEBUG("ObTableLockService::pre_check_lock_", K(ret), K(ctx), - K(ctx.task_type_), K(lock_mode), K(lock_owner)); + LOG_DEBUG("ObTableLockService::pre_check_lock_", K(ret), K(ctx)); } return ret; } @@ -1851,8 +1488,6 @@ int ObTableLockService::rpc_call_(RpcProxy &proxy_batch, } int ObTableLockService::pre_check_lock_old_version_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, const ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; @@ -1892,8 +1527,7 @@ int ObTableLockService::pre_check_lock_old_version_(ObTableLockCtx &ctx, if (OB_FAIL(retry_ctx.rpc_ls_array_.push_back(ls_id))) { LOG_WARN("push_back lsid failed", K(ret), K(ls_id)); - } else if (OB_FAIL(pack_request_(ctx, PRE_CHECK_TABLET, lock_mode, lock_owner, - lock_id, ls_id, addr, request))) { + } else if (OB_FAIL(pack_request_(ctx, PRE_CHECK_TABLET, lock_id, ls_id, addr, request))) { LOG_WARN("pack_request_ failed", K(ret), K(ls_id), K(lock_id)); // the rpc timeout must larger than stmt timeout. } else if (FALSE_IT(timeout_us = ctx.get_rpc_timeoutus())) { @@ -1943,8 +1577,7 @@ int ObTableLockService::pre_check_lock_old_version_(ObTableLockCtx &ctx, } } } while (need_retry); - LOG_DEBUG("ObTableLockService::pre_check_lock_", K(ret), K(ctx), - K(ctx.task_type_), K(lock_mode), K(lock_owner)); + LOG_DEBUG("ObTableLockService::pre_check_lock_", K(ret), K(ctx)); } return ret; } @@ -1996,22 +1629,23 @@ int ObTableLockService::get_table_partition_level_(const ObTableID table_id, int ObTableLockService::pack_batch_request_(ObTableLockCtx &ctx, const ObTableLockTaskType task_type, - const ObTableLockMode &lock_mode, - const ObTableLockOwnerID &lock_owner, const share::ObLSID &ls_id, const ObLockIDArray &lock_ids, - ObLockTaskBatchRequest &request) + ObLockTaskBatchRequest &request) { int ret = OB_SUCCESS; ObLockParam lock_param; if (OB_FAIL(request.init(task_type, ls_id, ctx.tx_desc_))) { - LOG_WARN("request init failed", K(ret), K(task_type), K(ls_id), KP(ctx.tx_desc_)); + LOG_WARN("request init failed", K(ret), K(ctx), K(ls_id), KP(ctx.tx_desc_), K(lock_ids), K(task_type)); + } else if (ctx.is_replace_task()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("lock_param is not compatible with request", K(ret), K(ctx), K(task_type)); } else { for (int i = 0; i < lock_ids.count() && OB_SUCC(ret); ++i) { lock_param.reset(); if (OB_FAIL(lock_param.set(lock_ids[i], - lock_mode, - lock_owner, + ctx.lock_mode_, + ctx.lock_owner_, ctx.lock_op_type_, ctx.schema_version_, ctx.is_deadlock_avoid_enabled(), @@ -2026,10 +1660,35 @@ int ObTableLockService::pack_batch_request_(ObTableLockCtx &ctx, return ret; } +int ObTableLockService::pack_batch_request_(ObTableLockCtx &ctx, + const ObTableLockTaskType task_type, + const share::ObLSID &ls_id, + const ObLockIDArray &lock_ids, + ObLockTaskBatchRequest &request) +{ + int ret = OB_SUCCESS; + ObReplaceLockParam lock_param; + if (OB_FAIL(request.init(task_type, ls_id, ctx.tx_desc_))) { + LOG_WARN("request init failed", K(ret), K(ctx), K(ls_id), KP(ctx.tx_desc_), K(lock_ids), K(task_type)); + } else if (!ctx.is_replace_task()) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("lock_param is not compatible with request", K(ret), K(ctx), K(task_type)); + } else { + const ObReplaceTableLockCtx &replace_ctx = static_cast(ctx); + for (int i = 0; i < lock_ids.count() && OB_SUCC(ret); ++i) { + lock_param.reset(); + if (OB_FAIL(replace_ctx.get_lock_param(lock_ids[i], lock_param))) { + LOG_WARN("get lock param failed", K(ret)); + } else if (OB_FAIL(request.params_.push_back(lock_param))) { + LOG_WARN("get lock request failed", K(ret), K(lock_param)); + } + } + } + return ret; +} + int ObTableLockService::pack_request_(ObTableLockCtx &ctx, const ObTableLockTaskType task_type, - const ObTableLockMode &lock_mode, - const ObTableLockOwnerID &lock_owner, const ObLockID &lock_id, const share::ObLSID &ls_id, ObAddr &addr, @@ -2038,8 +1697,8 @@ int ObTableLockService::pack_request_(ObTableLockCtx &ctx, int ret = OB_SUCCESS; ObLockParam lock_param; if (OB_FAIL(lock_param.set(lock_id, - lock_mode, - lock_owner, + ctx.lock_mode_, + ctx.lock_owner_, ctx.lock_op_type_, ctx.schema_version_, ctx.is_deadlock_avoid_enabled(), @@ -2064,9 +1723,7 @@ int ObTableLockService::pack_request_(ObTableLockCtx &ctx, template int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) + const ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; @@ -2093,8 +1750,6 @@ int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, } else if (OB_FAIL(batch_rpc_handle_(proxy_batch, ctx, *in_map, - lock_mode, - lock_owner, can_retry, *retry_map))) { LOG_WARN("process rpc failed", KR(ret), K(ctx), K(retry_times)); @@ -2110,35 +1765,21 @@ int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, return ret; } -template +template int ObTableLockService::send_rpc_task_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, const share::ObLSID &ls_id, const ObLockIDArray &lock_ids, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, ObRetryCtx &retry_ctx) { int ret = OB_SUCCESS; - ObLockTaskBatchRequest request; ObAddr addr; retry_ctx.need_retry_ = false; if (OB_FAIL(retry_ctx.rpc_ls_array_.push_back(ls_id))) { LOG_WARN("push_back lsid failed", K(ret), K(ls_id)); - } else if (OB_FAIL(pack_batch_request_(ctx, - ctx.task_type_, - lock_mode, - lock_owner, - ls_id, - lock_ids, - request))) { - LOG_WARN("pack_request_ failed", K(ret), K(ls_id)); - } else if (OB_FAIL(get_ls_leader_(ctx.tx_desc_->get_cluster_id(), - ctx.tx_desc_->get_tenant_id(), - ls_id, - ctx.abs_timeout_ts_, - addr))) { + } else if (OB_FAIL(get_ls_leader_( + ctx.tx_desc_->get_cluster_id(), ctx.tx_desc_->get_tenant_id(), ls_id, ctx.abs_timeout_ts_, addr))) { if (need_renew_location_(ret)) { retry_ctx.need_retry_ = true; ret = OB_SUCCESS; @@ -2147,30 +1788,65 @@ int ObTableLockService::send_rpc_task_(RpcProxy &proxy_batch, } else if (ctx.is_timeout()) { ret = OB_TIMEOUT; LOG_WARN("process obj lock timeout", K(ret), K(ctx)); - } else if (OB_FAIL(rpc_call_(proxy_batch, - addr, - ctx.get_rpc_timeoutus(), - request))) { - LOG_WARN("failed to call async rpc", KR(ret), K(addr), - K(ctx.abs_timeout_ts_), K(request)); } else { - retry_ctx.send_rpc_count_++; - ALLOW_NEXT_LOG(); - LOG_INFO("send table lock rpc", KR(ret), K(retry_ctx.send_rpc_count_), K(addr), "request", request); + ret = pack_and_call_rpc_(proxy_batch, ctx, ls_id, lock_ids, addr, retry_ctx); } + if (OB_FAIL(ret)) { retry_ctx.need_retry_ = false; } return ret; } -template +template +int ObTableLockService::pack_and_call_rpc_(RpcProxy &proxy_batch, + ObTableLockCtx &ctx, + const share::ObLSID &ls_id, + const ObLockIDArray &lock_ids, + const ObAddr &addr, + ObRetryCtx &retry_ctx) +{ + int ret = OB_SUCCESS; + ObLockTaskBatchRequest request; + if (OB_FAIL(pack_batch_request_(ctx, ctx.task_type_, ls_id, lock_ids, request))) { + LOG_WARN("pack_request_ failed", K(ret), K(ls_id), K(ctx), K(lock_ids)); + } else if (OB_FAIL(rpc_call_(proxy_batch, addr, ctx.get_rpc_timeoutus(), request))) { + LOG_WARN("failed to call async rpc", KR(ret), K(addr), K(ctx.abs_timeout_ts_), K(request)); + } else { + retry_ctx.send_rpc_count_++; + ALLOW_NEXT_LOG(); + LOG_INFO("send table lock rpc", KR(ret), K(retry_ctx.send_rpc_count_), K(addr), "request", request); + } + return ret; +} + +template <> +int ObTableLockService::pack_and_call_rpc_(obrpc::ObBatchReplaceLockProxy &proxy_batch, + ObTableLockCtx &ctx, + const share::ObLSID &ls_id, + const ObLockIDArray &lock_ids, + const ObAddr &addr, + ObRetryCtx &retry_ctx) +{ + int ret = OB_SUCCESS; + ObLockTaskBatchRequest request; + if (OB_FAIL(pack_batch_request_(ctx, ctx.task_type_, ls_id, lock_ids, request))) { + LOG_WARN("pack_request_ failed", K(ret), K(ls_id), K(ctx), K(lock_ids)); + } else if (OB_FAIL(rpc_call_(proxy_batch, addr, ctx.get_rpc_timeoutus(), request))) { + LOG_WARN("failed to call async rpc", KR(ret), K(addr), K(ctx.abs_timeout_ts_), K(request)); + } else { + retry_ctx.send_rpc_count_++; + ALLOW_NEXT_LOG(); + LOG_INFO("send table lock rpc", KR(ret), K(retry_ctx.send_rpc_count_), K(addr), "request", request); + } + return ret; +} + +template int ObTableLockService::send_one_rpc_task_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, const share::ObLSID &ls_id, const ObLockIDArray &lock_ids, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, ObRetryCtx &retry_ctx) { int ret = OB_SUCCESS; @@ -2180,8 +1856,6 @@ int ObTableLockService::send_one_rpc_task_(RpcProxy &proxy_batch, ctx, ls_id, lock_ids, - lock_mode, - lock_owner, retry_ctx))) { LOG_WARN("send rpc task failed", K(ret), K(ls_id)); } else if (retry_ctx.need_retry_) { @@ -2199,8 +1873,6 @@ template int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, bool &can_retry, ObLSLockMap &retry_ls_lock_map) { @@ -2217,8 +1889,6 @@ int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, ctx, ls_id, lock_ids, - lock_mode, - lock_owner, retry_ctx))) { can_retry = false; (void)collect_rollback_info_(retry_ctx.rpc_ls_array_, proxy_batch, ctx); @@ -2253,13 +1923,11 @@ int ObTableLockService::batch_rpc_handle_(RpcProxy &proxy_batch, return ret; } -template +template int ObTableLockService::parallel_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, const LockMap &lock_map, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) + const ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; int64_t timeout_us = 0; @@ -2277,8 +1945,7 @@ int ObTableLockService::parallel_rpc_handle_(RpcProxy &proxy_batch, if (OB_FAIL(retry_ctx.rpc_ls_array_.push_back(ls_id))) { LOG_WARN("push_back lsid failed", K(ret), K(ls_id)); - } else if (OB_FAIL(pack_request_(ctx, ctx.task_type_, lock_mode, lock_owner, - lock_id, ls_id, addr, request))) { + } else if (OB_FAIL(pack_request_(ctx, ctx.task_type_, lock_id, ls_id, addr, request))) { LOG_WARN("pack_request_ failed", K(ret), K(ls_id), K(lock_id)); } else if (FALSE_IT(timeout_us = ctx.get_rpc_timeoutus())) { } else if (ctx.is_timeout()) { @@ -2305,19 +1972,20 @@ int ObTableLockService::parallel_rpc_handle_(RpcProxy &proxy_batch, } int ObTableLockService::inner_process_obj_lock_batch_(ObTableLockCtx &ctx, - const ObLSLockMap &lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) + const ObLSLockMap &lock_map) { int ret = OB_SUCCESS; obrpc::ObSrvRpcProxy rpc_proxy(*GCTX.srv_rpc_proxy_); rpc_proxy.set_detect_session_killed(true); if (ctx.is_unlock_task()) { ObHighPriorityBatchLockProxy proxy_batch(rpc_proxy, &obrpc::ObSrvRpcProxy::batch_unlock_obj); - ret = batch_rpc_handle_(proxy_batch, ctx, lock_map, lock_mode, lock_owner); + ret = batch_rpc_handle_(proxy_batch, ctx, lock_map); + } else if (ctx.is_replace_task()) { + ObBatchReplaceLockProxy proxy_batch(rpc_proxy, &obrpc::ObSrvRpcProxy::batch_replace_lock_obj); + ret = batch_rpc_handle_(proxy_batch, ctx, lock_map); } else { ObBatchLockProxy proxy_batch(rpc_proxy, &obrpc::ObSrvRpcProxy::batch_lock_obj); - ret = batch_rpc_handle_(proxy_batch, ctx, lock_map, lock_mode, lock_owner); + ret = batch_rpc_handle_(proxy_batch, ctx, lock_map); } return ret; @@ -2325,9 +1993,7 @@ int ObTableLockService::inner_process_obj_lock_batch_(ObTableLockCtx &ctx, int ObTableLockService::inner_process_obj_lock_old_version_(ObTableLockCtx &ctx, const LockMap &lock_map, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) + const ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; obrpc::ObSrvRpcProxy rpc_proxy(*GCTX.srv_rpc_proxy_); @@ -2335,10 +2001,10 @@ int ObTableLockService::inner_process_obj_lock_old_version_(ObTableLockCtx &ctx, // TODO: yanyuan.cxf we process the rpc one by one and do parallel later. if (ctx.is_unlock_task()) { ObHighPriorityTableLockProxy proxy_batch(rpc_proxy, &obrpc::ObSrvRpcProxy::unlock_table); - ret = parallel_rpc_handle_(proxy_batch, ctx, lock_map, ls_lock_map, lock_mode, lock_owner); + ret = parallel_rpc_handle_(proxy_batch, ctx, lock_map, ls_lock_map); } else { ObTableLockProxy proxy_batch(rpc_proxy, &obrpc::ObSrvRpcProxy::lock_table); - ret = parallel_rpc_handle_(proxy_batch, ctx, lock_map, ls_lock_map, lock_mode, lock_owner); + ret = parallel_rpc_handle_(proxy_batch, ctx, lock_map, ls_lock_map); } return ret; @@ -2346,15 +2012,13 @@ int ObTableLockService::inner_process_obj_lock_old_version_(ObTableLockCtx &ctx, int ObTableLockService::inner_process_obj_lock_(ObTableLockCtx &ctx, const LockMap &lock_map, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) + const ObLSLockMap &ls_lock_map) { int ret = OB_SUCCESS; if (GET_MIN_CLUSTER_VERSION() > CLUSTER_VERSION_4_0_0_0) { - ret = inner_process_obj_lock_batch_(ctx, ls_lock_map, lock_mode, lock_owner); + ret = inner_process_obj_lock_batch_(ctx, ls_lock_map); } else { - ret = inner_process_obj_lock_old_version_(ctx, lock_map, ls_lock_map, lock_mode, lock_owner); + ret = inner_process_obj_lock_old_version_(ctx, lock_map, ls_lock_map); } return ret; @@ -2362,9 +2026,7 @@ int ObTableLockService::inner_process_obj_lock_(ObTableLockCtx &ctx, int ObTableLockService::process_obj_lock_(ObTableLockCtx &ctx, const ObLSID &ls_id, - const ObLockID &lock_id, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) + const ObLockID &lock_id) { int ret = OB_SUCCESS; int tmp_ret = OB_SUCCESS; @@ -2399,9 +2061,7 @@ int ObTableLockService::process_obj_lock_(ObTableLockCtx &ctx, } else { if (OB_FAIL(inner_process_obj_lock_(ctx, lock_map, - ls_lock_map, - lock_mode, - lock_owner))) { + ls_lock_map))) { LOG_WARN("process object lock failed", K(ret), K(lock_id), K(ls_id)); } if (OB_SUCC(ret)) { @@ -2420,20 +2080,16 @@ int ObTableLockService::process_obj_lock_(ObTableLockCtx &ctx, } } while (need_retry && OB_SUCC(ret)); } - LOG_DEBUG("ObTableLockService::process_obj_lock_", K(ret), K(ctx), K(ls_id), - K(lock_id), K(ctx.task_type_), K(lock_mode), K(lock_owner)); + LOG_DEBUG("ObTableLockService::process_obj_lock_", K(ret), K(ctx), K(ls_id), K(lock_id)); return ret; } int ObTableLockService::process_obj_lock_(ObTableLockCtx &ctx, const ObLSID &ls_id, - const common::ObIArray &lock_ids, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) + const common::ObIArray &lock_ids) { int ret = OB_SUCCESS; - int tmp_ret = OB_SUCCESS; bool need_retry = false; ObLSLockMap ls_lock_map; ObLockIDArray lock_array; @@ -2458,7 +2114,7 @@ int ObTableLockService::process_obj_lock_(ObTableLockCtx &ctx, } else if (OB_FAIL(start_sub_tx_(ctx))) { LOG_WARN("failed to start sub tx", K(ret), K(ctx)); } else { - if (OB_FAIL(inner_process_obj_lock_batch_(ctx, ls_lock_map, lock_mode, lock_owner))) { + if (OB_FAIL(inner_process_obj_lock_batch_(ctx, ls_lock_map))) { LOG_WARN("process object locks failed", K(ret), K(lock_ids), K(ls_id)); } if (OB_SUCC(ret)) { @@ -2477,43 +2133,35 @@ int ObTableLockService::process_obj_lock_(ObTableLockCtx &ctx, } } while (need_retry && OB_SUCC(ret)); } - LOG_DEBUG("ObTableLockService::process_obj_lock_", K(ret), K(ctx), K(ls_id), - K(lock_ids), K(ctx.task_type_), K(lock_mode), K(lock_owner)); + LOG_DEBUG("ObTableLockService::process_obj_lock_", K(ret), K(ctx), K(ls_id), K(lock_ids)); return ret; } -int ObTableLockService::process_table_lock_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner) +int ObTableLockService::process_table_lock_(ObTableLockCtx &ctx) { int ret = OB_SUCCESS; ObLockID lock_id; - ObTableLockMode table_lock_mode = lock_mode; - if (OB_FAIL(get_lock_id(ctx.table_id_, - lock_id))) { + // lock_mode may be changed in get_table_lock_mode_, so we record it here, + // and reset it after process_obj_lock_ + const ObTableLockMode orig_lock_mode = ctx.lock_mode_; + if (OB_FAIL(get_lock_id(ctx.table_id_, lock_id))) { LOG_WARN("get lock id failed", K(ret), K(ctx)); - } else if (is_part_table_lock_(ctx.task_type_) && - OB_FAIL(get_table_lock_mode_(ctx.task_type_, - lock_mode, - table_lock_mode))) { - LOG_WARN("get table lock mode failed", K(ret), K(ctx), K(ctx.task_type_), K(lock_mode)); - } else if (OB_FAIL(process_obj_lock_(ctx, - LOCK_SERVICE_LS, - lock_id, - table_lock_mode, - lock_owner))) { - LOG_WARN("lock obj failed", K(ret), K(ctx), K(LOCK_SERVICE_LS), K(lock_id), K(ctx.task_type_), - K(lock_mode)); + } else if (is_part_table_lock_(ctx.task_type_) + && OB_FAIL(get_table_lock_mode_(ctx.task_type_, orig_lock_mode, ctx.lock_mode_))) { + LOG_WARN("get table lock mode failed", K(ret), K(ctx)); + } else if (OB_FAIL(process_obj_lock_(ctx, LOCK_SERVICE_LS, lock_id))) { + LOG_WARN("lock obj failed", K(ret), K(ctx), K(LOCK_SERVICE_LS), K(lock_id)); } - LOG_DEBUG("ObTableLockService::process_table_lock_", K(ret), K(ctx), K(ctx.task_type_), K(lock_mode), K(lock_owner)); + // no matter it's success or not, set lock_mode back + ctx.lock_mode_ = orig_lock_mode; + + LOG_DEBUG("ObTableLockService::process_table_lock_", K(ret), K(ctx)); return ret; } int ObTableLockService::process_table_tablet_lock_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, const LockMap &lock_map, const ObLSLockMap &ls_lock_map) { @@ -2529,9 +2177,7 @@ int ObTableLockService::process_table_tablet_lock_(ObTableLockCtx &ctx, LOG_WARN("failed to start sub tx", K(ret), K(ctx)); } else if (OB_FAIL(inner_process_obj_lock_(ctx, lock_map, - ls_lock_map, - lock_mode, - lock_owner))) { + ls_lock_map))) { LOG_WARN("fail to lock tablets", K(ret)); // rollback the sub tx. need_retry = need_retry_single_task_(ctx, ret); @@ -2544,8 +2190,7 @@ int ObTableLockService::process_table_tablet_lock_(ObTableLockCtx &ctx, LOG_WARN("failed to end sub tx", K(ret), K(ctx)); } } while (need_retry && OB_SUCC(ret)); - LOG_DEBUG("ObTableLockService::process_table_tablet_lock_", K(ret), K(ctx), - K(ctx.task_type_), K(lock_mode), K(lock_owner)); + LOG_DEBUG("ObTableLockService::process_table_tablet_lock_", K(ret), K(ctx)); return ret; } @@ -2606,7 +2251,8 @@ int ObTableLockService::get_tablet_ls_( int ret = OB_SUCCESS; bool unused_cache_hit; const uint64_t tenant_id = MTL_ID(); - if (LOCK_ALONE_TABLET == ctx.task_type_ || UNLOCK_ALONE_TABLET == ctx.task_type_) { + if (LOCK_ALONE_TABLET == ctx.task_type_ || UNLOCK_ALONE_TABLET == ctx.task_type_ + || REPLACE_LOCK_ALONE_TABLET == ctx.task_type_) { // we have specified the ls, just do lock and unlock at the specified ls ls_id = ctx.ls_id_; } else if (force_refresh) { @@ -2618,9 +2264,7 @@ int ObTableLockService::get_tablet_ls_( LOG_WARN("failed to sync get ls by tablet failed.", K(ret), K(tenant_id), K(tablet_id)); } - } else if (OB_FAIL(location_service_->nonblock_get(tenant_id, - tablet_id, - ls_id))) { + } else if (OB_FAIL(location_service_->nonblock_get(tenant_id, tablet_id, ls_id))) { if (OB_MAPPING_BETWEEN_TABLET_AND_LS_NOT_EXIST == ret && OB_FAIL(location_service_->get(tenant_id, tablet_id, @@ -2639,8 +2283,7 @@ int ObTableLockService::get_tablet_ls_( return ret; } -int ObTableLockService::get_process_tablets_(const ObTableLockMode lock_mode, - const ObSimpleTableSchemaV2 *table_schema, +int ObTableLockService::get_process_tablets_(const ObSimpleTableSchemaV2 *table_schema, ObTableLockCtx &ctx) { int ret = OB_SUCCESS; @@ -2653,7 +2296,7 @@ int ObTableLockService::get_process_tablets_(const ObTableLockMode lock_mode, // } } else { ctx.tablet_list_.reuse(); - if (LOCK_PARTITION == ctx.task_type_ || UNLOCK_PARTITION == ctx.task_type_) { + if (LOCK_PARTITION == ctx.task_type_ || UNLOCK_PARTITION == ctx.task_type_ || REPLACE_LOCK_PARTITION == ctx.task_type_) { // case 2: lock/unlock partition // get all the tablet of this partition. ObObjectID part_id(ctx.partition_id_); @@ -2661,7 +2304,7 @@ int ObTableLockService::get_process_tablets_(const ObTableLockMode lock_mode, ctx.tablet_list_))) { LOG_WARN("failed to get tablet ids", K(ret), K(part_id)); } - } else if (LOCK_SUBPARTITION == ctx.task_type_ || UNLOCK_SUBPARTITION == ctx.task_type_) { + } else if (LOCK_SUBPARTITION == ctx.task_type_ || UNLOCK_SUBPARTITION == ctx.task_type_ || REPLACE_LOCK_SUBPARTITION == ctx.task_type_) { // case 3: lock/unlock subpartition // get the tablet of subpartition ObObjectID part_id(ctx.partition_id_); @@ -2672,13 +2315,23 @@ int ObTableLockService::get_process_tablets_(const ObTableLockMode lock_mode, } else if (OB_FAIL(ctx.tablet_list_.push_back(tablet_id))) { LOG_WARN("failed to push back tablet id", K(ret)); } - } else if ((LOCK_TABLE == ctx.task_type_ || UNLOCK_TABLE == ctx.task_type_) && - (SHARE == lock_mode || SHARE_ROW_EXCLUSIVE == lock_mode || EXCLUSIVE == lock_mode)) { + } else if ((LOCK_TABLE == ctx.task_type_ || UNLOCK_TABLE == ctx.task_type_) + && is_need_lock_tablet_mode(ctx.lock_mode_)) { // case 4: lock/unlock table // get all the tablet of this table. if (OB_FAIL(table_schema->get_tablet_ids(ctx.tablet_list_))) { LOG_WARN("failed to get tablet ids", K(ret)); } + } else if (REPLACE_LOCK_TABLE == ctx.task_type_) { + // case 5: replace lock table + const ObReplaceTableLockCtx &replace_ctx = static_cast(ctx); + // should check both the original lock_mode and the target lock_mode + if (is_need_lock_tablet_mode(replace_ctx.lock_mode_) || is_need_lock_tablet_mode(replace_ctx.new_lock_mode_)) { + // get all the tablet of this table. + if (OB_FAIL(table_schema->get_tablet_ids(ctx.tablet_list_))) { + LOG_WARN("failed to get tablet ids", K(ret)); + } + } } else { // do nothing } @@ -3103,7 +2756,6 @@ int ObTableLockService::end_stmt_(ObTableLockCtx &ctx, const bool is_rollback) return ret; } - } // tablelock } // transaction } // oceanbase diff --git a/src/storage/tablelock/ob_table_lock_service.h b/src/storage/tablelock/ob_table_lock_service.h index 8a324a4f7..1e136c95e 100644 --- a/src/storage/tablelock/ob_table_lock_service.h +++ b/src/storage/tablelock/ob_table_lock_service.h @@ -56,24 +56,10 @@ private: class ObTableLockCtx { public: - ObTableLockCtx(const ObTableLockTaskType task_type, - const int64_t origin_timeout_us, - const int64_t timeout_us); - ObTableLockCtx(const ObTableLockTaskType task_type, - const uint64_t table_id, - const int64_t origin_timeout_us, - const int64_t timeout_us); - ObTableLockCtx(const ObTableLockTaskType task_type, - const uint64_t table_id, - const uint64_t partition_id_, - const int64_t origin_timeout_us, - const int64_t timeout_us); - ObTableLockCtx(const ObTableLockTaskType task_type, - const uint64_t table_id, - const share::ObLSID &ls_id, - const int64_t origin_timeout_us, - const int64_t timeout_us); + ObTableLockCtx(); ~ObTableLockCtx() {} + int set_by_lock_req(const ObLockRequest &arg, const bool is_replace_task = false); + int set_by_lock_req_common_part(const ObLockRequest &arg); int set_tablet_id(const common::ObIArray &tablet_ids); int set_tablet_id(const common::ObTabletID &tablet_id); int set_lock_id(const common::ObIArray &lock_ids); @@ -94,22 +80,10 @@ private: bool is_stmt_savepoint_valid() { return stmt_savepoint_.is_valid(); } void reset_stmt_savepoint() { stmt_savepoint_.reset(); } ObTableLockOpType get_lock_op_type() const { return lock_op_type_; } - bool is_unlock_task() const - { - return (UNLOCK_TABLE == task_type_ || - UNLOCK_PARTITION == task_type_ || - UNLOCK_SUBPARTITION == task_type_ || - UNLOCK_TABLET == task_type_ || - UNLOCK_OBJECT == task_type_ || - UNLOCK_ALONE_TABLET == task_type_); - } - bool is_tablet_lock_task() const - { - return (LOCK_TABLET == task_type_ || - UNLOCK_TABLET == task_type_ || - LOCK_ALONE_TABLET == task_type_ || - UNLOCK_ALONE_TABLET == task_type_); - } + bool is_unlock_task() const { return tablelock::is_unlock_task(task_type_); } + bool is_replace_task() const { return tablelock::is_replace_lock_task(task_type_); } + bool is_tablet_lock_task() const { return tablelock::is_tablet_lock_task(task_type_); } + public: ObTableLockTaskType task_type_; // current lock request type bool is_in_trans_; @@ -135,6 +109,10 @@ private: // the current_savepoint_ created. common::ObTabletIDArray tablet_list_; // all the tablets need to be locked/unlocked ObLockIDArray obj_list_; + + ObTableLockMode lock_mode_; + ObTableLockOwnerID lock_owner_; + // TODO: yanyuan.cxf we need better performance. // share::ObLSArray ls_list_; // related ls list int64_t schema_version_; // the schema version of the table to be locked @@ -145,14 +123,29 @@ private: // use to kill the whole lock table stmt. transaction::ObTxSEQ stmt_savepoint_; - TO_STRING_KV(K(is_in_trans_), K(table_id_), K(partition_id_), + TO_STRING_KV(K(task_type_), K(is_in_trans_), K(table_id_), K(partition_id_), K(tablet_list_), K(obj_list_), K(lock_op_type_), K(origin_timeout_us_), K(timeout_us_), K(abs_timeout_ts_), KPC(tx_desc_), K(tx_param_), K(current_savepoint_), K(need_rollback_ls_), + K(lock_mode_), K(lock_owner_), K(schema_version_), K(tx_is_killed_), K(is_from_sql_), K(ret_code_before_end_stmt_or_tx_), K(stmt_savepoint_)); }; + + class ObReplaceTableLockCtx : public ObTableLockCtx + { + public: + ObReplaceTableLockCtx() : ObTableLockCtx(), new_lock_mode_(NO_LOCK), new_lock_owner_() {} + ~ObReplaceTableLockCtx() {} + int get_lock_param(const ObLockID &lock_id, ObReplaceLockParam &lock_param) const; + INHERIT_TO_STRING_KV("ObTableLockCtx", ObTableLockCtx, K_(new_lock_mode), K_(new_lock_owner)); + + public: + ObTableLockMode new_lock_mode_; + ObTableLockOwnerID new_lock_owner_; + }; + class ObRetryCtx { public: @@ -262,75 +255,22 @@ public: const int64_t timeout_us = 0); // ---------------------------- interface for IN_TRANS/OUT_TRANS lock ------------------------------/ - // arg.op_type_ specified the behavior after trans commit or abort: - // lock will be unlocked if it is IN_TRANS_COMMON_LOCK, - // lock will be left if it is OUT_TRANS_LOCK and the trans is commited and we need - // another trans to unlock the lock. - // lock the table level lock and all the tablet level lock of this table. - int lock_table(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockTableRequest &arg); - // arg.op_type_ should be OUT_TRANS_UNLOCK: - // unlock the table level lock and all the tablet level lock of this table. - int unlock_table(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockTableRequest &arg); - // arg.op_type_ specified the behavior after trans commit or abort: - // lock will be unlocked if it is IN_TRANS_COMMON_LOCK, - // lock will be left if it is OUT_TRANS_LOCK and the trans is commited and we need - // another trans to unlock the lock. - // lock the tablet level lock and all RX or RS at table level lock. - int lock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockTabletRequest &arg); - int lock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockTabletsRequest &arg); - // arg.op_type_ should be OUT_TRANS_UNLOCK: - // unlock the table level lock and the tablet level lock. - int unlock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockTabletRequest &arg); - int unlock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockTabletsRequest &arg); - int lock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockAloneTabletRequest &arg); - // arg.op_type_ should be OUT_TRANS_UNLOCK: - // unlock the table level lock and the tablet level lock. - int unlock_tablet(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockAloneTabletRequest &arg); int lock_partition_or_subpartition(ObTxDesc &tx_desc, const ObTxParam &tx_param, - const ObLockPartitionRequest &arg); - int lock_partition(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockPartitionRequest &arg); - int unlock_partition(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockPartitionRequest &arg); - int lock_subpartition(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockPartitionRequest &arg); - int unlock_subpartition(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockPartitionRequest &arg); - int lock_obj(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockObjRequest &arg); - int unlock_obj(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockObjRequest &arg); - int lock_obj(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObLockObjsRequest &arg); - int unlock_obj(ObTxDesc &tx_desc, - const ObTxParam &tx_param, - const ObUnLockObjsRequest &arg); + ObLockPartitionRequest &arg); + int lock(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObLockRequest &arg); + int unlock(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObUnLockRequest &arg); + // NOTICE: has the same restrictions as the lock interface mentioned above. + int replace_lock(ObTxDesc &tx_desc, + const ObTxParam &tx_param, + const ObReplaceLockRequest &replace_req); int garbage_collect_right_now(); int get_obj_lock_garbage_collector(ObOBJLockGarbageCollector *&obj_lock_garbage_collector); + private: int check_cluster_version_after_(const uint64_t version); int check_data_version_after_(const uint64_t version); @@ -346,18 +286,10 @@ private: bool is_lock_conflict_ret_code_(const int ret) const; bool is_timeout_ret_code_(const int ret) const; bool is_can_retry_err_(const int ret) const; - int process_lock_task_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); - int process_obj_lock_task_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); - int process_table_lock_task_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + int process_lock_task_(ObTableLockCtx &ctx); + int process_obj_lock_task_(ObTableLockCtx &ctx); + int process_table_lock_task_(ObTableLockCtx &ctx); int process_tablet_lock_task_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, const ObSimpleTableSchemaV2 *table_schema); int start_tx_(ObTableLockCtx &ctx); int end_tx_(ObTableLockCtx &ctx, const bool is_rollback); @@ -368,8 +300,7 @@ private: int check_op_allowed_(const uint64_t table_id, const ObSimpleTableSchemaV2 *table_schema, bool &is_allowed); - int get_process_tablets_(const ObTableLockMode lock_mode, - const ObSimpleTableSchemaV2 *table_schema, + int get_process_tablets_(const ObSimpleTableSchemaV2 *table_schema, ObTableLockCtx &ctx); int get_ls_lock_map_(ObTableLockCtx &ctx, const common::ObTabletIDArray &tablets, @@ -398,38 +329,33 @@ private: ObAddr &addr); int pack_request_(ObTableLockCtx &ctx, const ObTableLockTaskType task_type, - const ObTableLockMode &lock_mode, - const ObTableLockOwnerID &lock_owner, const ObLockID &lock_id, const share::ObLSID &ls_id, ObAddr &addr, ObTableLockTaskRequest &request); int pack_batch_request_(ObTableLockCtx &ctx, const ObTableLockTaskType task_type, - const ObTableLockMode &lock_mode, - const ObTableLockOwnerID &lock_owner, const share::ObLSID &ls_id, const ObLockIDArray &lock_ids, - ObLockTaskBatchRequest &request); + ObLockTaskBatchRequest &request); + int pack_batch_request_(ObTableLockCtx &ctx, + const ObTableLockTaskType task_type, + const share::ObLSID &ls_id, + const ObLockIDArray &lock_ids, + ObLockTaskBatchRequest &request); template int parallel_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, const LockMap &lock_map, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + const ObLSLockMap &ls_lock_map); template int batch_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, - const ObLSLockMap &lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + const ObLSLockMap &lock_map); template int batch_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, bool &can_retry, ObLSLockMap &retry_ls_lock_map); template @@ -441,48 +367,49 @@ private: template int parallel_batch_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, - const ObTableLockTaskType lock_task_type, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + const ObLSLockMap &ls_lock_map); template int parallel_batch_rpc_handle_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, - const ObTableLockTaskType lock_task_type, const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, bool &can_retry, ObLSLockMap &retry_ls_lock_map); template int parallel_send_rpc_task_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, - const ObTableLockTaskType lock_task_type, const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, ObRetryCtx &retry_ctx); template int send_one_rpc_task_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, const share::ObLSID &ls_id, const ObLockIDArray &lock_ids, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, ObRetryCtx &retry_ctx); template int send_rpc_task_(RpcProxy &proxy_batch, ObTableLockCtx &ctx, const share::ObLSID &ls_id, const ObLockIDArray &lock_ids, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, ObRetryCtx &retry_ctx); template int rpc_call_(RpcProxy &proxy_batch, const ObAddr &addr, const int64_t timeout_us, const LockRequest &request); + template + int pack_and_call_rpc_(RpcProxy &proxy_batch, + ObTableLockCtx &ctx, + const share::ObLSID &ls_id, + const ObLockIDArray &lock_ids, + const ObAddr &addr, + ObRetryCtx &retry_ctx); + template<> + int pack_and_call_rpc_(obrpc::ObBatchReplaceLockProxy &proxy_batch, + ObTableLockCtx &ctx, + const share::ObLSID &ls_id, + const ObLockIDArray &lock_ids, + const ObAddr &addr, + ObRetryCtx &retry_ctx); int get_retry_lock_ids_(const ObLockIDArray &lock_ids, const int64_t start_pos, ObLockIDArray &retry_lock_ids); @@ -500,57 +427,34 @@ private: ObTableLockCtx &ctx); int inner_process_obj_lock_(ObTableLockCtx &ctx, const LockMap &lock_map, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + const ObLSLockMap &ls_lock_map); int inner_process_obj_lock_old_version_(ObTableLockCtx &ctx, const LockMap &lock_map, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + const ObLSLockMap &ls_lock_map); int inner_process_obj_lock_batch_(ObTableLockCtx &ctx, - const ObLSLockMap &ls_lock_map, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + const ObLSLockMap &ls_lock_map); int process_obj_lock_(ObTableLockCtx &ctx, const share::ObLSID &ls_id, - const ObLockID &lock_id, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + const ObLockID &lock_id); int process_obj_lock_(ObTableLockCtx &ctx, const share::ObLSID &ls_id, - const common::ObIArray &lock_ids, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); + const common::ObIArray &lock_ids); static bool is_part_table_lock_(const ObTableLockTaskType task_type); int get_table_lock_mode_(const ObTableLockTaskType task_type, const ObTableLockMode part_lock_mode, ObTableLockMode &table_lock_mode); - int process_table_lock_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner); - int process_table_tablet_lock_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, - const LockMap &lock_map, - const ObLSLockMap &ls_lock_map); + int process_table_lock_(ObTableLockCtx &ctx); + int process_table_tablet_lock_(ObTableLockCtx &ctx, const LockMap &lock_map, const ObLSLockMap &ls_lock_map); // only useful in LOCK_TABLE/LOCK_PARTITION int pre_check_lock_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, const ObLSLockMap &ls_lock_map); int batch_pre_check_lock_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, const ObLSLockMap &ls_lock_map); int pre_check_lock_old_version_(ObTableLockCtx &ctx, - const ObTableLockMode lock_mode, - const ObTableLockOwnerID lock_owner, const ObLSLockMap &ls_lock_map); // used by deadlock detector. int deal_with_deadlock_(ObTableLockCtx &ctx); int get_table_partition_level_(const ObTableID table_id, ObPartitionLevel &part_level); - DISALLOW_COPY_AND_ASSIGN(ObTableLockService); private: // TODO: yanyuan.cxf use parallel rpc and modify this to 5s. diff --git a/src/storage/tablet/ob_i_tablet_mds_interface.cpp b/src/storage/tablet/ob_i_tablet_mds_interface.cpp index 1dd906bb4..7f1dcc129 100644 --- a/src/storage/tablet/ob_i_tablet_mds_interface.cpp +++ b/src/storage/tablet/ob_i_tablet_mds_interface.cpp @@ -219,6 +219,87 @@ int ObITabletMdsInterface::get_autoinc_seq( #undef PRINT_WRAPPER } +int ObITabletMdsInterface::get_split_data( + ObTabletSplitMdsUserData &data, + const int64_t timeout) const +{ + #define PRINT_WRAPPER KR(ret), K(data), K(timeout) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GET(WARN, "not inited"); + } else { + // TODO(lihongqin.lhq): use get_latest_committed and block during 2pc + const share::SCN snapshot = share::SCN::max_scn(); + const ObTabletMeta &tablet_meta = get_tablet_meta_(); + const bool has_transfer_table = tablet_meta.has_transfer_table(); + ObITabletMdsInterface *src = nullptr; + ObTabletHandle src_tablet_handle; + if (has_transfer_table) { + const share::ObLSID &src_ls_id = tablet_meta.transfer_info_.ls_id_; + const common::ObTabletID &tablet_id = tablet_meta.tablet_id_; + if (CLICK_FAIL(get_tablet_handle_and_base_ptr(src_ls_id, tablet_id, src_tablet_handle, src))) { + MDS_LOG(WARN, "fail to get src tablet handle", K(ret), K(src_ls_id), K(tablet_id)); + } + } + + if (OB_FAIL(ret)) { + } else if (CLICK_FAIL((cross_ls_get_snapshot(src, mds::DummyKey(), + ReadSplitDataOp(data), snapshot, timeout)))) { + if (OB_EMPTY_RESULT != ret) { + MDS_LOG_GET(WARN, "fail to cross ls get snapshot", K(lbt())); + } else { + data.reset(); // use default value + ret = OB_SUCCESS; + } + } + } + + return ret; + #undef PRINT_WRAPPER +} + +int ObITabletMdsInterface::split_partkey_compare(const blocksstable::ObDatumRowkey &rowkey, + const ObITableReadInfo &rowkey_read_info, + const ObIArray &partkey_projector, + int &cmp_ret, + const int64_t timeout) const +{ + #define PRINT_WRAPPER KR(ret), K(rowkey), K(rowkey_read_info) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GET(WARN, "not inited"); + } else { + // TODO(lihongqin.lhq): use get_latest_committed and block during 2pc + const share::SCN snapshot = share::SCN::max_scn(); + const ObTabletMeta &tablet_meta = get_tablet_meta_(); + const bool has_transfer_table = tablet_meta.has_transfer_table(); + ObITabletMdsInterface *src = nullptr; + ObTabletHandle src_tablet_handle; + if (has_transfer_table) { + const share::ObLSID &src_ls_id = tablet_meta.transfer_info_.ls_id_; + const common::ObTabletID &tablet_id = tablet_meta.tablet_id_; + if (CLICK_FAIL(get_tablet_handle_and_base_ptr(src_ls_id, tablet_id, src_tablet_handle, src))) { + MDS_LOG(WARN, "fail to get src tablet handle", K(ret), K(src_ls_id), K(tablet_id)); + } + } + + if (OB_FAIL(ret)) { + } else if (CLICK_FAIL((cross_ls_get_snapshot(src, mds::DummyKey(), + ReadSplitDataPartkeyCompareOp(rowkey, rowkey_read_info, partkey_projector, cmp_ret), snapshot, timeout)))) { + if (OB_EMPTY_RESULT != ret) { + MDS_LOG_GET(WARN, "fail to cross ls get snapshot", K(ret), K(lbt())); + } + } + } + + return ret; + #undef PRINT_WRAPPER +} + int ObITabletMdsInterface::read_raw_data( common::ObIAllocator &allocator, const uint8_t mds_unit_id, diff --git a/src/storage/tablet/ob_i_tablet_mds_interface.h b/src/storage/tablet/ob_i_tablet_mds_interface.h index c946c7d85..b50014641 100644 --- a/src/storage/tablet/ob_i_tablet_mds_interface.h +++ b/src/storage/tablet/ob_i_tablet_mds_interface.h @@ -63,6 +63,15 @@ public: const share::SCN &snapshot, share::ObTabletAutoincSeq &data, const int64_t timeout = ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US) const; + template + int get_latest_split_data(OP &&op, bool &is_committed) const; + int get_split_data(ObTabletSplitMdsUserData &data, + const int64_t timeout) const; + int split_partkey_compare(const blocksstable::ObDatumRowkey &rowkey, + const ObITableReadInfo &rowkey_read_info, + const ObIArray &partkey_projector, + int &cmp_ret, + const int64_t timeout) const; int fill_virtual_info(ObIArray &mds_node_info_array) const; TO_STRING_KV(KP(this), "is_inited", check_is_inited_(), "ls_id", get_tablet_meta_().ls_id_, "tablet_id", get_tablet_id_(), KP(get_tablet_pointer_())); @@ -215,6 +224,34 @@ struct ReadAutoIncSeqOp share::ObTabletAutoincSeq &auto_inc_seq_; }; +struct ReadSplitDataOp +{ + ReadSplitDataOp(ObTabletSplitMdsUserData &split_data) : split_data_(split_data) {} + int operator()(const ObTabletSplitMdsUserData &data) + { + return split_data_.assign(data); + } + ObTabletSplitMdsUserData &split_data_; +}; + +struct ReadSplitDataPartkeyCompareOp +{ + ReadSplitDataPartkeyCompareOp(const blocksstable::ObDatumRowkey &rowkey, + const ObITableReadInfo &rowkey_read_info, + const ObIArray &partkey_projector, + int &cmp_ret) + : rowkey_(rowkey), rowkey_read_info_(rowkey_read_info), partkey_projector_(partkey_projector), + cmp_ret_(cmp_ret) {} + int operator()(const ObTabletSplitMdsUserData &data) + { + return data.partkey_compare(rowkey_, rowkey_read_info_, partkey_projector_, cmp_ret_); + } + const blocksstable::ObDatumRowkey &rowkey_; + const ObITableReadInfo &rowkey_read_info_; + const ObIArray &partkey_projector_; + int &cmp_ret_; +}; + template <> int ObITabletMdsInterface::mds_range_query( ObTableScanParam &scan_param, diff --git a/src/storage/tablet/ob_i_tablet_mds_interface.ipp b/src/storage/tablet/ob_i_tablet_mds_interface.ipp index d096120b0..17c6e9cc4 100644 --- a/src/storage/tablet/ob_i_tablet_mds_interface.ipp +++ b/src/storage/tablet/ob_i_tablet_mds_interface.ipp @@ -670,6 +670,8 @@ inline int ObITabletMdsInterface::fill_virtual_info(ObIArray(mds_node_info_array))) { MDS_LOG_GET(WARN, "fail to fill aux_tablet_info_"); + } else if (CLICK_FAIL(fill_virtual_info_from_mds_sstable(mds_node_info_array))) { + MDS_LOG_GET(WARN, "fail to fill tablet_split_data_"); } else { MDS_LOG_GET(TRACE, "sucess to fill virtual info"); } @@ -803,5 +805,38 @@ inline int ObITabletMdsInterface::check_transfer_in_redo_written(bool &written) #undef PRINT_WRAPPER } +template +int ObITabletMdsInterface::get_latest_split_data(OP &&op, bool &is_committed) const +{ + #define PRINT_WRAPPER KR(ret) + MDS_TG(10_ms); + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!check_is_inited_())) { + ret = OB_NOT_INIT; + MDS_LOG_GET(WARN, "not inited"); + } else { + const ObTabletMeta &tablet_meta = get_tablet_meta_(); + const bool has_transfer_table = tablet_meta.has_transfer_table(); + ObITabletMdsInterface *src = nullptr; + ObTabletHandle src_tablet_handle; + if (has_transfer_table) { + const share::ObLSID &src_ls_id = tablet_meta.transfer_info_.ls_id_; + const common::ObTabletID &tablet_id = tablet_meta.tablet_id_; + if (CLICK_FAIL(get_tablet_handle_and_base_ptr(src_ls_id, tablet_id, src_tablet_handle, src))) { + MDS_LOG(WARN, "fail to get src tablet handle", K(ret), K(src_ls_id), K(tablet_id)); + } + } + + if (OB_FAIL(ret)) { + } else if (CLICK_FAIL((cross_ls_get_latest(src, op, is_committed)))) { + if (OB_EMPTY_RESULT != ret) { + MDS_LOG_GET(WARN, "fail to cross ls get latest", K(lbt())); + } + } + } + return ret; + #undef PRINT_WRAPPER +} + +} } -} \ No newline at end of file diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index 791c3d9df..3077a062b 100644 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -71,6 +71,7 @@ #include "storage/tablet/ob_tablet_mds_node_dump_operator.h" #include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" #include "storage/tablet/ob_tablet_binding_mds_user_data.h" +#include "storage/tablet/ob_tablet_split_mds_user_data.h" #include "storage/tx/ob_trans_part_ctx.h" #include "storage/tx/ob_trans_service.h" #include "storage/tx_storage/ob_ls_service.h" @@ -262,7 +263,7 @@ ObTablet::ObTablet(const bool is_external_tablet) is_external_tablet_(is_external_tablet) { #if defined(__x86_64__) && !defined(ENABLE_OBJ_LEAK_CHECK) - check_size(); + check_size(); #endif MEMSET(memtables_, 0x0, sizeof(memtables_)); } @@ -336,6 +337,7 @@ int ObTablet::init_for_first_time_creation( const int64_t snapshot_version, const ObCreateTabletSchema &create_tablet_schema, const bool need_create_empty_major_sstable, + const share::SCN &clog_checkpoint_scn, const bool micro_index_clustered, const bool need_generate_cs_replica_cg_array, const bool has_cs_replica, @@ -372,7 +374,7 @@ int ObTablet::init_for_first_time_creation( LOG_WARN("failed to init shared params", K(ret), K(ls_id), K(tablet_id), K(compat_mode), KP(freezer)); } else if (OB_FAIL(tablet_meta_.init(ls_id, tablet_id, data_tablet_id, create_scn, snapshot_version, compat_mode, table_store_flag, create_tablet_schema.get_schema_version()/*create_schema_version*/, - micro_index_clustered, has_cs_replica))) { + clog_checkpoint_scn, micro_index_clustered, has_cs_replica))) { LOG_WARN("failed to init tablet meta", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), K(create_scn), K(snapshot_version), K(compat_mode), K(table_store_flag)); } else if (OB_FAIL(pull_memtables(allocator))) { @@ -492,7 +494,7 @@ int ObTablet::init_for_merge( LOG_WARN("failed to init table store cache", K(ret), KPC(this)); } else if (OB_FAIL(try_update_start_scn())) { LOG_WARN("failed to update start scn", K(ret), K(param), K(table_store_addr_)); - } else if (OB_FAIL(try_update_table_store_flag(param))) { + } else if (OB_FAIL(try_update_table_store_flag(param.get_update_with_major_flag()))) { LOG_WARN("failed to update table store flag", K(ret), K(param), K(table_store_addr_)); } else { int64_t finish_medium_scn = 0; @@ -593,6 +595,7 @@ int ObTablet::init_for_shared_merge( old_tablet.tablet_meta_.compat_mode_, old_tablet.tablet_meta_.table_store_flag_, old_tablet.tablet_meta_.create_schema_version_, + SCN::invalid_scn()/*clog_checkpoint_scn*/, old_tablet.tablet_meta_.micro_index_clustered_, false /*has_cs_replica*/))) { LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet), K(param)); @@ -615,7 +618,7 @@ int ObTablet::init_for_shared_merge( LOG_WARN("failed to init table store cache", K(ret), KPC(this)); } else if (OB_FAIL(try_update_start_scn())) { LOG_WARN("failed to update start scn", K(ret), K(param), K(table_store_addr_)); - } else if (OB_FAIL(try_update_table_store_flag(param))) { + } else if (OB_FAIL(try_update_table_store_flag(param.get_update_with_major_flag()))) { LOG_WARN("failed to update table store flag", K(ret), K(param), K(table_store_addr_)); } else if (OB_FAIL(build_read_info(allocator))) { LOG_WARN("failed to build read info", K(ret)); @@ -898,6 +901,8 @@ int ObTablet::init_for_sstable_replace( ObStorageSchema *old_storage_schema = nullptr; const ObStorageSchema *storage_schema = nullptr; int64_t finish_medium_scn = 0; + int64_t max_sync_schema_version = 0; + const bool is_tablet_split = param.tablet_split_param_.is_valid(); if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -916,7 +921,14 @@ int ObTablet::init_for_sstable_replace( } else if (OB_FAIL(old_table_store_wrapper.get_member(old_table_store))) { LOG_WARN("failed to get old table store", K(ret)); } else if (FALSE_IT(storage_schema = OB_ISNULL(param.tablet_meta_) ? old_storage_schema : ¶m.tablet_meta_->storage_schema_)) { - } else if (OB_FAIL(tablet_meta_.init(old_tablet.tablet_meta_, param.tablet_meta_ + } else if (OB_FAIL(old_tablet.get_max_sync_storage_schema_version(max_sync_schema_version))) { + LOG_WARN("failed to get max sync storage schema version", K(ret)); + } else if (is_tablet_split && OB_FAIL(tablet_meta_.init(old_tablet.tablet_meta_, + param.tablet_split_param_.snapshot_version_, param.tablet_split_param_.multi_version_start_, + max_sync_schema_version))) { + // init split tablet meta. + LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet), K(param), K(max_sync_schema_version)); + } else if (!is_tablet_split && OB_FAIL(tablet_meta_.init(old_tablet.tablet_meta_, param.tablet_meta_ // this interface for migration to batch update table store // use max schema to make sure sstable and schema match ))) { @@ -925,11 +937,15 @@ int ObTablet::init_for_sstable_replace( LOG_WARN("fail to pull memtable", K(ret)); } else if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { LOG_WARN("fail to alloc and new table store object", K(ret), K_(table_store_addr)); - } else if (OB_FAIL(table_store_addr_.ptr_->build_ha_new_table_store(allocator, *this, param, *old_table_store))) { + } else if (is_tablet_split && OB_FAIL(table_store_addr_.ptr_->build_split_new_table_store(allocator, *this, param, *old_table_store))) { + LOG_WARN("failed to init split tablet table store", K(ret), K(old_tablet)); + } else if (!is_tablet_split && OB_FAIL(table_store_addr_.ptr_->build_ha_new_table_store(allocator, *this, param, *old_table_store))) { LOG_WARN("failed to init table store", K(ret), K(old_tablet)); } else if (OB_FAIL(ObStorageSchemaUtil::update_tablet_storage_schema( tablet_meta_.tablet_id_, *allocator_, *old_storage_schema, *storage_schema, storage_schema_addr_.ptr_))) { LOG_WARN("failed to choose and save storage schema", K(ret), K(old_tablet), K(param)); + } else if (is_tablet_split && OB_FAIL(try_update_table_store_flag(param.tablet_split_param_.update_with_major_tables_))) { + LOG_WARN("failed to update table store flag", K(ret), K(param), K(table_store_addr_)); } else if (OB_FAIL(try_update_start_scn())) { LOG_WARN("failed to update start scn", K(ret), K(param), K(table_store_addr_)); } else if (OB_FAIL(check_tablet_schema_mismatch(old_tablet, *storage_schema, false/*is_convert_co_major_merge*/))) { @@ -941,7 +957,7 @@ int ObTablet::init_for_sstable_replace( } else if (FALSE_IT(finish_medium_scn = get_last_major_snapshot_version())) { } else if (nullptr != param.tablet_meta_ && FALSE_IT(tablet_meta_.update_extra_medium_info( old_tablet.tablet_meta_.extra_medium_info_, param.tablet_meta_->extra_medium_info_, finish_medium_scn))) { - } else if (!is_ls_inner_tablet() && !param.is_transfer_replace_ && OB_FAIL(update_tablet_status_from_sstable(false/*expect_persist_status*/))) { + } else if (!is_ls_inner_tablet() && !param.is_transfer_replace_ && !is_tablet_split && OB_FAIL(update_tablet_status_from_sstable(false/*expect_persist_status*/))) { LOG_WARN("fail to update tablet status from sstable", K(ret)); } else if (OB_FAIL(build_read_info(*allocator_))) { LOG_WARN("failed to build read info", K(ret)); @@ -1692,8 +1708,7 @@ int ObTablet::init_empty_shell( LOG_WARN("old tablet should not have next tablet", K(ret), K(old_tablet.get_tablet_meta())); } else if (OB_FAIL(old_tablet.ObITabletMdsInterface::get_tablet_status(share::SCN::max_scn(), user_data))) { LOG_WARN("old tablet get ObTabletCreateDeleteMdsUserData failed", K(ret), K(old_tablet)); - } else if (user_data.tablet_status_ != ObTabletStatus::DELETED && - user_data.tablet_status_ != ObTabletStatus::TRANSFER_OUT_DELETED) { + } else if (OB_UNLIKELY(!user_data.tablet_status_.is_deleted_for_gc())) { ret = OB_STATE_NOT_MATCH; LOG_WARN("old tablet status is not deleted", K(ret), K(user_data.tablet_status_)); } else if (OB_FAIL(tablet_meta_.assign(old_tablet.tablet_meta_))) { @@ -3902,7 +3917,9 @@ int ObTablet::check_row_locked_by_myself( int ObTablet::get_read_tables( const int64_t snapshot_version, ObTabletTableIterator &iter, - const bool allow_no_ready_read) + const bool allow_no_ready_read, + const bool need_split_src_table, + const bool need_split_dst_table) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { @@ -3913,7 +3930,12 @@ int ObTablet::get_read_tables( } else if (OB_UNLIKELY(!iter.is_valid() || iter.get_tablet() != this)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(iter), K(this)); - } else if (OB_FAIL(auto_get_read_tables(snapshot_version, iter, allow_no_ready_read))) { + } else if (OB_FAIL(auto_get_read_tables( + snapshot_version, + iter, + allow_no_ready_read, + need_split_src_table, + need_split_dst_table))) { LOG_WARN("failed to get read tables", K(ret), K(snapshot_version), K(allow_no_ready_read)); } @@ -3937,6 +3959,7 @@ int ObTablet::get_src_tablet_read_tables_( ObTabletCreateDeleteMdsUserData user_data; ObLSTabletService *tablet_service = nullptr; SCN max_decided_scn; + const ObGetReadTablesMode mode = allow_no_ready_read ? ObGetReadTablesMode::ALLOW_NO_READY_READ : ObGetReadTablesMode::NORMAL; if (OB_UNLIKELY(snapshot_version < 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid argument", K(ret), K(snapshot_version)); @@ -3994,7 +4017,7 @@ int ObTablet::get_src_tablet_read_tables_( snapshot_version, iter.table_store_iter_, *(iter.table_store_iter_.transfer_src_table_store_handle_), - allow_no_ready_read))) { + mode))) { LOG_WARN("failed to get read tables from table store", K(ret), KPC(tablet)); } else { succ_get_src_tables = true; @@ -4007,13 +4030,16 @@ int ObTablet::get_src_tablet_read_tables_( int ObTablet::auto_get_read_tables( const int64_t snapshot_version, ObTabletTableIterator &iter, - const bool allow_no_ready_read) + const bool allow_no_ready_read, + const bool need_split_src_table, + const bool need_split_dst_table) { int ret = OB_SUCCESS; const share::ObLSID &ls_id = tablet_meta_.ls_id_; const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; iter.table_store_iter_.reset(); bool succ_get_src_tables = false; + bool succ_get_split_src_tables = false; if (OB_UNLIKELY(tablet_meta_.has_transfer_table())) { if (OB_FAIL(get_src_tablet_read_tables_(snapshot_version, allow_no_ready_read, iter, succ_get_src_tables))) { @@ -4024,14 +4050,30 @@ int ObTablet::auto_get_read_tables( FLOG_INFO("get read tables during transfer",K(ret), K(ls_id), K(tablet_id), K(snapshot_version), "has_transfer_table", tablet_meta_.has_transfer_table(), K(iter.table_store_iter_.table_ptr_array_)); +#endif + } + } else if (need_split_src_table) { // auto split query + if (OB_FAIL(get_split_src_read_table_if_need(snapshot_version, iter, succ_get_split_src_tables))) { + LOG_WARN("fail to get src read table.", K(ret), K(*this)); + } else { +#ifdef ENABLE_DEBUG_LOG + FLOG_INFO("get read tables during tablet splitting",K(ret), K(ls_id), K(tablet_id), + K(snapshot_version), K(iter.table_store_iter_.table_ptr_array_), K(succ_get_split_src_tables)); #endif } } if (OB_FAIL(ret)) { } else { bool allow_not_ready = succ_get_src_tables ? true : allow_no_ready_read; - if (OB_FAIL(get_read_tables_(snapshot_version, iter.table_store_iter_, iter.table_store_iter_.table_store_handle_, allow_not_ready))) { - LOG_WARN("failed to get read tables from table store", K(ret), K(ls_id), K(tablet_id)); + allow_not_ready = succ_get_split_src_tables ? true : allow_not_ready; + const ObGetReadTablesMode mode = allow_not_ready ? ObGetReadTablesMode::ALLOW_NO_READY_READ : ObGetReadTablesMode::NORMAL; + if (OB_FAIL(get_read_tables_(snapshot_version, iter.table_store_iter_, iter.table_store_iter_.table_store_handle_, mode))) { + LOG_WARN("failed to get read tables from table store", K(ret), K(ls_id), K(tablet_id), K(succ_get_src_tables)); + } + } + if (OB_SUCC(ret) && !succ_get_split_src_tables && need_split_dst_table) { + if (OB_FAIL(get_split_dst_read_table(snapshot_version, iter))) { + LOG_WARN("failed to get split dst read table", K(ret)); } } return ret; @@ -4041,7 +4083,7 @@ int ObTablet::get_read_tables_( const int64_t snapshot_version, ObTableStoreIterator &iter, ObStorageMetaHandle &table_store_handle, - const bool allow_no_ready_read) + const ObGetReadTablesMode mode) { int ret = OB_SUCCESS; const ObTabletTableStore *table_store = nullptr; @@ -4064,7 +4106,7 @@ int ObTablet::get_read_tables_( } if (OB_SUCC(ret)) { if (OB_FAIL(table_store->get_read_tables( - snapshot_version, *this, iter, allow_no_ready_read))) { + snapshot_version, *this, iter, mode))) { LOG_WARN("fail to get read tables", K(ret), K(iter), K(snapshot_version)); } } @@ -4073,7 +4115,8 @@ int ObTablet::get_read_tables_( int ObTablet::get_read_major_sstable( const int64_t &major_snapshot_version, - ObTabletTableIterator &iter) + ObTabletTableIterator &iter, + const bool need_split_src_table) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!is_inited_)) { @@ -4084,8 +4127,163 @@ int ObTablet::get_read_major_sstable( } else if (OB_UNLIKELY(!iter.is_valid() || iter.get_tablet() != this)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid argument", K(ret), K(iter), K(this)); - } else if (OB_FAIL(get_read_major_sstable(major_snapshot_version, *iter.table_iter()))) { - LOG_WARN("failed to get read tables", K(ret), K(major_snapshot_version)); + } + if (OB_SUCC(ret) && need_split_src_table) { + if (OB_FAIL(get_split_src_major_table_if_need(major_snapshot_version, iter))) { + LOG_WARN("fail to get split src major table", K(ret), K(*this)); + } + } + if (OB_SUCC(ret)) { + if (OB_FAIL(get_read_major_sstable(major_snapshot_version, *iter.table_iter()))) { + LOG_WARN("failed to get read tables", K(ret), K(major_snapshot_version)); + } + } + return ret; +} + +int ObTablet::get_split_src_read_table_if_need( + const int64_t snapshot_version, + ObTabletTableIterator &iter, + bool &succ_get_split_src_tables) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!tablet_meta_.table_store_flag_.with_major_sstable())) { + ObTabletSplitMdsUserData data; + const int64_t timeout = ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S; + if (OB_FAIL(ObITabletMdsInterface::get_split_data(data, timeout))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (data.is_split_dst()) { + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObTabletHandle src_tablet_handle; + ObTablet *src_tablet = nullptr; + if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(tablet_meta_.ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(tablet_meta_.ls_id_)); + } else if (OB_FAIL(data.get_split_src_tablet(*ls_handle.get_ls(), src_tablet_handle))) { + LOG_WARN("failed to get split src tablet", K(ret)); + } else if (OB_ISNULL(src_tablet = src_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet handle obj is nullptr", K(ret)); + } else if (OB_FAIL(iter.add_split_extra_tablet_handle(src_tablet_handle))) { + LOG_WARN("fail to set split src tabelt handle", K(ret)); + } else if (OB_FAIL(src_tablet->get_read_tables_( + snapshot_version, + iter.table_store_iter_, + iter.table_store_iter_.table_store_handle_, + ObGetReadTablesMode::NORMAL))) { + LOG_WARN("failed to get read tables from table store", K(ret), KPC(src_tablet)); + } else { + succ_get_split_src_tables = true; + } + LOG_INFO("is split dst", K(ret), "tablet_id", tablet_meta_.tablet_id_, K(data)); + } + } + return ret; +} + +int ObTablet::get_split_dst_read_table( + const int64_t snapshot_version, + ObTabletTableIterator &iter) +{ + int ret = OB_SUCCESS; + bool maybe_split_src = true; + { + SpinRLockGuard guard(mds_cache_lock_); + if (tablet_status_cache_.is_valid()) { + if (tablet_status_cache_.get_tablet_status().is_writable_for_dml()) { + maybe_split_src = false; + } + } + } + + if (OB_UNLIKELY(maybe_split_src)) { + ObTabletSplitMdsUserData data; + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + const int64_t timeout = ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S; + if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(tablet_meta_.ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(tablet_meta_.ls_id_)); + } else if (OB_FAIL(ObITabletMdsInterface::get_split_data(data, timeout))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (data.is_split_src()) { + ObArray dst_tablet_ids; + ObTabletHandle dst_tablet_handle; + if (OB_FAIL(data.get_split_dst_tablet_ids(dst_tablet_ids))) { + LOG_WARN("failed to get split dst tablet ids", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < dst_tablet_ids.count(); ++i) { + const ObTabletID &dst_tablet_id = dst_tablet_ids.at(i); + ObTablet *dst_tablet = nullptr; + if (OB_FAIL(ls_handle.get_ls()->get_tablet(dst_tablet_ids.at(i), dst_tablet_handle, timeout, + ObMDSGetTabletMode::READ_READABLE_COMMITED))) { + LOG_WARN("failed to get tablet", K(ret), K(dst_tablet_ids.at(i)), K(tablet_meta_.ls_id_)); + } else if (OB_FAIL(iter.add_split_extra_tablet_handle(dst_tablet_handle))) { + LOG_WARN("fail to set split src tablet handle", K(ret)); + } else if (OB_FALSE_IT(dst_tablet = dst_tablet_handle.get_obj())) { + } else if (dst_tablet->get_tablet_meta().table_store_flag_.with_major_sstable()) { + ObTabletCreateDeleteMdsUserData user_data; + if (get_last_major_snapshot_version() != dst_tablet->get_last_major_snapshot_version()) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("dst lastest major not same as src", K(ret), K(tablet_meta_.tablet_id_), K(dst_tablet_id), + K(get_last_major_snapshot_version()), K(dst_tablet->get_last_major_snapshot_version())); + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(dst_tablet_handle.get_obj()->get_read_tables_( + snapshot_version, + iter.table_store_iter_, + iter.table_store_iter_.table_store_handle_, + ObGetReadTablesMode::SKIP_MAJOR))) { + LOG_WARN("failed to get read tables from table store", K(ret), K(dst_tablet_ids.at(i))); + } + } + LOG_INFO("is split src", K(ret), "tablet_id", tablet_meta_.tablet_id_, K(data)); + } + } + return ret; +} + +int ObTablet::get_split_src_major_table_if_need( + const int64_t &major_snapshot_version, + ObTabletTableIterator &iter) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(!tablet_meta_.table_store_flag_.with_major_sstable())) { + ObTabletSplitMdsUserData data; + const int64_t timeout = ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S; + if (OB_FAIL(ObITabletMdsInterface::get_split_data(data, timeout))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (data.is_split_dst()) { + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + ObTabletHandle src_tablet_handle; + ObTablet *src_tablet = nullptr; + if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(tablet_meta_.ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(tablet_meta_.ls_id_)); + } else if (OB_FAIL(data.get_split_src_tablet(*ls_handle.get_ls(), src_tablet_handle))) { + LOG_WARN("failed to get split src tablet", K(ret)); + } else if (OB_ISNULL(src_tablet = src_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet handle obj is nullptr", K(ret)); + } else if (OB_FAIL(iter.add_split_extra_tablet_handle(src_tablet_handle))) { + LOG_WARN("fail to set split src tabelt handle", K(ret)); + } else if (OB_FAIL(src_tablet->get_read_major_sstable( + major_snapshot_version, + iter.table_store_iter_))) { + LOG_WARN("failed to get read major sstables from table store", K(ret), KPC(src_tablet)); + } + LOG_INFO("is split dst", K(ret), "tablet_id", tablet_meta_.tablet_id_, K(data)); + } } return ret; } @@ -4402,7 +4600,7 @@ int ObTablet::do_rowkey_exists( } else if (OB_FAIL(allow_to_read_())) { LOG_WARN("not allowed to read", K(ret), K(tablet_meta_)); } else if (OB_FAIL(auto_get_read_tables( - context.store_ctx_->mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), table_iter, context.query_flag_.index_invalid_))) { + context.store_ctx_->mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), table_iter, context.query_flag_.index_invalid_, true/*need_split_src_table*/, false/*need_split_dst_table*/))) { LOG_WARN("get read iterator fail", K(ret)); } else { bool found = false; @@ -4582,7 +4780,9 @@ int ObTablet::rowkeys_exists( if (OB_FAIL(relative_table.tablet_iter_.get_tablet()->auto_get_read_tables( store_ctx.mvcc_acc_ctx_.get_snapshot_version().get_val_for_tx(), tables_iter, - relative_table.allow_not_ready()))) { + relative_table.allow_not_ready(), + true/*need_split_src_table*/, + false/*need_split_dst_table*/))) { LOG_WARN("get read iterator fail", K(ret)); } else if (OB_FAIL(relative_table.tablet_iter_.get_tablet()->do_rowkeys_exist( tables_iter.table_store_iter_, rows_info, exists))) { @@ -5195,10 +5395,10 @@ int ObTablet::try_update_start_scn() return ret; } -int ObTablet::try_update_table_store_flag(const ObUpdateTableStoreParam ¶m) +int ObTablet::try_update_table_store_flag(const bool with_major) { int ret = OB_SUCCESS; - if (param.get_update_with_major_flag()) { + if (with_major) { tablet_meta_.table_store_flag_.set_with_major_sstable(); } return ret; @@ -5570,7 +5770,7 @@ int ObTablet::fetch_tablet_autoinc_seq_cache( SCN scn = SCN::min_scn(); if (OB_FAIL(autoinc_seq.set_autoinc_seq_value(allocator, result_autoinc_seq))) { LOG_WARN("failed to set autoinc seq value", K(ret), K(result_autoinc_seq)); - } else if (OB_FAIL(write_sync_tablet_seq_log(autoinc_seq, scn))) { + } else if (OB_FAIL(write_sync_tablet_seq_log(autoinc_seq, false/*is_tablet_creating*/, scn))) { LOG_WARN("fail to write sync tablet seq log", K(ret)); } else { result.start_ = interval_start; @@ -5661,6 +5861,7 @@ int ObTablet::get_kept_snapshot_info( } int ObTablet::write_sync_tablet_seq_log(ObTabletAutoincSeq &autoinc_seq, + const bool is_tablet_creating, share::SCN &scn) { int ret = OB_SUCCESS; @@ -5668,7 +5869,8 @@ int ObTablet::write_sync_tablet_seq_log(ObTabletAutoincSeq &autoinc_seq, const int64_t SYNC_TABLET_SEQ_LOG_TIMEOUT = 1000L * 1000L * 30L; // 30s const share::ObLSID &ls_id = tablet_meta_.ls_id_; const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; - const enum ObReplayBarrierType replay_barrier_type = logservice::ObReplayBarrierType::NO_NEED_BARRIER; + const enum ObReplayBarrierType replay_barrier_type = is_tablet_creating ? logservice::ObReplayBarrierType::PRE_BARRIER + : logservice::ObReplayBarrierType::NO_NEED_BARRIER; ObLogBaseHeader base_header(ObLogBaseType::TABLET_SEQ_SYNC_LOG_BASE_TYPE, replay_barrier_type); ObSyncTabletSeqLog log; // NOTICE: ObLogBaseHeader & ObSyncTabletSeqLog should have fixed serialize size! @@ -5745,7 +5947,7 @@ int ObTablet::write_sync_tablet_seq_log(ObTabletAutoincSeq &autoinc_seq, return ret; } -int ObTablet::update_tablet_autoinc_seq(const uint64_t autoinc_seq) +int ObTablet::update_tablet_autoinc_seq(const uint64_t autoinc_seq, const bool is_tablet_creating) { int ret = OB_SUCCESS; ObArenaAllocator allocator(common::ObMemAttr(MTL_ID(), "UpdAutoincSeq")); @@ -5763,7 +5965,7 @@ int ObTablet::update_tablet_autoinc_seq(const uint64_t autoinc_seq) } else if (autoinc_seq > curr_auto_inc_seqvalue) { if (OB_FAIL(curr_autoinc_seq.set_autoinc_seq_value(allocator, autoinc_seq))) { LOG_WARN("failed to set autoinc seq value", K(ret), K(autoinc_seq)); - } else if (OB_FAIL(write_sync_tablet_seq_log(curr_autoinc_seq, scn))) { + } else if (OB_FAIL(write_sync_tablet_seq_log(curr_autoinc_seq, is_tablet_creating, scn))) { LOG_WARN("fail to write sync tablet seq log", K(ret)); } } @@ -7870,12 +8072,14 @@ int ObTablet::check_schema_version_with_cache( int ObTablet::check_snapshot_readable_with_cache( const int64_t snapshot_version, const int64_t schema_version, - const int64_t timeout) + const int64_t timeout, + bool &need_split_dst_table) { int ret = OB_SUCCESS; const ObLSID &ls_id = tablet_meta_.ls_id_; const ObTabletID &tablet_id = tablet_meta_.tablet_id_; bool r_valid = false; + need_split_dst_table = true; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -7885,6 +8089,11 @@ int ObTablet::check_snapshot_readable_with_cache( } else { { SpinRLockGuard guard(mds_cache_lock_); + if (tablet_status_cache_.is_valid()) { + if (tablet_status_cache_.get_tablet_status().is_writable_for_dml()) { + need_split_dst_table = false; + } + } if (ddl_data_cache_.is_valid()) { if (OB_FAIL(check_snapshot_readable(ddl_data_cache_, snapshot_version, schema_version))) { LOG_WARN("fail to check schema version", K(ret)); diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index a1754e178..0fc436904 100644 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -53,11 +53,22 @@ namespace logservice class ObLogHandler; } +namespace memtable +{ +class ObIMultiSourceDataUnit; +} + namespace blocksstable { +class ObSSTable; struct ObSSTableMergeRes; } +namespace compaction +{ +class ObExtraMediumInfo; +} + namespace transaction { class ObTransID; @@ -182,6 +193,7 @@ public: const int64_t snapshot_version, const ObCreateTabletSchema &storage_schema, const bool need_create_empty_major_sstable, + const share::SCN &clog_checkpoint_scn, const bool micro_index_clustered, const bool need_generate_cs_replica_cg_array, const bool has_cs_replica, @@ -527,10 +539,11 @@ public: const uint64_t cache_size, share::ObTabletAutoincInterval &result); - int update_tablet_autoinc_seq(const uint64_t autoinc_seq); + int update_tablet_autoinc_seq(const uint64_t autoinc_seq, const bool is_tablet_creating); int get_kept_snapshot_info( const int64_t min_reserved_snapshot_on_ls, ObStorageSnapshotInfo &snapshot_info) const; + int get_end_autoinc_seq(uint64_t &end_autoinc_seq); int check_schema_version_elapsed( const int64_t schema_version, const bool need_wait_trans_end, @@ -557,7 +570,8 @@ public: int check_snapshot_readable_with_cache( const int64_t snapshot_version, const int64_t schema_version, - const int64_t timeout); + const int64_t timeout, + bool &need_split_dst_table); int set_tablet_status( const ObTabletCreateDeleteMdsUserData &tablet_status, mds::MdsCtx &ctx); @@ -574,16 +588,17 @@ public: const ObTabletBindingMdsUserData &ddl_info, mds::MdsCtx &ctx); - int set_frozen_for_all_memtables(); + // different from the is_valid() function // typically used for check valid for migration or restore int check_valid(const bool ignore_ha_status = false) const; int64_t to_string(char *buf, const int64_t buf_len) const; int get_max_column_cnt_on_schema_recorder(int64_t &max_column_cnt); - int get_ls_epoch(int64_t &ls_epoch); static int get_tablet_version(const char *buf, const int64_t len, int32_t &version); + int get_max_schema_version(int64_t &schema_version); + int get_ls_epoch(int64_t &ls_epoch); int get_sstable_column_checksum( const blocksstable::ObSSTable &sstable, common::ObIArray &column_checksums) const; @@ -685,8 +700,7 @@ private: const bool for_replay); int try_update_start_scn(); int try_update_ddl_checkpoint_scn(); - int try_update_table_store_flag(const ObUpdateTableStoreParam ¶m); - int get_max_schema_version(int64_t &schema_version); + int try_update_table_store_flag(const bool with_major); int inner_get_all_sstables(ObTableStoreIterator &iter, const bool need_unpack = false) const; int check_schema_version_for_bounded_staleness_read( const int64_t table_version_for_read, @@ -716,6 +730,7 @@ private: int inner_get_memtables(common::ObIArray &memtables, const bool need_active) const; int write_sync_tablet_seq_log(share::ObTabletAutoincSeq &autoinc_seq, + const bool is_tablet_creating, share::SCN &scn); int update_ddl_info( @@ -731,22 +746,38 @@ private: int get_read_tables( const int64_t snapshot_version, ObTabletTableIterator &iter, - const bool allow_no_ready_read); + const bool allow_no_ready_read, + const bool need_split_src_table, + const bool need_split_dst_table); int get_read_major_sstable( const int64_t &major_snapshot_version, - ObTabletTableIterator &iter); + ObTabletTableIterator &iter, + const bool need_split_src_table); int auto_get_read_tables( const int64_t snapshot_version, ObTabletTableIterator &iter, - const bool allow_no_ready_read); + const bool allow_no_ready_read, + const bool need_split_src_table, + const bool need_split_dst_table); int get_read_tables_( const int64_t snapshot_version, ObTableStoreIterator &iter, ObStorageMetaHandle &table_store_handle, - const bool allow_no_ready_read); + const ObGetReadTablesMode mode); int get_read_major_sstable( const int64_t &major_snapshot_version, ObTableStoreIterator &iter) const; + int get_split_src_major_table_if_need( + const int64_t &major_snapshot_version, + ObTabletTableIterator &iter); + int get_split_src_read_table_if_need( + const int64_t snapshot_version, + ObTabletTableIterator &iter, + bool &succ_get_split_src_tables); + int get_split_dst_read_table( + const int64_t snapshot_version, + ObTabletTableIterator &iter); + int allow_to_read_(); int check_medium_list() const; diff --git a/src/storage/tablet/ob_tablet_create_delete_helper.cpp b/src/storage/tablet/ob_tablet_create_delete_helper.cpp index 31da56446..066d0e322 100644 --- a/src/storage/tablet/ob_tablet_create_delete_helper.cpp +++ b/src/storage/tablet/ob_tablet_create_delete_helper.cpp @@ -231,7 +231,8 @@ int ObTabletCreateDeleteHelper::check_status_for_new_mds( const ObTabletStatus::Status &status = user_data.tablet_status_.get_status(); switch (status) { case ObTabletStatus::NORMAL: - ret = check_read_snapshot_for_normal(tablet, snapshot_version, timeout_us, user_data, is_committed); + case ObTabletStatus::SPLIT_DST: + ret = check_read_snapshot_for_normal_or_split_dst(tablet, snapshot_version, timeout_us, user_data, is_committed); break; case ObTabletStatus::DELETED: ret = check_read_snapshot_for_deleted(tablet, snapshot_version, user_data, is_committed); @@ -245,6 +246,12 @@ int ObTabletCreateDeleteHelper::check_status_for_new_mds( case ObTabletStatus::TRANSFER_OUT_DELETED: ret = check_read_snapshot_for_transfer_out_deleted(tablet, snapshot_version, user_data, is_committed); break; + case ObTabletStatus::SPLIT_SRC: + ret = check_read_snapshot_for_split_src(tablet, snapshot_version, user_data, is_committed); + break; + case ObTabletStatus::SPLIT_SRC_DELETED: + ret = check_read_snapshot_for_split_src_deleted(tablet, user_data, is_committed); + break; default: ret = OB_ERR_UNEXPECTED; LOG_WARN("unexpected tablet status", K(ret), K(ls_id), K(tablet_id), K(user_data)); @@ -298,7 +305,7 @@ int ObTabletCreateDeleteHelper::check_read_snapshot_by_commit_version( } if (OB_FAIL(ret)) { - } else if (ObTabletStatus::NORMAL == tablet_status || ObTabletStatus::TRANSFER_IN == tablet_status) { + } else if (ObTabletStatus::NORMAL == tablet_status || ObTabletStatus::TRANSFER_IN == tablet_status || ObTabletStatus::SPLIT_DST == tablet_status) { if (OB_UNLIKELY(tablet.is_empty_shell())) { ret = OB_TABLET_NOT_EXIST; LOG_WARN("tablet is empty shell", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(create_commit_version)); @@ -310,7 +317,7 @@ int ObTabletCreateDeleteHelper::check_read_snapshot_by_commit_version( return ret; } -int ObTabletCreateDeleteHelper::check_read_snapshot_for_normal( +int ObTabletCreateDeleteHelper::check_read_snapshot_for_normal_or_split_dst( ObTablet &tablet, const int64_t snapshot_version, const int64_t timeout_us, @@ -323,7 +330,7 @@ int ObTabletCreateDeleteHelper::check_read_snapshot_for_normal( const ObTabletStatus &tablet_status = user_data.tablet_status_; share::SCN read_snapshot; - if (OB_UNLIKELY(ObTabletStatus::NORMAL != tablet_status)) { + if (OB_UNLIKELY(ObTabletStatus::NORMAL != tablet_status && ObTabletStatus::SPLIT_DST != tablet_status)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(ls_id), K(tablet_id), K(user_data)); } else if (is_committed) { @@ -465,6 +472,55 @@ int ObTabletCreateDeleteHelper::check_read_snapshot_for_transfer_out_deleted( return ret; } +int ObTabletCreateDeleteHelper::check_read_snapshot_for_split_src( + ObTablet &tablet, + const int64_t snapshot_version, + const ObTabletCreateDeleteMdsUserData &user_data, + const bool is_committed) +{ + int ret = OB_SUCCESS; + const share::ObLSID &ls_id = tablet.get_tablet_meta().ls_id_; + const common::ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; + const ObTabletStatus &tablet_status = user_data.tablet_status_; + + if (OB_UNLIKELY(ObTabletStatus::SPLIT_SRC != tablet_status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(ls_id), K(tablet_id), K(user_data)); + } else if (is_committed) { + if (snapshot_version < user_data.create_commit_version_) { + ret = OB_SNAPSHOT_DISCARDED; + LOG_WARN("read snapshot smaller than create commit version", + K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(user_data)); + } else { + ret = OB_TABLET_IS_SPLIT_SRC; + LOG_WARN("tablet is split src", K(ret), K(ls_id), K(tablet_id), K(common::lbt())); + } + } + + return ret; +} + +int ObTabletCreateDeleteHelper::check_read_snapshot_for_split_src_deleted( + ObTablet &tablet, + const ObTabletCreateDeleteMdsUserData &user_data, + const bool is_committed) +{ + int ret = OB_SUCCESS; + const share::ObLSID &ls_id = tablet.get_tablet_meta().ls_id_; + const common::ObTabletID &tablet_id = tablet.get_tablet_meta().tablet_id_; + const ObTabletStatus &tablet_status = user_data.tablet_status_; + + if (OB_UNLIKELY(ObTabletStatus::SPLIT_SRC_DELETED != tablet_status)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid args", K(ret), K(ls_id), K(tablet_id), K(user_data)); + } else if (is_committed) { + ret = OB_TABLET_NOT_EXIST; + LOG_WARN("split src deleted", K(ret), K(ls_id), K(tablet_id), K(common::lbt())); + } + + return ret; +} + int ObTabletCreateDeleteHelper::create_tmp_tablet( const ObTabletMapKey &key, common::ObArenaAllocator &allocator, diff --git a/src/storage/tablet/ob_tablet_create_delete_helper.h b/src/storage/tablet/ob_tablet_create_delete_helper.h index f9621a086..1d70a5e8d 100644 --- a/src/storage/tablet/ob_tablet_create_delete_helper.h +++ b/src/storage/tablet/ob_tablet_create_delete_helper.h @@ -76,7 +76,7 @@ public: const int64_t delete_commit_version, const int64_t snapshot_version, const ObTabletStatus &tablet_status); - static int check_read_snapshot_for_normal( + static int check_read_snapshot_for_normal_or_split_dst( ObTablet &tablet, const int64_t snapshot_version, const int64_t timeout_us, @@ -102,6 +102,15 @@ public: const int64_t snapshot_version, const ObTabletCreateDeleteMdsUserData &user_data, const bool is_committed); + static int check_read_snapshot_for_split_src( + ObTablet &tablet, + const int64_t snapshot_version, + const ObTabletCreateDeleteMdsUserData &user_data, + const bool is_committed); + static int check_read_snapshot_for_split_src_deleted( + ObTablet &tablet, + const ObTabletCreateDeleteMdsUserData &user_data, + const bool is_committed); static int check_read_snapshot_by_commit_version( const int64_t snapshot_version, const ObTabletCreateDeleteMdsUserData &user_data); diff --git a/src/storage/tablet/ob_tablet_create_delete_mds_user_data.cpp b/src/storage/tablet/ob_tablet_create_delete_mds_user_data.cpp index 8ae90a47b..b6b558efd 100644 --- a/src/storage/tablet/ob_tablet_create_delete_mds_user_data.cpp +++ b/src/storage/tablet/ob_tablet_create_delete_mds_user_data.cpp @@ -36,20 +36,25 @@ ObTabletCreateDeleteMdsUserData::ObTabletCreateDeleteMdsUserData() create_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), delete_commit_scn_(share::SCN::invalid_scn()), delete_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), - transfer_out_commit_version_(ObTransVersion::INVALID_TRANS_VERSION) + transfer_out_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), + start_split_commit_version_(ObTransVersion::INVALID_TRANS_VERSION) { } -ObTabletCreateDeleteMdsUserData::ObTabletCreateDeleteMdsUserData(const ObTabletStatus::Status &status, const ObTabletMdsUserDataType type) +ObTabletCreateDeleteMdsUserData::ObTabletCreateDeleteMdsUserData( + const ObTabletStatus::Status &status, + const ObTabletMdsUserDataType &type, + const int64_t create_commit_version) : tablet_status_(status), transfer_scn_(share::SCN::invalid_scn()), transfer_ls_id_(), data_type_(type), create_commit_scn_(share::SCN::invalid_scn()), - create_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), + create_commit_version_(create_commit_version), delete_commit_scn_(share::SCN::invalid_scn()), delete_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), - transfer_out_commit_version_(ObTransVersion::INVALID_TRANS_VERSION) + transfer_out_commit_version_(ObTransVersion::INVALID_TRANS_VERSION), + start_split_commit_version_(ObTransVersion::INVALID_TRANS_VERSION) { } @@ -65,6 +70,7 @@ int ObTabletCreateDeleteMdsUserData::assign(const ObTabletCreateDeleteMdsUserDat delete_commit_scn_ = other.delete_commit_scn_; delete_commit_version_ = other.delete_commit_version_; transfer_out_commit_version_ = other.transfer_out_commit_version_; + start_split_commit_version_ = other.start_split_commit_version_; return ret; } @@ -79,6 +85,7 @@ void ObTabletCreateDeleteMdsUserData::reset() delete_commit_scn_.set_invalid(); create_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; transfer_out_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; + start_split_commit_version_ = ObTransVersion::INVALID_TRANS_VERSION; } void ObTabletCreateDeleteMdsUserData::on_init() @@ -97,7 +104,11 @@ void ObTabletCreateDeleteMdsUserData::on_redo(const share::SCN &redo_scn) case ObTabletMdsUserDataType::REMOVE_TABLET : case ObTabletMdsUserDataType::START_TRANSFER_OUT_PREPARE: case ObTabletMdsUserDataType::START_TRANSFER_IN : - case ObTabletMdsUserDataType::FINISH_TRANSFER_OUT : { + case ObTabletMdsUserDataType::FINISH_TRANSFER_OUT : + case ObTabletMdsUserDataType::START_SPLIT_SRC : + case ObTabletMdsUserDataType::START_SPLIT_DST : + case ObTabletMdsUserDataType::FINISH_SPLIT_SRC : + case ObTabletMdsUserDataType::FINISH_SPLIT_DST : { break; } case ObTabletMdsUserDataType::START_TRANSFER_OUT : { @@ -133,7 +144,8 @@ void ObTabletCreateDeleteMdsUserData::on_commit(const share::SCN &commit_version switch (data_type_) { case ObTabletMdsUserDataType::NONE : case ObTabletMdsUserDataType::START_TRANSFER_OUT_PREPARE: - case ObTabletMdsUserDataType::FINISH_TRANSFER_IN : { + case ObTabletMdsUserDataType::FINISH_TRANSFER_IN : + case ObTabletMdsUserDataType::FINISH_SPLIT_DST : { break; } case ObTabletMdsUserDataType::CREATE_TABLET : { @@ -156,6 +168,18 @@ void ObTabletCreateDeleteMdsUserData::on_commit(const share::SCN &commit_version start_transfer_out_on_commit_(commit_version); break; } + case ObTabletMdsUserDataType::START_SPLIT_SRC : { + start_split_src_on_commit_(commit_version); + break; + } + case ObTabletMdsUserDataType::START_SPLIT_DST : { + start_split_dst_on_commit_(commit_version); + break; + } + case ObTabletMdsUserDataType::FINISH_SPLIT_SRC : { + finish_split_src_on_commit_(commit_version, commit_scn); + break; + } default: { ret = OB_INVALID_ARGUMENT; LOG_ERROR("invalid cur status for fail", K(ret), KPC(this)); @@ -204,6 +228,29 @@ void ObTabletCreateDeleteMdsUserData::start_transfer_out_on_commit_( LOG_INFO("[TRANSFER] transfer out on commit", KPC(this)); } +void ObTabletCreateDeleteMdsUserData::start_split_src_on_commit_( + const share::SCN &commit_version) +{ + start_split_commit_version_ = commit_version.get_val_for_tx(); + LOG_INFO("start split src on commit", KPC(this)); +} + +void ObTabletCreateDeleteMdsUserData::start_split_dst_on_commit_( + const share::SCN &commit_version) +{ + start_split_commit_version_ = commit_version.get_val_for_tx(); + LOG_INFO("start split dst on commit", KPC(this)); +} + +void ObTabletCreateDeleteMdsUserData::finish_split_src_on_commit_( + const share::SCN &commit_version, + const share::SCN &commit_scn) +{ + delete_commit_scn_ = commit_scn; + delete_commit_version_ = commit_version.get_val_for_tx(); + LOG_INFO("split src delete tablet commit", KPC(this)); +} + int ObTabletCreateDeleteMdsUserData::set_tablet_gc_trigger( const share::ObLSID &ls_id) { @@ -251,7 +298,8 @@ OB_SERIALIZE_MEMBER( create_commit_version_, delete_commit_scn_, delete_commit_version_, - transfer_out_commit_version_ // FARM COMPAT WHITELIST + transfer_out_commit_version_, // FARM COMPAT WHITELIST + start_split_commit_version_ // FARM COMPAT WHITELIST ) } // namespace storage diff --git a/src/storage/tablet/ob_tablet_create_delete_mds_user_data.h b/src/storage/tablet/ob_tablet_create_delete_mds_user_data.h index fc05678e9..0034bc5b1 100644 --- a/src/storage/tablet/ob_tablet_create_delete_mds_user_data.h +++ b/src/storage/tablet/ob_tablet_create_delete_mds_user_data.h @@ -60,7 +60,7 @@ class ObTabletCreateDeleteMdsUserData public: ObTabletCreateDeleteMdsUserData(); ~ObTabletCreateDeleteMdsUserData() = default; - ObTabletCreateDeleteMdsUserData(const ObTabletStatus::Status &status, const ObTabletMdsUserDataType type); + ObTabletCreateDeleteMdsUserData(const ObTabletStatus::Status &status, const ObTabletMdsUserDataType &type, const int64_t create_commit_version); ObTabletCreateDeleteMdsUserData(const ObTabletCreateDeleteMdsUserData &) = delete; ObTabletCreateDeleteMdsUserData &operator=(const ObTabletCreateDeleteMdsUserData &) = delete; public: @@ -79,7 +79,8 @@ public: TO_STRING_KV(K_(tablet_status), K_(transfer_scn), K_(transfer_ls_id), K_(data_type), K_(create_commit_scn), K_(create_commit_version), - K_(delete_commit_scn), K_(delete_commit_version), K_(transfer_out_commit_version)); + K_(delete_commit_scn), K_(delete_commit_version), + K_(transfer_out_commit_version), K_(start_split_commit_version)); private: void start_transfer_out_on_redo_(const share::SCN &redo_scn); void finish_transfer_in_on_redo_(const share::SCN &redo_scn); @@ -89,6 +90,10 @@ private: void delete_tablet_on_commit_(const share::SCN &commit_version, const share::SCN &commit_scn); void finish_transfer_out_on_commit_(const share::SCN &commit_version, const share::SCN &commit_scn); void start_transfer_out_on_commit_(const share::SCN &commit_version); + + void start_split_src_on_commit_(const share::SCN &commit_version); + void start_split_dst_on_commit_(const share::SCN &commit_version); + void finish_split_src_on_commit_(const share::SCN &commit_version, const share::SCN &commit_scn); public: ObTabletStatus tablet_status_; share::SCN transfer_scn_; @@ -101,6 +106,7 @@ public: share::SCN delete_commit_scn_; // delete tx commit log scn int64_t delete_commit_version_; // delete tx commit trans version int64_t transfer_out_commit_version_; //transfer out commit trans version + int64_t start_split_commit_version_; // start split commit trans version TODO(lihongqin.lhq): master占位 }; inline bool ObTabletCreateDeleteMdsUserData::is_valid() const diff --git a/src/storage/tablet/ob_tablet_create_mds_helper.cpp b/src/storage/tablet/ob_tablet_create_mds_helper.cpp index d2d2d15d8..58e58ac8f 100644 --- a/src/storage/tablet/ob_tablet_create_mds_helper.cpp +++ b/src/storage/tablet/ob_tablet_create_mds_helper.cpp @@ -35,6 +35,7 @@ using namespace oceanbase::common; using namespace oceanbase::share; using namespace oceanbase::obrpc; +using namespace oceanbase::transaction; namespace oceanbase { @@ -668,10 +669,13 @@ int ObTabletCreateMdsHelper::build_pure_data_tablet( const ObLSID &ls_id = arg.id_; const ObTabletID &data_tablet_id = info.data_tablet_id_; const ObCreateTabletSchema *create_tablet_schema = nullptr; + const int64_t create_commit_version = info.create_commit_versions_.empty() ? ObTransVersion::INVALID_TRANS_VERSION + : info.create_commit_versions_.at(0); const ObSArray &create_tablet_schemas = arg.create_tablet_schemas_; const ObSArray &create_tablet_extra_infos = arg.tablet_extra_infos_; const lib::Worker::CompatMode &compat_mode = info.compat_mode_; const int64_t snapshot_version = arg.major_frozen_scn_.get_val_for_tx(); + const share::SCN &clog_checkpoint_scn = arg.clog_checkpoint_scn_; const bool has_cs_replica = info.has_cs_replica_; ObTabletHandle tablet_handle; bool exist = false; @@ -715,12 +719,13 @@ int ObTabletCreateMdsHelper::build_pure_data_tablet( LOG_WARN("check and get create tablet schema_info failed", K(ret)); } else if (CLICK_FAIL(ls->get_tablet_svr()->create_tablet(ls_id, data_tablet_id, data_tablet_id, scn, snapshot_version, *create_tablet_schema, compat_mode, - need_create_empty_major_sstable, micro_index_clustered, has_cs_replica, tablet_handle))) { + need_create_empty_major_sstable, clog_checkpoint_scn, micro_index_clustered, has_cs_replica, tablet_handle))) { LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(data_tablet_id), "arg", PRETTY_ARG(arg)); } if (OB_FAIL(ret)) { - } else if (CLICK_FAIL(set_tablet_normal_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx, arg.is_old_mds_))) { + } else if (CLICK_FAIL(set_tablet_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx, + arg.is_old_mds_, arg.create_type_, create_commit_version))) { LOG_WARN("failed to set tablet normal status", K(ret), K(ls_id), K(data_tablet_id)); } @@ -740,10 +745,12 @@ int ObTabletCreateMdsHelper::build_mixed_tablets( const ObLSID &ls_id = arg.id_; const ObTabletID &data_tablet_id = info.data_tablet_id_; const ObSArray &tablet_ids = info.tablet_ids_; + const ObIArray &create_commit_versions = info.create_commit_versions_; const ObSArray &create_tablet_schemas = arg.create_tablet_schemas_; const lib::Worker::CompatMode &compat_mode = info.compat_mode_; const ObSArray &create_tablet_extra_infos = arg.tablet_extra_infos_; const int64_t snapshot_version = arg.major_frozen_scn_.get_val_for_tx(); + const share::SCN &clog_checkpoint_scn = arg.clog_checkpoint_scn_; const bool has_cs_replica = info.has_cs_replica_; ObTabletHandle data_tablet_handle; ObTabletHandle tablet_handle; @@ -764,6 +771,8 @@ int ObTabletCreateMdsHelper::build_mixed_tablets( MDS_TG(5_ms); exist = false; const ObTabletID &tablet_id = tablet_ids[i]; + const int64_t create_commit_version = i < create_commit_versions.count() ? create_commit_versions.at(i) + : ObTransVersion::INVALID_TRANS_VERSION; const ObCreateTabletSchema *create_tablet_schema = nullptr; bool need_create_empty_major_sstable = true; bool micro_index_clustered = false; @@ -799,12 +808,13 @@ int ObTabletCreateMdsHelper::build_mixed_tablets( LOG_WARN("failed to push back tablet id", K(ret), K(ls_id), K(tablet_id)); } else if (CLICK_FAIL(ls->get_tablet_svr()->create_tablet(ls_id, tablet_id, data_tablet_id, scn, snapshot_version, *create_tablet_schema, compat_mode, - need_create_empty_major_sstable, micro_index_clustered, has_cs_replica, tablet_handle))) { + need_create_empty_major_sstable, clog_checkpoint_scn, micro_index_clustered, has_cs_replica, tablet_handle))) { LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), "arg", PRETTY_ARG(arg)); } if (OB_FAIL(ret)) { - } else if (CLICK_FAIL(set_tablet_normal_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx, arg.is_old_mds_))) { + } else if (CLICK_FAIL(set_tablet_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx, + arg.is_old_mds_, arg.create_type_, create_commit_version))) { LOG_WARN("failed to set tablet normal status", K(ret), K(ls_id), K(tablet_id)); } @@ -842,10 +852,12 @@ int ObTabletCreateMdsHelper::build_pure_aux_tablets( const ObLSID &ls_id = arg.id_; const ObTabletID &data_tablet_id = info.data_tablet_id_; const ObSArray &tablet_ids = info.tablet_ids_; + const ObIArray &create_commit_versions = info.create_commit_versions_; const ObSArray &create_tablet_schemas = arg.create_tablet_schemas_; const lib::Worker::CompatMode &compat_mode = info.compat_mode_; const ObSArray &create_tablet_extra_infos = arg.tablet_extra_infos_; const int64_t snapshot_version = arg.major_frozen_scn_.get_val_for_tx(); + const share::SCN &clog_checkpoint_scn = arg.clog_checkpoint_scn_; const bool has_cs_replica = info.has_cs_replica_; ObTabletHandle tablet_handle; bool exist = false; @@ -863,6 +875,8 @@ int ObTabletCreateMdsHelper::build_pure_aux_tablets( MDS_TG(5_ms); exist = false; const ObTabletID &tablet_id = tablet_ids[i]; + const int64_t create_commit_version = i < create_commit_versions.count() ? create_commit_versions.at(i) + : ObTransVersion::INVALID_TRANS_VERSION; const ObCreateTabletSchema *create_tablet_schema = nullptr; bool need_create_empty_major_sstable = true; bool micro_index_clustered = false; @@ -891,12 +905,13 @@ int ObTabletCreateMdsHelper::build_pure_aux_tablets( LOG_WARN("check and get create tablet schema_info failed", K(ret)); } else if (CLICK_FAIL(ls->get_tablet_svr()->create_tablet(ls_id, tablet_id, data_tablet_id, scn, snapshot_version, *create_tablet_schema, compat_mode, - need_create_empty_major_sstable, micro_index_clustered, has_cs_replica, tablet_handle))) { + need_create_empty_major_sstable, clog_checkpoint_scn, micro_index_clustered, has_cs_replica, tablet_handle))) { LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), "arg", PRETTY_ARG(arg)); } if (OB_FAIL(ret)) { - } else if (CLICK_FAIL(set_tablet_normal_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx, arg.is_old_mds_))) { + } else if (CLICK_FAIL(set_tablet_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx, + arg.is_old_mds_, arg.create_type_, create_commit_version))) { LOG_WARN("failed to set tablet normal status", K(ret), K(ls_id), K(tablet_id)); } } @@ -919,10 +934,12 @@ int ObTabletCreateMdsHelper::build_bind_hidden_tablets( const ObLSID &ls_id = arg.id_; const ObTabletID &orig_tablet_id = info.data_tablet_id_; const ObSArray &tablet_ids = info.tablet_ids_; + const ObIArray &create_commit_versions = info.create_commit_versions_; const ObSArray &create_tablet_schemas = arg.create_tablet_schemas_; const lib::Worker::CompatMode &compat_mode = info.compat_mode_; const ObSArray &create_tablet_extra_infos = arg.tablet_extra_infos_; const int64_t snapshot_version = arg.major_frozen_scn_.get_val_for_tx(); + const share::SCN &clog_checkpoint_scn = arg.clog_checkpoint_scn_; const bool has_cs_replica = info.has_cs_replica_; ObTabletHandle tablet_handle; int64_t aux_info_idx = -1; @@ -945,6 +962,8 @@ int ObTabletCreateMdsHelper::build_bind_hidden_tablets( lob_meta_tablet_id.reset(); lob_piece_tablet_id.reset(); const ObTabletID &tablet_id = tablet_ids[i]; + const int64_t create_commit_version = i < create_commit_versions.count() ? create_commit_versions.at(i) + : ObTransVersion::INVALID_TRANS_VERSION; const ObCreateTabletSchema *create_tablet_schema = nullptr; bool has_related_aux_info = find_aux_info_for_hidden_tablets(arg, tablet_id, aux_info_idx); bool need_create_empty_major_sstable = true; @@ -991,12 +1010,13 @@ int ObTabletCreateMdsHelper::build_bind_hidden_tablets( LOG_WARN("failed to push back tablet id", K(ret), K(ls_id), K(tablet_id)); } else if (CLICK_FAIL(ls->get_tablet_svr()->create_tablet(ls_id, tablet_id, tablet_id, scn, snapshot_version, *create_tablet_schema, compat_mode, - need_create_empty_major_sstable, micro_index_clustered, has_cs_replica, tablet_handle))) { + need_create_empty_major_sstable, clog_checkpoint_scn, micro_index_clustered, has_cs_replica, tablet_handle))) { LOG_WARN("failed to do create tablet", K(ret), K(ls_id), K(tablet_id), K(orig_tablet_id), "arg", PRETTY_ARG(arg)); } if (OB_FAIL(ret)) { - } else if (CLICK_FAIL(set_tablet_normal_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx, arg.is_old_mds_))) { + } else if (CLICK_FAIL(set_tablet_status(ls->get_tablet_svr(), tablet_handle, for_replay, scn, ctx, + arg.is_old_mds_, arg.create_type_, create_commit_version))) { LOG_WARN("failed to set tablet normal status", K(ret), K(ls_id), K(tablet_id)); } @@ -1049,19 +1069,22 @@ int ObTabletCreateMdsHelper::get_ls( return ret; } -int ObTabletCreateMdsHelper::set_tablet_normal_status( +int ObTabletCreateMdsHelper::set_tablet_status( ObLSTabletService *ls_tablet_service, ObTabletHandle &tablet_handle, const bool for_replay, const share::SCN &scn, mds::BufferCtx &ctx, - const bool for_old_mds) + const bool for_old_mds, + const ObTabletMdsUserDataType &data_type, + const int64_t create_commit_version) { MDS_TG(5_ms); int ret = OB_SUCCESS; + const ObTabletStatus status(data_type == ObTabletMdsUserDataType::START_SPLIT_DST ? ObTabletStatus::SPLIT_DST : ObTabletStatus::NORMAL); ObTablet *tablet = tablet_handle.get_obj(); mds::MdsCtx &user_ctx = static_cast(ctx); - ObTabletCreateDeleteMdsUserData data(ObTabletStatus::NORMAL, ObTabletMdsUserDataType::CREATE_TABLET); + const ObTabletCreateDeleteMdsUserData data(status, data_type, create_commit_version); if (OB_ISNULL(tablet)) { ret = OB_ERR_UNEXPECTED; @@ -1076,7 +1099,7 @@ int ObTabletCreateMdsHelper::set_tablet_normal_status( ObTabletCreateReplayExecutor replay_executor; const share::ObLSID &ls_id = tablet->get_tablet_meta().ls_id_; const common::ObTabletID &tablet_id = tablet->get_tablet_meta().tablet_id_; - if (CLICK_FAIL(replay_executor.init(ctx, scn, for_old_mds))) { + if (CLICK_FAIL(replay_executor.init(ctx, scn, for_old_mds, data))) { LOG_WARN("failed to init replay executor", K(ret)); } else if (CLICK_FAIL(replay_executor.execute(scn, ls_id, tablet_id))) { LOG_WARN("failed to replay mds data", K(ret)); diff --git a/src/storage/tablet/ob_tablet_create_mds_helper.h b/src/storage/tablet/ob_tablet_create_mds_helper.h index 71107facc..c9a3b002c 100644 --- a/src/storage/tablet/ob_tablet_create_mds_helper.h +++ b/src/storage/tablet/ob_tablet_create_mds_helper.h @@ -17,6 +17,7 @@ #include "lib/worker.h" #include "lib/container/ob_iarray.h" #include "storage/tx/ob_trans_define.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" #include "storage/ob_storage_schema.h" namespace oceanbase @@ -157,13 +158,15 @@ private: static int get_ls( const share::ObLSID &ls_id, ObLSHandle &ls_handle); - static int set_tablet_normal_status( + static int set_tablet_status( ObLSTabletService *ls_tablet_service, ObTabletHandle &tablet_handle, const bool for_replay, const share::SCN &scn, mds::BufferCtx &ctx, - const bool for_old_mds); + const bool for_old_mds, + const storage::ObTabletMdsUserDataType &create_type, + const int64_t create_commit_version); static void handle_ret_for_replay(int &ret); static int convert_schemas(obrpc::ObBatchCreateTabletArg &arg); static int check_and_get_create_tablet_schema_info( diff --git a/src/storage/tablet/ob_tablet_create_replay_executor.cpp b/src/storage/tablet/ob_tablet_create_replay_executor.cpp index bf1619b39..c62505ecb 100644 --- a/src/storage/tablet/ob_tablet_create_replay_executor.cpp +++ b/src/storage/tablet/ob_tablet_create_replay_executor.cpp @@ -25,14 +25,15 @@ namespace storage { ObTabletCreateReplayExecutor::ObTabletCreateReplayExecutor() : logservice::ObTabletReplayExecutor(), - user_ctx_(nullptr) + user_ctx_(nullptr), user_data_(nullptr) { } int ObTabletCreateReplayExecutor::init( mds::BufferCtx &user_ctx, const share::SCN &scn, - const bool for_old_mds) + const bool for_old_mds, + const ObTabletCreateDeleteMdsUserData &user_data) { int ret = OB_SUCCESS; if (OB_UNLIKELY(is_inited_)) { @@ -46,6 +47,7 @@ int ObTabletCreateReplayExecutor::init( scn_ = scn; is_inited_ = true; for_old_mds_ = for_old_mds; + user_data_ = &user_data; } return ret; } @@ -54,13 +56,12 @@ int ObTabletCreateReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) { int ret = OB_SUCCESS; mds::MdsCtx &user_ctx = static_cast(*user_ctx_); - ObTabletCreateDeleteMdsUserData user_data(ObTabletStatus::NORMAL, ObTabletMdsUserDataType::CREATE_TABLET); - if (OB_FAIL(replay_to_mds_table_(tablet_handle, user_data, user_ctx, scn_, for_old_mds_))) { + if (OB_FAIL(replay_to_mds_table_(tablet_handle, *user_data_, user_ctx, scn_, for_old_mds_))) { LOG_WARN("failed to replay to tablet", K(ret)); } return ret; } } // namespace storage -} // namespace oceanbase \ No newline at end of file +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_create_replay_executor.h b/src/storage/tablet/ob_tablet_create_replay_executor.h index cfa8b86de..8a89e8033 100644 --- a/src/storage/tablet/ob_tablet_create_replay_executor.h +++ b/src/storage/tablet/ob_tablet_create_replay_executor.h @@ -33,7 +33,8 @@ public: int init( mds::BufferCtx &user_ctx, const share::SCN &scn, - const bool for_old_mds); + const bool for_old_mds, + const ObTabletCreateDeleteMdsUserData &user_data); protected: bool is_replay_update_tablet_status_() const override @@ -52,6 +53,7 @@ private: mds::BufferCtx *user_ctx_; share::SCN scn_; bool for_old_mds_; + const ObTabletCreateDeleteMdsUserData *user_data_; }; } // namespace storage } // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_create_sstable_param.h b/src/storage/tablet/ob_tablet_create_sstable_param.h index 0a6ced384..1806db9ee 100644 --- a/src/storage/tablet/ob_tablet_create_sstable_param.h +++ b/src/storage/tablet/ob_tablet_create_sstable_param.h @@ -89,6 +89,7 @@ public: // Without checking the validity of the input parameters, necessary to ensure the correctness of the method call. // This is used to create remote sstable int init_for_remote(const blocksstable::ObMigrationSSTableParam &migration_param); + int init_for_mds(const compaction::ObBasicTabletMergeCtx &ctx, const blocksstable::ObSSTableMergeRes &res, const ObStorageSchema &mds_schema); diff --git a/src/storage/tablet/ob_tablet_iterator.cpp b/src/storage/tablet/ob_tablet_iterator.cpp index 50cea55ce..c1c2bdeec 100644 --- a/src/storage/tablet/ob_tablet_iterator.cpp +++ b/src/storage/tablet/ob_tablet_iterator.cpp @@ -187,7 +187,7 @@ int ObHALSTabletIDIterator::sort_tablet_ids_if_need() ret = OB_ERR_UNEXPECTED; LOG_WARN("get next tablet id before sort", K(ret), K_(idx)); } else { - std::sort(tablet_ids_.begin(), tablet_ids_.end()); + lib::ob_sort(tablet_ids_.begin(), tablet_ids_.end()); LOG_INFO("sort tablet ids if need"); } return ret; diff --git a/src/storage/tablet/ob_tablet_mds_data.cpp b/src/storage/tablet/ob_tablet_mds_data.cpp index f71f4fdad..bcd75f356 100644 --- a/src/storage/tablet/ob_tablet_mds_data.cpp +++ b/src/storage/tablet/ob_tablet_mds_data.cpp @@ -19,6 +19,7 @@ #include "storage/compaction/ob_medium_compaction_mgr.h" #include "storage/compaction/ob_medium_list_checker.h" #include "storage/compaction/ob_extra_medium_info.h" +#include "storage/tablet/ob_tablet_binding_info.h" #include "storage/tablet/ob_tablet_full_memory_mds_data.h" #include "storage/tablet/ob_tablet_obj_load_helper.h" #include "storage/tablet/ob_i_tablet_mds_interface.h" diff --git a/src/storage/tablet/ob_tablet_mds_table_mini_merger.cpp b/src/storage/tablet/ob_tablet_mds_table_mini_merger.cpp index 025f8fd81..a7e4773b3 100644 --- a/src/storage/tablet/ob_tablet_mds_table_mini_merger.cpp +++ b/src/storage/tablet/ob_tablet_mds_table_mini_merger.cpp @@ -417,6 +417,7 @@ int ObMdsTableMiniMerger::generate_mds_mini_sstable( ObTableHandleV2 &table_handle) { int ret = OB_SUCCESS; + TIMEGUARD_INIT(STORAGE, 20_ms); if (OB_UNLIKELY(!is_inited_)) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -428,9 +429,9 @@ int ObMdsTableMiniMerger::generate_mds_mini_sstable( STORAGE_LOG(WARN, "Failed to add macro blocks", K(ret)); } else if (OB_FAIL(sstable_builder_.close(res))) { LOG_WARN("fail to close sstable builder", K(ret), K(sstable_builder_)); - } else if (OB_FAIL(param.init_for_mds(*ctx_, res, *storage_schema_))) { + } else if (CLICK_FAIL(param.init_for_mds(*ctx_, res, *storage_schema_))) { LOG_WARN("fail to create sstable param for mds", K(ret)); - } else if (OB_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, allocator, table_handle))) { + } else if (CLICK_FAIL(ObTabletCreateDeleteHelper::create_sstable(param, allocator, table_handle))) { LOG_WARN("fail to create sstable", K(ret), K(param)); CTX_SET_DIAGNOSE_LOCATION(*ctx_); } else { diff --git a/src/storage/tablet/ob_tablet_meta.cpp b/src/storage/tablet/ob_tablet_meta.cpp index 0b7cd836a..03c513209 100644 --- a/src/storage/tablet/ob_tablet_meta.cpp +++ b/src/storage/tablet/ob_tablet_meta.cpp @@ -87,6 +87,7 @@ int ObTabletMeta::init( const lib::Worker::CompatMode compat_mode, const ObTabletTableStoreFlag &table_store_flag, const int64_t create_schema_version, + const share::SCN &clog_checkpoint_scn, const bool micro_index_clustered, const bool has_cs_replica) { @@ -103,7 +104,7 @@ int ObTabletMeta::init( || OB_UNLIKELY(lib::Worker::CompatMode::INVALID == compat_mode)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(ls_id), K(tablet_id), K(data_tablet_id), - K(create_scn), K(snapshot_version), K(compat_mode)); + K(create_scn), K(snapshot_version), K(clog_checkpoint_scn), K(compat_mode)); } else if (OB_FAIL(ha_status_.init_status())) { LOG_WARN("failed to init ha status", K(ret)); } else if (OB_FAIL(transfer_info_.init())) { @@ -117,7 +118,7 @@ int ObTabletMeta::init( create_schema_version_ = create_schema_version; micro_index_clustered_ = micro_index_clustered; start_scn_ = INIT_CLOG_CHECKPOINT_SCN; - clog_checkpoint_scn_ = INIT_CLOG_CHECKPOINT_SCN; + clog_checkpoint_scn_ = clog_checkpoint_scn.is_valid() ? clog_checkpoint_scn : INIT_CLOG_CHECKPOINT_SCN; ddl_checkpoint_scn_ = INIT_CLOG_CHECKPOINT_SCN; compat_mode_ = compat_mode; snapshot_version_ = snapshot_version; @@ -1048,7 +1049,7 @@ ObMigrationTabletParam::ObMigrationTabletParam() storage_schema_(), medium_info_list_(), extra_medium_info_(), - last_persisted_committed_tablet_status_(ObTabletStatus::MAX, ObTabletMdsUserDataType::MAX_TYPE), + last_persisted_committed_tablet_status_(ObTabletStatus::MAX, ObTabletMdsUserDataType::MAX_TYPE, ObTransVersion::INVALID_TRANS_VERSION), table_store_flag_(), ddl_start_scn_(SCN::min_scn()), ddl_snapshot_version_(OB_INVALID_TIMESTAMP), diff --git a/src/storage/tablet/ob_tablet_meta.h b/src/storage/tablet/ob_tablet_meta.h index ec9523ce4..b44bb9626 100644 --- a/src/storage/tablet/ob_tablet_meta.h +++ b/src/storage/tablet/ob_tablet_meta.h @@ -69,6 +69,7 @@ public: const lib::Worker::CompatMode compat_mode, const ObTabletTableStoreFlag &table_store_flag, const int64_t create_schema_version, + const share::SCN &clog_checkpoint_scn, const bool micro_index_clustered, const bool has_cs_replica); int init( diff --git a/src/storage/tablet/ob_tablet_split_mds_helper.cpp b/src/storage/tablet/ob_tablet_split_mds_helper.cpp new file mode 100644 index 000000000..bb161fb1e --- /dev/null +++ b/src/storage/tablet/ob_tablet_split_mds_helper.cpp @@ -0,0 +1,1166 @@ +/** + * 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/tablet/ob_tablet_split_mds_helper.h" + +#include "share/schema/ob_table_schema.h" +#include "share/tablet/ob_tablet_to_ls_operator.h" +#include "storage/tablet/ob_tablet_split_replay_executor.h" +#include "storage/ls/ob_ls.h" +#include "storage/multi_data_source/mds_ctx.h" +#include "storage/tablet/ob_tablet_common.h" +#include "storage/tablet/ob_tablet_create_delete_helper.h" +#include "storage/tablet/ob_tablet_binding_helper.h" + +using namespace oceanbase::obrpc; +using namespace oceanbase::common; +using namespace oceanbase::share; +using namespace oceanbase::transaction; +using namespace oceanbase::palf; +using namespace oceanbase::memtable; +using oceanbase::share::schema::ObTableSchema; +using oceanbase::share::schema::PartitionType; +using oceanbase::sqlclient::ObISQLConnection; +using oceanbase::observer::ObInnerSQLConnection; + +namespace oceanbase +{ +namespace storage +{ + +bool ObTabletSplitMdsArg::is_valid() const +{ + return OB_INVALID_TENANT_ID != tenant_id_ + && ls_id_.is_valid() + && (split_data_tablet_ids_.count() == split_datas_.count() || 0 == split_datas_.count()) + && ((tablet_status_ != ObTabletStatus::NONE) ^ tablet_status_tablet_ids_.empty()) + && ((tablet_status_ != ObTabletStatus::NONE) == (tablet_status_data_type_ != ObTabletMdsUserDataType::NONE)); +} + +int ObTabletSplitMdsArg::assign(const ObTabletSplitMdsArg &other) +{ + int ret = OB_SUCCESS; + tenant_id_ = other.tenant_id_; + ls_id_ = other.ls_id_; + tablet_status_ = other.tablet_status_; + tablet_status_data_type_ = other.tablet_status_data_type_; + if (OB_UNLIKELY(!other.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("other is invalid", K(ret), K(other)); + } else if (OB_FAIL(split_data_tablet_ids_.assign(other.split_data_tablet_ids_))) { + LOG_WARN("failed to assign tablet ids", K(ret)); + } else if (OB_FAIL(split_datas_.assign(other.split_datas_))) { + LOG_WARN("failed to assign datas", K(ret)); + } else if (OB_FAIL(tablet_status_tablet_ids_.assign(other.tablet_status_tablet_ids_))) { + LOG_WARN("failed to assign tablet ids", K(ret)); + } else if (OB_FAIL(set_freeze_flag_tablet_ids_.assign(other.set_freeze_flag_tablet_ids_))) { + LOG_WARN("failed to assign", K(ret)); + } + return ret; +} + +void ObTabletSplitMdsArg::reset() +{ + tenant_id_ = OB_INVALID_TENANT_ID; + ls_id_.reset(); + split_data_tablet_ids_.reset(); + split_datas_.reset(); + tablet_status_tablet_ids_.reset(); + tablet_status_ = ObTabletStatus::NONE; + tablet_status_data_type_ = ObTabletMdsUserDataType::NONE; + set_freeze_flag_tablet_ids_.reset(); +} + +bool ObTabletSplitMdsArg::is_split_data_table(const ObTableSchema &table_schema) +{ + return table_schema.is_user_table() || table_schema.is_tmp_table() || table_schema.is_global_index_table(); +} + +template +int ObTabletSplitMdsArg::foreach_part(const ObTableSchema &table_schema, const int64_t part_type_filter, F &&op) +{ + int ret = OB_SUCCESS; + const bool is_hidden = schema::is_hidden_partition(static_cast(part_type_filter)); + const ObPartitionLevel part_level = table_schema.get_part_level(); + const int64_t part_num = is_hidden ? table_schema.get_hidden_partition_num() : table_schema.get_partition_num(); + ObPartition **part_array = is_hidden ? table_schema.get_hidden_part_array() : table_schema.get_part_array(); + int64_t part_idx = 0; + if (OB_ISNULL(part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", K(ret), K(table_schema)); + } else { + for (int64_t i = 0; i < part_num && OB_SUCC(ret); ++i) { + if (OB_ISNULL(part_array[i])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", K(ret), K(i), K(table_schema)); + } else if (PARTITION_LEVEL_ONE == part_level) { + if (part_type_filter == part_array[i]->get_partition_type()) { + if (OB_FAIL(op(part_idx, *part_array[i]))) { + LOG_WARN("failed to op part", K(ret)); + } else { + part_idx++; + } + } + } else if (PARTITION_LEVEL_TWO == part_level) { + ObSubPartition **sub_part_array = is_hidden ? part_array[i]->get_hidden_subpart_array() : part_array[i]->get_subpart_array(); + int64_t sub_part_num = is_hidden ? part_array[i]->get_hidden_subpartition_num() : part_array[i]->get_subpartition_num(); + if (OB_ISNULL(sub_part_array)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("part array is null", K(ret), K(table_schema)); + } else { + for (int64_t j = 0; j < sub_part_num && OB_SUCC(ret); j++) { + if (OB_ISNULL(sub_part_array[j])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("NULL ptr", K(ret), K(j), K(table_schema)); + } else if (part_type_filter == sub_part_array[j]->get_partition_type()) { + if (OB_FAIL(op(part_idx, *sub_part_array[j]))) { + LOG_WARN("failed to op sub part", K(ret)); + } else { + part_idx++; + } + } + } + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("4.0 not support part type", K(ret), K(table_schema)); + } + } + } + return ret; +} + +int ObTabletSplitMdsArg::get_partkey_projector( + const ObTableSchema &data_table_schema, + const ObTableSchema &table_schema, + ObIArray &partkey_projector) +{ + int ret = OB_SUCCESS; + const ObPartitionKeyInfo &partkey_info = data_table_schema.get_partition_key_info(); + const ObRowkeyInfo &rowkey_info = table_schema.get_rowkey_info(); + partkey_projector.reset(); + if (OB_UNLIKELY(!partkey_info.is_valid() || !rowkey_info.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid partkey info or rowkey info", K(ret), K(partkey_info), K(rowkey_info)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < partkey_info.get_size(); i++) { + uint64_t column_id = OB_INVALID_ID; + int64_t idx = -1; + if (OB_FAIL(partkey_info.get_column_id(i, column_id))) { + LOG_WARN("failed to get partkey column id", K(ret), K(partkey_info), K(i)); + } else if (OB_FAIL(rowkey_info.get_index(column_id, idx))) { + LOG_WARN("failed to get partkey index in rowkey", K(ret), K(partkey_info), K(column_id), K(i), K(rowkey_info)); + } else if (OB_FAIL(partkey_projector.push_back(idx))) { + LOG_WARN("failed to push back", K(ret)); + } + } + if (OB_FAIL(ret)) { + partkey_projector.reset(); + } + return ret; +} + +int ObTabletSplitMdsArg::prepare_basic_args( + const ObIArray &upd_table_schemas, + const ObIArray &inc_table_schemas, + ObIArray &src_tablet_ids, + ObIArray> &dst_tablet_ids, + ObIArray &dst_high_bound_vals) +{ + int ret = OB_SUCCESS; + src_tablet_ids.reset(); + dst_tablet_ids.reset(); + dst_high_bound_vals.reset(); + if (OB_UNLIKELY(upd_table_schemas.count() != inc_table_schemas.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid schema count", K(ret), K(upd_table_schemas.count()), K(inc_table_schemas.count())); + } + + for (int64_t i = 0; OB_SUCC(ret) && i < upd_table_schemas.count(); i++) { + ObTableSchema *table_schema = nullptr; + if (OB_ISNULL(table_schema = upd_table_schemas.at(i))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table schema", K(ret)); + } else if (OB_UNLIKELY((i == 0 && !is_split_data_table(*table_schema)) + || (i != 0 && !(table_schema->is_index_local_storage() || table_schema->is_aux_lob_table())))) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("unexpected table schema type", K(ret), K(i), K(is_split_data_table(*table_schema)), + K(table_schema->is_index_local_storage()), K(table_schema->is_aux_lob_table())); + } else if (OB_UNLIKELY(i >= inc_table_schemas.count() || OB_ISNULL(inc_table_schemas.at(i)) + || table_schema->get_table_id() != inc_table_schemas.at(i)->get_table_id())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid inc table schemas", K(ret), K(i), K(inc_table_schemas.count())); + } else if (!table_schema->is_partitioned_table()) { + if (OB_FAIL(src_tablet_ids.push_back(table_schema->get_tablet_id()))) { + LOG_WARN("failed to push back", K(ret)); + } + } else { + ObTabletSplitMdsArgPrepareSrcOp op(src_tablet_ids, dst_tablet_ids); + if (OB_FAIL(foreach_part(*table_schema, PartitionType::PARTITION_TYPE_SPLIT_SOURCE, op))) { + LOG_WARN("failed to foreach part", K(ret), K(table_schema->get_table_id())); + } + } + } + + for (int64_t i = 0; OB_SUCC(ret) && i < inc_table_schemas.count(); i++) { + const ObTableSchema *table_schema = nullptr; + const ObArray empty_array; + const bool is_data_table = i == 0; + if (OB_ISNULL(table_schema = inc_table_schemas.at(i)) + || OB_UNLIKELY(table_schema->get_table_id() != upd_table_schemas.at(i)->get_table_id())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table schema", K(ret), K(i), K(dst_tablet_ids)); + } else if (OB_FAIL(dst_tablet_ids.push_back(empty_array))) { + LOG_WARN("failed to push back", K(ret)); + } else { + ObTabletSplitMdsArgPrepareDstOp op(is_data_table, dst_tablet_ids.at(i), dst_high_bound_vals); + if (OB_FAIL(foreach_part(*table_schema, PartitionType::PARTITION_TYPE_NORMAL, op))) { + LOG_WARN("failed to foreach part", K(ret)); + } else if (OB_UNLIKELY(dst_tablet_ids.at(i).count() != dst_tablet_ids.at(0).count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid dst tablet count", K(ret), K(dst_tablet_ids)); + } + } + } + return ret; +} + +int ObTabletSplitMdsArg::init_split_start_src( + const uint64_t tenant_id, + const bool is_oracle_mode, + const ObLSID &ls_id, + const ObIArray &new_table_schemas, + const ObIArray &upd_table_schemas, + const ObIArray &src_tablet_ids, + const ObIArray> &dst_tablet_ids) +{ + int ret = OB_SUCCESS; + reset(); + tenant_id_ = tenant_id; + ls_id_ = ls_id; + tablet_status_ = ObTabletStatus::SPLIT_SRC; + tablet_status_data_type_ = ObTabletMdsUserDataType::START_SPLIT_SRC; + if (OB_UNLIKELY(upd_table_schemas.count() != src_tablet_ids.count() + || upd_table_schemas.count() != dst_tablet_ids.count() + || new_table_schemas.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid schema count", K(ret), K(upd_table_schemas.count()), K(new_table_schemas.count()), + K(src_tablet_ids.count()), K(dst_tablet_ids.count())); + } + for (int64_t i = 0; OB_SUCC(ret) && i < upd_table_schemas.count(); i++) { + ObTabletSplitMdsUserData data; + ObArray partkey_projector; + const ObTabletID &src_tablet_id = src_tablet_ids.at(i); + ObTableSchema *src_table_schema = upd_table_schemas.at(i); + ObTableSchema *new_data_table_schema = new_table_schemas.at(0); + if (OB_ISNULL(src_table_schema) || OB_ISNULL(new_data_table_schema) || !is_split_data_table(*new_data_table_schema)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid table schema", K(ret)); + } else if (!src_table_schema->is_aux_lob_table() + && OB_FAIL(get_partkey_projector(*new_data_table_schema, *src_table_schema, partkey_projector))) { + LOG_WARN("failed to get parkey projector", K(ret)); + } else if (OB_FAIL(data.init_range_part_split_src(dst_tablet_ids.at(i), partkey_projector, *src_table_schema, is_oracle_mode))) { + LOG_WARN("failed to set data", K(ret)); + } else if (OB_FAIL(split_data_tablet_ids_.push_back(src_tablet_id))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(split_datas_.push_back(data))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(tablet_status_tablet_ids_.push_back(src_tablet_id))) { + LOG_WARN("failed to push back", K(ret)); + } + } + return ret; +} + +int ObTabletSplitMdsArg::init_set_freeze_flag( + const uint64_t tenant_id, + const ObLSID &ls_id, + const ObIArray &tablet_ids) +{ + int ret = OB_SUCCESS; + reset(); + tenant_id_ = tenant_id; + ls_id_ = ls_id; + if (OB_FAIL(set_freeze_flag_tablet_ids_.assign(tablet_ids))) { + LOG_WARN("failed to assign", K(ret)); + } + return ret; +} + +int ObTabletSplitMdsArg::init_split_start_dst( + const uint64_t tenant_id, + const ObLSID &ls_id, + const ObIArray &inc_table_schemas, + const ObIArray &src_tablet_ids, + const ObIArray> &dst_tablet_ids, + const ObIArray &dst_high_bound_vals) +{ + int ret = OB_SUCCESS; + ObArenaAllocator allocator; + reset(); + tenant_id_ = tenant_id; + ls_id_ = ls_id; + tablet_status_tablet_ids_.reset(); // split dst tablet status is NORMAL but without major, so no need to change its tablet status + tablet_status_ = ObTabletStatus::NONE; + tablet_status_data_type_ = ObTabletMdsUserDataType::NONE; + for (int64_t i = 0; OB_SUCC(ret) && i < inc_table_schemas.count(); i++) { + const ObTableSchema *inc_table_schema = inc_table_schemas.at(i); + const ObTabletID &src_tablet_id = src_tablet_ids.at(i); + if (OB_UNLIKELY(nullptr == inc_table_schema || dst_tablet_ids.at(i).count() != dst_high_bound_vals.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", KP(inc_table_schema), K(dst_tablet_ids), K(i), K(dst_high_bound_vals.count())); + } + for (int64_t j = 0; OB_SUCC(ret) && j < dst_tablet_ids.at(i).count(); j++) { + const int64_t part_idx = j; + const ObTabletID &dst_tablet_id = dst_tablet_ids.at(i).at(part_idx); + const ObRowkey &high_bound_val = dst_high_bound_vals.at(part_idx); + ObTabletSplitMdsUserData data; + if (OB_FAIL(split_data_tablet_ids_.push_back(dst_tablet_id))) { + LOG_WARN("failed to push back", K(ret)); + } else if (is_split_data_table(*inc_table_schema)) { + const int64_t auto_part_size = inc_table_schema->is_auto_partitioned_table() ? inc_table_schema->get_auto_part_size() : OB_INVALID_SIZE; + ObDatumRowkey end_partkey; + allocator.reuse(); + if (OB_FAIL(end_partkey.from_rowkey(high_bound_val, allocator))) { + LOG_WARN("failed to convert", K(ret)); + } else if (OB_FAIL(data.init_range_part_split_dst(auto_part_size, src_tablet_id, end_partkey))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(split_datas_.push_back(data))) { + LOG_WARN("failed to push back", K(ret)); + } + } else if (inc_table_schema->is_index_local_storage()) { + ObDatumRowkey data_tablet_end_partkey; + if (OB_UNLIKELY(part_idx >= split_datas_.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid data cnt", K(ret), K(*this), K(part_idx)); + } else if (OB_FAIL(split_datas_[part_idx].get_end_partkey(data_tablet_end_partkey))) { + LOG_WARN("failed to get data tablet's end partkey", K(ret)); + } else if (OB_FAIL(data.init_range_part_split_dst(OB_INVALID_SIZE/*auto_part_size*/, src_tablet_id, data_tablet_end_partkey))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(split_datas_.push_back(data))) { + LOG_WARN("failed to push back", K(ret)); + } + } else if (inc_table_schema->is_aux_lob_table()) { + ObDatumRowkey empty_partkey; + if (OB_FAIL(data.init_range_part_split_dst(OB_INVALID_SIZE/*auto_part_size*/, src_tablet_id, empty_partkey))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(split_datas_.push_back(data))) { + LOG_WARN("failed to push back", K(ret)); + } + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected table type", K(ret), K(inc_table_schema->get_table_id())); + } + } + } + return ret; +} + +int ObTabletSplitMdsArg::init_split_end_src( + const uint64_t tenant_id, + const ObLSID &ls_id, + const ObTabletID &src_data_tablet_id, + const ObIArray &src_local_index_tablet_ids, + const ObIArray &src_lob_tablet_ids) +{ + int ret = OB_SUCCESS; + reset(); + tenant_id_ = tenant_id; + ls_id_ = ls_id; + split_data_tablet_ids_.reset(); + split_datas_.reset(); + tablet_status_tablet_ids_.reset(); + tablet_status_ = ObTabletStatus::SPLIT_SRC_DELETED; + tablet_status_data_type_ = ObTabletMdsUserDataType::FINISH_SPLIT_SRC; + if (OB_FAIL(tablet_status_tablet_ids_.push_back(src_data_tablet_id))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(append(tablet_status_tablet_ids_, src_local_index_tablet_ids))) { + LOG_WARN("failed to append", K(ret)); + } else if (OB_FAIL(append(tablet_status_tablet_ids_, src_lob_tablet_ids))) { + LOG_WARN("failed to append", K(ret)); + } + + if (OB_SUCC(ret) && OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid arg", K(ret), K(*this)); + } + return ret; +} + +int ObTabletSplitMdsArg::init_split_end_dst( + const uint64_t tenant_id, + const ObLSID &ls_id, + const int64_t auto_part_size, + const ObIArray &dst_data_tablet_ids, + const ObIArray> &dst_local_index_tablet_ids, + const ObIArray> &dst_lob_tablet_ids) +{ + int ret = OB_SUCCESS; + ObTabletSplitMdsUserData data; + reset(); + tenant_id_ = tenant_id; + ls_id_ = ls_id; + tablet_status_tablet_ids_.reset(); + tablet_status_ = ObTabletStatus::NORMAL; + tablet_status_data_type_ = ObTabletMdsUserDataType::FINISH_SPLIT_DST; + + // data tablets + if (OB_FAIL(data.init_no_split(auto_part_size))) { + LOG_WARN("failed to set split data", K(ret)); + } else if (OB_FAIL(append(split_data_tablet_ids_, dst_data_tablet_ids))) { + LOG_WARN("failed to assign", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < dst_data_tablet_ids.count(); i++) { + if (OB_FAIL(split_datas_.push_back(data))) { + LOG_WARN("failed to push back", K(ret)); + } + } + + // local index tablets + if (OB_FAIL(ret)) { + } else if (OB_FAIL(data.init_no_split(OB_INVALID_SIZE))) { + LOG_WARN("failed to set split data", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < dst_local_index_tablet_ids.count(); i++) { + if (OB_FAIL(append(split_data_tablet_ids_, dst_local_index_tablet_ids.at(i)))) { + LOG_WARN("failed to assign", K(ret)); + } + for (int64_t j = 0; OB_SUCC(ret) && j < dst_local_index_tablet_ids.at(i).count(); j++) { + if (OB_FAIL(split_datas_.push_back(data))) { + LOG_WARN("failed to push back", K(ret)); + } + } + } + + // lob tablets + if (OB_FAIL(ret)) { + } else if (OB_FAIL(data.init_no_split(OB_INVALID_SIZE))) { + LOG_WARN("failed to set split data", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < dst_lob_tablet_ids.count(); i++) { + if (OB_FAIL(append(split_data_tablet_ids_, dst_lob_tablet_ids.at(i)))) { + LOG_WARN("failed to assign", K(ret)); + } + for (int64_t j = 0; OB_SUCC(ret) && j < dst_lob_tablet_ids.at(i).count(); j++) { + if (OB_FAIL(split_datas_.push_back(data))) { + LOG_WARN("failed to push back", K(ret)); + } + } + } + + if (OB_FAIL(ret)) { + } else if (OB_FAIL(tablet_status_tablet_ids_.assign(split_data_tablet_ids_))) { + LOG_WARN("failed to push back", K(ret)); + } + + if (OB_SUCC(ret) && OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid arg", K(ret), K(*this)); + } + return ret; +} + +int ObTabletSplitMdsArg::init( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObIArray &tablet_ids, + const ObIArray &split_datas) +{ + int ret = OB_SUCCESS; + reset(); + tenant_id_ = tenant_id; + ls_id_ = ls_id; + if (OB_FAIL(split_data_tablet_ids_.assign(tablet_ids))) { + LOG_WARN("failed to assign", K(ret)); + } else if (OB_FAIL(split_datas_.assign(split_datas))) { + LOG_WARN("failed to assign", K(ret)); + } + if (OB_SUCC(ret) && OB_UNLIKELY(!is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid arg", K(ret), K(*this)); + } + return ret; +} + +OB_SERIALIZE_MEMBER(ObTabletSplitMdsArg, tenant_id_, ls_id_, split_data_tablet_ids_, split_datas_, tablet_status_tablet_ids_, tablet_status_, tablet_status_data_type_, set_freeze_flag_tablet_ids_); + +int ObTabletSplitMdsArgPrepareSrcOp::operator()(const int64_t part_idx, ObBasePartition &part) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(0 != part_idx)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("only support one split src part now", K(ret), K(part_idx), K(src_tablet_ids_), K(part.get_tablet_id())); + } else if (OB_FAIL(src_tablet_ids_.push_back(part.get_tablet_id()))) { + LOG_WARN("failed to push back", K(ret)); + } + return ret; +} + +int ObTabletSplitMdsArgPrepareDstOp::operator()(const int64_t part_idx, ObBasePartition &part) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(dst_tablet_ids_.push_back(part.get_tablet_id()))) { + LOG_WARN("failed to push back", K(ret)); + } else if (is_data_table_) { + if (OB_FAIL(dst_high_bound_vals_.push_back(part.get_high_bound_val()))) { + LOG_WARN("failed to push back", K(ret)); + } + } + return ret; +} + +int ObTabletSplitMdsHelper::prepare_calc_split_dst( + ObLS &ls, + ObTablet &tablet, + const int64_t abs_timeout_us, + ObTabletSplitMdsUserData &src_split_data, + ObIArray &dst_split_datas) +{ + int ret = OB_SUCCESS; + const ObTabletID &src_tablet_id = tablet.get_tablet_meta().tablet_id_; + ObArray dst_tablet_ids; + ObTabletHandle dst_tablet_handle; + src_split_data.reset(); + dst_split_datas.reset(); + if (OB_FAIL(tablet.ObITabletMdsInterface::get_split_data(src_split_data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_UNLIKELY(!src_split_data.is_split_src())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("not split src", K(ret), K(src_tablet_id), K(src_split_data)); + } else if (OB_FAIL(src_split_data.get_split_dst_tablet_ids(dst_tablet_ids))) { + LOG_WARN("failed to get split dst tablet ids", K(ret)); + } else if (OB_FAIL(dst_split_datas.prepare_allocate(dst_tablet_ids.count()))) { + LOG_WARN("failed to prepare allocate", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < dst_tablet_ids.count(); i++) { + dst_tablet_handle.reset(); + if (OB_FAIL(ls.get_tablet_with_timeout(dst_tablet_ids.at(i), dst_tablet_handle, abs_timeout_us))) { + LOG_WARN("failed to get split dst tablet", K(ret)); + } else if (OB_FAIL(dst_tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(dst_split_datas.at(i), abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to part key compare", K(ret)); + } else if (OB_UNLIKELY(!dst_split_datas.at(i).is_split_dst())) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("no longer split dst", K(ret), K(src_tablet_id), K(dst_tablet_ids.at(i)), K(dst_split_datas.at(i))); + } + } + } + return ret; +} + +int ObTabletSplitMdsHelper::calc_split_dst( + ObLS &ls, + ObTablet &tablet, + const blocksstable::ObDatumRowkey &rowkey, + const int64_t abs_timeout_us, + common::ObTabletID &dst_tablet_id) +{ + int ret = OB_SUCCESS; + ObTabletSplitMdsUserData split_data; + if (OB_FAIL(tablet.ObITabletMdsInterface::get_split_data(split_data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_FAIL(split_data.calc_split_dst(ls, rowkey, abs_timeout_us, dst_tablet_id))) { + LOG_WARN("failed to calc split dst tablet id", K(ret), K(tablet.get_tablet_meta())); + } + return ret; +} + +int ObTabletSplitMdsHelper::calc_split_dst_lob( + ObLS &ls, + ObTablet &tablet, + const blocksstable::ObDatumRow &data_row, + const int64_t abs_timeout_us, + ObTabletID &dst_tablet_id) +{ + int ret = OB_SUCCESS; + const ObTabletMeta &tablet_meta = tablet.get_tablet_meta(); + const ObTabletID &src_tablet_id = tablet_meta.tablet_id_; + const ObTabletID &data_tablet_id = tablet.get_data_tablet_id(); + ObTabletHandle data_tablet_handle; + ObTabletHandle dst_data_tablet_handle; + ObTabletBindingMdsUserData ddl_data; + ObTabletBindingMdsUserData dst_ddl_data; + ObTabletSplitMdsUserData split_data; + ObTabletID dst_data_tablet_id; + if (OB_FAIL(ls.get_tablet_with_timeout(data_tablet_id, data_tablet_handle, abs_timeout_us, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_meta)); + } else { + const int64_t rowkey_column_cnt = data_tablet_handle.get_obj()->get_rowkey_read_info().get_schema_rowkey_count(); + ObDatumRowkey data_rowkey; + if (OB_FAIL(data_rowkey.assign(data_row.storage_datums_, rowkey_column_cnt))) { + LOG_WARN("failed to assign datum rowkey", K(ret), K(data_row), K(rowkey_column_cnt)); + } else if (OB_FAIL(calc_split_dst(ls, *data_tablet_handle.get_obj(), data_rowkey, abs_timeout_us, dst_data_tablet_id))) { + LOG_WARN("failed to get split data", K(ret), K(tablet_meta)); + } else if (OB_FAIL(ls.get_tablet_with_timeout(dst_data_tablet_id, dst_data_tablet_handle, + abs_timeout_us, ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_meta), K(dst_data_tablet_id)); + } else if (OB_FAIL(data_tablet_handle.get_obj()->ObITabletMdsInterface::get_ddl_data( + share::SCN::max_scn(), ddl_data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get ddl data", K(ret), K(tablet_meta)); + } else if (OB_FAIL(dst_data_tablet_handle.get_obj()->ObITabletMdsInterface::get_ddl_data( + share::SCN::max_scn(), dst_ddl_data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get ddl data from tablet", K(ret), K(tablet_meta), K(dst_data_tablet_id)); + } else { + if (src_tablet_id == ddl_data.lob_meta_tablet_id_) { + dst_tablet_id = dst_ddl_data.lob_meta_tablet_id_; + } else if (src_tablet_id == ddl_data.lob_piece_tablet_id_) { + dst_tablet_id = dst_ddl_data.lob_piece_tablet_id_; + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected lob tablet id", K(ret), K(src_tablet_id), K(data_tablet_id), + K(dst_data_tablet_id), K(ddl_data), K(dst_ddl_data)); + } + } + } + return ret; +} + +int ObTabletSplitMdsHelper::get_split_info(ObTablet &tablet, ObIAllocator &allocator, ObTabletSplitTscInfo &split_info) +{ + int ret = OB_SUCCESS; + const ObTabletMeta &tablet_meta = tablet.get_tablet_meta(); + const ObLSID &ls_id = tablet_meta.ls_id_; + const ObTabletID &tablet_id = tablet_meta.tablet_id_; + ObTabletSplitMdsUserData data; + const int64_t abs_timeout_us = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_ts() : ObTimeUtility::current_time() + ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S; + if (OB_FAIL(tablet.ObITabletMdsInterface::get_split_data(data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (data.is_split_dst()) { + ObLSService *ls_service = nullptr; + ObLSHandle ls_handle; + if (OB_ISNULL(ls_service = MTL(ObLSService*))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("failed to get ObLSService from MTL", K(ret), KP(ls_service)); + } else if (OB_FAIL(ls_service->get_ls(ls_id, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("failed to get ls", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls", K(ret), K(ls_id)); + } else if (OB_FAIL(data.get_tsc_split_info(tablet_id, *ls_handle.get_ls(), abs_timeout_us, allocator, split_info))) { + LOG_WARN("failed to get split info", K(ret)); + } + } else { + LOG_INFO("not split dst", K(ret), K(tablet_meta), K(data)); + } + return ret; +} + +int ObTabletSplitMdsHelper::get_is_spliting(ObTablet &tablet, bool &is_split_dst) +{ + int ret = OB_SUCCESS; + const ObTabletMeta &tablet_meta = tablet.get_tablet_meta(); + is_split_dst = false; + if (OB_UNLIKELY(!tablet_meta.table_store_flag_.with_major_sstable())) { + const int64_t timeout = THIS_WORKER.is_timeout_ts_valid() ? THIS_WORKER.get_timeout_remain() : ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S; + ObTabletSplitMdsUserData data; + if (OB_FAIL(tablet.ObITabletMdsInterface::get_split_data(data, timeout))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (data.is_split_dst()) { + is_split_dst = true; + } + } + return ret; +} + +int ObTabletSplitMdsHelper::batch_get_tablet_split( + const int64_t abs_timeout_us, + const ObBatchGetTabletSplitArg &arg, + ObBatchGetTabletSplitRes &res) +{ + int ret = OB_SUCCESS; + uint64_t tenant_id = arg.tenant_id_; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", K(ret), K(arg)); + } else { + MTL_SWITCH(tenant_id) { + ObLSService *ls_service = MTL(ObLSService *); + logservice::ObLogService *log_service = MTL(logservice::ObLogService*); + ObLSHandle ls_handle; + ObLS *ls = nullptr; + ObRole role = INVALID_ROLE; + if (OB_ISNULL(ls_service) || OB_ISNULL(log_service)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected ls_service or log_service", K(ret)); + } else if (OB_FAIL(ls_service->get_ls(arg.ls_id_, ls_handle, ObLSGetMod::DDL_MOD))) { + LOG_WARN("get ls failed", K(ret), K(arg)); + } else if (OB_ISNULL(ls = ls_handle.get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid ls", K(ret), K(arg.ls_id_)); + } else if (OB_FAIL(ls->get_ls_role(role))) { + LOG_WARN("get role failed", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else if (OB_UNLIKELY(ObRole::LEADER != role)) { + ret = OB_NOT_MASTER; + LOG_WARN("ls not leader", K(ret), K(MTL_ID()), K(arg.ls_id_)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_ids_.count(); i++) { + const ObTabletID &tablet_id = arg.tablet_ids_.at(i); + ObTabletHandle tablet_handle; + ObTabletSplitMdsUserData data; + if (OB_FAIL(ls->get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret), K(tablet_id), K(abs_timeout_us)); + } else if (OB_FAIL(tablet_handle.get_obj()->get_split_data(data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get split data", K(ret), K(abs_timeout_us)); + } else if (OB_FAIL(res.split_datas_.push_back(data))) { + LOG_WARN("failed to push back", K(ret)); + } + + // currently not support to read uncommitted mds set by this transaction, so check and avoid such usage + if (OB_SUCC(ret) && arg.check_committed_) { + ObTabletSplitMdsUserData tmp_data; + bool is_committed = true; + if (OB_FAIL(tablet_handle.get_obj()->get_latest_split_data(ReadSplitDataOp(tmp_data), is_committed))) { + if (OB_EMPTY_RESULT == ret) { + is_committed = true; + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get latest split data", K(ret)); + } + } else if (OB_UNLIKELY(!is_committed)) { + ret = OB_EAGAIN; + LOG_WARN("check committed failed", K(ret), K(tenant_id), K(arg.ls_id_), K(tablet_id), K(tmp_data)); + } + } + } + } + } + } + return ret; +} + +int ObTabletSplitMdsHelper::get_tablet_split_mds_by_rpc( + const uint64_t tenant_id, + const ObLSID &ls_id, + const ObIArray &tablet_ids, + const int64_t abs_timeout_us, + ObIArray &datas) +{ + int ret = OB_SUCCESS; + const int64_t cluster_id = GCONF.cluster_id; + obrpc::ObSrvRpcProxy *srv_rpc_proxy = nullptr; + share::ObLocationService *location_service = nullptr; + ObAddr leader_addr; + obrpc::ObBatchGetTabletSplitArg arg; + obrpc::ObBatchGetTabletSplitRes res; + if (OB_ISNULL(srv_rpc_proxy = GCTX.srv_rpc_proxy_) + || OB_ISNULL(location_service = GCTX.location_service_)) { + ret = OB_ERR_SYS; + LOG_WARN("root service or location_cache is null", K(ret), KP(srv_rpc_proxy), KP(location_service)); + } else if (OB_FAIL(arg.init(tenant_id, ls_id, tablet_ids, true/*check_committed*/))) { + LOG_WARN("failed to init arg", K(ret), K(tenant_id), K(ls_id), K(ls_id)); + } else { + bool force_renew = false; + bool finish = false; + for (int64_t retry_times = 0; OB_SUCC(ret) && !finish; retry_times++) { + if (OB_FAIL(location_service->get_leader(cluster_id, tenant_id, ls_id, force_renew, leader_addr))) { + LOG_WARN("fail to get ls locaiton leader", KR(ret), K(tenant_id), K(ls_id)); + } else if (OB_FAIL(srv_rpc_proxy->to(leader_addr).timeout(abs_timeout_us - ObTimeUtility::current_time()).batch_get_tablet_split(arg, res))) { + LOG_WARN("fail to batch get tablet split", K(ret), K(retry_times), K(abs_timeout_us)); + } else { + finish = true; + } + if (OB_FAIL(ret)) { + force_renew = true; + if (OB_LS_LOCATION_LEADER_NOT_EXIST == ret || OB_GET_LOCATION_TIME_OUT == ret || OB_NOT_MASTER == ret + || OB_ERR_SHARED_LOCK_CONFLICT == ret || OB_LS_OFFLINE == ret + || OB_NOT_INIT == ret || OB_LS_NOT_EXIST == ret || OB_TABLET_NOT_EXIST == ret || OB_TENANT_NOT_IN_SERVER == ret || OB_LS_LOCATION_NOT_EXIST == ret) { + // overwrite ret + if (OB_UNLIKELY(ObTimeUtility::current_time() > abs_timeout_us)) { + ret = OB_TIMEOUT; + LOG_WARN("timeout", K(ret), K(abs_timeout_us)); + } else if (OB_FAIL(THIS_WORKER.check_status())) { + LOG_WARN("failed to check status", K(ret), K(abs_timeout_us)); + } else if (retry_times >= 3) { + ob_usleep(100 * 1000L); // 100ms + } + } + } + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(datas.assign(res.split_datas_))) { + LOG_WARN("failed to assign", K(ret)); + } + return ret; +} + +int ObTabletSplitMdsHelper::set_auto_part_size_for_create( + const uint64_t tenant_id, + const obrpc::ObBatchCreateTabletArg &create_arg, + const ObIArray &auto_part_size_arr, + const int64_t abs_timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (!auto_part_size_arr.empty()) { + const ObLSID &ls_id = create_arg.id_; + ObTabletSplitMdsArg arg; + ObArray split_data_tablet_ids; + ObArray split_datas; + ObTabletSplitMdsUserData tmp_data; + if (OB_UNLIKELY(!create_arg.table_schemas_.empty() || create_arg.create_tablet_schemas_.count() != auto_part_size_arr.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg for set auto part size", K(ret), K(create_arg.table_schemas_.count()), K(create_arg.create_tablet_schemas_.count()), + K(auto_part_size_arr.count()), K(create_arg)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < create_arg.tablets_.count(); i++) { + const ObIArray &tablet_ids = create_arg.tablets_[i].tablet_ids_; + const ObIArray &table_schema_idx_arr = create_arg.tablets_[i].table_schema_index_; + if (OB_UNLIKELY(tablet_ids.count() != table_schema_idx_arr.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid table schema idx arr", K(ret), K(tablet_ids.count()), K(table_schema_idx_arr.count())); + } + for (int64_t j = 0; OB_SUCC(ret) && j < tablet_ids.count(); j++) { + const ObTabletID &tablet_id = tablet_ids.at(j); + const int64_t schema_idx = table_schema_idx_arr.at(j); + if (OB_UNLIKELY(schema_idx >= auto_part_size_arr.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("schema idx out of range", K(ret), K(i), K(j), K(create_arg), K(auto_part_size_arr)); + } else { + const int64_t auto_part_size = auto_part_size_arr.at(schema_idx); + if (OB_INVALID_SIZE != auto_part_size) { + if (OB_FAIL(tmp_data.init_no_split(auto_part_size))) { + LOG_WARN("failed to set split data", K(ret)); + } else if (OB_FAIL(split_data_tablet_ids.push_back(tablet_id))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(split_datas.push_back(tmp_data))) { + LOG_WARN("failed to push back", K(ret)); + } else if (split_data_tablet_ids.count() >= ObTabletSplitMdsArg::BATCH_TABLET_CNT) { + if (OB_FAIL(arg.init(tenant_id, ls_id, split_data_tablet_ids, split_datas))) { + LOG_WARN("failed to init tablet split mds arg", K(ret)); + } else if (OB_FAIL(register_mds(arg, false/*need_flush_redo*/, trans))) { + LOG_WARN("failed to register mds", K(ret)); + } else { + split_data_tablet_ids.reuse(); + split_datas.reuse(); + } + } + } + } + } + } + if (OB_SUCC(ret) && !split_data_tablet_ids.empty()) { + if (OB_FAIL(arg.init(tenant_id, ls_id, split_data_tablet_ids, split_datas))) { + LOG_WARN("failed to init tablet split mds arg", K(ret)); + } else if (OB_FAIL(register_mds(arg, false/*need_flush_redo*/, trans))) { + LOG_WARN("failed to register mds", K(ret)); + } + } + } + return ret; +} + +int ObModifyAutoPartSizeOp::operator()(ObTabletSplitMdsUserData &data) +{ + return data.modify_auto_part_size(auto_part_size_); +} + +int ObTabletSplitMdsHelper::modify_auto_part_size( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const int64_t auto_part_size, + const int64_t abs_timeout_us, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObModifyAutoPartSizeOp op(auto_part_size); + if (OB_FAIL(modify_tablet_split_(tenant_id, tablet_ids, abs_timeout_us, op, trans))) { + LOG_WARN("failed to modify table split", K(ret)); + } + return ret; +} + +template +int ObTabletSplitMdsHelper::modify_tablet_split_( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const int64_t abs_timeout_us, + F &&op, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + if (!tablet_ids.empty()) { + ObTabletSplitMdsArg arg; + ObArray> ls_tablets; + ObArray this_batch_tablet_ids; + if (OB_FAIL(ObTabletBindingMdsHelper::get_sorted_ls_tablets(tenant_id, tablet_ids, ls_tablets, trans))) { + LOG_WARN("failed to get sorted ls tablets", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < ls_tablets.count(); i++) { + const ObLSID &ls_id = ls_tablets.at(i).first; + const ObTabletID &tablet_id = ls_tablets.at(i).second; + const bool is_last_or_next_ls_id_changed = i == ls_tablets.count() - 1 || ls_id != ls_tablets.at(i+1).first; + if (OB_FAIL(this_batch_tablet_ids.push_back(tablet_id))) { + LOG_WARN("failed to push back", K(ret)); + } else if (is_last_or_next_ls_id_changed || this_batch_tablet_ids.count() >= ObTabletSplitMdsArg::BATCH_TABLET_CNT) { + + ObArray datas; + if (OB_FAIL(get_tablet_split_mds_by_rpc(tenant_id, ls_id, this_batch_tablet_ids, abs_timeout_us, datas))) { + LOG_WARN("failed to get tablet binding mds", K(ret)); + } + for (int64_t j = 0; OB_SUCC(ret) && j < datas.count(); j++) { + ret = op(datas.at(j)); + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(arg.init(tenant_id, ls_id, this_batch_tablet_ids, datas))) { + LOG_WARN("failed to init", K(ret)); + } else if (OB_FAIL(register_mds(arg, false/*need_flush_redo*/, trans))) { + LOG_WARN("failed to register mds", K(ret)); + } + + if (OB_SUCC(ret)) { + this_batch_tablet_ids.reuse(); + } + } + } + if (OB_SUCC(ret) && OB_UNLIKELY(!this_batch_tablet_ids.empty())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("batch not consumed out", K(ret), K(this_batch_tablet_ids)); + } + } + return ret; +} + +int ObTabletSplitMdsHelper::register_mds( + const ObTabletSplitMdsArg &arg, + const bool need_flush_redo, + ObMySQLTransaction &trans) +{ + int ret = OB_SUCCESS; + ObISQLConnection *isql_conn = nullptr; + if (OB_ISNULL(isql_conn = trans.get_connection())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid connection", K(ret)); + } else { + const int64_t size = arg.get_serialize_size(); + ObArenaAllocator allocator; + char *buf = nullptr; + int64_t pos = 0; + ObRegisterMdsFlag flag; + flag.need_flush_redo_instantly_ = need_flush_redo; + flag.mds_base_scn_.reset(); + if (OB_ISNULL(buf = static_cast(allocator.alloc(size)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate", K(ret)); + } else if (OB_FAIL(arg.serialize(buf, size, pos))) { + LOG_WARN("failed to serialize arg", K(ret)); + } else if (OB_FAIL(static_cast(isql_conn)->register_multi_data_source( + arg.tenant_id_, arg.ls_id_, ObTxDataSourceType::TABLET_SPLIT, buf, pos, flag))) { + LOG_WARN("failed to register mds", K(ret)); + } + } + return ret; +} + +int ObTabletSplitMdsHelper::on_register(const char* buf, const int64_t len, mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + ObTabletSplitMdsArg arg; + if (OB_FAIL(arg.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize arg", K(ret)); + } else if (OB_FAIL(modify(arg, SCN::invalid_scn(), ctx))) { + LOG_WARN("failed to register_process", K(ret)); + } + return ret; +} + +int ObTabletSplitMdsHelper::on_replay(const char* buf, const int64_t len, const share::SCN &scn, mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + int64_t pos = 0; + ObTabletSplitMdsArg arg; + if (OB_FAIL(arg.deserialize(buf, len, pos))) { + LOG_WARN("failed to deserialize arg", K(ret)); + } else if (OB_FAIL(modify(arg, scn, ctx))) { + LOG_WARN("failed to register_process", K(ret)); + } + return ret; +} + +int ObTabletSplitMdsHelper::modify( + const ObTabletSplitMdsArg &arg, + const share::SCN &scn, + mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + const bool is_reset_split_data = arg.split_datas_.empty(); + const share::ObLSID &ls_id = arg.ls_id_; + ObLSHandle ls_handle; + ObLS *ls = nullptr; + bool need_empty_shell_trigger = false; + if (OB_UNLIKELY(!arg.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret), K(arg)); + } else if (OB_FAIL(MTL(ObLSService*)->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD))) { + LOG_WARN("fail to get ls", KR(ret), K(arg)); + } else if (OB_UNLIKELY(nullptr == (ls = ls_handle.get_ls()))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("ls should not be NULL", KR(ret), K(arg), KP(ls)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < arg.split_data_tablet_ids_.count(); i++) { + const ObTabletID &tablet_id = arg.split_data_tablet_ids_[i]; + if (is_reset_split_data) { + ObTabletSplitMdsUserData data; + if (OB_FAIL(set_tablet_split_mds(ls_id, tablet_id, scn, data, ctx))) { + LOG_WARN("failed to modify", K(ret), K(ls_id), K(tablet_id), K(scn)); + } + } else { + const ObTabletSplitMdsUserData &data = arg.split_datas_[i]; // index range is checked by is_valid() + if (OB_FAIL(set_tablet_split_mds(ls_id, tablet_id, scn, data, ctx))) { + LOG_WARN("failed to modify", K(ret), K(ls_id), K(tablet_id), K(scn)); + } + } + } + for (int64_t i = 0; OB_SUCC(ret) && i < arg.tablet_status_tablet_ids_.count(); i++) { + const ObTabletID &tablet_id = arg.tablet_status_tablet_ids_[i]; + if (OB_FAIL(set_tablet_status(*ls, tablet_id, arg.tablet_status_, arg.tablet_status_data_type_, scn, ctx))) { + LOG_WARN("failed to modify", K(ret), K(ls_id), K(tablet_id), K(scn)); + } else if (ObTabletStatus::SPLIT_SRC_DELETED == arg.tablet_status_) { + need_empty_shell_trigger = true; + } + } + + if (OB_SUCC(ret) && need_empty_shell_trigger) { + if (OB_FAIL(ObTabletCreateDeleteMdsUserData::set_tablet_empty_shell_trigger(ls_id))) { + LOG_WARN("failed to set_tablet_empty_shell_trigger", K(ret), K(arg)); + } + } + + if (scn.is_valid()) { // on_replay + for (int64_t i = 0; OB_SUCC(ret) && i < arg.set_freeze_flag_tablet_ids_.count(); i++) { + const ObTabletID &tablet_id = arg.set_freeze_flag_tablet_ids_[i]; + if (OB_FAIL(set_freeze_flag(*ls, tablet_id, scn))) { + LOG_WARN("failed to set freeze flag", K(ret), K(tablet_id), K(scn)); + } + } + } + LOG_INFO("modify tablet split data", K(ret), K(scn), K(ctx.get_writer()), K(arg)); + return ret; +} + +int ObTabletSplitMdsHelper::set_tablet_split_mds( + const ObLSID &ls_id, + const ObTabletID &tablet_id, + const share::SCN &replay_scn, + const ObTabletSplitMdsUserData &data, + mds::BufferCtx &ctx) +{ + MDS_TG(100_ms); + int ret = OB_SUCCESS; + if (!replay_scn.is_valid()) { + const ObTabletMapKey key(ls_id, tablet_id); + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + mds::MdsCtx &user_ctx = static_cast(ctx); + if (CLICK_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret)); + } else if (OB_FALSE_IT(tablet = tablet_handle.get_obj())) { + } else if (CLICK_FAIL(tablet->ObITabletMdsInterface::set(data, user_ctx, 0/*lock_timeout_us*/))) { + LOG_WARN("failed to set mds data", K(ret)); + } + } else { + ObTabletSplitReplayExecutor replay_executor; + if (CLICK_FAIL(replay_executor.init(ctx, replay_scn, data))) { + LOG_WARN("failed to init replay executor", K(ret)); + } else if (CLICK_FAIL(replay_executor.execute(replay_scn, ls_id, tablet_id))) { + if (OB_EAGAIN != ret) { + LOG_WARN("failed to replay mds", K(ret)); + } + } + } + return ret; +} + +int ObTabletSplitMdsHelper::set_freeze_flag( + ObLS &ls, + const ObTabletID &tablet_id, + const share::SCN &replay_scn) +{ + int ret = OB_SUCCESS; + const ObLSID &ls_id = ls.get_ls_id(); + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObArray memtables; + if (OB_FAIL(ObTabletBindingHelper::get_tablet_for_new_mds(ls, tablet_id, replay_scn, tablet_handle))) { + if (OB_NO_NEED_UPDATE == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret)); + } + } else if (OB_FALSE_IT(tablet = tablet_handle.get_obj())) { + } else if (OB_FAIL(tablet->get_all_memtables(memtables))) { + LOG_WARN("failed to get_memtable_mgr for get all memtable", K(ret), KPC(tablet)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < memtables.count(); ++i) { + ObITable *table = memtables.at(i).get_table(); + if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("table in tables_handle is invalid", K(ret), KP(table)); + } else { + ObMemtable *memtable = static_cast(table); + if (memtable->is_active_memtable()) { + memtable->set_transfer_freeze(replay_scn); + LOG_INFO("succ set transfer freeze", K(ls_id), K(tablet_id), KP(memtable), K(replay_scn)); + } + } + } + } + return ret; +} + +int ObTabletSplitMdsHelper::set_tablet_status( + ObLS &ls, + const ObTabletID &tablet_id, + const ObTabletStatus tablet_status, + const ObTabletMdsUserDataType data_type, + const share::SCN &replay_scn, + mds::BufferCtx &ctx) +{ + int ret = OB_SUCCESS; + const ObLSID &ls_id = ls.get_ls_id(); + ObTabletHandle tablet_handle; + ObTablet *tablet = nullptr; + ObTabletCreateDeleteMdsUserData user_data; + bool is_committed = false; + if (OB_FAIL(ObTabletBindingHelper::get_tablet_for_new_mds(ls, tablet_id, replay_scn, tablet_handle))) { + if (OB_NO_NEED_UPDATE == ret) { + ret = OB_SUCCESS; + } else { + LOG_WARN("failed to get tablet", K(ret)); + } + } else if (OB_FALSE_IT(tablet = tablet_handle.get_obj())) { + } else if (OB_FAIL(tablet->ObITabletMdsInterface::get_latest_tablet_status(user_data, is_committed))) { + LOG_WARN("failed to get tx data", K(ret), KPC(tablet)); + } else if (OB_UNLIKELY(!is_committed)) { + ret = OB_EAGAIN; + LOG_WARN("tablet status not committed, retry", K(ret), K(user_data), KPC(tablet)); + } else { + mds::MdsCtx &user_ctx = static_cast(ctx); + user_data.data_type_ = data_type; + user_data.tablet_status_ = tablet_status; + if (!replay_scn.is_valid()) { + if (OB_FAIL(ls.get_tablet_svr()->set_tablet_status(tablet_id, user_data, user_ctx))) { + LOG_WARN("failed to set user data", K(ret), K(user_data), KPC(tablet)); + } + } else { + if (OB_FAIL(ls.get_tablet_svr()->replay_set_tablet_status(tablet_id, replay_scn, user_data, user_ctx))) { + LOG_WARN("failed to set user data", K(ret), K(user_data), KPC(tablet)); + } + } + } + return ret; +} + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_split_mds_helper.h b/src/storage/tablet/ob_tablet_split_mds_helper.h new file mode 100644 index 000000000..abead1a5f --- /dev/null +++ b/src/storage/tablet/ob_tablet_split_mds_helper.h @@ -0,0 +1,233 @@ +/** + * 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_TABLET_SPLIT_MDS_HELPER +#define OCEANBASE_STORAGE_OB_TABLET_SPLIT_MDS_HELPER + +#include "common/ob_tablet_id.h" +#include "common/rowkey/ob_rowkey.h" +#include "lib/container/ob_array.h" +#include "lib/container/ob_array_serialization.h" +#include "lib/mysqlclient/ob_mysql_transaction.h" +#include "share/ob_ls_id.h" +#include "src/storage/tablet/ob_tablet_create_delete_mds_user_data.h" +#include "src/storage/tablet/ob_tablet_split_mds_user_data.h" + +namespace oceanbase +{ +namespace obrpc +{ +struct ObBatchCreateTabletArg; +struct ObBatchGetTabletSplitArg; +struct ObBatchGetTabletSplitRes; +} + +namespace share +{ +class SCN; +namespace schema +{ +class ObTableSchema; +} +} + +namespace storage +{ +class ObTablet; + +namespace mds +{ +struct BufferCtx; +} + +class ObTabletSplitMdsArg final +{ +public: + // arg with such tablet cnt cannot be more than mds buffer limit (1.5M) + const static int64_t BATCH_TABLET_CNT = 8192; + + OB_UNIS_VERSION_V(1); + +public: + ObTabletSplitMdsArg() : tenant_id_(OB_INVALID_TENANT_ID), ls_id_(), split_data_tablet_ids_(), split_datas_(), tablet_status_tablet_ids_(), tablet_status_(ObTabletStatus::NONE), tablet_status_data_type_(ObTabletMdsUserDataType::NONE), set_freeze_flag_tablet_ids_() {} + ~ObTabletSplitMdsArg() {} + bool is_valid() const; + int assign(const ObTabletSplitMdsArg &other); + void reset(); + + static int prepare_basic_args( + const ObIArray &upd_table_schemas, + const ObIArray &inc_table_schemas, + ObIArray &src_tablet_ids, + ObIArray> &dst_tablet_ids, + ObIArray &dst_high_bound_vals); + + int init_split_start_src( + const uint64_t tenant_id, + const bool is_oracle_mode, + const share::ObLSID &ls_id, + const ObIArray &new_table_schemas, + const ObIArray &upd_table_schemas, + const ObIArray &src_tablet_ids, + const ObIArray> &dst_tablet_ids); + int init_set_freeze_flag( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObIArray &tablet_ids); + int init_split_start_dst( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObIArray &inc_table_schemas, + const ObIArray &src_tablet_ids, + const ObIArray> &dst_tablet_ids, + const ObIArray &dst_high_bound_vals); + int init_split_end_src( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObTabletID &src_data_tablet_id, // or global index tablets + const ObIArray &src_local_index_tablet_ids, + const ObIArray &src_lob_tablet_ids); + int init_split_end_dst( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const int64_t auto_part_size, + const ObIArray &dst_data_tablet_ids, // or global index tablets + const ObIArray> &dst_local_index_tablet_ids, + const ObIArray> &dst_lob_tablet_ids); + int init( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObIArray &tablet_ids, + const ObIArray &split_datas); + + TO_STRING_KV(K_(tenant_id), K_(ls_id), K_(split_data_tablet_ids), K_(split_datas), K_(tablet_status_tablet_ids), K_(tablet_status), K_(tablet_status_data_type), K_(set_freeze_flag_tablet_ids)); + +private: + static bool is_split_data_table(const share::schema::ObTableSchema &table_schema); + template + static int foreach_part(const share::schema::ObTableSchema &table_schema, const int64_t part_type_filter, F &&op); + int get_partkey_projector( + const share::schema::ObTableSchema &data_table_schema, + const share::schema::ObTableSchema &table_schema, + ObIArray &partkey_projector); + +public: + uint64_t tenant_id_; + share::ObLSID ls_id_; + ObSArray split_data_tablet_ids_; + ObSArray split_datas_; + ObSArray tablet_status_tablet_ids_; + ObTabletStatus tablet_status_; + ObTabletMdsUserDataType tablet_status_data_type_; + ObSArray set_freeze_flag_tablet_ids_; // set transfer freeze flag on replay +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitMdsArg); +}; + +class ObTabletSplitMdsArgPrepareSrcOp final +{ +public: + ObTabletSplitMdsArgPrepareSrcOp(ObIArray &src_tablet_ids, ObIArray> &dst_tablet_ids) + : src_tablet_ids_(src_tablet_ids), dst_tablet_ids_(dst_tablet_ids) {} + ~ObTabletSplitMdsArgPrepareSrcOp() = default; + int operator()(const int64_t part_idx, ObBasePartition &part); +private: + ObIArray &src_tablet_ids_; + ObIArray> &dst_tablet_ids_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitMdsArgPrepareSrcOp); +}; + +class ObTabletSplitMdsArgPrepareDstOp final +{ +public: + ObTabletSplitMdsArgPrepareDstOp(const bool is_data_table, ObIArray &dst_tablet_ids, ObIArray &dst_high_bound_vals) + : is_data_table_(is_data_table), dst_tablet_ids_(dst_tablet_ids), dst_high_bound_vals_(dst_high_bound_vals) {} + ~ObTabletSplitMdsArgPrepareDstOp() = default; + int operator()(const int64_t part_idx, ObBasePartition &part); +private: + bool is_data_table_; + ObIArray &dst_tablet_ids_; + ObIArray &dst_high_bound_vals_; +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitMdsArgPrepareDstOp); +}; + +struct ObModifyAutoPartSizeOp final +{ + ObModifyAutoPartSizeOp(const int64_t auto_part_size) : auto_part_size_(auto_part_size) {} + ~ObModifyAutoPartSizeOp() = default; + int operator()(ObTabletSplitMdsUserData &data); + int64_t auto_part_size_; +}; + +class ObTabletSplitMdsHelper +{ +public: + static int on_register(const char* buf, const int64_t len, mds::BufferCtx &ctx); + static int on_replay(const char* buf, const int64_t len, const share::SCN &scn, mds::BufferCtx &ctx); + static int register_mds(const ObTabletSplitMdsArg &arg, const bool need_flush_redo, ObMySQLTransaction &trans); + + static int set_auto_part_size_for_create( + const uint64_t tenant_id, + const obrpc::ObBatchCreateTabletArg &create_arg, + const ObIArray &auto_part_size_arr, + const int64_t abs_timeout_us, + ObMySQLTransaction &trans); + static int modify_auto_part_size( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const int64_t auto_part_size, + const int64_t abs_timeout_us, + ObMySQLTransaction &trans); + + static int batch_get_tablet_split( + const int64_t abs_timeout_us, + const obrpc::ObBatchGetTabletSplitArg &arg, + obrpc::ObBatchGetTabletSplitRes &res); + static int get_tablet_split_mds_by_rpc( + const uint64_t tenant_id, + const share::ObLSID &ls_id, + const ObIArray &tablet_ids, + const int64_t abs_timeout_us, + ObIArray &datas); + + static int get_is_spliting(ObTablet &tablet, bool &is_split_dst); + static int get_split_info(ObTablet &tablet, common::ObIAllocator &allocator, ObTabletSplitTscInfo &split_info); + static int prepare_calc_split_dst(ObLS &ls, ObTablet &tablet, const int64_t abs_timeout_us, ObTabletSplitMdsUserData &src_split_data, ObIArray &dst_split_datas); + static int calc_split_dst(ObLS &ls, ObTablet &tablet, const blocksstable::ObDatumRowkey &rowkey, const int64_t abs_timeout_us, ObTabletID &dst_tablet_id); + static int calc_split_dst_lob(ObLS &ls, ObTablet &tablet, const blocksstable::ObDatumRow &data_row, const int64_t abs_timeout_us, ObTabletID &dst_tablet_id); + +private: + template + static int modify_tablet_split_( + const uint64_t tenant_id, + const ObIArray &tablet_ids, + const int64_t abs_timeout_us, + F &&op, + ObMySQLTransaction &trans); + static int modify(const ObTabletSplitMdsArg &arg, const share::SCN &scn, mds::BufferCtx &ctx); + static int set_tablet_split_mds(const share::ObLSID &ls_id, const ObTabletID &tablet_id, const share::SCN &replay_scn, const ObTabletSplitMdsUserData &data, mds::BufferCtx &ctx); + static int set_freeze_flag(ObLS &ls, const ObTabletID &tablet_id, const share::SCN &replay_scn); + static int set_tablet_status( + ObLS &ls, + const ObTabletID &tablet_id, + const ObTabletStatus tablet_status, + const ObTabletMdsUserDataType data_type, + const share::SCN &replay_scn, + mds::BufferCtx &ctx); +}; + +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_SPLIT_MDS_HELPER diff --git a/src/storage/tablet/ob_tablet_split_mds_user_data.cpp b/src/storage/tablet/ob_tablet_split_mds_user_data.cpp new file mode 100644 index 000000000..0a03e3aad --- /dev/null +++ b/src/storage/tablet/ob_tablet_split_mds_user_data.cpp @@ -0,0 +1,518 @@ +/** + * 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 "storage/tablet/ob_tablet_split_mds_user_data.h" + +#include "storage/access/ob_table_read_info.h" +#include "storage/blocksstable/ob_datum_row.h" +#include "storage/ls/ob_ls_tablet_service.h" + +#define USING_LOG_PREFIX STORAGE + +using namespace oceanbase::share; +using oceanbase::blocksstable::ObDatumRowkey; +using oceanbase::blocksstable::ObStorageDatum; +using oceanbase::blocksstable::ObStorageDatumUtils; +using oceanbase::blocksstable::ObStoreCmpFuncs; + +namespace oceanbase +{ +namespace storage +{ + +void ObTabletSplitMdsUserData::reset() +{ + auto_part_size_ = OB_INVALID_SIZE; + status_ = NO_SPLIT; + ref_tablet_ids_.reset(); + partkey_projector_.reset(); + end_partkey_.reset(); + storage_schema_.reset(); + allocator_.reset(); + return; +} + +int ObTabletSplitMdsUserData::assign(const ObTabletSplitMdsUserData &other) +{ + int ret = OB_SUCCESS; + reset(); + if (OB_FAIL(ref_tablet_ids_.assign(other.ref_tablet_ids_))) { + LOG_WARN("failed to assign ref tablet ids", K(ret)); + } else if (0 != other.end_partkey_.get_datum_cnt() && OB_FAIL(other.end_partkey_.deep_copy(end_partkey_, allocator_))) { + LOG_WARN("failed to write rowkey", K(ret)); + } else if (OB_FAIL(partkey_projector_.assign(other.partkey_projector_))) { + LOG_WARN("failed to assign partkey projector", K(ret)); + } else if (other.storage_schema_.is_valid() && OB_FAIL(storage_schema_.assign(allocator_, other.storage_schema_))) { + LOG_WARN("failed to assign storage schema", K(ret)); + } else { + auto_part_size_ = other.auto_part_size_; + status_ = other.status_; + } + return ret; +} + +int ObTabletSplitMdsUserData::init_no_split(const int64_t auto_part_size) +{ + int ret = OB_SUCCESS; + reset(); + auto_part_size_ = auto_part_size; + return ret; +} + +int ObTabletSplitMdsUserData::init_range_part_split_src( + const ObIArray &dst_tablet_ids, + const ObIArray &partkey_projector, + const ObTableSchema &table_schema, + const bool is_oracle_mode) +{ + int ret = OB_SUCCESS; + reset(); + auto_part_size_ = OB_INVALID_SIZE; // split src tablet can no longer auto split + status_ = RANGE_PART_SPLIT_SRC; + const lib::Worker::CompatMode compat_mode = is_oracle_mode ? lib::Worker::CompatMode::ORACLE : lib::Worker::CompatMode::MYSQL; + if (OB_FAIL(ref_tablet_ids_.assign(dst_tablet_ids))) { + LOG_WARN("failed to assign ref tablet ids", K(ret)); + } else if (OB_FAIL(partkey_projector_.assign(partkey_projector))) { + LOG_WARN("failed to assign partkey projector", K(ret)); + } else if (OB_FAIL(storage_schema_.init(allocator_, table_schema, compat_mode, false/*skip_column_info*/))) { + LOG_WARN("failed to assign partkey projector", K(ret)); + } + return ret; +} + +int ObTabletSplitMdsUserData::init_range_part_split_dst( + const int64_t auto_part_size, + const ObTabletID &src_tablet_id, + const ObDatumRowkey &end_partkey) +{ + int ret = OB_SUCCESS; + reset(); + auto_part_size_ = auto_part_size; + status_ = RANGE_PART_SPLIT_DST; + if (OB_FAIL(ref_tablet_ids_.push_back(src_tablet_id))) { + LOG_WARN("failed to assign ref tablet ids", K(ret)); + } else if (end_partkey.get_datum_cnt() > 0 && OB_FAIL(end_partkey.deep_copy(end_partkey_, allocator_))) { + LOG_WARN("failed to write rowkey", K(ret)); + } + return ret; +} + +int ObTabletSplitMdsUserData::modify_auto_part_size(const int64_t auto_part_size) +{ + int ret = OB_SUCCESS; + auto_part_size_ = auto_part_size; + return ret; +} + +int ObTabletSplitMdsUserData::get_auto_part_size(int64_t &auto_part_size) const +{ + int ret = OB_SUCCESS; + auto_part_size = auto_part_size_; + return ret; +} + +int ObTabletSplitMdsUserData::calc_split_dst(ObLS &ls, const ObDatumRowkey &rowkey, const int64_t abs_timeout_us, ObTabletID &dst_tablet_id) const +{ + int ret = OB_SUCCESS; + dst_tablet_id.reset(); + if (RANGE_PART_SPLIT_SRC == status_) { + int64_t left_boundary = 0; + int64_t right_boundary = ref_tablet_ids_.count() - 1; + int64_t dst_tablet_id_loc = ref_tablet_ids_.count(); + while (OB_SUCC(ret) && left_boundary <= right_boundary) { + int64_t middle_loc = (left_boundary + right_boundary) / 2; + const ObTabletID &tablet_id = ref_tablet_ids_.at(middle_loc); + ObTabletHandle tablet_handle; + int cmp_ret = 0; + if (OB_FAIL(ls.get_tablet_with_timeout(tablet_id, tablet_handle, abs_timeout_us))) { + LOG_WARN("failed to get split dst tablet", K(ret)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::split_partkey_compare( + rowkey, tablet_handle.get_obj()->get_rowkey_read_info(), partkey_projector_, cmp_ret, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to part key compare", K(ret)); + if (OB_NOT_SUPPORTED == ret) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("no longer split dst, retry", K(ret), K(tablet_id)); + } + } else if (cmp_ret > 0) { // dst partition high bound > rowkey's partkey + right_boundary = middle_loc - 1; + dst_tablet_id_loc = middle_loc; + } else { + left_boundary = middle_loc + 1; + } + } + if (OB_SUCC(ret) && 0 <= dst_tablet_id_loc && dst_tablet_id_loc < ref_tablet_ids_.count()) { + dst_tablet_id = ref_tablet_ids_.at(dst_tablet_id_loc); + } + if (OB_FAIL(ret)) { + LOG_WARN("fail to get dst_tablet_id", K(ret), K(dst_tablet_id_loc), K(dst_tablet_id)); + } else if (OB_UNLIKELY(!dst_tablet_id.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rowkey not in any split dst tablet", K(ret), K(ls.get_ls_id()), K(rowkey), K(*this)); + print_ref_tablets_split_data(ls); + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +// TODO(lihongqin.lhq): optimize by binary search +// caller guarantee dst_split_datas.is_split_dst() == true +int ObTabletSplitMdsUserData::calc_split_dst( + const ObITableReadInfo &rowkey_read_info, + const ObIArray &dst_split_datas, + const ObDatumRowkey &rowkey, + ObTabletID &dst_tablet_id, + int64_t &dst_idx) const +{ + int ret = OB_SUCCESS; + dst_tablet_id.reset(); + if (RANGE_PART_SPLIT_SRC == status_) { + if (OB_UNLIKELY(dst_split_datas.count() != ref_tablet_ids_.count())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid dst split datas", K(ret), K(*this), K(dst_split_datas)); + } + for (int64_t i = 0; OB_SUCC(ret) && !dst_tablet_id.is_valid() && i < ref_tablet_ids_.count(); i++) { + const ObTabletID &tablet_id = ref_tablet_ids_.at(i); + ObTabletHandle tablet_handle; + int cmp_ret = 0; + if (OB_FAIL(dst_split_datas.at(i).partkey_compare(rowkey, rowkey_read_info, partkey_projector_, cmp_ret))) { + LOG_WARN("failed to part key compare", K(ret)); + } else if (cmp_ret > 0) { // dst partition high bound > rowkey's partkey + dst_tablet_id = tablet_id; + dst_idx = i; + } + } + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(!dst_tablet_id.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("rowkey not in any split dst tablet", K(ret), K(rowkey), K(*this), K(dst_split_datas)); + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +int ObTabletSplitMdsUserData::get_split_dst_tablet_ids(ObIArray &dst_tablet_ids) const +{ + int ret = OB_SUCCESS; + if (RANGE_PART_SPLIT_SRC == status_) { + if (OB_FAIL(dst_tablet_ids.assign(ref_tablet_ids_))) { + LOG_WARN("failed to assign", K(ret)); + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +int ObTabletSplitMdsUserData::get_split_dst_tablet_cnt(int64_t &split_cnt) const +{ + int ret = OB_SUCCESS; + if (RANGE_PART_SPLIT_SRC == status_) { + split_cnt = ref_tablet_ids_.count(); + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +int ObTabletSplitMdsUserData::get_storage_schema(const ObStorageSchema *&storage_schema) const +{ + int ret = OB_SUCCESS; + if (RANGE_PART_SPLIT_SRC == status_) { + storage_schema = &storage_schema_; + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +int ObTabletSplitMdsUserData::partkey_compare( + const ObDatumRowkey &rowkey, + const ObITableReadInfo &rowkey_read_info, + const ObIArray &partkey_projector, + int &cmp_ret) const +{ + int ret = OB_SUCCESS; + const ObStorageDatumUtils &datum_utils = rowkey_read_info.get_datum_utils(); + const ObStoreCmpFuncs &cmp_funcs = datum_utils.get_cmp_funcs(); + cmp_ret = 0; + if (RANGE_PART_SPLIT_DST == status_) { + for (int64_t i = 0; OB_SUCC(ret) && i < partkey_projector.count() && 0 == cmp_ret; i++) { + int64_t col_idx = partkey_projector.at(i); + if (OB_UNLIKELY(col_idx >= cmp_funcs.count() || col_idx >= rowkey.get_datum_cnt())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid cmp func cnt or rowkey cnt", K(ret), K(i), K(*this), K(rowkey), K(cmp_funcs)); + } else if (OB_FAIL(cmp_funcs.at(col_idx).compare(end_partkey_.datums_[i], rowkey.datums_[col_idx], cmp_ret))) { + LOG_WARN("Failed to compare datum rowkey", K(ret), K(i), K(*this), K(rowkey)); + } + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +int ObTabletSplitMdsUserData::get_split_src_tablet_id(ObTabletID &tablet_id) const +{ + int ret = OB_SUCCESS; + tablet_id.reset(); + if (RANGE_PART_SPLIT_DST == status_) { + if (OB_UNLIKELY(ref_tablet_ids_.count() != 1)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid status", K(ret), K(*this)); + } else { + tablet_id = ref_tablet_ids_[0]; + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +int ObTabletSplitMdsUserData::get_split_src_tablet(ObLS &ls, ObTabletHandle &src_tablet_handle) const +{ + int ret = OB_SUCCESS; + ObTabletID src_tablet_id; + src_tablet_handle.reset(); + if (OB_FAIL(get_split_src_tablet_id(src_tablet_id))) { + LOG_WARN("failed to get split src tablet id", K(ret)); + } else if (OB_FAIL(ls.get_tablet(src_tablet_id, src_tablet_handle, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US, + ObMDSGetTabletMode::READ_ALL_COMMITED))) { + LOG_WARN("failed to get tablet", K(ret), K(src_tablet_id), K(ls.get_ls_id())); + } else if (OB_ISNULL(src_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet", K(ret), K(ls.get_ls_id()), K(src_tablet_id)); + } + return ret; +} + +int ObTabletSplitMdsUserData::get_end_partkey(ObDatumRowkey &end_partkey) +{ + int ret = OB_SUCCESS; + end_partkey.reset(); + if (RANGE_PART_SPLIT_DST == status_) { + if (OB_UNLIKELY(!end_partkey_.is_valid())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid end partkey, maybe not a split dst data/local index tablet", K(ret), KPC(this)); + } else if (OB_FAIL(end_partkey.assign(end_partkey_.datums_, end_partkey_.datum_cnt_))) { + LOG_WARN("failed to assign partkey", K(ret)); + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +int ObTabletSplitMdsUserData::get_tsc_split_info( + const ObTabletID &tablet_id, + ObLS &ls, + const int64_t abs_timeout_us, + ObIAllocator &allocator, + ObTabletSplitTscInfo &split_info) +{ + int ret = OB_SUCCESS; + split_info.reset(); + if (RANGE_PART_SPLIT_DST == status_) { + ObTabletSplitMdsUserData src_data; + if (OB_FAIL(get_split_src_tablet(ls, split_info.src_tablet_handle_))) { + LOG_WARN("failed to get src tablet handle", K(ret)); + } else if (OB_FAIL(split_info.src_tablet_handle_.get_obj()->ObITabletMdsInterface::get_split_data(src_data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get split data", K(ret)); + } else { + split_info.split_cnt_ = src_data.ref_tablet_ids_.count(); + } + + if (OB_SUCC(ret) && 0 != end_partkey_.get_datum_cnt()) { // split dst lob tablet has no partkey + if (OB_FAIL(end_partkey_.deep_copy(split_info.end_partkey_, allocator))) { + LOG_WARN("failed to deep copy", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < src_data.ref_tablet_ids_.count(); i++) { + if (tablet_id == src_data.ref_tablet_ids_.at(i)) { + if (i == 0) { + split_info.start_partkey_.set_min_rowkey(); + } else { + ObTabletHandle prev_dst_tablet_handle; + ObTabletSplitMdsUserData prev_dst_data; + ObTabletID prev_dst_tablet_id = src_data.ref_tablet_ids_.at(i-1); + if (OB_FAIL(ls.get_tablet(prev_dst_tablet_id, prev_dst_tablet_handle))) { + LOG_WARN("failed to get tablet", K(ret)); + } else if (OB_ISNULL(prev_dst_tablet_handle.get_obj())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid tablet", K(ret)); + } else if (OB_FAIL(prev_dst_tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(prev_dst_data, abs_timeout_us - ObTimeUtility::current_time()))) { + LOG_WARN("failed to get split data", K(ret)); + } else if (OB_UNLIKELY(!prev_dst_data.is_split_dst())) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("dst tablet is no longer split dst, retry", K(ret), K(tablet_id), K(prev_dst_tablet_id)); + } else if (OB_FAIL(prev_dst_data.end_partkey_.deep_copy(split_info.start_partkey_, allocator))) { + LOG_WARN("failed to deep copy", K(ret), K(i), K(src_data), K(prev_dst_data)); + } + } + break; + } + } + + const int64_t partkey_cnt = src_data.partkey_projector_.count(); + if (OB_FAIL(ret)) { + } else if (split_info.start_partkey_.is_min_rowkey() && OB_FAIL(fill_min_max_datums(partkey_cnt, allocator, split_info.start_partkey_))) { + LOG_WARN("failed to fill min max datums", K(ret), K(split_info)); + } else if (split_info.end_partkey_.is_max_rowkey() && OB_FAIL(fill_min_max_datums(partkey_cnt, allocator, split_info.end_partkey_))) { + LOG_WARN("failed to fill min max datums", K(ret), K(split_info)); + } else if (OB_UNLIKELY(!split_info.start_partkey_.is_valid() + || split_info.start_partkey_.get_datum_cnt() != partkey_cnt + || split_info.end_partkey_.get_datum_cnt() != partkey_cnt)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid split info", K(ret), K(tablet_id), K(partkey_cnt), K(src_data), K(split_info)); + } + } + + if (OB_SUCC(ret)) { + bool is_prefix = true; + for (int64_t i = 0; is_prefix && i < src_data.partkey_projector_.count(); i++) { + if (src_data.partkey_projector_[i] != i) { + is_prefix = false; + } + } + split_info.partkey_is_rowkey_prefix_ = is_prefix; + split_info.split_type_ = ObTabletSplitType::RANGE; + } + } else { + ret = OB_NOT_SUPPORTED; + LOG_WARN("not supported such op", K(ret), KPC(this)); + } + return ret; +} + +int ObTabletSplitMdsUserData::fill_min_max_datums(const int64_t datum_cnt, ObIAllocator &allocator, ObDatumRowkey &partkey) +{ + int ret = OB_SUCCESS; + ObStorageDatum *datums = nullptr; + if (OB_UNLIKELY(!partkey.is_min_rowkey() && !partkey.is_max_rowkey())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("not min or max rowkey", K(ret), K(partkey)); + } else if (OB_ISNULL(datums = (ObStorageDatum *)allocator.alloc(sizeof(ObStorageDatum) * datum_cnt))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to alloc", K(ret), K(datum_cnt)); + } else { + datums = new (datums) ObStorageDatum[datum_cnt]; + for (int64_t i = 0; i < datum_cnt; ++ i) { + if (partkey.is_min_rowkey()) { + datums[i].set_min(); + } else { + datums[i].set_max(); + } + } + if (OB_FAIL(partkey.assign(datums, datum_cnt))) { + LOG_WARN("failed to assign datum rowkey", K(ret), KP(datums), K(datum_cnt)); + } + } + return ret; +} + +void ObTabletSplitMdsUserData::print_ref_tablets_split_data(ObLS &ls) const +{ + int ret = OB_SUCCESS; + ObTabletHandle tablet_handle; + ObTabletSplitMdsUserData data; + for (int64_t i = 0; i < ref_tablet_ids_.count(); i++) { // overwrite ret + const ObTabletID &tablet_id = ref_tablet_ids_.at(i); + if (OB_FAIL(ls.get_tablet(tablet_id, tablet_handle))) { + LOG_WARN("failed to get split dst tablet", K(ret), K(tablet_id)); + } else if (OB_FAIL(tablet_handle.get_obj()->ObITabletMdsInterface::get_split_data(data, ObTabletCommon::DEFAULT_GET_TABLET_DURATION_10_S))) { + LOG_WARN("failed to get split data", K(ret)); + } else { + LOG_WARN("dst split info", K(ret), K(tablet_id), K(data)); + } + } + return; +} + +OB_DEF_SERIALIZE(ObTabletSplitMdsUserData) +{ + int ret = OB_SUCCESS; + const bool storage_schema_is_valid = storage_schema_.is_valid(); + LST_DO_CODE(OB_UNIS_ENCODE, auto_part_size_, status_, ref_tablet_ids_, partkey_projector_); + OB_UNIS_ENCODE_ARRAY(end_partkey_.datums_, end_partkey_.datum_cnt_); + LST_DO_CODE(OB_UNIS_ENCODE, storage_schema_is_valid); + if (OB_SUCC(ret) && storage_schema_is_valid) { + LST_DO_CODE(OB_UNIS_ENCODE, storage_schema_); + } + return ret; +} + +OB_DEF_DESERIALIZE(ObTabletSplitMdsUserData) +{ + int ret = OB_SUCCESS; + LST_DO_CODE(OB_UNIS_DECODE, auto_part_size_, status_, ref_tablet_ids_, partkey_projector_); + + int64_t datum_cnt = 0; + OB_UNIS_DECODE(datum_cnt); + if (OB_FAIL(ret)) { + } else if (OB_UNLIKELY(datum_cnt < 0)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("invalid datum cnt", K(ret), K(datum_cnt)); + } else if (datum_cnt == 0) { + end_partkey_.reset(); + } else if (datum_cnt > 0) { + void *datum_buf = nullptr; + if (OB_ISNULL(datum_buf = allocator_.alloc(sizeof(ObStorageDatum) * datum_cnt))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + STORAGE_LOG(WARN, "failed to alloc memory", K(ret), K(datum_cnt)); + } else { + ObStorageDatum *datums = new (datum_buf) ObStorageDatum[datum_cnt]; + OB_UNIS_DECODE_ARRAY(datums, datum_cnt); + if (OB_SUCC(ret) && OB_FAIL(end_partkey_.assign(datums, datum_cnt))) { + LOG_WARN("failed to assign", K(ret)); + } + } + } + + bool storage_schema_is_valid = false; + OB_UNIS_DECODE(storage_schema_is_valid); + if (OB_SUCC(ret) && pos < data_len) { + if (storage_schema_is_valid) { + if (OB_FAIL(storage_schema_.deserialize(allocator_, buf, data_len, pos))) { + LOG_WARN("failed to deserialize storage schema", K(ret)); + } + } else { + storage_schema_.reset(); + } + } + return ret; +} + +OB_DEF_SERIALIZE_SIZE(ObTabletSplitMdsUserData) +{ + int64_t len = 0; + const bool storage_schema_is_valid = storage_schema_.is_valid(); + LST_DO_CODE(OB_UNIS_ADD_LEN, auto_part_size_, status_, ref_tablet_ids_, partkey_projector_); + OB_UNIS_ADD_LEN_ARRAY(end_partkey_.datums_, end_partkey_.datum_cnt_); + LST_DO_CODE(OB_UNIS_ADD_LEN, storage_schema_is_valid); + if (storage_schema_is_valid) { + LST_DO_CODE(OB_UNIS_ADD_LEN, storage_schema_); + } + return len; +} + +} // namespace storage +} // namespace oceanbase diff --git a/src/storage/tablet/ob_tablet_split_mds_user_data.h b/src/storage/tablet/ob_tablet_split_mds_user_data.h new file mode 100644 index 000000000..0abb001f1 --- /dev/null +++ b/src/storage/tablet/ob_tablet_split_mds_user_data.h @@ -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. + */ + +#ifndef OCEANBASE_STORAGE_OB_TABLET_SPLIT_MDS_USER_DATA +#define OCEANBASE_STORAGE_OB_TABLET_SPLIT_MDS_USER_DATA + +#include +#include "lib/container/ob_se_array.h" +#include "lib/utility/ob_print_utils.h" +#include "share/scn.h" +#include "common/ob_tablet_id.h" +#include "storage/blocksstable/ob_datum_rowkey.h" + +namespace oceanbase +{ +namespace common +{ +class ObIAllocator; +} + +namespace share +{ +namespace schema +{ +class ObTableSchema; +} +} + +namespace storage +{ +class ObITableReadInfo; +class ObLS; +class ObTabletHandle; +struct ObTabletSplitTscInfo; +class ObStorageSchema; + +enum ObTabletSplitStatus { + NO_SPLIT = 0, + RANGE_PART_SPLIT_SRC, + RANGE_PART_SPLIT_DST +}; + +class ObTabletSplitMdsUserData +{ +public: + OB_UNIS_VERSION_V(1); + +public: + ObTabletSplitMdsUserData() : allocator_(), auto_part_size_(OB_INVALID_SIZE), status_(NO_SPLIT), ref_tablet_ids_(), partkey_projector_(), end_partkey_(), storage_schema_() { } + virtual ~ObTabletSplitMdsUserData() { reset(); } + void reset(); + int assign(const ObTabletSplitMdsUserData &other); + int init_no_split(const int64_t auto_part_size); + int init_range_part_split_src(const ObIArray &dst_tablet_ids, const ObIArray &partkey_projector, const share::schema::ObTableSchema &table_schema, const bool is_oracle_mode); + int init_range_part_split_dst(const int64_t auto_part_size, const ObTabletID &src_tablet_id, const blocksstable::ObDatumRowkey &end_partkey); + int modify_auto_part_size(const int64_t auto_part_size); + bool is_split_src() const { return status_ == RANGE_PART_SPLIT_SRC; } + bool is_split_dst() const { return status_ == RANGE_PART_SPLIT_DST; } + + // for data tablets and global local tablets, other tablets are likely to return OB_INVALID_SIZE + int get_auto_part_size(int64_t &auto_part_size) const; + + // for split src data tablet + int calc_split_dst(ObLS &ls, const blocksstable::ObDatumRowkey &rowkey, const int64_t abs_timeout_us, ObTabletID &dst_tablet_id) const; + int calc_split_dst( + const ObITableReadInfo &rowkey_read_info, + const ObIArray &dst_split_datas, + const blocksstable::ObDatumRowkey &rowkey, + ObTabletID &dst_tablet_id, + int64_t &dst_idx) const; + + // for split src data/lob/local index tablet + int get_split_dst_tablet_ids(ObIArray &dst_tablet_ids) const; + int get_split_dst_tablet_cnt(int64_t &split_cnt) const; + int get_storage_schema(const ObStorageSchema *&storage_schema) const; + + // for split dst data/lob/local index tablet + int get_split_src_tablet_id(ObTabletID &tablet_id) const; + int get_split_src_tablet(ObLS &ls, ObTabletHandle &src_tablet_handle) const; + + // for split dst data tablet, return a shallow copy end_partkey + int get_end_partkey(blocksstable::ObDatumRowkey &end_partkey); + + // for split dst data tablet + int partkey_compare(const blocksstable::ObDatumRowkey &rowkey, const ObITableReadInfo &rowkey_read_info, const ObIArray &partkey_projector, int &cmp_ret) const; + + // for split dst data/local index tablet + int get_tsc_split_info( + const ObTabletID &tablet_id, + ObLS &ls, + const int64_t abs_timeout_us, + ObIAllocator &allocator, + ObTabletSplitTscInfo &split_info); + + TO_STRING_KV(K_(auto_part_size), K_(status), K_(ref_tablet_ids), K_(partkey_projector), K_(end_partkey)); + +private: + static int fill_min_max_datums(const int64_t datum_cnt, ObIAllocator &allocator, blocksstable::ObDatumRowkey &partkey); + void print_ref_tablets_split_data(ObLS &ls) const; + +private: + ObArenaAllocator allocator_; + int64_t auto_part_size_; + uint64_t status_; + ObSEArray ref_tablet_ids_; + ObSArray partkey_projector_; // rowkey[partkey_projector_[i]] = ith part key + blocksstable::ObDatumRowkey end_partkey_; // part key high bound of dst tablet, it's max for the rightmost tablet + ObStorageSchema storage_schema_; // generated by table schema of split start, only valid for split src +private: + DISALLOW_COPY_AND_ASSIGN(ObTabletSplitMdsUserData); +}; + +struct ReadSplitDataAutoPartSizeOp +{ + ReadSplitDataAutoPartSizeOp(int64_t &auto_part_size) : auto_part_size_(auto_part_size) {} + int operator()(const ObTabletSplitMdsUserData &data) + { + return data.get_auto_part_size(auto_part_size_); + } + int64_t &auto_part_size_; +}; + +} // namespace storage +} // namespace oceanbase + +#endif // OCEANBASE_STORAGE_OB_TABLET_SPLIT_MDS_USER_DATA diff --git a/src/storage/tablet/ob_tablet_split_replay_executor.cpp b/src/storage/tablet/ob_tablet_split_replay_executor.cpp new file mode 100644 index 000000000..26ca172a8 --- /dev/null +++ b/src/storage/tablet/ob_tablet_split_replay_executor.cpp @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2023 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#include "storage/tablet/ob_tablet_split_replay_executor.h" +#include "storage/multi_data_source/mds_ctx.h" + +#define USING_LOG_PREFIX STORAGE + +namespace oceanbase +{ +namespace storage +{ + +int ObTabletSplitReplayExecutor::init(mds::BufferCtx &user_ctx, const share::SCN &scn, const ObTabletSplitMdsUserData &data) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + TRANS_LOG(WARN, "tablet binding replay executor init twice", KR(ret), K_(is_inited)); + } else if (OB_UNLIKELY(!scn.is_valid())) { + ret = OB_INVALID_ARGUMENT; + TRANS_LOG(WARN, "get invalid argument", KR(ret), K(scn)); + } else { + user_ctx_ = &user_ctx; + scn_ = scn; + data_ = &data; + is_inited_ = true; + } + return ret; +} + +int ObTabletSplitReplayExecutor::do_replay_(ObTabletHandle &tablet_handle) +{ + int ret = OB_SUCCESS; + mds::MdsCtx &user_ctx = static_cast(*user_ctx_); + if (OB_FAIL(replay_to_mds_table_(tablet_handle, *data_, user_ctx, scn_))) { + TRANS_LOG(WARN, "failed to replay to tablet", K(ret)); + } + return ret; +} + +} +} diff --git a/src/storage/tablet/ob_tablet_split_replay_executor.h b/src/storage/tablet/ob_tablet_split_replay_executor.h new file mode 100644 index 000000000..d05d6bf9c --- /dev/null +++ b/src/storage/tablet/ob_tablet_split_replay_executor.h @@ -0,0 +1,55 @@ +/** + * Copyright (c) 2023 OceanBase + * OceanBase CE is licensed under Mulan PubL v2. + * You can use this software according to the terms and conditions of the Mulan PubL v2. + * You may obtain a copy of Mulan PubL v2 at: + * http://license.coscl.org.cn/MulanPubL-2.0 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PubL v2 for more details. + */ + +#ifndef OCEANBASE_STORAGE_OB_TABLET_SPLIT_REPLAY_EXECUTOR +#define OCEANBASE_STORAGE_OB_TABLET_SPLIT_REPLAY_EXECUTOR + +#include "common/ob_tablet_id.h" +#include "logservice/replayservice/ob_tablet_replay_executor.h" +#include "storage/tablet/ob_tablet_split_mds_user_data.h" + +namespace oceanbase +{ +namespace storage +{ + +class ObTabletSplitReplayExecutor final : public logservice::ObTabletReplayExecutor +{ +public: + ObTabletSplitReplayExecutor() + : logservice::ObTabletReplayExecutor(), user_ctx_(nullptr), scn_(), data_(nullptr) {} + + int init(mds::BufferCtx &user_ctx, const share::SCN &scn, const ObTabletSplitMdsUserData &data); + +protected: + bool is_replay_update_tablet_status_() const override + { + return true; + } + + int do_replay_(ObTabletHandle &tablet_handle) override; + + virtual bool is_replay_update_mds_table_() const override + { + return true; + } + +private: + mds::BufferCtx *user_ctx_; + share::SCN scn_; + const ObTabletSplitMdsUserData *data_; +}; + +} +} + +#endif diff --git a/src/storage/tablet/ob_tablet_status.cpp b/src/storage/tablet/ob_tablet_status.cpp index 5b86c0627..f9f41fdb5 100644 --- a/src/storage/tablet/ob_tablet_status.cpp +++ b/src/storage/tablet/ob_tablet_status.cpp @@ -44,6 +44,20 @@ const char *ObTabletStatus::get_str(const ObTabletStatus &status) return str; } +bool ObTabletStatus::is_deleted_for_gc() const +{ + return ObTabletStatus::DELETED == status_ + || ObTabletStatus::TRANSFER_OUT_DELETED == status_ + || ObTabletStatus::SPLIT_SRC_DELETED == status_; +} + +bool ObTabletStatus::is_writable_for_dml() const +{ + return ObTabletStatus::NORMAL == status_ + || ObTabletStatus::TRANSFER_IN == status_ + || ObTabletStatus::SPLIT_DST == status_; +} + int ObTabletStatus::serialize(char *buf, const int64_t len, int64_t &pos) const { int ret = OB_SUCCESS; diff --git a/src/storage/tablet/ob_tablet_status.h b/src/storage/tablet/ob_tablet_status.h index 34e0c687e..8f31ede1a 100644 --- a/src/storage/tablet/ob_tablet_status.h +++ b/src/storage/tablet/ob_tablet_status.h @@ -53,6 +53,9 @@ public: Status &get_status() { return status_; } const Status &get_status() const { return status_; } + bool is_deleted_for_gc() const; + bool is_writable_for_dml() const; + int serialize(char *buf, const int64_t len, int64_t &pos) const; int deserialize(const char *buf, const int64_t len, int64_t &pos); int64_t get_serialize_size() const; diff --git a/src/storage/tablet/ob_tablet_table_store.cpp b/src/storage/tablet/ob_tablet_table_store.cpp index 4d4565d30..29fc643b9 100644 --- a/src/storage/tablet/ob_tablet_table_store.cpp +++ b/src/storage/tablet/ob_tablet_table_store.cpp @@ -814,17 +814,18 @@ int ObTabletTableStore::calculate_read_tables( const int64_t snapshot_version, const ObTablet &tablet, ObTableStoreIterator &iterator, - const bool allow_no_ready_read) const + const bool allow_no_ready_read, + const bool skip_major) const { int ret = OB_SUCCESS; const ObSSTable *base_table = nullptr; - if (!meta_major_tables_.empty() && meta_major_tables_.at(0)->get_snapshot_version() < snapshot_version) { + if (!skip_major && !meta_major_tables_.empty() && meta_major_tables_.at(0)->get_snapshot_version() < snapshot_version) { base_table = meta_major_tables_.at(0); if (OB_FAIL(iterator.add_table(meta_major_tables_.at(0)))) { LOG_WARN("failed to add meta major table to iterator", K(ret), K(meta_major_tables_)); } - } else if (!is_major_sstable_empty(tablet.get_tablet_meta().ddl_commit_scn_)) { + } else if (!skip_major && !is_major_sstable_empty(tablet.get_tablet_meta().ddl_commit_scn_)) { if (!major_tables_.empty()) { for (int64_t i = major_tables_.count() - 1; OB_SUCC(ret) && i >= 0; --i) { if (major_tables_[i]->get_snapshot_version() <= snapshot_version) { @@ -1065,9 +1066,22 @@ int ObTabletTableStore::get_read_tables( const int64_t snapshot_version, const ObTablet &tablet, ObTableStoreIterator &iterator, - const bool allow_no_ready_read) const + const ObGetReadTablesMode mode) const { int ret = OB_SUCCESS; + bool allow_no_ready_read = false; + bool skip_major = false; + if (OB_LIKELY(ObGetReadTablesMode::NORMAL == mode)) { + allow_no_ready_read = false; + skip_major = false; + } else if (ObGetReadTablesMode::ALLOW_NO_READY_READ == mode) { + allow_no_ready_read = true; + skip_major = false; + } else if (ObGetReadTablesMode::SKIP_MAJOR == mode) { + allow_no_ready_read = true; + skip_major = true; + } + common::SpinRLockGuard guard(memtables_lock_); if (OB_UNLIKELY(snapshot_version < 0)) { ret = OB_INVALID_ARGUMENT; @@ -1085,7 +1099,7 @@ int ObTabletTableStore::get_read_tables( } else if (OB_UNLIKELY(!is_valid())) { ret = OB_ERR_SYS; LOG_WARN("table store not valid", K(ret), K(snapshot_version), K(*this)); - } else if (OB_FAIL(calculate_read_tables(snapshot_version, tablet, iterator, allow_no_ready_read))) { + } else if (OB_FAIL(calculate_read_tables(snapshot_version, tablet, iterator, allow_no_ready_read, skip_major))) { LOG_WARN("failed to get read tables", K(ret)); } if (OB_SUCC(ret)) { @@ -1614,7 +1628,6 @@ int ObTabletTableStore::build_minor_tables( ObITable *new_table = const_cast(static_cast(new_sstable)); //table can be null ObArray sstables; const ObSSTableArray &old_sstables = is_mds ? old_store.mds_sstables_ : old_store.minor_tables_; - ObSSTableArray &new_sstables = is_mds ? mds_sstables_ : minor_tables_; if (NULL == new_table || !is_table_valid_mds_or_minor_sstable(*new_table, is_mds)) { } else if (!new_table->get_key().scn_range_.is_valid() || @@ -1684,69 +1697,87 @@ int ObTabletTableStore::build_minor_tables( LOG_WARN("failed to add new minor table", K(ret), KPC(new_table)); } } + if (OB_SUCC(ret)) { + if (OB_FAIL(inner_process_minor_tables(allocator, + old_store, sstables, inc_base_snapshot_version, ha_status, upper_trans_param, is_mds))) { + LOG_WARN("inner process minor tables failed", K(ret)); + } + } + } + return ret; +} - if (OB_FAIL(ret)) { - } else if (sstables.empty()) { // no minor tables - } else if (OB_FAIL(ObTableStoreUtil::sort_minor_tables(sstables))) { - LOG_WARN("failed to sort minor tables", K(ret)); - } else if (is_mds && OB_FAIL(init_minor_sstable_array_with_check(new_sstables, allocator, sstables))) { - LOG_WARN("failed to init mds_tables", K(ret), K(is_mds)); - } else if (!is_mds) { - int64_t inc_pos = -1; - const int64_t minor_cnt = sstables.count(); - const ObIArray *new_upper_trans = upper_trans_param.new_upper_trans_; - const bool has_valid_update = new_upper_trans != nullptr - && minor_cnt == new_upper_trans->count() - && minor_cnt > 0 - && sstables.at(minor_cnt-1)->get_end_scn() == upper_trans_param.last_minor_end_scn_; - int64_t current_upper_trans_version = INT64_MAX; - if (!ha_status.check_allow_read()) { - inc_pos = 0; //in ha status do not recycle minor sstable - LOG_INFO("tablet in ha status, no need recycle minor sstable", K(ha_status)); - } else { - /* - * if the upper trans version of the ith sstable can't be calculated, the sstables with bigger end_scn can't be calculated either. - * new_upper_trans means the latest value of upper_trans_version for minor_tables. - * - * upper trans versions in old minors: - * --------- ascending by end_scn --------------> - * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | - * | val1 | val2 | val3 | MAX | MAX | MAX | MAX | - * new_upper_trans: - * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | - * | val1 | val2 | val3 | new1 | new2 | MAX | MAX | - */ - for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); ++i) { - current_upper_trans_version = has_valid_update ? new_upper_trans->at(i) : sstables.at(i)->get_upper_trans_version(); - if (current_upper_trans_version > inc_base_snapshot_version) { - inc_pos = i; - break; - } +int ObTabletTableStore::inner_process_minor_tables( + common::ObArenaAllocator &allocator, + const ObTabletTableStore &old_store, + ObArray &sstables, + const int64_t inc_base_snapshot_version, + const ObTabletHAStatus &ha_status, + const UpdateUpperTransParam &upper_trans_param, + const bool is_mds) +{ + int ret = OB_SUCCESS; + ObSSTableArray &new_sstables = is_mds ? mds_sstables_ : minor_tables_; + if (sstables.empty()) { // no minor tables + } else if (OB_FAIL(ObTableStoreUtil::sort_minor_tables(sstables))) { + LOG_WARN("failed to sort minor tables", K(ret)); + } else if (is_mds && OB_FAIL(init_minor_sstable_array_with_check(new_sstables, allocator, sstables))) { + LOG_WARN("failed to init mds_tables", K(ret), K(is_mds)); + } else if (!is_mds) { + int64_t inc_pos = -1; + const int64_t minor_cnt = sstables.count(); + const ObIArray *new_upper_trans = upper_trans_param.new_upper_trans_; + const bool has_valid_update = new_upper_trans != nullptr + && minor_cnt == new_upper_trans->count() + && minor_cnt > 0 + && sstables.at(minor_cnt-1)->get_end_scn() == upper_trans_param.last_minor_end_scn_; + int64_t current_upper_trans_version = INT64_MAX; + if (!ha_status.check_allow_read()) { + inc_pos = 0; //in ha status do not recycle minor sstable + LOG_INFO("tablet in ha status, no need recycle minor sstable", K(ha_status)); + } else { + /* + * if the upper trans version of the ith sstable can't be calculated, the sstables with bigger end_scn can't be calculated either. + * new_upper_trans means the latest value of upper_trans_version for minor_tables. + * + * upper trans versions in old minors: + * --------- ascending by end_scn --------------> + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | + * | val1 | val2 | val3 | MAX | MAX | MAX | MAX | + * new_upper_trans: + * | 0 | 1 | 2 | 3 | 4 | 5 | 6 | + * | val1 | val2 | val3 | new1 | new2 | MAX | MAX | + */ + for (int64_t i = 0; OB_SUCC(ret) && i < sstables.count(); ++i) { + current_upper_trans_version = has_valid_update ? new_upper_trans->at(i) : sstables.at(i)->get_upper_trans_version(); + if (current_upper_trans_version > inc_base_snapshot_version) { + inc_pos = i; + break; } } - if (OB_FAIL(ret) || inc_pos < 0) { - } else if (OB_FAIL(init_minor_sstable_array_with_check(new_sstables, allocator, sstables, inc_pos))) { - LOG_WARN("failed to init minor_tables", K(ret)); - } else if (ha_status.check_allow_read() && has_valid_update && new_sstables.count() > 0) { - // update upper_trans_version of new table store with latest value - for (int64_t i = 0; OB_SUCC(ret) && i < new_sstables.count(); ++i) { - ObSSTable *sstable = new_sstables[i]; - if (OB_ISNULL(sstable)) { - ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null sstable pointer", K(ret), K(i)); - } else if (INT64_MAX != sstable->get_upper_trans_version()) { - } else if (i+inc_pos >= new_upper_trans->count()) { - ret = OB_SIZE_OVERFLOW; - LOG_WARN("index of new_upper_trans overflow", K(ret), K(i), K(inc_pos), KPC(new_upper_trans)); - } else if (FALSE_IT(current_upper_trans_version = new_upper_trans->at(i+inc_pos))) { - } else if (INT64_MAX == current_upper_trans_version) { - break; - } else if (OB_FAIL(sstable->set_upper_trans_version(allocator, current_upper_trans_version))) { - LOG_WARN("failed to set new upper_trans_version", K(ret), K(i), KPC(sstable)); - } + } + if (OB_FAIL(ret) || inc_pos < 0) { + } else if (OB_FAIL(init_minor_sstable_array_with_check(new_sstables, allocator, sstables, inc_pos))) { + LOG_WARN("failed to init minor_tables", K(ret)); + } else if (ha_status.check_allow_read() && has_valid_update && new_sstables.count() > 0) { + // update upper_trans_version of new table store with latest value + for (int64_t i = 0; OB_SUCC(ret) && i < new_sstables.count(); ++i) { + ObSSTable *sstable = new_sstables[i]; + if (OB_ISNULL(sstable)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected null sstable pointer", K(ret), K(i)); + } else if (INT64_MAX != sstable->get_upper_trans_version()) { + } else if (i+inc_pos >= new_upper_trans->count()) { + ret = OB_SIZE_OVERFLOW; + LOG_WARN("index of new_upper_trans overflow", K(ret), K(i), K(inc_pos), KPC(new_upper_trans)); + } else if (FALSE_IT(current_upper_trans_version = new_upper_trans->at(i+inc_pos))) { + } else if (INT64_MAX == current_upper_trans_version) { + break; + } else if (OB_FAIL(sstable->set_upper_trans_version(allocator, current_upper_trans_version))) { + LOG_WARN("failed to set new upper_trans_version", K(ret), K(i), KPC(sstable)); } - LOG_INFO("Finish update upper_trans_version", K(ret), K(upper_trans_param), K(new_sstables)); } + LOG_INFO("Finish update upper_trans_version", K(ret), K(upper_trans_param), K(new_sstables)); } } return ret; @@ -2790,7 +2821,6 @@ int ObTabletTableStore::replace_ha_remote_mds_tables_( return ret; } - int ObTabletTableStore::cut_ha_sstable_scn_range_( common::ObArenaAllocator &allocator, common::ObIArray &orig_minor_sstables, @@ -3161,6 +3191,27 @@ int ObTabletTableStore::get_mini_minor_sstables_(ObTableStoreIterator &iter) con return ret; } +int ObTabletTableStore::build_split_new_table_store( + common::ObArenaAllocator &allocator, + ObTablet &tablet, + const ObBatchUpdateTableStoreParam ¶m, + const ObTabletTableStore &old_store) +{ + int ret = OB_SUCCESS; + if (IS_INIT) { + ret = OB_INIT_TWICE; + LOG_WARN("double init", K(ret)); + } else if (OB_UNLIKELY(!param.is_valid() || !old_store.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("init tablet table store get invalid argument", K(ret), K(tablet), K(param), K(old_store)); + } else if (OB_FAIL(init(allocator, tablet))) { + LOG_WARN("failed to init a new empty table store", K(ret)); + } else if (OB_FAIL(build_split_new_table_store_(allocator, tablet, param, old_store))) { + LOG_WARN("failed to build new table store with old store", K(ret)); + } + return ret; +} + template int ObTabletTableStore::init_minor_sstable_array_with_check( ObSSTableArray &minor_sstable_array, @@ -3189,6 +3240,140 @@ int ObTabletTableStore::get_all_minor_sstables( return ret; } +int ObTabletTableStore::build_split_new_table_store_( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObBatchUpdateTableStoreParam ¶m, + const ObTabletTableStore &old_store) +{ + int ret = OB_SUCCESS; + UpdateUpperTransParam unused_param; + ObITable *last_sstable = nullptr; + int64_t inc_base_snapshot_version = -1; + ObSEArray batch_tables; + const ObTabletHAStatus &ha_status = tablet.get_tablet_meta().ha_status_; + if (OB_FAIL(param.tables_handle_.get_tables(batch_tables))) { + LOG_WARN("get tables failed", K(ret), K(param)); + } else if (OB_FAIL(inner_build_major_tables_(allocator, old_store, batch_tables, + param.tablet_split_param_.multi_version_start_, + false/*allow_duplicate_sstable*/, + inc_base_snapshot_version))) { + LOG_WARN("failed to inner build major tables", K(ret), K(param), K(batch_tables)); + } else if (OB_FAIL(build_split_minor_tables_(allocator, old_store, batch_tables, + inc_base_snapshot_version, + ha_status))) { + LOG_WARN("failed to inner build minor tables", K(ret), K(param), K(batch_tables)); + } else if (OB_FALSE_IT(last_sstable = batch_tables.empty() ? nullptr : batch_tables.at(batch_tables.count() - 1))) { + // It must be the last one if there is a meta major sstable. + } else if (OB_FAIL(build_meta_major_table(allocator, static_cast(last_sstable), old_store))) { + LOG_WARN("failed to build meta major tables", K(ret)); + } else if (OB_FAIL(build_memtable_array(tablet))) { + LOG_WARN("failed to pull memtable from memtable_mgr", K(ret)); + } else if (OB_FAIL(pull_ddl_memtables(allocator, tablet))) { + LOG_WARN("pull_ddl_memtables failed", K(ret)); + } else if (OB_FAIL(build_minor_tables(allocator, nullptr/*new_sstable*/, old_store, false/*need_check_sstable*/, -1/*inc_base_snapshot_version*/, ha_status, unused_param, true/*is_mds*/))) { + LOG_WARN("failed to build mds sstables", K(ret)); + } else { + is_inited_ = true; + if (OB_FAIL(check_ready_for_read(tablet))) { + LOG_WARN("failed to check ready for read", K(ret)); + } else { + int tmp_ret = OB_SUCCESS; + if (OB_TMP_FAIL(try_cache_local_sstables(allocator))) { + LOG_WARN("failed to try cache local sstables", K(tmp_ret)); + } + FLOG_INFO("succeed to build split new table store", K(major_tables_), K(minor_tables_), K(memtables_), K(PRINT_TS(*this))); + } + } + return ret; +} + +int ObTabletTableStore::build_split_minor_tables_( + common::ObArenaAllocator &allocator, + const ObTabletTableStore &old_store, + const ObIArray &tables_array, + const int64_t inc_base_snapshot_version, + const ObTabletHAStatus &ha_status) +{ + int ret = OB_SUCCESS; + ObArray minor_tables; + if (OB_UNLIKELY(tables_array.empty())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid arg", K(ret)); + } else { + for (int64_t i = 0; OB_SUCC(ret) && i < tables_array.count(); i++) { + ObITable *new_table = tables_array.at(i); + if (OB_ISNULL(new_table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret)); + } else if (new_table->is_minor_sstable() && OB_FAIL(minor_tables.push_back(new_table))) { + LOG_WARN("push back failed", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (minor_tables.empty()) { + // not split minor tables. + } else if (OB_UNLIKELY(minor_tables.count() != tables_array.count())) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(minor_tables), K(tables_array)); + } else if (OB_FAIL(ObTableStoreUtil::sort_minor_tables(minor_tables))) { + LOG_WARN("failed to sort minor tables", K(ret)); + } else { + // check continuous. + ObITable *oldest_minor_in_old_store = nullptr; + ObITable *newest_minor_in_split = nullptr; + if (old_store.minor_tables_.empty()) { + LOG_INFO("empty minor in split dst tablet, skip check"); + } else if (OB_ISNULL(oldest_minor_in_old_store = old_store.minor_tables_[0])) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(old_store.minor_tables_)); + } else if (OB_ISNULL(newest_minor_in_split = minor_tables.at(minor_tables.count() - 1))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(minor_tables)); + } else if (newest_minor_in_split->get_end_scn() == oldest_minor_in_old_store->get_start_scn()) { + // expected status, end_scn of the newest split minor equals to the start_scn of the existed oldest table. + } else if (newest_minor_in_split->get_end_scn() < oldest_minor_in_old_store->get_start_scn()) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err, non-continuous split minors is caught", K(ret), KPC(oldest_minor_in_old_store), KPC(newest_minor_in_split)); + } else { + // update batch split-minors to the table store repeatedly is possible, and update repeatedly without error is necessary. + const SCN &smallest_start_scn_in_old_store = old_store.minor_tables_.at(0)->get_start_scn(); + const SCN &biggest_end_scn_in_old_store = old_store.minor_tables_.at(old_store.minor_tables_.count() - 1)->get_end_scn(); + const SCN &smallest_start_scn_in_split_minor = minor_tables.at(0)->get_start_scn(); + const SCN &biggest_end_scn_in_split_minor = minor_tables.at(minor_tables.count() - 1)->get_end_scn(); + if (OB_LIKELY(smallest_start_scn_in_old_store == smallest_start_scn_in_split_minor + && biggest_end_scn_in_old_store >= biggest_end_scn_in_split_minor)) { + // update batch split-minors to the table store repeatedly again. + LOG_INFO("update split minors repeatedly, ignore to add again", K(minor_tables), K(old_store.minor_tables_)); + minor_tables.reset(); // reset, to ignore to add split-minors again. + } else { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err is caught", K(ret), K(minor_tables), K(old_store.minor_tables_)); + } + } + } + } + + if (OB_SUCC(ret)) { + UpdateUpperTransParam unused_param; + for (int64_t i = 0; OB_SUCC(ret) && i < old_store.minor_tables_.count(); ++i) { + ObITable *table = old_store.minor_tables_[i]; + if (OB_ISNULL(table)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected err", K(ret), K(old_store.minor_tables_)); + } else if (OB_FAIL(minor_tables.push_back(table))) { + LOG_WARN("push back failed", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (OB_FAIL(inner_process_minor_tables(allocator, + old_store, minor_tables, inc_base_snapshot_version, ha_status, unused_param, false/*is_mds*/))) { + LOG_WARN("inner process minor tables failed", K(ret)); + } + } + return ret; +} + int64_t ObTabletTableStore::to_string(char *buf, const int64_t buf_len) const { int64_t pos = 0; diff --git a/src/storage/tablet/ob_tablet_table_store.h b/src/storage/tablet/ob_tablet_table_store.h index 65bab70d5..e067c42d8 100644 --- a/src/storage/tablet/ob_tablet_table_store.h +++ b/src/storage/tablet/ob_tablet_table_store.h @@ -32,6 +32,13 @@ class ObCachedTableHandle; class ObStorageMetaHandle; struct ObTabletHAStatus; +enum class ObGetReadTablesMode : uint8_t +{ + NORMAL = 0, + ALLOW_NO_READY_READ = 1, + SKIP_MAJOR = 2 +}; + class ObReadyForReadParam final { // if you want to add a member variable, please add here. @@ -169,7 +176,7 @@ public: const int64_t snapshot_version, const ObTablet &tablet, ObTableStoreIterator &iter, - const bool allow_no_ready_read = false) const; + const ObGetReadTablesMode mode = ObGetReadTablesMode::NORMAL) const; int get_all_sstable(ObTableStoreIterator &iter, const bool unpack_co_table = false) const; int get_read_major_sstable(const int64_t snapshot_version, ObTableStoreIterator &iter) const; int get_memtables(common::ObIArray &memtables, const bool need_active = false) const; @@ -215,6 +222,12 @@ public: blocksstable::ObSSTable &orig_sstable, ObStorageMetaHandle &loaded_sstable_handle, blocksstable::ObSSTable *&loaded_sstable); + // ddl-split + int build_split_new_table_store( + common::ObArenaAllocator &allocator, + ObTablet &tablet, + const ObBatchUpdateTableStoreParam ¶m, + const ObTabletTableStore &old_store); const blocksstable::ObMajorChecksumInfo &get_major_ckm_info() const { return major_ckm_info_; } int get_all_minor_sstables(ObTableStoreIterator &iter) const; private: @@ -249,7 +262,8 @@ private: const int64_t snapshot_version, const ObTablet &tablet, ObTableStoreIterator &iterator, - const bool allow_no_ready_read = false) const; + const bool allow_no_ready_read, + const bool skip_major) const; int calculate_read_memtables(const ObTablet &tablet, ObTableStoreIterator &iterator) const; bool check_read_tables( const ObTablet &tablet, @@ -269,6 +283,14 @@ private: const ObTabletHAStatus &ha_status, const UpdateUpperTransParam &upper_trans_param, const bool is_mds); + int inner_process_minor_tables( + common::ObArenaAllocator &allocator, + const ObTabletTableStore &old_store, + ObArray &minor_tables, + const int64_t inc_base_snapshot_version, + const ObTabletHAStatus &ha_status, + const UpdateUpperTransParam &upper_trans_param, + const bool is_mds); int build_meta_major_table( common::ObArenaAllocator &allocator, const blocksstable::ObSSTable *new_sstable, @@ -412,6 +434,18 @@ private: const ObTabletTableStore &old_store); bool is_major_sstable_empty(const share::SCN &ddl_commit_scn) const; int get_ddl_major_sstables(ObIArray &ddl_major_sstables) const; + // ddl-split + int build_split_new_table_store_( + common::ObArenaAllocator &allocator, + const ObTablet &tablet, + const ObBatchUpdateTableStoreParam ¶m, + const ObTabletTableStore &old_store); + int build_split_minor_tables_( + common::ObArenaAllocator &allocator, + const ObTabletTableStore &old_store, + const ObIArray &tables_array, + const int64_t inc_base_snapshot_version, + const ObTabletHAStatus &ha_status); int inner_replace_sstables( common::ObArenaAllocator &allocator, diff --git a/src/storage/tx/ob_multi_data_source_printer.cpp b/src/storage/tx/ob_multi_data_source_printer.cpp index edd13848c..984c688a3 100644 --- a/src/storage/tx/ob_multi_data_source_printer.cpp +++ b/src/storage/tx/ob_multi_data_source_printer.cpp @@ -49,6 +49,7 @@ const char *ObMultiDataSourcePrinter::to_str_mds_type(const ObTxDataSourceType & TRX_ENUM_CASE_TO_STR(ObTxDataSourceType, TRANSFER_MOVE_TX_CTX); TRX_ENUM_CASE_TO_STR(ObTxDataSourceType, TRANSFER_DEST_PREPARE); TRX_ENUM_CASE_TO_STR(ObTxDataSourceType, CHANGE_TABLET_TO_TABLE_MDS); + TRX_ENUM_CASE_TO_STR(ObTxDataSourceType, TABLET_SPLIT); TRX_ENUM_CASE_TO_STR(ObTxDataSourceType, TABLET_BINDING); TRX_ENUM_CASE_TO_STR(ObTxDataSourceType, MAX_TYPE); diff --git a/src/storage/tx/ob_trans_part_ctx.cpp b/src/storage/tx/ob_trans_part_ctx.cpp index 2117399b0..852b4a0d6 100644 --- a/src/storage/tx/ob_trans_part_ctx.cpp +++ b/src/storage/tx/ob_trans_part_ctx.cpp @@ -6435,7 +6435,8 @@ int ObPartTransCtx::switch_to_leader(const SCN &start_working_ts) const bool contain_mds_transfer_out = is_contain_mds_type_(ObTxDataSourceType::START_TRANSFER_OUT) || is_contain_mds_type_(ObTxDataSourceType::START_TRANSFER_OUT_PREPARE) || is_contain_mds_type_(ObTxDataSourceType::START_TRANSFER_OUT_V2); - const bool need_kill_tx = contain_mds_table_lock || contain_mds_transfer_out; + const bool contain_mds_tablet_split = is_contain_mds_type_(ObTxDataSourceType::TABLET_SPLIT); + const bool need_kill_tx = contain_mds_table_lock || contain_mds_transfer_out || contain_mds_tablet_split; bool kill_by_append_mode_initial_scn = false; if (append_mode_initial_scn.is_valid()) { kill_by_append_mode_initial_scn = exec_info_.max_applying_log_ts_ <= append_mode_initial_scn; @@ -6443,21 +6444,21 @@ int ObPartTransCtx::switch_to_leader(const SCN &start_working_ts) if (ObTxState::INIT == exec_info_.state_) { if (exec_info_.data_complete_ && !contain_mds_table_lock && !contain_mds_transfer_out - && !kill_by_append_mode_initial_scn) { + && !contain_mds_tablet_split && !kill_by_append_mode_initial_scn) { if (OB_FAIL(mt_ctx_.replay_to_commit(false /*is_resume*/))) { TRANS_LOG(WARN, "replay to commit failed", KR(ret), K(*this)); } } else { TRANS_LOG(WARN, "txn data incomplete, will be aborted", K(contain_mds_table_lock), - K(contain_mds_transfer_out), K(kill_by_append_mode_initial_scn), + K(contain_mds_transfer_out), K(contain_mds_tablet_split), K(kill_by_append_mode_initial_scn), K(append_mode_initial_scn), KPC(this)); if (has_persisted_log_()) { if (ObPartTransAction::COMMIT == part_trans_action_ || get_upstream_state() >= ObTxState::REDO_COMPLETE) { TRANS_LOG(WARN, "abort self instantly with a tx_commit request", - K(contain_mds_table_lock), K(contain_mds_transfer_out), K(need_kill_tx), - K(kill_by_append_mode_initial_scn), K(append_mode_initial_scn), KPC(this)); + K(contain_mds_table_lock), K(contain_mds_transfer_out), K(contain_mds_tablet_split), + K(need_kill_tx), K(kill_by_append_mode_initial_scn), K(append_mode_initial_scn), KPC(this)); if (OB_FAIL(do_local_tx_end_(TxEndAction::ABORT_TX))) { //Temporary fix: //The transaction cannot be killed temporarily, waiting for handle_timeout to retry abort. diff --git a/src/storage/tx/ob_tx_log.cpp b/src/storage/tx/ob_tx_log.cpp index 912b2902c..a3a8e7225 100644 --- a/src/storage/tx/ob_tx_log.cpp +++ b/src/storage/tx/ob_tx_log.cpp @@ -41,6 +41,7 @@ ObTxLogTypeChecker::need_replay_barrier(const ObTxLogType log_type, || data_source_type == ObTxDataSourceType::START_TRANSFER_OUT || data_source_type == ObTxDataSourceType::START_TRANSFER_OUT_PREPARE || data_source_type == ObTxDataSourceType::FINISH_TRANSFER_OUT + || data_source_type == ObTxDataSourceType::TABLET_SPLIT || data_source_type == ObTxDataSourceType::TABLET_BINDING) { barrier_flag = logservice::ObReplayBarrierType::PRE_BARRIER; diff --git a/src/storage/tx/ob_tx_replay_executor.cpp b/src/storage/tx/ob_tx_replay_executor.cpp index 80d273407..b6a01cb85 100644 --- a/src/storage/tx/ob_tx_replay_executor.cpp +++ b/src/storage/tx/ob_tx_replay_executor.cpp @@ -784,7 +784,7 @@ int ObTxReplayExecutor::replay_one_row_in_memtable_(ObMutatorRowHeader &row_head } int ObTxReplayExecutor::prepare_memtable_replay_(ObStorageTableGuard &w_guard, - ObIMemtable *&mem_ptr) + storage::ObIMemtable *&mem_ptr) { int ret = OB_SUCCESS; if (OB_FAIL(w_guard.refresh_and_protect_memtable_for_replay())) { @@ -807,7 +807,7 @@ int ObTxReplayExecutor::replay_row_(storage::ObStoreCtx &store_ctx, const share::ObLSID &ls_id = tablet->get_ls_id(); const common::ObTabletID &tablet_id = tablet->get_tablet_id(); common::ObTimeGuard timeguard("replay_row_in_memtable", 10_ms); - ObIMemtable *mem_ptr = nullptr; + storage::ObIMemtable *mem_ptr = nullptr; ObMemtable *data_mem_ptr = nullptr; ObStorageTableGuard w_guard(tablet, store_ctx, true, true, log_ts_ns_); if (OB_ISNULL(mmi_ptr)) { diff --git a/src/storage/tx/ob_tx_replay_executor.h b/src/storage/tx/ob_tx_replay_executor.h index 977c1ee98..f114a44e0 100644 --- a/src/storage/tx/ob_tx_replay_executor.h +++ b/src/storage/tx/ob_tx_replay_executor.h @@ -132,7 +132,7 @@ private: virtual int replay_one_row_in_memtable_(memtable::ObMutatorRowHeader& row_head, memtable::ObMemtableMutatorIterator *mmi_ptr); int prepare_memtable_replay_(storage::ObStorageTableGuard &w_guard, - ObIMemtable *&mem_ptr); + storage::ObIMemtable *&mem_ptr); int replay_row_(storage::ObStoreCtx &store_ctx, storage::ObTablet *tablet, memtable::ObMemtableMutatorIterator *mmi_ptr); diff --git a/src/storage/tx_storage/ob_access_service.cpp b/src/storage/tx_storage/ob_access_service.cpp index 9fcf90351..e546cf2d2 100644 --- a/src/storage/tx_storage/ob_access_service.cpp +++ b/src/storage/tx_storage/ob_access_service.cpp @@ -275,6 +275,52 @@ int ObAccessService::unlock_obj( return ret; } +int ObAccessService::replace_obj_lock( + const share::ObLSID &ls_id, + transaction::ObTxDesc &tx_desc, + const transaction::tablelock::ObReplaceLockParam &lock_param) +{ + int ret = OB_SUCCESS; + ObStoreCtxGuard ctx_guard; + ObLS *ls = nullptr; + int64_t user_specified_snapshot = transaction::ObTransVersion::INVALID_TRANS_VERSION; + transaction::ObTxReadSnapshot snapshot; + snapshot.init_none_read(); + concurrent_control::ObWriteFlag write_flag; + write_flag.set_is_table_lock(); + + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + LOG_WARN("ob access service is not running.", K(ret)); + } else if (OB_UNLIKELY(!ls_id.is_valid()) + || OB_UNLIKELY(!tx_desc.is_valid()) + || OB_UNLIKELY(!lock_param.is_valid())) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid argument", + K(ret), + K(ls_id), + K(tx_desc), + K(lock_param), + K(ls_id.is_valid()), + K(tx_desc.is_valid()), + K(lock_param.is_valid())); + } else if (OB_FAIL(get_write_store_ctx_guard_(ls_id, + lock_param.expired_time_, /*timeout*/ + tx_desc, + snapshot, + 0,/*branch_id*/ + write_flag, + ctx_guard))) { + LOG_WARN("fail to check query allowed", K(ret), K(ls_id)); + } else if (OB_ISNULL(ls = ctx_guard.get_ls_handle().get_ls())) { + ret = OB_ERR_UNEXPECTED; + LOG_ERROR("ls should not be null", K(ret), KP(ls)); + } else { + ret = ls->replace_lock(ctx_guard.get_store_ctx(), lock_param); + } + return ret; +} + int ObAccessService::table_scan( ObVTableScanParam &vparam, ObNewRowIterator *&result) @@ -539,6 +585,21 @@ int ObAccessService::construct_store_ctx_other_variables_( } else if (OB_FAIL(get_source_ls_tx_table_guard_(tablet_handle, ctx_guard))) { LOG_WARN("failed to get src ls tx table guard", K(ret), K(ls_id), K(tablet_id)); } + if (OB_TABLET_IS_SPLIT_SRC == ret) { + ObArray tmp_tablet_ids; + bool has_active_memtable = false; + if (OB_FAIL(tmp_tablet_ids.push_back(tablet_id))) { + LOG_WARN("failed to push back", K(ret)); + } else if (OB_FAIL(ls.check_tablet_no_active_memtable(tmp_tablet_ids, has_active_memtable))) { + LOG_WARN("check tablet has active memtable failed", K(ret), K(tablet_id)); + } else if (OB_UNLIKELY(has_active_memtable)) { + ret = OB_SCHEMA_EAGAIN; + LOG_WARN("split src tablet has active memtable, retry", K(ret), K(tablet_id)); + } else if (OB_FAIL(tablet_service->get_tablet_with_timeout( + tablet_id, tablet_handle, timeout, ObMDSGetTabletMode::READ_ALL_COMMITED, share::SCN::max_scn()))) { + LOG_WARN("failed to check and get tablet", K(ret), K(ls_id), K(tablet_id), K(timeout), K(snapshot)); + } + } return ret; } /* diff --git a/src/storage/tx_storage/ob_access_service.h b/src/storage/tx_storage/ob_access_service.h index 541054a44..905242885 100644 --- a/src/storage/tx_storage/ob_access_service.h +++ b/src/storage/tx_storage/ob_access_service.h @@ -98,6 +98,14 @@ public: const share::ObLSID &ls_id, transaction::ObTxDesc &tx_desc, const transaction::tablelock::ObLockParam ¶m); + // replace lock of obj + // @param [in] ls_id, this replace lock operation will be processed at which logstream. + // @param [in] tx_desc, the trans context. + // @param [in] lock_param, contain all the parameters of previous lock, and lock_owner / lock_mode of new lock + int replace_obj_lock( + const share::ObLSID &ls_id, + transaction::ObTxDesc &tx_desc, + const transaction::tablelock::ObReplaceLockParam &lock_param); // ObITabletScan interface virtual int table_scan( ObVTableScanParam &vparam, diff --git a/src/storage/tx_storage/ob_empty_shell_object_checker.cpp b/src/storage/tx_storage/ob_empty_shell_object_checker.cpp new file mode 100644 index 000000000..ad382b757 --- /dev/null +++ b/src/storage/tx_storage/ob_empty_shell_object_checker.cpp @@ -0,0 +1,232 @@ +/** + * 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 "ob_empty_shell_object_checker.h" +#include "share/scheduler/ob_partition_auto_split_helper.h" + +namespace oceanbase +{ +using namespace share; +namespace storage +{ + +void ObDDLEmptyShellChecker::reset() +{ + ls_ = nullptr; + last_check_normal_time_ = 0; + (void)delayed_gc_tablet_infos_.destroy(); + is_inited_ = false; +} + +int ObDDLEmptyShellChecker::init(storage::ObLS *ls) +{ + int ret = OB_SUCCESS; + if (OB_UNLIKELY(is_inited_)) { + ret = OB_INIT_TWICE; + STORAGE_LOG(WARN, "init twice", K(ret)); + } else if (OB_ISNULL(ls)) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "invalid arg", K(ret)); + } else if (OB_FAIL(delayed_gc_tablet_infos_.create(128/*bucket_num*/, lib::ObLabel("DDLDelayedGC")))) { + STORAGE_LOG(WARN, "create ddl tablet delayed gc infos failed", K(ret)); + } else { + ls_ = ls; + last_check_normal_time_ = ObClockGenerator::getClock(); + is_inited_ = true; + } + return ret; +} + +int ObDDLEmptyShellChecker::periodic_check_normal() +{ + int ret = OB_SUCCESS; + const int64_t CHECK_NORMAL_INTERVAL = 7200 * 1000 * 1000L; // 2h + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "not init", K(ret)); + } else if (OB_UNLIKELY(last_check_normal_time_ + CHECK_NORMAL_INTERVAL <= ObClockGenerator::getClock())) { + ObSEArray leak_tablets; + DelayedGCTabletIterator iter = delayed_gc_tablet_infos_.begin(); + for (; iter != delayed_gc_tablet_infos_.end(); ++iter) { + // override ret to find and release leak tablets more. + ObTabletHandle tablet_handle; + const ObTabletID &tablet_id = iter->first; + const int64_t tag_deleted_us = iter->second; + bool has_leak = false; + if (OB_FAIL(ls_->get_tablet_svr()->get_tablet(tablet_id, tablet_handle, + ObTabletCommon::DEFAULT_GET_TABLET_DURATION_US * 10, ObMDSGetTabletMode::READ_WITHOUT_CHECK))) { + if (OB_TABLET_NOT_EXIST == ret) { + has_leak = true; + STORAGE_LOG(WARN, "ddl delayed tablet info leak", K(ret), K(tablet_id), K(tag_deleted_us)); + } else { + STORAGE_LOG(WARN, "get tablet failed", K(ret), K(tablet_id), K(tag_deleted_us)); + } + } else if (OB_UNLIKELY(tablet_handle.get_obj()->is_empty_shell())) { + ret = OB_ERR_UNEXPECTED; + has_leak = true; + STORAGE_LOG(WARN, "ddl delayed tablet info leak", K(ret), K(tablet_id), K(tag_deleted_us)); + } + if (has_leak && OB_FAIL(leak_tablets.push_back(tablet_id))) { + // override ret is expected. + STORAGE_LOG(WARN, "push back failed", K(ret), K(tablet_id), K(tag_deleted_us)); + } + } + if (OB_UNLIKELY(!leak_tablets.empty())) { + for (int64_t i = 0; i < leak_tablets.count(); i++) { + // override ret to release leak tablets more. + const ObTabletID &tablet_id = leak_tablets.at(i); + if (OB_FAIL(delayed_gc_tablet_infos_.erase_refactored(tablet_id))) { + STORAGE_LOG(WARN, "erase leak ddl tablet failed", K(ret), K(tablet_id)); + } + } + } + last_check_normal_time_ = ObClockGenerator::getClock(); + } + return ret; +} + +int ObDDLEmptyShellChecker::check_disk_space_exceeds( + const ObTabletID &tablet_id, + bool &can_become_empty_shell) +{ + int ret = OB_SUCCESS; + if (GCTX.is_shared_storage_mode()) { + can_become_empty_shell = false; + } else { + const int64_t required_size = LOCAL_DEVICE_INSTANCE.get_total_block_size() * 0.1; + if (OB_FAIL(LOCAL_DEVICE_INSTANCE.check_space_full(required_size))) { + if (OB_SERVER_OUTOF_DISK_SPACE == ret) { + ret = OB_SUCCESS; + can_become_empty_shell = true; + STORAGE_LOG(INFO, "delete split src tablet when reaching data disk used limit", K(tablet_id), K(required_size)); + } else { + STORAGE_LOG(WARN, "check data disk space full failed", K(ret), K(required_size)); + } + } + } + return ret; +} + +int ObDDLEmptyShellChecker::check_tablets_cnt_exceeds( + const ObTabletID &tablet_id, + bool &can_become_empty_shell) +{ + int ret = OB_SUCCESS; + if (OB_FAIL(ObServerAutoSplitScheduler::check_tablet_creation_limit(0/*inc_tablet_cnt*/, 0.8/*safe_ratio*/))) { + if (OB_TOO_MANY_PARTITIONS_ERROR == ret) { + ret = OB_SUCCESS; + can_become_empty_shell = true; + STORAGE_LOG(INFO, "delete split src tablet when reaching unit tablet cnt limit", K(tablet_id)); + } else { + STORAGE_LOG(WARN, "check tablet cnt reach limit failed", K(ret), K(tablet_id)); + } + } + return ret; +} + +int ObDDLEmptyShellChecker::check_delay_deleted_time_exceeds( + const ObTabletID &tablet_id, + bool &can_become_empty_shell) +{ + int ret = OB_SUCCESS; + int64_t tag_deleted_us = 0; + int64_t DELAY_GC_INTERVAL = 0.5 * 3600 * 1000 * 1000L; // 0.5h +#ifdef ERRSIM + if (DELAY_GC_INTERVAL != GCONF.errsim_delay_gc_interval) { + DELAY_GC_INTERVAL = GCONF.errsim_delay_gc_interval; + } +#endif + if (OB_FAIL(delayed_gc_tablet_infos_.get_refactored(tablet_id, tag_deleted_us))) { + if (OB_HASH_NOT_EXIST == ret) { + if (OB_FAIL(delayed_gc_tablet_infos_.set_refactored(tablet_id, ObClockGenerator::getClock()))) { + STORAGE_LOG(WARN, "update tablet tag deleted time failed", K(ret), K(tablet_id)); + } + } else { + STORAGE_LOG(WARN, "get refactored failed", K(ret), K(tablet_id)); + } + } else if (ObClockGenerator::getClock() - tag_deleted_us >= DELAY_GC_INTERVAL) { + can_become_empty_shell = true; + STORAGE_LOG(INFO, "delete split src tablet when reaching predefined time limit", K(ret), K(tablet_id)); + } else { + STORAGE_LOG(TRACE, "can not change to empty shell", K(tablet_id), K(tag_deleted_us)); + } + return ret; +} + +int ObDDLEmptyShellChecker::erase_tablet_record( + const ObTabletID &tablet_id) +{ + int ret = OB_SUCCESS; + if (IS_NOT_INIT) { + STORAGE_LOG(WARN, "not init", K(ret), K(tablet_id)); + } else if (OB_FAIL(delayed_gc_tablet_infos_.erase_refactored(tablet_id))) { + if (OB_HASH_NOT_EXIST == ret ) { + ret = OB_SUCCESS; + } else { + STORAGE_LOG(WARN, "erase failed", K(ret), K(tablet_id)); + } + } + return ret; +} + +int ObDDLEmptyShellChecker::check_split_src_deleted_tablet( + const ObTablet &tablet, + const ObTabletCreateDeleteMdsUserData &user_data, + bool &can_become_empty_shell, + bool &need_retry) +{ + int ret = OB_SUCCESS; + can_become_empty_shell = false; + SCN decided_scn; + const ObTabletID tablet_id(tablet.get_tablet_meta().tablet_id_); + const share::ObLSID ls_id(tablet.get_tablet_meta().ls_id_); + if (IS_NOT_INIT) { + ret = OB_NOT_INIT; + STORAGE_LOG(WARN, "not init", K(ret)); + } else if (OB_UNLIKELY(!user_data.is_valid())) { + ret = OB_INVALID_ARGUMENT; + STORAGE_LOG(WARN, "arguments are invalid", K(ret), K(user_data)); + } else if (ObTabletStatus::SPLIT_SRC_DELETED != user_data.get_tablet_status()) { + // not split source tablet, ignore. + } else if (OB_FAIL(ls_->get_max_decided_scn(decided_scn))) { + STORAGE_LOG(WARN, "failed to get max decided scn", K(ret), K(user_data)); + } else if (decided_scn < user_data.delete_commit_scn_) { + need_retry = true; + if (REACH_TENANT_TIME_INTERVAL(1 * 1000 * 1000/*1s*/)) { + STORAGE_LOG(INFO, "decided_scn is smaller than tablet delete commit scn", + K(ls_id), K(tablet_id), K(user_data), K(decided_scn)); + } + } else { + int tmp_ret = OB_SUCCESS; + if (!can_become_empty_shell) { + if (OB_TMP_FAIL(check_disk_space_exceeds(tablet_id, can_become_empty_shell))) { + STORAGE_LOG(WARN, "check data disk space full failed", K(tmp_ret), K(tablet_id)); + } + } + if (!can_become_empty_shell) { + if (OB_TMP_FAIL(check_tablets_cnt_exceeds(tablet_id, can_become_empty_shell))) { + STORAGE_LOG(WARN, "check tablet cnt reach limit failed", K(tmp_ret), K(tablet_id), K(user_data)); + } + } + if (!can_become_empty_shell) { + if (OB_TMP_FAIL(check_delay_deleted_time_exceeds(tablet_id, can_become_empty_shell))) { + STORAGE_LOG(WARN, "update tablet tag deleted time failed", K(tmp_ret), K(tablet_id)); + } + } + need_retry = !can_become_empty_shell ? true : need_retry; + } + (void)periodic_check_normal(); + return ret; +} + +} // storage +} // oceanbase diff --git a/src/storage/tx_storage/ob_empty_shell_object_checker.h b/src/storage/tx_storage/ob_empty_shell_object_checker.h new file mode 100644 index 000000000..4e0cc50f7 --- /dev/null +++ b/src/storage/tx_storage/ob_empty_shell_object_checker.h @@ -0,0 +1,74 @@ +/** + * 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 OCEABASE_STORAGE_OB_EMPTY_SHELL_OBJECT_CHECKER +#define OCEABASE_STORAGE_OB_EMPTY_SHELL_OBJECT_CHECKER + +#include "lib/oblog/ob_log.h" +#include "lib/task/ob_timer.h" +#include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" + +namespace oceanbase +{ +namespace storage +{ +// check whether the ddl tablet can become empty shell. +class ObDDLEmptyShellChecker +{ +public: + ObDDLEmptyShellChecker() + : ls_(nullptr), + last_check_normal_time_(), + delayed_gc_tablet_infos_(), + is_inited_(false) + { } + ~ObDDLEmptyShellChecker() { reset(); } + void reset(); + int init(storage::ObLS *ls); + int check_split_src_deleted_tablet( + const ObTablet &tablet, + const ObTabletCreateDeleteMdsUserData &user_data, + bool &can_become_empty_shell, + bool &need_retry); + int erase_tablet_record( + const ObTabletID &tablet_id); +private: + int check_disk_space_exceeds( + const ObTabletID &tablet_id, + bool &can_become_empty_shell); + int check_tablets_cnt_exceeds( + const ObTabletID &tablet_id, + bool &can_become_empty_shell); + int check_delay_deleted_time_exceeds( + const ObTabletID &tablet_id, + bool &can_become_empty_shell); + int periodic_check_normal(); +private: + typedef typename common::hash::ObHashMap, + common::hash::equal_to, + common::hash::SimpleAllocer::AllocType>, + common::hash::NormalPointer, + oceanbase::common::ObMalloc, + 2/*MAP_EXTEND_RATIO*/> DelayedGCTabletMap; + typedef typename DelayedGCTabletMap::iterator DelayedGCTabletIterator; + storage::ObLS *ls_; + int64_t last_check_normal_time_; // to decide whether to check map leak. + DelayedGCTabletMap delayed_gc_tablet_infos_; + bool is_inited_; +}; +} // storage +} // oceanbase + +#endif diff --git a/src/storage/tx_storage/ob_empty_shell_task.cpp b/src/storage/tx_storage/ob_empty_shell_task.cpp index 35cec7d21..c343a9bac 100644 --- a/src/storage/tx_storage/ob_empty_shell_task.cpp +++ b/src/storage/tx_storage/ob_empty_shell_task.cpp @@ -115,6 +115,8 @@ int ObTabletEmptyShellHandler::init(ObLS *ls) } else if (OB_ISNULL(ls)) { ret = OB_INVALID_ARGUMENT; STORAGE_LOG(WARN, "invalid argument", KR(ret)); + } else if (OB_FAIL(ddl_empty_shell_checker_.init(ls))) { + STORAGE_LOG(WARN, "create ddl tablet checker failed", K(ret)); } else { ls_ = ls; is_inited_ = true; @@ -202,6 +204,8 @@ int ObTabletEmptyShellHandler::update_tablets_to_empty_shell(ObLS *ls, const com const ObTabletID &tablet_id = tablet_ids.at(i); if (OB_FAIL(ls->get_tablet_svr()->update_tablet_to_empty_shell(tablet_id))) { STORAGE_LOG(WARN, "failed to update tablet to shell", K(ret), K(ls->get_ls_id()), K(tablet_id)); + } else if (OB_FAIL(ddl_empty_shell_checker_.erase_tablet_record(tablet_id))) { + STORAGE_LOG(WARN, "erase ddl tablet record failed", K(ret)); } else { #ifdef ERRSIM const uint64_t tenant_id = MTL_ID(); @@ -231,8 +235,7 @@ int ObTabletEmptyShellHandler::check_tablet_deleted_(ObTablet *tablet, bool &is_ } else { STORAGE_LOG(WARN, "failed to get latest tablet status", K(ret), KP(tablet)); } - } else if (ObTabletStatus::DELETED == data.tablet_status_ - || ObTabletStatus::TRANSFER_OUT_DELETED == data.tablet_status_) { + } else if (data.tablet_status_.is_deleted_for_gc()) { is_deleted = true; STORAGE_LOG(INFO, "get tablet for deleting", "ls_id", ls_->get_ls_id(), "tablet_id", tablet->get_tablet_meta().tablet_id_, K(data)); } @@ -293,6 +296,8 @@ int ObTabletEmptyShellHandler::check_tablet_empty_shell_( } else if (ObTabletStatus::TRANSFER_OUT_DELETED == tablet_status && OB_FAIL(check_transfer_out_deleted_tablet_(tablet, user_data, not_depend_on, need_retry))) { STORAGE_LOG(WARN, "failed to check transfer out deleted tablet", K(ret), K(readable_scn), K(user_data)); + } else if (!not_depend_on && OB_FAIL(ddl_empty_shell_checker_.check_split_src_deleted_tablet(tablet, user_data, not_depend_on, need_retry))) { + STORAGE_LOG(WARN, "failed to check split source deleted tablet", K(ret), K(readable_scn), K(user_data)); } else if (ObTabletStatus::DELETED == tablet_status || not_depend_on) { if (user_data.delete_commit_scn_.is_valid() && user_data.delete_commit_scn_ <= readable_scn) { can = true; diff --git a/src/storage/tx_storage/ob_empty_shell_task.h b/src/storage/tx_storage/ob_empty_shell_task.h index 45cf8a779..fec43282a 100644 --- a/src/storage/tx_storage/ob_empty_shell_task.h +++ b/src/storage/tx_storage/ob_empty_shell_task.h @@ -18,6 +18,7 @@ #include "share/scn.h" #include "storage/tablet/ob_tablet_create_delete_mds_user_data.h" #include "storage/meta_mem/ob_tablet_handle.h" +#include "storage/tx_storage/ob_empty_shell_object_checker.h" #include "share/ob_tenant_info_proxy.h" namespace oceanbase @@ -37,12 +38,14 @@ public: : ls_(NULL), is_trigger_(true), stopped_(false), + ddl_empty_shell_checker_(), is_inited_(false) {} ~ObTabletEmptyShellHandler() { reset(); } void reset() { ls_ = NULL; + ddl_empty_shell_checker_.reset(); is_inited_ = false; } int init(storage::ObLS *ls); @@ -80,6 +83,7 @@ private: storage::ObLS *ls_; bool is_trigger_; bool stopped_; + ObDDLEmptyShellChecker ddl_empty_shell_checker_; // to record the tag deleted time of the ddl tablet. bool is_inited_; }; diff --git a/src/storage/tx_storage/ob_tablet_gc_service.cpp b/src/storage/tx_storage/ob_tablet_gc_service.cpp index d6a777fa2..e07eb037f 100644 --- a/src/storage/tx_storage/ob_tablet_gc_service.cpp +++ b/src/storage/tx_storage/ob_tablet_gc_service.cpp @@ -707,6 +707,12 @@ int ObTabletGCHandler::gc_tablets(const common::ObIArray &delete STORAGE_LOG(WARN, "failed to remove tablet", K(ret), K(tablet_handle)); } } else { +#ifdef ERRSIM + SERVER_EVENT_SYNC_ADD("tablet_gc", "gc_tablet_finish", + "ls_id", tablet_handle.get_obj()->get_tablet_meta().ls_id_.id(), + "tablet_id", tablet_handle.get_obj()->get_tablet_meta().tablet_id_.id(), + "transfer_seq", tablet_handle.get_obj()->get_tablet_meta().transfer_info_.transfer_seq_); +#endif STORAGE_LOG(INFO, "gc tablet finish", K(ret), "ls_id", tablet_handle.get_obj()->get_tablet_meta().ls_id_, "tablet_id", tablet_handle.get_obj()->get_tablet_meta().tablet_id_); diff --git a/tools/deploy/mysql_test/r/mysql/information_schema.result b/tools/deploy/mysql_test/r/mysql/information_schema.result index 54b8fe78a..ac3d3def1 100644 --- a/tools/deploy/mysql_test/r/mysql/information_schema.result +++ b/tools/deploy/mysql_test/r/mysql/information_schema.result @@ -28,31 +28,33 @@ desc information_schema.columns; | GENERATION_EXPRESSION | longtext | NO | | | | +--------------------------+---------------------+------+-----+---------+-------+ desc information_schema.tables; -+-----------------+---------------------+------+-----+---------+-------+ -| Field | Type | Null | Key | Default | Extra | -+-----------------+---------------------+------+-----+---------+-------+ -| TABLE_CATALOG | varchar(512) | NO | | | | -| TABLE_SCHEMA | varchar(64) | NO | | | | -| TABLE_NAME | varchar(64) | NO | | | | -| TABLE_TYPE | varchar(64) | NO | | | | -| ENGINE | varchar(64) | NO | | | | -| VERSION | bigint(0) unsigned | NO | | | | -| ROW_FORMAT | varchar(10) | NO | | | | -| TABLE_ROWS | bigint(20) unsigned | NO | | | | -| AVG_ROW_LENGTH | bigint(21) unsigned | NO | | | | -| DATA_LENGTH | bigint(20) unsigned | NO | | | | -| MAX_DATA_LENGTH | bigint(0) unsigned | NO | | | | -| INDEX_LENGTH | bigint(21) unsigned | NO | | | | -| DATA_FREE | bigint(0) unsigned | NO | | | | -| AUTO_INCREMENT | bigint(0) unsigned | NO | | | | -| CREATE_TIME | datetime | NO | | | | -| UPDATE_TIME | datetime | NO | | | | -| CHECK_TIME | datetime | NO | | | | -| TABLE_COLLATION | varchar(32) | NO | | | | -| CHECKSUM | bigint(0) unsigned | NO | | | | -| CREATE_OPTIONS | varchar(255) | NO | | | | -| TABLE_COMMENT | text | NO | | | | -+-----------------+---------------------+------+-----+---------+-------+ ++------------------------+---------------------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++------------------------+---------------------+------+-----+---------+-------+ +| TABLE_CATALOG | varchar(512) | NO | | | | +| TABLE_SCHEMA | varchar(64) | NO | | | | +| TABLE_NAME | varchar(64) | NO | | | | +| TABLE_TYPE | varchar(64) | NO | | | | +| ENGINE | varchar(64) | NO | | | | +| VERSION | bigint(0) unsigned | NO | | | | +| ROW_FORMAT | varchar(10) | NO | | | | +| TABLE_ROWS | bigint(20) unsigned | NO | | | | +| AVG_ROW_LENGTH | bigint(21) unsigned | NO | | | | +| DATA_LENGTH | bigint(20) unsigned | NO | | | | +| MAX_DATA_LENGTH | bigint(0) unsigned | NO | | | | +| INDEX_LENGTH | bigint(21) unsigned | NO | | | | +| DATA_FREE | bigint(0) unsigned | NO | | | | +| AUTO_INCREMENT | bigint(0) unsigned | NO | | | | +| CREATE_TIME | datetime | NO | | | | +| UPDATE_TIME | datetime | NO | | | | +| CHECK_TIME | datetime | NO | | | | +| TABLE_COLLATION | varchar(32) | NO | | | | +| CHECKSUM | bigint(0) unsigned | NO | | | | +| CREATE_OPTIONS | varchar(255) | NO | | | | +| TABLE_COMMENT | text | NO | | | | +| AUTO_SPLIT | varchar(16) | NO | | | | +| AUTO_SPLIT_TABLET_SIZE | bigint(20) unsigned | NO | | | | ++------------------------+---------------------+------+-----+---------+-------+ desc information_schema.session_variables; +----------------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | @@ -182,802 +184,803 @@ desc information_schema.files; +----------------------+---------------------+------+-----+---------+-------+ select * from information_schema.tables where table_schema in ('oceanbase', 'mysql', 'information_schema') order by TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME; -+---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+ -| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT | -+---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+ -| def | information_schema | CHARACTER_SETS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | CHECK_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | COLLATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | COLLATION_CHARACTER_SET_APPLICABILITY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | COLUMN_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ENABLED_ROLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ENGINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | EVENTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | GLOBAL_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | GLOBAL_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_BUFFER_PAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_BUFFER_PAGE_LRU | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_BUFFER_POOL_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMP | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMPMEM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMPMEM_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMP_PER_INDEX | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMP_PER_INDEX_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMP_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_FT_BEING_DELETED | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_FT_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_FT_DELETED | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_FT_INDEX_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_LOCK_WAITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_METRICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_DATAFILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_FIELDS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_FOREIGN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_FOREIGN_COLS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_INDEXES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_TABLESTATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_VIRTUAL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_TEMP_TABLE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_TRX | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | KEY_COLUMN_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | NDB_TRANSID_MYSQL_CONNECTION_MAP | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | OPTIMIZER_TRACE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PLUGINS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PROFILING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | QUERY_RESPONSE_TIME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | REFERENTIAL_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ROLE_COLUMN_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ROLE_ROUTINE_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ROLE_TABLE_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ROUTINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | SCHEMATA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | SCHEMA_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | SESSION_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | SESSION_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ST_GEOMETRY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ST_SPATIAL_REFERENCE_SYSTEMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TABLE_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TABLE_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TRIGGERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | USER_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | VIEWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | VIEW_TABLE_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | audit_log_filter | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | audit_log_user | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | columns_priv | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | db | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | default_roles | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | func | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | help_category | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | help_keyword | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | help_relation | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | help_topic | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | proc | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | procs_priv | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | role_edges | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | time_zone | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | time_zone_name | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | time_zone_transition | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | time_zone_transition_type | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | user | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | ALL_OB_EXTERNAL_TABLE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_DB_LINKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_INDEX_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_IND_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_IND_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_IND_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVIEWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVIEW_LOGS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_CHANGE_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_RUN_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_STATS_PARAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_STATS_SYS_DEFAULTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_STMT_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OBJECTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ACCESS_POINT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ARCHIVELOG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ARCHIVELOG_PIECE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ARCHIVELOG_SUMMARY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ARCHIVE_DEST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_AUTO_INCREMENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_AUX_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_POLICY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_PARAMETER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_SET_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_STORAGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_STORAGE_INFO_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BALANCE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BALANCE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BALANCE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BALANCE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_CONCURRENT_LIMIT_SQL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_DATABASES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_DATABASE_PRIVILEGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_DATA_DICTIONARY_IN_LOG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_DEADLOCK_EVENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_EXTERNAL_TABLE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_FORMAT_OUTLINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_FREEZE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_IMPORT_TABLE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_IMPORT_TABLE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_IMPORT_TABLE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_IMPORT_TABLE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_KV_TTL_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_KV_TTL_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LOG_RESTORE_SOURCE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_ARB_REPLICA_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_ARB_REPLICA_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_LOCATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_LOG_ARCHIVE_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_REPLICA_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_REPLICA_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_MAJOR_COMPACTION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_OUTLINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_OUTLINE_CONCURRENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RECOVER_TABLE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RECOVER_TABLE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RESTORE_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RESTORE_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RSRC_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RSRC_IO_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_SEQUENCE_OBJECTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_SERVICES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_STORAGE_IO_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_SYS_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLEGROUPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLEGROUP_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLEGROUP_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLEGROUP_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLET_REPLICAS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLET_TO_LS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLE_LOCATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLE_STAT_STALE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TASK_OPT_STAT_GATHER_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TEMP_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TENANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TENANT_EVENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TRANSFER_PARTITION_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TRANSFER_PARTITION_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TRANSFER_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TRANSFER_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_USERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_USER_DEFINED_RULES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ZONE_MAJOR_COMPACTION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_INDEXES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_KEY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RECYCLEBIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RSRC_CONSUMER_GROUPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RSRC_GROUP_MAPPINGS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RSRC_PLANS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RSRC_PLAN_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SCHEDULER_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SCHEDULER_JOB_RUN_DETAILS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SCHEDULER_WINDOWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SEQUENCES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SQL_MANAGEMENT_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SQL_PLAN_BASELINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SUBPARTITION_TEMPLATES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SUBPART_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SUBPART_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SUBPART_KEY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_MODIFICATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_STATS_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_CONTROL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_SNAPSHOT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$DML_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$LATCH | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_ARBITRATION_MEMBER_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_ARBITRATION_SERVICE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_CGROUP_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_COMPACTION_DIAGNOSE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_COMPACTION_SUGGESTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_DTL_INTERM_RESULT_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_FLT_TRACE_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_FUNCTION_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_GROUP_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_KVCACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_KV_CLIENT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_KV_GROUP_COMMIT_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_MERGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_NIC_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_OPT_STAT_GATHER_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PLAN_CACHE_PLAN_EXPLAIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PLAN_CACHE_PLAN_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PLAN_CACHE_REFERENCE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PLAN_CACHE_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PL_CACHE_OBJECT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PS_ITEM_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PS_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PX_P2P_DATAHUB | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PX_TARGET_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PX_WORKER_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_RPC_INCOMING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_RPC_OUTGOING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SERVER_SCHEMA_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SESSION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SESSION_PS_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SHARED_STORAGE_QUOTA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SQL_AUDIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SQL_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SQL_WORKAREA_MEMORY_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SSTABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SS_LOCAL_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TABLET_COMPACTION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TABLET_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TABLET_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TENANT_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TENANT_RESOURCE_LIMIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TENANT_RESOURCE_LIMIT_DETAIL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_THREAD | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TRACEPOINT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TRANSACTION_PARTICIPANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TRANSACTION_SCHEDULERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_UNITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSION_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSION_LONGOPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSION_WAIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSION_WAIT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_JOIN_FILTER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_PLAN_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_WORKAREA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_WORKAREA_ACTIVE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_WORKAREA_HISTOGRAM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SYSTEM_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$DML_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$ENCRYPTED_TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$EVENT_NAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$LATCH | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_ARBITRATION_MEMBER_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_ARBITRATION_SERVICE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_ARCHIVE_DEST_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_CGROUP_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_COMPACTION_DIAGNOSE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_COMPACTION_SUGGESTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_COMPATIBILITY_CONTROL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_DTL_INTERM_RESULT_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_ENCRYPTED_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_FUNCTION_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_GROUP_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_KVCACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_KV_CLIENT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_KV_GROUP_COMMIT_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_MERGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_NIC_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_OPT_STAT_GATHER_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PLAN_CACHE_PLAN_EXPLAIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PLAN_CACHE_PLAN_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PLAN_CACHE_REFERENCE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PLAN_CACHE_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PL_CACHE_OBJECT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PS_ITEM_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PS_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PX_P2P_DATAHUB | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PX_TARGET_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PX_WORKER_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_RPC_INCOMING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_RPC_OUTGOING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SERVER_SCHEMA_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SESSION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SESSION_PS_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SHARED_STORAGE_QUOTA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SQL_AUDIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SQL_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SQL_WORKAREA_MEMORY_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SSTABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SS_LOCAL_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TABLET_COMPACTION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TABLET_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TABLET_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TENANT_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TENANT_RESOURCE_LIMIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TENANT_RESOURCE_LIMIT_DETAIL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_THREAD | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TIMESTAMP_SERVICE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TRACEPOINT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TRANSACTION_PARTICIPANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TRANSACTION_SCHEDULERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_UNITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$RSRC_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSION_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSION_LONGOPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSION_WAIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSION_WAIT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_JOIN_FILTER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_MONITOR_STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_PLAN_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_WORKAREA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_WORKAREA_ACTIVE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_WORKAREA_HISTOGRAM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SYSTEM_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __ALL_VIRTUAL_INFORMATION_COLUMNS | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_acquired_snapshot | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_audit_log_filter | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_audit_log_user | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_auto_increment | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_aux_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_balance_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_balance_job_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_balance_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_balance_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_client_to_server_session_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_coll_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_coll_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_group_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_group_mapping | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_group_mapping_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_usage | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_constraint | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_constraint_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_context | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_context_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_core_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dam_cleanup_jobs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dam_last_arch_ts | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_data_dictionary_in_log | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_database | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_database_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_database_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_database_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dblink | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dblink_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dbms_lock_allocated | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_checksum | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_error_message | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_id | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_operation | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_task_status | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_def_sub_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_def_sub_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_detect_lock_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dummy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_external_table_file | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_foreign_key | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_foreign_key_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_foreign_key_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_foreign_key_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_freeze_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_func | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_func_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_histogram_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_histogram_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_index_usage_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_job_log | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ls | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mlog | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mock_fk_parent_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mock_fk_parent_table_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mock_fk_parent_table_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mock_fk_parent_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_monitor_modified | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_dep | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_change_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_run_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_stats_params | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_stats_sys_defaults | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_stmt_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ncomp_dll | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_optstat_global_prefs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_optstat_user_prefs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ori_schema_version | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_outline | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_outline_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_package | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_package_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_part_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_part_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_pending_transaction | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_plan_baseline | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_plan_baseline_item | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_recyclebin | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_res_mgr_consumer_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_res_mgr_directive | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_res_mgr_mapping_rule | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_res_mgr_plan | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_attribute | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_attribute_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_context | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_context_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_group_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_policy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_policy_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_security_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_security_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_param | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_param_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_scheduler_job_run_detail_v2 | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sequence_object | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sequence_object_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sequence_value | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_spatial_reference_systems | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_spm_config | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sub_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sub_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_synonym | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_synonym_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sys_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sys_variable | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sys_variable_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablegroup | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablegroup_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablet_checksum | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablet_to_ls | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablet_to_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_temp_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_constraint_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_constraint_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_dependency | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_directory | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_directory_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_error | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_keystore | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_keystore_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_objauth | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_objauth_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_object_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_object_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_component | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_component_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_label | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_label_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_policy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_policy_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_user_level | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_user_level_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_profile | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_profile_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_rewrite_rules | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_role_grantee_map | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_role_grantee_map_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_job_class | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_job_run_detail | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_program | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_program_argument | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_security_audit | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_security_audit_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_security_audit_record | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_sysauth | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_sysauth_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_tablespace | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_tablespace_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_time_zone | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_time_zone_name | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_time_zone_transition | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_time_zone_transition_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_trigger | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_trigger_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_transfer_partition_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_transfer_partition_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_transfer_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_transfer_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_type_attr | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_type_attr_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_proxy_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_proxy_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_proxy_role_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_proxy_role_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_apply_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_arbitration_member_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_arbitration_service_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_archive_dest_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_archive_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ash | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_audit_action | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_audit_operation | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_ls_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_ls_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_policy | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_set_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_storage_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_storage_info_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_cgroup_config | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_checkpoint_diagnose_checkpoint_unit_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_checkpoint_diagnose_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_checkpoint_diagnose_memtable_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_client_to_server_session_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_column_group_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_column_group_mapping | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_column_group_mapping_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_compatibility_control | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_core_column_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_core_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_data_type | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_data_type_class | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_deadlock_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_detect_lock_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dml_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dtl_interm_result_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dup_ls_lease_mgr | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dup_ls_tablet_set | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dup_ls_tablets | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_engine | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_flt_config | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_freeze_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_function_io_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_global_transaction | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_group_io_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_import_table_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_import_table_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_import_table_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_import_table_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_client_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_connection | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_group_commit_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_ttl_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_ttl_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kvcache_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_latch | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_lock_wait_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_archive_dest_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_archive_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_archive_piece_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_archive_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_restore_source | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_arb_replica_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_arb_replica_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_election_reference_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_log_archive_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_log_restore_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_recovery_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_replica_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_replica_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_replica_task_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mds_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mds_node_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_memstore_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_merge_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mlog | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_change_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_run_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_stats_params | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_stats_sys_defaults | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_stmt_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_nic_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_obj_lock | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_obrpc_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_open_cursor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_opt_stat_gather_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_plan_cache_plan_explain | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_plan_cache_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_plan_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_privilege | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_processlist | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_proxy_partition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_proxy_partition_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_proxy_schema | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_proxy_sub_partition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ps_item_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ps_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_px_p2p_datahub | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_px_target_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_px_worker_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_query_response_time | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_recover_table_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_recover_table_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_replay_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_res_mgr_directive | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_resource_pool_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_restore_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_restore_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_restore_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_server_compaction_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_server_compaction_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_server_schema_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_service | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_event | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_ps_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_wait | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_wait_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sesstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_shared_storage_quota | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_show_trace | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_audit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_monitor_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_plan_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_workarea_active | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_workarea_histogram | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_workarea_history_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_workarea_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ss_local_cache_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_storage_io_usage | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sys_variable_default_value | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sysstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_system_event | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_table_mgr | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_table_opt_stat_gather_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_checksum_error_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_compaction_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_compaction_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_compaction_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_encrypt_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_task_opt_stat_gather_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_temp_file | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_memstore_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_resource_limit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_resource_limit_detail | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_thread | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_timestamp_service | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_trace_span_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tracepoint_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_trans_lock_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_trans_scheduler | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_trans_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_transaction_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_transaction_freeze_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_unit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_user | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_vector_index_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_virtual_long_ops_status_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_active_session_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_control | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_sysstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_zone_merge_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_zone_storage_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_all_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_charset | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_collation | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_concurrent_limit_sql | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_current_tenant | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_database_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_event_name | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_global_variable | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_object_definition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_outline | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_privilege_grant | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_session_variable | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_database | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_procedure | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_tablegroup | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_trigger | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_tables | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_table_column | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_table_index | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_tenant_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_warning | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -+---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+ ++---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+------------+------------------------+ +| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT | AUTO_SPLIT | AUTO_SPLIT_TABLET_SIZE | ++---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+------------+------------------------+ +| def | information_schema | CHARACTER_SETS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | CHECK_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | COLLATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | COLLATION_CHARACTER_SET_APPLICABILITY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | COLUMN_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ENABLED_ROLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ENGINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | EVENTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | GLOBAL_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | GLOBAL_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_BUFFER_PAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_BUFFER_PAGE_LRU | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_BUFFER_POOL_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMP | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMPMEM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMPMEM_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMP_PER_INDEX | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMP_PER_INDEX_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMP_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_FT_BEING_DELETED | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_FT_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_FT_DELETED | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_FT_INDEX_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_LOCK_WAITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_METRICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_DATAFILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_FIELDS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_FOREIGN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_FOREIGN_COLS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_INDEXES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_TABLESTATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_VIRTUAL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_TEMP_TABLE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_TRX | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | KEY_COLUMN_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | NDB_TRANSID_MYSQL_CONNECTION_MAP | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | OPTIMIZER_TRACE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PLUGINS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PROFILING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | QUERY_RESPONSE_TIME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | REFERENTIAL_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ROLE_COLUMN_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ROLE_ROUTINE_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ROLE_TABLE_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ROUTINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | SCHEMATA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | SCHEMA_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | SESSION_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | SESSION_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ST_GEOMETRY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ST_SPATIAL_REFERENCE_SYSTEMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TABLE_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TABLE_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TRIGGERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | USER_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | VIEWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | VIEW_TABLE_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | audit_log_filter | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | audit_log_user | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | columns_priv | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | db | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | default_roles | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | func | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | help_category | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | help_keyword | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | help_relation | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | help_topic | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | proc | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | procs_priv | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | role_edges | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | time_zone | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | time_zone_name | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | time_zone_transition | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | time_zone_transition_type | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | user | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | ALL_OB_EXTERNAL_TABLE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_DB_LINKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_INDEX_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_IND_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_IND_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_IND_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVIEWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVIEW_LOGS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_CHANGE_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_RUN_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_STATS_PARAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_STATS_SYS_DEFAULTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_STMT_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OBJECTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ACCESS_POINT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ARCHIVELOG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ARCHIVELOG_PIECE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ARCHIVELOG_SUMMARY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ARCHIVE_DEST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_AUTO_INCREMENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_AUX_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_POLICY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_PARAMETER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_SET_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_STORAGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_STORAGE_INFO_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BALANCE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BALANCE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BALANCE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BALANCE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_CONCURRENT_LIMIT_SQL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_DATABASES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_DATABASE_PRIVILEGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_DATA_DICTIONARY_IN_LOG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_DEADLOCK_EVENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_EXTERNAL_TABLE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_FORMAT_OUTLINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_FREEZE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_IMPORT_TABLE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_IMPORT_TABLE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_IMPORT_TABLE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_IMPORT_TABLE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_KV_TTL_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_KV_TTL_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LOG_RESTORE_SOURCE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_ARB_REPLICA_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_ARB_REPLICA_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_LOCATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_LOG_ARCHIVE_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_REPLICA_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_REPLICA_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_MAJOR_COMPACTION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_OUTLINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_OUTLINE_CONCURRENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RECOVER_TABLE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RECOVER_TABLE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RESTORE_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RESTORE_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RSRC_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RSRC_IO_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_SEQUENCE_OBJECTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_SERVICES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_STORAGE_IO_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_SYS_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLEGROUPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLEGROUP_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLEGROUP_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLEGROUP_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLET_REPLICAS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLET_TO_LS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLE_LOCATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLE_STAT_STALE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TASK_OPT_STAT_GATHER_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TEMP_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TENANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TENANT_EVENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TRANSFER_PARTITION_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TRANSFER_PARTITION_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TRANSFER_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TRANSFER_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_USERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_USER_DEFINED_RULES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ZONE_MAJOR_COMPACTION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_INDEXES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_KEY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RECYCLEBIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RSRC_CONSUMER_GROUPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RSRC_GROUP_MAPPINGS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RSRC_PLANS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RSRC_PLAN_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SCHEDULER_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SCHEDULER_JOB_RUN_DETAILS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SCHEDULER_WINDOWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SEQUENCES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SQL_MANAGEMENT_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SQL_PLAN_BASELINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SUBPARTITION_TEMPLATES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SUBPART_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SUBPART_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SUBPART_KEY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_MODIFICATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_STATS_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_CONTROL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_SNAPSHOT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$DML_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$LATCH | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_ARBITRATION_MEMBER_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_ARBITRATION_SERVICE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_CGROUP_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_COMPACTION_DIAGNOSE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_COMPACTION_SUGGESTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_DTL_INTERM_RESULT_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_FLT_TRACE_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_FUNCTION_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_GROUP_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_KVCACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_KV_CLIENT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_KV_GROUP_COMMIT_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_LS_SNAPSHOTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_MEMSTORE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_MERGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_NIC_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_OPT_STAT_GATHER_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PLAN_CACHE_PLAN_EXPLAIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PLAN_CACHE_PLAN_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PLAN_CACHE_REFERENCE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PLAN_CACHE_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PL_CACHE_OBJECT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PS_ITEM_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PS_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PX_P2P_DATAHUB | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PX_TARGET_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PX_WORKER_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_RPC_INCOMING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_RPC_OUTGOING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SERVER_SCHEMA_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SESSION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SESSION_PS_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SHARED_STORAGE_QUOTA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SQL_AUDIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SQL_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SQL_WORKAREA_MEMORY_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SSTABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SS_LOCAL_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TABLET_COMPACTION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TABLET_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TABLET_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TENANT_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TENANT_RESOURCE_LIMIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TENANT_RESOURCE_LIMIT_DETAIL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_THREAD | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TRACEPOINT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TRANSACTION_PARTICIPANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TRANSACTION_SCHEDULERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_UNITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSION_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSION_LONGOPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSION_WAIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSION_WAIT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_JOIN_FILTER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_PLAN_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_WORKAREA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_WORKAREA_ACTIVE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_WORKAREA_HISTOGRAM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SYSTEM_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$DML_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$ENCRYPTED_TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$EVENT_NAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$LATCH | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_ARBITRATION_MEMBER_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_ARBITRATION_SERVICE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_ARCHIVE_DEST_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_CGROUP_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_COMPACTION_DIAGNOSE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_COMPACTION_SUGGESTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_COMPATIBILITY_CONTROL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_DTL_INTERM_RESULT_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_ENCRYPTED_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_FUNCTION_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_GROUP_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_KVCACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_KV_CLIENT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_KV_GROUP_COMMIT_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LS_LOG_RESTORE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LS_REPLICA_TASK_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LS_SNAPSHOTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_MEMSTORE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_MERGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_NIC_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_OPT_STAT_GATHER_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PLAN_CACHE_PLAN_EXPLAIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PLAN_CACHE_PLAN_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PLAN_CACHE_REFERENCE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PLAN_CACHE_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PL_CACHE_OBJECT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PS_ITEM_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PS_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PX_P2P_DATAHUB | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PX_TARGET_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PX_WORKER_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_RPC_INCOMING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_RPC_OUTGOING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SERVER_SCHEMA_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SESSION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SESSION_PS_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SHARED_STORAGE_QUOTA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SQL_AUDIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SQL_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SQL_WORKAREA_MEMORY_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SSTABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SS_LOCAL_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TABLET_COMPACTION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TABLET_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TABLET_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TENANT_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TENANT_RESOURCE_LIMIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TENANT_RESOURCE_LIMIT_DETAIL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_THREAD | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TIMESTAMP_SERVICE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TRACEPOINT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TRANSACTION_PARTICIPANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TRANSACTION_SCHEDULERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_UNITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$RSRC_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSION_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSION_LONGOPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSION_WAIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSION_WAIT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_JOIN_FILTER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_MONITOR_STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_PLAN_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_WORKAREA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_WORKAREA_ACTIVE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_WORKAREA_HISTOGRAM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SYSTEM_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __ALL_VIRTUAL_INFORMATION_COLUMNS | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_acquired_snapshot | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_audit_log_filter | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_audit_log_user | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_auto_increment | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_aux_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_balance_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_balance_job_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_balance_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_balance_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_client_to_server_session_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_coll_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_coll_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_group_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_group_mapping | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_group_mapping_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_usage | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_constraint | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_constraint_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_context | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_context_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_core_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dam_cleanup_jobs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dam_last_arch_ts | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_data_dictionary_in_log | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_database | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_database_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_database_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_database_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dblink | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dblink_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dbms_lock_allocated | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_checksum | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_error_message | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_id | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_operation | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_task_status | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_def_sub_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_def_sub_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_detect_lock_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dummy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_external_table_file | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_foreign_key | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_foreign_key_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_foreign_key_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_foreign_key_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_freeze_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_func | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_func_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_histogram_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_histogram_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_index_usage_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_job_log | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ls | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mlog | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mock_fk_parent_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mock_fk_parent_table_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mock_fk_parent_table_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mock_fk_parent_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_monitor_modified | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_dep | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_change_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_run_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_stats_params | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_stats_sys_defaults | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_stmt_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ncomp_dll | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_optstat_global_prefs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_optstat_user_prefs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ori_schema_version | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_outline | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_outline_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_package | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_package_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_part_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_part_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_pending_transaction | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_plan_baseline | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_plan_baseline_item | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_recyclebin | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_res_mgr_consumer_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_res_mgr_directive | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_res_mgr_mapping_rule | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_res_mgr_plan | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_attribute | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_attribute_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_context | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_context_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_group_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_policy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_policy_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_security_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_security_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_param | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_param_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_scheduler_job_run_detail_v2 | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sequence_object | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sequence_object_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sequence_value | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_spatial_reference_systems | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_spm_config | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sub_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sub_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_synonym | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_synonym_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sys_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sys_variable | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sys_variable_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablegroup | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablegroup_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablet_checksum | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablet_reorganize_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablet_to_ls | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablet_to_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_temp_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_constraint_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_constraint_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_dependency | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_directory | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_directory_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_error | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_keystore | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_keystore_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_objauth | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_objauth_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_object_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_object_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_component | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_component_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_label | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_label_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_policy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_policy_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_user_level | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_user_level_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_profile | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_profile_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_rewrite_rules | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_role_grantee_map | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_role_grantee_map_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_job_class | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_job_run_detail | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_program | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_program_argument | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_security_audit | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_security_audit_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_security_audit_record | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_sysauth | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_sysauth_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_tablespace | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_tablespace_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_time_zone | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_time_zone_name | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_time_zone_transition | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_time_zone_transition_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_trigger | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_trigger_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_transfer_partition_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_transfer_partition_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_transfer_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_transfer_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_type_attr | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_type_attr_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_proxy_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_proxy_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_proxy_role_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_proxy_role_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_apply_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_arbitration_member_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_arbitration_service_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_archive_dest_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_archive_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ash | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_audit_action | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_audit_operation | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_ls_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_ls_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_policy | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_set_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_storage_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_storage_info_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_cgroup_config | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_checkpoint_diagnose_checkpoint_unit_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_checkpoint_diagnose_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_checkpoint_diagnose_memtable_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_client_to_server_session_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_clone_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_clone_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_column_group_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_column_group_mapping | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_column_group_mapping_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_compaction_diagnose_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_compaction_suggestion | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_compatibility_control | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_core_all_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_core_column_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_core_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_data_type | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_data_type_class | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_deadlock_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_detect_lock_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dml_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dtl_interm_result_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dup_ls_lease_mgr | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dup_ls_tablet_set | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dup_ls_tablets | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_engine | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_flt_config | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_freeze_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_function_io_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_global_transaction | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_group_io_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_import_table_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_import_table_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_import_table_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_import_table_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_client_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_connection | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_group_commit_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_ttl_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_ttl_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kvcache_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_latch | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_lock_wait_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_archive_dest_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_archive_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_archive_piece_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_archive_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_restore_source | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_arb_replica_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_arb_replica_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_election_reference_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_log_archive_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_log_restore_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_recovery_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_replica_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_replica_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_replica_task_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_restore_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_restore_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_transfer_member_list_lock_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_malloc_sample_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mds_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mds_node_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_memstore_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_merge_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mlog | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_change_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_run_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_stats_params | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_stats_sys_defaults | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_stmt_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_nic_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_obj_lock | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_obrpc_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_open_cursor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_opt_stat_gather_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_plan_cache_plan_explain | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_plan_cache_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_plan_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_privilege | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_processlist | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_proxy_partition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_proxy_partition_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_proxy_schema | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_proxy_sub_partition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ps_item_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ps_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_px_p2p_datahub | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_px_target_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_px_worker_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_query_response_time | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_recover_table_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_recover_table_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_replay_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_res_mgr_directive | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_resource_pool_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_restore_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_restore_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_restore_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_server_compaction_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_server_compaction_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_server_schema_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_service | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_event | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_ps_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_wait | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_wait_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sesstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_shared_storage_quota | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_show_trace | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_audit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_monitor_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_plan_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_workarea_active | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_workarea_histogram | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_workarea_history_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_workarea_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ss_local_cache_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_storage_io_usage | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sys_variable_default_value | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sysstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_system_event | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_table_mgr | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_table_opt_stat_gather_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_checksum_error_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_compaction_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_compaction_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_compaction_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_encrypt_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_task_opt_stat_gather_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_temp_file | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_memstore_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_parameter_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_resource_limit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_resource_limit_detail | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot_ls | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot_ls_replica | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot_ls_replica_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_tablespace | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_user_failed_login_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_thread | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_timestamp_service | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_trace_span_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tracepoint_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_trans_lock_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_trans_scheduler | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_trans_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_transaction_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_transaction_freeze_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_unit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_user | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_vector_index_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_virtual_long_ops_status_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_active_session_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_control | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_sysstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_zone_merge_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_zone_storage_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_all_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_charset | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_collation | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_concurrent_limit_sql | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_current_tenant | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_database_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_event_name | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_global_variable | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_object_definition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_outline | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_privilege_grant | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_session_variable | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_database | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_procedure | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_tablegroup | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_trigger | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_tables | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_table_column | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_table_index | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_tenant_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_warning | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | ++---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+------------+------------------------+ test select * from information_schema.table_constraints where table_schema in ('oceanbase', 'mysql', 'information_schema') order by CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME; +--------------------+-------------------+-----------------+--------------+------------+-----------------+----------+ @@ -1485,6 +1488,14 @@ select * from information_schema.statistics where table_schema in ('oceanbase', | def | oceanbase | __all_tablet_checksum | 0 | oceanbase | PRIMARY | 2 | compaction_scn | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_checksum | 0 | oceanbase | PRIMARY | 3 | tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_checksum | 0 | oceanbase | PRIMARY | 4 | ls_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 2 | ls_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 3 | src_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 4 | dest_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_dest | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_dest | 2 | dest_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_src | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_src | 2 | src_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_to_ls | 0 | oceanbase | PRIMARY | 1 | tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_to_ls | 1 | oceanbase | idx_tablet_to_ls_id | 1 | ls_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_to_ls | 1 | oceanbase | idx_tablet_to_table_id | 1 | table_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | @@ -1745,803 +1756,804 @@ create database test1; use test1; create table t1tenant1(c1 bigint primary key, c2 bigint); select * from information_schema.tables where table_schema in ('oceanbase', 'mysql', 'information_schema', 'test1') order by TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME; -+---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+ -| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT | -+---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+ -| def | information_schema | CHARACTER_SETS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | CHECK_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | COLLATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | COLLATION_CHARACTER_SET_APPLICABILITY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | COLUMN_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ENABLED_ROLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ENGINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | EVENTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | GLOBAL_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | GLOBAL_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_BUFFER_PAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_BUFFER_PAGE_LRU | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_BUFFER_POOL_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMP | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMPMEM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMPMEM_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMP_PER_INDEX | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMP_PER_INDEX_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_CMP_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_FT_BEING_DELETED | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_FT_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_FT_DELETED | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_FT_INDEX_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_LOCK_WAITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_METRICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_DATAFILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_FIELDS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_FOREIGN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_FOREIGN_COLS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_INDEXES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_TABLESTATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_SYS_VIRTUAL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_TEMP_TABLE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | INNODB_TRX | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | KEY_COLUMN_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | NDB_TRANSID_MYSQL_CONNECTION_MAP | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | OPTIMIZER_TRACE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PLUGINS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | PROFILING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | QUERY_RESPONSE_TIME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | REFERENTIAL_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ROLE_COLUMN_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ROLE_ROUTINE_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ROLE_TABLE_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ROUTINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | SCHEMATA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | SCHEMA_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | SESSION_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | SESSION_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ST_GEOMETRY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | ST_SPATIAL_REFERENCE_SYSTEMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TABLE_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TABLE_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | TRIGGERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | USER_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | VIEWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | information_schema | VIEW_TABLE_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | audit_log_filter | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | audit_log_user | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | columns_priv | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | db | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | default_roles | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | func | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | help_category | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | help_keyword | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | help_relation | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | help_topic | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | proc | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | procs_priv | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | role_edges | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | time_zone | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | time_zone_name | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | time_zone_transition | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | time_zone_transition_type | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | mysql | user | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | ALL_OB_EXTERNAL_TABLE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_DB_LINKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_INDEX_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_IND_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_IND_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_IND_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVIEWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVIEW_LOGS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_CHANGE_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_RUN_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_STATS_PARAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_STATS_SYS_DEFAULTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_MVREF_STMT_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OBJECTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ACCESS_POINT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ARCHIVELOG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ARCHIVELOG_PIECE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ARCHIVELOG_SUMMARY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ARCHIVE_DEST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_AUTO_INCREMENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_AUX_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_POLICY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_DELETE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_PARAMETER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_SET_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_STORAGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_STORAGE_INFO_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BACKUP_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BALANCE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BALANCE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BALANCE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_BALANCE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_CONCURRENT_LIMIT_SQL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_DATABASES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_DATABASE_PRIVILEGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_DATA_DICTIONARY_IN_LOG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_DEADLOCK_EVENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_EXTERNAL_TABLE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_FORMAT_OUTLINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_FREEZE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_IMPORT_TABLE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_IMPORT_TABLE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_IMPORT_TABLE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_IMPORT_TABLE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_KV_TTL_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_KV_TTL_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LOG_RESTORE_SOURCE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_ARB_REPLICA_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_ARB_REPLICA_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_LOCATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_LOG_ARCHIVE_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_REPLICA_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_LS_REPLICA_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_MAJOR_COMPACTION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_OUTLINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_OUTLINE_CONCURRENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RECOVER_TABLE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RECOVER_TABLE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RESTORE_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RESTORE_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RSRC_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_RSRC_IO_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_SEQUENCE_OBJECTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_SERVICES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_STORAGE_IO_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_SYS_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLEGROUPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLEGROUP_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLEGROUP_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLEGROUP_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLET_REPLICAS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLET_TO_LS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLE_LOCATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TABLE_STAT_STALE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TASK_OPT_STAT_GATHER_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TEMP_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TENANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TENANT_EVENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TRANSFER_PARTITION_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TRANSFER_PARTITION_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TRANSFER_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_TRANSFER_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_USERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_USER_DEFINED_RULES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_OB_ZONE_MAJOR_COMPACTION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_INDEXES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_KEY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_PART_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RECYCLEBIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RSRC_CONSUMER_GROUPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RSRC_GROUP_MAPPINGS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RSRC_PLANS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_RSRC_PLAN_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SCHEDULER_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SCHEDULER_JOB_RUN_DETAILS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SCHEDULER_WINDOWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SEQUENCES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SQL_MANAGEMENT_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SQL_PLAN_BASELINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SUBPARTITION_TEMPLATES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SUBPART_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SUBPART_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_SUBPART_KEY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_MODIFICATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_STATS_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_TAB_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_CONTROL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_SNAPSHOT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | DBA_WR_SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$DML_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$LATCH | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_ARBITRATION_MEMBER_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_ARBITRATION_SERVICE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_CGROUP_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_COMPACTION_DIAGNOSE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_COMPACTION_SUGGESTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_DTL_INTERM_RESULT_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_FLT_TRACE_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_FUNCTION_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_GROUP_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_KVCACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_KV_CLIENT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_KV_GROUP_COMMIT_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_MERGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_NIC_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_OPT_STAT_GATHER_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PLAN_CACHE_PLAN_EXPLAIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PLAN_CACHE_PLAN_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PLAN_CACHE_REFERENCE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PLAN_CACHE_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PL_CACHE_OBJECT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PS_ITEM_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PS_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PX_P2P_DATAHUB | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PX_TARGET_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_PX_WORKER_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_RPC_INCOMING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_RPC_OUTGOING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SERVER_SCHEMA_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SESSION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SESSION_PS_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SHARED_STORAGE_QUOTA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SQL_AUDIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SQL_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SQL_WORKAREA_MEMORY_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SSTABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_SS_LOCAL_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TABLET_COMPACTION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TABLET_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TABLET_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TENANT_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TENANT_RESOURCE_LIMIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TENANT_RESOURCE_LIMIT_DETAIL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_THREAD | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TRACEPOINT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TRANSACTION_PARTICIPANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_TRANSACTION_SCHEDULERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$OB_UNITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSION_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSION_LONGOPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSION_WAIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSION_WAIT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SESSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_JOIN_FILTER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_PLAN_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_WORKAREA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_WORKAREA_ACTIVE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SQL_WORKAREA_HISTOGRAM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | GV$SYSTEM_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$DML_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$ENCRYPTED_TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$EVENT_NAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$LATCH | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_ARBITRATION_MEMBER_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_ARBITRATION_SERVICE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_ARCHIVE_DEST_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_CGROUP_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_COMPACTION_DIAGNOSE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_COMPACTION_SUGGESTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_COMPATIBILITY_CONTROL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_DTL_INTERM_RESULT_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_ENCRYPTED_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_FUNCTION_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_GROUP_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_KVCACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_KV_CLIENT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_KV_GROUP_COMMIT_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_MERGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_NIC_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_OPT_STAT_GATHER_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PLAN_CACHE_PLAN_EXPLAIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PLAN_CACHE_PLAN_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PLAN_CACHE_REFERENCE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PLAN_CACHE_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PL_CACHE_OBJECT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PS_ITEM_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PS_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PX_P2P_DATAHUB | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PX_TARGET_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_PX_WORKER_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_RPC_INCOMING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_RPC_OUTGOING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SERVER_SCHEMA_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SESSION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SESSION_PS_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SHARED_STORAGE_QUOTA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SQL_AUDIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SQL_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SQL_WORKAREA_MEMORY_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SSTABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_SS_LOCAL_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TABLET_COMPACTION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TABLET_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TABLET_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TENANT_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TENANT_RESOURCE_LIMIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TENANT_RESOURCE_LIMIT_DETAIL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_THREAD | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TIMESTAMP_SERVICE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TRACEPOINT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TRANSACTION_PARTICIPANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_TRANSACTION_SCHEDULERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$OB_UNITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$RSRC_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSION_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSION_LONGOPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSION_WAIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSION_WAIT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SESSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_JOIN_FILTER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_MONITOR_STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_PLAN_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_WORKAREA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_WORKAREA_ACTIVE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SQL_WORKAREA_HISTOGRAM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | V$SYSTEM_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_acquired_snapshot | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_audit_log_filter | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_audit_log_user | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_auto_increment | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_aux_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_balance_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_balance_job_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_balance_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_balance_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_client_to_server_session_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_coll_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_coll_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_group_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_group_mapping | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_group_mapping_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_column_usage | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_constraint | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_constraint_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_context | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_context_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_core_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dam_cleanup_jobs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dam_last_arch_ts | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_database | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_database_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_database_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_database_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_data_dictionary_in_log | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dblink | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dblink_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dbms_lock_allocated | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_checksum | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_error_message | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_id | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_operation | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ddl_task_status | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_def_sub_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_def_sub_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_detect_lock_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_dummy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_external_table_file | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_foreign_key | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_foreign_key_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_foreign_key_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_foreign_key_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_freeze_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_func | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_func_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_histogram_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_histogram_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_index_usage_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_job_log | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ls | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mlog | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mock_fk_parent_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mock_fk_parent_table_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mock_fk_parent_table_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mock_fk_parent_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_monitor_modified | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_dep | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_change_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_run_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_stats_params | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_stats_sys_defaults | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_mview_refresh_stmt_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ncomp_dll | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_optstat_global_prefs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_optstat_user_prefs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_ori_schema_version | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_outline | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_outline_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_package | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_package_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_part_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_part_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_pending_transaction | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_plan_baseline | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_plan_baseline_item | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_recyclebin | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_res_mgr_consumer_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_res_mgr_directive | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_res_mgr_mapping_rule | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_res_mgr_plan | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_attribute | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_attribute_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_context | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_context_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_group_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_policy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_policy_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_security_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_rls_security_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_param | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_param_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_routine_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_scheduler_job_run_detail_v2 | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sequence_object | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sequence_object_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sequence_value | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_spatial_reference_systems | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_spm_config | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sub_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sub_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_synonym | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_synonym_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sys_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sys_variable | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_sys_variable_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablegroup | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablegroup_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablet_checksum | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablet_to_ls | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tablet_to_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_table_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_temp_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_constraint_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_constraint_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_dependency | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_directory | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_directory_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_error | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_keystore | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_keystore_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_objauth | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_objauth_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_object_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_object_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_component | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_component_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_label | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_label_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_policy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_policy_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_user_level | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_ols_user_level_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_profile | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_profile_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_rewrite_rules | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_role_grantee_map | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_role_grantee_map_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_job_class | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_job_run_detail | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_program | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_scheduler_program_argument | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_security_audit | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_security_audit_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_security_audit_record | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_sysauth | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_sysauth_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_tablespace | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_tablespace_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_time_zone | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_time_zone_name | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_time_zone_transition | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_time_zone_transition_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_trigger | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_tenant_trigger_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_transfer_partition_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_transfer_partition_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_transfer_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_transfer_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_type_attr | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_type_attr_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_proxy_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_proxy_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_proxy_role_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_user_proxy_role_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_apply_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_arbitration_member_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_arbitration_service_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_archive_dest_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_archive_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ash | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_audit_action | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_audit_operation | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_ls_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_ls_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_policy | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_delete_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_set_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_storage_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_storage_info_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_backup_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_cgroup_config | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_checkpoint_diagnose_checkpoint_unit_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_checkpoint_diagnose_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_checkpoint_diagnose_memtable_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_client_to_server_session_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_column_group_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_column_group_mapping | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_column_group_mapping_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_compatibility_control | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_core_column_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_core_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_data_type | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_data_type_class | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_deadlock_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_detect_lock_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dml_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dtl_interm_result_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dup_ls_lease_mgr | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dup_ls_tablets | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_dup_ls_tablet_set | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_engine | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_flt_config | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_freeze_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_function_io_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_global_transaction | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_group_io_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_import_table_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_import_table_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_import_table_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_import_table_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __ALL_VIRTUAL_INFORMATION_COLUMNS | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kvcache_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_client_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_connection | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_group_commit_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_ttl_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_kv_ttl_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_latch | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_lock_wait_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_archive_dest_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_archive_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_archive_piece_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_archive_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_restore_source | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_log_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_arb_replica_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_arb_replica_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_election_reference_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_log_archive_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_log_restore_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_recovery_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_replica_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_replica_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ls_replica_task_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mds_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mds_node_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_memstore_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_merge_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mlog | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_change_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_run_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_stats_params | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_stats_sys_defaults | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_mview_refresh_stmt_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_nic_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_obj_lock | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_obrpc_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_open_cursor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_opt_stat_gather_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_plan_cache_plan_explain | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_plan_cache_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_plan_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_privilege | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_processlist | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_proxy_partition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_proxy_partition_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_proxy_schema | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_proxy_sub_partition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ps_item_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ps_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_px_p2p_datahub | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_px_target_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_px_worker_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_query_response_time | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_recover_table_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_recover_table_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_replay_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_resource_pool_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_restore_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_restore_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_restore_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_res_mgr_directive | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_server_compaction_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_server_compaction_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_server_schema_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_service | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_event | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_ps_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_wait | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_session_wait_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sesstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_shared_storage_quota | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_show_trace | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_audit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_monitor_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_plan_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_workarea_active | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_workarea_histogram | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_workarea_history_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sql_workarea_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_ss_local_cache_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_storage_io_usage | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sysstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_system_event | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_sys_variable_default_value | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_checksum_error_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_compaction_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_compaction_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_compaction_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_encrypt_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tablet_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_table_mgr | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_table_opt_stat_gather_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_task_opt_stat_gather_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_temp_file | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_memstore_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_resource_limit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tenant_resource_limit_detail | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | 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 | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_thread | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_timestamp_service | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_tracepoint_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_trace_span_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_transaction_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_transaction_freeze_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_trans_lock_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_trans_scheduler | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_trans_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_unit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_user | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_vector_index_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_virtual_long_ops_status_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_active_session_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_control | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_wr_sysstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_zone_merge_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __all_virtual_zone_storage_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_all_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_charset | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_collation | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_concurrent_limit_sql | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_current_tenant | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_database_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_event_name | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_global_variable | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_object_definition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_outline | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_privilege_grant | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_session_variable | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_database | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_procedure | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_tablegroup | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_create_trigger | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_show_tables | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_table_column | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_table_index | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_tenant_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | oceanbase | __tenant_virtual_warning | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -| def | test1 | t1tenant1 | BASE TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | -+---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+ ++---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+------------+------------------------+ +| TABLE_CATALOG | TABLE_SCHEMA | TABLE_NAME | TABLE_TYPE | ENGINE | VERSION | ROW_FORMAT | TABLE_ROWS | AVG_ROW_LENGTH | DATA_LENGTH | MAX_DATA_LENGTH | INDEX_LENGTH | DATA_FREE | AUTO_INCREMENT | CREATE_TIME | UPDATE_TIME | CHECK_TIME | TABLE_COLLATION | CHECKSUM | CREATE_OPTIONS | TABLE_COMMENT | AUTO_SPLIT | AUTO_SPLIT_TABLET_SIZE | ++---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+------------+------------------------+ +| def | information_schema | CHARACTER_SETS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | CHECK_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | COLLATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | COLLATION_CHARACTER_SET_APPLICABILITY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | COLUMN_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | CONNECTION_CONTROL_FAILED_LOGIN_ATTEMPTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ENABLED_ROLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ENGINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | EVENTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | GLOBAL_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | GLOBAL_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_BUFFER_PAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_BUFFER_PAGE_LRU | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_BUFFER_POOL_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMP | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMPMEM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMPMEM_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMP_PER_INDEX | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMP_PER_INDEX_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_CMP_RESET | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_FT_BEING_DELETED | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_FT_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_FT_DELETED | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_FT_INDEX_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_LOCK_WAITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_METRICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_DATAFILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_FIELDS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_FOREIGN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_FOREIGN_COLS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_INDEXES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_TABLESTATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_SYS_VIRTUAL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_TEMP_TABLE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | INNODB_TRX | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | KEY_COLUMN_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | NDB_TRANSID_MYSQL_CONNECTION_MAP | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | OPTIMIZER_TRACE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PLUGINS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | PROFILING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | QUERY_RESPONSE_TIME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | REFERENTIAL_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ROLE_COLUMN_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ROLE_ROUTINE_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ROLE_TABLE_GRANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ROUTINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | SCHEMATA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | SCHEMA_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | SESSION_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | SESSION_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ST_GEOMETRY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | ST_SPATIAL_REFERENCE_SYSTEMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TABLE_CONSTRAINTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TABLE_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | TRIGGERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | USER_PRIVILEGES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | VIEWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | information_schema | VIEW_TABLE_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | audit_log_filter | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | audit_log_user | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | columns_priv | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | db | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | default_roles | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | func | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | help_category | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | help_keyword | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | help_relation | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | help_topic | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | proc | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | procs_priv | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | role_edges | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | time_zone | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | time_zone_name | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | time_zone_transition | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | time_zone_transition_type | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | mysql | user | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | ALL_OB_EXTERNAL_TABLE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_DB_LINKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_INDEX_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_IND_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_IND_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_IND_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVIEWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVIEW_LOGS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_CHANGE_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_RUN_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_STATS_PARAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_STATS_SYS_DEFAULTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_MVREF_STMT_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OBJECTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ACCESS_POINT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ARCHIVELOG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ARCHIVELOG_PIECE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ARCHIVELOG_SUMMARY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ARCHIVE_DEST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_AUTO_INCREMENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_AUX_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_POLICY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_DELETE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_PARAMETER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_SET_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_STORAGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_STORAGE_INFO_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BACKUP_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BALANCE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BALANCE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BALANCE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_BALANCE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_CONCURRENT_LIMIT_SQL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_DATABASES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_DATABASE_PRIVILEGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_DATA_DICTIONARY_IN_LOG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_DEADLOCK_EVENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_EXTERNAL_TABLE_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_FORMAT_OUTLINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_FREEZE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_IMPORT_TABLE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_IMPORT_TABLE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_IMPORT_TABLE_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_IMPORT_TABLE_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_KV_TTL_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_KV_TTL_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LOG_RESTORE_SOURCE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_ARB_REPLICA_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_ARB_REPLICA_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_LOCATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_LOG_ARCHIVE_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_REPLICA_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_LS_REPLICA_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_MAJOR_COMPACTION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_OUTLINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_OUTLINE_CONCURRENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RECOVER_TABLE_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RECOVER_TABLE_JOB_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RESTORE_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RESTORE_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RSRC_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_RSRC_IO_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_SEQUENCE_OBJECTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_SERVICES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_STORAGE_IO_USAGE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_SYS_VARIABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLEGROUPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLEGROUP_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLEGROUP_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLEGROUP_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLET_REPLICAS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLET_TO_LS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLE_LOCATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLE_OPT_STAT_GATHER_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TABLE_STAT_STALE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TASK_OPT_STAT_GATHER_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TEMP_FILES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TENANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TENANT_EVENT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TRANSFER_PARTITION_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TRANSFER_PARTITION_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TRANSFER_TASKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_TRANSFER_TASK_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_USERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_USER_DEFINED_RULES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_OB_ZONE_MAJOR_COMPACTION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_INDEXES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_KEY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_PART_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RECYCLEBIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RSRC_CONSUMER_GROUPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RSRC_GROUP_MAPPINGS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RSRC_PLANS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_RSRC_PLAN_DIRECTIVES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SCHEDULER_JOBS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SCHEDULER_JOB_RUN_DETAILS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SCHEDULER_WINDOWS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SEQUENCES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SQL_MANAGEMENT_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SQL_PLAN_BASELINES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SUBPARTITION_TEMPLATES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SUBPART_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SUBPART_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_SUBPART_KEY_COLUMNS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_COL_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_HISTOGRAMS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_MODIFICATIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_PARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_STATISTICS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_STATS_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_TAB_SUBPARTITIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_CONTROL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_SNAPSHOT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | DBA_WR_SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$DML_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$LATCH | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_ARBITRATION_MEMBER_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_ARBITRATION_SERVICE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_CGROUP_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_COMPACTION_DIAGNOSE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_COMPACTION_SUGGESTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_DTL_INTERM_RESULT_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_FLT_TRACE_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_FUNCTION_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_GROUP_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_KVCACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_KV_CLIENT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_KV_GROUP_COMMIT_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_LS_SNAPSHOTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_MEMSTORE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_MERGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_NIC_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_OPT_STAT_GATHER_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PLAN_CACHE_PLAN_EXPLAIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PLAN_CACHE_PLAN_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PLAN_CACHE_REFERENCE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PLAN_CACHE_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PL_CACHE_OBJECT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PS_ITEM_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PS_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PX_P2P_DATAHUB | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PX_TARGET_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_PX_WORKER_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_RPC_INCOMING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_RPC_OUTGOING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SERVER_SCHEMA_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SESSION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SESSION_PS_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SHARED_STORAGE_QUOTA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SQL_AUDIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SQL_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SQL_WORKAREA_MEMORY_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SSTABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_SS_LOCAL_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TABLET_COMPACTION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TABLET_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TABLET_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TENANT_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TENANT_RESOURCE_LIMIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TENANT_RESOURCE_LIMIT_DETAIL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_THREAD | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TRACEPOINT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TRANSACTION_PARTICIPANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_TRANSACTION_SCHEDULERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$OB_UNITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSION_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSION_LONGOPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSION_WAIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSION_WAIT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SESSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_JOIN_FILTER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_PLAN_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_WORKAREA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_WORKAREA_ACTIVE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SQL_WORKAREA_HISTOGRAM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | GV$SYSTEM_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$ACTIVE_SESSION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$DML_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$ENCRYPTED_TABLESPACES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$EVENT_NAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$LATCH | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_ARBITRATION_MEMBER_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_ARBITRATION_SERVICE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_ARCHIVE_DEST_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_CGROUP_CONFIG | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_COMPACTION_DIAGNOSE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_COMPACTION_SUGGESTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_COMPATIBILITY_CONTROL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_DTL_INTERM_RESULT_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_ENCRYPTED_TABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_FUNCTION_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_GROUP_IO_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_KVCACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_KV_CLIENT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_KV_CONNECTIONS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_KV_GROUP_COMMIT_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LOCKS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LOG_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LS_LOG_RESTORE_STATUS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LS_REPLICA_TASK_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_LS_SNAPSHOTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_MEMSTORE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_MEMSTORE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_MERGE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_NIC_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_OPT_STAT_GATHER_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PARAMETERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PLAN_CACHE_PLAN_EXPLAIN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PLAN_CACHE_PLAN_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PLAN_CACHE_REFERENCE_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PLAN_CACHE_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PL_CACHE_OBJECT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PROCESSLIST | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PS_ITEM_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PS_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PX_P2P_DATAHUB | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PX_TARGET_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_PX_WORKER_STAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_RPC_INCOMING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_RPC_OUTGOING | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SERVER_SCHEMA_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SESSION | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SESSION_PS_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SHARED_STORAGE_QUOTA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SQL_AUDIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SQL_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SQL_WORKAREA_MEMORY_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SSTABLES | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_SS_LOCAL_CACHE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TABLET_COMPACTION_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TABLET_COMPACTION_PROGRESS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TABLET_STATS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TENANT_MEMORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TENANT_RESOURCE_LIMIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TENANT_RESOURCE_LIMIT_DETAIL | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_THREAD | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TIMESTAMP_SERVICE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TRACEPOINT_INFO | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TRANSACTION_PARTICIPANTS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_TRANSACTION_SCHEDULERS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$OB_UNITS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$RSRC_PLAN | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSION_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSION_LONGOPS | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSION_WAIT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSION_WAIT_HISTORY | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SESSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_JOIN_FILTER | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_MONITOR_STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_PLAN_MONITOR | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_WORKAREA | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_WORKAREA_ACTIVE | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SQL_WORKAREA_HISTOGRAM | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$STATNAME | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SYSSTAT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | V$SYSTEM_EVENT | SYSTEM VIEW | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_acquired_snapshot | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_audit_log_filter | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_audit_log_user | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_auto_increment | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_aux_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_balance_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_balance_job_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_balance_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_balance_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_client_to_server_session_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_coll_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_coll_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_group_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_group_mapping | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_group_mapping_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_column_usage | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_constraint | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_constraint_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_context | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_context_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_core_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dam_cleanup_jobs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dam_last_arch_ts | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_database | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_database_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_database_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_database_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_data_dictionary_in_log | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dblink | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dblink_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dbms_lock_allocated | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_checksum | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_error_message | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_id | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_operation | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ddl_task_status | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_def_sub_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_def_sub_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_detect_lock_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_dummy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_external_table_file | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_foreign_key | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_foreign_key_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_foreign_key_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_foreign_key_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_freeze_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_func | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_func_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_histogram_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_histogram_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_index_usage_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_job_log | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ls | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mlog | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mock_fk_parent_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mock_fk_parent_table_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mock_fk_parent_table_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mock_fk_parent_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_monitor_modified | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_dep | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_change_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_run_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_stats_params | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_stats_sys_defaults | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_mview_refresh_stmt_stats | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ncomp_dll | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_optstat_global_prefs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_optstat_user_prefs | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_ori_schema_version | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_outline | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_outline_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_package | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_package_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_part_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_part_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_pending_transaction | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_plan_baseline | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_plan_baseline_item | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_recyclebin | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_res_mgr_consumer_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_res_mgr_directive | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_res_mgr_mapping_rule | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_res_mgr_plan | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_attribute | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_attribute_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_context | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_context_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_group | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_group_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_policy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_policy_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_security_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_rls_security_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_param | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_param_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_routine_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_scheduler_job_run_detail_v2 | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sequence_object | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sequence_object_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sequence_value | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_spatial_reference_systems | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_spm_config | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sub_part | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sub_part_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_synonym | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_synonym_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sys_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sys_variable | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_sys_variable_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablegroup | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablegroup_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablet_checksum | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablet_reorganize_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablet_to_ls | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tablet_to_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_privilege | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_privilege_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_stat | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_table_stat_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_temp_table | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_constraint_column | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_constraint_column_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_dependency | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_directory | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_directory_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_error | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_keystore | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_keystore_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_objauth | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_objauth_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_object_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_object_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_component | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_component_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_label | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_label_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_policy | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_policy_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_user_level | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_ols_user_level_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_profile | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_profile_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_rewrite_rules | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_role_grantee_map | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_role_grantee_map_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_job | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_job_class | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_job_run_detail | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_program | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_scheduler_program_argument | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_security_audit | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_security_audit_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_security_audit_record | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_sysauth | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_sysauth_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_tablespace | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_tablespace_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_time_zone | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_time_zone_name | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_time_zone_transition | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_time_zone_transition_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_trigger | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_tenant_trigger_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_transfer_partition_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_transfer_partition_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_transfer_task | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_transfer_task_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_type | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_type_attr | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_type_attr_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_type_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_proxy_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_proxy_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_proxy_role_info | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_user_proxy_role_info_history | SYSTEM TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_apply_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_arbitration_member_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_arbitration_service_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_archive_dest_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_archive_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ash | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_audit_action | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_audit_operation | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_ls_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_ls_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_policy | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_delete_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_set_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_storage_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_storage_info_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_backup_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_cgroup_config | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_checkpoint_diagnose_checkpoint_unit_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_checkpoint_diagnose_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_checkpoint_diagnose_memtable_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_client_to_server_session_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_clone_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_clone_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_column_group_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_column_group_mapping | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_column_group_mapping_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_compaction_diagnose_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_compaction_suggestion | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_compatibility_control | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_core_all_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_core_column_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_core_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_data_type | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_data_type_class | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_deadlock_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_detect_lock_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dml_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dtl_interm_result_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dup_ls_lease_mgr | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dup_ls_tablets | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_dup_ls_tablet_set | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_engine | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_flt_config | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_freeze_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_function_io_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_global_transaction | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_group_io_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_import_table_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_import_table_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_import_table_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_import_table_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __ALL_VIRTUAL_INFORMATION_COLUMNS | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kvcache_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_client_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_connection | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_group_commit_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_ttl_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_kv_ttl_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_latch | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_lock_wait_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_archive_dest_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_archive_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_archive_piece_files | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_archive_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_restore_source | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_log_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_arb_replica_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_arb_replica_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_election_reference_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_log_archive_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_log_restore_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_recovery_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_replica_task | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_replica_task_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_replica_task_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_restore_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_restore_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ls_transfer_member_list_lock_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_malloc_sample_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mds_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mds_node_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_memstore_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_merge_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mlog | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_change_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_run_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_stats_params | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_stats_sys_defaults | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_mview_refresh_stmt_stats | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_nic_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_obj_lock | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_obrpc_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_open_cursor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_opt_stat_gather_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_plan_cache_plan_explain | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_plan_cache_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_plan_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_privilege | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_processlist | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_proxy_partition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_proxy_partition_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_proxy_schema | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_proxy_sub_partition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ps_item_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ps_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_px_p2p_datahub | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_px_target_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_px_worker_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_query_response_time | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_recover_table_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_recover_table_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_replay_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_resource_pool_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_restore_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_restore_job_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_restore_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_res_mgr_directive | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_server_compaction_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_server_compaction_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_server_schema_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_service | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_event | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_ps_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_wait | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_session_wait_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sesstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_shared_storage_quota | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_show_trace | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_audit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_monitor_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_plan | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_plan_monitor | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_workarea_active | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_workarea_histogram | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_workarea_history_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sql_workarea_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_ss_local_cache_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_storage_io_usage | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sysstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_system_event | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_sys_variable_default_value | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_checksum_error_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_compaction_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_compaction_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_compaction_progress | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_encrypt_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_meta_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tablet_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_table_mgr | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_table_opt_stat_gather_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_task_opt_stat_gather_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_temp_file | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_event_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_memory_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_memstore_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_parameter | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_parameter_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_resource_limit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_resource_limit_detail | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot_job | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot_ls | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot_ls_replica | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_snapshot_ls_replica_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_tablespace | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tenant_user_failed_login_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_thread | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_timestamp_service | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_tracepoint_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_trace_span_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_transaction_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_transaction_freeze_checkpoint | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_trans_lock_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_trans_scheduler | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_trans_stat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_unit | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_user | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_vector_index_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_virtual_long_ops_status_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_active_session_history | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_control | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_snapshot | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_wr_sysstat | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_zone_merge_info | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __all_virtual_zone_storage_mysql_sys_agent | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_all_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_charset | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_collation | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_concurrent_limit_sql | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_current_tenant | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_database_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_event_name | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_global_variable | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_object_definition | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_outline | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_privilege_grant | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_session_variable | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_database | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_procedure | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_table | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_tablegroup | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_create_trigger | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_show_tables | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_statname | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_table_column | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_table_index | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_tenant_status | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | oceanbase | __tenant_virtual_warning | SYSTEM TABLE | MEMORY | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | +| def | test1 | t1tenant1 | BASE TABLE | InnoDB | NULL | DYNAMIC | NULL | NULL | NULL | NULL | 0 | NULL | NULL | NULL | NULL | NULL | utf8mb4_general_ci | NULL | NULL | | FALSE | 0 | ++---------------+--------------------+--------------------------------------------------------+--------------+--------+---------+------------+------------+----------------+-------------+-----------------+--------------+-----------+----------------+---------------------+---------------------+------------+--------------------+----------+----------------+---------------+------------+------------------------+ create index t1tenant1_idx1 on t1tenant1(c2, c1); create unique index t1tenant1_uidx on t1tenant1(c2); @@ -3333,6 +3345,14 @@ select * from information_schema.statistics where table_schema in ('oceanbase', | def | oceanbase | __all_tablet_meta_table | 0 | oceanbase | PRIMARY | 3 | ls_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_meta_table | 0 | oceanbase | PRIMARY | 4 | svr_ip | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_meta_table | 0 | oceanbase | PRIMARY | 5 | svr_port | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 2 | ls_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 3 | src_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 4 | dest_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_dest | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_dest | 2 | dest_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_src | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_src | 2 | src_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_replica_checksum | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_replica_checksum | 0 | oceanbase | PRIMARY | 2 | tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_replica_checksum | 0 | oceanbase | PRIMARY | 3 | svr_ip | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | @@ -4159,6 +4179,14 @@ select * from information_schema.statistics where table_schema in ('oceanbase', | def | oceanbase | __all_tablet_checksum | 0 | oceanbase | PRIMARY | 2 | compaction_scn | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_checksum | 0 | oceanbase | PRIMARY | 3 | tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_checksum | 0 | oceanbase | PRIMARY | 4 | ls_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 2 | ls_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 3 | src_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 0 | oceanbase | PRIMARY | 4 | dest_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_dest | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_dest | 2 | dest_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_src | 1 | tenant_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | +| def | oceanbase | __all_tablet_reorganize_history | 1 | oceanbase | idx_tablet_his_table_id_src | 2 | src_tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_to_ls | 0 | oceanbase | PRIMARY | 1 | tablet_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_to_ls | 1 | oceanbase | idx_tablet_to_ls_id | 1 | ls_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | | def | oceanbase | __all_tablet_to_ls | 1 | oceanbase | idx_tablet_to_table_id | 1 | table_id | A | NULL | NULL | NULL | | BTREE | VALID | | YES | NULL | diff --git a/tools/deploy/mysql_test/test_suite/information_schema/r/mysql/information_schema_desc.result b/tools/deploy/mysql_test/test_suite/information_schema/r/mysql/information_schema_desc.result index 047d5ba5a..be0757b66 100644 --- a/tools/deploy/mysql_test/test_suite/information_schema/r/mysql/information_schema_desc.result +++ b/tools/deploy/mysql_test/test_suite/information_schema/r/mysql/information_schema_desc.result @@ -183,6 +183,8 @@ TABLE_COLLATION varchar(32) NO CHECKSUM bigint(0) unsigned NO CREATE_OPTIONS varchar(255) NO TABLE_COMMENT text NO +AUTO_SPLIT varchar(16) NO +AUTO_SPLIT_TABLET_SIZE bigint(20) unsigned NO desc user_privileges; Field Type Null Key Default Extra GRANTEE varchar(81) NO @@ -248,7 +250,7 @@ View Create View character_set_client collation_connection KEY_COLUMN_USAGE CREATE VIEW `KEY_COLUMN_USAGE` AS (select 'def' as CONSTRAINT_CATALOG, c.database_name collate utf8mb4_name_case as CONSTRAINT_SCHEMA, 'PRIMARY' as CONSTRAINT_NAME, 'def' as TABLE_CATALOG, c.database_name collate utf8mb4_name_case as TABLE_SCHEMA, a.table_name collate utf8mb4_name_case as TABLE_NAME, b.column_name as COLUMN_NAME, b.rowkey_position as ORDINAL_POSITION, CAST(NULL AS UNSIGNED) as POSITION_IN_UNIQUE_CONSTRAINT, CAST(NULL AS CHAR(64)) as REFERENCED_TABLE_SCHEMA, CAST(NULL AS CHAR(64)) as REFERENCED_TABLE_NAME, CAST(NULL AS CHAR(64)) as REFERENCED_COLUMN_NAME from oceanbase.__all_table a join oceanbase.__all_column b on a.tenant_id = b.tenant_id and a.table_id = b.table_id join oceanbase.__all_database c on a.tenant_id = c.tenant_id and a.database_id = c.database_id where a.tenant_id = 0 and a.table_mode >> 12 & 15 in (0,1) and c.in_recyclebin = 0 and c.database_name != '__recyclebin' and b.rowkey_position > 0 and b.column_id >= 16 and a.table_type != 5 and a.table_type != 12 and a.table_type != 13 and b.column_flags & (0x1 << 8) = 0) union all (select 'def' as CONSTRAINT_CATALOG, d.database_name collate utf8mb4_name_case as CONSTRAINT_SCHEMA, substr(a.table_name, 2 + length(substring_index(a.table_name,'_',4))) as CONSTRAINT_NAME, 'def' as TABLE_CATALOG, d.database_name collate utf8mb4_name_case as TABLE_SCHEMA, c.table_name collate utf8mb4_name_case as TABLE_NAME, b.column_name as COLUMN_NAME, b.index_position as ORDINAL_POSITION, CAST(NULL AS UNSIGNED) as POSITION_IN_UNIQUE_CONSTRAINT, CAST(NULL AS CHAR(64)) as REFERENCED_TABLE_SCHEMA, CAST(NULL AS CHAR(64)) as REFERENCED_TABLE_NAME, CAST(NULL AS CHAR(64)) as REFERENCED_COLUMN_NAME from oceanbase.__all_table a join oceanbase.__all_column b on a.tenant_id = b.tenant_id and a.table_id = b.table_id join oceanbase.__all_table c on a.tenant_id = c.tenant_id and a.data_table_id = c.table_id join oceanbase.__all_database d on a.tenant_id = d.tenant_id and c.database_id = d.database_id where a.tenant_id = 0 and d.in_recyclebin = 0 and d.database_name != '__recyclebin' and a.table_type = 5 and a.index_type in (2, 4, 8) and b.index_position > 0) union all (select 'def' as CONSTRAINT_CATALOG, d.database_name collate utf8mb4_name_case as CONSTRAINT_SCHEMA, f.foreign_key_name as CONSTRAINT_NAME, 'def' as TABLE_CATALOG, d.database_name collate utf8mb4_name_case as TABLE_SCHEMA, t.table_name collate utf8mb4_name_case as TABLE_NAME, c.column_name as COLUMN_NAME, fc.position as ORDINAL_POSITION, CAST(fc.position AS UNSIGNED) as POSITION_IN_UNIQUE_CONSTRAINT, d2.database_name as REFERENCED_TABLE_SCHEMA, t2.table_name as REFERENCED_TABLE_NAME, c2.column_name as REFERENCED_COLUMN_NAME from oceanbase.__all_foreign_key f join oceanbase.__all_table t on f.tenant_id = t.tenant_id and f.child_table_id = t.table_id join oceanbase.__all_database d on f.tenant_id = d.tenant_id and t.database_id = d.database_id join oceanbase.__all_foreign_key_column fc on f.tenant_id = fc.tenant_id and f.foreign_key_id = fc.foreign_key_id join oceanbase.__all_column c on f.tenant_id = c.tenant_id and fc.child_column_id = c.column_id and t.table_id = c.table_id join oceanbase.__all_table t2 on f.tenant_id = t2.tenant_id and f.parent_table_id = t2.table_id join oceanbase.__all_database d2 on f.tenant_id = d2.tenant_id and t2.database_id = d2.database_id join oceanbase.__all_column c2 on f.tenant_id = c2.tenant_id and fc.parent_column_id = c2.column_id and t2.table_id = c2.table_id where f.tenant_id = 0) union all (select 'def' as CONSTRAINT_CATALOG, d.database_name collate utf8mb4_name_case as CONSTRAINT_SCHEMA, f.foreign_key_name as CONSTRAINT_NAME, 'def' as TABLE_CATALOG, d.database_name collate utf8mb4_name_case as TABLE_SCHEMA, t.table_name collate utf8mb4_name_case as TABLE_NAME, c.column_name as COLUMN_NAME, fc.position as ORDINAL_POSITION, CAST(fc.position AS UNSIGNED) as POSITION_IN_UNIQUE_CONSTRAINT, d.database_name as REFERENCED_TABLE_SCHEMA, t2.mock_fk_parent_table_name as REFERENCED_TABLE_NAME, c2.parent_column_name as REFERENCED_COLUMN_NAME from oceanbase.__all_foreign_key f join oceanbase.__all_table t on f.tenant_id = t.tenant_id and f.child_table_id = t.table_id join oceanbase.__all_database d on f.tenant_id = d.tenant_id and t.database_id = d.database_id join oceanbase.__all_foreign_key_column fc on f.tenant_id = fc.tenant_id and f.foreign_key_id = fc.foreign_key_id join oceanbase.__all_column c on f.tenant_id = c.tenant_id and fc.child_column_id = c.column_id and t.table_id = c.table_id join oceanbase.__all_mock_fk_parent_table t2 on f.tenant_id = t2.tenant_id and f.parent_table_id = t2.mock_fk_parent_table_id join oceanbase.__all_mock_fk_parent_table_column c2 on f.tenant_id = c2.tenant_id and fc.parent_column_id = c2.parent_column_id and t2.mock_fk_parent_table_id = c2.mock_fk_parent_table_id where f.tenant_id = 0) utf8mb4 utf8mb4_general_ci show create table partitions; View Create View character_set_client collation_connection -PARTITIONS CREATE VIEW `PARTITIONS` AS SELECT CAST('def' as CHAR(4096)) AS TABLE_CATALOG, DB.DATABASE_NAME collate utf8mb4_name_case AS TABLE_SCHEMA, T.TABLE_NAME collate utf8mb4_name_case AS TABLE_NAME, P.PART_NAME AS PARTITION_NAME, SP.SUB_PART_NAME AS SUBPARTITION_NAME, CAST(PART_POSITION AS UNSIGNED) AS PARTITION_ORDINAL_POSITION, CAST(SUB_PART_POSITION AS UNSIGNED) AS SUBPARTITION_ORDINAL_POSITION, CAST(CASE WHEN T.PART_LEVEL = 0 THEN NULL ELSE (CASE T.PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) PARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE T.SUB_PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) SUBPARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE T.PART_FUNC_EXPR END AS CHAR(2048)) PARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE T.SUB_PART_FUNC_EXPR END AS CHAR(2048)) SUBPARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL ELSE P.LIST_VAL END) END AS CHAR(4096)) AS PARTITION_DESCRIPTION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL ELSE SP.LIST_VAL END) END AS CHAR(4096)) AS SUBPARTITION_DESCRIPTION, CAST(TS.ROW_CNT AS UNSIGNED) AS TABLE_ROWS, CAST(TS.AVG_ROW_LEN AS UNSIGNED) AS AVG_ROW_LENGTH, CAST(COALESCE(TS.MACRO_BLK_CNT * 2 * 1024 * 1024, 0) AS UNSIGNED) AS DATA_LENGTH, CAST(NULL AS UNSIGNED) AS MAX_DATA_LENGTH, CAST(COALESCE(IDX_STAT.INDEX_LENGTH, 0) AS UNSIGNED) AS INDEX_LENGTH, CAST(NULL AS UNSIGNED) AS DATA_FREE, CASE T.PART_LEVEL WHEN 0 THEN T.GMT_CREATE WHEN 1 THEN P.GMT_CREATE WHEN 2 THEN SP.GMT_CREATE END AS CREATE_TIME, CAST(NULL AS DATETIME) AS UPDATE_TIME, CAST(NULL AS DATETIME) AS CHECK_TIME, CAST(NULL AS SIGNED) AS CHECKSUM, CAST(CASE T.PART_LEVEL WHEN 0 THEN NULL WHEN 1 THEN P.COMMENT WHEN 2 THEN SP.COMMENT END AS CHAR(1024)) AS PARTITION_COMMENT, CAST('default' AS CHAR(256)) NODEGROUP, CAST(TP.TABLESPACE_NAME AS CHAR(268)) AS TABLESPACE_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_DATABASE DB ON T.DATABASE_ID = DB.DATABASE_ID AND T.TENANT_ID = DB.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID ORDER BY PART_IDX) AS PART_POSITION FROM OCEANBASE.__ALL_PART ) P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, SUB_PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID,PART_ID ORDER BY SUB_PART_IDX) AS SUB_PART_POSITION FROM OCEANBASE.__ALL_SUB_PART ) SP ON T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID AND T.TENANT_ID = SP.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = IFNULL(SP.TABLESPACE_ID, P.TABLESPACE_ID) AND TP.TENANT_ID = T.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TABLE_STAT TS ON T.TENANT_ID = TS.TENANT_ID AND TS.TABLE_ID = T.TABLE_ID AND TS.PARTITION_ID = CASE T.PART_LEVEL WHEN 0 THEN T.TABLE_ID WHEN 1 THEN P.PART_ID WHEN 2 THEN SP.SUB_PART_ID END LEFT JOIN ( SELECT E.TENANT_ID AS TENANT_ID, E.DATA_TABLE_ID AS DATA_TABLE_ID, F.PART_IDX AS PART_IDX, SF.SUB_PART_IDX AS SUB_PART_IDX, SUM(G.macro_blk_cnt * 2 * 1024 * 1024) AS INDEX_LENGTH FROM OCEANBASE.__ALL_TABLE E LEFT JOIN OCEANBASE.__ALL_PART F ON E.TENANT_ID = F.TENANT_ID AND E.TABLE_ID = F.TABLE_ID LEFT JOIN OCEANBASE.__ALL_SUB_PART SF ON E.TENANT_ID = SF.TENANT_ID AND E.TABLE_ID = SF.TABLE_ID AND F.PART_ID = SF.PART_ID JOIN OCEANBASE.__ALL_TABLE_STAT G ON E.TENANT_ID = G.TENANT_ID AND E.TABLE_ID = G.TABLE_ID AND G.PARTITION_ID = CASE E.PART_LEVEL WHEN 0 THEN E.TABLE_ID WHEN 1 THEN F.PART_ID WHEN 2 THEN SF.SUB_PART_ID END WHERE E.INDEX_TYPE in (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12) AND E.TABLE_TYPE = 5 GROUP BY TENANT_ID, DATA_TABLE_ID, PART_IDX, SUB_PART_IDX ) IDX_STAT ON IDX_STAT.TENANT_ID = T.TENANT_ID AND IDX_STAT.DATA_TABLE_ID = T.TABLE_ID AND CASE T.PART_LEVEL WHEN 0 THEN 1 WHEN 1 THEN P.PART_IDX = IDX_STAT.PART_IDX WHEN 2 THEN P.PART_IDX = IDX_STAT.PART_IDX AND SP.SUB_PART_IDX = IDX_STAT.SUB_PART_IDX END WHERE T.TABLE_TYPE IN (3,6,8,9,14,15) utf8mb4 utf8mb4_general_ci +PARTITIONS CREATE VIEW `PARTITIONS` AS SELECT CAST('def' as CHAR(4096)) AS TABLE_CATALOG, DB.DATABASE_NAME collate utf8mb4_name_case AS TABLE_SCHEMA, T.TABLE_NAME collate utf8mb4_name_case AS TABLE_NAME, P.PART_NAME AS PARTITION_NAME, SP.SUB_PART_NAME AS SUBPARTITION_NAME, CAST(PART_POSITION AS UNSIGNED) AS PARTITION_ORDINAL_POSITION, CAST(SUB_PART_POSITION AS UNSIGNED) AS SUBPARTITION_ORDINAL_POSITION, CAST(CASE WHEN T.PART_LEVEL = 0 THEN NULL ELSE (CASE T.PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) PARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE T.SUB_PART_FUNC_TYPE WHEN 0 THEN 'HASH' WHEN 1 THEN 'KEY' WHEN 2 THEN 'KEY' WHEN 3 THEN 'RANGE' WHEN 4 THEN 'RANGE COLUMNS' WHEN 5 THEN 'LIST' WHEN 6 THEN 'LIST COLUMNS' WHEN 7 THEN 'RANGE' END) END AS CHAR(13)) SUBPARTITION_METHOD, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE T.PART_FUNC_EXPR END AS CHAR(2048)) PARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE T.SUB_PART_FUNC_EXPR END AS CHAR(2048)) SUBPARTITION_EXPRESSION, CAST(CASE WHEN (T.PART_LEVEL = 0) THEN NULL ELSE (CASE WHEN LENGTH(P.HIGH_BOUND_VAL) > 0 THEN P.HIGH_BOUND_VAL ELSE P.LIST_VAL END) END AS CHAR(4096)) AS PARTITION_DESCRIPTION, CAST(CASE WHEN (T.PART_LEVEL = 0 OR T.PART_LEVEL = 1) THEN NULL ELSE (CASE WHEN LENGTH(SP.HIGH_BOUND_VAL) > 0 THEN SP.HIGH_BOUND_VAL ELSE SP.LIST_VAL END) END AS CHAR(4096)) AS SUBPARTITION_DESCRIPTION, CAST(TS.ROW_CNT AS UNSIGNED) AS TABLE_ROWS, CAST(TS.AVG_ROW_LEN AS UNSIGNED) AS AVG_ROW_LENGTH, CAST(COALESCE(TS.MACRO_BLK_CNT * 2 * 1024 * 1024, 0) AS UNSIGNED) AS DATA_LENGTH, CAST(NULL AS UNSIGNED) AS MAX_DATA_LENGTH, CAST(COALESCE(IDX_STAT.INDEX_LENGTH, 0) AS UNSIGNED) AS INDEX_LENGTH, CAST(NULL AS UNSIGNED) AS DATA_FREE, CASE T.PART_LEVEL WHEN 0 THEN T.GMT_CREATE WHEN 1 THEN P.GMT_CREATE WHEN 2 THEN SP.GMT_CREATE END AS CREATE_TIME, CAST(NULL AS DATETIME) AS UPDATE_TIME, CAST(NULL AS DATETIME) AS CHECK_TIME, CAST(NULL AS SIGNED) AS CHECKSUM, CAST(CASE T.PART_LEVEL WHEN 0 THEN NULL WHEN 1 THEN P.COMMENT WHEN 2 THEN SP.COMMENT END AS CHAR(1024)) AS PARTITION_COMMENT, CAST('default' AS CHAR(256)) NODEGROUP, CAST(TP.TABLESPACE_NAME AS CHAR(268)) AS TABLESPACE_NAME FROM OCEANBASE.__ALL_TABLE T JOIN OCEANBASE.__ALL_DATABASE DB ON T.DATABASE_ID = DB.DATABASE_ID AND T.TENANT_ID = DB.TENANT_ID AND T.TABLE_MODE >> 12 & 15 in (0,1) LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, PARTITION_TYPE, PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID ORDER BY PART_IDX) AS PART_POSITION FROM OCEANBASE.__ALL_PART ) P ON T.TABLE_ID = P.TABLE_ID AND T.TENANT_ID = P.TENANT_ID LEFT JOIN ( SELECT TENANT_ID, TABLE_ID, PART_ID, SUB_PART_ID, SUB_PART_NAME, HIGH_BOUND_VAL, LIST_VAL, TABLESPACE_ID, GMT_CREATE, COMMENT, PARTITION_TYPE, SUB_PART_IDX, ROW_NUMBER() OVER(PARTITION BY TENANT_ID,TABLE_ID,PART_ID ORDER BY SUB_PART_IDX) AS SUB_PART_POSITION FROM OCEANBASE.__ALL_SUB_PART ) SP ON T.TABLE_ID = SP.TABLE_ID AND P.PART_ID = SP.PART_ID AND T.TENANT_ID = SP.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TENANT_TABLESPACE TP ON TP.TABLESPACE_ID = IFNULL(SP.TABLESPACE_ID, P.TABLESPACE_ID) AND TP.TENANT_ID = T.TENANT_ID LEFT JOIN OCEANBASE.__ALL_TABLE_STAT TS ON T.TENANT_ID = TS.TENANT_ID AND TS.TABLE_ID = T.TABLE_ID AND TS.PARTITION_ID = CASE T.PART_LEVEL WHEN 0 THEN T.TABLE_ID WHEN 1 THEN P.PART_ID WHEN 2 THEN SP.SUB_PART_ID END LEFT JOIN ( SELECT E.TENANT_ID AS TENANT_ID, E.DATA_TABLE_ID AS DATA_TABLE_ID, F.PART_IDX AS PART_IDX, SF.SUB_PART_IDX AS SUB_PART_IDX, SUM(G.macro_blk_cnt * 2 * 1024 * 1024) AS INDEX_LENGTH FROM OCEANBASE.__ALL_TABLE E LEFT JOIN OCEANBASE.__ALL_PART F ON E.TENANT_ID = F.TENANT_ID AND E.TABLE_ID = F.TABLE_ID LEFT JOIN OCEANBASE.__ALL_SUB_PART SF ON E.TENANT_ID = SF.TENANT_ID AND E.TABLE_ID = SF.TABLE_ID AND F.PART_ID = SF.PART_ID JOIN OCEANBASE.__ALL_TABLE_STAT G ON E.TENANT_ID = G.TENANT_ID AND E.TABLE_ID = G.TABLE_ID AND G.PARTITION_ID = CASE E.PART_LEVEL WHEN 0 THEN E.TABLE_ID WHEN 1 THEN F.PART_ID WHEN 2 THEN SF.SUB_PART_ID END WHERE E.INDEX_TYPE in (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12) AND E.TABLE_TYPE = 5 GROUP BY TENANT_ID, DATA_TABLE_ID, PART_IDX, SUB_PART_IDX ) IDX_STAT ON IDX_STAT.TENANT_ID = T.TENANT_ID AND IDX_STAT.DATA_TABLE_ID = T.TABLE_ID AND CASE T.PART_LEVEL WHEN 0 THEN 1 WHEN 1 THEN P.PART_IDX = IDX_STAT.PART_IDX WHEN 2 THEN P.PART_IDX = IDX_STAT.PART_IDX AND SP.SUB_PART_IDX = IDX_STAT.SUB_PART_IDX END WHERE T.TABLE_TYPE IN (3,6,8,9,14,15) AND (P.PARTITION_TYPE = 0 OR P.PARTITION_TYPE is NULL) AND (SP.PARTITION_TYPE = 0 OR SP.PARTITION_TYPE is NULL) utf8mb4 utf8mb4_general_ci show create table processlist; View Create View character_set_client collation_connection PROCESSLIST CREATE VIEW `PROCESSLIST` AS SELECT id AS ID, user AS USER, concat(user_client_ip, ':', user_client_port) AS HOST, db AS DB, command AS COMMAND, cast(time as SIGNED) AS TIME, state AS STATE, info AS INFO FROM oceanbase.__all_virtual_processlist WHERE is_serving_tenant(svr_ip, svr_port, effective_tenant_id()) utf8mb4 utf8mb4_general_ci @@ -281,7 +283,7 @@ View Create View character_set_client collation_connection TABLE_PRIVILEGES CREATE VIEW `TABLE_PRIVILEGES` AS WITH DB_PRIV AS ( select A.tenant_id TENANT_ID, A.user_id USER_ID, A.database_name DATABASE_NAME, A.priv_alter PRIV_ALTER, A.priv_create PRIV_CREATE, A.priv_delete PRIV_DELETE, A.priv_drop PRIV_DROP, A.priv_grant_option PRIV_GRANT_OPTION, A.priv_insert PRIV_INSERT, A.priv_update PRIV_UPDATE, A.priv_select PRIV_SELECT, A.priv_index PRIV_INDEX, A.priv_create_view PRIV_CREATE_VIEW, A.priv_show_view PRIV_SHOW_VIEW, A.GMT_CREATE GMT_CREATE, A.GMT_MODIFIED GMT_MODIFIED, A.PRIV_OTHERS PRIV_OTHERS from oceanbase.__all_database_privilege_history A, (select tenant_id, user_id, database_name, max(schema_version) schema_version from oceanbase.__all_database_privilege_history group by tenant_id, user_id, database_name, database_name collate utf8mb4_bin) B where A.tenant_id = B.tenant_id and A.user_id = B.user_id and A.database_name collate utf8mb4_bin = B.database_name collate utf8mb4_bin and A.schema_version = B.schema_version and A.is_deleted = 0 ), TABLE_PRIV AS ( select A.tenant_id TENANT_ID, A.user_id USER_ID, A.database_name DATABASE_NAME, A.table_name TABLE_NAME, A.priv_alter PRIV_ALTER, A.priv_create PRIV_CREATE, A.priv_delete PRIV_DELETE, A.priv_drop PRIV_DROP, A.priv_grant_option PRIV_GRANT_OPTION, A.priv_insert PRIV_INSERT, A.priv_update PRIV_UPDATE, A.priv_select PRIV_SELECT, A.priv_index PRIV_INDEX, A.priv_create_view PRIV_CREATE_VIEW, A.priv_show_view PRIV_SHOW_VIEW, A.PRIV_OTHERS PRIV_OTHERS from oceanbase.__all_table_privilege_history A, (select tenant_id, user_id, database_name, table_name, max(schema_version) schema_version from oceanbase.__all_table_privilege_history group by tenant_id, user_id, database_name, database_name collate utf8mb4_bin, table_name, table_name collate utf8mb4_bin) B where A.tenant_id = B.tenant_id and A.user_id = B.user_id and A.database_name collate utf8mb4_bin = B.database_name collate utf8mb4_bin and A.schema_version = B.schema_version and A.table_name collate utf8mb4_bin = B.table_name collate utf8mb4_bin and A.is_deleted = 0 ) SELECT CAST(CONCAT('''', V.USER_NAME, '''', '@', '''', V.HOST, '''') AS CHAR(81)) AS GRANTEE , CAST('def' AS CHAR(512)) AS TABLE_CATALOG , CAST(V.DATABASE_NAME AS CHAR(128)) collate utf8mb4_name_case AS TABLE_SCHEMA , CAST(V.TABLE_NAME AS CHAR(64)) collate utf8mb4_name_case AS TABLE_NAME, CAST(V.PRIVILEGE_TYPE AS CHAR(64)) AS PRIVILEGE_TYPE , CAST(V.IS_GRANTABLE AS CHAR(3)) AS IS_GRANTABLE FROM (SELECT TP.DATABASE_NAME AS DATABASE_NAME, TP.TABLE_NAME AS TABLE_NAME, U.USER_NAME AS USER_NAME, U.HOST AS HOST, CASE WHEN V1.C1 = 1 AND TP.PRIV_ALTER = 1 THEN 'ALTER' WHEN V1.C1 = 2 AND TP.PRIV_CREATE = 1 THEN 'CREATE' WHEN V1.C1 = 4 AND TP.PRIV_DELETE = 1 THEN 'DELETE' WHEN V1.C1 = 5 AND TP.PRIV_DROP = 1 THEN 'DROP' WHEN V1.C1 = 7 AND TP.PRIV_INSERT = 1 THEN 'INSERT' WHEN V1.C1 = 8 AND TP.PRIV_UPDATE = 1 THEN 'UPDATE' WHEN V1.C1 = 9 AND TP.PRIV_SELECT = 1 THEN 'SELECT' WHEN V1.C1 = 10 AND TP.PRIV_INDEX = 1 THEN 'INDEX' WHEN V1.C1 = 11 AND TP.PRIV_CREATE_VIEW = 1 THEN 'CREATE VIEW' WHEN V1.C1 = 12 AND TP.PRIV_SHOW_VIEW = 1 THEN 'SHOW VIEW' WHEN V1.C1 = 22 AND (TP.PRIV_OTHERS & (1 << 6)) != 0 THEN 'REFERENCES' WHEN V1.C1 = 44 AND (TP.PRIV_OTHERS & (1 << 9)) != 0 THEN 'TRIGGER' ELSE NULL END PRIVILEGE_TYPE , CASE WHEN TP.PRIV_GRANT_OPTION = 1 THEN 'YES' WHEN TP.PRIV_GRANT_OPTION = 0 THEN 'NO' END IS_GRANTABLE FROM TABLE_PRIV TP, oceanbase.__all_user U, (SELECT 1 AS C1 UNION ALL SELECT 2 AS C1 UNION ALL SELECT 4 AS C1 UNION ALL SELECT 5 AS C1 UNION ALL SELECT 7 AS C1 UNION ALL SELECT 8 AS C1 UNION ALL SELECT 9 AS C1 UNION ALL SELECT 10 AS C1 UNION ALL SELECT 11 AS C1 UNION ALL SELECT 12 AS C1 UNION ALL SELECT 22 AS C1 UNION ALL SELECT 44 AS C1) V1, (SELECT USER_ID FROM oceanbase.__all_user WHERE TENANT_ID = 0 AND CONCAT(USER_NAME, '@', HOST) = CURRENT_USER()) CURR LEFT JOIN (SELECT USER_ID FROM DB_PRIV WHERE TENANT_ID = 0 AND DATABASE_NAME = 'mysql' AND PRIV_SELECT = 1) DB ON CURR.USER_ID = DB.USER_ID WHERE TP.TENANT_ID = 0 AND TP.TENANT_ID = U.TENANT_ID AND TP.USER_ID = U.USER_ID AND (DB.USER_ID IS NOT NULL OR 512 & CURRENT_USER_PRIV() = 512 OR TP.USER_ID = CURR.USER_ID)) V WHERE V.PRIVILEGE_TYPE IS NOT NULL utf8mb4 utf8mb4_general_ci show create table tables; View Create View character_set_client collation_connection -TABLES CREATE VIEW `TABLES` AS select /*+ leading(a) no_use_nl(ts)*/ cast('def' as char(512)) as TABLE_CATALOG, cast(b.database_name as char(64)) collate utf8mb4_name_case as TABLE_SCHEMA, cast(a.table_name as char(64)) collate utf8mb4_name_case as TABLE_NAME, cast(case when (a.database_id = 201002 or a.table_type = 1) then 'SYSTEM VIEW' when a.table_type in (0, 2) then 'SYSTEM TABLE' when a.table_type = 4 then 'VIEW' when a.table_type = 14 then 'EXTERNAL TABLE' else 'BASE TABLE' end as char(64)) as TABLE_TYPE, cast(case when a.table_type in (0,3,5,6,7,11,12,13,15) then 'InnoDB' else 'MEMORY' end as char(64)) as ENGINE, cast(NULL as unsigned) as VERSION, cast(a.store_format as char(10)) as ROW_FORMAT, cast( coalesce(ts.row_cnt,0) as unsigned) as TABLE_ROWS, cast( coalesce(ts.avg_row_len,0) as unsigned) as AVG_ROW_LENGTH, cast( coalesce(ts.data_size,0) as unsigned) as DATA_LENGTH, cast(NULL as unsigned) as MAX_DATA_LENGTH, cast( coalesce(idx_stat.index_length, 0) as unsigned) as INDEX_LENGTH, cast(NULL as unsigned) as DATA_FREE, cast(NULL as unsigned) as AUTO_INCREMENT, cast(a.gmt_create as datetime) as CREATE_TIME, cast(a.gmt_modified as datetime) as UPDATE_TIME, cast(NULL as datetime) as CHECK_TIME, cast(d.collation as char(32)) as TABLE_COLLATION, cast(NULL as unsigned) as CHECKSUM, cast(NULL as char(255)) as CREATE_OPTIONS, cast(case when a.table_type = 4 then 'VIEW' else a.comment end as char(2048)) as TABLE_COMMENT from ( select cast(0 as signed) as tenant_id, c.database_id, c.table_id, c.table_name, c.collation_type, c.table_type, usec_to_time(d.schema_version) as gmt_create, usec_to_time(c.schema_version) as gmt_modified, c.comment, c.store_format from oceanbase.__all_virtual_core_all_table c join oceanbase.__all_virtual_core_all_table d on c.tenant_id = d.tenant_id and d.table_name = '__all_core_table' where c.tenant_id = effective_tenant_id() union all select tenant_id, database_id, table_id, table_name, collation_type, table_type, gmt_create, gmt_modified, comment, store_format from oceanbase.__all_table where table_mode >> 12 & 15 in (0,1)) a join oceanbase.__all_database b on a.database_id = b.database_id and a.tenant_id = b.tenant_id join oceanbase.__tenant_virtual_collation d on a.collation_type = d.collation_type left join ( select tenant_id, table_id, row_cnt, avg_row_len, (macro_blk_cnt * 2 * 1024 * 1024) as data_size from oceanbase.__all_table_stat where partition_id = -1 or partition_id = table_id) ts on a.table_id = ts.table_id and a.tenant_id = ts.tenant_id left join ( select e.tenant_id as tenant_id, e.data_table_id as data_table_id, SUM(f.macro_blk_cnt * 2 * 1024 * 1024) AS index_length FROM oceanbase.__all_table e JOIN oceanbase.__all_table_stat f ON e.tenant_id = f.tenant_id and e.table_id = f.table_id and (f.partition_id = -1 or f.partition_id = e.table_id) WHERE e.index_type in (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12) and e.table_type = 5 group by tenant_id, data_table_id ) idx_stat on idx_stat.tenant_id = a.tenant_id and idx_stat.data_table_id = a.table_id where a.tenant_id = 0 and a.table_type in (0, 1, 2, 3, 4, 14, 15) and b.database_name != '__recyclebin' and b.in_recyclebin = 0 and 0 = sys_privilege_check('table_acc', effective_tenant_id(), b.database_name, a.table_name) utf8mb4 utf8mb4_general_ci +TABLES CREATE VIEW `TABLES` AS select /*+ leading(a) no_use_nl(ts)*/ cast('def' as char(512)) as TABLE_CATALOG, cast(b.database_name as char(64)) collate utf8mb4_name_case as TABLE_SCHEMA, cast(a.table_name as char(64)) collate utf8mb4_name_case as TABLE_NAME, cast(case when (a.database_id = 201002 or a.table_type = 1) then 'SYSTEM VIEW' when a.table_type in (0, 2) then 'SYSTEM TABLE' when a.table_type = 4 then 'VIEW' when a.table_type = 14 then 'EXTERNAL TABLE' else 'BASE TABLE' end as char(64)) as TABLE_TYPE, cast(case when a.table_type in (0,3,5,6,7,11,12,13,15) then 'InnoDB' else 'MEMORY' end as char(64)) as ENGINE, cast(NULL as unsigned) as VERSION, cast(a.store_format as char(10)) as ROW_FORMAT, cast( coalesce(ts.row_cnt,0) as unsigned) as TABLE_ROWS, cast( coalesce(ts.avg_row_len,0) as unsigned) as AVG_ROW_LENGTH, cast( coalesce(ts.data_size,0) as unsigned) as DATA_LENGTH, cast(NULL as unsigned) as MAX_DATA_LENGTH, cast( coalesce(idx_stat.index_length, 0) as unsigned) as INDEX_LENGTH, cast(NULL as unsigned) as DATA_FREE, cast(NULL as unsigned) as AUTO_INCREMENT, cast(a.gmt_create as datetime) as CREATE_TIME, cast(a.gmt_modified as datetime) as UPDATE_TIME, cast(NULL as datetime) as CHECK_TIME, cast(d.collation as char(32)) as TABLE_COLLATION, cast(NULL as unsigned) as CHECKSUM, cast(NULL as char(255)) as CREATE_OPTIONS, cast(case when a.table_type = 4 then 'VIEW' else a.comment end as char(2048)) as TABLE_COMMENT, cast(case when a.auto_part = 1 then 'TRUE' else 'FALSE' end as char(16)) as AUTO_SPLIT, cast(case when a.auto_part = 1 then a.auto_part_size else 0 end as unsigned) as AUTO_SPLIT_TABLET_SIZE from ( select cast(0 as signed) as tenant_id, c.database_id, c.table_id, c.table_name, c.collation_type, c.table_type, usec_to_time(d.schema_version) as gmt_create, usec_to_time(c.schema_version) as gmt_modified, c.comment, c.store_format, c.auto_part, c.auto_part_size from oceanbase.__all_virtual_core_all_table c join oceanbase.__all_virtual_core_all_table d on c.tenant_id = d.tenant_id and d.table_name = '__all_core_table' where c.tenant_id = effective_tenant_id() union all select tenant_id, database_id, table_id, table_name, collation_type, table_type, gmt_create, gmt_modified, comment, store_format, auto_part, auto_part_size from oceanbase.__all_table where table_mode >> 12 & 15 in (0,1)) a join oceanbase.__all_database b on a.database_id = b.database_id and a.tenant_id = b.tenant_id join oceanbase.__tenant_virtual_collation d on a.collation_type = d.collation_type left join ( select tenant_id, table_id, row_cnt, avg_row_len, (macro_blk_cnt * 2 * 1024 * 1024) as data_size from oceanbase.__all_table_stat where partition_id = -1 or partition_id = table_id) ts on a.table_id = ts.table_id and a.tenant_id = ts.tenant_id left join ( select e.tenant_id as tenant_id, e.data_table_id as data_table_id, SUM(f.macro_blk_cnt * 2 * 1024 * 1024) AS index_length FROM oceanbase.__all_table e JOIN oceanbase.__all_table_stat f ON e.tenant_id = f.tenant_id and e.table_id = f.table_id and (f.partition_id = -1 or f.partition_id = e.table_id) WHERE e.index_type in (1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12) and e.table_type = 5 group by tenant_id, data_table_id ) idx_stat on idx_stat.tenant_id = a.tenant_id and idx_stat.data_table_id = a.table_id where a.tenant_id = 0 and a.table_type in (0, 1, 2, 3, 4, 14, 15) and b.database_name != '__recyclebin' and b.in_recyclebin = 0 and 0 = sys_privilege_check('table_acc', effective_tenant_id(), b.database_name, a.table_name) utf8mb4 utf8mb4_general_ci show create table user_privileges; View Create View character_set_client collation_connection USER_PRIVILEGES CREATE VIEW `USER_PRIVILEGES` AS SELECT CAST(CONCAT('''', V.USER_NAME, '''', '@', '''', V.HOST, '''') AS CHAR(81)) AS GRANTEE , CAST('def' AS CHAR(512)) AS TABLE_CATALOG , CAST(V.PRIVILEGE_TYPE AS CHAR(64)) AS PRIVILEGE_TYPE , CAST(V.IS_GRANTABLE AS CHAR(3)) AS IS_GRANTABLE FROM (SELECT U.USER_NAME AS USER_NAME, U.HOST AS HOST, CASE WHEN V1.C1 = 1 AND U.PRIV_ALTER = 1 THEN 'ALTER' WHEN V1.C1 = 2 AND U.PRIV_CREATE = 1 THEN 'CREATE' WHEN V1.C1 = 3 AND U.PRIV_CREATE_USER = 1 THEN 'CREATE USER' WHEN V1.C1 = 4 AND U.PRIV_DELETE = 1 THEN 'DELETE' WHEN V1.C1 = 5 AND U.PRIV_DROP = 1 THEN 'DROP' WHEN V1.C1 = 7 AND U.PRIV_INSERT = 1 THEN 'INSERT' WHEN V1.C1 = 8 AND U.PRIV_UPDATE = 1 THEN 'UPDATE' WHEN V1.C1 = 9 AND U.PRIV_SELECT = 1 THEN 'SELECT' WHEN V1.C1 = 10 AND U.PRIV_INDEX = 1 THEN 'INDEX' WHEN V1.C1 = 11 AND U.PRIV_CREATE_VIEW = 1 THEN 'CREATE VIEW' WHEN V1.C1 = 12 AND U.PRIV_SHOW_VIEW = 1 THEN 'SHOW VIEW' WHEN V1.C1 = 13 AND U.PRIV_SHOW_DB = 1 THEN 'SHOW DATABASES' WHEN V1.C1 = 14 AND U.PRIV_SUPER = 1 THEN 'SUPER' WHEN V1.C1 = 15 AND U.PRIV_PROCESS = 1 THEN 'PROCESS' WHEN V1.C1 = 17 AND U.PRIV_CREATE_SYNONYM = 1 THEN 'CREATE SYNONYM' WHEN V1.C1 = 22 AND (U.PRIV_OTHERS & (1 << 6)) != 0 THEN 'REFERENCES' WHEN V1.C1 = 23 AND (U.PRIV_OTHERS & (1 << 0)) != 0 THEN 'EXECUTE' WHEN V1.C1 = 27 AND U.PRIV_FILE = 1 THEN 'FILE' WHEN V1.C1 = 28 AND U.PRIV_ALTER_TENANT = 1 THEN 'ALTER TENANT' WHEN V1.C1 = 29 AND U.PRIV_ALTER_SYSTEM = 1 THEN 'ALTER SYSTEM' WHEN V1.C1 = 30 AND U.PRIV_CREATE_RESOURCE_POOL = 1 THEN 'CREATE RESOURCE POOL' WHEN V1.C1 = 31 AND U.PRIV_CREATE_RESOURCE_UNIT = 1 THEN 'CREATE RESOURCE UNIT' WHEN V1.C1 = 33 AND U.PRIV_REPL_SLAVE = 1 THEN 'REPLICATION SLAVE' WHEN V1.C1 = 34 AND U.PRIV_REPL_CLIENT = 1 THEN 'REPLICATION CLIENT' WHEN V1.C1 = 35 AND U.PRIV_DROP_DATABASE_LINK = 1 THEN 'DROP DATABASE LINK' WHEN V1.C1 = 36 AND U.PRIV_CREATE_DATABASE_LINK = 1 THEN 'CREATE DATABASE LINK' WHEN V1.C1 = 37 AND (U.PRIV_OTHERS & (1 << 1)) != 0 THEN 'ALTER ROUTINE' WHEN V1.C1 = 38 AND (U.PRIV_OTHERS & (1 << 2)) != 0 THEN 'CREATE ROUTINE' WHEN V1.C1 = 39 AND (U.PRIV_OTHERS & (1 << 3)) != 0 THEN 'CREATE TABLESPACE' WHEN V1.C1 = 40 AND (U.PRIV_OTHERS & (1 << 4)) != 0 THEN 'SHUTDOWN' WHEN V1.C1 = 41 AND (U.PRIV_OTHERS & (1 << 5)) != 0 THEN 'RELOAD' WHEN V1.C1 = 42 AND (U.PRIV_OTHERS & (1 << 7)) != 0 THEN 'CREATE ROLE' WHEN V1.C1 = 43 AND (U.PRIV_OTHERS & (1 << 8)) != 0 THEN 'DROP ROLE' WHEN V1.C1 = 44 AND (U.PRIV_OTHERS & (1 << 9)) != 0 THEN 'TRIGGER' WHEN V1.C1 = 0 AND U.PRIV_ALTER = 0 AND U.PRIV_CREATE = 0 AND U.PRIV_CREATE_USER = 0 AND U.PRIV_DELETE = 0 AND U.PRIV_DROP = 0 AND U.PRIV_INSERT = 0 AND U.PRIV_UPDATE = 0 AND U.PRIV_SELECT = 0 AND U.PRIV_INDEX = 0 AND U.PRIV_CREATE_VIEW = 0 AND U.PRIV_SHOW_VIEW = 0 AND U.PRIV_SHOW_DB = 0 AND U.PRIV_SUPER = 0 AND U.PRIV_PROCESS = 0 AND U.PRIV_CREATE_SYNONYM = 0 AND U.PRIV_FILE = 0 AND U.PRIV_ALTER_TENANT = 0 AND U.PRIV_ALTER_SYSTEM = 0 AND U.PRIV_CREATE_RESOURCE_POOL = 0 AND U.PRIV_CREATE_RESOURCE_UNIT = 0 AND U.PRIV_REPL_SLAVE = 0 AND U.PRIV_REPL_CLIENT = 0 AND U.PRIV_DROP_DATABASE_LINK = 0 AND U.PRIV_CREATE_DATABASE_LINK = 0 AND U.PRIV_OTHERS = 0 THEN 'USAGE' END PRIVILEGE_TYPE , CASE WHEN U.PRIV_GRANT_OPTION = 0 THEN 'NO' WHEN U.PRIV_ALTER = 0 AND U.PRIV_CREATE = 0 AND U.PRIV_CREATE_USER = 0 AND U.PRIV_DELETE = 0 AND U.PRIV_DROP = 0 AND U.PRIV_INSERT = 0 AND U.PRIV_UPDATE = 0 AND U.PRIV_SELECT = 0 AND U.PRIV_INDEX = 0 AND U.PRIV_CREATE_VIEW = 0 AND U.PRIV_SHOW_VIEW = 0 AND U.PRIV_SHOW_DB = 0 AND U.PRIV_SUPER = 0 AND U.PRIV_PROCESS = 0 AND U.PRIV_CREATE_SYNONYM = 0 AND U.PRIV_FILE = 0 AND U.PRIV_ALTER_TENANT = 0 AND U.PRIV_ALTER_SYSTEM = 0 AND U.PRIV_CREATE_RESOURCE_POOL = 0 AND U.PRIV_CREATE_RESOURCE_UNIT = 0 AND U.PRIV_REPL_SLAVE = 0 AND U.PRIV_REPL_CLIENT = 0 AND U.PRIV_DROP_DATABASE_LINK = 0 AND U.PRIV_CREATE_DATABASE_LINK = 0 AND U.PRIV_OTHERS = 0 THEN 'NO' WHEN U.PRIV_GRANT_OPTION = 1 THEN 'YES' END IS_GRANTABLE FROM oceanbase.__all_user U, (SELECT 0 AS C1 UNION ALL SELECT 1 AS C1 UNION ALL SELECT 2 AS C1 UNION ALL SELECT 3 AS C1 UNION ALL SELECT 4 AS C1 UNION ALL SELECT 5 AS C1 UNION ALL SELECT 7 AS C1 UNION ALL SELECT 8 AS C1 UNION ALL SELECT 9 AS C1 UNION ALL SELECT 10 AS C1 UNION ALL SELECT 11 AS C1 UNION ALL SELECT 12 AS C1 UNION ALL SELECT 13 AS C1 UNION ALL SELECT 14 AS C1 UNION ALL SELECT 15 AS C1 UNION ALL SELECT 17 AS C1 UNION ALL SELECT 22 AS C1 UNION ALL SELECT 23 AS C1 UNION ALL SELECT 27 AS C1 UNION ALL SELECT 28 AS C1 UNION ALL SELECT 29 AS C1 UNION ALL SELECT 30 AS C1 UNION ALL SELECT 31 AS C1 UNION ALL SELECT 33 AS C1 UNION ALL SELECT 34 AS C1 UNION ALL SELECT 35 AS C1 UNION ALL SELECT 36 AS C1 UNION ALL SELECT 37 AS C1 UNION ALL SELECT 38 AS C1 UNION ALL SELECT 39 AS C1 UNION ALL SELECT 40 AS C1 UNION ALL SELECT 41 AS C1 UNION ALL SELECT 42 AS C1 UNION ALL SELECT 43 AS C1 UNION ALL SELECT 44 AS C1) V1, (SELECT USER_ID FROM oceanbase.__all_user WHERE TENANT_ID = 0 AND CONCAT(USER_NAME, '@', HOST) = CURRENT_USER()) CURR LEFT JOIN (SELECT USER_ID FROM oceanbase.__all_database_privilege WHERE TENANT_ID = 0 AND DATABASE_NAME = 'mysql' AND PRIV_SELECT = 1) DB ON CURR.USER_ID = DB.USER_ID WHERE U.TENANT_ID = 0 AND (DB.USER_ID IS NOT NULL OR 512 & CURRENT_USER_PRIV() = 512 OR U.USER_ID = CURR.USER_ID)) V WHERE V.PRIVILEGE_TYPE IS NOT NULL utf8mb4 utf8mb4_general_ci diff --git a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result index 940621268..856cd2b4e 100644 --- a/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result +++ b/tools/deploy/mysql_test/test_suite/inner_table/r/mysql/all_virtual_sys_parameter_stat.result @@ -40,6 +40,7 @@ audit_log_strategy audit_sys_operations audit_trail autoinc_cache_refresh_interval +auto_split_tablet_size backup_data_file_size balancer_idle_time balancer_log_interval @@ -90,6 +91,7 @@ disk_io_thread_count dtl_buffer_size dump_data_dictionary_to_log_interval enable_async_syslog +enable_auto_split enable_cgroup enable_crazy_medium_compaction enable_dblink 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 46eb14daa..bf23014f0 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 @@ -174,6 +174,8 @@ TABLE_COLLATION varchar(32) NO CHECKSUM bigint(0) unsigned NO CREATE_OPTIONS varchar(255) NO TABLE_COMMENT text NO +AUTO_SPLIT varchar(16) NO +AUTO_SPLIT_TABLET_SIZE bigint(20) unsigned NO select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from information_schema.TABLES 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 d2675f189..e00cf7c66 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 @@ -175,6 +175,8 @@ TABLE_COLLATION varchar(32) NO CHECKSUM bigint(0) unsigned NO CREATE_OPTIONS varchar(255) NO TABLE_COMMENT text NO +AUTO_SPLIT varchar(16) NO +AUTO_SPLIT_TABLET_SIZE bigint(20) unsigned NO select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from information_schema.TABLES limit 1); cnt 1 @@ -2889,6 +2891,8 @@ HAS_SENSITIVE_COLUMN varchar(3) NO ADMIT_NULL varchar(3) NO DATA_LINK_DML_ENABLED varchar(3) NO LOGICAL_REPLICATION varchar(8) NO +AUTO_SPLIT varchar(16) NO +AUTO_SPLIT_TABLET_SIZE bigint(20) NO select /*+QUERY_TIMEOUT(60000000)*/ count(*) as cnt from (select * from oceanbase.CDB_TABLES limit 1); cnt 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 370f8ef49..c83645fbe 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 @@ -9727,6 +9727,18 @@ is_deleted bigint(20) NO NULL select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_user_proxy_role_info_history; IF(count(*) >= 0, 1, 0) 1 +desc oceanbase.__all_virtual_tablet_reorganize_history; +Field Type Null Key Default Extra +tenant_id bigint(20) NO PRI NULL +ls_id bigint(20) NO PRI NULL +src_tablet_id bigint(20) NO PRI NULL +dest_tablet_id bigint(20) NO PRI NULL +type bigint(20) NO NULL +create_time timestamp(6) NO NULL +finish_time timestamp(6) NO NULL +select /*+QUERY_TIMEOUT(60000000)*/ IF(count(*) >= 0, 1, 0) from oceanbase.__all_virtual_tablet_reorganize_history; +IF(count(*) >= 0, 1, 0) +1 desc oceanbase.__all_virtual_res_mgr_directive; Field Type Null Key Default Extra tenant_id bigint(20) NO PRI NULL 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 2247676f5..d24db9641 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 @@ -277,6 +277,7 @@ 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 +482 __all_tablet_reorganize_history 0 201001 1 483 __all_storage_ha_error_diagnose_history 0 201001 1 484 __all_storage_ha_perf_diagnose_history 0 201001 1 485 __all_clone_job 0 201001 1 @@ -764,6 +765,7 @@ select 0xffffffffff & table_id, table_name, table_type, database_id, part_num fr 12475 __all_virtual_user_proxy_info_history 2 201001 1 12476 __all_virtual_user_proxy_role_info 2 201001 1 12477 __all_virtual_user_proxy_role_info_history 2 201001 1 +12478 __all_virtual_tablet_reorganize_history 2 201001 1 12479 __all_virtual_res_mgr_directive 2 201001 1 12480 __all_virtual_service 2 201001 1 12481 __all_virtual_tenant_resource_limit 2 201001 1 diff --git a/tools/ob_admin/log_tool/parser/ob_admin_parser_log_entry.cpp b/tools/ob_admin/log_tool/parser/ob_admin_parser_log_entry.cpp index 6ff5f2252..f642393b3 100644 --- a/tools/ob_admin/log_tool/parser/ob_admin_parser_log_entry.cpp +++ b/tools/ob_admin/log_tool/parser/ob_admin_parser_log_entry.cpp @@ -411,6 +411,33 @@ int ObAdminParserLogEntry::parse_ddl_log_() } break; } + case ObDDLClogType::DDL_TABLET_SPLIT_START_LOG: { + ObTabletSplitStartLog log; + if (OB_FAIL(log.deserialize(buf_, buf_len_, pos_))) { + LOG_WARN("deserialize tablet split start log failed", K(ret), KP(buf_), K(buf_len_), K(pos_)); + } else { + fprintf(stdout, " ###: %s\n", to_cstring(log)); + } + break; + } + case ObDDLClogType::DDL_TABLET_SPLIT_FINISH_LOG: { + ObTabletSplitFinishLog log; + if (OB_FAIL(log.deserialize(buf_, buf_len_, pos_))) { + LOG_WARN("deserialize tablet split finish log failed", K(ret), KP(buf_), K(buf_len_), K(pos_)); + } else { + fprintf(stdout, " ###: %s\n", to_cstring(log)); + } + break; + } + case ObDDLClogType::DDL_TABLET_FREEZE_LOG: { + ObTabletFreezeLog log; + if (OB_FAIL(log.deserialize(buf_, buf_len_, pos_))) { + LOG_WARN("deserialize tablet freeze log failed", K(ret), KP(buf_), K(buf_len_), K(pos_)); + } else { + fprintf(stdout, " ###: %s\n", to_cstring(log)); + } + break; + } default: { ret = OB_NOT_SUPPORTED; LOG_WARN("Unknown log type", K(ret), K(type)); diff --git a/unittest/storage/ddl/CMakeLists.txt b/unittest/storage/ddl/CMakeLists.txt index 7c2b3073c..46bd43734 100644 --- a/unittest/storage/ddl/CMakeLists.txt +++ b/unittest/storage/ddl/CMakeLists.txt @@ -1,3 +1,9 @@ #storage_unittest(test_ddl_kv) +#storage_unittest(test_auto_partition_split_range) +#storage_dml_unittest(test_auto_partition_estimate) +#storage_dml_unittest(test_auto_partition_get_read_tables) +#storage_dml_unittest(test_auto_partition_scan_table) storage_unittest(test_chunk_compact_store) +storage_unittest(test_auto_split_polling_mgr) +storage_unittest(test_tablet_data_split) storage_unittest(test_ddl_seq_generator) diff --git a/unittest/storage/ddl/test_auto_split_polling_mgr.cpp b/unittest/storage/ddl/test_auto_split_polling_mgr.cpp new file mode 100644 index 000000000..fa2536251 --- /dev/null +++ b/unittest/storage/ddl/test_auto_split_polling_mgr.cpp @@ -0,0 +1,352 @@ +/** + * 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 + +#define ASSERT_OK(x) ASSERT_EQ(OB_SUCCESS, (x)) +#include +#include +#include +#define private public +#define protected public +#include "share/scheduler/ob_partition_auto_split_helper.h" +#undef private + +namespace oceanbase +{ + +using namespace common; +using namespace lib; +using namespace share; +using namespace storage; +using namespace blocksstable; +using namespace share::schema; +using namespace compaction; + +static const uint64_t TEST_TENANT_A_ID = 1002; +static const uint64_t TEST_TENANT_B_ID = 1003; +static const uint64_t TEST_TENANT_C_ID = 1004; +static const ObLSID ls_id{1}; + +class TestSplitTaskScheduler : public ::testing::Test +{ +public: + TestSplitTaskScheduler() + : rs_scheduler_(ObRsAutoSplitScheduler::get_instance()), polling_mgr_(rs_scheduler_.polling_mgr_), sys_tenant_(OB_SYS_TENANT_ID) + { + ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(TEST_TENANT_A_ID); + ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(TEST_TENANT_B_ID); + ObMallocAllocator::get_instance()->create_and_add_tenant_allocator(TEST_TENANT_C_ID); + init(); + } + virtual void SetUp(); + void reset(); + int init() { return rs_scheduler_.init(); }; + +public: + ObRsAutoSplitScheduler &rs_scheduler_; + ObAutoSplitTaskPollingMgr &polling_mgr_; + ObTenantBase sys_tenant_; +}; + +void pop(ObArray &task_array, ObAutoSplitTaskPollingMgr &polling_mgr) +{ + ObArray> tenant_task_array; + int64_t pop_nums = 1; + while (ATOMIC_LOAD(&polling_mgr.total_tasks_) > 0) { + tenant_task_array.reuse(); + ASSERT_OK(polling_mgr.pop_tasks(pop_nums, tenant_task_array)); + if (tenant_task_array.count() == 0) { + break; + } + for (int64_t i = 0; i < tenant_task_array.count(); ++i) { + task_array.push_back(tenant_task_array.at(i)); + } + pop_nums%=10; + pop_nums+=1; + } +} + +void push(const ObArray> &tenants_task_array, ObAutoSplitTaskPollingMgr &polling_mgr) +{ + for (int64_t i = 0; i < tenants_task_array.count(); ++i) { + int ret = polling_mgr.push_tasks(tenants_task_array.at(i)); + ASSERT_OK(ret); + } +} + +void TestSplitTaskScheduler::reset() +{ + rs_scheduler_.reset(); +} + +void TestSplitTaskScheduler::SetUp() +{ + ObTenantEnv::set_tenant(&sys_tenant_); +} + +TEST_F(TestSplitTaskScheduler, simple_push_and_pop) +{ + ObArray task_array; + ObArray ids; + ObAutoSplitTask task_a(TEST_TENANT_A_ID, ls_id, 1/*tablet_id*/, 1/*auto_split_size*/, 2/*used_disk_size*/, 0); + ObAutoSplitTask task_b(TEST_TENANT_A_ID, ls_id, 2/*tablet_id*/, 1/*auto_split_size*/, 3/*used_disk_size*/, 0); + ObAutoSplitTask task_c(TEST_TENANT_B_ID, ls_id, 3/*tablet_id*/, 1/*auto_split_size*/, 4/*used_disk_size*/, 0); + ASSERT_OK(task_array.push_back(task_a)); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + + ASSERT_OK(task_array.push_back(task_c)); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + + ASSERT_OK(task_array.push_back(task_b)); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + // we expect the first tablet_id popped from mgr to be 2, + // because the tenant_cache A is at index 0 and the last_access_index is 0, and the tablet with id 2 has the hightest priority in that cache + ObArray> tenants_task_array; + ASSERT_OK(polling_mgr_.pop_tasks(1, tenants_task_array)); + ASSERT_EQ(1, tenants_task_array.count()); + ASSERT_EQ(1, tenants_task_array.at(0).count()); + ObAutoSplitTask &task1 = tenants_task_array.at(0).at(0); + ASSERT_OK(ids.push_back(task1.tablet_id_.id_)); + tenants_task_array.reuse(); + // we expect the second tablet_id popped from mgr to be 2, + // because the tenant_cache B is at index 1, and the last_access_index is 1, the tablet with id 3 has the hightest priority in that cache + ASSERT_OK(polling_mgr_.pop_tasks(1, tenants_task_array)); + ASSERT_EQ(1, tenants_task_array.count()); + ASSERT_EQ(1, tenants_task_array.at(0).count()); + ObAutoSplitTask &task2 = tenants_task_array.at(0).at(0); + ASSERT_OK(ids.push_back(task2.tablet_id_.id_)); + tenants_task_array.reuse(); + // we expect the third tablet_id popped from mgr to be 2, + // because the tenant_cache B is at index 1, and the last_access_index is 0, the tablet with id 3 has the hightest priority in that cache + ASSERT_OK(polling_mgr_.pop_tasks(1, tenants_task_array)); + ASSERT_EQ(1, tenants_task_array.count()); + ASSERT_EQ(1, tenants_task_array.at(0).count()); + ObAutoSplitTask &task3 = tenants_task_array.at(0).at(0); + ASSERT_OK(ids.push_back(task3.tablet_id_.id_)); + tenants_task_array.reuse(); + + std::sort(ids.begin(), ids.end()); + for (int64_t i = 0; i < ids.count(); ++i) { + ASSERT_EQ(i + 1, ids.at(i)); + } +} + +TEST_F(TestSplitTaskScheduler, test_reset) +{ + ObArray task_array; + ObAutoSplitTask task_a(TEST_TENANT_A_ID, ls_id, 1/*tablet_id*/, 1/*auto_split_size*/, 2/*used_disk_size*/, 0); + ObAutoSplitTask task_b(TEST_TENANT_A_ID, ls_id, 2/*tablet_id*/, 1/*auto_split_size*/, 3/*used_disk_size*/, 0); + ASSERT_OK(task_array.push_back(task_a)); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + ASSERT_OK(task_array.push_back(task_b)); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + + reset(); + init(); + + task_array.push_back(task_a); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + ObArray> tenants_task_array; + ASSERT_OK(polling_mgr_.pop_tasks(1, tenants_task_array)); + ASSERT_EQ(1, tenants_task_array.count()); + ASSERT_EQ(1, tenants_task_array.at(0).count()); + ObAutoSplitTask &task1 = tenants_task_array.at(0).at(0); + ASSERT_EQ(1, task1.tablet_id_.id_); + tenants_task_array.reuse(); +} + + +TEST_F(TestSplitTaskScheduler, single_tenant_hard_push_and_pop) +{ + ObArray task_array; + ObAutoSplitTask task_high_prio(TEST_TENANT_A_ID, ls_id, 1000/*tablet_id*/, 1/*auto_split_size*/, 1000/*used_disk_size*/, 0); + ASSERT_OK(task_array.push_back(task_high_prio)); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + for (int64_t i = 2; i < ObAutoSplitTaskCache::CACHE_MAX_CAPACITY + 10; ++i ) { + ASSERT_OK(task_array.push_back(ObAutoSplitTask(TEST_TENANT_A_ID, ls_id, i/*tablet_id*/, 1/*auto_split_size*/, i/*used_disk_size*/, 0))); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + } + ObArray> tenants_task_array; + ASSERT_OK(polling_mgr_.pop_tasks(1, tenants_task_array)); + ASSERT_EQ(1, tenants_task_array.count()); + ASSERT_EQ(1, tenants_task_array.at(0).count()); + ObAutoSplitTask &high_prio_task = tenants_task_array.at(0).at(0); + ASSERT_EQ(1000, high_prio_task.tablet_id_.id_); + tenants_task_array.reuse(); + + int64_t expect_hightest_prio_tablet_id = ObAutoSplitTaskCache::CACHE_MAX_CAPACITY + 9; + int64_t total_tasks = ObAutoSplitTaskCache::CACHE_MAX_CAPACITY - 1; + while (total_tasks > 0) { + tenants_task_array.reuse(); + ASSERT_OK(polling_mgr_.pop_tasks(5, tenants_task_array)); + ASSERT_EQ(1, tenants_task_array.count()); + int64_t task_arr_len = tenants_task_array.at(0).count(); + ASSERT_TRUE(task_arr_len != 0); + total_tasks -= task_arr_len; + ASSERT_EQ(total_tasks, polling_mgr_.total_tasks_); + ASSERT_TRUE(tenants_task_array.at(0).count() >= 4); + LOG_INFO("tenants_task_array", K(tenants_task_array)); + for (int64_t i = 0; i < tenants_task_array.at(0).count(); ++i) { + ObAutoSplitTask &task = tenants_task_array.at(0).at(i); + ASSERT_EQ(expect_hightest_prio_tablet_id--, task.tablet_id_.id_); + } + } + + for (hash::ObHashMap::iterator iter = polling_mgr_.map_tenant_to_cache_.begin(); iter != polling_mgr_.map_tenant_to_cache_.end(); iter++) { + uint64_t tenant_id = iter->first; + ObAutoSplitTaskCache *&tenant_cache = iter->second; + ASSERT_TRUE(tenant_cache != nullptr); + ASSERT_EQ(0, tenant_cache->get_tasks_num()); + } +} + +TEST_F(TestSplitTaskScheduler, mutiple_tenants_hard_push_and_pop) +{ + ObArray task_array; + ObArray nums; + for (int64_t i = 2; i < 102; ++i) { + ASSERT_OK(nums.push_back(i)); + } + std::random_shuffle(nums.begin(), nums.end()); + for (int64_t i = 0; i < nums.count(); ++i ) { + int64_t num = nums.at(i); + ASSERT_OK(task_array.push_back(ObAutoSplitTask(TEST_TENANT_A_ID, ls_id, num/*tablet_id*/, 1/*auto_split_size*/, num/*used_disk_size*/, 0))); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + + ASSERT_OK(task_array.push_back(ObAutoSplitTask(TEST_TENANT_B_ID, ls_id, num/*tablet_id*/, 1/*auto_split_size*/, num/*used_disk_size*/, 0))); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + + ASSERT_OK(task_array.push_back(ObAutoSplitTask(TEST_TENANT_C_ID, ls_id, num/*tablet_id*/, 1/*auto_split_size*/, num/*used_disk_size*/, 0))); + ASSERT_OK(polling_mgr_.push_tasks(task_array)); + task_array.reuse(); + } + ASSERT_EQ(3 * nums.count(), polling_mgr_.total_tasks_); + ASSERT_EQ(3, polling_mgr_.get_total_tenants()); + ObArray> tenants_task_array; + int64_t total_tasks = nums.count() * 3; + + ObArray tenant_A_task_id; + ObArray tenant_B_task_id; + ObArray tenant_C_task_id; + + while (total_tasks > 0) { + tenants_task_array.reuse(); + ASSERT_OK(polling_mgr_.pop_tasks(5, tenants_task_array)); + for (int64_t i = 0; i < tenants_task_array.count(); ++i) { + ObArray &task_array = tenants_task_array.at(i); + ASSERT_TRUE(task_array.count() > 0); + uint64_t tenant_id = task_array.at(0).tenant_id_; + for (int64_t j = 0; j < task_array.count(); ++j) { + total_tasks -= 1; + ASSERT_EQ(tenant_id, task_array.at(j).tenant_id_); + if (tenant_id == TEST_TENANT_A_ID) { + ASSERT_OK(tenant_A_task_id.push_back(task_array.at(j).tablet_id_.id_)); + } else if (tenant_id == TEST_TENANT_B_ID) { + ASSERT_OK(tenant_B_task_id.push_back(task_array.at(j).tablet_id_.id_)); + } else if (tenant_id == TEST_TENANT_C_ID) { + ASSERT_OK(tenant_C_task_id.push_back(task_array.at(j).tablet_id_.id_)); + } + } + } + } + + for (hash::ObHashMap::iterator iter = polling_mgr_.map_tenant_to_cache_.begin(); iter != polling_mgr_.map_tenant_to_cache_.end(); iter++) { + uint64_t tenant_id = iter->first; + ObAutoSplitTaskCache *&tenant_cache = iter->second; + ASSERT_TRUE(tenant_cache != nullptr); + ASSERT_EQ(0, tenant_cache->get_tasks_num()); + } + + + ASSERT_EQ(100, tenant_A_task_id.count()); + ASSERT_EQ(100, tenant_B_task_id.count()); + ASSERT_EQ(100, tenant_C_task_id.count()); + for (int64_t i = 100; i > 0 ; --i) { + ASSERT_EQ(i+1, tenant_A_task_id.at(100 - i)); + ASSERT_EQ(i+1, tenant_B_task_id.at(100 - i)); + ASSERT_EQ(i+1, tenant_C_task_id.at(100 - i)); + } +} + +TEST_F(TestSplitTaskScheduler, parallel_push_and_pop) +{ + ObArray> task_array_1; + ObArray> task_array_2; + ObArray nums_1; + ObArray nums_2; + for (int64_t i = 2; i < 50000; ++i) { + if (i%2 == 0) { + ASSERT_OK(nums_1.push_back(i)); + } else { + ASSERT_OK(nums_2.push_back(i)); + } + } + std::random_shuffle(nums_1.begin(), nums_1.end()); + ObArray tmp_array; + for (int64_t i = 0; i < nums_1.count(); ++i ) { + tmp_array.reuse(); + int64_t num_1 = nums_1.at(i); + ASSERT_OK(tmp_array.push_back(ObAutoSplitTask(TEST_TENANT_A_ID, ls_id, num_1/*tablet_id*/, 1/*auto_split_size*/, num_1/*used_disk_size*/, 0))); + ASSERT_OK(task_array_1.push_back(tmp_array)); + tmp_array.reuse(); + int64_t num_2 = nums_2.at(i); + ASSERT_OK(tmp_array.push_back(ObAutoSplitTask(TEST_TENANT_A_ID, ls_id, num_2/*tablet_id*/, 1/*auto_split_size*/, num_2/*used_disk_size*/, 0))); + ASSERT_OK(task_array_2.push_back(tmp_array)); + } + + + std::thread t1(&push, std::ref(task_array_1), std::ref(polling_mgr_)); + std::thread t2(&push, std::ref(task_array_2), std::ref(polling_mgr_)); + t1.join(); + t2.join(); + ObArray result_array_1; + ObArray result_array_2; + std::thread t3(&pop, std::ref(result_array_1), std::ref(polling_mgr_)); + std::thread t4(&pop, std::ref(result_array_2), std::ref(polling_mgr_)); + t3.join(); + t4.join(); + tmp_array.reuse(); + ASSERT_OK(tmp_array.push_back(result_array_1)); + ASSERT_OK(tmp_array.push_back(result_array_2)); + ASSERT_EQ(100, tmp_array.count()); + int64_t max = 49999; + ObArray id_array; + for (int64_t i = 0; i < tmp_array.count(); ++i) { + id_array.push_back(tmp_array.at(i).tablet_id_.id()); + } + std::sort(id_array.begin(),id_array.end()); + for (int64_t i = id_array.count()-1; i > -1; --i) { + ASSERT_EQ(max--, id_array.at(i)); + } +} + +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + system("rm -rf test_auto_split_polling_mgr.log"); + OB_LOGGER.set_log_level("INFO"); + OB_LOGGER.set_file_name("test_auto_split_polling_mgr.log", true); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/unittest/storage/ddl/test_tablet_data_split.cpp b/unittest/storage/ddl/test_tablet_data_split.cpp new file mode 100644 index 000000000..33f1d779c --- /dev/null +++ b/unittest/storage/ddl/test_tablet_data_split.cpp @@ -0,0 +1,334 @@ +/** + * 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 UNITTEST_DEBUG +#define USING_LOG_PREFIX STORAGE +#include +#include + +#define private public +#define protected public + +#include "share/ob_rpc_struct.h" +#include "share/ob_ddl_common.h" +#include "storage/ddl/ob_tablet_split_task.h" + +namespace oceanbase +{ + +using namespace common; +using namespace lib; +using namespace share; +using namespace storage; +using namespace blocksstable; +using namespace share::schema; +using namespace compaction; + +static const int64_t TEST_TENANT_ID = 1; +static const int64_t TEST_TABLE_ID = 8000; +static const ObLSID TEST_LS_ID = ObLSID(9001); +static const ObTabletID TEST_TABLET_ID = ObTabletID(2323233); +static const int64_t TEST_LOB_COL_CNT = 3; +static const int64_t TEST_SPLIT_DST_CNT = 2; +static const int64_t TEST_CONCURRENT_CNT = 10; + +namespace unittest +{ + +class TestDataSplit : public ::testing::Test +{ +public: + TestDataSplit() = default; + ~TestDataSplit() = default; +public: + virtual void SetUp() override; + virtual void TearDown() override; +public: + int prepare_mock_start_arg( + const bool is_split, + obrpc::ObDDLBuildSingleReplicaRequestArg &arg); + int prepare_mock_finish_arg( + obrpc::ObTabletSplitArg &arg); +}; + +void TestDataSplit::SetUp() +{ +} + +void TestDataSplit::TearDown() +{ +} + +int TestDataSplit::prepare_mock_start_arg( + const bool is_split, + obrpc::ObDDLBuildSingleReplicaRequestArg &arg) +{ + int ret = OB_SUCCESS; + arg.tenant_id_ = TEST_TENANT_ID; + arg.ls_id_ = TEST_LS_ID; + arg.source_tablet_id_ = TEST_TABLET_ID; + arg.dest_tablet_id_ = TEST_TABLET_ID; + arg.source_table_id_ = TEST_TABLE_ID; + arg.dest_schema_id_ = TEST_TABLE_ID; + arg.schema_version_ = 1; + arg.snapshot_version_ = 1; + arg.ddl_type_ = 1006; + arg.task_id_ = 1; + arg.parallelism_ = 1; + arg.execution_id_ = 1; + arg.tablet_task_id_ = 1; + arg.data_format_version_ = 1; + arg.consumer_group_id_ = 1; + arg.dest_tenant_id_ = TEST_TENANT_ID; + arg.dest_ls_id_ = TEST_LS_ID; + arg.dest_schema_version_ = 1; + if (is_split) { + arg.ddl_type_ = 100; + arg.compaction_scn_ = 1; + arg.can_reuse_macro_block_ = 1; + arg.split_sstable_type_ = ObSplitSSTableType::SPLIT_BOTH; + ObDatumRowkey tmp_datum_rowkey; + ObStorageDatum datums[OB_INNER_MAX_ROWKEY_COLUMN_NUMBER]; + tmp_datum_rowkey.assign(datums, OB_INNER_MAX_ROWKEY_COLUMN_NUMBER); + if (OB_FAIL(arg.parallel_datum_rowkey_list_.prepare_allocate(TEST_CONCURRENT_CNT + 1))) { + LOG_WARN("prepare allocate failed", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < TEST_CONCURRENT_CNT + 1; i++) { + if (OB_SUCC(ret) && i < TEST_LOB_COL_CNT) { + if (OB_FAIL(arg.lob_col_idxs_.push_back(i))) { + LOG_WARN("push back failed", K(ret)); + } + } + if (OB_FAIL(ret)) { + } else if (i == 0) { + ObDatumRowkey tmp_min_key; + tmp_min_key.set_min_rowkey(); + if (OB_FAIL(tmp_min_key.deep_copy(arg.parallel_datum_rowkey_list_[i], arg.rowkey_allocator_))) { + LOG_WARN("failed to push min rowkey", K(ret)); + } + } else if (i == TEST_CONCURRENT_CNT) { + ObDatumRowkey tmp_max_key; + tmp_max_key.set_max_rowkey(); + if (OB_FAIL(tmp_max_key.deep_copy(arg.parallel_datum_rowkey_list_[i], arg.rowkey_allocator_))) { + LOG_WARN("failed to push min rowkey", K(ret)); + } + } else { + tmp_datum_rowkey.datums_[0].set_string("aaaaa"); + tmp_datum_rowkey.datums_[1].set_int(i); + tmp_datum_rowkey.datum_cnt_ = 2; + if (OB_FAIL(tmp_datum_rowkey.deep_copy(arg.parallel_datum_rowkey_list_[i] /*dst*/, arg.rowkey_allocator_))) { + LOG_WARN("failed to deep copy datum rowkey", K(ret), K(i), K(tmp_datum_rowkey)); + } + } + } + } + return ret; +} + +int TestDataSplit::prepare_mock_finish_arg(obrpc::ObTabletSplitArg &arg) +{ + int ret = OB_SUCCESS; + arg.ls_id_ = TEST_LS_ID; + arg.table_id_ = TEST_TABLE_ID; + arg.lob_table_id_ = TEST_TABLE_ID; + arg.schema_version_ = 1; + arg.task_id_ = 1; + arg.source_tablet_id_ = TEST_TABLET_ID; + // ASSERT_EQ(OB_SUCCESS, arg.dest_tablets_id_.push_back(TEST_TABLET_ID)); + // ASSERT_EQ(OB_SUCCESS, arg.dest_tablets_id_.push_back(TEST_TABLET_ID)); + arg.compaction_scn_ = 1; + arg.data_format_version_ = 1; + arg.consumer_group_id_ = 1; + arg.can_reuse_macro_block_ = true; + arg.split_sstable_type_ = ObSplitSSTableType::SPLIT_BOTH; + // ASSERT_EQ(OB_SUCCESS, arg.lob_col_idxs_.push_back(0)); + // ASSERT_EQ(OB_SUCCESS, arg.lob_col_idxs_.push_back(1)); + // ASSERT_EQ(OB_SUCCESS, arg.lob_col_idxs_.push_back(2)); + ObDatumRowkey tmp_datum_rowkey; + ObStorageDatum datums[OB_INNER_MAX_ROWKEY_COLUMN_NUMBER]; + tmp_datum_rowkey.assign(datums, OB_INNER_MAX_ROWKEY_COLUMN_NUMBER); + if (OB_FAIL(arg.parallel_datum_rowkey_list_.prepare_allocate(TEST_CONCURRENT_CNT + 1))) { + LOG_WARN("prepare allocate failed", K(ret)); + } + for (int64_t i = 0; OB_SUCC(ret) && i < TEST_CONCURRENT_CNT + 1; i++) { + if (OB_SUCC(ret) && i < TEST_LOB_COL_CNT) { + if (OB_FAIL(arg.lob_col_idxs_.push_back(i))) { + LOG_WARN("push back failed", K(ret)); + } + } + if (OB_SUCC(ret) && i < TEST_SPLIT_DST_CNT) { + if (OB_FAIL(arg.dest_tablets_id_.push_back(TEST_TABLET_ID))) { + LOG_WARN("push back failed", K(ret)); + } + } + + if (OB_FAIL(ret)) { + } else if (i == 0) { + ObDatumRowkey tmp_min_key; + tmp_min_key.set_min_rowkey(); + if (OB_FAIL(tmp_min_key.deep_copy(arg.parallel_datum_rowkey_list_[i], arg.rowkey_allocator_))) { + LOG_WARN("failed to push min rowkey", K(ret)); + } + } else if (i == TEST_CONCURRENT_CNT) { + ObDatumRowkey tmp_max_key; + tmp_max_key.set_max_rowkey(); + if (OB_FAIL(tmp_max_key.deep_copy(arg.parallel_datum_rowkey_list_[i], arg.rowkey_allocator_))) { + LOG_WARN("failed to push min rowkey", K(ret)); + } + } else { + tmp_datum_rowkey.datums_[0].set_string("aaaaa"); + tmp_datum_rowkey.datums_[1].set_int(i); + tmp_datum_rowkey.datum_cnt_ = 2; + if (OB_FAIL(tmp_datum_rowkey.deep_copy(arg.parallel_datum_rowkey_list_[i] /*dst*/, arg.rowkey_allocator_))) { + LOG_WARN("failed to deep copy datum rowkey", K(ret), K(i), K(tmp_datum_rowkey)); + } + } + } + return ret; +} + +TEST_F(TestDataSplit, test_single_replica_request_arg_serialize) +{ + int ret = OB_SUCCESS; + STORAGE_LOG(INFO, "TestDataSplit::ObDDLBuildSingleReplicaRequestArg"); + int64_t pos = 0; + int64_t write_pos = 0; + const int64_t buf_len = 1 * 1024 * 1024; + char serialize_buf[buf_len]; + memset(serialize_buf, 0, sizeof(serialize_buf)); + // without split info, scenarios like drop column. + obrpc::ObDDLBuildSingleReplicaRequestArg drop_column_arg; + ret = prepare_mock_start_arg(false, drop_column_arg); + ASSERT_EQ(OB_SUCCESS, ret); + ret = drop_column_arg.serialize(serialize_buf, buf_len, write_pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(drop_column_arg.get_serialize_size(), write_pos); + obrpc::ObDDLBuildSingleReplicaRequestArg deserialize_drop_column_arg; + ret = deserialize_drop_column_arg.deserialize(serialize_buf, write_pos, pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(pos, write_pos); + + // with split info, scenarios like tablet split. + pos = write_pos = 0; + memset(serialize_buf, 0, sizeof(serialize_buf)); + obrpc::ObDDLBuildSingleReplicaRequestArg split_arg; + ret = prepare_mock_start_arg(true, split_arg); + ASSERT_EQ(OB_SUCCESS, ret); + ret = split_arg.serialize(serialize_buf, buf_len, write_pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(split_arg.get_serialize_size(), write_pos); + obrpc::ObDDLBuildSingleReplicaRequestArg deserialize_split_arg; + ret = deserialize_split_arg.deserialize(serialize_buf, write_pos, pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(pos, write_pos); + ASSERT_EQ(TEST_CONCURRENT_CNT + 1, deserialize_split_arg.parallel_datum_rowkey_list_.count()); + for (int64_t i = 0; OB_SUCC(ret) && i < TEST_LOB_COL_CNT; i++) { + ASSERT_TRUE(deserialize_split_arg.lob_col_idxs_[i] == i); + } + for (int64_t i = 0; OB_SUCC(ret) && i < TEST_CONCURRENT_CNT + 1; i++) { + if (i == 0) { + ASSERT_TRUE(split_arg.parallel_datum_rowkey_list_[i].is_min_rowkey()); + ASSERT_TRUE(deserialize_split_arg.parallel_datum_rowkey_list_[i].is_min_rowkey()); + } else if (i == TEST_CONCURRENT_CNT) { + ASSERT_TRUE(split_arg.parallel_datum_rowkey_list_[i].is_max_rowkey()); + ASSERT_TRUE(deserialize_split_arg.parallel_datum_rowkey_list_[i].is_max_rowkey()); + } else { + ASSERT_TRUE(split_arg.parallel_datum_rowkey_list_[i].datums_[0] == deserialize_split_arg.parallel_datum_rowkey_list_[i].datums_[0]); + ASSERT_TRUE(i == deserialize_split_arg.parallel_datum_rowkey_list_[i].datums_[1].get_int()); + } + } +} + +TEST_F(TestDataSplit, test_split_finish_arg_serialize) +{ + int ret = OB_SUCCESS; + STORAGE_LOG(INFO, "TestDataSplit::test_split_finish_arg_serialize"); + int64_t pos = 0; + int64_t write_pos = 0; + const int64_t buf_len = 1 * 1024 * 1024; + char serialize_buf[buf_len]; + memset(serialize_buf, 0, sizeof(serialize_buf)); + obrpc::ObTabletSplitArg split_arg; + ret = prepare_mock_finish_arg(split_arg); + ASSERT_EQ(OB_SUCCESS, ret); + ret = split_arg.serialize(serialize_buf, buf_len, write_pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(split_arg.get_serialize_size(), write_pos); + + obrpc::ObTabletSplitArg deserialize_split_arg; + ret = deserialize_split_arg.deserialize(serialize_buf, write_pos, pos); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(pos, write_pos); + ASSERT_EQ(TEST_CONCURRENT_CNT + 1, deserialize_split_arg.parallel_datum_rowkey_list_.count()); + for (int64_t i = 0; OB_SUCC(ret) && i < TEST_LOB_COL_CNT; i++) { + ASSERT_TRUE(deserialize_split_arg.lob_col_idxs_[i] == i); + } + for (int64_t i = 0; OB_SUCC(ret) && i < TEST_CONCURRENT_CNT - 1; i++) { + if (i == 0) { + ASSERT_TRUE(split_arg.parallel_datum_rowkey_list_[i].is_min_rowkey()); + ASSERT_TRUE(deserialize_split_arg.parallel_datum_rowkey_list_[i].is_min_rowkey()); + } else if (i == TEST_CONCURRENT_CNT) { + ASSERT_TRUE(split_arg.parallel_datum_rowkey_list_[i].is_max_rowkey()); + ASSERT_TRUE(deserialize_split_arg.parallel_datum_rowkey_list_[i].is_max_rowkey()); + } else { + ASSERT_TRUE(split_arg.parallel_datum_rowkey_list_[i].datums_[0] == deserialize_split_arg.parallel_datum_rowkey_list_[i].datums_[0]); + ASSERT_TRUE(i == deserialize_split_arg.parallel_datum_rowkey_list_[i].datums_[1].get_int()); + } + } +} + +TEST_F(TestDataSplit, test_convert_rowkey_to_range) +{ + int ret = OB_SUCCESS; + STORAGE_LOG(INFO, "TestDataSplit::test_convert_rowkey_to_range"); + ObStorageDatum cmp_datum; + cmp_datum.set_string("aaaaa"); + ObArray datum_ranges_array; + ObArenaAllocator tmp_arena("SplitCnvRange"); + obrpc::ObDDLBuildSingleReplicaRequestArg split_arg; + ret = prepare_mock_start_arg(true, split_arg); + ASSERT_EQ(OB_SUCCESS, ret); + ret = ObTabletSplitUtil::convert_rowkey_to_range(tmp_arena, split_arg.parallel_datum_rowkey_list_, datum_ranges_array); + ASSERT_EQ(OB_SUCCESS, ret); + ASSERT_EQ(TEST_CONCURRENT_CNT, datum_ranges_array.count()); + for (int64_t i = 0; OB_SUCC(ret) && i < TEST_CONCURRENT_CNT; i++) { + if (i == 0) { + ASSERT_TRUE(datum_ranges_array.at(i).start_key_.is_min_rowkey()); + } else { + const ObDatumRowkey &last_end_key = datum_ranges_array.at(i - 1).end_key_; + const ObDatumRowkey &cur_start_key = datum_ranges_array.at(i).start_key_; + const ObDatumRowkey &cur_end_key = datum_ranges_array.at(i).end_key_; + ASSERT_TRUE(last_end_key == cur_start_key); + ASSERT_TRUE(cmp_datum == cur_start_key.datums_[0]); + ASSERT_TRUE(i == cur_start_key.datums_[1].get_int()); + if (TEST_CONCURRENT_CNT - 1 == i) { // the last datum range. + ASSERT_TRUE(cur_end_key.is_max_rowkey()); + } + } + } + STORAGE_LOG(INFO, "TestDataSplit::test_convert_rowkey_to_range", K(ret), "parallel_datum_rowkey_list", split_arg.parallel_datum_rowkey_list_, + K(datum_ranges_array)); +} + +} //unittest +} //oceanbase + + +int main(int argc, char **argv) +{ + system("rm -rf test_tablet_data_split.log*"); + OB_LOGGER.set_file_name("test_tablet_data_split.log", true); + OB_LOGGER.set_log_level("INFO"); + CLOG_LOG(INFO, "begin unittest: test_tablet_data_split"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/unittest/storage/init_basic_struct.h b/unittest/storage/init_basic_struct.h index 69d42418e..ed0d3eb35 100644 --- a/unittest/storage/init_basic_struct.h +++ b/unittest/storage/init_basic_struct.h @@ -85,6 +85,7 @@ int __attribute__((weak)) gen_create_tablet_arg(const int64_t tenant_id, obrpc::ObCreateTabletInfo tablet_info; ObArray index_tablet_ids; ObArray index_tablet_schema_idxs; + ObArray create_commit_versions; uint64_t table_id = 12345; arg.reset(); share::schema::ObTableSchema table_schema_obj; @@ -114,6 +115,7 @@ int __attribute__((weak)) gen_create_tablet_arg(const int64_t tenant_id, index_tablet_schema_idxs, lib::Worker::CompatMode::MYSQL, false, + create_commit_versions, false /*has_cs_replica*/))) { STORAGE_LOG(WARN, "failed to init tablet info", KR(ret), K(index_tablet_ids), K(tablet_id), K(index_tablet_schema_idxs)); diff --git a/unittest/storage/test_compaction_policy.cpp b/unittest/storage/test_compaction_policy.cpp index 7d6f6c47e..c28f02407 100644 --- a/unittest/storage/test_compaction_policy.cpp +++ b/unittest/storage/test_compaction_policy.cpp @@ -443,8 +443,7 @@ int TestCompactionPolicy::mock_tablet( LOG_WARN("failed to init storage schema", KR(ret), K(table_schema)); } else if (FALSE_IT(need_generate_cs_replica_cg_array = ls_handle.get_ls()->is_cs_replica() && create_tablet_schema.is_row_store() && create_tablet_schema.is_user_data_table())) { } else if (OB_FAIL(tablet->init_for_first_time_creation(allocator, ls_id, tablet_id, tablet_id, - SCN::min_scn(), snapshot_version, create_tablet_schema, need_empty_major_table, - false/*micro_index_clustered*/, need_generate_cs_replica_cg_array, false/*has_cs_replica*/, ls_handle.get_ls()->get_freezer()))) { + SCN::min_scn(), snapshot_version, create_tablet_schema, need_empty_major_table, SCN::invalid_scn(), false/*micro_index_clustered*/, need_generate_cs_replica_cg_array, false/*has_cs_replica*/, ls_handle.get_ls()->get_freezer()))) { LOG_WARN("failed to init tablet", K(ret), K(ls_id), K(tablet_id), K(snapshot_version), K(table_schema), K(compat_mode)); } else { diff --git a/unittest/storage/test_dml_common.h b/unittest/storage/test_dml_common.h index 62127ba5b..ea35b2286 100644 --- a/unittest/storage/test_dml_common.h +++ b/unittest/storage/test_dml_common.h @@ -567,6 +567,7 @@ int TestDmlCommon::build_pure_data_tablet_arg( ObCreateTabletInfo tablet_info; ObArray tablet_id_array; ObArray tablet_schema_index_array; + ObArray create_commit_versions; share::schema::ObTableSchema table_schema; build_data_table_schema(tenant_id, table_schema); @@ -575,7 +576,7 @@ int TestDmlCommon::build_pure_data_tablet_arg( STORAGE_LOG(WARN, "failed to push tablet id into array", K(ret), K(data_tablet_id)); } else if (OB_FAIL(tablet_schema_index_array.push_back(0))) { STORAGE_LOG(WARN, "failed to push index into array", K(ret)); - } else if (OB_FAIL(tablet_info.init(tablet_id_array, data_tablet_id, tablet_schema_index_array, lib::Worker::CompatMode::MYSQL, false, false /*has_cs_replica*/))) { + } else if (OB_FAIL(tablet_info.init(tablet_id_array, data_tablet_id, tablet_schema_index_array, lib::Worker::CompatMode::MYSQL, false, create_commit_versions, false /*has_cs_replica*/))) { STORAGE_LOG(WARN, "failed to init tablet info", K(ret), K(tablet_id_array), K(data_tablet_id), K(tablet_schema_index_array)); } else if (OB_FAIL(arg.init_create_tablet(ls_id, share::SCN::min_scn(), false/*need_check_tablet_cnt*/))) { @@ -605,6 +606,7 @@ int TestDmlCommon::build_mixed_tablets_arg( ObCreateTabletInfo tablet_info; ObArray tablet_id_array; ObArray tablet_schema_index_array; + ObArray create_commit_versions; share::schema::ObTableSchema data_table_schema; share::schema::ObTableSchema index_table_schema; build_data_table_schema(tenant_id, data_table_schema); @@ -627,7 +629,7 @@ int TestDmlCommon::build_mixed_tablets_arg( STORAGE_LOG(WARN, "failed to push index into array", K(ret)); } else if (OB_FAIL(tablet_schema_index_array.push_back(1))) { STORAGE_LOG(WARN, "failed to push index into array", K(ret)); - } else if (OB_FAIL(tablet_info.init(tablet_id_array, data_tablet_id, tablet_schema_index_array, lib::Worker::CompatMode::MYSQL, false, false /*has_cs_replica*/))) { + } else if (OB_FAIL(tablet_info.init(tablet_id_array, data_tablet_id, tablet_schema_index_array, lib::Worker::CompatMode::MYSQL, false, create_commit_versions, false /*has_cs_replica*/))) { STORAGE_LOG(WARN, "failed to init tablet info", K(ret), K(tablet_id_array), K(data_tablet_id), K(tablet_schema_index_array)); } else if (OB_FAIL(arg.init_create_tablet(ls_id, share::SCN::min_scn(), false/*need_check_tablet_cnt*/))) { diff --git a/unittest/storage/test_lob_common.h b/unittest/storage/test_lob_common.h index ce0e9dc88..cd7b5af6c 100644 --- a/unittest/storage/test_lob_common.h +++ b/unittest/storage/test_lob_common.h @@ -314,6 +314,7 @@ int TestLobCommon::build_lob_tablet_arg( ObCreateTabletInfo tablet_info; ObArray tablet_id_array; ObArray tablet_schema_index_array; + ObArray create_commit_versions; share::schema::ObTableSchema table_schema; build_data_table_schema(tenant_id, table_schema); share::schema::ObTableSchema lob_meta_schema; @@ -335,7 +336,7 @@ int TestLobCommon::build_lob_tablet_arg( } else if (OB_FAIL(tablet_schema_index_array.push_back(2))) { STORAGE_LOG(WARN, "failed to push index into array", K(ret)); } else if (OB_FAIL(tablet_info.init(tablet_id_array, data_tablet_id, tablet_schema_index_array, - lib::get_compat_mode(), false/*is_create_bind_hidden_tablets*/))) { + lib::get_compat_mode(), false/*is_create_bind_hidden_tablets*/, create_commit_versions))) { STORAGE_LOG(WARN, "failed to init tablet info", K(ret), K(tablet_id_array), K(data_tablet_id), K(tablet_schema_index_array)); } else if (OB_FAIL(arg.init_create_tablet(ls_id, share::SCN::min_scn(), false/*need_check_tablet_cnt*/))) { diff --git a/unittest/storage/test_tablet_helper.h b/unittest/storage/test_tablet_helper.h index bb09aa135..88d0cc43f 100644 --- a/unittest/storage/test_tablet_helper.h +++ b/unittest/storage/test_tablet_helper.h @@ -138,8 +138,7 @@ inline int TestTabletHelper::create_tablet( } else if (OB_FAIL(tablet_handle.get_obj()->init_for_first_time_creation( *tablet_handle.get_allocator(), ls_id, tablet_id, tablet_id, share::SCN::base_scn(), - snapshot_version, create_tablet_schema, need_create_empty_major_sstable, - false/*micro_index_clustered*/, need_generate_cs_replica_cg_array, false/*has_cs_replica*/, freezer))){ + snapshot_version, create_tablet_schema, need_create_empty_major_sstable, share::SCN::invalid_scn(), false/*micro_index_clustered*/, need_generate_cs_replica_cg_array, false/*has_cs_replica*/, freezer))){ STORAGE_LOG(WARN, "failed to init tablet", K(ret), K(ls_id), K(tablet_id)); } else if (ObTabletStatus::Status::MAX != tablet_status) { ObTabletCreateDeleteMdsUserData data; diff --git a/unittest/storage/transaction/CMakeLists.txt b/unittest/storage/transaction/CMakeLists.txt index 4411a3e35..6fc239053 100644 --- a/unittest/storage/transaction/CMakeLists.txt +++ b/unittest/storage/transaction/CMakeLists.txt @@ -1,3 +1,5 @@ +add_subdirectory(tablelock) + storage_unittest(test_ob_trans_mem_stat) storage_unittest(test_ob_trans_factory) #storage_unittest(test_ob_time_wheel) diff --git a/unittest/storage/transaction/tablelock/CMakeLists.txt b/unittest/storage/transaction/tablelock/CMakeLists.txt new file mode 100644 index 000000000..9f860da4e --- /dev/null +++ b/unittest/storage/transaction/tablelock/CMakeLists.txt @@ -0,0 +1 @@ +storage_unittest(test_ob_replace_lock_request) diff --git a/unittest/storage/transaction/tablelock/test_ob_replace_lock_request.cpp b/unittest/storage/transaction/tablelock/test_ob_replace_lock_request.cpp new file mode 100644 index 000000000..36796f712 --- /dev/null +++ b/unittest/storage/transaction/tablelock/test_ob_replace_lock_request.cpp @@ -0,0 +1,227 @@ +/** + * 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 UNITTEST_DEBUG +#include "storage/tablelock/ob_table_lock_rpc_struct.h" +#include + +namespace oceanbase +{ +namespace unittest +{ +using namespace common; +using namespace transaction; +using namespace transaction::tablelock; +#define CHECK_SERIALIZE_AND_DESERIALIZE(T) \ + ret = replace_req.serialize(buf, LEN, pos); \ + ASSERT_EQ(ret, OB_SUCCESS); \ + ASSERT_GT(pos, 0); \ + TABLELOCK_LOG(INFO, "1. replace_req and unlock_req", K(replace_req), K(unlock_req), K(pos), KPHEX(buf, pos)); \ + ObReplaceLockRequest des_replace_req; \ + T des_unlock_req; \ + pos = 0; \ + ret = des_replace_req.deserialize_and_check_header(buf, LEN, pos); \ + ASSERT_EQ(ret, OB_SUCCESS); \ + ASSERT_GT(pos, 0); \ + TABLELOCK_LOG(INFO, "2. deserialize and check header", K(orig_pos), K(pos), KPHEX(buf + orig_pos, pos - orig_pos)); \ + orig_pos = pos; \ + ret = des_replace_req.deserialize_new_lock_mode_and_owner(buf, LEN, pos); \ + ASSERT_EQ(ret, OB_SUCCESS); \ + ASSERT_GT(pos, orig_pos); \ + TABLELOCK_LOG(INFO, \ + "3. deserialize new lock_mode and new lock_owner", \ + K(orig_pos), \ + K(pos), \ + KPHEX(buf + orig_pos, pos - orig_pos)); \ + orig_pos = pos; \ + ret = des_unlock_req.deserialize(buf, LEN, pos); \ + ASSERT_EQ(ret, OB_SUCCESS); \ + ASSERT_GT(pos, orig_pos); \ + des_replace_req.unlock_req_ = &des_unlock_req; \ + TABLELOCK_LOG(INFO, \ + "4. deserialized replace_req and unlock_req", \ + K(des_replace_req), \ + K(des_unlock_req), \ + K(orig_pos), \ + K(pos), \ + KPHEX(buf + orig_pos, pos - orig_pos)); \ + ASSERT_TRUE(replace_req_is_equal(replace_req, des_replace_req)); + +template +bool list_is_equal(const ObIArray &list1, const ObIArray &list2) +{ + bool is_equal = false; + is_equal = list1.count() == list2.count(); + if (is_equal) { + for (int64_t i = 0; i < list1.count(); i++) { + is_equal = list1.at(i) == list2.at(i); + if (!is_equal) { + TABLELOCK_LOG(INFO, "meet not equal element", K(list1), K(list2), K(list1.at(i)), K(list2.at(i))); + break; + } + } + } + return is_equal; +} + +bool unlock_req_is_equal(const ObLockRequest &req1, const ObLockRequest &req2) +{ + bool is_equal = false; + is_equal = req1.type_ == req2.type_ && req1.owner_id_ == req2.owner_id_ && req1.lock_mode_ == req2.lock_mode_ + && req1.op_type_ == req2.op_type_ && req1.timeout_us_ == req2.timeout_us_; + if (is_equal) { + switch (req1.type_) { + case transaction::tablelock::ObLockRequest::ObLockMsgType::LOCK_TABLE_REQ: { + const ObUnLockTableRequest &lock_req1 = static_cast(req1); + const ObUnLockTableRequest &lock_req2 = static_cast(req2); + is_equal = lock_req1.table_id_ == lock_req2.table_id_; + TABLELOCK_LOG(INFO, "compare unlock request", K(lock_req1), K(lock_req2), K(is_equal)); + break; + } + case transaction::tablelock::ObLockRequest::ObLockMsgType::LOCK_TABLET_REQ: { + const ObUnLockTabletsRequest &lock_req1 = static_cast(req1); + const ObUnLockTabletsRequest &lock_req2 = static_cast(req2); + is_equal = + lock_req1.table_id_ == lock_req2.table_id_ && list_is_equal(lock_req1.tablet_ids_, lock_req1.tablet_ids_); + TABLELOCK_LOG(INFO, "compare unlock request", K(lock_req1), K(lock_req2), K(is_equal)); + break; + } + case transaction::tablelock::ObLockRequest::ObLockMsgType::LOCK_PARTITION_REQ: { + const ObUnLockPartitionRequest &lock_req1 = static_cast(req1); + const ObUnLockPartitionRequest &lock_req2 = static_cast(req2); + is_equal = lock_req1.table_id_ == lock_req2.table_id_ && lock_req1.part_object_id_ == lock_req2.part_object_id_; + TABLELOCK_LOG(INFO, "compare unlock request", K(lock_req1), K(lock_req2), K(is_equal)); + break; + } + case transaction::tablelock::ObLockRequest::ObLockMsgType::LOCK_OBJ_REQ: { + const ObUnLockObjsRequest &lock_req1 = static_cast(req1); + const ObUnLockObjsRequest &lock_req2 = static_cast(req2); + is_equal = list_is_equal(lock_req1.objs_, lock_req1.objs_); + TABLELOCK_LOG(INFO, "compare unlock request", K(lock_req1), K(lock_req2), K(is_equal)); + break; + } + case transaction::tablelock::ObLockRequest::ObLockMsgType::LOCK_ALONE_TABLET_REQ: { + const ObUnLockAloneTabletRequest &lock_req1 = static_cast(req1); + const ObUnLockAloneTabletRequest &lock_req2 = static_cast(req2); + is_equal = lock_req1.table_id_ == lock_req2.table_id_ && lock_req1.ls_id_ == lock_req2.ls_id_ + && list_is_equal(lock_req1.tablet_ids_, lock_req1.tablet_ids_); + TABLELOCK_LOG(INFO, "compare unlock request", K(lock_req1), K(lock_req2), K(is_equal)); + break; + } + default: { + is_equal = false; + int ret = OB_INVALID_ARGUMENT; + TABLELOCK_LOG(WARN, "meet unspport request type", K(req1), K(req2)); + } + } + } + return is_equal; +} + +bool replace_req_is_equal(const ObReplaceLockRequest &req1, const ObReplaceLockRequest &req2) +{ + bool is_equal = false; + is_equal = req1.new_lock_owner_ == req2.new_lock_owner_ && req2.new_lock_mode_ == req2.new_lock_mode_; + return is_equal && unlock_req_is_equal(*(req1.unlock_req_), *(req2.unlock_req_)); +} + +TEST(ObReplaceLockRequest, test_replace_table_lock) +{ + INIT_SUCC(ret); + ObReplaceLockRequest replace_req; + ObUnLockTableRequest unlock_req; + const int LEN = 100; + char buf[LEN]; + int64_t pos = 0; + int64_t orig_pos = 0; + + unlock_req.owner_id_.convert_from_value(1001); + unlock_req.lock_mode_ = EXCLUSIVE; + unlock_req.op_type_ = OUT_TRANS_UNLOCK; + unlock_req.timeout_us_ = 1000; + unlock_req.table_id_ = 998; + + replace_req.new_lock_mode_ = SHARE; + replace_req.new_lock_owner_.convert_from_value(1002); + replace_req.unlock_req_ = &unlock_req; + CHECK_SERIALIZE_AND_DESERIALIZE(ObUnLockTableRequest); +} + +TEST(ObReplaceLockRequest, test_replace_alone_tablet) +{ + INIT_SUCC(ret); + ObReplaceLockRequest replace_req; + ObUnLockAloneTabletRequest unlock_req; + const int LEN = 100; + char buf[LEN]; + int64_t pos = 0; + int64_t orig_pos = 0; + + unlock_req.owner_id_.convert_from_value(1001); + unlock_req.lock_mode_ = EXCLUSIVE; + unlock_req.op_type_ = OUT_TRANS_UNLOCK; + unlock_req.timeout_us_ = 1000; + unlock_req.table_id_ = 998; + unlock_req.ls_id_ = 1; + unlock_req.tablet_ids_.push_back(ObTabletID(123)); + unlock_req.tablet_ids_.push_back(ObTabletID(456)); + unlock_req.tablet_ids_.push_back(ObTabletID(789)); + + replace_req.new_lock_mode_ = SHARE; + replace_req.new_lock_owner_.convert_from_value(1002); + replace_req.unlock_req_ = &unlock_req; + CHECK_SERIALIZE_AND_DESERIALIZE(ObUnLockAloneTabletRequest); +} + +TEST(ObReplaceLockRequest, test_replace_objs) +{ + INIT_SUCC(ret); + ObReplaceLockRequest replace_req; + ObUnLockObjsRequest unlock_req; + const int LEN = 100; + char buf[LEN]; + int64_t pos = 0; + int64_t orig_pos = 0; + + unlock_req.owner_id_.convert_from_value(1001); + unlock_req.lock_mode_ = EXCLUSIVE; + unlock_req.op_type_ = OUT_TRANS_UNLOCK; + unlock_req.timeout_us_ = 1000; + ObLockID lock_id1; + lock_id1.set(ObLockOBJType::OBJ_TYPE_TABLE, 123); + unlock_req.objs_.push_back(lock_id1); + ObLockID lock_id2; + lock_id2.set(ObLockOBJType::OBJ_TYPE_TABLET, 456); + unlock_req.objs_.push_back(lock_id2); + ObLockID lock_id3; + lock_id3.set(ObLockOBJType::OBJ_TYPE_COMMON_OBJ, 789); + unlock_req.objs_.push_back(lock_id3); + + replace_req.new_lock_mode_ = SHARE; + replace_req.new_lock_owner_.convert_from_value(1002); + replace_req.unlock_req_ = &unlock_req; + CHECK_SERIALIZE_AND_DESERIALIZE(ObUnLockTableRequest); +} +} // namespace unittest +} // namespace oceanbase +int main(int argc, char **argv) +{ + system("rm -rf test_ob_replace_lock_request.log"); + + oceanbase::ObLogger &logger = oceanbase::ObLogger::get_logger(); + logger.set_file_name("test_ob_replace_lock_request.log", false); + logger.set_log_level(OB_LOG_LEVEL_DEBUG); + + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); + ; +}