---
title: OceanBase 数据库 V4.2 版本，关于锁冲突问题的排查手册-OceanBase数据库使用指南
description: 了解OceanBase数据库在实际应用中关于OceanBase 数据库 V4.2 版本，关于锁冲突问题的排查手册相关的常见问题和使用技巧，帮助您快速解决OceanBase 数据库 V4.2 版本，关于锁冲突问题的排查手册的难题。
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

划线反馈

# OceanBase 数据库 V4.2 版本，关于锁冲突问题的排查手册

更新时间：2026-07-01 08:46

适用版本： V4.2.x 内容类型：TechNote  

本文以 MySQL 模式为例，介绍在 OceanBase 数据库 V4.2.x 版本中有关锁冲突问题的排查。另外在 Oracle 模式下，锁冲突问题排查和锁冲突问题处理使用的 SQL 是一样的。

## MySQL 模式下，锁冲突排查和锁冲突处理示例

1. 登录业务租户的 `test` 数据库。

   ```shell
   [admin@xxx]# mysql -h${DB_HOST} -P2883 -uroot@obmysql#obcluster -Dtest -A -p${DB_PASSWORD}

   ```
 2. 在业务租户 `test` 数据库中创建测试表。

   ```shell
   obclient [test]> CREATE TABLE tb_test_lock (c1 INT, c2 VARCHAR(20));
   Query OK, 0 rows affected (0.087 sec)

   ```
 3. 向测试表插入数据。

   ```shell
   obclient [test]> INSERT INTO tb_test_lock values(1,'row 1'),(2,'row 2'),(3,'row 3'),(4,'row 4'),(5,'row 5');
   Query OK, 5 rows affected (0.042 sec)
   Records: 5  Duplicates: 0  Warnings: 0

   ```
 4. 提交插入数据。

   ```shell
   obclient [test]> COMMIT;
   Query OK, 0 rows affected (0.035 sec)

   ```
 5. 查询测试表。

   ```shell
   obclient [test]>  SELECT now(),* FROM tb_test_lock;

   ```

   输出结果如下：

   ```shell
   +---------------------+------+-------+
   | now()               | c1   | c2    |
   +---------------------+------+-------+
   | 2024-03-14 16:14:17 |    1 | row 1 |
   | 2024-03-14 16:14:17 |    2 | row 2 |
   | 2024-03-14 16:14:17 |    3 | row 3 |
   | 2024-03-14 16:14:17 |    4 | row 4 |
   | 2024-03-14 16:14:17 |    5 | row 5 |
   +---------------------+------+-------+
   5 rows in set (0.036 sec)

   ```
 6. 打开新的 obclient 窗口会话 Session 1。

   a. 设置 SQL 最大执行时间，单位是微秒。

   ```shell
   obclient [test]> SET ob_query_timeout = 3600000000; -- 换算成秒等于 3600s。
   Query OK, 0 rows affected (0.035 sec)

   ```

   b. 设置事务超时时间，单位为微秒。

   ```shell
   obclient [test]> SET ob_trx_timeout = 3600000000; -- 换算成秒等于 3600s。
   Query OK, 0 rows affected (0.035 sec)

   ```

   c. 设置事务空闲超时时间，即事务中两条语句之间的执行间隔超过该值时超时，单位为微秒。

   ```shell
   obclient [test]> SET ob_trx_idle_timeout = 3600000000; -- 3600s
   Query OK, 0 rows affected (0.035 sec)

   ```

   d. 返回当前日期时间。

   ```shell
   obclient [test]> SELECT now();

   ```

   输出结果如下：

   ```shell
   +---------------------+
   | now()               |
   +---------------------+
    2024-03-14 16:14:32 |
   +---------------------+
   1 row in set (0.035 sec)

   ```

   e. 返回当前会话的 SESSION_ID，该 ID 是会话在客户端中的唯一标识。

   ```shell
   obclient [test]> SELECT connection_id();

   ```

   输出结果如下：

   ```shell
   +-----------------+
   | connection_id() |
   +-----------------+
   |      3222040188 |
   +-----------------+
   1 row in set (0.034 sec)

   ```

   f. 使用 `BEGIN` 显式开启一个事务，通过 `SELECT ... FOR UPDATE` 的方式为读事务的对象加锁，从而达到阻塞写事务的目的。

   ```shell
   obclient [test]> BEGIN;
   Query OK, 0 rows affected (0.035 sec)

   ```

   ```shell
   obclient [test]> SELECT * FROM tb_test_lock WHERE c1 = 1 FOR UPDATE;

   ```

   输出结果如下：

   ```shell
   +------+-------+
   | c1   | c2    |
   +------+-------+
   |    1 | row 1 |
   +------+-------+
   1 row in set (0.036 sec)

   ```
 7. 打开新的 obclient 窗口会话 Session 2。

   ```shell
   obclient [test]> SET ob_query_timeout = 3600000000; -- 换算成秒等于 3600s。
   Query OK, 0 rows affected (0.038 sec)

   ```

   ```shell
   obclient [test]> SET ob_trx_timeout = 3600000000; -- 换算成秒等于 3600s。
   Query OK, 0 rows affected (0.038 sec)

   ```

   ```shell
   obclient [test]> SET ob_trx_idle_timeout = 3600000000; -- 3600s
   Query OK, 0 rows affected (0.038 sec)

   ```

   ```

   输出结果如下：

   ```shell
   +---------------------+
   | now()               |
   +---------------------+
   | 2024-03-14 16:14:50 |
   +---------------------+
   1 row in set (0.038 sec)

   ```

   ```

   输出结果如下：

   ```shell
   +-----------------+
   | connection_id() |
   +-----------------+
   |      3222040115 |
   +-----------------+
   1 row in set (0.038 sec)

   ```

   f. 使用 `BEGIN` 显式开启一个事务，之后执行二次 DELETE 语句。

   ```shell
   obclient [test]> BEGIN;
   Query OK, 0 rows affected (0.034 sec)

   ```

   ```shell
   obclient [test]> DELETE FROM tb_test_lock WHERE c1 = 4; -- 语句 1。
   Query OK, 1 row affected (0.036 sec)

   ```

   ```shell
   obclient [test]> DELETE FROM tb_test_lock WHERE c1 = 1; -- 语句 2,执行之后无返回信息。

   ```

