注册
达梦数据库压力测试 SQL 性能监控手册
专栏/技术分享/ 文章详情 /

达梦数据库压力测试 SQL 性能监控手册

dm-9527 2026/10/23 77 0 0
摘要

达梦数据库压力测试 SQL 性能监控手册

适用场景:压测期间定位长时间运行的 SQL、识别资源消耗和锁阻塞,并保存实际缓存计划用于优化前后对比。

不同 DM8 构建版本的视图字段、函数和权限可能不同,使用前先确认版本。以下以单实例排查为主;DSC、MPP 环境需按相应集群视图补充实例或节点信息。

1. 现场排查顺序

  1. 压测前记录版本、监控参数原值、压测批次和并发量。
  2. 在执行目标 SQL 的连接开启会话级执行监控,另开连接进行观察。
  3. 查看活动会话数量,筛选消息间隔较长的活动会话,定位目标会话。
  4. 对同一次 SQL 执行间隔约 10 秒采样两次,比较资源计数增量。
  5. 同时检查事务等待关系;发现阻塞后定位源头和空闲未提交写事务。
  6. 保存完整 SQL、执行标识和缓存计划,必要时结合 ET 分析操作符。
  7. 完成取证后再决定是否终止会话或清理指定计划缓存。
  8. 压测结束恢复本次修改的监控参数,保存结果并对比优化效果。

监控连接中的会话级设置,不会自动作用于应用连接池中的其他连接。应在目标业务连接执行 SQL 前开启;已在执行的 SQL 不应假定能够补齐此前未采集的数据。

2. 压测前准备与开启监控

2.1 记录版本、连接和参数

SELECT * FROM V$VERSION; SELECT SESSID(); SELECT PARA_NAME, SESS_VALUE FROM V$DM_INI WHERE PARA_NAME IN ('ENABLE_MONITOR', 'MONITOR_TIME', 'MONITOR_SQL_EXEC');

将参数原值保存到本次压测记录。SESS_VALUE 表示当前连接看到的值;应用连接的会话级配置需在对应连接确认。

2.2 在目标连接开启 SQL 执行监控

ALTER SESSION SET 'MONITOR_SQL_EXEC' = 1;

V$SQL_STAT 的资源统计依赖 ENABLE_MONITOR=1;操作符执行节点监控还需要开启 MONITOR_SQL_EXEC。如需 ET 时间分析,同时检查 MONITOR_TIME。

以下是参数未开启时的系统级设置示例,应由有权限的人员按本次压测方案执行,并记录原值:

-- 系统级设置:会影响实例监控配置 CALL SP_SET_PARA_VALUE(1, 'ENABLE_MONITOR', 1); CALL SP_SET_PARA_VALUE(1, 'MONITOR_TIME', 1);

执行监控会增加额外开销,优先限定目标连接;优化前后对比应保持相同监控配置。参数及 ET 配置参考达梦官方:数据库优化。

3. 查看当前活动会话数量

SELECT SYSDATE AS SAMPLE_TIME, COUNT(*) AS ACTIVE_SESSION_COUNT FROM V$SESSIONS WHERE STATE = 'ACTIVE';

该值表示采样时处于 ACTIVE 状态的会话数量,不是总连接数,也不能直接作为正在消耗 CPU 的 SQL 数量。锁等待会话也可能处于活动状态,监控查询自身也可能计入。
建议在压测各并发阶段持续记录,并结合响应时间、吞吐量、错误率及服务器 CPU、磁盘指标判断。

4. 定位运行较久的活动 SQL

SELECT S.SESS_ID, S.SESS_SEQ, S.TRX_ID, S.STATE, S.USER_NAME, S.CLNT_IP, S.SQL_TEXT, SF_GET_SESSION_SQL(S.SESS_ID) AS FULL_SQL, DATEDIFF(SS, S.LAST_RECV_TIME, SYSDATE) AS LAST_RECV_GAP_SEC, 'CALL SP_CLOSE_SESSION(' || S.SESS_ID || ');' AS CLOSE_SESSION_SQL FROM V$SESSIONS S WHERE S.STATE = 'ACTIVE' AND DATEDIFF(SS, S.LAST_RECV_TIME, SYSDATE) >= 1 ORDER BY LAST_RECV_GAP_SEC DESC;
字段 用途与解释
SESS_ID / SESS_SEQ 会话标识及序列号,后续关联资源统计时同时保留
TRX_ID 关联事务、锁等待关系
USER_NAME / CLNT_IP 定位业务账号与应用来源
SQL_TEXT 快速识别 SQL,长文本可能截断
FULL_SQL 会话最近处理的完整 SQL;不保证是最初持锁的语句
LAST_RECV_GAP_SEC 最近接收消息到采样时间的秒数
CLOSE_SESSION_SQL 仅生成关闭命令文本,此 SELECT 不会关闭连接

