注册
基础定位负载操作
技术分享/ 文章详情 /

基础定位负载操作

Ariamaru 2026/07/31 167 0 0

基础定位负载操作

系统视图

当数据库突然变慢,最直观的反应就是查看当前正在执行的SQL。达梦提供了动态视图 V$SESSIONSV$SQL_STAT,我们可以关联查询,获取会话状态、执行时间、客户端IP以及完整的SQL文本。

下面是一条实用的监控SQL,它会列出所有处于 ACTIVEWAIT 状态的会话,并计算SQL已执行的时间(秒),同时提供关闭会话的快捷语句(以防紧急kill):

SELECT * FROM ( SELECT 'SP_CLOSE_SESSION('||SESS_ID||');' AS CLOSE_SESSION, DATEDIFF(SS,LAST_SEND_TIME,SYSDATE) sql_exectime, TRX_ID, CLNT_IP, B.IO_WAIT_TIME AS IO_WAIT_TIME, SF_GET_SESSION_SQL(SESS_ID) FULLSQL, A.SQL_TEXT FROM V$SESSIONS a,V$SQL_STAT B WHERE STATE IN ('ACTIVE','WAIT') AND A.SESS_ID = B.SESSID )

SQL_TEXT列记录的是部分SQL语句,FULLSQL列存储了完整的执行SQL语句,需要记录保存下来,针对这些SQL语句进行优化。

模拟慢sql:为了演示,创建两张表 DM(5万行)和 EM(500万行),并在关联字段上建立索引,然后执行一个带有 UPPER 函数和 OR 条件的查询,该查询会导致索引失效,从而产生全表扫描,执行时间显著变长。

-- 1. 创建小表 dm,用于关联查询
DROP TABLE IF EXISTS DM;
CREATE TABLE DM (
    DID INT PRIMARY KEY IDENTITY(2,3),
    ENAME VARCHAR(200),
    DEPTNO INT
);

-- 插入5万条数据
DECLARE I INT;
BEGIN
    FOR I IN 1..50000 LOOP
        INSERT INTO DM (ENAME, DEPTNO)
        SELECT 
            DBMS_RANDOM.STRING('2', TRUNC(DBMS_RANDOM.VALUE(2,4))),
            TRUNC(DBMS_RANDOM.VALUE(1,6))
        FROM DUAL;
    END LOOP;
END;
/

-- 2. 创建大表 em,模拟主要数据表
DROP TABLE IF EXISTS EM;
CREATE TABLE EM (
    EID INT PRIMARY KEY IDENTITY(1,1),
    ENAME VARCHAR(200),
    AGE INT,
    HIREDATE DATE,
    DEPTNO INT
);

-- 插入500万条数据
DECLARE I INT;
BEGIN
    FOR I IN 1..5000000 LOOP
        INSERT INTO EM (ENAME, AGE, HIREDATE, DEPTNO)
        SELECT 
            DBMS_RANDOM.STRING('2', TRUNC(DBMS_RANDOM.VALUE(2,4))),
            TRUNC(DBMS_RANDOM.VALUE(1,100)),
            ADD_DAYS(SYSDATE(), DBMS_RANDOM.VALUE(-10000,-10)),
            TRUNC(DBMS_RANDOM.VALUE(1,6))
        FROM DUAL;
    END LOOP;
END;
/

-- 3. 为关联字段创建索引
CREATE INDEX IDX_EM_ENAME ON EM(ENAME);
CREATE INDEX IDX_DM_ENAME ON DM(ENAME);

-- 4. 收集统计信息,帮助优化器生成执行计划
DBMS_STATS.GATHER_TABLE_STATS('SYSDBA','DM',NULL,100,TRUE,'FOR ALL COLUMNS SIZE AUTO');
DBMS_STATS.GATHER_TABLE_STATS('SYSDBA','EM',NULL,100,TRUE,'FOR ALL COLUMNS SIZE AUTO');

执行一个可能导致全表扫描或复杂关联的查询。下面的SQL可能会因为函数,导致优化器放弃使用索引而选择全表扫描。

