Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Metz
oceanbase
提交
7c4d50e3
O
oceanbase
项目概览
Metz
/
oceanbase
与 Fork 源项目一致
Fork自
oceanbase / oceanbase
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
O
oceanbase
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7c4d50e3
编写于
6月 12, 2022
作者:
O
obdev
提交者:
wangzelin.wzl
6月 12, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Set limitation for large transaction && Add some obtest for large transaction testing
上级
53a562dc
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
282 addition
and
45 deletion
+282
-45
CMakeLists.txt
CMakeLists.txt
+6
-0
build.sh
build.sh
+6
-0
deps/oblib/src/lib/utility/ob_tracepoint.h
deps/oblib/src/lib/utility/ob_tracepoint.h
+7
-0
src/storage/ob_garbage_collector.cpp
src/storage/ob_garbage_collector.cpp
+1
-1
src/storage/transaction/ob_trans_define.cpp
src/storage/transaction/ob_trans_define.cpp
+32
-0
src/storage/transaction/ob_trans_define.h
src/storage/transaction/ob_trans_define.h
+10
-2
src/storage/transaction/ob_trans_part_ctx.cpp
src/storage/transaction/ob_trans_part_ctx.cpp
+211
-40
src/storage/transaction/ob_trans_part_ctx.h
src/storage/transaction/ob_trans_part_ctx.h
+5
-2
src/storage/transaction/ob_trans_service.cpp
src/storage/transaction/ob_trans_service.cpp
+4
-0
未找到文件。
CMakeLists.txt
浏览文件 @
7c4d50e3
...
...
@@ -17,6 +17,12 @@ if(ENABLE_DEBUG_LOG)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-DENABLE_DEBUG_LOG"
)
endif
()
if
(
OB_ERRSIM
)
set
(
CMAKE_C_FLAGS
"
${
CMAKE_C_FLAGS
}
-DERRSIM"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-DERRSIM"
)
set
(
OB_TRANS_ERRSIM ON
)
endif
()
if
(
WITH_OSS
)
set
(
CMAKE_C_FLAGS
"
${
CMAKE_C_FLAGS
}
-D_WITH_OSS"
)
set
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-D_WITH_OSS"
)
...
...
build.sh
浏览文件 @
7c4d50e3
...
...
@@ -121,6 +121,12 @@ function build
xdebug_no_unity
)
do_build
"
$@
"
-DCMAKE_BUILD_TYPE
=
Debug
-DOB_ENABLE_UNITY
=
OFF
-DOB_ENABLE_PCH
=
OFF
;;
xerrsim_debug
)
do_build
"
$@
"
-DCMAKE_BUILD_TYPE
=
Debug
-DOB_ERRSIM
=
ON
-DOB_USE_LLD
=
$LLD_OPTION
;;
xerrsim
)
do_build
"
$@
"
-DCMAKE_BUILD_TYPE
=
RelWithDebInfo
-DOB_ERRSIM
=
ON
-DOB_USE_LLD
=
$LLD_OPTION
;;
xrpm
)
do_build
"
$@
"
-DOB_BUILD_RPM
=
ON
-DCMAKE_BUILD_TYPE
=
RelWithDebInfo
-DOB_USE_CCACHE
=
OFF
-DOB_COMPRESS_DEBUG_SECTIONS
=
ON
-DOB_STATIC_LINK_LGPL_DEPS
=
OFF
;;
...
...
deps/oblib/src/lib/utility/ob_tracepoint.h
浏览文件 @
7c4d50e3
...
...
@@ -466,6 +466,7 @@ public:
EN_INVALID_ADDR_WEAK_READ_FAILED
=
215
,
EN_STACK_OVERFLOW_CHECK_EXPR_STACK_SIZE
=
216
,
EN_ENABLE_PDML_ALL_FEATURE
=
217
,
EN_FAST_MIGRATE_ADD_MEMBER_FAIL
=
220
,
EN_MIGRATE_ADD_PARTITION_FAILED
=
224
,
EN_PRINT_QUERY_SQL
=
231
,
...
...
@@ -501,11 +502,17 @@ public:
EN_CLOG_DUMP_ILOG_MEMSTORE_RENAME_FAILURE
=
267
,
EN_CLOG_ILOG_MEMSTORE_ALLOC_MEMORY_FAILURE
=
268
,
EN_PARTICIPANTS_SIZE_OVERFLOW
=
275
,
EN_UNDO_ACTIONS_SIZE_OVERFLOW
=
276
,
EN_PART_PLUS_UNDO_OVERFLOW
=
277
,
EN_PREVENT_SYNC_REPORT
=
360
,
EN_PREVENT_ASYNC_REPORT
=
361
,
EN_LOG_IDS_COUNT_ERROR
=
363
,
// DDL related 500-550
EN_SUBMIT_INDEX_TASK_ERROR_BEFORE_STAT_RECORD
=
503
,
EN_SUBMIT_INDEX_TASK_ERROR_AFTER_STAT_RECORD
=
504
,
...
...
src/storage/ob_garbage_collector.cpp
浏览文件 @
7c4d50e3
...
...
@@ -1200,7 +1200,7 @@ int ObGarbageCollector::gc_check_log_archive_(
int64_t
delay_interval
=
LOG_ARCHIVE_DROP_DELAY
;
#ifdef ERRSIM
delay_interval
=
std
::
min
(
LOG_ARCHIVE_DROP_DELAY
,
(
int64_t
)
ObServerConfig
::
get_instance
().
schema_drop_gc_delay_time
);
//
delay_interval = std::min(LOG_ARCHIVE_DROP_DELAY, (int64_t)ObServerConfig::get_instance().schema_drop_gc_delay_time);
#endif
if
(
enable_log_archive
&&
!
is_restore
&&
!
is_sys_tenant
)
{
...
...
src/storage/transaction/ob_trans_define.cpp
浏览文件 @
7c4d50e3
...
...
@@ -1419,6 +1419,38 @@ int ObTransDesc::merge_participants(const common::ObPartitionArray& participants
return
ret
;
}
int
ObTransDesc
::
check_participants_size
()
{
int
ret
=
OB_SUCCESS
;
#ifdef ERRSIM
// test if this function can handle participants size overflow successfully
if
(
OB_FAIL
(
E
(
EventTable
::
EN_PARTICIPANTS_SIZE_OVERFLOW
)
OB_SUCCESS
))
{
OB_MAX_TRANS_SERIALIZE_SIZE
=
1500
;
OB_MIN_REDO_LOG_SERIALIZE_SIZE
=
500
;
TRANS_LOG
(
INFO
,
"ERRSIM modify trans ctx serialize size for case 1 "
,
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
K
(
OB_MIN_REDO_LOG_SERIALIZE_SIZE
));
}
else
if
(
OB_FAIL
(
E
(
EventTable
::
EN_PART_PLUS_UNDO_OVERFLOW
)
OB_SUCCESS
))
{
OB_MAX_TRANS_SERIALIZE_SIZE
=
7500
;
OB_MIN_REDO_LOG_SERIALIZE_SIZE
=
500
;
TRANS_LOG
(
INFO
,
"ERRSIM modify trans ctx serialize size for case 2 "
,
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
K
(
OB_MIN_REDO_LOG_SERIALIZE_SIZE
));
}
OB_MAX_UNDO_ACTION_SERIALIZE_SIZE
=
OB_MAX_TRANS_SERIALIZE_SIZE
-
OB_MIN_REDO_LOG_SERIALIZE_SIZE
;
ret
=
OB_SUCCESS
;
#endif
int64_t
participants_size
=
participants_
.
get_serialize_size
();
if
(
participants_size
>
OB_MAX_TRANS_SERIALIZE_SIZE
)
{
ret
=
OB_SIZE_OVERFLOW
;
TRANS_LOG
(
WARN
,
"Participants are too large which may make dump trans state table failed."
,
KR
(
ret
),
K
(
participants_size
),
K
(
participants_
.
count
()),
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
K
(
participants_
));
}
return
ret
;
}
int
ObTransDesc
::
set_cur_stmt_desc
(
const
ObStmtDesc
&
stmt_desc
)
{
int
ret
=
OB_SUCCESS
;
...
...
src/storage/transaction/ob_trans_define.h
浏览文件 @
7c4d50e3
...
...
@@ -69,8 +69,15 @@ class AggreLogTask;
class
ObPartTransCtxMgr
;
class
ObPartitionTransCtxMgr
;
// Reserve 50KB to store the fields in trans ctx except undo_status, participants and redo_log
static
const
int64_t
OB_MAX_TRANS_SERIALIZE_SIZE
=
common
::
OB_MAX_USER_ROW_LENGTH
-
51200
;
// The redo log id can use at least 128KB storage space
static
int64_t
OB_MIN_REDO_LOG_SERIALIZE_SIZE
=
131072
;
// redo_log + participants + undo_actions can use MAX_VARCHAR_LENGTH-10KB storage space
static
int64_t
OB_MAX_TRANS_SERIALIZE_SIZE
=
common
::
OB_MAX_VARCHAR_LENGTH
-
10
*
1024
;
// The participants and undo actions share the last storage space
static
int64_t
OB_MAX_UNDO_ACTION_SERIALIZE_SIZE
=
OB_MAX_TRANS_SERIALIZE_SIZE
-
OB_MIN_REDO_LOG_SERIALIZE_SIZE
;
class
ObTransErrsim
{
public:
...
...
@@ -1672,6 +1679,7 @@ public:
int
merge_participants_pla
();
int
merge_participants
(
const
common
::
ObPartitionArray
&
participants
);
int
merge_participants_pla
(
const
common
::
ObPartitionLeaderArray
&
participant_pla
);
int
check_participants_size
();
const
common
::
ObPartitionArray
&
get_participants
()
const
{
return
participants_
;
...
...
src/storage/transaction/ob_trans_part_ctx.cpp
浏览文件 @
7c4d50e3
...
...
@@ -175,8 +175,9 @@ int ObPartTransCtx::init(const uint64_t tenant_id, const ObTransID& trans_id, co
}
is_listener_
=
false
;
listener_handler_
=
NULL
;
ctx_serialize_size_
=
undo_status_
.
get_serialize_size
()
+
partition_log_info_arr_
.
get_serialize_size
()
+
prev_redo_log_ids_
.
get_serialize_size
();
redo_log_id_serialize_size_
=
prev_redo_log_ids_
.
get_serialize_size
();
participants_serialize_size_
=
partition_log_info_arr_
.
get_serialize_size
();
undo_serialize_size_
=
undo_status_
.
get_serialize_size
();
}
if
(
OB_FAIL
(
ret
))
{
if
(
NULL
!=
redo_sync_task_
)
{
...
...
@@ -390,7 +391,9 @@ void ObPartTransCtx::reset()
last_redo_log_mutator_size_
=
0
;
has_write_or_replay_mutator_redo_log_
=
false
;
is_in_redo_with_prepare_
=
false
;
ctx_serialize_size_
=
0
;
redo_log_id_serialize_size_
=
0
;
participants_serialize_size_
=
0
;
undo_serialize_size_
=
0
;
prev_checkpoint_id_
=
0
;
}
...
...
@@ -1650,6 +1653,7 @@ bool ObPartTransCtx::not_need_write_next_log_(const int64_t log_type)
void
ObPartTransCtx
::
reset_prev_redo_log_ids
()
{
prev_redo_log_ids_
.
reset
();
redo_log_id_serialize_size_
=
0
;
}
// when submit log success
...
...
@@ -4841,20 +4845,29 @@ bool ObPartTransCtx::has_logged_() const
bool
ObPartTransCtx
::
need_record_log
()
const
{
// Record Log will be generated if the number of log ids
// is no less than the max size of prev_redo_log_ids_
uint64_t
prev_log_ids_count
=
MAX_PREV_LOG_IDS_COUNT
;
// There are three variables can be very large : participants array, redo log array and undo
// actions array. In order to avoiding the serialize size of ObPartTransCtx is too large, which
// may larger than 1MB, we have to limit the size of these three variables. We set the
// following principles:
//
// 1. The redo_log can use at least 128KB
// 2. All the three variables can use 1014KB(MAX_VARCHAR_LENGTH-10KB)
//
// In this function, we sum the serialize size of these three fileds to decide if this transaction
// need write record log. So this function return true implicates the serialize size of these
// three variables is larger than 1014KB and we need write record log to make sure the trans state
// table can be dumped successfully.
bool
bool_ret
=
false
;
int
total_size
=
participants_serialize_size_
+
undo_serialize_size_
+
redo_log_id_serialize_size_
;
#ifdef ERRSIM
// Error injection test, used for changing prev_log_ids_count for test
int
tmp_ret
=
E
(
EventTable
::
EN_LOG_IDS_COUNT_ERROR
)
OB_SUCCESS
;
if
(
tmp_ret
!=
OB_SUCCESS
)
{
prev_log_ids_count
=
2
;
TRANS_LOG
(
INFO
,
"need_record_log: "
,
K
(
prev_log_ids_count
));
if
(
total_size
>
OB_MAX_TRANS_SERIALIZE_SIZE
)
{
bool_ret
=
true
;
TRANS_LOG
(
INFO
,
"need flush record log."
,
K
(
participants_serialize_size_
),
K
(
undo_serialize_size_
),
K
(
redo_log_id_serialize_size_
),
K
(
total_size
),
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
KPC
(
this
));
}
#endif
return
prev_redo_log_ids_
.
count
()
>=
prev_log_ids_coun
t
;
return
bool_re
t
;
}
int
ObPartTransCtx
::
reserve_log_header_
(
char
*
buf
,
const
int64_t
size
,
int64_t
&
pos
)
...
...
@@ -12155,56 +12168,214 @@ void ObPartTransCtx::DEBUG_SYNC_slow_txn_during_2pc_prepare_phase_for_physical_b
}
}
// for more explanation of this function, see ObPartTransCtx::need_record_log()
int
ObPartTransCtx
::
calc_serialize_size_and_set_redo_log_
(
const
int64_t
log_id
)
{
int
ret
=
OB_SUCCESS
;
if
((
ctx_serialize_size_
+=
serialization
::
encoded_length_vi64
(
log_id
))
>
OB_MAX_TRANS_SERIALIZE_SIZE
)
{
ret
=
OB_SIZE_OVERFLOW
;
TRANS_LOG
(
WARN
,
"size overflow when set redo log."
,
KR
(
ret
),
K
(
ctx_serialize_size_
),
K
(
log_id
));
}
else
if
(
OB_FAIL
(
prev_redo_log_ids_
.
push_back
(
log_id
)))
{
ctx_serialize_size_
-=
serialization
::
encoded_length_vi64
(
log_id
);
TRANS_LOG
(
WARN
,
"sp redo log id push back error"
,
KR
(
ret
),
"context"
,
*
this
,
K
(
log_id
));
redo_log_id_serialize_size_
+=
serialization
::
encoded_length_vi64
(
log_id
);
if
(
OB_FAIL
(
prev_redo_log_ids_
.
push_back
(
log_id
)))
{
redo_log_id_serialize_size_
-=
serialization
::
encoded_length_vi64
(
log_id
);
TRANS_LOG
(
WARN
,
"prev redo log id push back error"
,
KR
(
ret
),
K
(
log_id
),
KPC
(
this
));
}
else
{
// push back redo log success
}
return
ret
;
}
/*
* There are three kinds of cases when set participants. We calculate serialize size and do
* something to avoid dumping trans state table fail.
*
* ┌─────────────────────────────────────────────────┐
* CASE 1 : │ participants │
* └─────────────────────────────────────────────────┘
*
* │ OB_MAX_TRANS_SERIALIZE_SIZE │
* └────────────────────────────────────────────┘
* Participants are too large. This situation should be handled by upper layer
*
* ┌────────────────────────────┬────────────────────┐
* CASE 2 : │ participants │ undo status │
* └────────────────────────────┴────────────────────┘
*
* │ OB_MAX_TRANS_SERIALIZE_SIZE │
* └────────────────────────────────────────────┘
* Participants plus undo status are too large. Trans state table can not be dumped by flushing
* record log.Rollback it without returning error code because the follower cannot response to the
* leader if return error code here.
*
* ┌─────────────────┬───────────────┬────────────────┐
* CASE 3 : │ participants │ undo status │ redo log │
* └─────────────────┴───────────────┴────────────────┘
*
* │ OB_MAX_TRANS_SERIALIZE_SIZE │
* └────────────────────────────────────────────┘
* Flush record log can make trans state table be successfully dumped.
*/
int
ObPartTransCtx
::
calc_serialize_size_and_set_participants_
(
const
ObPartitionArray
&
participants
)
{
int
ret
=
OB_SUCCESS
;
if
((
ctx_serialize_size_
+=
participants
.
get_serialize_size
())
>
OB_MAX_TRANS_SERIALIZE_SIZE
)
{
set_status_
(
OB_TRANS_NEED_ROLLBACK
);
ret
=
OB_SIZE_OVERFLOW
;
TRANS_LOG
(
WARN
,
"size overflow when set participants."
,
KR
(
ret
),
K
(
ctx_serialize_size_
),
K
(
participants
.
get_serialize_size
()));
int64_t
tmp_participants_size
=
participants_serialize_size_
+
participants
.
get_serialize_size
();
bool
has_redo_log
=
false
;
bool
need_submit_record_log
=
false
;
#ifdef ERRSIM
// test if this function can handle participants size overflow successfully
if
(
OB_FAIL
(
E
(
EventTable
::
EN_PARTICIPANTS_SIZE_OVERFLOW
)
OB_SUCCESS
))
{
OB_MAX_TRANS_SERIALIZE_SIZE
=
1500
;
OB_MIN_REDO_LOG_SERIALIZE_SIZE
=
500
;
}
else
if
(
OB_FAIL
(
E
(
EventTable
::
EN_PART_PLUS_UNDO_OVERFLOW
)
OB_SUCCESS
))
{
OB_MAX_TRANS_SERIALIZE_SIZE
=
7500
;
OB_MIN_REDO_LOG_SERIALIZE_SIZE
=
500
;
}
OB_MAX_UNDO_ACTION_SERIALIZE_SIZE
=
OB_MAX_TRANS_SERIALIZE_SIZE
-
OB_MIN_REDO_LOG_SERIALIZE_SIZE
;
TRANS_LOG
(
INFO
,
"ERRSIM modify trans ctx serialize size "
,
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
K
(
OB_MIN_REDO_LOG_SERIALIZE_SIZE
),
K
(
OB_MAX_UNDO_ACTION_SERIALIZE_SIZE
));
ret
=
OB_SUCCESS
;
#endif
if
(
OB_UNLIKELY
(
tmp_participants_size
>
OB_MAX_TRANS_SERIALIZE_SIZE
))
{
// case 1
ret
=
OB_ERR_UNEXPECTED
;
int64_t
participants_count
=
participants
.
count
();
TRANS_LOG
(
ERROR
,
"participants is unexpected too large."
,
KR
(
ret
),
K
(
participants_count
),
K
(
tmp_participants_size
),
KPC
(
this
));
}
else
if
(
OB_UNLIKELY
(
tmp_participants_size
+
undo_serialize_size_
>
OB_MAX_TRANS_SERIALIZE_SIZE
))
{
// case 2
// undo_serialize_size_ is an estimate value. Here we update undo serialize size before checking
// because a large range undo action can remove some little range undo actions.
undo_serialize_size_
=
undo_status_
.
get_serialize_size
();
if
(
tmp_participants_size
+
undo_serialize_size_
>
OB_MAX_TRANS_SERIALIZE_SIZE
)
{
TRANS_LOG
(
WARN
,
"transaction is too large. flush record log can not handle it"
,
K
(
tmp_participants_size
),
K
(
participants_serialize_size_
),
K
(
undo_serialize_size_
),
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
K
(
trans_id_
),
KPC
(
this
));
set_status_
(
OB_TRANS_NEED_ROLLBACK
);
// Reset undo status to make trans state table can be dumped.
undo_status_
.
reset
();
undo_serialize_size_
=
0
;
}
}
else
{
// normal case, set participants directly
}
if
(
OB_SUCC
(
ret
)
&&
OB_UNLIKELY
(
tmp_participants_size
+
undo_serialize_size_
+
redo_log_id_serialize_size_
>
OB_MAX_TRANS_SERIALIZE_SIZE
))
{
// case 3
need_submit_record_log
=
true
;
int64_t
participants_size
=
tmp_participants_size
;
int64_t
real_undo_size
=
undo_status_
.
get_serialize_size
();
int64_t
total_size
=
participants_size
+
redo_log_id_serialize_size_
+
undo_serialize_size_
;
TRANS_LOG
(
INFO
,
"flush record log to reserve space for participants"
,
K
(
participants_size
),
K
(
undo_serialize_size_
),
K
(
real_undo_size
),
K
(
redo_log_id_serialize_size_
),
K
(
total_size
),
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
KPC
(
this
));
}
if
(
OB_FAIL
(
ret
))
{
// participants is too large, this function can not handle it
}
else
if
(
OB_UNLIKELY
(
need_submit_record_log
)
&&
OB_FAIL
(
submit_log_async_
(
OB_LOG_TRANS_RECORD
,
has_redo_log
)))
{
TRANS_LOG
(
WARN
,
"submit record log failed"
,
KR
(
ret
),
KPC
(
this
));
}
else
if
(
OB_FAIL
(
set_participants_
(
participants
)))
{
ctx_serialize_size_
-=
participants
.
get_serialize_size
();
TRANS_LOG
(
WARN
,
"set participants error"
,
KR
(
ret
),
K
(
participants
));
TRANS_LOG
(
WARN
,
"set participants error"
,
KR
(
ret
),
KPC
(
this
),
K
(
participants
));
}
else
{
participants_serialize_size_
=
tmp_participants_size
;
}
return
ret
;
}
int
ObPartTransCtx
::
calc_serialize_size_and_set_undo_
(
const
int64_t
undo_to
,
const
int64_t
undo_from
)
/*
* There are two cases when set undo status. We calculate serialize size and do something to avoid
* dumping trans state table fail.
*
* We increase undo_serialize_size_ every time we set undo. But if the undo_serialize_size is too
* large and the transaction need rollback, we update this variable to get a real size.
*
* ┌────────────────────────────────────────┐
* CASE 4 : │ undo status │
* └────────────────────────────────────────┘
*
* │ OB_MAX_UNDO_ACTION_SERIALIZE_SIZE │
* └────────────────────────────────────┘
*
* │ OB_MAX_TRANS_SERIALIZE_SIZE │
* └────────────────────────────────────────────┘
* Undo status are too large, rollback this transaction.
*
* ┌───────────────────────────┬───────────────────────┐
* CASE 5 : │ undo status │ redo log │
* └───────────────────────────┴───────────────────────┘
*
* │ OB_MAX_UNDO_ACTION_SERIALIZE_SIZE │
* └────────────────────────────────────┘
*
* │ OB_MAX_TRANS_SERIALIZE_SIZE │
* └────────────────────────────────────────────┘
* Flush record log can make trans state table be successfully dumped.
*/
int
ObPartTransCtx
::
calc_serialize_size_and_set_undo_
(
const
int64_t
undo_to
,
const
int64_t
undo_from
)
{
int
ret
=
OB_SUCCESS
;
ObUndoAction
undo_action
(
undo_to
,
undo_from
);
if
((
ctx_serialize_size_
+=
undo_action
.
get_serialize_size
())
>
OB_MAX_TRANS_SERIALIZE_SIZE
)
{
undo_serialize_size_
+=
undo_action
.
get_serialize_size
();
bool
has_redo_log
=
false
;
bool
updated_size
=
false
;
#ifdef ERRSIM
// test if this function can handle participants size overflow successfully
if
(
OB_FAIL
(
E
(
EventTable
::
EN_UNDO_ACTIONS_SIZE_OVERFLOW
)
OB_SUCCESS
))
{
OB_MAX_TRANS_SERIALIZE_SIZE
=
4100
;
OB_MIN_REDO_LOG_SERIALIZE_SIZE
=
1500
;
TRANS_LOG
(
INFO
,
"ERRSIM modify trans ctx serialize size for case 4"
,
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
K
(
OB_MIN_REDO_LOG_SERIALIZE_SIZE
));
}
OB_MAX_UNDO_ACTION_SERIALIZE_SIZE
=
OB_MAX_TRANS_SERIALIZE_SIZE
-
OB_MIN_REDO_LOG_SERIALIZE_SIZE
;
ret
=
OB_SUCCESS
;
#endif
if
(
OB_UNLIKELY
(
undo_serialize_size_
>
OB_MAX_UNDO_ACTION_SERIALIZE_SIZE
))
{
// undo_serialize_size_ is an estimate value. Here we update undo serialize size before checking
// because a large range undo action can remove some little range undo actions.
undo_serialize_size_
=
undo_status_
.
get_serialize_size
();
updated_size
=
true
;
}
if
(
undo_serialize_size_
>
OB_MAX_UNDO_ACTION_SERIALIZE_SIZE
)
{
// case 4
set_status_
(
OB_TRANS_NEED_ROLLBACK
);
ret
=
OB_SIZE_OVERFLOW
;
TRANS_LOG
(
WARN
,
"size overflow when set undo action"
,
KR
(
ret
),
K
(
ctx_serialize_size_
),
K
(
ctx_serialize_size_
),
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
));
TRANS_LOG
(
WARN
,
"size overflow when set undo action"
,
KR
(
ret
),
K
(
undo_serialize_size_
),
K
(
redo_log_id_serialize_size_
),
K
(
participants_serialize_size_
),
K
(
OB_MAX_UNDO_ACTION_SERIALIZE_SIZE
),
KPC
(
this
));
}
else
if
(
OB_UNLIKELY
(
undo_serialize_size_
+
redo_log_id_serialize_size_
>
OB_MAX_TRANS_SERIALIZE_SIZE
))
{
// case 5
TRANS_LOG
(
INFO
,
"flush record log to reserve space for undo"
,
K
(
undo_serialize_size_
),
K
(
redo_log_id_serialize_size_
),
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
));
if
(
OB_FAIL
(
submit_log_async_
(
OB_LOG_TRANS_RECORD
,
has_redo_log
)))
{
TRANS_LOG
(
WARN
,
"submit record log failed"
,
KR
(
ret
),
K
(
undo_serialize_size_
),
K
(
redo_log_id_serialize_size_
),
K
(
OB_MAX_TRANS_SERIALIZE_SIZE
),
KPC
(
this
));
}
}
if
(
OB_FAIL
(
ret
))
{
}
else
if
(
OB_FAIL
(
undo_status_
.
undo
(
undo_to
,
undo_from
)))
{
ctx_serialize_size_
-=
undo_action
.
get_serialize_size
();
TRANS_LOG
(
WARN
,
"record rollback action failed"
,
K
(
ret
),
K
(
undo_to
),
K
(
undo_from
));
TRANS_LOG
(
WARN
,
"record rollback action failed"
,
KR
(
ret
),
K
(
undo_action
),
KPC
(
this
));
}
if
(
OB_FAIL
(
ret
)
&&
!
updated_size
)
{
undo_serialize_size_
-=
undo_action
.
get_serialize_size
();
}
return
ret
;
}
...
...
src/storage/transaction/ob_trans_part_ctx.h
浏览文件 @
7c4d50e3
...
...
@@ -405,7 +405,8 @@ public:
K
(
mt_ctx_
.
get_checksum_log_ts
()),
K_
(
is_changing_leader
),
K_
(
has_trans_state_log
),
K_
(
is_trans_state_sync_finished
),
K_
(
status
),
K_
(
same_leader_batch_partitions_count
),
K_
(
is_hazardous_ctx
),
K
(
mt_ctx_
.
get_callback_count
()),
K_
(
in_xa_prepare_state
),
K_
(
is_listener
),
K_
(
last_replayed_redo_log_id
),
K_
(
status
),
K_
(
is_xa_trans_prepared
),
K_
(
ctx_serialize_size
));
K_
(
status
),
K_
(
is_xa_trans_prepared
),
K_
(
redo_log_id_serialize_size
),
K_
(
participants_serialize_size
),
K_
(
undo_serialize_size
));
public:
static
const
int64_t
OP_LOCAL_NUM
=
16
;
...
...
@@ -752,7 +753,9 @@ ObTransSubmitLogCb submit_log_cb_;
bool
is_xa_trans_prepared_
;
bool
has_write_or_replay_mutator_redo_log_
;
bool
is_in_redo_with_prepare_
;
int64_t
ctx_serialize_size_
;
int64_t
redo_log_id_serialize_size_
;
int64_t
participants_serialize_size_
;
int64_t
undo_serialize_size_
;
// the log id of prev checkpoint log
uint64_t
prev_checkpoint_id_
;
};
...
...
src/storage/transaction/ob_trans_service.cpp
浏览文件 @
7c4d50e3
...
...
@@ -2500,6 +2500,10 @@ int ObTransService::end_stmt(bool is_rollback, bool is_incomplete, const ObParti
}
}
if
(
OB_SUCC
(
ret
)
&&
OB_FAIL
(
trans_desc
.
check_participants_size
()))
{
trans_desc
.
set_need_rollback
();
TRANS_LOG
(
WARN
,
"check participants size failed."
,
KR
(
ret
));
}
REC_TRACE_EXT
(
tlog
,
end_stmt
,
Y
(
ret
));
if
(
OB_FAIL
(
ret
))
{
trans_desc
.
set_need_print_trace_log
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录