阈值为 大于等于 1 秒。原脚本的 Y_EXETIME 在此改为 LAST_RECV_GAP_SEC,避免误认为精确执行耗时。该间隔可能包含等待,不能解释为纯 CPU 时间。秒级 DATEDIFF 也不适合精确测量短 SQL。

动态视图会随执行变化,获取完整文本时会话可能已切换到下一条 SQL。定位后应尽快保存 SQL 和执行标识。

5. 采样目标 SQL 的实际资源消耗

5.1 目标 SQL 保持运行,另一个连接采样

以下保留所有会话状态。示例目标为涉及 GTSHY_BH_JTJC 的计数 SQL,可替换为实际业务关键字。

SELECT SYSDATE AS SAMPLE_TIME, S.SESS_ID, S.SESS_SEQ, S.STATE, DATEDIFF(SS, S.LAST_RECV_TIME, SYSDATE) AS LAST_RECV_GAP_SEC, Q.EXEC_ID, Q.START_TIME, Q.END_TIME, Q.PLN_ADDR, Q.LOGIC_READ_CNT, Q.PHY_READ_CNT, Q.RECYCLE_PHY_READ_CNT, Q.IO_WAIT_TIME, S.SQL_TEXT FROM V$SESSIONS S LEFT JOIN V$SQL_STAT Q ON Q.SESSID = S.SESS_ID AND Q.SESS_SEQ = S.SESS_SEQ WHERE UPPER(S.SQL_TEXT) LIKE '%GTSHY!_BH!_JTJC%' ESCAPE '!' AND UPPER(S.SQL_TEXT) NOT LIKE '%V$SESSIONS%';

关键词中的下划线已按字面值转义。匹配 SQL_TEXT 可能因文本截断漏查,应用存储过程内 SQL 也可能不直接显示在这里。定位会话后,建议将上述文本筛选替换为 WHERE S.SESS_ID = 实际会话ID AND S.SESS_SEQ = 实际序列号,继续采样。

5.2 间隔约 10 秒执行两次

保存两次完整结果及采样时间,必须对齐 SESS_ID + SESS_SEQ + EXEC_ID。不能将不同执行的累计值相减;若执行标识改变、计数回退或记录消失,应重新确认执行生命周期。

计数增量 = 第二次计数 - 第一次计数
每秒变化量 = 计数增量 / 两次实际采样间隔秒数
指标变化 排查方向 判断边界
LOGIC_READ_CNT 持续增加 大量扫描、重复关联、访问数据量大 不直接等于 CPU 使用量
PHY_READ_CNT 持续增加 数据物理读取 结合磁盘吞吐、延迟确认 I/O 瓶颈
IO_WAIT_TIME 持续增加 I/O 等待积累 单位为毫秒,不是 CPU 时间或锁等待时间
RECYCLE_PHY_READ_CNT 持续增加 临时表空间读取、中间结果落盘 结合排序、哈希连接及临时空间使用验证
所有指标基本不变 锁等待、其他等待、执行已结束或监控未更新 继续检查事务等待与执行标识
指标为 NULL 或无匹配行 未开启监控、关联无记录、记录生命周期或版本差异 不能据此认定没有资源消耗

逻辑读、物理读和临时空间读是访问次数类计数,不应直接当作字节量。字段含义及单位见达梦官方:动态性能视图。

对执行计划中“约 1313 万行扫描”等信息,应先确认其是否为优化器估算行数。仅凭估算不能断定它就是当前耗时来源,需结合资源增量和操作符实际统计。

6. 排查锁等待与阻塞链

6.1 查正在等待的一方

例如 A 更新一行未提交,B 更新同一行,则 B 是等待方,A 是阻塞方。

SELECT W.*, T.SESS_ID AS WAIT_SESS_ID, S.USER_NAME, S.STATE, S.CLNT_IP, S.SQL_TEXT FROM V$TRXWAIT W JOIN V$TRX T ON W.ID = T.ID JOIN V$SESSIONS S ON T.SESS_ID = S.SESS_ID;

6.2 查让别人等待的一方

SELECT W.ID AS WAIT_TRX_ID, W.WAIT_FOR_ID AS BLOCK_TRX_ID, T.SESS_ID AS BLOCK_SESS_ID, S.USER_NAME, S.STATE, S.CLNT_IP, S.SQL_TEXT FROM V$TRXWAIT W JOIN V$TRX T ON W.WAIT_FOR_ID = T.ID JOIN V$SESSIONS S ON T.SESS_ID = S.SESS_ID;

6.3 汇总等待方与阻塞方