-- 执行一个可能很慢的查询
SELECT EM.* 
FROM EM 
JOIN DM ON UPPER(EM.ENAME) = UPPER(DM.ENAME)   -- 使用函数,索引失效
WHERE (EM.EID = 3 AND EM.AGE = 67) 
   OR (EM.EID = 5 AND EM.AGE = 20);

image.png

第一个是监控的sql,第二个能看到正在执行的慢sql,他的语句信息、执行信息、事务id

日志分析

通过分析dmsql_log日志来获取哪些SQL语句慢,需要掌握Dmlog分析工具的使用方法以及需要安装jdk环境。
为避免记录SQL log对服务器产生较大的影响,还需要配置异步日志刷新ASYNC_FLUSH = 1。
image.png
开启sqllog

 SP_SET_PARA_VALUE(1, 'SVR_LOG', 1);

只执行了一条查询语句的log也是非常多的,所以我们可以通过grep去过滤对我们有用的信息,比如执行时间:

[root@localhost log]# cat dmsql_PROD_20260727_171401.log | grep EXECTIME
   OR (EM.EID = 5 AND EM.AGE = 20); EXECTIME: 13562(ms) ROWCOUNT: 0(rows) EXEC_ID: 834.
and SF_COL_IS_IDX_KEY(INDS.KEYNUM, INDS.KEYINFO, COLS.COLID) = 1; EXECTIME: 64(ms) ROWCOUNT: 1(rows) EXEC_ID: 835.
2026-07-27 17:14:20.275 (EP[0] sess:0x7f7f9c020328 thrd:3434 user:SYSDBA trxid:0 stmt:0x7f7f9c040a00 appname:manager ip:::ffff:127.0.0.1) [SEL] /***Manager***/ SELECT count(*),max(trxid) from SYS.SYSOBJECTS; EXECTIME: 42(ms) ROWCOUNT: 1(rows) EXEC_ID: 1426.
2026-07-27 17:16:00.565 (EP[0] sess:0x7f7f9c020328 thrd:3434 user:SYSDBA trxid:0 stmt:0x7f7f9c040a00 appname:manager ip:::ffff:127.0.0.1) [SEL] /***Manager***/ SELECT count(*),max(trxid) from SYS.SYSOBJECTS; EXECTIME: 58(ms) ROWCOUNT: 1(rows) EXEC_ID: 1427.
2026-07-27 17:17:40.794 (EP[0] sess:0x7f7f9c020328 thrd:3434 user:SYSDBA trxid:0 stmt:0x7f7f9c040a00 appname:manager ip:::ffff:127.0.0.1) [SEL] /***Manager***/ SELECT count(*),max(trxid) from SYS.SYSOBJECTS; EXECTIME: 16(ms) ROWCOUNT: 1(rows) EXEC_ID: 1428.

性能监控

性能监控相关参数(ET)

参数名称 作用与含义 开启后可以做什么? 重要提醒
ENABLE_MONITOR 监控的总开关 开启后,数据库才会开始收集SQL执行、性能等关键数据,是使用其他监控功能的前提。 系统级动态参数。开启会带来一定的性能损耗,建议按需开启,用完即关。
MONITOR_SQL_EXEC SQL执行细节监控 精确记录SQL语句执行过程中每个操作符的耗时,是使用 ETDBMS_SQLTUNE 等高级分析工具的核心参数。 会话级动态参数强烈建议只在需要分析的会话中开启,避免全局开启影响性能。
ENABLE_MONITOR_DMSQL DMSQL程序监控 开启对DMSQL程序(如存储过程、函数、触发器)的监控。 如果你需要分析存储过程的性能问题,这个参数必须开启。

打开监控

 SP_SET_PARA_VALUE(1,'ENABLE_MONITOR',1);
 SP_SET_PARA_VALUE(1,'MONITOR_SQL_EXEC',1);

通过ET 函数能展示SQL执行计划中每个操作符的具体耗时

CALL ET(执行号)

image.png

none

还可以通过V$LONG_EXEC_SQLS来查看慢sql

image.png

分析堆栈

配置操作系统保存core文件

