BUGFIX: optimize the tablelock conflict log

This commit is contained in:
obdev 2024-10-30 13:45:07 +00:00 committed by ob-robot
parent 8a422ad27d
commit 9380029845
4 changed files with 255 additions and 144 deletions

View File

@ -1086,12 +1086,16 @@ int ObOBJLock::check_allow_lock_(
// get all the conflict tx id that lock mode conflict with me
// but not myself
int tmp_ret = OB_SUCCESS;
if (OB_SUCCESS != (tmp_ret = get_tx_id_set_(lock_op.create_trans_id_,
conflict_modes,
include_finish_tx,
conflict_tx_set))) {
if (OB_TMP_FAIL(get_tx_id_set_(lock_op.create_trans_id_,
conflict_modes,
include_finish_tx,
conflict_tx_set))) {
LOG_WARN("get conflict tx failed", K(tmp_ret), K(lock_op));
}
if (REACH_TIME_INTERVAL(1 * 1000 * 1000)) {
LOG_WARN("obj_lock conflict with others", K(ret), KNN(curr_lock, lock_op), KNN(conflict_tx, conflict_tx_set),
K(conflict_modes));
}
}
// for pre check
if (OB_TRY_LOCK_ROW_CONFLICT == ret && only_check_dml_lock) {
@ -1650,6 +1654,12 @@ int ObOBJLock::check_op_allow_lock_from_list_(
// can not lock with the same lock mode twice.
ret = OB_TRY_LOCK_ROW_CONFLICT;
need_break = true;
if (OB_TRY_LOCK_ROW_CONFLICT == ret) {
if (REACH_TIME_INTERVAL(1 * 1000 * 1000)) {
LOG_WARN("obj_lock conflict with itself", K(ret), KNN(curr_lock, lock_op),
KNN(older_lock, curr->lock_op_));
}
}
} else if (curr->lock_op_.lock_op_status_ == LOCK_OP_COMPLETE) {
// need continue to check unlock op
ret = OB_OBJ_LOCK_EXIST;
@ -1663,6 +1673,12 @@ int ObOBJLock::check_op_allow_lock_from_list_(
ret = OB_TRY_LOCK_ROW_CONFLICT;
has_unlock_op = true;
need_break = true;
if (OB_TRY_LOCK_ROW_CONFLICT == ret) {
if (REACH_TIME_INTERVAL(1 * 1000 * 1000)) {
LOG_WARN("obj_lock conflict with itself", K(ret), KNN(curr_lock, lock_op),
KNN(older_lock, curr->lock_op_));
}
}
} else if (curr->lock_op_.op_type_ == IN_TRANS_COMMON_LOCK &&
curr->lock_op_.create_trans_id_ == lock_op.create_trans_id_) {
// continue

View File

@ -28,6 +28,102 @@ namespace tablelock
constexpr const char ObSimpleIteratorModIds::OB_OBJ_LOCK[];
constexpr const char ObSimpleIteratorModIds::OB_OBJ_LOCK_MAP[];
const char *get_name(const ObTableLockPriority intype)
{
const char *type_name = "UNKNOWN";
switch (static_cast<const uint64_t>(intype)) {
#define DEF_LOCK_PRIORITY(n, type) \
case n: \
type_name = #type; \
break;
#include "ob_table_lock_def.h"
#undef DEF_LOCK_PRIORITY
default:
break;
}
return type_name;
}
const char *get_name(const ObTableLockMode intype)
{
const char *type_name = "U";
switch (intype) {
#define DEF_LOCK_MODE(n, type, name) \
case n: \
type_name = #name; \
break;
#include "ob_table_lock_def.h"
#undef DEF_LOCK_MODE
default:
break;
}
return type_name;
}
const char *get_name(const ObTableLockOpType intype)
{
const char *type_name = "UNKNOWN_TYPE";
switch (static_cast<const uint64_t>(intype)) {
#define DEF_LOCK_OP_TYPE(n, type) \
case n: \
type_name = #type; \
break;
#include "ob_table_lock_def.h"
#undef DEF_LOCK_OP_TYPE
default:
break;
}
return type_name;
}
const char *get_name(const ObTableLockOpStatus intype)
{
const char *type_name = "UNKNOWN";
switch (static_cast<const uint64_t>(intype)) {
#define DEF_LOCK_OP_STATUS(n, type) \
case n: \
type_name = #type; \
break;
#include "ob_table_lock_def.h"
#undef DEF_LOCK_OP_STATUS
default:
break;
}
return type_name;
}
const char *get_name(const ObLockOBJType intype)
{
const char *type_name = "UNKNOWN";
switch (static_cast<const uint64_t>(intype)) {
#define DEF_OBJ_TYPE(n, type) \
case n: \
type_name = #type; \
break;
#include "ob_table_lock_def.h"
#undef DEF_OBJ_TYPE
default:
break;
}
return type_name;
}
const char *get_name(const ObLockOwnerType intype)
{
const char *type_name = "UNKNOWN";
switch (static_cast<const uint64_t>(intype)) {
#define DEF_LOCK_OWNER_TYPE(n, type) \
case n: \
type_name = #type; \
break;
#include "ob_table_lock_def.h"
#undef DEF_LOCK_OWNER_TYPE
default:
break;
}
return type_name;
}
bool is_deadlock_avoid_enabled(const bool is_from_sql, const int64_t timeout_us)
{
return (!is_from_sql && timeout_us >= MIN_DEADLOCK_AVOID_TIMEOUT_US);

View File

@ -21,6 +21,8 @@
#include "share/ob_common_id.h"
#include "storage/tx/ob_trans_define.h"
// KNN means print the value x with a new name
#define KNN(name, x) #name, ::oceanbase::common::check_char_array(x)
namespace oceanbase
{
@ -43,11 +45,12 @@ struct ObObjLockPriorityTaskID
enum class ObTableLockPriority : int8_t
{
INVALID = -1,
HIGH1 = 0,
HIGH2 = 10,
NORMAL = 20,
LOW = 30,
#define DEF_LOCK_PRIORITY(n, type) \
type = n,
#include "ob_table_lock_def.h"
#undef DEF_LOCK_PRIORITY
};
const char *get_name(const ObTableLockPriority intype);
// Lock compatibility matrix:
//
@ -64,12 +67,11 @@ enum class ObTableLockPriority : int8_t
typedef unsigned char ObTableLockMode;
static const char TABLE_LOCK_MODE_COUNT = 5;
static const unsigned char NO_LOCK = 0x0; // binary 0000
static const unsigned char ROW_SHARE = 0x8; // binary 1000
static const unsigned char ROW_EXCLUSIVE = 0x4; // binary 0100
static const unsigned char SHARE = 0x2; // binary 0010
static const unsigned char SHARE_ROW_EXCLUSIVE = 0x6; // binary 0110, SHARE | ROW_EXCLUSIVE
static const unsigned char EXCLUSIVE = 0x1; // binary 0001
#define DEF_LOCK_MODE(n, type, name) \
static const unsigned char type = n;
#include "ob_table_lock_def.h"
#undef DEF_LOCK_MODE
static const unsigned char MAX_LOCK_MODE = 0xf;
// Each item occupies 4 bits, stand for ROW SHARE, ROW EXCLUSIVE, SHARE, EXCLUSIVE.
@ -78,27 +80,14 @@ static const unsigned char compatibility_matrix[] = { 0x0, /* EXCLUSIVE : 000
0xc, /* ROW EXCLUSIVE: 1100 */
0xe /* ROW SHARE : 1110 */ };
const char *get_name(const ObTableLockMode intype);
static inline
int lock_mode_to_string(const ObTableLockMode lock_mode,
char *str,
const int64_t str_len)
{
int ret = OB_SUCCESS;
if (NO_LOCK == lock_mode) {
strncpy(str ,"N", str_len);
} else if (ROW_SHARE == lock_mode) {
strncpy(str ,"RS", str_len);
} else if (ROW_EXCLUSIVE == lock_mode) {
strncpy(str ,"RX", str_len);
} else if (SHARE == lock_mode) {
strncpy(str ,"S", str_len);
} else if (SHARE_ROW_EXCLUSIVE == lock_mode) {
strncpy(str ,"SRX", str_len);
} else if (EXCLUSIVE == lock_mode) {
strncpy(str ,"X", str_len);
} else {
ret = OB_INVALID_ARGUMENT;
}
strncpy(str, get_name(lock_mode), str_len);
return ret;
}
@ -185,60 +174,42 @@ bool request_lock(ObTableLockMode curr_lock,
enum ObTableLockOpType : char
{
UNKNOWN_TYPE = 0,
IN_TRANS_DML_LOCK = 1, // will be unlock if we do callback
OUT_TRANS_LOCK = 2, // will be unlock use OUT_TRANS_UNLOCK
OUT_TRANS_UNLOCK = 3,
IN_TRANS_COMMON_LOCK = 4,
TABLET_SPLIT = 5,
#define DEF_LOCK_OP_TYPE(n, type) \
type = n,
#include "ob_table_lock_def.h"
#undef DEF_LOCK_OP_TYPE
MAX_VALID_LOCK_OP_TYPE,
};
const char *get_name(const ObTableLockOpType intype);
static inline
int lock_op_type_to_string(const ObTableLockOpType op_type,
char *str,
const int64_t str_len)
{
int ret = OB_SUCCESS;
if (UNKNOWN_TYPE == op_type) {
strncpy(str ,"UNKNOWN_TYPE", str_len);
} else if (IN_TRANS_DML_LOCK == op_type) {
strncpy(str ,"IN_TRANS_DML_LOCK", str_len);
} else if (OUT_TRANS_LOCK == op_type) {
strncpy(str ,"OUT_TRANS_LOCK", str_len);
} else if (OUT_TRANS_UNLOCK == op_type) {
strncpy(str ,"OUT_TRANS_UNLOCK", str_len);
} else if (IN_TRANS_COMMON_LOCK == op_type) {
strncpy(str ,"IN_TRANS_COMMON_LOCK", str_len);
} else if (TABLET_SPLIT == op_type) {
strncpy(str ,"TABLET_SPLIT", str_len);
} else {
ret = OB_INVALID_ARGUMENT;
}
strncpy(str, get_name(op_type), str_len);
return ret;
}
enum ObTableLockOpStatus : char
{
UNKNOWN_STATUS = 0,
LOCK_OP_DOING = 1,
LOCK_OP_COMPLETE
#define DEF_LOCK_OP_STATUS(n, type) \
LOCK_OP_##type = n,
#include "ob_table_lock_def.h"
#undef DEF_LOCK_OP_STATUS
};
const char *get_name(const ObTableLockOpStatus intype);
static inline
int lock_op_status_to_string(const ObTableLockOpStatus op_status,
char *str,
const int64_t str_len)
{
int ret = OB_SUCCESS;
if (UNKNOWN_STATUS == op_status) {
strncpy(str ,"UNKNOWN", str_len);
} else if (LOCK_OP_DOING == op_status) {
strncpy(str ,"DOING", str_len);
} else if (LOCK_OP_COMPLETE == op_status) {
strncpy(str ,"COMPLETE", str_len);
} else {
ret = OB_INVALID_ARGUMENT;
}
strncpy(str, get_name(op_status), str_len);
return ret;
}
@ -277,90 +248,23 @@ bool is_op_status_valid(const ObTableLockOpStatus status)
enum class ObLockOBJType : char
{
OBJ_TYPE_INVALID = 0,
OBJ_TYPE_TABLE = 1, // table
OBJ_TYPE_TABLET = 2, // tablet
OBJ_TYPE_COMMON_OBJ = 3, // common_obj
OBJ_TYPE_LS = 4, // for ls
OBJ_TYPE_TENANT = 5, // for tenant
OBJ_TYPE_EXTERNAL_TABLE_REFRESH = 6, // for external table
OBJ_TYPE_ONLINE_DDL_TABLE = 7, // online ddl table
OBJ_TYPE_ONLINE_DDL_TABLET = 8, // online ddl tablets
OBJ_TYPE_DATABASE_NAME = 9, // for database related ddl
OBJ_TYPE_OBJECT_NAME = 10, // for obj related ddl
OBJ_TYPE_DBMS_LOCK = 11, // for dbms lock
OBJ_TYPE_MATERIALIZED_VIEW = 12, // for materialized view operations
OBJ_TYPE_MYSQL_LOCK_FUNC = 13, // for mysql lock function
OBJ_TYPE_REFRESH_VECTOR_INDEX = 14,
#define DEF_OBJ_TYPE(n, type) \
OBJ_TYPE_##type = n,
#include "ob_table_lock_def.h"
#undef DEF_OBJ_TYPE
OBJ_TYPE_MAX
};
const char *get_name(const ObLockOBJType obj_type);
static inline
int lock_obj_type_to_string(const ObLockOBJType obj_type,
char *str,
const int64_t str_len)
{
int ret = OB_SUCCESS;
switch (obj_type) {
case ObLockOBJType::OBJ_TYPE_TABLE: {
strncpy(str, "TABLE", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_TABLET: {
strncpy(str, "TABLET", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_COMMON_OBJ: {
strncpy(str, "COMMON_OBJ", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_LS: {
strncpy(str, "LS", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_TENANT: {
strncpy(str, "TENANT", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_EXTERNAL_TABLE_REFRESH: {
strncpy(str, "EXTERNAL_TABLE_REFRES", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLE: {
strncpy(str, "ONLINE_DDL_TABLE", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_ONLINE_DDL_TABLET: {
strncpy(str, "ONLINE_DDL_TABLET", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_DATABASE_NAME: {
strncpy(str, "DATABASE_NAME", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_OBJECT_NAME: {
strncpy(str, "OBJECT_NAME", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_DBMS_LOCK: {
strncpy(str, "DBMS_LOCK", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_MATERIALIZED_VIEW: {
strncpy(str, "MATERIALIZED_VIEW", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_MYSQL_LOCK_FUNC: {
strncpy(str, "MYSQL_LOCK_FUNC", str_len);
break;
}
case ObLockOBJType::OBJ_TYPE_REFRESH_VECTOR_INDEX: {
strncpy(str, "REFRESH_VECTOR_INDEX", str_len);
break;
}
default: {
strncpy(str, "UNKNOWN", str_len);
}
}
strncpy(str, get_name(obj_type), str_len);
return ret;
}
@ -429,7 +333,9 @@ public:
obj_id_ = common::OB_INVALID_ID;
hash_value_ = 0;
}
TO_STRING_KV(K_(obj_type), K_(obj_id));
TO_STRING_KV(KNN("type", obj_type_),
"type_str", get_name(obj_type_),
KNN("id", obj_id_));
NEED_SERIALIZE_AND_DESERIALIZE;
public:
ObLockOBJType obj_type_;
@ -448,15 +354,17 @@ int get_lock_id(const ObIArray<ObTabletID> &tablets,
// typedef share::ObCommonID ObTableLockOwnerID;
enum class ObLockOwnerType : unsigned char {
DEFAULT_OWNER_TYPE = 0,
SESS_ID_OWNER_TYPE = 1,
#define DEF_LOCK_OWNER_TYPE(n, type) \
type##_OWNER_TYPE = n,
#include "ob_table_lock_def.h"
#undef DEF_LOCK_OWNER_TYPE
// make sure this is smaller than INVALID_OWNER_TYPE
MAX_OWNER_TYPE,
INVALID_OWNER_TYPE = 255,
};
const char *get_name(const ObLockOwnerType intype);
static inline
bool is_lock_owner_type_valid(const ObLockOwnerType &type)
{
@ -537,7 +445,9 @@ public:
uint64_t hash() const
{ return pack_; }
NEED_SERIALIZE_AND_DESERIALIZE;
TO_STRING_KV(K_(pack), K_(type), K_(id), K_(reserved), K_(valid_flag));
TO_STRING_KV(K_(pack), K_(type),
"type_name", get_name(static_cast<ObLockOwnerType>(type_)),
K_(id), K_(reserved), K_(valid_flag));
private:
union {
struct {
@ -650,8 +560,13 @@ private:
lock_mode_ == EXCLUSIVE);
}
public:
TO_STRING_KV(K_(lock_id), K_(lock_mode), K_(owner_id), K_(create_trans_id),
K_(op_type), K_(lock_op_status), K_(lock_seq_no),
TO_STRING_KV(K_(lock_id), K_(lock_mode),
"lock_mode_name", get_name(lock_mode_),
K_(owner_id), K_(create_trans_id), K_(op_type),
"op_type_name", get_name(op_type_),
K_(lock_op_status),
"lock_op_status_name", get_name(lock_op_status_),
K_(lock_seq_no),
K_(commit_version), K_(commit_scn), K_(create_timestamp),
K_(create_schema_version));
@ -694,7 +609,8 @@ public:
bool is_valid() const
{ return ObTableLockPriority::INVALID != priority_ && lock_op_.is_valid(); }
public:
TO_STRING_KV(K_(lock_op), K_(priority));
TO_STRING_KV(K_(lock_op), K_(priority),
"priority_name", get_name(priority_));
public:
ObTableLockOp lock_op_;
ObTableLockPriority priority_;
@ -711,7 +627,8 @@ public:
: priority_(priority) {}
bool is_valid() const { return ObTableLockPriority::INVALID != priority_; }
public:
TO_STRING_KV(K_(priority));
TO_STRING_KV(K_(priority),
"priority_name", get_name(priority_));
public:
ObTableLockPriority priority_;
};

View File

@ -0,0 +1,82 @@
/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
// DEF_LOCK_PRIORITY(n, type)
// the type will be #type, the type value will be n
// the name will be #type
#ifdef DEF_LOCK_PRIORITY
DEF_LOCK_PRIORITY(0, HIGH1)
DEF_LOCK_PRIORITY(10, HIGH2)
DEF_LOCK_PRIORITY(20, NORMAL)
DEF_LOCK_PRIORITY(30, LOW)
#endif
// DEF_LOCK_MODE(n, type, name)
// the type will be #type, the type value will be n
// the name will be #name
#ifdef DEF_LOCK_MODE
DEF_LOCK_MODE(0x0, NO_LOCK, N)
DEF_LOCK_MODE(0x8, ROW_SHARE, RS)
DEF_LOCK_MODE(0x4, ROW_EXCLUSIVE, RX)
DEF_LOCK_MODE(0x2, SHARE, S)
DEF_LOCK_MODE(0x6, SHARE_ROW_EXCLUSIVE, SRX)
DEF_LOCK_MODE(0x1, EXCLUSIVE, X)
#endif
// DEF_LOCK_OP_TYPE(n, type)
// the type will be type
// the type name will be #type
#ifdef DEF_LOCK_OP_TYPE
DEF_LOCK_OP_TYPE(1, IN_TRANS_DML_LOCK)
DEF_LOCK_OP_TYPE(2, OUT_TRANS_LOCK)
DEF_LOCK_OP_TYPE(3, OUT_TRANS_UNLOCK)
DEF_LOCK_OP_TYPE(4, IN_TRANS_COMMON_LOCK)
DEF_LOCK_OP_TYPE(5, TABLET_SPLIT)
#endif
// DEF_LOCK_OP_STATUS(n, type)
// the type will be LOCK_OP_##type
// the type name will be #type
#ifdef DEF_LOCK_OP_STATUS
DEF_LOCK_OP_STATUS(1, DOING)
DEF_LOCK_OP_STATUS(2, COMPLETE)
#endif
// DEF_OBJ_TYPE(n, type)
// the type will be OBJ_TYPE_##type
// the type name will be #type
// WARNNING: the type name should less than 24
#ifdef DEF_OBJ_TYPE
DEF_OBJ_TYPE(1, TABLE)
DEF_OBJ_TYPE(2, TABLET)
DEF_OBJ_TYPE(3, COMMON_OBJ)
DEF_OBJ_TYPE(4, LS)
DEF_OBJ_TYPE(5, TENANT)
DEF_OBJ_TYPE(6, EXTERNAL_TABLE_REFRESH)
DEF_OBJ_TYPE(7, ONLINE_DDL_TABLE)
DEF_OBJ_TYPE(8, ONLINE_DDL_TABLET)
DEF_OBJ_TYPE(9, DATABASE_NAME) // for database related ddl
DEF_OBJ_TYPE(10, OBJECT_NAME) // for obj related ddl
DEF_OBJ_TYPE(11, DBMS_LOCK)
DEF_OBJ_TYPE(12, MATERIALIZED_VIEW)
DEF_OBJ_TYPE(13, MYSQL_LOCK_FUNC)
DEF_OBJ_TYPE(14, REFRESH_VECTOR_INDEX)
#endif
// DEF_LOCK_OWNER_TYPE(n, type)
// the type will be type##_OWNER_TYPE
// the name will be #type
#ifdef DEF_LOCK_OWNER_TYPE
DEF_LOCK_OWNER_TYPE(0, DEFAULT)
DEF_LOCK_OWNER_TYPE(1, SESS_ID)
#endif