diff --git a/mittest/mtlenv/storage/test_tablet_create_delete_helper.cpp b/mittest/mtlenv/storage/test_tablet_create_delete_helper.cpp index 294de388fa..1d8f2d1d9c 100644 --- a/mittest/mtlenv/storage/test_tablet_create_delete_helper.cpp +++ b/mittest/mtlenv/storage/test_tablet_create_delete_helper.cpp @@ -1143,6 +1143,8 @@ TEST_F(TestTabletCreateDeleteHelper, abort_create_tablets_no_redo) trans_flags.for_replay_ = false; trans_flags.tx_id_ = 1; trans_flags.scn_ = share::SCN::invalid_scn(); + trans_flags.redo_submitted_ = true; + trans_flags.redo_synced_ = true; // mock, no prepare(as if prepare create failed) // and log ts is invalid @@ -1847,7 +1849,7 @@ TEST_F(TestTabletCreateDeleteHelper, roll_back_prepare_remove_tablet) ObMulSourceDataNotifyArg trans_flags; trans_flags.for_replay_ = false; trans_flags.tx_id_ = 1; - const share::SCN val = share::SCN::minus(share::SCN::max_scn(), 200); + const share::SCN val = share::SCN::minus(share::SCN::max_scn(), 300); trans_flags.scn_ = val; ObLSHandle ls_handle; @@ -1906,6 +1908,10 @@ TEST_F(TestTabletCreateDeleteHelper, roll_back_prepare_remove_tablet) ASSERT_EQ(OB_SUCCESS, ret); tablet_handle.get_obj()->get_tx_data(tx_data); ASSERT_EQ(ObTabletStatus::NORMAL, tx_data.tablet_status_); + + trans_flags.scn_ = share::SCN::plus(trans_flags.scn_, 1); + ret = ls_tablet_service.on_abort_remove_tablets(arg, trans_flags); + ASSERT_NE(OB_SUCCESS, ret); } } @@ -2369,7 +2375,7 @@ TEST_F(TestTabletCreateDeleteHelper, partial_prepare_remove_and_full_abort_remov int ret = OB_SUCCESS; ObMulSourceDataNotifyArg trans_flags; - trans_flags.for_replay_ = false; + trans_flags.for_replay_ = true; trans_flags.tx_id_ = 1; trans_flags.scn_ = share::SCN::minus(share::SCN::max_scn(), 100); @@ -2427,7 +2433,7 @@ TEST_F(TestTabletCreateDeleteHelper, partial_prepare_remove_and_full_abort_remov ASSERT_EQ(OB_SUCCESS, ret); trans_flags.tx_id_ = 2; - trans_flags.scn_ = share::SCN::invalid_scn(); + trans_flags.scn_ = share::SCN::minus(share::SCN::max_scn(), 95); // mock partial prepare remove ret = ls_tablet_service.on_prepare_remove_tablets(partial_arg, trans_flags); ASSERT_EQ(OB_SUCCESS, ret); @@ -2447,7 +2453,6 @@ TEST_F(TestTabletCreateDeleteHelper, partial_prepare_remove_and_full_abort_remov ASSERT_EQ(ObTabletStatus::NORMAL, tx_data.tablet_status_); ASSERT_TRUE(tablet_handle.get_obj()->is_data_tablet()); - key.tablet_id_ = 2; ret = ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle); ASSERT_EQ(OB_SUCCESS, ret); @@ -2913,7 +2918,7 @@ TEST_F(TestTabletCreateDeleteHelper, tablet_not_exist_commit) int main(int argc, char **argv) { system("rm -f test_tablet_create_delete_helper.log*"); - OB_LOGGER.set_file_name("test_tablet_create_delete_helper.log", true); + OB_LOGGER.set_file_name("test_tablet_create_delete_helper.log"); OB_LOGGER.set_log_level("INFO"); testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); diff --git a/src/storage/memtable/ob_memtable.cpp b/src/storage/memtable/ob_memtable.cpp index 78db89e85a..45232a2f39 100644 --- a/src/storage/memtable/ob_memtable.cpp +++ b/src/storage/memtable/ob_memtable.cpp @@ -267,6 +267,17 @@ void ObMemtable::destroy() snapshot_version_.set_max(); } +int ObMemtable::safe_to_destroy(bool &is_safe) +{ + int ret = OB_SUCCESS; + + is_safe = (0 == get_ref() && + 0 == get_write_ref() && + 0 == get_unsubmitted_cnt() && + 0 == get_unsynced_cnt()); + + return ret; +} //////////////////////////////////////////////////////////////////////////////////////////////////// // Public Functions: set/lock diff --git a/src/storage/memtable/ob_memtable.h b/src/storage/memtable/ob_memtable.h index cde32f2c71..6dbb5e1ed0 100644 --- a/src/storage/memtable/ob_memtable.h +++ b/src/storage/memtable/ob_memtable.h @@ -174,6 +174,7 @@ public: const int64_t schema_version, const uint32_t freeze_clock); virtual void destroy(); + virtual int safe_to_destroy(bool &is_safe); OB_INLINE void reset() { destroy(); } public: diff --git a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp index b65b70ea9e..412323f1ca 100644 --- a/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp +++ b/src/storage/meta_mem/ob_tenant_meta_mem_mgr.cpp @@ -288,10 +288,13 @@ int ObTenantMetaMemMgr::gc_tables_in_queue(bool &all_table_cleaned) } else { TableGCItem *item = static_cast(ptr); ObITable *table = item->table_; + bool is_safe = false; if (OB_ISNULL(table)) { ret = OB_ERR_UNEXPECTED; LOG_WARN("the table in gc item is nullptr", K(ret), KP(item)); - } else { + } else if (OB_FAIL(table->safe_to_destroy(is_safe))) { + LOG_WARN("fail to check safe_to_destroy", K(ret), KPC(table)); + } else if (is_safe) { ObITable::TableType table_type = item->table_type_; int64_t index = static_cast(table_type); if (OB_UNLIKELY(!ObITable::is_table_type_valid(table_type) || nullptr == pool_arr_[index])) { @@ -301,9 +304,11 @@ int ObTenantMetaMemMgr::gc_tables_in_queue(bool &all_table_cleaned) pool_arr_[index]->free_obj(static_cast(table)); table_cnt_arr[index]++; } + } else if (TC_REACH_TIME_INTERVAL(1000 * 1000)) { + LOG_INFO("the table is unsafe to destroy", KPC(table)); } - if (OB_SUCC(ret)) { + if (OB_SUCC(ret) && is_safe) { left_recycle_cnt--; ob_free(item); item = nullptr; diff --git a/src/storage/ob_i_table.cpp b/src/storage/ob_i_table.cpp index 5cb4feb1eb..32584e2de1 100644 --- a/src/storage/ob_i_table.cpp +++ b/src/storage/ob_i_table.cpp @@ -119,6 +119,12 @@ void ObITable::reset() key_.reset(); } +int ObITable::safe_to_destroy(bool &is_safe) +{ + is_safe = true; + return OB_SUCCESS; +} + int ObITable::exist( ObStoreCtx &ctx, const uint64_t table_id, diff --git a/src/storage/ob_i_table.h b/src/storage/ob_i_table.h index 1b121ab0cd..c6f4555112 100644 --- a/src/storage/ob_i_table.h +++ b/src/storage/ob_i_table.h @@ -160,6 +160,7 @@ public: int init(const TableKey &table_key); void reset(); + virtual int safe_to_destroy(bool &is_safe); OB_INLINE const TableKey &get_key() const { return key_; } void set_scn_range(share::ObScnRange scn_range) { key_.scn_range_ = scn_range; } void set_table_type(ObITable::TableType table_type) { key_.table_type_ = table_type; } diff --git a/unittest/storage/test_sstable_log_ts_range_cut.cpp b/unittest/storage/test_sstable_log_ts_range_cut.cpp index d8aa05e9d7..168365b4bf 100644 --- a/unittest/storage/test_sstable_log_ts_range_cut.cpp +++ b/unittest/storage/test_sstable_log_ts_range_cut.cpp @@ -118,6 +118,7 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_no_cross_and_continue) ASSERT_EQ(OB_SUCCESS, ret); ret = tablet_table_store.cut_ha_sstable_scn_range_(minor_sstables, tables_handle); ASSERT_EQ(OB_SUCCESS, ret); + tables_handle.meta_mem_mgr_ = nullptr; ASSERT_EQ(0, tables_handle.get_table(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); ASSERT_EQ(100, tables_handle.get_table(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); @@ -160,6 +161,7 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_is_not_continue) ASSERT_EQ(OB_SUCCESS, ret); ret = tablet_table_store.cut_ha_sstable_scn_range_(minor_sstables, tables_handle); ASSERT_EQ(OB_ERR_UNEXPECTED, ret); + tables_handle.meta_mem_mgr_ = nullptr; } @@ -193,6 +195,7 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_contain) ASSERT_EQ(OB_SUCCESS, ret); ret = tablet_table_store.cut_ha_sstable_scn_range_(minor_sstables, tables_handle); ASSERT_EQ(OB_SUCCESS, ret); + tables_handle.meta_mem_mgr_ = nullptr; ASSERT_EQ(0, tables_handle.get_table(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); ASSERT_EQ(100, tables_handle.get_table(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); @@ -235,6 +238,7 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_has_overlap) ASSERT_EQ(OB_SUCCESS, ret); ret = tablet_table_store.cut_ha_sstable_scn_range_(minor_sstables, tables_handle); ASSERT_EQ(OB_SUCCESS, ret); + tables_handle.meta_mem_mgr_ = nullptr; ASSERT_EQ(0, tables_handle.get_table(0)->key_.scn_range_.start_scn_.get_val_for_inner_table_field()); ASSERT_EQ(100, tables_handle.get_table(0)->key_.scn_range_.end_scn_.get_val_for_inner_table_field()); @@ -252,6 +256,8 @@ TEST_F(TestSSTableScnRangeCut, sstable_scn_range_has_overlap) int main(int argc, char** argv) { + system("rm -f test_sstable_log_ts_range_cut.log*"); + OB_LOGGER.set_file_name("test_sstable_log_ts_range_cut.log"); OB_LOGGER.set_log_level("INFO"); testing::InitGoogleTest(&argc, argv); oceanbase::lib::set_memory_limit(40L << 30);