SELECT SYSDATE AS SAMPLE_TIME, W.ID AS WAIT_TRX_ID, W.WAIT_FOR_ID AS BLOCK_TRX_ID, WT.SESS_ID AS WAIT_SESS_ID, WS.USER_NAME AS WAIT_USER, WS.STATE AS WAIT_STATE, WS.CLNT_IP AS WAIT_CLIENT_IP, WS.SQL_TEXT AS WAIT_SQL, BT.SESS_ID AS BLOCK_SESS_ID, BS.USER_NAME AS BLOCK_USER, BS.STATE AS BLOCK_STATE, BS.CLNT_IP AS BLOCK_CLIENT_IP, BS.SQL_TEXT AS BLOCK_LAST_SQL FROM V$TRXWAIT W LEFT JOIN V$TRX WT ON WT.ID = W.ID LEFT JOIN V$SESSIONS WS ON WS.SESS_ID = WT.SESS_ID LEFT JOIN V$TRX BT ON BT.ID = W.WAIT_FOR_ID LEFT JOIN V$SESSIONS BS ON BS.SESS_ID = BT.SESS_ID;

此结果展示每条等待关系;一笔事务可能出现在多条关系中,不能直接用结果行数作为被阻塞会话数。动态取样期间事务可能结束,部分关联列为空时应重新采样确认。

原 V$LOCK 汇总脚本不作为通用主查询:同一事务可能对应多张表,标量子查询可能返回多行;ROW_IDX 的含义也需要结合锁类型确认。若需补查锁对象,可先保存相关事务的锁记录,再按版本文档解读:

-- 将 123456 替换为实际事务 ID SELECT L.*, O.NAME AS OBJECT_NAME FROM V$LOCK L LEFT JOIN SYSOBJECTS O ON O.ID = L.TABLE_ID WHERE L.TRX_ID = 123456;

对象名只作为锁对象线索,不直接说明该对象就是等待链源头。

6.4 查阻塞链源头会话

SELECT SYSDATE AS SAMPLE_TIME, S.SESS_ID, S.SESS_SEQ, S.TRX_ID, S.USER_NAME, S.STATE, S.CLNT_IP, DATEDIFF(SS, S.LAST_RECV_TIME, SYSDATE) AS LAST_RECV_GAP_SEC, S.SQL_TEXT, SF_GET_SESSION_SQL(S.SESS_ID) AS FULL_SQL, 'CALL SP_CLOSE_SESSION(' || S.SESS_ID || ');' AS CLOSE_SESSION_SQL FROM V$SESSIONS S WHERE EXISTS ( SELECT 1 FROM V$TRXWAIT W WHERE W.WAIT_FOR_ID = S.TRX_ID ) AND NOT EXISTS ( SELECT 1 FROM V$TRXWAIT W WHERE W.ID = S.TRX_ID ) ORDER BY LAST_RECV_GAP_SEC DESC;

含义:别人正在等它,但它没有出现在等待方列表中。对于 C 等 B,B 等 A,A 不再等其他事务,该查询定位 A。使用 NOT EXISTS 避免 NOT IN 遇到空值时的判断问题。

这里不筛选 STATE='ACTIVE',因此能发现空闲但未提交的阻塞源头。LAST_RECV_GAP_SEC 不是阻塞持续时间。循环等待可能没有这种源头,需结合完整等待关系继续排查;查询无结果不代表没有阻塞。

7. 查空闲但仍有未结束写事务的会话

SELECT S.SESS_ID, S.SESS_SEQ, S.USER_NAME, S.CLNT_IP, S.SQL_TEXT, S.CREATE_TIME AS SESSION_CREATE_TIME, S.STATE, S.TRX_ID, T.STATUS AS TRX_STATUS, T.INS_CNT, T.UPD_CNT, T.DEL_CNT, T.UPD_INS_CNT FROM V$SESSIONS S JOIN V$TRX T ON S.TRX_ID = T.ID WHERE S.STATE = 'IDLE' AND T.STATUS = 'ACTIVE' AND (T.INS_CNT > 0 OR T.UPD_CNT > 0 OR T.DEL_CNT > 0 OR T.UPD_INS_CNT > 0) ORDER BY S.CREATE_TIME;

这是应用漏提交或漏回滚的重要线索:会话当前空闲,但事务尚未结束,且存在写操作计数。应与等待关系一起核对是否正在阻塞其他会话。

  • SESSION_CREATE_TIME 是连接创建时间,不能据此判断事务未提交多久。
  • SQL_TEXT 是最近语句线索,不一定是最初获取锁的语句。
  • 此条件只筛选有相关写计数的事务,不能覆盖所有持锁情形。
  • 原脚本重复的 UPD_INS_CNT 已删除。

8. 获取完整 SQL 与缓存执行计划

8.1 获取完整 SQL

