From cb81c7d64c98a4888c42a93e41131ae48a13e5ba Mon Sep 17 00:00:00 2001 From: obdev Date: Thu, 3 Aug 2023 03:54:03 +0000 Subject: [PATCH] ObTablet Compression --- src/storage/access/ob_table_read_info.cpp | 8 + src/storage/access/ob_table_read_info.h | 2 +- src/storage/blocksstable/ob_sstable.cpp | 2 +- src/storage/ls/ob_ls_tablet_service.cpp | 3 +- src/storage/meta_mem/ob_tablet_pointer.cpp | 7 +- src/storage/tablet/ob_table_store_util.cpp | 8 +- src/storage/tablet/ob_table_store_util.h | 3 +- src/storage/tablet/ob_tablet.cpp | 206 ++++++++++++------ src/storage/tablet/ob_tablet.h | 54 +++-- .../ob_tablet_binding_mds_user_data.cpp | 6 +- .../tablet/ob_tablet_binding_mds_user_data.h | 2 +- src/storage/tablet/ob_tablet_meta.cpp | 4 +- src/storage/tablet/ob_tablet_meta.h | 14 +- src/storage/tablet/ob_tablet_persister.cpp | 50 ++++- src/storage/tablet/ob_tablet_persister.h | 8 +- src/storage/tablet/ob_tablet_table_store.cpp | 3 + 16 files changed, 251 insertions(+), 129 deletions(-) diff --git a/src/storage/access/ob_table_read_info.cpp b/src/storage/access/ob_table_read_info.cpp index c869d44ff8..50db2d143f 100644 --- a/src/storage/access/ob_table_read_info.cpp +++ b/src/storage/access/ob_table_read_info.cpp @@ -538,6 +538,14 @@ int64_t ObTableReadInfo::to_string(char *buf, const int64_t buf_len) const /* * ------------------------------- ObRowkeyReadInfo ------------------------------- */ +ObRowkeyReadInfo::ObRowkeyReadInfo() + : ObReadInfoStruct(true/*rowkey_mode*/) +{ +#if defined(__x86_64__) + static_assert(sizeof(ObRowkeyReadInfo) == 368, "The size of ObRowkeyReadInfo will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); +#endif +} + int ObRowkeyReadInfo::init( common::ObIAllocator &allocator, const int64_t schema_column_count, diff --git a/src/storage/access/ob_table_read_info.h b/src/storage/access/ob_table_read_info.h index 34151f0e1d..d298c931d3 100644 --- a/src/storage/access/ob_table_read_info.h +++ b/src/storage/access/ob_table_read_info.h @@ -292,7 +292,7 @@ private: class ObRowkeyReadInfo final : public ObReadInfoStruct { public: - ObRowkeyReadInfo() : ObReadInfoStruct(true/*rowkey_mode*/) {} + ObRowkeyReadInfo(); virtual ~ObRowkeyReadInfo() {} int init( diff --git a/src/storage/blocksstable/ob_sstable.cpp b/src/storage/blocksstable/ob_sstable.cpp index cd9e949876..23a1f31879 100644 --- a/src/storage/blocksstable/ob_sstable.cpp +++ b/src/storage/blocksstable/ob_sstable.cpp @@ -73,7 +73,7 @@ ObSSTable::ObSSTable() meta_(nullptr) { #if defined(__x86_64__) - static_assert(sizeof(ObSSTable) <= 1280, "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) <= 160, "The size of ObSSTable will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); #endif } diff --git a/src/storage/ls/ob_ls_tablet_service.cpp b/src/storage/ls/ob_ls_tablet_service.cpp index c5b018642d..ed1df12f3d 100755 --- a/src/storage/ls/ob_ls_tablet_service.cpp +++ b/src/storage/ls/ob_ls_tablet_service.cpp @@ -1841,8 +1841,7 @@ int ObLSTabletService::replay_create_tablet( if (tablet->is_empty_shell()) { pool_type = ObTabletPoolType::TP_NORMAL; } else { - const int64_t try_cache_size = sizeof(ObTablet) - + tablet->rowkey_read_info_->get_deep_copy_size(); + const int64_t try_cache_size = tablet->get_try_cache_size(); if (try_cache_size > ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { pool_type = ObTabletPoolType::TP_LARGE; } else { diff --git a/src/storage/meta_mem/ob_tablet_pointer.cpp b/src/storage/meta_mem/ob_tablet_pointer.cpp index 2a546988e5..ec9787cd6d 100644 --- a/src/storage/meta_mem/ob_tablet_pointer.cpp +++ b/src/storage/meta_mem/ob_tablet_pointer.cpp @@ -47,6 +47,9 @@ ObTabletPointer::ObTabletPointer() ddl_kv_mgr_lock_(), old_version_chain_(nullptr) { +#if defined(__x86_64__) + static_assert(sizeof(ObTabletPointer) == 576, "The size of ObTabletPointer will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); +#endif } ObTabletPointer::ObTabletPointer( @@ -132,11 +135,9 @@ int ObTabletPointer::dump_meta_obj(ObMetaObjGuard &guard, void *&free_ const ObLSID ls_id = obj_.ptr_->tablet_meta_.ls_id_; const ObTabletID tablet_id = obj_.ptr_->tablet_meta_.tablet_id_; const int64_t wash_score = obj_.ptr_->get_wash_score(); - const int64_t rowkey_info_size = nullptr == obj_.ptr_->rowkey_read_info_ - ? 0 : obj_.ptr_->rowkey_read_info_->get_deep_copy_size(); guard.get_obj(meta_obj); ObTablet *tmp_obj = obj_.ptr_; - if (OB_NOT_NULL(meta_obj.ptr_) && sizeof(ObTablet) + rowkey_info_size <= ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { + if (OB_NOT_NULL(meta_obj.ptr_) && obj_.ptr_->get_try_cache_size() <= ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { char *buf = reinterpret_cast(meta_obj.ptr_); const int64_t buf_len = ObMetaObjBufferHelper::get_buffer_header(buf).buf_len_; const int64_t cur_buf_len = ObMetaObjBufferHelper::get_buffer_header(reinterpret_cast(tmp_obj)).buf_len_; diff --git a/src/storage/tablet/ob_table_store_util.cpp b/src/storage/tablet/ob_table_store_util.cpp index 92847f37b5..17f33e4249 100755 --- a/src/storage/tablet/ob_table_store_util.cpp +++ b/src/storage/tablet/ob_table_store_util.cpp @@ -644,7 +644,7 @@ int ObMemtableArray::assign(ObMemtableArray &dst_array) const { int ret = OB_SUCCESS; dst_array.count_ = count_; - for (int64_t i = 0; i < MEMTABLE_ARRAY_SIZE; ++i) { + for (int64_t i = 0; i < MAX_MEMSTORE_CNT; ++i) { dst_array.memtable_array_[i] = memtable_array_[i]; } return ret; @@ -674,7 +674,7 @@ int ObMemtableArray::build( } else if (FALSE_IT(memtable = reinterpret_cast(table))) { } else if (memtable->is_empty()) { FLOG_INFO("empty memtable discarded", KPC(memtable)); - } else if (OB_UNLIKELY(count_ == MEMTABLE_ARRAY_SIZE)) { + } else if (OB_UNLIKELY(count_ == MAX_MEMSTORE_CNT)) { ret = OB_ARRAY_OUT_OF_RANGE; LOG_WARN("too many elements for memtable array", K(ret)); } else { @@ -708,7 +708,7 @@ int ObMemtableArray::rebuild(const common::ObIArray &table_array) } else if (table->get_end_scn() < endscn) { } else if (exist_memtable_with_end_scn(table, endscn)) { FLOG_INFO("duplicated memtable with same end_scn discarded", KPC(table), K(endscn)); - } else if (OB_UNLIKELY(count_ == MEMTABLE_ARRAY_SIZE)) { + } else if (OB_UNLIKELY(count_ == MAX_MEMSTORE_CNT)) { ret = OB_SIZE_OVERFLOW; LOG_WARN("too many elements for memtable array", K(ret)); } else { @@ -743,7 +743,7 @@ int ObMemtableArray::rebuild( } else if (table->get_end_scn() <= clog_checkpoint_scn) { FLOG_INFO("memtable end scn no greater than clog checkpoint scn, should be discarded", K(ret), "end_scn", table->get_end_scn(), K(clog_checkpoint_scn)); - } else if (OB_UNLIKELY(count_ == MEMTABLE_ARRAY_SIZE)) { + } else if (OB_UNLIKELY(count_ == MAX_MEMSTORE_CNT)) { ret = OB_SIZE_OVERFLOW; LOG_WARN("too many elements for memtable array", K(ret)); } else { diff --git a/src/storage/tablet/ob_table_store_util.h b/src/storage/tablet/ob_table_store_util.h index 3fb1930475..a7ab741e27 100755 --- a/src/storage/tablet/ob_table_store_util.h +++ b/src/storage/tablet/ob_table_store_util.h @@ -93,7 +93,6 @@ private: class ObMemtableArray { public: - static constexpr int64_t MEMTABLE_ARRAY_SIZE =16; ObMemtableArray() : memtable_array_(), count_(0) {} OB_INLINE memtable::ObIMemtable *operator[](const int64_t pos) const { @@ -116,7 +115,7 @@ public: int64_t to_string(char *buf, const int64_t buf_len) const; private: bool exist_memtable_with_end_scn(const ObITable *table, const share::SCN &end_scn); - memtable::ObIMemtable *memtable_array_[MEMTABLE_ARRAY_SIZE]; + memtable::ObIMemtable *memtable_array_[MAX_MEMSTORE_CNT]; int64_t count_; private: DISALLOW_COPY_AND_ASSIGN(ObMemtableArray); diff --git a/src/storage/tablet/ob_tablet.cpp b/src/storage/tablet/ob_tablet.cpp index b316aa5ec1..1fe4507807 100755 --- a/src/storage/tablet/ob_tablet.cpp +++ b/src/storage/tablet/ob_tablet.cpp @@ -115,6 +115,7 @@ ObTablet::ObTablet() : version_(TABLET_VERSION_V2), length_(0), wash_score_(INT64_MIN), + mds_data_(), ref_cnt_(0), next_tablet_guard_(), tablet_meta_(), @@ -122,25 +123,24 @@ ObTablet::ObTablet() table_store_addr_(), storage_schema_addr_(), memtable_count_(0), - ddl_kvs_(), + ddl_kvs_(nullptr), ddl_kv_count_(0), pointer_hdl_(), next_full_tablet_guard_(), - allocator_(nullptr), tablet_addr_(), + allocator_(nullptr), + memtables_lock_(), memtable_mgr_(nullptr), log_handler_(nullptr), - mds_data_(), - memtables_lock_(), - mds_cache_lock_(), - tablet_status_cache_(), - ddl_data_cache_(), next_tablet_(nullptr), hold_ref_cnt_(false), - is_inited_(false) + is_inited_(false), + mds_cache_lock_(), + tablet_status_cache_(), + ddl_data_cache_() { #if defined(__x86_64__) - static_assert(sizeof(ObTablet) + sizeof(ObRowkeyReadInfo) <= 6000, "The size of ObTablet will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); + static_assert(sizeof(ObTablet) + sizeof(ObRowkeyReadInfo) == 1632, "The size of ObTablet will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); #endif MEMSET(memtables_, 0x0, sizeof(memtables_)); } @@ -197,6 +197,8 @@ int ObTablet::init( { int ret = OB_SUCCESS; const int64_t default_max_sync_medium_scn = 0; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -226,9 +228,11 @@ int ObTablet::init( K(create_scn), K(snapshot_version), K(compat_mode), K(store_flag)); } else if (is_ls_inner_tablet() && OB_FAIL(inner_create_memtable())) { LOG_WARN("failed to create first memtable", K(ret), K(tablet_id)); - } else if (OB_FAIL(pull_memtables())) { + } else if (OB_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { LOG_WARN("fail to pull memtable", K(ret)); } else { + ddl_kvs_ = ddl_kvs_addr; + ddl_kv_count_ = ddl_kv_count; ALLOC_AND_INIT(allocator, table_store_addr_, (*this), sstable); ALLOC_AND_INIT(allocator, storage_schema_addr_, table_schema, compat_mode, true/*skip_column_info*/, ObStorageSchema::STORAGE_SCHEMA_VERSION_V2); @@ -273,6 +277,8 @@ int ObTablet::init( const ObTabletMdsData &old_mds_data = old_tablet.mds_data_; const bool update_in_major_type_merge = param.need_report_ && param.sstable_->is_major_sstable(); int64_t finish_medium_scn = 0; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -305,9 +311,11 @@ int ObTablet::init( LOG_WARN("failed to fetch old table store", K(ret), K(old_tablet)); } 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 (OB_FAIL(pull_memtables())) { + } else if (OB_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { LOG_WARN("failed to pull memtable", K(ret)); } else { + ddl_kvs_ = ddl_kvs_addr; + ddl_kv_count_ = ddl_kv_count; ALLOC_AND_INIT(allocator, table_store_addr_, (*this), param, (*old_table_store)); } @@ -373,6 +381,8 @@ int ObTablet::init( const ObTabletTableStore *old_table_store = nullptr; const ObStorageSchema *old_storage_schema = nullptr; int64_t finish_medium_scn = 0; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -390,7 +400,7 @@ int ObTablet::init( LOG_WARN("failed to load storage schema", K(ret), K(old_tablet)); } else if (CLICK_FAIL(tablet_meta_.init(old_tablet.tablet_meta_, flush_scn))) { LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet), K(flush_scn)); - } else if (CLICK_FAIL(pull_memtables())) { + } else if (CLICK_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { LOG_WARN("fail to pull memtable", K(ret)); } else if (CLICK_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)); @@ -401,6 +411,8 @@ int ObTablet::init( } else if (CLICK_FAIL(mds_data_.init(allocator, mds_table_data, base_data, finish_medium_scn))) { LOG_WARN("failed to init mds data", K(ret), K(finish_medium_scn)); } else { + ddl_kvs_ = ddl_kvs_addr; + ddl_kv_count_ = ddl_kv_count; ALLOC_AND_INIT(allocator, storage_schema_addr_, *old_storage_schema); } @@ -435,6 +447,9 @@ int ObTablet::init( const share::ObLSID &ls_id = param.ls_id_; const common::ObTabletID &tablet_id = param.tablet_id_; allocator_ = &allocator; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; + if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("init twice", K(ret), K(is_inited_)); @@ -479,9 +494,11 @@ int ObTablet::init( } else { if (OB_FAIL(mds_data_.init(*allocator_, param.mds_data_))) { LOG_WARN("failed to assign mds data", K(ret), K(param)); - } else if (OB_FAIL(pull_memtables())) { + } else if (OB_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { LOG_WARN("fail to pull memtable", K(ret)); } else { + ddl_kvs_ = ddl_kvs_addr; + ddl_kv_count_ = ddl_kv_count; ALLOC_AND_INIT(allocator, table_store_addr_, (*this), nullptr/*ObTableHandleV2*/); ALLOC_AND_INIT(allocator, storage_schema_addr_, param.storage_schema_); } @@ -521,6 +538,8 @@ int ObTablet::init( const ObStorageSchema *old_storage_schema = nullptr; const ObTabletMdsData &old_mds_data = old_tablet.mds_data_; allocator_ = &allocator; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -544,13 +563,15 @@ int ObTablet::init( old_tablet.get_multi_version_start(), old_tablet.tablet_meta_.max_sync_storage_schema_version_))) { LOG_WARN("fail to init tablet_meta", K(ret), K(old_tablet.tablet_meta_)); - } else if (OB_FAIL(pull_memtables())) { + } else if (OB_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { 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_.get_ptr()->init(*allocator_, *this, tables, *old_table_store))) { LOG_WARN("fail to init table store", K(ret), K(old_tablet), K(tables)); } else { + ddl_kvs_ = ddl_kvs_addr; + ddl_kv_count_ = ddl_kv_count; ALLOC_AND_INIT(allocator, storage_schema_addr_, *old_storage_schema); } @@ -597,6 +618,8 @@ int ObTablet::init( const ObStorageSchema *old_storage_schema = nullptr; const ObStorageSchema *storage_schema = nullptr; int64_t finish_medium_scn = 0; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; @@ -623,7 +646,7 @@ int ObTablet::init( // use max schema to make sure sstable and schema match ))) { LOG_WARN("failed to init tablet meta", K(ret), K(old_tablet), K(param)); - } else if (OB_FAIL(pull_memtables())){ + } else if (OB_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))){ 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)); @@ -655,6 +678,8 @@ int ObTablet::init( } else if (OB_FAIL(inner_inc_macro_ref_cnt())) { LOG_WARN("failed to increase macro ref cnt", K(ret)); } else { + ddl_kvs_ = ddl_kvs_addr; + ddl_kv_count_ = ddl_kv_count; if (old_tablet.get_tablet_meta().has_next_tablet_) { set_next_tablet_guard(old_tablet.next_tablet_guard_); } @@ -856,8 +881,13 @@ int ObTablet::init_with_update_medium_info( || OB_ISNULL(log_handler_)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("tablet pointer handle is invalid", K(ret), K_(pointer_hdl), K_(pointer_hdl), K_(memtable_mgr), K_(log_handler)); - } else if (OB_FAIL(assign_memtables(old_tablet))) { + } else if (OB_FAIL(assign_memtables(old_tablet.memtables_, old_tablet.memtable_count_))) { LOG_WARN("fail to assign memtables", K(ret)); + } else if (OB_ISNULL(ddl_kvs_ = static_cast(allocator.alloc(sizeof(ObITable*) * DDL_KV_ARRAY_SIZE)))) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate memory for ddl_kvs_", K(ret), KP(ddl_kvs_)); + } else if (OB_FAIL(assign_ddl_kvs(old_tablet.ddl_kvs_, old_tablet.ddl_kv_count_))) { + LOG_WARN("fail to assign ddl kvs", K(ret), KP(old_tablet.ddl_kvs_), K(old_tablet.ddl_kv_count_)); } else if (OB_FAIL(old_tablet.fetch_table_store(table_store_wrapper))) { LOG_WARN("fail to fetch table store", K(ret), K(old_tablet)); } else if (OB_FAIL(table_store_wrapper.get_member(old_table_store))) { @@ -1175,6 +1205,8 @@ int ObTablet::load_deserialize_v1( ObTabletTxMultiSourceDataUnit tx_data; ObTabletBindingInfo ddl_data; ObMediumCompactionInfoList info_list; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; if (OB_FAIL(ObTabletObjLoadHelper::alloc_and_new(allocator, table_store_addr_.ptr_))) { LOG_WARN("fail to allocate and new table store", K(ret)); @@ -1207,9 +1239,11 @@ int ObTablet::load_deserialize_v1( if (FAILEDx(build_read_info(allocator))) { LOG_WARN("failed to build read info", K(ret)); - } else if (OB_FAIL(pull_memtables())) { + } else if (OB_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { LOG_WARN("fail to pull memtable", K(ret), K(len), K(new_pos)); } else { + ddl_kvs_ = ddl_kvs_addr; + ddl_kv_count_ = ddl_kv_count; set_mem_addr(); mds_data_.set_mem_addr(); version_ = TABLET_VERSION_V2; @@ -1323,6 +1357,8 @@ int ObTablet::load_deserialize_v2( const bool prepare_memtable) { int ret = OB_SUCCESS; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; if (new_pos - pos < length_ && OB_FAIL(tablet_meta_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize tablet meta", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(table_store_addr_.addr_.deserialize(buf, len, new_pos))) { @@ -1336,9 +1372,11 @@ int ObTablet::load_deserialize_v2( LOG_WARN("fail to deserialize rowkey read info", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(mds_data_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize mds data", K(ret), K(len), K(new_pos)); - } else if (prepare_memtable && OB_FAIL(pull_memtables())) { + } else if (prepare_memtable && OB_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { LOG_WARN("fail to pull memtable", K(ret), K(len), K(new_pos)); } else { + ddl_kvs_ = ddl_kvs_addr; + ddl_kv_count_ = ddl_kv_count; if (!table_store_addr_.addr_.is_none()) { IO_AND_DESERIALIZE(allocator, table_store_addr_.addr_, table_store_addr_.ptr_, *this); if (FAILEDx(table_store_addr_.ptr_->batch_cache_sstable_meta(allocator, INT64_MAX))) {// cache all @@ -1363,6 +1401,8 @@ int ObTablet::deserialize( int64_t remain = buf_header.buf_len_ - sizeof(ObTablet); int64_t start_pos = sizeof(ObTablet); ObArenaAllocator allocator; + ObITable **ddl_kvs_addr = nullptr; + int64_t ddl_kv_count = 0; if (OB_UNLIKELY(is_inited_)) { ret = OB_INIT_TWICE; LOG_WARN("cannot deserialize inited tablet meta", K(ret), K_(is_inited)); @@ -1385,7 +1425,7 @@ int ObTablet::deserialize( LOG_WARN("buffer's length is not enough", K(ret), K(length_), K(len - new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(tablet_meta_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize tablet meta", K(ret), K(len), K(new_pos)); - } else if (OB_FAIL(pull_memtables())) { + } else if (OB_FAIL(pull_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { LOG_WARN("fail to pull memtable", K(ret), K(len), K(new_pos)); } else if (new_pos - pos < length_ && OB_FAIL(table_store_addr_.addr_.deserialize(buf, len, new_pos))) { LOG_WARN("failed to deserialize table read info addr", K(ret), K(len), K(new_pos)); @@ -1411,6 +1451,22 @@ int ObTablet::deserialize( remain -= rowkey_read_info_->get_deep_copy_size(); start_pos += rowkey_read_info_->get_deep_copy_size(); } + } else { + if (OB_NOT_NULL(ddl_kvs_addr)) { + const int64_t ddl_kv_size = sizeof(ObITable*) * DDL_KV_ARRAY_SIZE; + if (remain < ddl_kv_size) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to deep copy ddl kv to tablet", K(ret), K(remain), K(ddl_kv_size), K(ddl_kv_count)); + } else { + ddl_kvs_ = reinterpret_cast(tablet_buf + start_pos); + if (OB_FAIL(assign_ddl_kvs(ddl_kvs_addr, ddl_kv_count))) { + LOG_WARN("fail to assign ddl_kvs", K(ret), KP(ddl_kvs_addr), K(ddl_kv_count), KP(tablet_buf), K(start_pos)); + } else { + start_pos += ddl_kv_size; + remain -= ddl_kv_size; + } + } + } } if (OB_SUCC(ret)) { @@ -2485,7 +2541,7 @@ int ObTablet::get_all_sstables(ObTableStoreIterator &iter) const int ObTablet::get_all_tables(ObTableStoreIterator &iter) const { int ret = OB_SUCCESS; - ObSEArray memtables; + ObSEArray memtables; if (IS_NOT_INIT) { ret = OB_NOT_INIT; LOG_WARN("not inited", K(ret), K_(is_inited)); @@ -2565,7 +2621,7 @@ int ObTablet::get_sstables_size(int64_t &used_size, const bool ignore_shared_blo int ObTablet::get_memtables(common::ObIArray &memtables, const bool need_active) const { - TCRLockGuard guard(memtables_lock_); + common::SpinRLockGuard guard(memtables_lock_); return inner_get_memtables(memtables, need_active); } @@ -3233,7 +3289,7 @@ int ObTablet::create_memtable( const share::ObLSID &ls_id = tablet_meta_.ls_id_; const common::ObTabletID &tablet_id = tablet_meta_.tablet_id_; ObTimeGuard time_guard("ObTablet::create_memtable", 10 * 1000); - TCWLockGuard guard(memtables_lock_); + common::SpinWLockGuard guard(memtables_lock_); time_guard.click("lock"); const SCN new_clog_checkpoint_scn = clog_checkpoint_scn.is_min() ? tablet_meta_.clog_checkpoint_scn_ : clog_checkpoint_scn; @@ -3292,7 +3348,7 @@ int ObTablet::inner_create_memtable( if (OB_UNLIKELY(!clog_checkpoint_scn.is_valid_and_not_min()) || OB_UNLIKELY(schema_version < 0)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid args", K(ret), K(clog_checkpoint_scn), K(schema_version)); - } else if (OB_UNLIKELY(ObTablet::MEMTABLE_ARRAY_SIZE == memtable_count_)) { + } else if (OB_UNLIKELY(MAX_MEMSTORE_CNT == memtable_count_)) { ret = OB_MINOR_FREEZE_NOT_ALLOW; if (TC_REACH_TIME_INTERVAL(1000 * 1000)) { LOG_WARN("The memtable array in the tablet reaches the upper limit, and no more memtable can " @@ -4808,7 +4864,7 @@ int64_t ObTablet::to_string(char *buf, const int64_t buf_len) const BUF_PRINTF("memtables"); J_COLON(); J_ARRAY_START(); - for (int64_t i = 0; i < MEMTABLE_ARRAY_SIZE; ++i) { + for (int64_t i = 0; i < MAX_MEMSTORE_CNT; ++i) { if (i > 0) { J_COMMA(); } @@ -4846,12 +4902,12 @@ int ObTablet::refresh_memtable_and_update_seq(const uint64_t seq) return ret; } -int ObTablet::pull_memtables() +int ObTablet::pull_memtables(ObArenaAllocator &allocator, ObITable **&ddl_kvs_addr, int64_t &ddl_kv_count) { int ret = OB_SUCCESS; if (OB_FAIL(pull_memtables_without_ddl())) { LOG_WARN("fail to pull memtables without ddl", K(ret)); - } else if (OB_FAIL(pull_ddl_memtables())) { + } else if (OB_FAIL(pull_ddl_memtables(allocator, ddl_kvs_addr, ddl_kv_count))) { LOG_WARN("failed to pull ddl memtables", K(ret)); } return ret; @@ -4973,27 +5029,6 @@ int ObTablet::update_memtables() return ret; } -int ObTablet::build_memtable() -{ - int ret = OB_SUCCESS; - if (OB_ISNULL(memtable_mgr_)) { - ret = OB_ERR_NULL_VALUE; - LOG_ERROR("failed to get all memtables from memtable_mgr", K(ret)); - } else if (OB_SUCC(ret)) { // init sstables when first creating tablet - ObSEArray memtable_handles; - if (memtable_mgr_->has_memtable()) { - if (OB_FAIL(memtable_mgr_->get_all_memtables(memtable_handles))) { - LOG_WARN("failed to get all memtables from memtable_mgr", K(ret)); - } else if (OB_FAIL(build_memtable(memtable_handles))) { - LOG_WARN("failed to pull memtable array", K(ret)); - } else { - LOG_INFO("success to pull memtables when first creating tablet", K(ret), K(*this)); - } - } - } - return ret; -} - int ObTablet::inner_get_mds_table(mds::MdsTableHandle &mds_table, bool not_exist_create) const { int ret = OB_SUCCESS; @@ -5013,7 +5048,7 @@ int ObTablet::build_memtable(common::ObIArray &handle_array, co { int ret = OB_SUCCESS; - if (OB_UNLIKELY(start_pos < 0 || start_pos >= handle_array.count() || handle_array.count() > MEMTABLE_ARRAY_SIZE)) { + if (OB_UNLIKELY(start_pos < 0 || start_pos >= handle_array.count() || handle_array.count() > MAX_MEMSTORE_CNT)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid arguments", K(ret), K(start_pos), K(handle_array)); } @@ -5204,7 +5239,7 @@ int ObTablet::add_memtable(memtable::ObMemtable* const table) if (OB_ISNULL(table)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("get invalid argument", K(ret), KPC(table)); - } else if (MEMTABLE_ARRAY_SIZE == memtable_count_) { + } else if (MAX_MEMSTORE_CNT == memtable_count_) { ret = OB_SIZE_OVERFLOW; LOG_DEBUG("memtable is full", K(ret), KPC(table), K(memtable_count_)); } else { @@ -5234,32 +5269,48 @@ bool ObTablet::exist_memtable_with_end_scn(const ObITable *table, const SCN &end return is_exist; } -int ObTablet::assign_memtables(const ObTablet &other_tablet) +int ObTablet::assign_memtables(memtable::ObIMemtable * const * memtables, const int64_t memtable_count) { int ret = OB_SUCCESS; - if (OB_ISNULL(other_tablet.memtables_) - || OB_ISNULL(other_tablet.ddl_kvs_) - || OB_UNLIKELY(other_tablet.memtable_count_ < 0 || 0 != memtable_count_) - || OB_UNLIKELY(other_tablet.ddl_kv_count_ < 0 || 0 != ddl_kv_count_)) { + + if (OB_ISNULL(memtables) || OB_UNLIKELY(memtable_count < 0 || 0 != memtable_count_)) { ret = OB_INVALID_ARGUMENT; - LOG_WARN("invalid other tablet memtable array", K(ret), K_(memtable_count), K_(ddl_kv_count), K(other_tablet)); + LOG_WARN("invalid memtable argument", K(ret), KP(memtables), K(memtable_count)); } else { - for (int64_t i = 0; OB_SUCC(ret) && i < other_tablet.memtable_count_; ++i) { - memtable::ObIMemtable * memtable = other_tablet.memtables_[i]; + MEMSET(memtables_, 0, sizeof(memtable::ObIMemtable*) * MAX_MEMSTORE_CNT); + // deep copy memtables to tablet.memtables_ and inc ref + for (int64_t i = 0; OB_SUCC(ret) && i < memtable_count; ++i) { + memtable::ObIMemtable * memtable = memtables[i]; if (OB_ISNULL(memtable)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected null memtable ptr", K(ret), K(i), K(other_tablet)); + LOG_WARN("unexpected null memtable ptr", K(ret), K(i), KP(memtables)); } else { memtables_[i] = memtable; memtable->inc_ref(); ++memtable_count_; } } - for (int64_t i = 0; OB_SUCC(ret) && i < other_tablet.ddl_kv_count_; ++i) { - ObITable *ddl_kv = other_tablet.ddl_kvs_[i]; + } + + return ret; +} + +int ObTablet::assign_ddl_kvs(ObITable * const *ddl_kvs, const int64_t ddl_kv_count) +{ + int ret = OB_SUCCESS; + + if (OB_UNLIKELY(OB_NOT_NULL(ddl_kvs) && ddl_kv_count == 0) || + OB_UNLIKELY(OB_ISNULL(ddl_kvs) && ddl_kv_count > 0) || + OB_UNLIKELY(ddl_kv_count < 0 || 0 != ddl_kv_count_)) { + ret = OB_INVALID_ARGUMENT; + LOG_WARN("invalid ddl_kv argument", K(ret), KP(ddl_kvs), K(ddl_kv_count)); + } else { + // deep copy ddl_kvs to tablet.ddl_kvs_ and inc ref + for (int64_t i = 0; OB_SUCC(ret) && i < ddl_kv_count; ++i) { + ObITable *ddl_kv = ddl_kvs[i]; if (OB_ISNULL(ddl_kv)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected ddl kv", K(ret), K(i), K(other_tablet)); + LOG_WARN("unexpected ddl_kvs", K(ret), K(i), KP(ddl_kvs)); } else { ddl_kvs_[i] = ddl_kv; ddl_kv->inc_ref(); @@ -5267,13 +5318,14 @@ int ObTablet::assign_memtables(const ObTablet &other_tablet) } } } + return ret; } void ObTablet::reset_memtable() { ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*); - for(int i = 0; i < MEMTABLE_ARRAY_SIZE; ++i) { + for(int i = 0; i < MAX_MEMSTORE_CNT; ++i) { if (OB_NOT_NULL(memtables_[i])) { const ObITable::TableType table_type = memtables_[i]->get_key().table_type_; const int64_t ref_cnt = memtables_[i]->dec_ref(); @@ -5335,16 +5387,16 @@ int ObTablet::get_mds_table_handle_(mds::MdsTableHandle &handle, return ret; } -int ObTablet::pull_ddl_memtables() +int ObTablet::pull_ddl_memtables(ObArenaAllocator &allocator, ObITable **&ddl_kvs_addr, int64_t &ddl_kv_count) { int ret = OB_SUCCESS; ObArray ddl_memtables; ObDDLKvMgrHandle kv_mgr_handle; bool has_ddl_kv = false; ObTablesHandleArray ddl_kvs_handle; - if (OB_UNLIKELY(0 != ddl_kv_count_)) { + if (OB_UNLIKELY(0 != ddl_kv_count)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("unexpected ddl kv count when pull ddl memtables", K(ret), K_(ddl_kv_count), KPC(this)); + LOG_WARN("unexpected ddl kv count when pull ddl memtables", K(ret), K(ddl_kv_count), KPC(this)); } else if (OB_FAIL(get_ddl_kv_mgr(kv_mgr_handle))) { if (OB_ENTRY_NOT_EXIST != ret) { LOG_WARN("get ddl kv mgr failed", K(ret), KPC(this)); @@ -5355,6 +5407,14 @@ int ObTablet::pull_ddl_memtables() } else if (OB_FAIL(kv_mgr_handle.get_obj()->get_ddl_kvs_for_query(*this, ddl_kvs_handle))) { LOG_WARN("failed to get all ddl freeze kvs", K(ret)); } else { + ObITable *temp_ddl_kvs; + if (ddl_kvs_handle.get_count() > 0) { + ddl_kvs_addr = static_cast(allocator.alloc(sizeof(ObITable*) * DDL_KV_ARRAY_SIZE)); + if (OB_ISNULL(ddl_kvs_addr)) { + ret = OB_ALLOCATE_MEMORY_FAILED; + LOG_WARN("failed to allocate memory for ddl_kvs_addr", K(ret), K(ddl_kvs_handle.get_count())); + } + } SCN ddl_checkpoint_scn = get_tablet_meta().ddl_checkpoint_scn_; for (int64_t i = 0; OB_SUCC(ret) && i < ddl_kvs_handle.get_count(); ++i) { ObDDLKV *ddl_kv = static_cast(ddl_kvs_handle.get_table(i)); @@ -5366,17 +5426,25 @@ int ObTablet::pull_ddl_memtables() } else if (ddl_kv->get_freeze_scn() > ddl_checkpoint_scn) { if (OB_FAIL(ddl_kv->prepare_sstable(false/*need_check*/))) { LOG_WARN("prepare sstable failed", K(ret)); - } else if (OB_UNLIKELY(ddl_kv_count_ >= DDL_KV_ARRAY_SIZE)) { + } else if (OB_UNLIKELY(ddl_kv_count >= DDL_KV_ARRAY_SIZE)) { ret = OB_ERR_UNEXPECTED; - LOG_WARN("ddl kv count overflow", K(ret), K(i), K_(ddl_kv_count), K(ddl_kvs_handle)); + LOG_WARN("ddl kv count overflow", K(ret), K(i), K(ddl_kv_count), K(ddl_kvs_handle)); } else { - ddl_kvs_[ddl_kv_count_] = ddl_kv; + ddl_kvs_addr[ddl_kv_count] = ddl_kv; ddl_kv->inc_ref(); - ++ddl_kv_count_; + ++ddl_kv_count; } } } } + if (ddl_kv_count == 0) { + // In the above for loop, ddl_kvs_addr's assignment can be skipped (e.g. ddl_kv->is_closed()). + ddl_kvs_addr = nullptr; + } + if (OB_SUCC(ret) && OB_ISNULL(ddl_kvs_addr) && ddl_kv_count > 0) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("unexpected value on ddl_kvs_addr and ddl_kv_count", KP(ddl_kvs_addr), K(ddl_kv_count)); + } return ret; } diff --git a/src/storage/tablet/ob_tablet.h b/src/storage/tablet/ob_tablet.h index 5747bc2567..5aaf72154d 100755 --- a/src/storage/tablet/ob_tablet.h +++ b/src/storage/tablet/ob_tablet.h @@ -515,6 +515,7 @@ private: static void dec_addr_ref_cnt(const ObMetaDiskAddr &addr); static int inc_linked_block_ref_cnt(const ObMetaDiskAddr &head_addr, bool &inc_success); static void dec_linked_block_ref_cnt(const ObMetaDiskAddr &head_addr); + int64_t get_try_cache_size() const; private: int inner_check_valid(const bool ignore_ha_status = false) const; @@ -689,10 +690,9 @@ private: // memtable operation - int pull_memtables(); + int pull_memtables(ObArenaAllocator &allocator, ObITable **&ddl_kvs_addr, int64_t &ddl_kv_count); int pull_memtables_without_ddl(); int update_memtables(); - int build_memtable(); int build_memtable(common::ObIArray &handle_array, const int64_t start_pos = 0); int rebuild_memtable(common::ObIArray &handle_array); int rebuild_memtable( @@ -700,13 +700,13 @@ private: common::ObIArray &handle_array); int add_memtable(memtable::ObMemtable* const table); bool exist_memtable_with_end_scn(const ObITable *table, const share::SCN &end_scn); - int assign_memtables(const ObTablet &other_tablet); + int assign_memtables(memtable::ObIMemtable * const *memtables, const int64_t memtable_count); + int assign_ddl_kvs(ObITable * const *ddl_kvs, const int64_t ddl_kv_count); void reset_memtable(); - int pull_ddl_memtables(); + int pull_ddl_memtables(ObArenaAllocator &allocator, ObITable **&ddl_kvs_addr, int64_t &ddl_kv_count); void reset_ddl_memtables(); int wait_release_memtables_(); private: - static const int64_t MEMTABLE_ARRAY_SIZE = 16; // ObTabletDDLKvMgr::MAX_DDL_KV_CNT_IN_STORAGE // Array size is too large, need to shrink it if possible static const int64_t DDL_KV_ARRAY_SIZE = 64; @@ -715,49 +715,55 @@ private: private: int32_t version_; int32_t length_; - volatile int64_t wash_score_ CACHE_ALIGNED; - volatile int64_t ref_cnt_ CACHE_ALIGNED; - ObTabletHandle next_tablet_guard_; - ObTabletMeta tablet_meta_; + volatile int64_t wash_score_; + ObTabletMdsData mds_data_; // size: 440B, alignment: 8B + volatile int64_t ref_cnt_; + ObTabletHandle next_tablet_guard_; // size: 56B, alignment: 8B + ObTabletMeta tablet_meta_; // size: 248, alignment: 8B ObRowkeyReadInfo *rowkey_read_info_; // in memory or disk - ObTabletComplexAddr table_store_addr_; + ObTabletComplexAddr table_store_addr_; // size: 48B, alignment: 8B // always in disk - ObTabletComplexAddr storage_schema_addr_; - // won't persist - memtable::ObIMemtable *memtables_[MEMTABLE_ARRAY_SIZE]; + ObTabletComplexAddr storage_schema_addr_; // size: 48B, alignment: 8B int64_t memtable_count_; - ObITable *ddl_kvs_[DDL_KV_ARRAY_SIZE]; + ObITable **ddl_kvs_; int64_t ddl_kv_count_; - ObTabletPointerHandle pointer_hdl_; - ObTabletHandle next_full_tablet_guard_; - ObArenaAllocator *allocator_; - ObMetaDiskAddr tablet_addr_; + ObTabletPointerHandle pointer_hdl_; // size: 24B, alignment: 8B + ObTabletHandle next_full_tablet_guard_; // size: 56B, alignment: 8B + ObMetaDiskAddr tablet_addr_; // size: 40B, alignment: 8B // NOTICE: these two pointers: memtable_mgr_ and log_handler_, // are considered as cache for tablet. // we keep it on tablet because we cannot get them in ObTablet::deserialize // through ObTabletPointerHandle. // may be some day will fix this issue, then the pointers have no need to exist. + // won't persist + memtable::ObIMemtable *memtables_[MAX_MEMSTORE_CNT]; + ObArenaAllocator *allocator_; + mutable common::SpinRWLock memtables_lock_; // size: 12B, alignment: 4B ObIMemtableMgr *memtable_mgr_; logservice::ObLogHandler *log_handler_; - ObTabletMdsData mds_data_; - - mutable common::TCRWLock memtables_lock_; // protect memtable read and update - mutable common::SpinRWLock mds_cache_lock_; - ObTabletStatusCache tablet_status_cache_; - ObDDLInfoCache ddl_data_cache_; //ATTENTION : Add a new variable need consider ObMigrationTabletParam // and tablet meta init interface for migration. // yuque : ObTablet *next_tablet_; // used in old_version_chain and tablet_gc_queue + // whether hold ref cnt // when destroying tablet, only if hold_ref_cnt_ is true do we decrease meta blocks' ref cnt // we need to set it to true after increasing meta blocks' ref cnt or deserializing tablet bool hold_ref_cnt_; bool is_inited_; + mutable common::SpinRWLock mds_cache_lock_; // size: 12B, alignment: 4B + ObTabletStatusCache tablet_status_cache_; // size: 24B, alignment: 8B + ObDDLInfoCache ddl_data_cache_; // size: 24B, alignment: 8B }; +inline int64_t ObTablet::get_try_cache_size() const +{ + return sizeof(ObTablet) + (OB_ISNULL(rowkey_read_info_) ? 0 : rowkey_read_info_->get_deep_copy_size()) + + (ddl_kv_count_ > 0 ? sizeof(ObITable *) * DDL_KV_ARRAY_SIZE : 0); +} + inline bool ObTablet::is_ls_inner_tablet() const { return tablet_meta_.tablet_id_.is_ls_inner_tablet(); diff --git a/src/storage/tablet/ob_tablet_binding_mds_user_data.cpp b/src/storage/tablet/ob_tablet_binding_mds_user_data.cpp index f405c80da4..cbed04c895 100644 --- a/src/storage/tablet/ob_tablet_binding_mds_user_data.cpp +++ b/src/storage/tablet/ob_tablet_binding_mds_user_data.cpp @@ -20,13 +20,13 @@ namespace oceanbase namespace storage { ObTabletBindingMdsUserData::ObTabletBindingMdsUserData() - : redefined_(false), - snapshot_version_(0), + : snapshot_version_(0), schema_version_(0), data_tablet_id_(), hidden_tablet_id_(), lob_meta_tablet_id_(), - lob_piece_tablet_id_() + lob_piece_tablet_id_(), + redefined_(false) { } diff --git a/src/storage/tablet/ob_tablet_binding_mds_user_data.h b/src/storage/tablet/ob_tablet_binding_mds_user_data.h index 77c1292032..56abe32184 100644 --- a/src/storage/tablet/ob_tablet_binding_mds_user_data.h +++ b/src/storage/tablet/ob_tablet_binding_mds_user_data.h @@ -61,13 +61,13 @@ public: K_(is_old_mds)); public: - bool redefined_; int64_t snapshot_version_; // if redefined it is max readable snapshot, else it is min readable snapshot. int64_t schema_version_; common::ObTabletID data_tablet_id_; common::ObTabletID hidden_tablet_id_; common::ObTabletID lob_meta_tablet_id_; common::ObTabletID lob_piece_tablet_id_; + bool redefined_; bool is_old_mds_; }; } // namespace storage diff --git a/src/storage/tablet/ob_tablet_meta.cpp b/src/storage/tablet/ob_tablet_meta.cpp index 786ed37b4a..18bdf6e256 100644 --- a/src/storage/tablet/ob_tablet_meta.cpp +++ b/src/storage/tablet/ob_tablet_meta.cpp @@ -40,14 +40,12 @@ ObTabletMeta::ObTabletMeta() tablet_id_(), data_tablet_id_(), ref_tablet_id_(), - has_next_tablet_(false), create_scn_(ObTabletMeta::INVALID_CREATE_SCN), start_scn_(), clog_checkpoint_scn_(), ddl_checkpoint_scn_(SCN::min_scn()), snapshot_version_(OB_INVALID_TIMESTAMP), multi_version_start_(OB_INVALID_TIMESTAMP), - compat_mode_(lib::Worker::CompatMode::INVALID), ha_status_(), report_status_(), table_store_flag_(), @@ -61,6 +59,8 @@ ObTabletMeta::ObTabletMeta() mds_checkpoint_scn_(), transfer_info_(), create_schema_version_(0), + compat_mode_(lib::Worker::CompatMode::INVALID), + has_next_tablet_(false), is_inited_(false) { } diff --git a/src/storage/tablet/ob_tablet_meta.h b/src/storage/tablet/ob_tablet_meta.h index 1c9d289086..7ef32c7d0d 100644 --- a/src/storage/tablet/ob_tablet_meta.h +++ b/src/storage/tablet/ob_tablet_meta.h @@ -148,21 +148,19 @@ public: public: int32_t version_; int32_t length_; - share::ObLSID ls_id_; - common::ObTabletID tablet_id_; + share::ObLSID ls_id_; // alignment: 8B, size: 8B + common::ObTabletID tablet_id_; // alignment: 8B, size: 8B common::ObTabletID data_tablet_id_; common::ObTabletID ref_tablet_id_; - bool has_next_tablet_; - share::SCN create_scn_; + share::SCN create_scn_; // alignment: 8B, size: 8B share::SCN start_scn_; share::SCN clog_checkpoint_scn_; // may less than last_minor->end_log_ts share::SCN ddl_checkpoint_scn_; // snapshot_version of last minor int64_t snapshot_version_; int64_t multi_version_start_; - lib::Worker::CompatMode compat_mode_; ObTabletHAStatus ha_status_; - ObTabletReportStatus report_status_; + ObTabletReportStatus report_status_; // alignment: 8B, size: 32B ObTabletTableStoreFlag table_store_flag_; share::SCN ddl_start_scn_; int64_t ddl_snapshot_version_; @@ -176,11 +174,13 @@ public: int64_t max_serialized_medium_scn_; // abandon after 4.2 share::SCN ddl_commit_scn_; share::SCN mds_checkpoint_scn_; - ObTabletTransferInfo transfer_info_; + ObTabletTransferInfo transfer_info_; // alignment: 8B, size: 32B int64_t create_schema_version_; // add after 4.2, record schema_version when first create tablet. NEED COMPAT //ATTENTION : Add a new variable need consider ObMigrationTabletParam // and tablet meta init interface for migration. // yuque : + lib::Worker::CompatMode compat_mode_; // alignment: 1B, size: 4B + bool has_next_tablet_; private: int inner_check_( diff --git a/src/storage/tablet/ob_tablet_persister.cpp b/src/storage/tablet/ob_tablet_persister.cpp index d1817d8399..f291195d09 100644 --- a/src/storage/tablet/ob_tablet_persister.cpp +++ b/src/storage/tablet/ob_tablet_persister.cpp @@ -40,8 +40,12 @@ ObTabletTransformArg::ObTabletTransformArg() medium_info_list_addr_(), auto_inc_seq_addr_(), tablet_status_cache_(), - aux_tablet_info_cache_() + aux_tablet_info_cache_(), + ddl_kvs_(nullptr), + ddl_kv_count_(0), + memtable_count_(0) { + MEMSET(memtables_, 0x0, sizeof(memtables_)); } ObTabletTransformArg::~ObTabletTransformArg() @@ -165,6 +169,10 @@ int ObTabletPersister::convert_tablet_to_mem_arg( arg.extra_medium_info_ = tablet.mds_data_.extra_medium_info_; arg.medium_info_list_addr_ = tablet.mds_data_.medium_info_list_.addr_; arg.auto_inc_seq_addr_ = tablet.mds_data_.auto_inc_seq_.addr_; + arg.ddl_kvs_ = tablet.ddl_kvs_; + arg.ddl_kv_count_ = tablet.ddl_kv_count_; + MEMCPY(arg.memtables_, tablet.memtables_, sizeof(memtable::ObIMemtable*) * MAX_MEMSTORE_CNT); + arg.memtable_count_ = tablet.memtable_count_; } return ret; } @@ -217,6 +225,12 @@ int ObTabletPersister::convert_tablet_to_disk_arg( allocator, fetch_auto_inc_seq, auto_inc_seq, write_infos, tablet_meta_write_ctxs))) { LOG_WARN("fail to fetch auto inc seq wrapper and write info", K(ret)); } else if (FALSE_IT(arg.auto_inc_seq_ptr_ = auto_inc_seq.get_member())) { + } else if (FALSE_IT(arg.ddl_kvs_ = tablet.ddl_kvs_)) { + } else if (FALSE_IT(arg.ddl_kv_count_ = tablet.ddl_kv_count_)) { + } else if (FALSE_IT(arg.memtable_count_ = tablet.memtable_count_)) { + } else if (OB_ISNULL(MEMCPY(arg.memtables_, tablet.memtables_, sizeof(arg.memtables_)))) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("fail to memcpy memtables", K(ret), KP(arg.memtables_), KP(tablet.memtables_)); } else if (CLICK_FAIL(load_member_and_write_info( allocator, load_storage_schema, storage_schema, write_infos))) { LOG_WARN("fail to load storage schema and write info", K(ret)); @@ -233,9 +247,7 @@ int ObTabletPersister::convert_tablet_to_disk_arg( } else if (CLICK_FAIL(load_medium_info_list_and_write(allocator, medium_info_list_addr, arg.medium_info_list_addr_, tablet_meta_write_ctxs))) { LOG_WARN("fail to load medium info list and write", K(ret), K(medium_info_list_addr)); } else { - const int64_t try_cache_size = sizeof(ObTablet) - + tablet.rowkey_read_info_->get_deep_copy_size() - + table_store.get_member()->get_deep_copy_size(); + const int64_t try_cache_size = tablet.get_try_cache_size() + table_store.get_member()->get_deep_copy_size(); if (try_cache_size > ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { type = ObTabletPoolType::TP_LARGE; } @@ -270,7 +282,7 @@ int ObTabletPersister::persist_and_fill_tablet( } else if (CLICK_FAIL(convert_tablet_to_disk_arg( allocator, old_tablet, tablet_meta_write_ctxs, sstable_meta_write_ctxs, type, auto_inc_seq, arg))) { LOG_WARN("fail to conver tablet to disk arg", K(ret), K(old_tablet)); - } else if (sizeof(old_tablet) + old_tablet.rowkey_read_info_->get_deep_copy_size() > ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { + } else if (old_tablet.get_try_cache_size() > ObTenantMetaMemMgr::NORMAL_TABLET_POOL_SIZE) { try_smaller_pool = false; } @@ -376,7 +388,8 @@ int ObTabletPersister::persist_4k_tablet(common::ObArenaAllocator &allocator, Ob int ObTabletPersister::convert_arg_to_tablet( const ObTabletTransformArg &arg, - ObTablet &tablet) + ObTablet &tablet, + ObArenaAllocator &allocator) { int ret = OB_SUCCESS; if (OB_UNLIKELY(!arg.is_valid())) { @@ -384,12 +397,12 @@ int ObTabletPersister::convert_arg_to_tablet( LOG_WARN("invalid arguments", K(ret), K(arg)); } else if (OB_FAIL(tablet.tablet_meta_.assign(arg.tablet_meta_))) { LOG_WARN("fail to assign tablet meta", K(ret), K(arg.tablet_meta_)); - } else if (OB_FAIL(tablet.pull_memtables())) { - LOG_WARN("fail to build memtables", K(ret), K(tablet)); } else if (OB_FAIL(tablet.mds_data_.tablet_status_cache_.assign(arg.tablet_status_cache_))) { LOG_WARN("fail to assign tablet status cache", K(ret), K(arg.aux_tablet_info_cache_)); } else if (OB_FAIL(tablet.mds_data_.aux_tablet_info_cache_.assign(arg.aux_tablet_info_cache_))) { LOG_WARN("fail to assign aux tablet info cache", K(ret), K(arg.aux_tablet_info_cache_)); + } else if (OB_FAIL(tablet.assign_memtables(arg.memtables_, arg.memtable_count_))) { + LOG_WARN("fail to assign memtables", K(ret), KP(arg.memtables_), K(arg.memtable_count_)); } else { tablet.table_store_addr_.addr_ = arg.table_store_addr_; tablet.storage_schema_addr_.addr_ = arg.storage_schema_addr_; @@ -414,10 +427,11 @@ int ObTabletPersister::transform( TIMEGUARD_INIT(STORAGE, 10_ms, 5_s); int ret = OB_SUCCESS; ObTablet *tiny_tablet = reinterpret_cast(buf); + ObArenaAllocator allocator("TmpPullMemTbl"); if (len <= sizeof(ObTablet) || OB_ISNULL(buf)) { ret = OB_INVALID_ARGUMENT; LOG_WARN("invalid arguments", K(ret), KP(buf), K(len)); - } else if (OB_FAIL(convert_arg_to_tablet(arg, *tiny_tablet))) { + } else if (OB_FAIL(convert_arg_to_tablet(arg, *tiny_tablet, allocator))) { LOG_WARN("fail to convert arg to tablet", K(ret), K(arg.tablet_meta_)); } else { // buf related @@ -446,6 +460,24 @@ int ObTabletPersister::transform( LOG_DEBUG("TINY TABLET: tablet + rowkey_read_info", KP(buf), K(start_pos), K(remain)); } + // ddl_kvs_ related + if (OB_SUCC(ret) && (arg.ddl_kv_count_ > 0)) { + const int ddl_kvs_size = sizeof(ObITable*) * ObTablet::DDL_KV_ARRAY_SIZE; + if (OB_UNLIKELY(remain < ddl_kvs_size)) { + ret = OB_ERR_UNEXPECTED; + LOG_WARN("tablet memory buffer not enough for ddl kvs", K(ret), K(remain), K(ddl_kvs_size)); + } else { + tiny_tablet->ddl_kvs_ = reinterpret_cast(buf + start_pos); + if (OB_FAIL(tiny_tablet->assign_ddl_kvs(arg.ddl_kvs_, arg.ddl_kv_count_))) { + LOG_WARN("fail to assign ddl_kvs_", K(ret), KP(arg.ddl_kvs_), K(arg.ddl_kv_count_), KP(buf), K(start_pos)); + } else { + remain -= ddl_kvs_size; + start_pos += ddl_kvs_size; + } + } + LOG_DEBUG("TINY TABLET: tablet + ddl_kvs", KP(buf), K(start_pos), K(remain), K(tiny_tablet->ddl_kv_count_)); + } + // table store related ObTabletTableStore *table_store = nullptr; if (OB_SUCC(ret)) { diff --git a/src/storage/tablet/ob_tablet_persister.h b/src/storage/tablet/ob_tablet_persister.h index 2a8560e77c..52bfa13614 100644 --- a/src/storage/tablet/ob_tablet_persister.h +++ b/src/storage/tablet/ob_tablet_persister.h @@ -62,6 +62,11 @@ public: ObMetaDiskAddr auto_inc_seq_addr_; ObTabletCreateDeleteMdsUserData tablet_status_cache_; ObTabletBindingMdsUserData aux_tablet_info_cache_; + ObITable **ddl_kvs_; + int64_t ddl_kv_count_; + // memtable::ObIMemtable **memtables_; + memtable::ObIMemtable *memtables_[MAX_MEMSTORE_CNT]; + int64_t memtable_count_; // If you want to add new member, make sure all member is assigned in 2 convert function. // ObTabletPersister::convert_tablet_to_mem_arg // ObTabletPersister::convert_tablet_to_disk_arg @@ -113,7 +118,8 @@ private: ObTabletTransformArg &arg); static int convert_arg_to_tablet( const ObTabletTransformArg &arg, - ObTablet &tablet); + ObTablet &tablet, + ObArenaAllocator &allocator); static int transform( const ObTabletTransformArg &arg, char *buf, diff --git a/src/storage/tablet/ob_tablet_table_store.cpp b/src/storage/tablet/ob_tablet_table_store.cpp index 9fef83847a..b5a0449ef3 100755 --- a/src/storage/tablet/ob_tablet_table_store.cpp +++ b/src/storage/tablet/ob_tablet_table_store.cpp @@ -45,6 +45,9 @@ ObTabletTableStore::ObTabletTableStore() is_ready_for_read_(false), is_inited_(false) { +#if defined(__x86_64__) + static_assert(sizeof(ObTabletTableStore) == 320, "The size of ObTabletTableStore will affect the meta memory manager, and the necessity of adding new fields needs to be considered."); +#endif } ObTabletTableStore::~ObTabletTableStore()