Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
不争之德
oceanbase
提交
4e81072c
O
oceanbase
项目概览
不争之德
/
oceanbase
与 Fork 源项目一致
Fork自
oceanbase / oceanbase
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
oceanbase
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
4e81072c
编写于
8月 25, 2022
作者:
O
obdev
提交者:
wangzelin.wzl
8月 25, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[CP] [CP] Fix reference count leak when stmt_info expires
上级
649a2dc6
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
95 addition
and
17 deletion
+95
-17
src/sql/ob_sql.cpp
src/sql/ob_sql.cpp
+1
-1
src/sql/plan_cache/ob_prepare_stmt_struct.cpp
src/sql/plan_cache/ob_prepare_stmt_struct.cpp
+10
-1
src/sql/plan_cache/ob_prepare_stmt_struct.h
src/sql/plan_cache/ob_prepare_stmt_struct.h
+8
-3
src/sql/plan_cache/ob_ps_cache.cpp
src/sql/plan_cache/ob_ps_cache.cpp
+35
-8
src/sql/plan_cache/ob_ps_cache.h
src/sql/plan_cache/ob_ps_cache.h
+3
-3
src/sql/plan_cache/ob_ps_cache_callback.cpp
src/sql/plan_cache/ob_ps_cache_callback.cpp
+13
-1
src/sql/plan_cache/ob_ps_cache_callback.h
src/sql/plan_cache/ob_ps_cache_callback.h
+25
-0
未找到文件。
src/sql/ob_sql.cpp
浏览文件 @
4e81072c
...
...
@@ -729,7 +729,7 @@ int ObSql::handle_ps_prepare(const ObString &stmt, ObSqlCtx &context, ObResultSe
stmt_info
->
set_is_expired
();
ps_sql_key
.
set_db_id
(
stmt_info
->
get_db_id
());
ps_sql_key
.
set_ps_sql
(
stmt_info
->
get_ps_sql
());
if
(
OB_FAIL
(
ps_cache
->
erase_stmt_item
(
ps_sql_key
)))
{
if
(
OB_FAIL
(
ps_cache
->
erase_stmt_item
(
inner_stmt_id
,
ps_sql_key
)))
{
LOG_WARN
(
"fail to erase stmt item"
,
K
(
ret
),
K
(
*
stmt_info
));
}
need_do_real_prepare
=
true
;
...
...
src/sql/plan_cache/ob_prepare_stmt_struct.cpp
浏览文件 @
4e81072c
...
...
@@ -61,12 +61,19 @@ ObPsStmtItem::ObPsStmtItem()
db_id_
(
OB_INVALID_ID
),
ps_sql_
(),
stmt_id_
(
OB_INVALID_STMT_ID
),
is_expired_evicted_
(
false
),
allocator_
(
NULL
),
external_allocator_
(
NULL
)
{}
ObPsStmtItem
::
ObPsStmtItem
(
const
ObPsStmtId
ps_stmt_id
)
:
ref_count_
(
1
),
db_id_
(
OB_INVALID_ID
),
ps_sql_
(),
stmt_id_
(
ps_stmt_id
),
allocator_
(
NULL
),
external_allocator_
(
NULL
)
:
ref_count_
(
1
),
db_id_
(
OB_INVALID_ID
),
ps_sql_
(),
stmt_id_
(
ps_stmt_id
),
is_expired_evicted_
(
false
),
allocator_
(
NULL
),
external_allocator_
(
NULL
)
{}
ObPsStmtItem
::
ObPsStmtItem
(
ObIAllocator
*
inner_allocator
,
ObIAllocator
*
external_allocator
)
...
...
@@ -74,6 +81,7 @@ ObPsStmtItem::ObPsStmtItem(ObIAllocator* inner_allocator, ObIAllocator* external
db_id_
(
OB_INVALID_ID
),
ps_sql_
(),
stmt_id_
(
OB_INVALID_STMT_ID
),
is_expired_evicted_
(
false
),
allocator_
(
inner_allocator
),
external_allocator_
(
external_allocator
)
{}
...
...
@@ -102,6 +110,7 @@ ObPsStmtItem& ObPsStmtItem::operator=(const ObPsStmtItem& other)
db_id_
=
other
.
get_db_id
();
ps_sql_
=
other
.
get_ps_sql
();
stmt_id_
=
other
.
get_ps_stmt_id
();
is_expired_evicted_
=
other
.
is_expired_evicted_
;
}
return
*
this
;
}
...
...
src/sql/plan_cache/ob_prepare_stmt_struct.h
浏览文件 @
4e81072c
...
...
@@ -121,19 +121,24 @@ public:
{
return
external_allocator_
;
}
bool
*
get_is_expired_evicted_ptr
()
{
return
&
is_expired_evicted_
;
}
TO_STRING_KV
(
K_
(
ref_count
),
K_
(
db_id
),
K_
(
ps_sql
),
K_
(
stmt_id
));
TO_STRING_KV
(
K_
(
ref_count
),
K_
(
db_id
),
K_
(
ps_sql
),
K_
(
stmt_id
)
,
K_
(
is_expired_evicted
)
);
private:
volatile
int64_t
ref_count_
;
uint64_t
db_id_
;
common
::
ObString
ps_sql_
;
ObPsStmtId
stmt_id_
;
bool
is_expired_evicted_
;
// ObDataBuffer is used to use the internal memory of ObPsStmtItem.
// The memory essentially comes from inner_allocator_ in ObPsPlancache
common
::
ObIAllocator
*
allocator_
;
common
::
ObIAllocator
*
allocator_
;
// Point to inner_allocator_ in ObPsPlancache, used to release the memory of the entire ObPsStmtItem
common
::
ObIAllocator
*
external_allocator_
;
common
::
ObIAllocator
*
external_allocator_
;
};
struct
ObPsSqlMeta
{
...
...
src/sql/plan_cache/ob_ps_cache.cpp
浏览文件 @
4e81072c
...
...
@@ -127,7 +127,7 @@ int ObPsCache::deref_ps_stmt(const ObPsStmtId stmt_id, bool erase_item /*=false*
ps_sql_key
.
set_ps_sql
(
ps_info
->
get_ps_sql
());
int
tmp_ret
=
OB_SUCCESS
;
if
(
erase_item
)
{
// dec cached ref
if
(
OB_FAIL
(
erase_stmt_item
(
ps_sql_key
)))
{
if
(
OB_FAIL
(
erase_stmt_item
(
stmt_id
,
ps_sql_key
)))
{
LOG_WARN
(
"fail to erase stmt"
,
K
(
ret
));
}
}
else
{
// dec session ref
...
...
@@ -420,21 +420,48 @@ int ObPsCache::get_or_add_stmt_info(const ObResultSet& result, int64_t param_cnt
}
// may parallel execute by multi_thread
int
ObPsCache
::
erase_stmt_item
(
ObPsS
qlKey
&
ps_key
)
int
ObPsCache
::
erase_stmt_item
(
ObPsS
tmtId
stmt_id
,
ObPsSqlKey
&
ps_key
)
{
int
ret
=
OB_SUCCESS
;
ObPsStmtItem
*
ps_item
=
NULL
;
if
(
OB_FAIL
(
stmt_id_map_
.
erase_refactored
(
ps_key
,
&
ps_item
)))
{
ObPsStmtItem
*
ps_item
=
NULL
;
/*
* Thread A Thread B
* Get stmt_item successfully Get stmt_item successfully
*
* Check stmt_info expired
* Check stmt_info expired
*
* Delete stmt_item by key(db_id, ps_sql)
*
*
*
* Add stmt_item with (db_id, ps_sql) as key
*
* Delete stmt_item by key(db_id, ps_sql)
* The item added in the previous step of thread A is deleted
*
*
*/
ObPsStmtItemEraseAtomicOp
op
(
stmt_id
);
if
(
OB_FAIL
(
stmt_id_map_
.
read_atomic
(
ps_key
,
op
)))
{
if
(
OB_HASH_NOT_EXIST
==
ret
)
{
LOG_INFO
(
"erased by others"
,
K
(
ret
),
K
(
ps_key
));
ret
=
OB_SUCCESS
;
}
else
{
LOG_WARN
(
"fail to erase stmt info"
,
K
(
ps_key
),
K
(
ret
));
LOG_WARN
(
"failed to get ps stmt item"
,
K
(
ps_key
),
K
(
ret
));
}
}
else
if
(
op
.
need_erase
())
{
if
(
OB_FAIL
(
stmt_id_map_
.
erase_refactored
(
ps_key
,
&
ps_item
)))
{
if
(
OB_HASH_NOT_EXIST
==
ret
)
{
LOG_INFO
(
"erased by others"
,
K
(
ret
),
K
(
ps_key
));
ret
=
OB_SUCCESS
;
}
else
{
LOG_WARN
(
"fail to erase stmt info"
,
K
(
ps_key
),
K
(
ret
));
}
}
else
{
ps_item
->
dec_ref_count_check_erase
();
}
}
else
{
ps_item
->
dec_ref_count_check_erase
();
}
return
ret
;
}
...
...
src/sql/plan_cache/ob_ps_cache.h
浏览文件 @
4e81072c
...
...
@@ -109,9 +109,9 @@ public:
return
stmt_info_map_
.
size
();
}
int
get_all_stmt_id
(
common
::
ObIArray
<
ObPsStmtId
>
*
id_array
);
int
check_schema_version
(
ObSchemaGetterGuard
&
schema_guard
,
ObPsStmtInfo
&
stmt_info
,
bool
&
is_expired
);
int
erase_stmt_item
(
ObPsS
qlKey
&
ps_key
);
int
get_all_stmt_id
(
common
::
ObIArray
<
ObPsStmtId
>
*
id_array
);
int
check_schema_version
(
ObSchemaGetterGuard
&
schema_guard
,
ObPsStmtInfo
&
stmt_info
,
bool
&
is_expired
);
int
erase_stmt_item
(
ObPsS
tmtId
stmt_id
,
ObPsSqlKey
&
ps_key
);
private:
int
inner_cache_evict
(
bool
is_evict_all
);
...
...
src/sql/plan_cache/ob_ps_cache_callback.cpp
浏览文件 @
4e81072c
...
...
@@ -56,7 +56,19 @@ void ObPsStmtItemDerefAtomicOp::operator()(const PsStmtIdKV& entry)
}
}
void
ObPsStmtInfoRefAtomicOp
::
operator
()(
const
PsStmtInfoKV
&
entry
)
void
ObPsStmtItemEraseAtomicOp
::
operator
()(
const
PsStmtIdKV
&
entry
)
{
if
(
OB_ISNULL
(
entry
.
second
))
{
ret_
=
OB_HASH_NOT_EXIST
;
LOG_WARN
(
"entry not exist"
,
K_
(
ret
));
}
else
if
(
entry
.
second
->
get_ps_stmt_id
()
==
stmt_id_
)
{
if
(
ATOMIC_BCAS
(
entry
.
second
->
get_is_expired_evicted_ptr
(),
false
,
true
))
{
need_erase_
=
true
;
}
}
}
void
ObPsStmtInfoRefAtomicOp
::
operator
()(
const
PsStmtInfoKV
&
entry
)
{
if
(
NULL
!=
entry
.
second
)
{
if
(
entry
.
second
->
check_erase_inc_ref_count
())
{
...
...
src/sql/plan_cache/ob_ps_cache_callback.h
浏览文件 @
4e81072c
...
...
@@ -152,6 +152,31 @@ private:
DISALLOW_COPY_AND_ASSIGN
(
ObPsStmtItemDerefAtomicOp
);
};
class
ObPsStmtItemEraseAtomicOp
{
typedef
common
::
hash
::
HashMapPair
<
ObPsSqlKey
,
ObPsStmtItem
*>
PsStmtIdKV
;
public:
ObPsStmtItemEraseAtomicOp
(
ObPsStmtId
id
)
:
stmt_id_
(
id
),
ret_
(
common
::
OB_SUCCESS
),
need_erase_
(
false
)
{}
virtual
~
ObPsStmtItemEraseAtomicOp
()
{}
void
operator
()(
const
PsStmtIdKV
&
entry
);
int
get_ret
()
const
{
return
ret_
;
}
bool
need_erase
()
const
{
return
need_erase_
;
}
private:
ObPsStmtId
stmt_id_
;
int
ret_
;
bool
need_erase_
;
DISALLOW_COPY_AND_ASSIGN
(
ObPsStmtItemEraseAtomicOp
);
};
class
ObPsStmtInfoRefAtomicOp
{
typedef
common
::
hash
::
HashMapPair
<
ObPsStmtId
,
ObPsStmtInfo
*>
PsStmtInfoKV
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录