[dmdba@localhost  bin]$ ulimit -c unlimited  

修改core文件路径

[root@localhost  ~]# echo "/corefile/core-%e-%p-%t" >  /proc/sys/kernel/core_pattern  

手动生成core文件

[dmdba@localhost bin]$ ps -ef|grep dmserver
dmdba      3134      1  0 05:35 pts/0    00:00:00 /opt/dmdbms/bin/dmserver /opt/dmdbms/bin/dm.ini -noconsole
dmdba      3210   2778  0 05:37 pts/0    00:00:00 grep dmserver
[dmdba@localhost bin]$ kill -11  3134

当操作系统是麒麟v10时,需要变为以下设置:

[dmdba@localhost bin]$ echo -e “\nkernel.core_pattern=/corefile/core-%e-%s-%p-%t” >>/etc/sysctl.conf
[dmdba@localhost bin]$ echo -e “1” >>/proc/sys/kernel/core_uses_pid
[dmdba@localhost bin]$ sysctl -p /etc/sysctl.conf 

利用gdb分析打印堆栈:

dmdba@localhost bin]$ gdb dmserver(可执行文件) core.3134 (core文件)
(gdb) set logging file dmstack.log
(gdb) set logging on
Copying output to dmstack.log.
(gdb) thread apply all bt
…                      #一直enter直到所有线程打印退出
(gdb) set logging off
Done logging to dmstack.log.

image.png

无core文件时

[dmdba@localhost bin]$ ps -ef|grep dmserver
dmdba      3287      1  2 05:51 pts/0    00:00:00 /opt/dmdbms/bin/dmserver /opt/dmdbms/bin/dm.ini -noconsole
dmdba      3398   2778  0 05:51 pts/0    00:00:00 grep dmserver
[dmdba@localhost bin]$ gdb 
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) attach 3287 
Attaching to process 3287
Reading symbols from /opt/dmdbms/bin/dmserver...(no debugging symbols found)...done.
Reading symbols from /lib64/librt.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib64/librt.so.1
Reading symbols from /lib64/libpthread.so.0...(no debugging symbols found)...done.
[New LWP 3389]
[New LWP 3388]
…
(gdb) set logging file dmstack.log
(gdb) set logging on
Copying output to dmstack.log.
(gdb) thread apply all bt
…
(gdb) set logging off
(gdb) detach
(gdb) quit

image.png

进程不在,一启动就挂,无法attach又core不出来,怎么办?

[dmdba@localhost bin]$ gdb dmserver
GNU gdb (GDB) Red Hat Enterprise Linux (7.2-60.el6_4.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /opt/dmdbms/bin/dmserver...(no debugging symbols found)...done.
(gdb) r   /opt/dmdbms/bin/dm.ini
Starting program: /opt/dmdbms/bin/dmserver /opt/dmdbms/bin/dm.ini
[Thread debugging using libthread_db enabled]
file dm.key not found, use default license!
Read ini warning, default backup path [/dbdata/dmbak] does not exist. 
Detaching after fork from child process 3476.
version info: develop
Detaching after fork from child process 3477.
Use normal os_malloc instead of HugeTLB
Use normal os_malloc instead of HugeTLB
DM Database Server x64 V7.6.1.60-Build(2020.06.02-122414)ENT  startup...
[New Thread 0x7ffe8f07d700 (LWP 3478)]
[New Thread 0x7ffe8ef7c700 (LWP 3479)]
[New Thread 0x7ffe4d796700 (LWP 3480)]
[New Thread 0x7ffe4d695700 (LWP 3481)]
[New Thread 0x7ffe4d594700 (LWP 3482)]
[New Thread 0x7ffe4d493700 (LWP 3483)]
License will expire on 2021-06-02
[New Thread 0x7ffe4cf49700 (LWP 3484)]
[New Thread 0x7ffe4ce48700 (LWP 3485)]
…
这样在gdb中启动的进程就算由于某些问题core掉,这部分内存数据还是可以在gdb中分析的,可以按照上面gdb分析堆栈的流程进行处理。

image.png

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服