-- 替换为目标会话 ID SELECT SF_GET_SESSION_SQL(139948995123864) AS FULL_SQL FROM DUAL;

8.2 获取目标执行的计划地址

-- disql 客户端显示设置;其他客户端需使用其对应的大字段显示配置 SET LONG 1000000 SELECT Q.SESSID, Q.SESS_SEQ, Q.EXEC_ID, Q.START_TIME, Q.END_TIME, Q.PLN_ADDR FROM V$SQL_STAT Q WHERE Q.SESSID = 139948995123864;

先核对 SESS_SEQ、EXEC_ID 和 SQL 文本,避免取到该连接的其他执行。示例中的 ID 均须替换为现场值。

8.3 打印缓存计划

在支持 SF_TRACE_DUMP_PLN 的版本执行:

SELECT Q.SESSID, Q.SESS_SEQ, Q.EXEC_ID, Q.PLN_ADDR, SF_TRACE_DUMP_PLN(Q.PLN_ADDR) AS CACHED_PLAN FROM V$SQL_STAT Q WHERE Q.SESSID = 139948995123864;

若返回多条执行记录,按已记录的 SESS_SEQ、EXEC_ID 进一步限定。函数可用性需按实际构建版本验证;不存在时使用该版本支持的计划导出方式。地址可能因缓存淘汰或执行结束而失效,应在定位后尽快取证。

SET LONG 只调整当前客户端显示,不会开启监控或改变服务器执行计划。缓存计划展示计划结构,不能单独替代操作符实际耗时。

8.4 必要时分析执行节点

目标执行已开启相应监控且记录仍可用时:

-- 示例,替换为目标 SQL 的 EXEC_ID CALL ET(123456);

重点查看耗时高的操作符及重复进入次数,结合扫描、关联、排序和临时空间读进行判断。未采集的执行不能仅靠事后开启监控还原节点统计。

9. 处置命令:取证后按需执行

以下操作会改变压测状态,应与常规采样分开记录。先保存证据,再确认目标及处置目的。

9.1 生成清理指定计划缓存的命令

SELECT CACHE_ITEM, SQLSTR, 'CALL SP_CLEAR_PLAN_CACHE(' || CACHE_ITEM || ');' AS CLEAR_SQL FROM SYS.V$CACHEPLN WHERE LOWER(SQLSTR) LIKE '%sscpfm!_task%' ESCAPE '!';

该 SELECT 只生成命令文本。!_ 配合 ESCAPE '!' 按字面匹配下划线;若直接写 %sscpfm_task%,其中 _ 会匹配任意单字符。仍需核对完整 SQL,避免仅因文本包含同名片段而误选。

确认目标后执行实际生成的命令:

-- 示例 ID,必须替换为现场确认的 CACHE_ITEM CALL SP_CLEAR_PLAN_CACHE(123456789);

此操作清除指定缓存计划,后续需要重新获取计划时会重新解析或优化;不应把它作为终止当前运行 SQL 的方法。比较冷缓存与热缓存结果时,应分别标记;清缓存引起的额外解析可能影响压测结果。

9.2 关闭指定会话

-- 示例 ID,必须替换为现场确认的会话 ID CALL SP_CLOSE_SESSION(139948995123864);

关闭前再次核对会话序列号、账号、客户端和事务,避免会话状态已变化。关闭会话会中断该连接,未提交事务需要回滚,锁释放可能需要等待回滚完成。优先由业务连接正常提交或回滚;长事务回滚期间继续观察资源与阻塞变化。

函数和过程语义参考达梦官方:系统函数与系统过程附录。11. 收尾检查

  • 保存两次采样、完整 SQL、等待关系和执行计划,避免动态记录消失。
  • 将本次修改的会话级和系统级监控配置恢复为原值;原来已开启的参数不应统一关闭。
  • 确认压测连接的事务已按业务预期结束,检查遗留阻塞和空闲写事务。
  • 单独标记清缓存、终止连接及回滚时段,分析结果时说明这些干预。
  • 依据证据区分大量数据访问、I/O、临时空间和锁等待,再安排下一轮优化验证。

10. 快速判断表

现场现象 优先执行
压测响应突然变慢 第 3、4 节:活动会话数量与长间隔会话
单条 COUNT 长时间不返回 第 5 节:同一次执行的两次资源采样
活动很多但资源增量小 第 6 节:事务等待与阻塞源头
源头会话显示 IDLE 第 7 节:空闲未结束写事务
逻辑读、物理读或临时空间读持续增长 第 8 节:缓存计划与 ET,并结合系统指标
修改优化策略后仍复用旧计划 第 9.1 节:核对并按需清理指定计划缓存
必须终止异常连接 第 9.2 节:确认目标、保存证据并观察回滚
评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服