### 锁冲突问题排查

锁冲突排查步骤示例。

1. 登录业务租户的 `oceanbase` 数据库查询。

   ```shell
   [admin@xxx]# mysql -h${DB_HOST} -P2883 -uroot@obmysql#obcluster -Doceanbase -A -p${DB_PASSWORD}

   ```
 2. 切换当前的数据库。

   ```shell
   obclient [test]> use oceanbase;
   Database changed

   ```
 3. 当前用户各表锁情况以及表或者分区所处的位置信息。

   a. 通过 `gv$ob_locks` 视图获取持锁或请求锁的事务 ID 以及事务被阻塞信息。

   ```shell
   MySQL [oceanbase]> SELECT t.tenant_id,t.trans_id,t.type,t.id1,t.id2,t.lmode,t.request,round(t.ctime / 1000000) ctime_s,t.block FROM gv$ob_locks t WHERE t.block = 1 ORDER BY t.trans_id;

   ```

   输出结果如下：

   ```shell
   +-----------+----------+------+----------+--------------------------------+-------+---------+---------+-------+
   | tenant_id | trans_id | type | id1      | id2                            | lmode | request | ctime_s | block |
   +-----------+----------+------+----------+--------------------------------+-------+---------+---------+-------+
   |      1002 | 23723243 | TR   |   200051 | 23723237-{"BIGINT UNSIGNED":1} | NONE  | X       |      20 |     1 |
   |      1002 | 23723243 | TX   | 23723237 | NULL                           | NONE  | X       |      20 |     1 |
   +-----------+----------+------+----------+--------------------------------+-------+---------+---------+-------+
   2 rows in set (0.014 sec)

   ```

   b. 通过持有锁的事务 `tablet_id` 的值，查询 `dba_ob_table_locations` 表，获取表或分区所在的 Zone 和 IP 地址和端口号，副本角色，数据库名等信息。

   ```shell
   MySQL [oceanbase]> SELECT zone,svr_ip,svr_port,role,tablet_id，database_name,table_name FROM dba_ob_table_locations WHERE tablet_id = 200051 ORDER BY zone,svr_ip,svr_port;

   ```

   输出结果如下：

   ```shell
   +-------+---------------+----------+----------+-----------+---------------+--------------+
   | zone  | svr_ip        | svr_port | role     | tablet_id | database_name | table_name   |
   +-------+---------------+----------+----------+-----------+---------------+--------------+
   | zone1 | xx.xx.xx.xx   |     2882 | FOLLOWER |    200051 | test          | tb_test_lock |
   | zone2 | xx.xx.xx.xx   |     2882 | FOLLOWER |    200051 | test          | tb_test_lock |
   | zone3 | xx.xx.xx.xx   |     2882 | LEADER   |    200051 | test          | tb_test_lock |
   +-------+---------------+----------+----------+-----------+---------------+--------------+
   3 rows in set (0.075 sec)

   ```

   综上通过 `gv$ob_locks` 视图（用于显示当前用户各表持锁或请求锁的情况。）以及表`dba_ob_table_locations` （展示表或者分区所在的位置，包括：系统表、用户表、索引表等。），获取关于锁冲突方面的信息便于排查锁冲突问题。

   视图（`gv$ob_locks`）与表（`dba_ob_table_locations`）中涉及锁冲突相关的字段含义如下：

      - `gv$ob_locks.trans_id` 为被 block 的 `trans_id`。
      - `gv$ob_locks.type` 为 `TX` 的记录中，`gv$ob_locks.id1` 为当前持有锁的 `trans_id`。
      - `gv$ob_locks.type` 为 `TR` 的记录中，`gv$ob_locks.id1` 为当前被锁的对象的 `dba_ob_table_locations.tablet_id`，`gv$ob_locks.id2` 为被锁的行。

   可知以上示例排查步骤 4 中，`trans_id` 为 `23723243` 是被 block 的事务，`trans_id` 为 `23723237` 是持有锁的事务。
 4. 通过字段 `tx_id` 的值（即步骤 3 中获取的 `trans_id` 值。），查询视图 `gv$ob_transaction_participants` 获取 `session_id` 值。

   ```shell
   MySQL [oceanbase]> SELECT round(now() - t.ctx_create_time)  running_time_s,t.tenant_id,t.svr_ip,t.svr_port,t.session_id,t.tx_type,t.tx_id,t.state,t.action,t.ctx_create_time,t.last_request_time FROM gv$ob_transaction_participants t WHERE t.tx_id IN (23723243, 23723237);

   ```

   输出结果如下：

   ```shell
   +----------------+-----------+---------------+----------+------------+-----------+----------+--------+--------+----------------------------+----------------------------+
   | running_time_s | tenant_id | svr_ip        | svr_port | session_id | tx_type   | tx_id    | state  | action | ctx_create_time            | last_request_time          |
   +----------------+-----------+---------------+----------+------------+-----------+----------+--------+--------+----------------------------+----------------------------+
   |             83 |      1002 | xx.xx.xx.xx   |     2882 | 3222040115 | UNDECIDED | 23723243 | ACTIVE | START  | 2024-03-14 16:14:28.764186 | 2024-03-14 16:15:10.533369 |
   |             94 |      1002 | xx.xx.xx.xx   |     2882 | 3222040188 | UNDECIDED | 23723237 | ACTIVE | START  | 2024-03-14 16:14:17.961048 | 2024-03-14 16:14:17.961048 |
   +----------------+-----------+---------------+----------+------------+-----------+----------+--------+--------+----------------------------+----------------------------+
   2 rows in set (0.019 sec)

   ```
 5. 通过字段 `id`（会话 ID 的值，即步骤 4 中获取的 `session_id` 值。），查询视图 `gv$ob_processlist` 获取会话信息。

   ```shell
   MySQL [oceanbase]> SELECT t.svr_ip,t.svr_port,t.id,t.host,t.db,t.tenant,t.command,t.time,t.state,t.info,t.user_client_ip,t.retry_cnt,t.retry_info,t.trans_id,t.trans_state FROM gv$ob_processlist t WHERE t.id IN (3222040115, 3222040188);

   ```

   输出结果如下：

   ```shell
   +---------------+----------+------------+------+---------------------+------+---------+---------+------+-------+------+----------------+-----------+------------+----------+-------------+
   | svr_ip        | svr_port | id         | user | host                | db   | tenant  | command | time | state | info | user_client_ip | retry_cnt | retry_info | trans_id | trans_state |
   +---------------+----------+------------+------+---------------------+------+---------+---------+------+-------+------+----------------+-----------+------------+----------+-------------+
   | xx.xx.xx.xx   |     2882 | 3222040188 | root | xx.xx.xx.xx:xxxxx   | test | obmysql | Sleep   |   84 | SLEEP | NULL | xx.xx.xx.xx    |         0 |          0 | 23723237 | ACTIVE      |
   | xx.xx.xx.xx   |     2882 | 3222040115 | root | xx.xx.xx.xx:xxxxx   | test | obmysql | Sleep   |    2 | SLEEP | NULL | xx.xx.xx.xx    |        24 |      -6005 | 23723243 | ACTIVE      |
   +---------------+----------+------------+------+---------------------+------+---------+---------+------+-------+------+----------------+-----------+------------+----------+-------------+
   2 rows in set (0.007 sec)

   ```

   可知以上示例排查步骤 5 中，`session_id` 为 `3222040115` 是被 block 的 session，`session_id` 为 `3222040188` 是持有锁的 session。
 6. 通过字段 `sid` 的值（即步骤 5 中获取的 `session_id` 值。），查询视图 `gv$ob_sql_audit` 分析执行过的历史 SQL。该步骤的表的记录，可能会随时刷掉，因此可能查询为空集。

   ```shell
   MySQL [oceanbase]> SELECT usec_to_time(request_time) request_time_s,t.svr_ip ip,t.svr_port port,t.tenant_id,t.trace_id,t.sid,t.ret_code,t.elapsed_time / 1000000 elapsed_time_s,t.query_sql FROM gv$ob_sql_audit t WHERE sid IN (3222040115, 3222040188) ORDER BY request_time;

   ```

   输出结果如下：

   ```shell
   +----------------------------+---------------+------+-----------+-----------------------------------+------------+----------+-----------------+----------------------------------------------------+
   | request_time_s             | ip            | port | tenant_id | trace_id                          | sid        | ret_code | elapsed_time(s) | query_sql                                          |
   +----------------------------+---------------+------+-----------+-----------------------------------+------------+----------+-----------------+----------------------------------------------------+
   | 2024-03-14 16:14:17.957421 | xx.xx.xx.xx   | 2882 |      1002 | xxxxxxxxxxxx-xxxxxxxxxxxxxxxx-0-0 | 3222040188 |        0 |          0.0003 | SET @_min_cluster_version = '4.2.1.3';             |
   | 2024-03-14 16:14:17.958552 | xx.xx.xx.xx   | 2882 |      1002 | xxxxxxxxxxxx-xxxxxxxxxxxxxxxx-0-0 | 3222040188 |        0 |          0.0002 | BEGIN                                              |
   | 2024-03-14 16:14:17.959404 | xx.xx.xx.xx   | 2882 |      1002 | xxxxxxxxxxxx-xxxxxxxxxxxxxxxx-0-0 | 3222040188 |        0 |          0.0023 | SELECT * FROM tb_test_lock WHERE c1 = 1 FOR UPDATE |
   | 2024-03-14 16:14:28.761535 | xx.xx.xx.xx   | 2882 |      1002 | xxxxxxxxxxxx-xxxxxxxxxxxxxxxx-0-0 | 3222040115 |        0 |          0.0003 | SET @_min_cluster_version = '4.2.1.3';             |
   | 2024-03-14 16:14:28.762309 | xx.xx.xx.xx   | 2882 |      1002 | xxxxxxxxxxxx-xxxxxxxxxxxxxxxx-0-0 | 3222040115 |        0 |          0.0001 | BEGIN                                              |
   | 2024-03-14 16:14:28.762747 | xx.xx.xx.xx   | 2882 |      1002 | xxxxxxxxxxxx-xxxxxxxxxxxxxxxx-0-0 | 3222040115 |        0 |          0.0021 | DELETE FROM tb_test_lock WHERE c1 = 4              |
   +----------------------------+---------------+------+-----------+-----------------------------------+------------+----------+-----------------+----------------------------------------------------+
   6 rows in set (0.199 sec)

   ```

