Tablet will not hold memtable ref when ls offline

This commit is contained in:
godyangfight
2023-10-12 02:10:01 +00:00
committed by ob-robot
parent 7d90783c71
commit fc85a979ab
4 changed files with 100 additions and 52 deletions

View File

@ -172,11 +172,11 @@ int ObLSTabletService::offline()
if (IS_NOT_INIT) {
ret = OB_NOT_INIT;
LOG_WARN("not inited", K(ret), K_(is_inited));
} else if (OB_FAIL(offline_build_tablet_without_memtable_())) {
LOG_WARN("failed to offline build tablet without memtable", K(ret));
} else if (OB_FAIL(offline_destroy_memtable_and_mds_table_())) {
LOG_WARN("failed to offline destroy memtable and mds table", K(ret));
} else {
DestroyMemtableAndMemberAndMdsTableOperator clean_mem_op(this);
if (OB_FAIL(tablet_id_set_.foreach(clean_mem_op))) {
LOG_WARN("fail to clean memtables", K(ret), "cur_tablet_id", clean_mem_op.cur_tablet_id_);
}
mds_table_mgr_.offline();
}
return ret;
@ -1435,13 +1435,15 @@ int ObLSTabletService::build_new_tablet_from_mds_table(
return ret;
}
int ObLSTabletService::update_tablet_release_memtable(
int ObLSTabletService::update_tablet_release_memtable_for_offline(
const common::ObTabletID &tablet_id,
const SCN scn)
{
int ret = OB_SUCCESS;
const ObTabletMapKey key(ls_->get_ls_id(), tablet_id);
const ObLSID ls_id(ls_->get_ls_id());
const ObTabletMapKey key(ls_id, tablet_id);
ObTabletHandle tablet_handle;
ObTablet *tablet = nullptr;
ObTimeGuard time_guard("ObLSTabletService::update_tablet_release_memtable", 1_s);
ObBucketHashWLockGuard lock_guard(bucket_lock_, tablet_id.hash());
time_guard.click("Lock");
@ -1453,37 +1455,49 @@ int ObLSTabletService::update_tablet_release_memtable(
LOG_WARN("invalid arguments", K(ret), K(tablet_id), K(scn));
} else if (OB_FAIL(ObTabletCreateDeleteHelper::get_tablet(key, tablet_handle))) {
LOG_WARN("fail to direct get tablet", K(ret), K(key));
} else if (OB_ISNULL(tablet = tablet_handle.get_obj())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("tablet should not be NULL", K(ret), K(key));
} else if (tablet->is_empty_shell()) {
//do nothing
} else {
time_guard.click("get_tablet");
ObTablet *tablet = tablet_handle.get_obj();
ObTabletHandle new_tablet_handle;
ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*);
const bool need_persist = nullptr != tablet_handle.get_allocator();
ObMetaDiskAddr disk_addr;
if (!need_persist) {
ObITable *table = nullptr;
ObTableStoreIterator iter;
const bool is_from_buf_pool = nullptr == tablet_handle.get_obj()->get_allocator();
if (is_from_buf_pool) {
ObTenantMetaMemMgr *t3m = MTL(ObTenantMetaMemMgr*);
ObTabletHandle new_tablet_handle;
if (OB_FAIL(ObTabletPersister::copy_from_old_tablet(*tablet, new_tablet_handle))) {
LOG_WARN("fail to copy from old tablet", K(ret), KPC(tablet));
} else if (FALSE_IT(time_guard.click("CpTablet"))) {
} else if (OB_FAIL(new_tablet_handle.get_obj()->rebuild_memtables(scn))) {
LOG_WARN("fail to rebuild memtables", K(ret), K(scn), K(new_tablet_handle));
} else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, new_tablet_handle))) {
LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle), K(new_tablet_handle));
} else {
time_guard.click("CpTablet");
time_guard.click("CASwap");
LOG_INFO("succeeded to copy tablet to release memtable", K(ret), K(key), K(tablet_handle), K(new_tablet_handle));
}
} else if (OB_FAIL(ObTabletPersister::persist_and_transform_tablet(*tablet, new_tablet_handle))) {
LOG_WARN("fail to persist and transform tablet", K(ret), KPC(tablet), K(new_tablet_handle));
} else if (FALSE_IT(time_guard.click("Persist"))) {
} else if (FALSE_IT(disk_addr = new_tablet_handle.get_obj()->tablet_addr_)) {
} else if (OB_FAIL(ObTabletSlogHelper::write_update_tablet_slog(key.ls_id_, tablet_id, disk_addr))) {
LOG_WARN("failed to write update tablet slog", K(ret), K(key), K(disk_addr));
} else if (OB_UNLIKELY(!tablet->get_tablet_addr().is_memory())) {
ret = OB_NOT_SUPPORTED;
LOG_ERROR("This tablet is full tablet, but its addr isn't memory", K(ret), KPC(tablet));
} else if (OB_FAIL(tablet->get_all_sstables(iter))) {
LOG_WARN("fail to get all sstable", K(ret), K(iter));
} else if (1 == iter.count() && OB_FAIL(iter.get_next(table))) {
LOG_WARN("fail to get next table", K(ret), K(iter));
} else if (OB_UNLIKELY(iter.count() > 1)
|| (OB_NOT_NULL(table) && (!table->is_sstable()
|| static_cast<ObSSTable *>(table)->get_data_macro_block_count() != 0))) {
ret = OB_NOT_SUPPORTED;
LOG_ERROR("This tablet is full tablet, but all of its sstables isn't only one empty major",
K(ret), K(iter), KPC(table));
} else if (OB_FAIL(tablet_handle.get_obj()->wait_release_memtables())) {
LOG_ERROR("failed to release memtables", K(ret), K(tablet_id));
} else if (OB_FAIL(inner_remove_tablet(ls_id, tablet_id))) {
LOG_ERROR("failed to do remove tablet", K(ret), K(ls_id), K(tablet_id));
} else {
time_guard.click("WrSlog");
}
if (FAILEDx(new_tablet_handle.get_obj()->rebuild_memtables(scn))) {
LOG_WARN("fail to rebuild memtables", K(ret), K(scn), K(new_tablet_handle));
} else if (OB_FAIL(t3m->compare_and_swap_tablet(key, tablet_handle, new_tablet_handle))) {
LOG_ERROR("failed to compare and swap tablet", K(ret), K(key), K(tablet_handle), K(new_tablet_handle));
ob_usleep(1000 * 1000);
ob_abort();
} else {
time_guard.click("CASwap");
LOG_INFO("succeeded to build new tablet", K(ret), K(key), K(disk_addr), K(tablet_handle));
time_guard.click("RmTablet");
}
}
return ret;
@ -6266,5 +6280,37 @@ int ObLSTabletService::check_parts_tx_state_in_transfer_for_4377_(transaction::O
return ret;
}
int ObLSTabletService::offline_build_tablet_without_memtable_()
{
int ret = OB_SUCCESS;
ObArray<ObTabletID> tablet_id_array;
const bool except_ls_inner_tablet = false;
const SCN scn(SCN::max_scn());
if (OB_FAIL(get_all_tablet_ids(except_ls_inner_tablet, tablet_id_array))) {
LOG_WARN("failed to get all tablet ids", K(ret));
} else {
for (int64_t i = 0; OB_SUCC(ret) && i < tablet_id_array.count(); ++i) {
const ObTabletID &tablet_id = tablet_id_array.at(i);
if (OB_FAIL(update_tablet_release_memtable_for_offline(tablet_id, scn))) {
LOG_WARN("failed to update tablet release memtable", K(ret), K(tablet_id));
}
}
}
return ret;
}
int ObLSTabletService::offline_destroy_memtable_and_mds_table_()
{
int ret = OB_SUCCESS;
DestroyMemtableAndMemberAndMdsTableOperator clean_mem_op(this);
if (OB_FAIL(tablet_id_set_.foreach(clean_mem_op))) {
LOG_WARN("fail to clean memtables", K(ret), "cur_tablet_id", clean_mem_op.cur_tablet_id_);
}
return ret;
}
} // namespace storage
} // namespace oceanbase