BUGFIX: fix tablelock core
This commit is contained in:
@ -166,7 +166,7 @@ int ObOBJLock::recover_(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOBJLock::lock_(
|
||||
int ObOBJLock::slow_lock(
|
||||
const ObLockParam ¶m,
|
||||
const ObTableLockOp &lock_op,
|
||||
const ObTableLockMode &lock_mode_in_same_trans,
|
||||
@ -186,6 +186,7 @@ int ObOBJLock::lock_(
|
||||
ObMemAttr attr(tenant_id, "ObTableLockOp");
|
||||
// 1. check lock conflict.
|
||||
// 2. record lock op.
|
||||
WRLockGuard guard(rwlock_);
|
||||
if (is_deleted_) {
|
||||
ret = OB_EAGAIN;
|
||||
need_retry = false;
|
||||
@ -197,12 +198,6 @@ int ObOBJLock::lock_(
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
|
||||
LOG_WARN("check allow lock failed", K(ret), K(lock_op));
|
||||
}
|
||||
} else if (OB_LIKELY(!lock_op.need_record_lock_op())) {
|
||||
if (lock_op.lock_mode_ == ROW_EXCLUSIVE) {
|
||||
lock_row_exclusive_();
|
||||
} else if (lock_op.lock_mode_ == ROW_SHARE) {
|
||||
lock_row_share_();
|
||||
}
|
||||
} else if (OB_FAIL(get_or_create_op_list(lock_op.lock_mode_,
|
||||
tenant_id,
|
||||
allocator,
|
||||
@ -416,6 +411,96 @@ int ObOBJLock::update_lock_status(const ObTableLockOp &lock_op,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOBJLock::try_fast_lock_(
|
||||
const ObTableLockOp &lock_op,
|
||||
const ObTableLockMode &lock_mode_in_same_trans,
|
||||
bool &need_retry,
|
||||
ObTxIDSet &conflict_tx_set)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
bool unused_conflict_with_dml_lock = false;
|
||||
if (is_deleted_) {
|
||||
ret = OB_EAGAIN;
|
||||
need_retry = false;
|
||||
} else if (OB_UNLIKELY(lock_op.need_record_lock_op())) {
|
||||
ret = OB_ERR_UNEXPECTED;
|
||||
LOG_WARN("this lock op should not do fast lock", KR(ret), K(lock_op));
|
||||
} else if (OB_FAIL(check_allow_lock_(lock_op,
|
||||
lock_mode_in_same_trans,
|
||||
conflict_tx_set,
|
||||
unused_conflict_with_dml_lock))) {
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
|
||||
LOG_WARN("check allow lock failed", K(ret), K(lock_op));
|
||||
}
|
||||
} else {
|
||||
if (lock_op.lock_mode_ == ROW_EXCLUSIVE) {
|
||||
lock_row_exclusive_();
|
||||
} else if (lock_op.lock_mode_ == ROW_SHARE) {
|
||||
lock_row_share_();
|
||||
}
|
||||
LOG_DEBUG("succeed create lock ", K(lock_op));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOBJLock::fast_lock(
|
||||
const ObLockParam ¶m,
|
||||
const ObTableLockOp &lock_op,
|
||||
const ObTableLockMode &lock_mode_in_same_trans,
|
||||
bool &need_retry,
|
||||
ObMalloc &allocator,
|
||||
ObTxIDSet &conflict_tx_set)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
bool is_compacted = false;
|
||||
const bool is_force_compact = true;
|
||||
{
|
||||
// lock first time
|
||||
RDLockGuard guard(rwlock_);
|
||||
if (OB_FAIL(try_fast_lock_(lock_op,
|
||||
lock_mode_in_same_trans,
|
||||
need_retry,
|
||||
conflict_tx_set))) {
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
|
||||
LOG_WARN("try fast lock failed", KR(ret), K(lock_op));
|
||||
}
|
||||
} else {
|
||||
LOG_DEBUG("succeed create lock ", K(lock_op));
|
||||
}
|
||||
}
|
||||
// compact if need.
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT == ret) {
|
||||
WRLockGuard guard(rwlock_);
|
||||
if (is_deleted_) {
|
||||
ret = OB_EAGAIN;
|
||||
need_retry = false;
|
||||
} else if(OB_TMP_FAIL(compact_tablelock_(allocator, is_compacted, is_force_compact))) {
|
||||
// compact the obj lock to make sure the lock op that need compact will
|
||||
// not block the lock operation next time.
|
||||
LOG_WARN("compact tablelock failed", K(tmp_ret), K(lock_op));
|
||||
}
|
||||
}
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT == ret && is_compacted) {
|
||||
RDLockGuard guard(rwlock_);
|
||||
if (OB_FAIL(try_fast_lock_(lock_op,
|
||||
lock_mode_in_same_trans,
|
||||
need_retry,
|
||||
conflict_tx_set))) {
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
|
||||
LOG_WARN("try fast lock failed", KR(ret), K(lock_op));
|
||||
}
|
||||
} else {
|
||||
LOG_DEBUG("succeed create lock ", K(lock_op));
|
||||
}
|
||||
}
|
||||
// 1. need retry basic conditions
|
||||
if (ret == OB_TRY_LOCK_ROW_CONFLICT && !param.is_try_lock_) {
|
||||
need_retry = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ObOBJLock::lock(
|
||||
const ObLockParam ¶m,
|
||||
ObStoreCtx &ctx,
|
||||
@ -438,10 +523,8 @@ int ObOBJLock::lock(
|
||||
bool need_retry = false;
|
||||
do {
|
||||
need_retry = false;
|
||||
{
|
||||
if (OB_LIKELY(!lock_op.need_record_lock_op())) {
|
||||
RDLockGuard guard(rwlock_);
|
||||
if (OB_FAIL(lock_(param,
|
||||
if (OB_FAIL(fast_lock(param,
|
||||
lock_op,
|
||||
lock_mode_in_same_trans,
|
||||
need_retry,
|
||||
@ -452,9 +535,7 @@ int ObOBJLock::lock(
|
||||
LOG_WARN("lock failed.", K(ret), K(lock_op));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WRLockGuard guard(rwlock_);
|
||||
if (OB_FAIL(lock_(param,
|
||||
} else if (OB_FAIL(slow_lock(param,
|
||||
lock_op,
|
||||
lock_mode_in_same_trans,
|
||||
need_retry,
|
||||
@ -465,8 +546,6 @@ int ObOBJLock::lock(
|
||||
LOG_WARN("lock failed.", K(ret), K(lock_op));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (need_retry &&
|
||||
ret == OB_TRY_LOCK_ROW_CONFLICT) {
|
||||
@ -934,15 +1013,21 @@ int ObOBJLock::check_allow_lock(
|
||||
const ObTableLockMode &lock_mode_in_same_trans,
|
||||
ObTxIDSet &conflict_tx_set,
|
||||
bool &conflict_with_dml_lock,
|
||||
ObMalloc &allocator,
|
||||
const bool include_finish_tx,
|
||||
const bool only_check_dml_lock)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
int tmp_ret = OB_SUCCESS;
|
||||
bool is_compacted = false;
|
||||
const bool is_force_compact = true;
|
||||
if (OB_UNLIKELY(!lock_op.is_valid())) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("invalid argument.", K(ret), K(lock_op));
|
||||
} else {
|
||||
// prevent from create new lock op.
|
||||
// may be we need compact the lock.
|
||||
{
|
||||
RDLockGuard guard(rwlock_);
|
||||
ret = check_allow_lock_(lock_op,
|
||||
lock_mode_in_same_trans,
|
||||
@ -951,6 +1036,26 @@ int ObOBJLock::check_allow_lock(
|
||||
include_finish_tx,
|
||||
only_check_dml_lock);
|
||||
}
|
||||
// compact if need.
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT == ret) {
|
||||
WRLockGuard guard(rwlock_);
|
||||
if(OB_TMP_FAIL(compact_tablelock_(allocator, is_compacted, is_force_compact))) {
|
||||
// compact the obj lock to make sure the lock op that need compact will
|
||||
// not block the lock operation next time.
|
||||
LOG_WARN("compact tablelock failed", K(tmp_ret), K(lock_op));
|
||||
}
|
||||
}
|
||||
// recheck if compacted
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT == ret && is_compacted) {
|
||||
RDLockGuard guard(rwlock_);
|
||||
ret = check_allow_lock_(lock_op,
|
||||
lock_mode_in_same_trans,
|
||||
conflict_tx_set,
|
||||
conflict_with_dml_lock,
|
||||
include_finish_tx,
|
||||
only_check_dml_lock);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2042,6 +2147,7 @@ int ObOBJLockMap::check_allow_lock(
|
||||
lock_mode_in_same_trans,
|
||||
conflict_tx_set,
|
||||
conflict_with_dml_lock,
|
||||
allocator_,
|
||||
include_finish_tx,
|
||||
only_check_dml_lock))) {
|
||||
if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
|
||||
|
||||
@ -114,6 +114,7 @@ public:
|
||||
const ObTableLockMode &lock_mode_in_same_trans,
|
||||
ObTxIDSet &conflict_tx_set,
|
||||
bool &conflict_with_dml_lock,
|
||||
ObMalloc &allocator,
|
||||
const bool include_finish_tx = true,
|
||||
const bool only_check_dml_lock = false);
|
||||
share::SCN get_min_ddl_lock_committed_scn(const share::SCN &flushed_scn) const;
|
||||
@ -161,13 +162,25 @@ private:
|
||||
int recover_(
|
||||
const ObTableLockOp &lock_op,
|
||||
ObMalloc &allocator);
|
||||
int lock_(
|
||||
int fast_lock(
|
||||
const ObLockParam ¶m,
|
||||
const ObTableLockOp &lock_op,
|
||||
const ObTableLockMode &lock_mode_in_same_trans,
|
||||
bool &need_retry,
|
||||
ObMalloc &allocator,
|
||||
ObTxIDSet &conflict_tx_set);
|
||||
int slow_lock(
|
||||
const ObLockParam ¶m,
|
||||
const ObTableLockOp &lock_op,
|
||||
const ObTableLockMode &lock_mode_in_same_trans,
|
||||
bool &need_retry,
|
||||
ObMalloc &allocator,
|
||||
ObTxIDSet &conflict_tx_set);
|
||||
int try_fast_lock_(
|
||||
const ObTableLockOp &lock_op,
|
||||
const ObTableLockMode &lock_mode_in_same_trans,
|
||||
bool &need_retry,
|
||||
ObTxIDSet &conflict_tx_set);
|
||||
int unlock_(
|
||||
const ObTableLockOp &unlock_op,
|
||||
ObMalloc &allocator);
|
||||
|
||||
@ -626,7 +626,7 @@ DEF_COMMAND(TRANS, remove_lock, 1, "tenant_id ls_id obj_type obj_id lock_mode ow
|
||||
}
|
||||
|
||||
if (OB_FAIL(ret)) {
|
||||
} else if (12 != sscanf(arg_str.c_str(),
|
||||
} else if (8 != sscanf(arg_str.c_str(),
|
||||
"%ld %ld %ld %ld %ld %ld %ld %ld",
|
||||
&tenant_id_to_set, &ls_id_to_set, &obj_type,
|
||||
&obj_id, &lock_mode, &owner_id, &create_tx_id, &op_type)) {
|
||||
|
||||
Reference in New Issue
Block a user