找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

5792

积分

0

好友

713

主题
发表于 4 天前 | 查看: 4| 回复: 0

核心结论

  1. GV$OB_LOCKS.SESSION_ID 是事务调度器层面的 session id,与 gv$ob_processlist.ID 不是同一层概念。两者通过 TRANS_ID 桥接,不能直接用 SESSION_ID 等值 JOIN。
  2. GV$OB_LOCKS 视图 SQL 明确定义:等待者行的 ID1 = HOLDER_TRANS_IDID2 = HOLDER_SESSION_ID(持有者事务调度器 session)。
  3. KILL 命令分模式:MySQL 模式用 KILL QUERY/KILL(参数是 id),Oracle 模式用 ALTER SYSTEM KILL SESSION(参数是 id,@SVR_IP:SVR_PORT)。

一、概述

本文围绕 OceanBase V4.2.x 的行锁(per-row lock)冲突排障,覆盖以下几个模块:

  • 关键视图速查(GV$OB_LOCKS、gv$ob_processlist、ASH、事务相关视图)
  • 三大 Session ID 之谜(核心陷阱)
  • 行锁快速定位 SQL 模板(MySQL 模式 + Oracle 模式)
  • 实战案例还原
  • KILL 命令速查(按模式分)
  • 常见坑与最佳实践

适用版本:V4.2.x
内容类型:TechNote
适用范围:OceanBase 数据库 V4.2.x 行锁模式(per-row lock),同时覆盖 MySQL 模式与 Oracle 模式。

MySQL 模式与 Oracle 模式的区别:锁排查、锁处理使用的 SQL 逻辑完全相同,仅以下三点有差异:

  1. 取当前会话 SESSION_ID:MySQL 模式用 connection_id(),Oracle 模式用 USERENV('SID')
  2. 视图名大小写:MySQL 模式小写(gv$ob_locks),Oracle 模式大写(GV$OB_LOCKS)——视图本身同义
  3. KILL 命令语法:见第 8 节

二、OB 行锁机制

2.1 锁结构

  • 锁存储:OBServer 进程内存
  • 锁粒度:tablet_id + rowkey(主键定位)
  • 索引行锁:主键 / 唯一索引 / 二级索引行都会持锁

2.2 锁类型(GV$OB_LOCKS TYPE)

TYPE 名称 含义 模式
TR Table Row 行锁(具体行) X
TX Transaction 事务锁(事务状态保护) X
TM Table/Object 表级/对象锁 RX
UL DBMS_LOCK 用户自定义锁

2.3 锁模式

  • X:排他锁(写)
  • RX:行级排他(TM 表锁)
  • 等待者:REQUEST=X 且 LMODE=NONE
  • 持有者:LMODE=X 且 REQUEST=NONE

三、关键视图速查

3.1 GV$OB_LOCKS(核心)

