From 6570b1eb6c9aa7a974201ccd37360747806b0bd1 Mon Sep 17 00:00:00 2001 From: shadowao Date: Wed, 17 Apr 2024 07:39:02 +0000 Subject: [PATCH] [CP] fix memtable reference leaks due to not deconstruct lob cursor --- deps/oblib/src/lib/json_type/ob_json_bin.cpp | 1 + .../engine/expr/ob_expr_json_func_helper.cpp | 34 +++++++++++++++++++ .../engine/expr/ob_expr_json_func_helper.h | 1 + src/storage/lob/ob_lob_manager.cpp | 13 +++++++ 4 files changed, 49 insertions(+) diff --git a/deps/oblib/src/lib/json_type/ob_json_bin.cpp b/deps/oblib/src/lib/json_type/ob_json_bin.cpp index 78160042d4..0f0a116383 100644 --- a/deps/oblib/src/lib/json_type/ob_json_bin.cpp +++ b/deps/oblib/src/lib/json_type/ob_json_bin.cpp @@ -5331,6 +5331,7 @@ ObJsonBinCtx::~ObJsonBinCtx() { if (OB_NOT_NULL(update_ctx_) && is_update_ctx_alloc_) { update_ctx_->~ObJsonBinUpdateCtx(); + update_ctx_ = nullptr; } } diff --git a/src/sql/engine/expr/ob_expr_json_func_helper.cpp b/src/sql/engine/expr/ob_expr_json_func_helper.cpp index 472a395c94..8e9bc80bdc 100644 --- a/src/sql/engine/expr/ob_expr_json_func_helper.cpp +++ b/src/sql/engine/expr/ob_expr_json_func_helper.cpp @@ -331,6 +331,9 @@ int ObJsonExprHelper::get_json_for_partial_update( } else { j_base = delta_lob.get_json_bin(); } + if (OB_FAIL(ret)) { + delta_lob.reset(); + } } else if (! locator.is_persist_lob() || locator.is_inrow()) { ret = OB_ERR_UNEXPECTED; LOG_WARN("persis lob or no-delta inrow lob locator not support", KR(ret), K(locator)); @@ -364,6 +367,17 @@ int ObJsonExprHelper::get_json_for_partial_update( ret = OB_ERR_UNEXPECTED; LOG_WARN("get j_base is null", KR(ret), K(locator)); } + + if (OB_FAIL(ret)) { + if (OB_NOT_NULL(j_base)) { + j_base->reset(); + j_base = nullptr; + } + if (OB_NOT_NULL(cursor)) { + cursor->reset(); + cursor = nullptr; + } + } return ret; } @@ -2615,6 +2629,26 @@ int ObJsonDeltaLob::init(ObIAllocator *allocator, ObLobLocatorV2 locator, int64_ return ret; } +void ObJsonDeltaLob::reset() +{ + if (OB_NOT_NULL(j_base_)) { + j_base_->reset(); + j_base_ = nullptr; + } + if (OB_NOT_NULL(update_ctx_)) { + update_ctx_->~ObJsonBinUpdateCtx(); + update_ctx_ = nullptr; + } + if (OB_NOT_NULL(cursor_)) { + cursor_->~ObLobCursor(); + cursor_ = nullptr; + } + if (OB_NOT_NULL(partial_data_)) { + partial_data_->~ObLobPartialData(); + partial_data_ = nullptr; + } +} + int64_t ObJsonDeltaLob::get_lob_diff_serialize_size() const { int64_t len = 0; diff --git a/src/sql/engine/expr/ob_expr_json_func_helper.h b/src/sql/engine/expr/ob_expr_json_func_helper.h index 59ae107587..3ffe3d2870 100644 --- a/src/sql/engine/expr/ob_expr_json_func_helper.h +++ b/src/sql/engine/expr/ob_expr_json_func_helper.h @@ -490,6 +490,7 @@ public: int init(ObJsonBin *j_bin); int init(ObIAllocator *allocator, ObLobLocatorV2 locator, int64_t query_timeout_ts); + void reset(); int64_t get_partial_data_serialize_size() const; int64_t get_lob_diff_serialize_size() const; diff --git a/src/storage/lob/ob_lob_manager.cpp b/src/storage/lob/ob_lob_manager.cpp index e44fea4d10..7efb39a54b 100644 --- a/src/storage/lob/ob_lob_manager.cpp +++ b/src/storage/lob/ob_lob_manager.cpp @@ -946,6 +946,7 @@ int ObLobManager::query( INIT_SUCC(ret); ObLobAccessParam *param = nullptr; bool is_remote_lob = false; + bool is_partial_data_alloc = false; common::ObAddr dst_addr; if (! locator.has_lob_header() || ! locator.is_persist_lob() || locator.is_inrow()) { ret = OB_INVALID_ARGUMENT; @@ -968,6 +969,7 @@ int ObLobManager::query( } else if (OB_FAIL(is_remote(*param, is_remote_lob, dst_addr))) { LOG_WARN("check is remote fail", K(ret), K(param)); } else if (OB_ISNULL(partial_data)) { + is_partial_data_alloc = true; if (OB_ISNULL(partial_data = OB_NEWx(ObLobPartialData, allocator))) { ret = OB_ALLOCATE_MEMORY_FAILED; LOG_WARN("alloc lob param fail", K(ret), "size", sizeof(ObLobPartialData)); @@ -991,6 +993,17 @@ int ObLobManager::query( } else if (OB_FAIL(cursor->init(allocator, param, partial_data, lob_ctx_))) { LOG_WARN("cursor init fail", K(ret)); } + + if (OB_FAIL(ret)) { + if (OB_NOT_NULL(cursor)) { + cursor->~ObLobCursor(); + cursor = nullptr; + } + if (OB_NOT_NULL(partial_data) && is_partial_data_alloc) { + partial_data->~ObLobPartialData(); + partial_data = nullptr; + } + } return ret; }