首批通过分布式安全可靠测评,为关键业务系统打造
等待事件
更新时间:2025-08-21 10:22:16
在 OceanBase 数据库中,我们使用等待事件(Wait Event)来标记一个活跃会话处于等待状态。等待事件用于记录工作线程在进行 CPU 计算或等待的状态,如等待 IO、等待网络、等待临界区等情况。通过记录和统计等待事件,可以帮助识别系统的性能瓶颈,特别是对于高并发小查询的性能场景。等待事件在性能分析中扮演重要的角色,帮助优化系统性能。
使用场景
常见有以下的几个典型场景:
当前系统不管负载如何增加,CPU 使用率一直比较低,通常是因为系统中存在某些并发瓶颈,比如热点的临界区等,通过记录这些临界区上等待的持续时间,可以定位这一问题(Top Wait)。
业务 SQL 通常 RT<1ms,但是偶尔会有 >100ms 的尖刺,发生这种问题的原因,通常是因为 SQL 在执行中被卡在了什么地方,记录这条 SQL 执行过程中的等待,特别是时间最长的那条等待的详细信息,可以定位这一问题(Max Wait)。
系统突然停止执行,发生这种问题的原因,通常是因为某些会话被阻塞了,比如有热点行,或者发生了某种未知原因的死锁,通过记录会话当前正在等待的详细信息,可以定位这一问题(Current Wait)。
等待事件属性
每个等待事件包含以下属性:
- 等待事件名称。
- 等待时间:每次等待事件持续了多久。
- parameter1(p1)、parameter2(p2)、parameter3(p3): 每个等待事件会带有三个额外的等待事件参数,这些参数提供了关于等待事件的额外信息,帮助深入了解等待发生的上下文和原因。
等待事件类型
等待事件可以根据它们所表示的资源或操作类型被分为几个类别。这种分类有助于数据库管理员在诊断和解决性能问题时更清晰地识别问题领域:
| 等待事件所属类型名称 | 等待类别编号 ID | 描述 |
|---|---|---|
| OTHER | 100 | 不属于其他类型的等待事件 |
| APPLICATION | 101 | 由于客户端代码导致的等待事件 |
| CONFIGURATION | 102 | 由于数据库或实例资源配置不足而导致的等待事件 |
| ADMINISTRATIVE | 103 | 由于数据库管理员输入命令导致用户等待的等待事件 |
| CONCURRENCY | 104 | 等待数据库内部资源的等待事件 |
| COMMIT | 105 | 在日志提交有关的等待事件 |
| IDLE | 106 | 会话处于非活动状态,等待任务的等待事件 |
| NETWORK | 107 | 与网络通信相关的等待事件 |
| USER_IO | 108 | 等待用户 I/O 的等待事件 |
| SYSTEM_IO | 109 | 等待后台进程 I/O 的等待事件 |
| CLUSTER | 111 | 与集群相关的等待事件 |
OceanBase 数据库目前已有 11 个大类,300 多个等待事件,涵盖网络、调度、临界区、锁、集群、事务提交、用户 IO(用户直接引发的 IO 等待,比如缓存缺页)、系统 IO(后台任务引发的 IO 等待,比如合并)等。所有等待事件相关的监控信息可以通过四个视图展示出来,分为等待统计和等待明细。等待统计包括会话级和租户级,可以展示等待次数和等待时间,建议通过外部监控系统的可视化大图查看。等待明细包括会话级,一个展示每个会话当前的等待明细(Current Wait),如果当前会话不在等待,则展示最近发生的一次等待明细,另一个则展示每个会话历史上发生的最近 10 次的等待明细。
等待事件相关视图
OceanBase 数据库中的所有等待事件及对应的等待事件参数可以查询视图 V$EVENT_NAME 获取。可在系统租户下通过 SQL 语句按字母顺序显示所有等待事件及其所属的等待事件类型。示例如下:
obclient> SELECT name, wait_class FROM V$EVENT_NAME ORDER BY name;
OceanBase 数据库中的等待事件的查询视图有以下几种:
| 视图 | 展示内容 |
|---|---|
| V$EVENT_NAME | 展示租户下所有等待事件及对应的等待事件的详细信息。 |
| GV$SYSTEM_EVENT | 从租户(Tenant)维度展示等待事件的汇总信息。 |
| GV$SESSION_EVENT | 从会话(Session)维度展示等待事件的汇总信息。它展示所有 Session 所有历史 Wait Event 的统计信息,总共进入过多少次等待事件、总等待时间、平均等待时间等,由于是统计型表格,因此不会带 p1,p2,p3 等信息 |
| GV$SESSION_WAIT | 展示所有会话当前或最近完成的等待事件详细信息。会话级等待明细。 |
| GV$SESSION_WAIT_HISTORY | 展示每个会话最近 10 次的等待事件详细信息。会话级等待明细历史。 |
| V$OB_ACTIVE_SESSION_HISTORY | 展示租户下当前 OBServer 节点的活跃会话历史记录。 |
| GV$OB_ACTIVE_SESSION_HISTORY | 展示租户下所有 OBServer 节点的活跃会话历史记录。 |
根据用途不同,等待事件相关的监控信息可以分为两类:等待统计和等待明细。
等待统计
主要用于性能优化,包括各类等待事件的总等待次数、总等待时间、总超时次数和平均等待时间等。
GV$SYSTEM_EVENT 视图描述了租户级的等待事件统计,其主要字段介绍如下:
CON_ID:租户 ID。SVR_IP:节点 IP。WAIT_CLASS:等待事件类别。EVENT_ID:等待事件 ID。EVENT:等待事件名称。TOTAL_WAITS:总等待次数。TIME_WAITED:总等待时间。TOTAL_TIMEOUTS:总超时次数。AVERAGE_WAIT:平均等待时间。
可以通过如下语句对租户的等待事件统计进行查询:
obclient> select tenant_id, tenant_name, sum(total_waits) as total_waits, sum(time_waited_micro) / 1000000 as time_waited_seconds
from v$system_event join DBA_OB_TENANTS
on v$system_event.con_id = DBA_OB_TENANTS.tenant_id
where v$system_event.wait_class <> 'IDLE' and DBA_OB_TENANTS.tenant_type!='META'
group by tenant_name;
查询结果如下:
+-----------+---------------+-------------+---------------------+
| tenant_id | tenant_name | total_waits | time_waited_seconds |
+-----------+---------------+-------------+---------------------+
| 1 | sys | 14669140176 | 522012421.8556 |
| 1008 | mq_t1 | 3234084699 | 32159617.6839 |
+-----------+---------------+-------------+---------------------+
2 rows in set (0.06 sec)
等待明细
主要用于问题诊断,包括一次特定等待事件的等待开始时间、当前状态、剩余时间等,为了帮助问题定位,等待明细中允许传递三个特定的参数,比如对于一个加锁操作引发的等待,我们可以在等待明细中记录谁来加锁、加什么模式的锁、当前谁持有了锁,等待发生时,这些明细信息可以被直接展示出来。
GV$SESSION_WAIT 视图描述了会话级的等待明细,其主要字段介绍如下:
SID:会话 ID。WAIT_CLASS:等待事件类别。EVENT:等待事件名称。P1TEXT、P1、P2TEXT、P2、P3TEXT、P3:等待明细中允许传递的三个参数。STATE:当前状态。WAIT_TIME_MICRO:已经等待时间,单位为微秒。TIME_REMAINING_MICRO:剩余等待时间,单位为微秒。
如下语句展示了一个处于等待状态的会话的等待明细信息:
obclient> select * from GV$SESSION_WAIT where STATE='WAITING' limit 1 \G
查询结果如下:
*************************** 1. row ***************************
SID: 3222786366
CON_ID: 1
SVR_IP: xx.xx.xx.xx
SVR_PORT: 2882
EVENT: px loop condition wait
P1TEXT: address
P1: 140578612358640
P2TEXT:
P2: 0
P3TEXT:
P3: 0
WAIT_CLASS_ID: 104
WAIT_CLASS#: 4
WAIT_CLASS: CONCURRENCY
STATE: WAITING
WAIT_TIME_MICRO: 926
TIME_REMAINING_MICRO: 74
TIME_SINCE_LAST_WAIT_MICRO: 0
1 row in set (0.06 sec)
常见的等待事件
目前 OceanBase 数据库 V4.x 版本,大约有 309 个等待事件,常用的等待事件列举如下:
| 等待事件名称 | 等待事件编号 ID | 等待事件类别 | 描述 |
|---|---|---|---|
| sync rpc | 13000 | NETWORK | 数据库发送同步 RPC 请求后,等待同步 RPC 返回。 |
| das wait remote response | 13002 | NETWORK | SQL 分布式执行中,数据库等待远程 DAS 任务执行返回结果。 |
| wait for network request in queue | 13004 | NETWORK | 数据库系统接收了某会话请求,但该请求正在等待被工作线程处理。 |
| db file data read | 10001 | USER_IO | 用户 SQL 请求读取磁盘,等待数据返回。 |
| memstore memory page alloc wait | 11015 | SYSTEM_IO | 用户 SQL 需要写入 MEMStore,等待 MEMStore 分配写空间,通常原因是转储未完成,导致没有 MEMStore 可用。 |
| db file compact read | 11001 | SYSTEM_IO | 数据库转储时等待读磁盘完成。 |
| db file compact write | 11002 | SYSTEM_IO | 数据库转储时等待写磁盘完成。 |
| palf read | 11016 | SYSTEM_IO | 数据库读 clog 日志,等待读磁盘完成。 |
| palf write | 11017 | SYSTEM_IO | 数据库写 clog 日志,等待写磁盘完成。 |
| async commiting wait | 16018 | COMMIT | 等待日志异步提交完成,即 Clog 通过 OceanBase 数据库共识协议进行提交。 |
| sleep: wait refresh schema | 30100 | CONFIGURATION | 数据库执行过程中需要获取 Schema 信息,等待 Schema 刷新到指定版本。 |
| mysql response wait client | 13001 | NETWORK | OceanBase 数据库等待回复客户端的结果集发送完毕。在 OceanBase 数据库和客户端通过 MySQL 协议进行交互时,当 OceanBase 数据库向客户端回复非最后一个结果集时,回复过程是同步的。因此,OceanBase 数据库需要同步等待结果集发送完毕,才能继续进行后续的操作。 |
| async rpc proxy condition wait | 15111 | NETWORK | OceanBase 数据库等待内部节点间交互的异步网络通信返回结果。 |
| exec inner sql wait | 30000 | OTHER | OceanBase 数据库等待执行过程中发出的访问内部表的SQL 结果返回,比如获取用户表位置、Schema 信息等。 |
| sync get gts timestamp wait | 18101 | CONCURRENCY | 用户 SQL 执行过程中,等待同步获取 GTS(Global Timestamp Service,即全局时间戳服务)。 |