字段 含义
SVR_IP / SVR_PORT 锁所在节点
TENANT_ID 租户 ID
TRANS_ID 当前事务 ID(等待者行:等待者自己的 trans_id;持有者行:持有者自己的 trans_id)
SESSION_ID 事务调度器 session id(非 OBServer session)
TYPE TR / TX / TM / UL
ID1 等待者行HOLDER_TRANS_ID(持有者 trans_id);持有者行:自己的 TRANS_ID
ID2 等待者行HOLDER_SESSION_ID(持有者事务调度器 session);持有者行:自己的事务调度器 session
ID3 TR 行:"TABLET_ID-ROWKEY"(如 200022-{"NUMBER":"1"});TX 行:NULL;TM 行:table_id
LMODE 持有锁模式(X / RX
REQUEST 申请锁模式(X / RX / NONE
CTIME 持有/等待时长(微秒,需 /1000000 转秒)
BLOCK 1=等待者,0=持有者

⚠️ 官方文档描述 vs 实际视图 SQL 的差异:

官方文档对 TYPE=TR 的描述是 "ID1=tablet_id, ID2=rowkey"——但 V4.2.x 实际视图 SQL(SYS.ALL_VIRTUAL_LOCK_WAIT_STAT 派生部分)等待者行 ID1 是 HOLDER_TRANS_ID、ID2 是 HOLDER_SESSION_ID,不是 tablet_id/rowkey。应以本环境实际视图 SQL 为准(参考第 10 节视图 SQL 解读)。

排查时建议同时结合 ID3 字段(TR 行包含 TABLET_ID-ROWKEY 信息)来定位具体行。

3.2 gv$ob_processlist

字段 含义
ID OBServer 内部 session id(应用层 session,可 KILL)
PROXY_SESSID OBProxy 会话 ID
TRANS_ID 当前事务 ID(与 GV$OB_LOCKS 关联的桥梁)
TRANS_STATE ACTIVE / IMPLICIT_ACTIVE / ROLLBACK
SQL_ID 当前 SQL
INFO SQL 文本
STATE ACTIVE / SLEEP

3.3 gv$active_session_history

字段 含义
session_id 事务调度器 session id(不是 processlist 的 ID)
BLOCKING_SESSION_ID 阻塞者的事务调度器 session id
SESSION_STATE WAITING / ON CPU
event row lock wait

3.4 GV$OB_TRANSACTION_PARTICIPANTS / GV$OB_TRANSACTION_SCHEDULERS

字段 含义
TX_ID 事务 ID
SESSION_ID 事务调度器 session id
ROLE LEADER / FOLLOWER
STATE ACTIVE / COMMITTED / ABORTED
LAST_REQUEST_TIME 最后一次操作时间(判断长事务)
TX_EXPIRED_TIME 事务过期时间
CTX_CREATE_TIME 事务上下文创建时间
ACTION START / COMMIT / ABORT

3.5 dba_ob_table_locations(辅助定位)

字段 含义
TABLET_ID tablet 编号(与 GV$OB_LOCKS.ID3 中的 TABLET_ID 对应)
ZONE 所在 Zone
SVR_IP / SVR_PORT 节点 IP/端口
ROLE 副本角色(LEADER / FOLLOWER
DATABASE_NAME / TABLE_NAME 数据库名/表名

用途:从 GV$OB_LOCKS.ID3 解析出 tablet_id 后,反查此表得到表/分区所在位置,便于跨节点排查。

四、多层 Session ID 之谜

4.1 多层 Session ID 区分

层级 字段来源 含义 案例值
客户端层(MySQL 模式) connection_id() 业务连接 session(MySQL 协议) 3222040188
客户端层(Oracle 模式) USERENV('SID') 业务连接 session(Oracle 协议) 284713
OBProxy 层 PROXY_SESSID OBProxy 内部会话 ID 12399…
OBServer 层 gv$ob_processlist.ID OBServer 内部 session(可 KILL 284713 / 3222040188
事务调度器层 GV$OB_LOCKS.SESSION_ID 事务调度器 session(不可 KILL 3221692919
历史层(ASH) gv$active_session_history.session_id 采样的 session 3221692919

4.2 关键关系(本案验证)

关联 方法 案例验证
connection_id() / USERENV('SID')gv$ob_processlist.ID 直接相同 284713 = 284713
gv$ob_processlist.IDgv$ob_processlist.TRANS_ID 同一记录字段 284713 持有 31007974
GV$OB_LOCKS.SESSION_IDgv$ob_processlist.ID 不能直接 JOIN 3221692919 ≠ 284713(无映射
GV$OB_LOCKS.ID1(等待者行)↔ gv$ob_processlist.TRANS_ID 通过 TRANS_ID 关联 31007974 = 31007974
gv$active_session_history.BLOCKING_SESSION_ID 事务调度器 session 3221692919(要去事务视图找)

4.3 翻译路径

路径 A:GV$OB_LOCKS → gv$ob_processlist(推荐)

GV$OB_LOCKS.BLOCK=1 的等待者行
   ↓ 提取 ID1(持有者 TRANS_ID = 31007974)
gv$ob_processlist WHERE TRANS_ID = 31007974
   ↓ 得到应用层 ID = 284713
KILL 284713;   -- MySQL 模式
ALTER SYSTEM KILL SESSION '284713,@192.168.56.213:2882' TENANT = orcl;   -- Oracle 模式

路径 B:GV$OB_LOCKS → GV$OB_TRANSACTION_PARTICIPANTS → gv$ob_processlist(参考官方文档路径)

GV$OB_LOCKS.BLOCK=1 的等待者行
   ↓ 提取 ID1(持有者 TRANS_ID = 31007974)
GV$OB_TRANSACTION_PARTICIPANTS WHERE TX_ID = 31007974
   ↓ 得到事务调度器 session_id = 3221692919
gv$ob_processlist WHERE ID = 3221692919
   ↓ (本环境验证返回 Empty set,路径 B 在本环境可能不成立)

⚠️ 路径 B 的风险:参考官方文档走的是这条路径,但在本案例中验证 gv$ob_processlist WHERE ID = 3221692919 返回 Empty set——这是因为本环境中 GV$OB_LOCKS.SESSION_ID 是事务调度器 ID,不直接对应 gv$ob_processlist.ID。应以本环境实际行为为准,优先使用路径 A(TRANS_ID 关联)。

五、行锁快速定位 SQL 模板

Step 0:排查前超时设置(防误超时退出)

无论是阻塞者还是等待者,排查过程中可能耗时较长,先在两个 session 都设置超时时间,避免排查过程中连接被自动断开:

MySQL 模式:

SET ob_query_timeout = 3600000000;       -- SQL 最大执行时间(3600s)
SET ob_trx_timeout = 3600000000;         -- 事务超时(3600s)
SET ob_trx_idle_timeout = 3600000000;    -- 事务空闲超时(3600s)

Oracle 模式:

ALTER SESSION SET ob_query_timeout = 3600000000;
ALTER SESSION SET ob_trx_timeout = 3600000000;
ALTER SESSION SET ob_trx_idle_timeout = 3600000000;

Step 1:发现行锁等待(业务租户或 sys 租户)

-- 关键过滤:BLOCK=1(等待者)
SELECT SVR_IP, SVR_PORT, TENANT_ID, TRANS_ID, SESSION_ID, TYPE,
       ID1, ID2, ID3, LMODE, REQUEST,
       ROUND(CTIME / 1000000) AS CTIME_S, BLOCK
FROM GV$OB_LOCKS
WHERE BLOCK = 1 -- 等待者
AND CTIME > 10000000 -- 等待超过 10 秒(CTIME 单位是微秒)
ORDER BY CTIME DESC;

记下:

  • 等待者 TRANS_ID
  • 持有者 ID1(持有者 TRANS_ID)
  • 持有者 ID2(持有者事务调度器 session)
  • 持有者 ID3(解析 TABLET_ID-ROWKEY

Step 2:通过 tablet_id 反查表/分区位置(可选)

-- 从 ID3 解析出 tablet_id(去掉 ROWKEY 部分),反查表/分区位置
SELECT zone, svr_ip, svr_port, role, tablet_id, database_name, table_name
FROM dba_ob_table_locations
WHERE tablet_id = <TABLET_ID> -- 从 ID3 解析
ORDER BY zone, svr_ip, svr_port;

Step 3:定位阻塞者应用层 session(路径 A,TRANS_ID 关联)

SELECT svr_ip, svr_port, ID, user, tenant, time, total_time,
       state, PROXY_SESSID, SQL_ID, TRANS_ID, TRANS_STATE, INFO
FROM gv$ob_processlist
WHERE TRANS_ID = '<持有者TRANS_ID>';   -- 本案:31007974

Step 4:等待事件和 ASH 验证

SELECT SVR_IP, session_id, SESSION_STATE, event, BLOCKING_SESSION_ID
FROM gv$active_session_history
WHERE sql_id = '<等待者SQL_ID>'
AND SESSION_STATE = 'WAITING'
AND event = 'row lock wait'
ORDER BY sample_time DESC
LIMIT 20;

Step 5:阻塞者事务详情

SELECT * FROM GV$OB_TRANSACTION_PARTICIPANTS WHERE tx_id = '<持有者TRANS_ID>';
SELECT * FROM GV$OB_TRANSACTION_SCHEDULERS  WHERE tx_id = '<持有者TRANS_ID>';

Step 6:历史 SQL 追溯(可能为空)

-- 用 gv$ob_processlist.ID(应用层 session)追溯历史 SQL
SELECT usec_to_time(request_time) AS request_time_s,
       t.svr_ip AS ip, t.svr_port AS port, t.tenant_id, t.trace_id, t.sid,
       t.ret_code, t.elapsed_time / 1000000 AS elapsed_time_s, t.query_sql
FROM gv$ob_sql_audit t
WHERE sid IN (<应用层session_id_1>, <应用层session_id_2>)
ORDER BY request_time;

⚠️ gv$ob_sql_audit 记录在内存中,可能随时被淘汰,结果可能为空集。

Step 7:决策与处置(按模式分 KILL 命令)

见第 8 节。

六、实战案例还原

6.1 现场

  • 租户:orcl(Oracle 模式)
  • 表:tab1
  • SESSION 1(USERENV('SID')=284713):持有锁
  • SESSION 2(USERENV('SID')=297086):等待锁
  • 环境版本:V4.2.x

6.2 排查过程

Step 1:从 GV$OB_LOCKS 拿持有者 TRANS_ID

SELECT * FROM GV$OB_LOCKS;
ROLE TRANS_ID SESSION_ID TYPE LMODE REQUEST BLOCK 含义
等待者 31008008 3221700502 TR NONE X 1 SESSION 2 事务 31008008 等锁
阻塞者 31007974 3221692919 TR X NONE 0 事务 31007974 持锁
- 31007974 3221692919 TX X NONE 0 事务锁
- 31007974 3221692919 TM RX NONE 0 表锁

持有者 TRANS_ID = 31007974(来自等待者行 ID1)。

Step 2:从 sys 租户查 processlist(用 TRANS_ID 关联)

SELECT * FROM gv$ob_processlist WHERE TRANS_ID = 31007974;
ID USER STATE TRANS_ID TRANS_STATE
284713 SYS SLEEP 31007974 IMPLICIT_ACTIVE

找到阻塞者应用层 session:ID=284713。

6.3 Session ID 对应关系图

┌──────────────────────────────────┐
│  USERENV('SID') = 284713         │  ← Oracle 模式客户端视角
│  / connection_id() = 284713      │  ← MySQL 模式客户端视角
└──────────────┬───────────────────┘
               │ (相同)
┌──────────────▼───────────────────┐
│  gv$ob_processlist.ID = 284713   │  ← OBServer 内部 session(可 KILL)
│  TRANS_ID = 31007974             │  ← 关联桥梁
└──────────────┬───────────────────┘
               │ (TRANS_ID 关联)
┌──────────────▼───────────────────┐
│  GV$OB_TRANSACTION_SCHEDULERS    │
│    .SESSION_ID = 3221692919      │  ← 事务调度器 session(不可 KILL)
│  GV$OB_TRANSACTION_PARTICIPANTS  │
│    .SESSION_ID = 3221692919      │
│  GV$OB_LOCKS.ID2 = 3221692919    │
└──────────────┬───────────────────┘
               │
┌──────────────▼───────────────────┐
│  gv$active_session_history       │
│    .BLOCKING_SESSION_ID =        │
│     3221692919                   │  ← 同样是事务调度器 session
└──────────────────────────────────┘

6.4 反向验证(多视角交叉确认)

视角 过滤条件 阻塞者标识
GV$OB_LOCKS(持有者行) BLOCK=0 TRANS_ID=31007974, SESSION_ID=3221692919
gv$ob_processlist TRANS_ID=31007974 ID=284713
gv$ob_session ID=284713 TENANT=orcl, TRANS_ID=31007974
GV$OB_TRANSACTION_SCHEDULERS TX_ID=31007974 SESSION_ID=3221692919
GV$OB_TRANSACTION_PARTICIPANTS TX_ID=31007974 SESSION_ID=3221692919, ROLE=LEADER

七、一键定位脚本(终极版)

-- 一条 SQL 找出所有行锁阻塞的完整链路
SELECT
    L.SVR_IP                        AS lock_svr_ip,
    L.SVR_PORT                      AS lock_svr_port,
    L.TENANT_ID,
    L.ID1                           AS holder_trans_id,
    L.ID2                           AS holder_scheduler_sid,
    L.ID3                           AS rowkey,
    L.CTIME / 1000000               AS wait_seconds,
    P.ID                            AS holder_ob_sid,
    P.USER                          AS holder_user,
    P.HOST                          AS holder_host,
    P.PROXY_SESSID                  AS holder_proxy_sid,
    P.INFO                          AS holder_sql,
    P.STATE                         AS holder_state,
    P.TIME                          AS holder_idle_seconds,
    P.SVR_IP                        AS holder_svr_ip
FROM GV$OB_LOCKS L
LEFT JOIN gv$ob_processlist P
       ON P.TRANS_ID = L.ID1
      AND P.SVR_IP   = L.SVR_IP
      AND P.TENANT_ID = L.TENANT_ID
WHERE L.BLOCK = 1
  AND L.CTIME > 10000000            -- 10 秒以上
ORDER BY L.CTIME DESC;

八、KILL 命令速查(按模式分)

8.1 决策矩阵

阻塞者状态 MySQL 模式命令 Oracle 模式命令
STATE=ACTIVECOMMAND=Query(正在执行 SQL) KILL QUERY <id>; ALTER SYSTEM KILL QUERY '<id>,@<SVR_IP>:<SVR_PORT>' TENANT = <tenant>;
STATE=ACTIVECOMMAND=Sleep(空闲连接持锁) KILL <id>; ALTER SYSTEM KILL SESSION '<id>,@<SVR_IP>:<SVR_PORT>' TENANT = <tenant>;
长事务彻底回滚 KILL <id>; + 监控回滚 ALTER SYSTEM KILL SESSION ...; + 监控回滚

8.2 MySQL 模式示例

-- 终止当前正在执行的语句(保持连接)
KILL QUERY 3222040188;

-- 终止整个连接
KILL 3222040188;

-- 被 KILL 后的客户端表现
-- KILL QUERY:ERROR 1317 (70100): Query execution was interrupted
-- KILL:ERROR 2013 (HY000): Lost connection to MySQL server during query

8.3 Oracle 模式示例

-- 终止当前正在执行的语句(保持连接)
ALTER SYSTEM KILL QUERY '284713,@192.168.56.213:2882' TENANT = orcl;

-- 终止整个连接
ALTER SYSTEM KILL SESSION '284713,@192.168.56.213:2882' TENANT = orcl;

关键点:

  • KILL 参数中的 id 是 gv$ob_processlist.ID(不是 GV$OB_LOCKS.SESSION_ID)
  • 必须指定 SVR_IP(MySQL 模式可选,Oracle 模式必填)
  • 多租户环境必须 TENANT = <tenant>

8.4 本案例 KILL 命令

-- 阻塞者 ID=284713,SVR_IP=192.168.56.213,租户 orcl
-- MySQL 模式:
KILL 284713;

-- Oracle 模式:
ALTER SYSTEM KILL SESSION '284713,@192.168.56.213:2882' TENANT = orcl;

九、常见坑与最佳实践

9.1 常见坑

坑 1:SESSION_ID 直接 JOIN 错乱

-- 错误 ❌:GV$OB_LOCKS.SESSION_ID ≠ gv$ob_processlist.ID
SELECT * FROM GV$OB_LOCKS L
JOIN gv$ob_processlist P
ON L.SESSION_ID = P.ID;

坑 2:从 ASH 找阻塞者直接查 processlist.ID

-- 错误 ❌:Empty set
SELECT * FROM gv$ob_processlist
WHERE ID = (SELECT BLOCKING_SESSION_ID FROM gv$active_session_history ...);
-- BLOCKING_SESSION_ID 是事务调度器 session,不在 processlist 中

坑 3:KILL 错对象

  • KILL 事务调度器 session(3221692919):无效
  • KILL 应用层 session(284713):正确

坑 4:MySQL 模式误用 Oracle 模式 KILL 语法

-- 错误 ❌:MySQL 模式不应使用 ALTER SYSTEM KILL SESSION
ALTER SYSTEM KILL SESSION '284713,@192.168.56.213:2882' TENANT = orcl;

-- 正确:MySQL 模式
KILL 284713;

坑 5:误判长事务

  • gv$ob_processlist.TIME 大但 TRANS_STATE=SLEEP:可能只是空闲连接
  • 真正长事务用 GV$OB_TRANSACTION_PARTICIPANTS.LAST_REQUEST_TIME 判定

坑 6:CTIME 单位混淆

  • GV$OB_LOCKS.CTIME 单位是微秒,需 /1000000 转秒
  • gv$ob_processlist.TIME 单位是

9.2 最佳实践

  1. 诊断时通过 TRANS_ID 关联,不直接 JOIN SESSION_ID
  2. KILL 用 gv$ob_processlist.ID(不是事务调度器 session)
  3. 排查前设置超时时间(避免排查过程中连接被自动断开)
  4. 行锁监控告警基于 GV$OB_LOCKS
-- 超过 60 秒的行锁等待
SELECT * FROM GV$OB_LOCKS WHERE BLOCK = 1 AND CTIME > 60000000;
  1. 预防措施
  • 事务及时提交(避免长事务)
  • 批量 DML 分批提交
  • 应用层加超时控制
  • 高频更新行考虑应用层排队(乐观锁 / 版本号)
  • 监控 GV$OB_LOCKS BLOCK=1 的 CTIME 增长

十、速查流程(5 步法)

┌─────────────────────────────────────────────────────────────┐
│  Step 1: GV$OB_LOCKS WHERE BLOCK=1                           │
│  → 拿持有者 ID1(TRANS_ID)和等待者 SESSION_ID               │
│  → 拿 ID3 解析 TABLET_ID-ROWKEY                              │
└────────────────────────┬────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────────┐
│  Step 2 (可选): dba_ob_table_locations WHERE tablet_id=...  │
│  → 反查表/分区位置(zone、svr_ip、role)                    │
└────────────────────────┬────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────────┐
│  Step 3: gv$ob_processlist WHERE TRANS_ID = ID1             │
│  → 拿应用层 ID(可 KILL 的 session)和 SVR_IP                │
└────────────────────────┬────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────────┐
│  Step 4: 验证 ID=284713 的 INFO/SQL_ID/USER                 │
│  → 业务/重要操作 → 联系;空闲/慢 SQL → KILL                  │
└────────────────────────┬────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────────┐
│  Step 5: KILL(按模式分)                                    │
│  MySQL 模式:    KILL QUERY <id> | KILL <id>                  │
│  Oracle 模式:   ALTER SYSTEM KILL SESSION 'id,@ip:port'...  │
└────────────────────────┬────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────────────┐
│  Step 6: 等待者自动唤醒,ASH/SQL_AUDIT 复盘根因              │
└─────────────────────────────────────────────────────────────┘

十一、附:GV$OB_LOCKS 视图 SQL 解读

SELECT text FROM dba_views WHERE view_name = 'GV$OB_LOCKS';

返回的是 4 个 UNION ALL

# 来源表 TYPE BLOCK 含义
1 ALL_VIRTUAL_LOCK_WAIT_STAT TR 1 等待者(只有这一类 BLOCK=1)
2 ALL_VIRTUAL_TRANS_LOCK_STAT (ROWKEY NOT NULL) TR 0 行锁持有者
3 ALL_VIRTUAL_TRANS_LOCK_STAT (GROUP BY) TX 0 事务锁持有者
4 ALL_VIRTUAL_OBJ_LOCK JOIN 事务视图 TM/UL 0 对象/表锁持有者

第 1 部分(等待者)关键字段:

SELECT SVR_IP, SVR_PORT, TENANT_ID, TRANS_ID, SESSION_ID,
       'TR' AS TYPE,
       HOLDER_TRANS_ID AS ID1,        -- 持有者 trans_id
       HOLDER_SESSION_ID AS ID2,      -- 持有者事务调度器 session
       CONCAT(TABLET_ID, '-', ROWKEY) AS ID3,
       'NONE' AS LMODE,
       LOCK_MODE AS REQUEST,
       TIME_AFTER_RECV AS CTIME,
       1 AS BLOCK
FROM SYS.ALL_VIRTUAL_LOCK_WAIT_STAT

重要细节:

  • 第 1 部分(等待者)SESSION_ID 是等待者自己;ID1/ID2持有者的 TRANS_ID/SESSION_ID
  • 第 2/3/4 部分(持有者)SESSION_IDID1ID2 都是自己的
  • 第 2 部分(行锁持有者)ID3CONCAT(TABLET_ID, '-', ROWKEY)

所以一个完整的"锁链"在 GV$OB_LOCKS 中表现为:

  • 1 条 BLOCK=1 等待者行(ID1/ID2 指持有者)
  • N 条 BLOCK=0 持有者行(同 TRANS_ID

十二、一句话总结

在 OB V4 行锁模式中,GV$OB_LOCKS.SESSION_ID 是事务调度器 session,gv$ob_processlist.ID 是应用层 session,两者通过 TRANS_ID 桥接。要 KILL 阻塞会话,始终用 gv$ob_processlist 中通过 TRANS_ID 查到的 ID + SVR_IPMySQL 模式用 KILL QUERY/KILL,Oracle 模式用 ALTER SYSTEM KILL SESSION

这套排查思路在 V4.2.x 系列环境验证有效。如果你在 OceanBase 或分布式数据库运维中还遇到过其他疑难锁问题,也欢迎到 云栈社区 与更多 DBA 同行交流实战经验。




上一篇:Jane Street低延迟系统抖动优化实战:从637ns到163ns的调优全过程
下一篇:MySQL 8.0 InnoDB 哪条 DDL 操作不会锁表?附解析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-8-26 11:28 , Processed in 0.926973 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表