数据库性能问题的定位最怕的是事后无法复现。比如一条SQL在凌晨突然执行了40秒,白天再跑却恢复正常;或者两个应用同时更新同一行数据造成死锁,但事务日志里只有Rollback记录。DB2提供的事件监视器(Event Monitor)正是用来应对这类问题的数据库级审计工具。它不靠轮询采样,而是由数据库引擎在特定事件发生时主动触发采集,把执行语句、事务上下文、锁竞争、连接来源等信息写入指定目标。创建事件监视器的入口是 CREATE EVENT MONITOR,后续的启用、查询、文件分析都围绕这个定义展开。

理解了事件监视器的定位之后,下一步就是确定要监控哪些事件类型,以及输出到哪里。这两个选择直接决定监控方案的可用性、存储成本和对业务库的性能影响,因此在实际执行创建命令前需要先想清楚。
一、事件类型与写入目标如何选择
DB2的事件监视器支持多种事件类型,每一类都对应不同的排查目标。STATEMENTS 用于捕获SQL语句执行结束时的信息,包括语句文本、执行时间、CPU消耗、读取行数等,适合做SQL审计和慢查询分析。TRANSACTIONS 记录事务的开始和结束,可以帮助分析长事务、锁持有时间以及回滚行为。DEADLOCKS 专门捕获死锁事件,通常配合 WITH DETAILS 获取参与死锁的应用程序、锁类型和SQL上下文。CONNECTIONS 关注连接建立和断开,适合排查连接风暴或未释放连接的问题。此外,还有 ACTIVITIES 用于活动监控,能够按工作负载或服务类统计资源消耗。
写入目标同样重要,DB2支持三种输出方式。写入表(WRITE TO TABLE)的好处是事件数据可以直接用SQL查询、聚合和关联,适合需要频繁分析或对接报表的场景。但它会把事件写入数据库自身的表中,必然消耗一部分业务库的CPU、日志和表空间资源。写入文件(WRITE TO FILE)将事件输出到文件系统,由数据库后台进程异步写入,对业务库内部影响较小,适合保留长期历史数据或离线分析。写入管道(WRITE TO PIPE)则面向实时消费,外部程序可以从命名管道读取事件流并即时处理,适合监控告警、实时大屏等场景。不同目标的参数和运维方式差异明显,创建前应根据实际需求进行取舍。
二、CREATE EVENT MONITOR 核心语法解析
创建事件监视器的简化语法如下,不同DB2版本支持的选项可能有细微差别,但核心结构保持一致:
CREATE EVENT MONITOR evmon_name
FOR event_type [, event_type ...]
WRITE TO TABLE | FILE path | PIPE pipe_name
[BUFFERSIZE buffersize]
[BLOCKED | NONBLOCKED]
[AUTOSTART | MANUALSTART]
上面的 event_type 可以写一个或多个,例如 FOR STATEMENTS, TRANSACTIONS 表示同时监控语句和事务两类事件。WRITE TO 决定输出目标,后接 TABLE 时数据库会自动创建一组以事件监视器名称为前缀的表;后接 FILE 时需要提供文件系统路径;后接 PIPE 时则需要操作系统先创建好命名管道。
BUFFERSIZE 控制事件缓冲区大小,单位通常为4K页。缓冲区越大,能够临时容纳的事件越多,对突发的容忍度也越高,但会占用更多内存。BLOCKED 和 NONBLOCKED 是两种背压策略:BLOCKED 表示当缓冲区满时,触发事件的数据库操作会被暂时阻塞,直到事件被写出,这样可以保证事件不丢失,但可能拖慢业务;NONBLOCKED 则允许在缓冲区满时丢弃新事件,优先保证业务执行速度。生产环境如果必须完整记录每一类事件,建议选择 BLOCKED;如果监控只用于趋势分析,偶尔丢失几条也可以接受,则可以用 NONBLOCKED 降低影响。
三、实战:创建写入表的语句事件监视器
下面以最常见的SQL审计场景为例,创建一个只监控语句事件的监视器,并把结果写入数据库表。先连接到目标数据库:
db2 connect to sample
执行创建命令。这里使用 MANUALSTART,意思是创建后不会立即开始采集,需要手动启动。这样可以先把定义准备好,在合适的时间窗口再开启监控。
CREATE EVENT MONITOR stmt_evm
FOR STATEMENTS
WRITE TO TABLE
MANUALSTART
创建完成后,DB2会在当前数据库内生成事件表。事件监视器名称 stmt_evm 会作为表名前缀,例如语句事件表通常命名为 STMT_EVM_STMT,其中包含事件ID、时间戳、语句文本、执行指标等字段。可以通过系统目录表确认定义是否创建成功:
SELECT EVMONNAME, EVENTTYPE, WRITE_TO FROM SYSCAT.EVENTMONITORS WHERE EVMONNAME = 'STMT_EVM'
确认无误后,启动事件监视器:
SET EVENT MONITOR stmt_evm STATE = 1
此时数据库开始记录语句结束事件。执行几条SQL作为测试,然后查询事件表:
SELECT EVENT_ID, EVENT_TIMESTAMP, STMT_TEXT FROM STMT_EVM_STMT ORDER BY EVENT_TIMESTAMP DESC FETCH FIRST 10 ROWS ONLY
如果只需要分析执行次数最多的SQL,可以按语句文本前缀进行聚合。由于 STMT_TEXT 可能是CLOB类型,直接分组会受限,可以截取前80个字符再统计:
SELECT SUBSTR(STMT_TEXT, 1, 80) AS SQL_TEXT, COUNT(*) AS EXEC_COUNT FROM STMT_EVM_STMT GROUP BY SUBSTR(STMT_TEXT, 1, 80) ORDER BY EXEC_COUNT DESC
业务高峰过去后,应停止事件监视器,避免它继续消耗资源:
SET EVENT MONITOR stmt_evm STATE = 0
四、文件与管道目标:离线和实时分析
如果不想把监控数据写进业务库,或者需要长期保存大量历史事件,文件目标是更合适的选择。下面创建一个带详细信息的死锁事件监视器,输出到文件系统路径:
CREATE EVENT MONITOR deadlock_file_evm
FOR DEADLOCKS WITH DETAILS
WRITE TO FILE '/db2data/evmon/deadlock_file_evm'
MAXFILES 10
MAXFILESIZE 1000
BUFFERSIZE 8
BLOCKED
MANUALSTART
这里 MAXFILES 表示最多保留的滚动文件数量,MAXFILESIZE 限制单个文件的大小,单位与 BUFFERSIZE 一样是4K页。设置合理的滚动上限可以防止监控文件无限增长占满磁盘。文件事件监视器启动后,数据不会自动进入数据库表,需要使用DB2提供的 db2evmon 工具进行解析和查看:
db2evmon -db sample -evm deadlock_file_evm
管道目标则用于实时消费。比如希望应用及时感知连接异常,可以先在操作系统上创建命名管道,再把事件监视器指向该管道:
mkfifo /tmp/db2_event_pipe
CREATE EVENT MONITOR conn_pipe_evm
FOR CONNECTIONS
WRITE TO PIPE '/tmp/db2_event_pipe'
NONBLOCKED
MANUALSTART
此后外部程序持续读取管道内容,即可获得准实时的连接事件流。管道方式对消费端的稳定性要求较高,如果读取程序处理缓慢或没有及时读取,可能在 BLOCKED 模式下阻塞数据库活动,因此实时监控通常建议配合 NONBLOCKED 使用。
五、事件监视器的生命周期管理与优化
事件监视器不会自动消失,它会一直存在于数据库中并可能持续占用资源。日常管理中,可以用系统目录视图查看所有事件监视器的状态:
SELECT EVMONNAME, EVENTTYPE, WRITE_TO, AUTOSTART FROM SYSCAT.EVENTMONITORS
对于不再需要的事件监视器,先确保它已经停止,再执行删除命令:
SET EVENT MONITOR stmt_evm STATE = 0; DROP EVENT MONITOR stmt_evm;
需要特别注意的是,写入表的事件监视器会持续向数据库中插入数据,表空间会随着监控时间线性增长。如果在生产环境开启全量语句监控,几个小时内就可能产生数十万甚至数百万行记录。因此建议只对必要的数据库分区、必要的业务时间段开启,并建立定期归档和清理机制。可以先把事件表数据导出到外部文件或数仓,再删除历史分区或直接清理旧数据。
权限方面,创建事件监视器通常需要 DBADM 或相应的数据库管理权限。普通开发账号如果只具备查询权限,无法执行 CREATE EVENT MONITOR 和 SET EVENT MONITOR 操作。在权限受控的环境中,应由DBA统一创建监控对象,再把事件表的查询权限开放给分析人员。
最后还要留意事件监视器与快照监控的差异。快照适合查看某一瞬间的全局状态,而事件监视器擅长还原事件发生的完整过程。两者并不是替代关系,很多成熟运维体系会把它们结合起来:日常趋势看快照和表函数,异常根因分析则依赖事件监视器提供语句级、事务级的明细数据。理解了这一点,就能更合理地规划 CREATE EVENT MONITOR 的使用范围,而不是把所有事件类型全部打开,反而给数据库增加不必要的负担。
DB2事件监视器CREATE EVENT MONITOR数据库性能监控修改时间:2026-09-30 02:19:10