/** * 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_MULTI_VERSION_SSTABLE_TEST_H_ #define OB_MULTI_VERSION_SSTABLE_TEST_H_ #define USING_LOG_PREFIX STORAGE #include #define private public #define protected public #include "ob_data_file_prepare.h" #include "share/ob_device_manager.h" #include "share/ob_local_device.h" #include "storage/ls/ob_ls.h" #include "storage/ls/ob_ls_tablet_service.h" #include "storage/mock_ob_meta_report.h" #include "storage/mock_disk_usage_report.h" #include "storage/meta_mem/ob_tenant_meta_mem_mgr.h" #include "lib/file/file_directory_utils.h" #include "share/ob_device_manager.h" #include "share/ob_local_device.h" #include "share/schema/ob_tenant_schema_service.h" #include "storage/tablet/ob_tablet_create_delete_helper.h" #include "storage/tx_storage/ob_tenant_freezer.h" #include "mtlenv/mock_tenant_module_env.h" #include "storage/test_dml_common.h" #include "share/ob_simple_mem_limit_getter.h" #include "../mockcontainer/mock_ob_iterator.h" #include "storage/tablet/ob_tablet_create_sstable_param.h" #include "unittest/storage/mock_ob_table_read_info.h" #include "storage/column_store/ob_column_oriented_sstable.h" #include "storage/compaction/ob_compaction_memory_context.h" #include "storage/ob_storage_schema_util.h" #define OK(ass) ASSERT_EQ(OB_SUCCESS, (ass)) namespace oceanbase { using namespace common; using namespace blocksstable; using namespace share::schema; using namespace compaction; static ObSimpleMemLimitGetter getter; namespace storage { int init_io_device(const char *test_name, const int64_t macro_block_size = OB_DEFAULT_MACRO_BLOCK_SIZE, const int64_t macro_block_count = 1000) { int ret = OB_SUCCESS; char cur_dir[OB_MAX_FILE_NAME_LENGTH]; char data_dir[OB_MAX_FILE_NAME_LENGTH]; char file_dir[OB_MAX_FILE_NAME_LENGTH]; char slog_dir[OB_MAX_FILE_NAME_LENGTH]; char clog_dir[OB_MAX_FILE_NAME_LENGTH]; char cmd[OB_MAX_FILE_NAME_LENGTH]; char dirname[MAX_PATH_SIZE]; char link_name[MAX_PATH_SIZE]; ObStorageEnv storage_env; const int64_t bucket_num = 1024L; const int64_t max_cache_size = 1024L * 1024L * 512; const int64_t block_size = common::OB_MALLOC_BIG_BLOCK_SIZE; const int64_t mem_limit = 10 * 1024L * 1024L * 1024L; lib::set_memory_limit(mem_limit); if (NULL == getcwd(cur_dir, OB_MAX_FILE_NAME_LENGTH)) { ret = OB_BUF_NOT_ENOUGH; STORAGE_LOG(WARN, "cannot get cur dir", K(ret)); } else if (OB_FAIL(databuff_printf(data_dir, OB_MAX_FILE_NAME_LENGTH, "%s/data_%s", cur_dir, test_name))) { STORAGE_LOG(WARN, "failed to gen data dir", K(ret)); } else if (OB_FAIL(databuff_printf(file_dir, OB_MAX_FILE_NAME_LENGTH, "%s/sstable/", data_dir))) { STORAGE_LOG(WARN, "failed to databuff printf", K(ret)); } else if (OB_FAIL(databuff_printf(slog_dir, OB_MAX_FILE_NAME_LENGTH, "%s/slog/", data_dir))) { STORAGE_LOG(WARN, "failed to gen slog dir", K(ret)); } else if (OB_FAIL(databuff_printf(clog_dir, OB_MAX_FILE_NAME_LENGTH, "%s/clog/", data_dir))) { STORAGE_LOG(WARN, "failed to gen clog dir", K(ret)); } else { storage_env.data_dir_ = data_dir; storage_env.sstable_dir_ = file_dir; storage_env.default_block_size_ = macro_block_size; storage_env.log_spec_.log_dir_ = slog_dir; storage_env.log_spec_.max_log_file_size_ = 64 * 1024 * 1024; storage_env.clog_dir_ = clog_dir; storage_env.bf_cache_miss_count_threshold_ = 10000; storage_env.bf_cache_priority_ = 1; storage_env.index_block_cache_priority_ = 10; storage_env.user_block_cache_priority_ = 1; storage_env.user_row_cache_priority_ = 1; storage_env.fuse_row_cache_priority_ = 1; storage_env.storage_meta_cache_priority_ = 10; storage_env.ethernet_speed_ = 1000000; storage_env.redundancy_level_ = ObStorageEnv::NORMAL_REDUNDANCY; storage_env.clog_file_spec_.retry_write_policy_ = "normal"; storage_env.clog_file_spec_.log_create_policy_ = "normal"; storage_env.clog_file_spec_.log_write_policy_ = "truncate"; storage_env.slog_file_spec_.retry_write_policy_ = "normal"; storage_env.slog_file_spec_.log_create_policy_ = "normal"; storage_env.slog_file_spec_.log_write_policy_ = "truncate"; storage_env.data_disk_size_ = macro_block_count * macro_block_size; GCONF.micro_block_merge_verify_level = 0; ObAddr tmp_addr = GCTX.self_addr(); tmp_addr.set_ip_addr("100.1.2.3", 456); GCTX.self_addr_seq_.set_addr(tmp_addr); } if (OB_SUCC(ret)) { if (OB_FAIL(ObIODeviceWrapper::get_instance().init( storage_env.data_dir_, storage_env.sstable_dir_, storage_env.default_block_size_, storage_env.data_disk_percentage_, storage_env.data_disk_size_))) { STORAGE_LOG(WARN, "init io device fail", K(ret), K(storage_env)); } else if (OB_FAIL(OB_STORE_CACHE.init( storage_env.index_block_cache_priority_, storage_env.user_block_cache_priority_, storage_env.user_row_cache_priority_, storage_env.fuse_row_cache_priority_, storage_env.bf_cache_priority_, storage_env.bf_cache_miss_count_threshold_, storage_env.storage_meta_cache_priority_))) { STORAGE_LOG(WARN, "Fail to init OB_STORE_CACHE, ", K(ret), K(storage_env.data_dir_)); } } return ret; } class ObMultiVersionSSTableTest : public ::testing::Test { public: ObMultiVersionSSTableTest( const char *test_name, const ObMergeType merge_type = MINOR_MERGE, const ObRowStoreType row_store_type = FLAT_ROW_STORE); virtual ~ObMultiVersionSSTableTest(); virtual void SetUp(); virtual void TearDown(); static void SetUpTestCase(); static void TearDownTestCase(); void prepare_data( ObTableHandleV2 &handle, const char **micro_data, const int64_t micro_cnt, const int64_t rowkey_cnt, const ObScnRange &scn_range, const int64_t snapshot_version); public: ObITable::TableType get_merged_table_type() const; void prepare_table_schema(const char **micro_data, const int64_t schema_rowkey_cnt, const ObScnRange &scn_range, const int64_t snapshot_version); void init_tablet(); void reset_writer(const int64_t snapshot_version); void prepare_one_macro( const char **micro_data, const int64_t micro_cnt, const int64_t max_merged_trans_version = INT64_MAX - 2, const bool contain_uncommitted = false); void prepare_data_end(ObTableHandleV2 &handle, const ObITable::TableType &table_type = ObITable::MINI_SSTABLE, const uint16_t column_idx = 0); void append_micro_block(ObMockIterator &data_iter); public: static const int64_t MICRO_BLOCK_SIZE = 4 * 1024; static const int64_t MACRO_BLOCK_SIZE = 64 * 1024; static const int64_t MAX_MICRO_BLOCK_CNT = 100; static const int64_t MACRO_BLOCK_COUNT = 1000; static const int64_t SCHEMA_VERSION = 10; static const int64_t TEST_COLUMN_CNT = 6; static const int64_t TEST_ROWKEY_COLUMN_CNT = 2; static const int64_t MAX_FILE_SIZE = 256 * 1024 * 1024; enum LoadDataType { ALL_DELETE = 0, ALL_INSERT = 1, MIX_DELETE_WITH_UPDATE = 2, }; static const uint64_t tenant_id_ = 1; static const uint64_t tablet_id_ = 300000; static const uint64_t table_id_ = 300000; static const uint64_t ls_id_ = 1001; ObMergeType merge_type_; ObTenantFreezeInfoMgr *mgr_; ObTableSchema table_schema_; ObITable::TableKey table_key_; ObWholeDataStoreDesc data_desc_; ObWholeDataStoreDesc index_desc_; ObMacroBlockWriter macro_writer_; ObMicroBlockWriter micro_writer_; ObRowStoreType row_store_type_; ObSSTableIndexBuilder *root_index_builder_; int64_t data_iter_cursor_; ObMockIterator data_iter_[MAX_MICRO_BLOCK_CNT]; // query ObFixedArray full_cols_; ObTableIterParam iter_param_; ObTableAccessContext context_; storage::MockObTableReadInfo full_read_info_; ObDatumRow datum_row_; static ObArenaAllocator allocator_; static compaction::ObLocalArena local_arena_; static compaction::ObCompactionMemoryContext mem_ctx_; char test_name_[100]; MockObMetaReport rs_reporter_; MockDiskUsageReport disk_reporter_; }; ObArenaAllocator ObMultiVersionSSTableTest::allocator_; compaction::ObLocalArena ObMultiVersionSSTableTest::local_arena_("TestArena", OB_MALLOC_NORMAL_BLOCK_SIZE); compaction::ObCompactionMemoryContext ObMultiVersionSSTableTest::mem_ctx_(ObMultiVersionSSTableTest::allocator_); void ObMultiVersionSSTableTest::SetUpTestCase() { int ret = OB_SUCCESS; ret = MockTenantModuleEnv::get_instance().init(); ASSERT_EQ(OB_SUCCESS, ret); ObServerCheckpointSlogHandler::get_instance().is_started_ = true; //OK(init_io_device("multi_version_test")); // create ls ObLSHandle ls_handle; ret = TestDmlCommon::create_ls(tenant_id_, ObLSID(ls_id_), ls_handle); ASSERT_EQ(OB_SUCCESS, ret); } void ObMultiVersionSSTableTest::TearDownTestCase() { ASSERT_EQ(OB_SUCCESS, MTL(ObLSService*)->remove_ls(ObLSID(ls_id_))); ObKVGlobalCache::get_instance().destroy(); //ObIODeviceWrapper::get_instance().destroy(); OB_STORE_CACHE.destroy(); MockTenantModuleEnv::get_instance().destroy(); } ObMultiVersionSSTableTest::ObMultiVersionSSTableTest( const char *test_name, const ObMergeType merge_type, const ObRowStoreType row_store_type) : merge_type_(merge_type), mgr_(nullptr), table_schema_(), row_store_type_(row_store_type), root_index_builder_(nullptr), data_iter_cursor_(0), full_read_info_() { memcpy(test_name_, test_name, strlen(test_name)); } ObMultiVersionSSTableTest::~ObMultiVersionSSTableTest() {} void ObMultiVersionSSTableTest::SetUp() { ASSERT_TRUE(MockTenantModuleEnv::get_instance().is_inited()); } void ObMultiVersionSSTableTest::TearDown() { if (nullptr != root_index_builder_) { root_index_builder_->~ObSSTableIndexBuilder(); allocator_.free((void *)root_index_builder_); root_index_builder_ = nullptr; } } ObITable::TableType ObMultiVersionSSTableTest::get_merged_table_type() const { ObITable::TableType table_type = ObITable::MAX_TABLE_TYPE; if (MAJOR_MERGE == merge_type_) { table_type = ObITable::TableType::MAJOR_SSTABLE; } else if (MINI_MERGE == merge_type_) { table_type = ObITable::TableType::MINI_SSTABLE; } else if (META_MAJOR_MERGE == merge_type_) { table_type = ObITable::TableType::META_MAJOR_SSTABLE; } else if (DDL_KV_MERGE == merge_type_) { table_type = ObITable::TableType::DDL_MERGE_CO_SSTABLE; } else { // MINOR_MERGE table_type = ObITable::TableType::MINOR_SSTABLE; } return table_type; } void ObMultiVersionSSTableTest::prepare_table_schema( const char **micro_data, const int64_t schema_rowkey_cnt, const ObScnRange &scn_range, const int64_t snapshot_version) { full_read_info_.reset(); data_iter_cursor_ = 0; for (int64_t i = 0; i < MAX_MICRO_BLOCK_CNT; i++) { data_iter_[i].reset(); } OK(data_iter_[0].from(micro_data[0])); ObSEArray tmp_col_descs; int64_t extra_rowkey_cnt = ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); int64_t column_cnt = data_iter_[0].get_column_cnt(); for (int64_t i = 0; i < column_cnt; i++) { share::schema::ObColDesc col_desc; col_desc.col_type_ = data_iter_[0].get_column_type()[i]; if (i == schema_rowkey_cnt) { col_desc.col_id_ = common::OB_HIDDEN_TRANS_VERSION_COLUMN_ID; } else if (i == schema_rowkey_cnt + 1) { col_desc.col_id_ = common::OB_HIDDEN_SQL_SEQUENCE_COLUMN_ID; } else { col_desc.col_id_ = common::OB_APP_MIN_COLUMN_ID + i; } OK(tmp_col_descs.push_back(col_desc)); } OK(full_read_info_.init(allocator_, column_cnt - extra_rowkey_cnt, schema_rowkey_cnt, lib::is_oracle_mode(), tmp_col_descs)); //init table schema table_schema_.reset(); ASSERT_EQ(OB_SUCCESS, table_schema_.set_table_name("test_index_block")); table_schema_.set_tenant_id(tenant_id_); table_schema_.set_tablegroup_id(1); table_schema_.set_database_id(1); table_schema_.set_table_id(table_id_); table_schema_.set_rowkey_column_num(full_read_info_.get_schema_rowkey_count()); table_schema_.set_max_used_column_id(common::OB_APP_MIN_COLUMN_ID + full_read_info_.get_request_count()); table_schema_.set_block_size(2 * 1024); table_schema_.set_compress_func_name("none"); table_schema_.set_row_store_type(FLAT_ROW_STORE); table_schema_.set_storage_format_version(OB_STORAGE_FORMAT_VERSION_V4); ObColumnSchemaV2 column; //init column char name[OB_MAX_FILE_NAME_LENGTH]; memset(name, 0, sizeof(name)); column_cnt = full_read_info_.get_request_count(); for(int64_t i = 0; i < tmp_col_descs.count(); ++i) { column.reset(); bool is_rowkey_col = false; if (i < schema_rowkey_cnt) { is_rowkey_col = true; column.set_rowkey_position(i + 1); } else if (i == schema_rowkey_cnt || i == schema_rowkey_cnt + 1) { continue; } column.set_table_id(table_id_); sprintf(name, "test%020ld", i); ASSERT_EQ(OB_SUCCESS, column.set_column_name(name)); column.set_data_type(tmp_col_descs.at(i).col_type_.get_type()); column.set_column_id(tmp_col_descs.at(i).col_id_); column.set_collation_type(CS_TYPE_UTF8MB4_GENERAL_CI); column.set_data_length(1); ASSERT_EQ(OB_SUCCESS, table_schema_.add_column(column)); } column.reset(); table_key_.table_type_ = get_merged_table_type(); table_key_.tablet_id_ = tablet_id_; table_key_.scn_range_ = scn_range; if (is_major_merge(merge_type_)) { table_key_.version_range_.snapshot_version_ = snapshot_version; } init_tablet(); } void ObMultiVersionSSTableTest::init_tablet() { ObLSID ls_id(ls_id_); ObTabletID tablet_id(tablet_id_); ObLSHandle ls_handle; ObLSService *ls_svr = MTL(ObLSService*); ASSERT_EQ(OB_SUCCESS, ls_svr->get_ls(ls_id, ls_handle, ObLSGetMod::STORAGE_MOD)); ObTabletHandle tablet_handle; void *ptr = nullptr; ASSERT_EQ(OB_SUCCESS, ls_handle.get_ls()->get_tablet(tablet_id, tablet_handle)); ObTablet *tablet = tablet_handle.get_obj(); ASSERT_EQ(OB_SUCCESS, ObStorageSchemaUtil::alloc_storage_schema(allocator_, tablet->storage_schema_addr_.ptr_)); tablet->storage_schema_addr_.get_ptr()->init(allocator_, table_schema_, lib::Worker::CompatMode::MYSQL); ASSERT_NE(nullptr, ptr = allocator_.alloc(sizeof(ObRowkeyReadInfo))); tablet->rowkey_read_info_ = new (ptr) ObRowkeyReadInfo(); tablet->build_read_info(allocator_); } void ObMultiVersionSSTableTest::reset_writer(const int64_t snapshot_version) { ObMacroDataSeq start_seq(0); start_seq.set_data_block(); macro_writer_.reset(); datum_row_.reset(); datum_row_.init(allocator_, full_read_info_.get_request_count()); if (nullptr != root_index_builder_) { root_index_builder_->~ObSSTableIndexBuilder(); allocator_.free((void *)root_index_builder_); root_index_builder_ = nullptr; } ObLSID ls_id(ls_id_); ObTabletID tablet_id(tablet_id_); SCN scn; scn.convert_for_tx(snapshot_version); ASSERT_EQ(OB_SUCCESS, data_desc_.init(table_schema_, ls_id, tablet_id, merge_type_, snapshot_version, DATA_VERSION_4_1_0_0, scn)); void *builder_buf = allocator_.alloc(sizeof(ObSSTableIndexBuilder)); root_index_builder_ = new (builder_buf) ObSSTableIndexBuilder(); ASSERT_NE(nullptr, root_index_builder_); data_desc_.get_desc().sstable_index_builder_ = root_index_builder_; data_desc_.get_desc().row_store_type_ = row_store_type_; ASSERT_TRUE(data_desc_.is_valid()); ASSERT_EQ(OB_SUCCESS, index_desc_.gen_index_store_desc(data_desc_.get_desc())); ASSERT_TRUE(index_desc_.is_valid()); ASSERT_EQ(OB_SUCCESS, root_index_builder_->init(index_desc_.get_desc())); ASSERT_EQ(OB_SUCCESS, macro_writer_.open(data_desc_.get_desc(), start_seq)); } void ObMultiVersionSSTableTest::prepare_one_macro( const char **micro_data, const int64_t micro_cnt, const int64_t max_merged_trans_version, const bool contain_uncommitted) { int64_t parsed_micro_cnt = 0; ASSERT_TRUE(data_iter_cursor_ < MAX_MICRO_BLOCK_CNT); macro_writer_.macro_blocks_[macro_writer_.current_index_].update_max_merged_trans_version(max_merged_trans_version); if (contain_uncommitted) { macro_writer_.macro_blocks_[macro_writer_.current_index_].set_contain_uncommitted_row(); } if (0 == data_iter_cursor_) { macro_writer_.last_key_.set_min_rowkey(); append_micro_block(data_iter_[0]); if (1 == micro_cnt) { OK(macro_writer_.build_micro_block()); OK(macro_writer_.try_switch_macro_block()); } else { OK(macro_writer_.build_micro_block()); } parsed_micro_cnt++; data_iter_cursor_++; } for (; parsed_micro_cnt < micro_cnt && data_iter_cursor_ < MAX_MICRO_BLOCK_CNT;) { OK(data_iter_[data_iter_cursor_].from(micro_data[parsed_micro_cnt])); append_micro_block(data_iter_[data_iter_cursor_]); parsed_micro_cnt++; data_iter_cursor_++; if (micro_cnt == parsed_micro_cnt) { OK(macro_writer_.build_micro_block()); OK(macro_writer_.try_switch_macro_block()); } else { OK(macro_writer_.build_micro_block()); } } } void ObMultiVersionSSTableTest::append_micro_block(ObMockIterator &data_iter) { const ObStoreRow *row = nullptr; for (int64_t i = 0; i < data_iter.count(); i++) { OK(data_iter.get_row(i, row)); ASSERT_TRUE(nullptr != row); datum_row_.from_store_row(*row); ASSERT_EQ(OB_SUCCESS, macro_writer_.append_row(datum_row_)); } } void ObMultiVersionSSTableTest::prepare_data_end( ObTableHandleV2 &handle, const ObITable::TableType &table_type, const uint16_t column_idx) { ASSERT_EQ(OB_SUCCESS, macro_writer_.close()); ObSSTableMergeRes res; const int64_t column_cnt = table_schema_.get_column_count() + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); ASSERT_EQ(OB_SUCCESS, root_index_builder_->close(res)); ObTabletCreateSSTableParam param; table_key_.table_type_ = table_type; ASSERT_EQ(OB_SUCCESS, param.data_block_ids_.assign(res.data_block_ids_)); ASSERT_EQ(OB_SUCCESS, param.other_block_ids_.assign(res.other_block_ids_)); param.table_key_ = table_key_; param.schema_version_ = SCHEMA_VERSION; param.create_snapshot_version_ = 0; param.progressive_merge_round_ = table_schema_.get_progressive_merge_round(); param.progressive_merge_step_ = 0; param.table_mode_ = table_schema_.get_table_mode_struct(); param.index_type_ = table_schema_.get_index_type(); param.latest_row_store_type_ = table_schema_.get_row_store_type(); param.rowkey_column_cnt_ = table_schema_.get_rowkey_column_num() + ObMultiVersionRowkeyHelpper::get_extra_rowkey_col_cnt(); ObSSTableMergeRes::fill_addr_and_data(res.root_desc_, param.root_block_addr_, param.root_block_data_); ObSSTableMergeRes::fill_addr_and_data(res.data_root_desc_, param.data_block_macro_meta_addr_, param.data_block_macro_meta_); param.is_meta_root_ = res.data_root_desc_.is_meta_root_; param.root_row_store_type_ = res.root_row_store_type_; param.data_index_tree_height_ = res.root_desc_.height_; param.index_blocks_cnt_ = res.index_blocks_cnt_; param.data_blocks_cnt_ = res.data_blocks_cnt_; param.micro_block_cnt_ = res.micro_block_cnt_; param.use_old_macro_block_count_ = 0; param.column_cnt_= column_cnt; param.data_checksum_ = 0; param.occupy_size_ = 0; param.original_size_ = 0; param.compressor_type_ = ObCompressorType::NONE_COMPRESSOR; param.encrypt_id_ = 0; param.master_key_id_ = 0; param.nested_size_ = res.nested_size_; param.nested_offset_ = res.nested_offset_; param.ddl_scn_.set_min(); if (table_type == ObITable::MAJOR_SSTABLE) { ASSERT_EQ(OB_SUCCESS, ObSSTableMergeRes::fill_column_checksum_for_empty_major(param.column_cnt_, param.column_checksums_)); } ObLSHandle ls_handle; ObLSService *ls_svr = MTL(ObLSService*); ObLSID lsid(ls_id_); OK(ls_svr->get_ls(lsid, ls_handle, ObLSGetMod::STORAGE_MOD)); if (table_type == ObITable::COLUMN_ORIENTED_SSTABLE) { param.table_key_.column_group_idx_ = column_idx; OK(ObTabletCreateDeleteHelper::create_sstable(param, allocator_, handle)); } else { OK(ObTabletCreateDeleteHelper::create_sstable(param, allocator_, handle)); } ObTableReadInfo read_info; ObSEArray cols_desc; ASSERT_EQ(OB_SUCCESS, table_schema_.get_multi_version_column_descs(cols_desc)); ASSERT_EQ(OB_SUCCESS, read_info.init(allocator_, table_schema_.get_rowkey_column_num() + 1, table_schema_.get_rowkey_column_num(), false, cols_desc, nullptr/*storage_cols_index*/)); } void ObMultiVersionSSTableTest::prepare_data( ObTableHandleV2 &handle, const char **micro_data, const int64_t micro_cnt, const int64_t schema_rowkey_cnt, const ObScnRange &scn_range, const int64_t snapshot_version) { prepare_table_schema(micro_data, schema_rowkey_cnt, scn_range, snapshot_version); reset_writer(snapshot_version); prepare_one_macro(micro_data, micro_cnt); prepare_data_end(handle); } } // end namespace uinttest } // end namspace oceanbase #endif // OB_MULTI_VERSION_SSTABLE_TEST_H_