From c160d9503375a0453a75017301b4173b01f5e261 Mon Sep 17 00:00:00 2001 From: JiahuaChen Date: Mon, 28 Feb 2022 20:16:59 +0800 Subject: [PATCH] Fix pg_key not removed from tenant file pg_map when replaying 22x remove pg slog during upgrade --- src/storage/ob_partition_meta_redo_module.h | 6 +-- src/storage/ob_partition_service.cpp | 46 +-------------------- src/storage/ob_partition_service.h | 4 +- src/storage/ob_server_checkpoint_writer.cpp | 18 ++++++++ src/storage/ob_tenant_file_mgr.cpp | 2 +- src/storage/ob_tenant_file_struct.cpp | 4 ++ 6 files changed, 29 insertions(+), 51 deletions(-) diff --git a/src/storage/ob_partition_meta_redo_module.h b/src/storage/ob_partition_meta_redo_module.h index 111686a0e9..718391b435 100644 --- a/src/storage/ob_partition_meta_redo_module.h +++ b/src/storage/ob_partition_meta_redo_module.h @@ -77,9 +77,9 @@ public: protected: virtual int inner_add_partition( ObIPartitionGroup& partition, const bool need_check_tenant, const bool is_replay, const bool allow_multi_value); - virtual int inner_del_partition_for_replay(const common::ObPartitionKey& pkey, const int64_t file_id); - virtual int inner_del_partition(const common::ObPartitionKey& pkey); - int inner_del_partition_impl(const common::ObPartitionKey& pkey, const int64_t* file_id); + int inner_del_partition_for_replay(const common::ObPartitionKey& pkey, const int64_t file_id); + int inner_del_partition(const common::ObPartitionKey& pkey); + virtual int inner_del_partition_impl(const common::ObPartitionKey& pkey, const int64_t* file_id); virtual int init_partition_group(ObIPartitionGroup& pg, const common::ObPartitionKey& pkey); virtual int post_replay_remove_pg_partition(const ObChangePartitionLogEntry& log_entry) { diff --git a/src/storage/ob_partition_service.cpp b/src/storage/ob_partition_service.cpp index 2ae6b5b3a2..ea27892882 100644 --- a/src/storage/ob_partition_service.cpp +++ b/src/storage/ob_partition_service.cpp @@ -3786,15 +3786,7 @@ int ObPartitionService::delete_rows(const transaction::ObTransDesc& trans_desc, } else if (OB_FAIL(check_query_allowed(pkey, trans_desc, ctx_guard, guard))) { STORAGE_LOG(WARN, "fail to check query allowed", K(ret)); } else { - //@NOTICE:(yuchen.wyc)为了规避外键自引用带来的防御检查不过的问题: - //由于目前delete语句的TableScan操作使用的快照点是语句级,无法看到本语句的最新修改, - //因此,对于外键自引用的级联删除时,同一行可能会被自己和外键级联操作多次删除, - //这个问题目前没有出现语义上的问题,但会导致delete的防御检查报错,详见: - // https://aone.alibaba-inc.com/issue/36022956 - // DML的防御检查读使用的默认快照点是可以读到本语最新修改,因此对于该场景会出现两次读到的数据不一致的问题 - //正确的做法是从外键的删除操作上规避掉多次删除同一行的情况,这要求delete的TableScan能够看到自己的最新修改 - //由于担心这个修改的影响较大,3.2暂时从防御检查上规避掉这个问题, - // 4.0上delete改为读本语句的最新修改来避免同一行的多次删除 + //@NOTICE:(yuchen.wyc) avoid defensive check problem on foreign key self reference if (trans_desc.get_cur_stmt_desc().is_delete_stmt()) { const_cast(dml_param).query_flag_.read_latest_ = 0; } @@ -3819,15 +3811,7 @@ int ObPartitionService::delete_row(const ObTransDesc& trans_desc, const ObDMLBas } else if (OB_FAIL(check_query_allowed(pkey, trans_desc, ctx_guard, guard))) { STORAGE_LOG(WARN, "fail to check query allowed", K(ret)); } else { - //@NOTICE:(yuchen.wyc)为了规避外键自引用带来的防御检查不过的问题: - //由于目前delete语句的TableScan操作使用的快照点是语句级,无法看到本语句的最新修改, - //因此,对于外键自引用的级联删除时,同一行可能会被自己和外键级联操作多次删除, - //这个问题目前没有出现语义上的问题,但会导致delete的防御检查报错,详见: - // https://aone.alibaba-inc.com/issue/36022956 - // DML的防御检查读使用的默认快照点是可以读到本语最新修改,因此对于该场景会出现两次读到的数据不一致的问题 - //正确的做法是从外键的删除操作上规避掉多次删除同一行的情况,这要求delete的TableScan能够看到自己的最新修改 - //由于担心这个修改的影响较大,3.2暂时从防御检查上规避掉这个问题, - // 4.0上delete改为读本语句的最新修改来避免同一行的多次删除 + //@NOTICE:(yuchen.wyc) avoid defensive check problem on foreign key self reference if (trans_desc.get_cur_stmt_desc().is_delete_stmt()) { const_cast(dml_param).query_flag_.read_latest_ = 0; } @@ -4271,32 +4255,6 @@ int ObPartitionService::inner_del_partition_impl(const ObPartitionKey& pkey, con return ret; } -int ObPartitionService::inner_del_partition(const ObPartitionKey& pkey) -{ - int ret = OB_SUCCESS; - if (OB_FAIL(inner_del_partition_impl(pkey, nullptr /*file_id*/))) { - STORAGE_LOG(WARN, "fail to inner del partition", K(ret), K(pkey)); - } - return ret; -} - -int ObPartitionService::inner_del_partition_for_replay(const ObPartitionKey& pkey, const int64_t file_id) -{ - int ret = OB_SUCCESS; - ObIPartitionGroupGuard guard; - if (OB_FAIL(get_partition(pkey, guard))) { - if (OB_PARTITION_NOT_EXIST == ret) { - LOG_INFO("pg not exist in partition image", K(pkey)); - ret = OB_SUCCESS; - } else { - LOG_WARN("fail to get partition", K(ret), K(pkey)); - } - } else if (OB_FAIL(inner_del_partition_impl(pkey, OB_INVALID_DATA_FILE_ID == file_id ? nullptr : &file_id))) { - STORAGE_LOG(WARN, "fail to inner del partition impl", K(ret)); - } - return ret; -} - int ObPartitionService::init_partition_group(ObIPartitionGroup& pg, const common::ObPartitionKey& pkey) { int ret = OB_SUCCESS; diff --git a/src/storage/ob_partition_service.h b/src/storage/ob_partition_service.h index 12efa5ee22..3cd3def28c 100644 --- a/src/storage/ob_partition_service.h +++ b/src/storage/ob_partition_service.h @@ -991,9 +991,7 @@ private: int remove_pg_from_mgr(const ObIPartitionGroup* partition, const bool write_slog); int inner_add_partition(ObIPartitionGroup& partition, const bool need_check_tenant, const bool is_replay, const bool allow_multi_value) override; - int inner_del_partition(const common::ObPartitionKey& pkey) override; - int inner_del_partition_for_replay(const common::ObPartitionKey& pkey, const int64_t file_id) override; - int inner_del_partition_impl(const common::ObPartitionKey& pkey, const int64_t* file_id); + int inner_del_partition_impl(const common::ObPartitionKey& pkey, const int64_t* file_id) override; int create_sstables(const obrpc::ObCreatePartitionArg& arg, const bool in_slog_trans, ObIPartitionGroup& partition_group, ObTablesHandle& handle); int create_sstables(const ObCreatePartitionParam& arg, const bool in_slog_trans, ObIPartitionGroup& partition_group, diff --git a/src/storage/ob_server_checkpoint_writer.cpp b/src/storage/ob_server_checkpoint_writer.cpp index 1fa5b1e873..663817a1a4 100644 --- a/src/storage/ob_server_checkpoint_writer.cpp +++ b/src/storage/ob_server_checkpoint_writer.cpp @@ -171,6 +171,24 @@ int ObServerCheckpointWriter::update_tenant_file_super_block( common::hash::ObHashMap& file_checkpoint_map) { int ret = OB_SUCCESS; + // defensive code for trouble shooting + ObArenaAllocator allocator; + ObArray tenant_file_infos; + if (OB_FAIL(OB_SERVER_FILE_MGR.get_all_tenant_file_infos(allocator, tenant_file_infos))) { + LOG_WARN("fail to get all tenant file infos", K(ret)); + } else { + for (int64_t i = 0; i < tenant_file_infos.count(); ++i) { + const ObTenantFileInfo &file_info = *tenant_file_infos.at(i); + if (ObTenantFileStatus::TENANT_FILE_DELETING != file_info.tenant_file_super_block_.status_) { + ObTenantFileCheckpointEntry entry; + // ignore ret on purpose + if (OB_SUCCESS != file_checkpoint_map.get_refactored(file_info.tenant_key_, entry)) { + LOG_WARN("tenant file ckpt not updated, may be leak!", K(file_info)); + } + } + } + } + for (common::hash::ObHashMap::iterator iter = file_checkpoint_map.begin(); OB_SUCC(ret) && iter != file_checkpoint_map.end(); diff --git a/src/storage/ob_tenant_file_mgr.cpp b/src/storage/ob_tenant_file_mgr.cpp index cbdd23f446..63a9cb1a5d 100644 --- a/src/storage/ob_tenant_file_mgr.cpp +++ b/src/storage/ob_tenant_file_mgr.cpp @@ -691,7 +691,7 @@ int ObTenantFileMgr::remove_pg(const ObTenantFileKey& file_key, const ObPGKey& p } else { if (file_value->file_info_.is_empty_file()) { file_value->file_info_.tenant_file_super_block_.status_ = TENANT_FILE_DELETING; - LOG_INFO("mark file deleting", K(file_key)); + FLOG_INFO("mark file deleting", K(file_key)); } } return ret; diff --git a/src/storage/ob_tenant_file_struct.cpp b/src/storage/ob_tenant_file_struct.cpp index f9acc14525..5888cc30ed 100644 --- a/src/storage/ob_tenant_file_struct.cpp +++ b/src/storage/ob_tenant_file_struct.cpp @@ -175,6 +175,8 @@ int ObTenantFileInfo::add_pg(const ObPGKey& pg_key) if (OB_SUCC(ret)) { if (OB_FAIL(pg_map_.set_refactored(pg_key, true))) { LOG_WARN("fail to add pg to pg map", K(ret), K(pg_key)); + } else { + FLOG_INFO("add pg", K(tenant_key_), K(pg_key)); } } return ret; @@ -190,6 +192,8 @@ int ObTenantFileInfo::remove_pg(const ObPGKey& pg_key) ret = OB_ENTRY_NOT_EXIST; } else if (OB_FAIL(pg_map_.erase_refactored(pg_key))) { LOG_WARN("fail to erase pg from map", K(ret), K(pg_key)); + } else { + FLOG_INFO("remove pg", K(tenant_key_), K(pg_key)); } return ret; } -- GitLab