BUGFIX: fix tablelock core

This commit is contained in:
obdev
2023-01-05 05:11:50 +00:00
committed by ob-robot
parent a2ab33a2dd
commit d5b0d8c541
3 changed files with 161 additions and 42 deletions

View File

@ -166,7 +166,7 @@ int ObOBJLock::recover_(
return ret; return ret;
} }
int ObOBJLock::lock_( int ObOBJLock::slow_lock(
const ObLockParam &param, const ObLockParam &param,
const ObTableLockOp &lock_op, const ObTableLockOp &lock_op,
const ObTableLockMode &lock_mode_in_same_trans, const ObTableLockMode &lock_mode_in_same_trans,
@ -186,6 +186,7 @@ int ObOBJLock::lock_(
ObMemAttr attr(tenant_id, "ObTableLockOp"); ObMemAttr attr(tenant_id, "ObTableLockOp");
// 1. check lock conflict. // 1. check lock conflict.
// 2. record lock op. // 2. record lock op.
WRLockGuard guard(rwlock_);
if (is_deleted_) { if (is_deleted_) {
ret = OB_EAGAIN; ret = OB_EAGAIN;
need_retry = false; need_retry = false;
@ -197,12 +198,6 @@ int ObOBJLock::lock_(
if (OB_TRY_LOCK_ROW_CONFLICT != ret) { if (OB_TRY_LOCK_ROW_CONFLICT != ret) {
LOG_WARN("check allow lock failed", K(ret), K(lock_op)); 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_, } else if (OB_FAIL(get_or_create_op_list(lock_op.lock_mode_,
tenant_id, tenant_id,
allocator, allocator,
@ -416,6 +411,96 @@ int ObOBJLock::update_lock_status(const ObTableLockOp &lock_op,
return ret; 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 &param,
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( int ObOBJLock::lock(
const ObLockParam &param, const ObLockParam &param,
ObStoreCtx &ctx, ObStoreCtx &ctx,
@ -438,10 +523,8 @@ int ObOBJLock::lock(
bool need_retry = false; bool need_retry = false;
do { do {
need_retry = false; need_retry = false;
{
if (OB_LIKELY(!lock_op.need_record_lock_op())) { if (OB_LIKELY(!lock_op.need_record_lock_op())) {
RDLockGuard guard(rwlock_); if (OB_FAIL(fast_lock(param,
if (OB_FAIL(lock_(param,
lock_op, lock_op,
lock_mode_in_same_trans, lock_mode_in_same_trans,
need_retry, need_retry,
@ -452,9 +535,7 @@ int ObOBJLock::lock(
LOG_WARN("lock failed.", K(ret), K(lock_op)); LOG_WARN("lock failed.", K(ret), K(lock_op));
} }
} }
} else { } else if (OB_FAIL(slow_lock(param,
WRLockGuard guard(rwlock_);
if (OB_FAIL(lock_(param,
lock_op, lock_op,
lock_mode_in_same_trans, lock_mode_in_same_trans,
need_retry, need_retry,
@ -465,8 +546,6 @@ int ObOBJLock::lock(
LOG_WARN("lock failed.", K(ret), K(lock_op)); LOG_WARN("lock failed.", K(ret), K(lock_op));
} }
} }
}
}
if (need_retry && if (need_retry &&
ret == OB_TRY_LOCK_ROW_CONFLICT) { ret == OB_TRY_LOCK_ROW_CONFLICT) {
@ -934,15 +1013,21 @@ int ObOBJLock::check_allow_lock(
const ObTableLockMode &lock_mode_in_same_trans, const ObTableLockMode &lock_mode_in_same_trans,
ObTxIDSet &conflict_tx_set, ObTxIDSet &conflict_tx_set,
bool &conflict_with_dml_lock, bool &conflict_with_dml_lock,
ObMalloc &allocator,
const bool include_finish_tx, const bool include_finish_tx,
const bool only_check_dml_lock) const bool only_check_dml_lock)
{ {
int ret = OB_SUCCESS; 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())) { if (OB_UNLIKELY(!lock_op.is_valid())) {
ret = OB_INVALID_ARGUMENT; ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument.", K(ret), K(lock_op)); LOG_WARN("invalid argument.", K(ret), K(lock_op));
} else { } else {
// prevent from create new lock op. // prevent from create new lock op.
// may be we need compact the lock.
{
RDLockGuard guard(rwlock_); RDLockGuard guard(rwlock_);
ret = check_allow_lock_(lock_op, ret = check_allow_lock_(lock_op,
lock_mode_in_same_trans, lock_mode_in_same_trans,
@ -951,6 +1036,26 @@ int ObOBJLock::check_allow_lock(
include_finish_tx, include_finish_tx,
only_check_dml_lock); 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; return ret;
} }
@ -2042,6 +2147,7 @@ int ObOBJLockMap::check_allow_lock(
lock_mode_in_same_trans, lock_mode_in_same_trans,
conflict_tx_set, conflict_tx_set,
conflict_with_dml_lock, conflict_with_dml_lock,
allocator_,
include_finish_tx, include_finish_tx,
only_check_dml_lock))) { only_check_dml_lock))) {
if (OB_TRY_LOCK_ROW_CONFLICT != ret) { if (OB_TRY_LOCK_ROW_CONFLICT != ret) {

View File

@ -114,6 +114,7 @@ public:
const ObTableLockMode &lock_mode_in_same_trans, const ObTableLockMode &lock_mode_in_same_trans,
ObTxIDSet &conflict_tx_set, ObTxIDSet &conflict_tx_set,
bool &conflict_with_dml_lock, bool &conflict_with_dml_lock,
ObMalloc &allocator,
const bool include_finish_tx = true, const bool include_finish_tx = true,
const bool only_check_dml_lock = false); const bool only_check_dml_lock = false);
share::SCN get_min_ddl_lock_committed_scn(const share::SCN &flushed_scn) const; share::SCN get_min_ddl_lock_committed_scn(const share::SCN &flushed_scn) const;
@ -161,13 +162,25 @@ private:
int recover_( int recover_(
const ObTableLockOp &lock_op, const ObTableLockOp &lock_op,
ObMalloc &allocator); ObMalloc &allocator);
int lock_( int fast_lock(
const ObLockParam &param, const ObLockParam &param,
const ObTableLockOp &lock_op, const ObTableLockOp &lock_op,
const ObTableLockMode &lock_mode_in_same_trans, const ObTableLockMode &lock_mode_in_same_trans,
bool &need_retry, bool &need_retry,
ObMalloc &allocator, ObMalloc &allocator,
ObTxIDSet &conflict_tx_set); ObTxIDSet &conflict_tx_set);
int slow_lock(
const ObLockParam &param,
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_( int unlock_(
const ObTableLockOp &unlock_op, const ObTableLockOp &unlock_op,
ObMalloc &allocator); ObMalloc &allocator);

View File

@ -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)) { 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", "%ld %ld %ld %ld %ld %ld %ld %ld",
&tenant_id_to_set, &ls_id_to_set, &obj_type, &tenant_id_to_set, &ls_id_to_set, &obj_type,
&obj_id, &lock_mode, &owner_id, &create_tx_id, &op_type)) { &obj_id, &lock_mode, &owner_id, &create_tx_id, &op_type)) {