BUGFIX: wake up lock wait mgr if OUT_TRANS_UNLOCK finished
This commit is contained in:
@ -424,6 +424,7 @@ class ObString;
|
|||||||
ACT(AFTER_BACKUP_FETCH_MACRO_BLOCK_FAILED,)\
|
ACT(AFTER_BACKUP_FETCH_MACRO_BLOCK_FAILED,)\
|
||||||
ACT(BEFORE_TABLE_REDEFINITION_TASK_EFFECT,)\
|
ACT(BEFORE_TABLE_REDEFINITION_TASK_EFFECT,)\
|
||||||
ACT(ALTER_LS_CHOOSE_SRC,)\
|
ACT(ALTER_LS_CHOOSE_SRC,)\
|
||||||
|
ACT(BEFORE_LOCK_SERVICE_UNLOCK,)\
|
||||||
ACT(MAX_DEBUG_SYNC_POINT,)
|
ACT(MAX_DEBUG_SYNC_POINT,)
|
||||||
|
|
||||||
DECLARE_ENUM(ObDebugSyncPoint, debug_sync_point, OB_DEBUG_SYNC_POINT_DEF);
|
DECLARE_ENUM(ObDebugSyncPoint, debug_sync_point, OB_DEBUG_SYNC_POINT_DEF);
|
||||||
|
|||||||
@ -171,8 +171,7 @@ int ObLockMemtable::lock_(
|
|||||||
if (ret == OB_OBJ_LOCK_EXIST) {
|
if (ret == OB_OBJ_LOCK_EXIST) {
|
||||||
ret = OB_SUCCESS;
|
ret = OB_SUCCESS;
|
||||||
}
|
}
|
||||||
if (ENABLE_USE_LOCK_WAIT_MGR &&
|
if (OB_TRY_LOCK_ROW_CONFLICT == ret &&
|
||||||
OB_TRY_LOCK_ROW_CONFLICT == ret &&
|
|
||||||
lock_op.is_dml_lock_op() && // only in trans dml lock will wait at lock wait mgr.
|
lock_op.is_dml_lock_op() && // only in trans dml lock will wait at lock wait mgr.
|
||||||
conflict_tx_set.count() != 0) {
|
conflict_tx_set.count() != 0) {
|
||||||
// TODO: yanyuan.cxf only wait at the first conflict trans now, but we need
|
// TODO: yanyuan.cxf only wait at the first conflict trans now, but we need
|
||||||
@ -351,19 +350,6 @@ int ObLockMemtable::post_obj_lock_conflict_(ObMvccAccessCtx &acc_ctx,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObLockMemtable::wakeup_waiters_(const ObTableLockOp &lock_op)
|
|
||||||
{
|
|
||||||
// dml in trans lock does not need do this.
|
|
||||||
if (OB_LIKELY(!lock_op.need_wakeup_waiter())) {
|
|
||||||
// do nothing
|
|
||||||
} else if (OB_ISNULL(MTL(ObLockWaitMgr*))) {
|
|
||||||
LOG_WARN("MTL(ObLockWaitMgr*) is null");
|
|
||||||
} else {
|
|
||||||
MTL(ObLockWaitMgr*)->wakeup(lock_op.lock_id_);
|
|
||||||
LOG_DEBUG("ObLockMemtable::wakeup_waiters_ ", K(lock_op));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ObLockMemtable::check_lock_conflict(
|
int ObLockMemtable::check_lock_conflict(
|
||||||
const ObMemtableCtx *mem_ctx,
|
const ObMemtableCtx *mem_ctx,
|
||||||
const ObTableLockOp &lock_op,
|
const ObTableLockOp &lock_op,
|
||||||
@ -489,9 +475,6 @@ void ObLockMemtable::remove_lock_record(const ObTableLockOp &lock_op)
|
|||||||
LOG_WARN("invalid argument", K(ret), K(lock_op));
|
LOG_WARN("invalid argument", K(ret), K(lock_op));
|
||||||
} else {
|
} else {
|
||||||
obj_lock_map_.remove_lock_record(lock_op);
|
obj_lock_map_.remove_lock_record(lock_op);
|
||||||
if (ENABLE_USE_LOCK_WAIT_MGR) {
|
|
||||||
wakeup_waiters_(lock_op);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
LOG_DEBUG("ObLockMemtable::remove_lock_record", K(lock_op));
|
LOG_DEBUG("ObLockMemtable::remove_lock_record", K(lock_op));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -207,7 +207,6 @@ private:
|
|||||||
const ObLockID &lock_id,
|
const ObLockID &lock_id,
|
||||||
const ObTransID &conflict_tx_id,
|
const ObTransID &conflict_tx_id,
|
||||||
ObFunction<int(bool &need_wait)> &recheck_f);
|
ObFunction<int(bool &need_wait)> &recheck_f);
|
||||||
void wakeup_waiters_(const ObTableLockOp &lock_op);
|
|
||||||
private:
|
private:
|
||||||
typedef common::SpinRWLock RWLock;
|
typedef common::SpinRWLock RWLock;
|
||||||
typedef common::SpinRLockGuard RLockGuard;
|
typedef common::SpinRLockGuard RLockGuard;
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
#include "share/ob_define.h"
|
#include "share/ob_define.h"
|
||||||
#include "share/ob_errno.h"
|
#include "share/ob_errno.h"
|
||||||
#include "lib/oblog/ob_log_module.h"
|
#include "lib/oblog/ob_log_module.h"
|
||||||
|
#include "storage/memtable/ob_lock_wait_mgr.h"
|
||||||
#include "storage/tx/ob_trans_deadlock_adapter.h"
|
#include "storage/tx/ob_trans_deadlock_adapter.h"
|
||||||
#include "storage/tx/ob_trans_define.h"
|
#include "storage/tx/ob_trans_define.h"
|
||||||
#include "storage/tx/ob_trans_part_ctx.h"
|
#include "storage/tx/ob_trans_part_ctx.h"
|
||||||
@ -401,6 +402,11 @@ int ObOBJLock::update_lock_status(
|
|||||||
LOG_WARN("compact tablelock failed", K(tmp_ret), K(lock_op));
|
LOG_WARN("compact tablelock failed", K(tmp_ret), K(lock_op));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (OB_SUCC(ret) &&
|
||||||
|
lock_op.op_type_ == OUT_TRANS_UNLOCK &&
|
||||||
|
status == LOCK_OP_COMPLETE) {
|
||||||
|
wakeup_waiters_(lock_op);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LOG_DEBUG("update lock status", K(ret), K(lock_op), K(commit_version), K(status));
|
LOG_DEBUG("update lock status", K(ret), K(lock_op), K(commit_version), K(status));
|
||||||
return ret;
|
return ret;
|
||||||
@ -470,8 +476,7 @@ int ObOBJLock::lock(
|
|||||||
// something else.
|
// something else.
|
||||||
need_retry = false;
|
need_retry = false;
|
||||||
ret = OB_TRANS_KILLED;
|
ret = OB_TRANS_KILLED;
|
||||||
} else if (ENABLE_USE_LOCK_WAIT_MGR &&
|
} else if (lock_op.is_dml_lock_op() /* only dml lock will wait at lock wait mgr */) {
|
||||||
lock_op.is_dml_lock_op() /* only dml lock will wait at lock wait mgr */) {
|
|
||||||
// wait at lock wait mgr but not retry at here.
|
// wait at lock wait mgr but not retry at here.
|
||||||
need_retry = false;
|
need_retry = false;
|
||||||
} else {
|
} else {
|
||||||
@ -590,10 +595,24 @@ void ObOBJLock::remove_lock_op(
|
|||||||
drop_op_list_if_empty_(lock_op.lock_mode_,
|
drop_op_list_if_empty_(lock_op.lock_mode_,
|
||||||
op_list,
|
op_list,
|
||||||
allocator);
|
allocator);
|
||||||
|
wakeup_waiters_(lock_op);
|
||||||
}
|
}
|
||||||
LOG_DEBUG("ObOBJLock::remove_lock_op finish.");
|
LOG_DEBUG("ObOBJLock::remove_lock_op finish.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObOBJLock::wakeup_waiters_(const ObTableLockOp &lock_op)
|
||||||
|
{
|
||||||
|
// dml in trans lock does not need do this.
|
||||||
|
if (OB_LIKELY(!lock_op.need_wakeup_waiter())) {
|
||||||
|
// do nothing
|
||||||
|
} else if (OB_ISNULL(MTL(ObLockWaitMgr*))) {
|
||||||
|
LOG_WARN("MTL(ObLockWaitMgr*) is null");
|
||||||
|
} else {
|
||||||
|
MTL(ObLockWaitMgr*)->wakeup(lock_op.lock_id_);
|
||||||
|
LOG_DEBUG("ObOBJLock::wakeup_waiters_ ", K(lock_op));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int64_t ObOBJLock::get_min_ddl_lock_committed_log_ts(const int64_t flushed_log_ts) const
|
int64_t ObOBJLock::get_min_ddl_lock_committed_log_ts(const int64_t flushed_log_ts) const
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
|
|||||||
@ -155,6 +155,7 @@ private:
|
|||||||
const int64_t commit_log_ts,
|
const int64_t commit_log_ts,
|
||||||
const ObTableLockOpStatus status,
|
const ObTableLockOpStatus status,
|
||||||
ObTableLockOpList *op_list);
|
ObTableLockOpList *op_list);
|
||||||
|
void wakeup_waiters_(const ObTableLockOp &lock_op);
|
||||||
int recover_(
|
int recover_(
|
||||||
const ObTableLockOp &lock_op,
|
const ObTableLockOp &lock_op,
|
||||||
ObMalloc &allocator);
|
ObMalloc &allocator);
|
||||||
|
|||||||
@ -427,8 +427,6 @@ typedef common::ObSimpleIterator<ObLockID, ObSimpleIteratorModIds::OB_OBJ_LOCK_M
|
|||||||
// Is used to store and traverse all lock op
|
// Is used to store and traverse all lock op
|
||||||
typedef common::ObSimpleIterator<ObTableLockOp, ObSimpleIteratorModIds::OB_OBJ_LOCK, 16> ObLockOpIterator;
|
typedef common::ObSimpleIterator<ObTableLockOp, ObSimpleIteratorModIds::OB_OBJ_LOCK, 16> ObLockOpIterator;
|
||||||
|
|
||||||
// whether use lock wait mgr or not.
|
|
||||||
static const bool ENABLE_USE_LOCK_WAIT_MGR = true;
|
|
||||||
// the threshold of timeout interval which will enable the deadlock avoid.
|
// the threshold of timeout interval which will enable the deadlock avoid.
|
||||||
static const int64_t MIN_DEADLOCK_AVOID_TIMEOUT_US = 60 * 1000 * 1000; // 1 min
|
static const int64_t MIN_DEADLOCK_AVOID_TIMEOUT_US = 60 * 1000 * 1000; // 1 min
|
||||||
bool is_deadlock_avoid_enabled(const int64_t expire_time);
|
bool is_deadlock_avoid_enabled(const int64_t expire_time);
|
||||||
|
|||||||
@ -290,6 +290,7 @@ int ObTableLockService::unlock_table(const uint64_t table_id,
|
|||||||
LOG_INFO("ObTableLockService::unlock_table",
|
LOG_INFO("ObTableLockService::unlock_table",
|
||||||
K(table_id), K(lock_mode), K(lock_owner), K(timeout_us));
|
K(table_id), K(lock_mode), K(lock_owner), K(timeout_us));
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
|
DEBUG_SYNC(BEFORE_LOCK_SERVICE_UNLOCK);
|
||||||
if (IS_NOT_INIT) {
|
if (IS_NOT_INIT) {
|
||||||
ret = OB_NOT_INIT;
|
ret = OB_NOT_INIT;
|
||||||
LOG_WARN("lock service is not inited", K(ret), K(table_id), K(lock_mode),
|
LOG_WARN("lock service is not inited", K(ret), K(table_id), K(lock_mode),
|
||||||
@ -353,6 +354,7 @@ int ObTableLockService::unlock_tablet(const uint64_t table_id,
|
|||||||
const int64_t timeout_us)
|
const int64_t timeout_us)
|
||||||
{
|
{
|
||||||
int ret = OB_SUCCESS;
|
int ret = OB_SUCCESS;
|
||||||
|
DEBUG_SYNC(BEFORE_LOCK_SERVICE_UNLOCK);
|
||||||
if (IS_NOT_INIT) {
|
if (IS_NOT_INIT) {
|
||||||
ret = OB_NOT_INIT;
|
ret = OB_NOT_INIT;
|
||||||
LOG_WARN("lock service is not inited", K(ret), K(table_id), K(tablet_id),
|
LOG_WARN("lock service is not inited", K(ret), K(table_id), K(tablet_id),
|
||||||
|
|||||||
Reference in New Issue
Block a user