### 锁冲突问题处理

结合业务，根据 **锁冲突问题排查** 一节，分析造成锁的原因。必要情况下可从应用层面停止持有锁的相关操作等。

生产环境紧急情况下，与 OceanBase 技术支持确认后，可考虑执行如下 SQL。

- 如果持有锁的 session （`gv$ob_processlist.id` = 3222040188）中，`gv$ob_processlist.state` 为 `ACTIVE` 且 `gv$ob_processlist.command` 不为 `Sleep`，可以考虑执行 `KILL QUERY 3222040188` 终止连接当前正在执行的语句。

  ```shell
  id: 3222040188
  command: Query
  state: ACTIVE
  info: SELECT sleep(30)

  ```

  a. 终止连接当前正在执行的语句 (但是会保持连接)。

  ```shell
  MySQL [oceanbase]> KILL QUERY 3222040188;

  ```

  b. 被 `KILL QUERY` 的 session 报错如下。

  ```shell
  MySQL [test]> SELECT sleep(20);
  ERROR 1317 (70100): Query execution was interrupted

  ```
 - 如果持有锁的 session （`gv$ob_processlist.id` = 3222040188）中， `gv$ob_processlist.state` 为 `ACTIVE` 且 `gv$ob_processlist.command` 为 `Sleep`，可以考虑执行 `KILL 3222040188` 终止连接。

  ```shell
  id: 3222040188
  command: Sleep
  state: SLEEP
  info: NULL

  ```

  a. 终止连接。

  ```shell
  MySQL [oceanbase]> KILL 3222040188;

  ```

  b. 被 `KILL` 的 session 报错如下。

  ```shell
  MySQL [test]> SELECT now();
  ERROR 2013 (HY000): Lost connection to MySQL server during query

  ```

  ```shell
  MySQL [test]> SELECT now();
  ERROR 2006 (HY000): MySQL server has gone away
  No connection. Trying to reconnect...
  Connection id:    3221670379
  Current database: test

  ```

  输出结果如下：

  ```shell
  +---------------------+
  | now()               |
  +---------------------+
  | 2024-03-14 16:21:47 |
  +---------------------+
  1 row in set (0.005 sec)

  ```

  #### 注意

  锁冲突问题处理中`3222040188` 为持有锁的 `session_id`。

## 适用版本

OceanBase 数据库 V4.2.x 版本。

上一篇

[如何统计正在运行的事务](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000004409028)

下一篇

[租户 ssstore_read IO 响应异常 Callback、Enqueue 性能优化](https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000006298389) ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
