首批通过分布式安全可靠测评,为关键业务系统打造
ob_admin 删除表锁
更新时间:2026-06-10 09:51
在 DDL 锁泄漏、Transfer 异常导致的表锁、异常情况残留的表锁导致 DDL 卡住等异常场景下,根据 oceanbase.__all_virtual_obj_lock.create_trans_id 查询不到对应的 gv$ob_transaction_participants.tx_id 记录,无法通过 KILL SESSION 的方式释放表锁,此时可以通过 ob_admin 工具紧急修复表锁相关问题。
详细说明
步骤一:设置 ob_admin 日志路径
mkdir -p ~/.ob_admin_log
export OB_ADMIN_LOG_DIR=~/.ob_admin_log
步骤二:查询表锁
以查询 table_id 为 2498210 的表锁为例。
OceanBase 数据库 MySQL 模式:
SELECT svr_ip,svr_port,lock_id,tenant_id,ls_id,obj_type,obj_id,lock_mode,owner_id,owner_type,create_trans_id,op_type,usec_to_time(create_timestamp) FROM oceanbase.__all_virtual_obj_lock WHERE lock_id LIKE '%2498210%' ORDER BY create_timestamp;
OceanBase 数据库 Oracle 模式:
SELECT svr_ip,svr_port,lock_id,tenant_id,ls_id,obj_type,obj_id,lock_mode,owner_id,owner_type,create_trans_id,op_type,create_timestamp FROM sys.all_virtual_obj_lock WHERE lock_id LIKE '%2498210%' ORDER BY create_timestamp;
可以根据 table_id 或 tablet_id 查询对应的表名。
OceanBase 数据库 MySQL 模式:
SELECT DISTINCT database_name,table_name FROM oceanbase.dba_ob_table_locations WHERE table_id IN (SELECT obj_id FROM oceanbase.__all_virtual_obj_lock WHERE obj_type = 'TABLE' ) OR tablet_id IN (SELECT obj_id FROM oceanbase.__all_virtual_obj_lock WHERE obj_type = 'TABLET');
OceanBase 数据库 Oracle 模式:
SELECT DISTINCT database_name,table_name FROM dba_ob_table_locations WHERE table_id IN (SELECT obj_id FROM sys.all_virtual_obj_lock WHERE obj_type = 'TABLE' ) OR tablet_id IN (SELECT obj_id FROM sys.all_virtual_obj_lock WHERE obj_type = 'TABLET');
注意
OceanBase 数据库 Oracle 模式非 SYS 用户查询 dba_ob_table_locations 需要授予权限,如 GRANT SELECT ANY DITIONARY TO ALVIN。
步骤三:使用 ob_admin 删除表锁
在 svr_ip 对应的服务器上,进入如下目录。
cd /home/admin/oceanbase/bin
ob_admin 命令格式如下。
./ob_admin -S ../run/rpc.sock remove_lock {tenant_id} {ls_id} {obj_type} {obj_id} {lock_mode} {owner_id} {owner_type} {create_trans_id} {op_type}
根据表锁查询结果,并将 obj_type、lock_mode、op_type 按如下转换规则的表格将名字转换为对应的 value,转换后 ob_admin 示例如下。
./ob_admin -S ../run/rpc.sock remove_lock 1006 1 1 2498210 8 6724833815 0 6724833814 2
转换规则
具体转换规则如下。
obj_type
| name | value |
|---|---|
| TABLE | 1 |
| TABLET | 2 |
| COMMON_OBJ | 3 |
| LS | 4 |
| TENANT | 5 |
| EXTERNAL_TABLE_REFRES | 6 |
| ONLINE_DDL_TABLE | 7 |
| ONLINE_DDL_TABLET | 8 |
| DATABASE_NAME | 9 |
| OBJECT_NAME | 10 |
| DBMS_LOCK | 11 |
| MATERIALIZED_VIEW | 12 |
| MYSQL_LOCK_FUNC | 13 |
lock_mode
| name | value |
|---|---|
| X | 1 |
| S | 2 |
| RX | 4 |
| SRX | 6 |
| RS | 8 |
op_type
| name | value |
|---|---|
| IN_TRANS_DML_LOCK | 1 |
| OUT_TRANS_LOCK | 2 |
| OUT_TRANS_UNLOCK | 3 |
| IN_TRANS_LOCK_TABLE_LOCK | 4 |
批量生成 ob_admin 命令
当表有很多分区且 obj_type 为 TABLET 等情况下,可以通过如下 SQL 批量生成 ob_admin 命令。
OceanBase 数据库 MySQL 模式。
SELECT DISTINCT concat_ws(' ', './ob_admin -S ../run/rpc.sock remove_lock',tenant_id,ls_id,obj_type,obj_id,lock_mode,owner_id,owner_type,create_trans_id,op_type) cmd FROM oceanbase.__all_virtual_obj_lock WHERE lock_id LIKE '%2498210%';
OceanBase 数据库 Oracle 模式:
SELECT DISTINCT './ob_admin -S ../run/rpc.sock remove_lock'||' '||tenant_id||' '||ls_id||' '||obj_type||' '||obj_id||' '||lock_mode||' '||owner_id||' '||owner_type||' '||create_trans_id||' '||op_type cmd FROM sys.all_virtual_obj_lock WHERE lock_id LIKE '%2498210%';
注意
集群部署时多个 svr_ip 对应的 ob_admin 命令相同,需要在每个 svr_ip 服务器上执行 ob_admin 命令。
生成的 ob_admin 命令示例。
./ob_admin -S ../run/rpc.sock remove_lock 1006 1 TABLE 2498210 RS 6724833815 0 6724833814 OUT_TRANS_LOCK
将 obj_type、lock_mode、op_type 按转换规则的表格将名字批量转换为对应的 value,转换后示例如下。
./ob_admin -S ../run/rpc.sock remove_lock 1006 1 1 2498210 8 6724833815 0 6724833814 2
步骤四:再次查看表锁
同本文 步骤二:查询表锁 章节内容,查看表锁是否被成功删除。
步骤五:查看 ob_admin 日志
当表锁未被删除时,可以查看 ob_admin 日志。
vim ~/.ob_admin_log/ob_admin.log
当报错 invalid arg 时,表示传的参数不对, 如下报错日志少了 owner_type。
invalid arg(ret=-4002, arg_str.c_str()="1006 1 7 2498210 4 6724833815 6724833814 2", cmd_.c_str()
="remove_lock 1006 1 7 2498210 4 6724833815 6724833814 2", tenant_id_to_set=1006, ls_id_to_set=1, obj_type=7, obj_id=2498210, lock_mode=4,
owner_id=6724833815, owner_type=6724833814, create_tx_id=2, op_type=0, lock_op_status=1, seq_no=0, create_timestamp=0, create_schema_version=0)
步骤六:在所有服务器上执行 ob_admin 命令
集群部署时有可能在所有节点上都有表锁,需要在每个 svr_ip 服务器上执行 ob_admin 命令,多个 svr_ip 对应的 ob_admin 命令相同。
适用版本
OceanBase 数据库 V4.x