在数据库运维过程中,经常收到用户对数据库使用的反馈比如“数据库挂了”,“数据库慢”,这种反馈方式是一种比较模糊的说法,仅通过这种问题描述对问题分析往往没有任何帮助,也无法定位问题原因。
下面分享一种排查问题SQL语句的方法,由于引发数据库相关问题的因素也比较多,不足之处欢迎指正。
不良的SQL语句最明显的问题,就会造成服务器资源使用率的飙升,影响其他正常的业务无法获取资源造成等待,通过对操作系统cpu及内存的查看,来识别系统资源的瓶颈在哪。
内存使用情况(示例):
[dmdba@localhost ~]$ free -h
total used free shared buff/cache available
Mem: 254Gi 188Gi 1.4Gi 1.2Gi 64Gi 62Gi
Swap: 0B 0B 0B
[dmdba@localhost ~]$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
10 2 0 1423936 192 67698688 0 0 58 577 0 0 2 0 98 0 0
7 0 0 1419712 192 67701312 0 0 392 688 30630 40959 8 0 92 0 0
7 0 0 1417280 192 67703680 0 0 820 60804 29251 39335 7 0 93 0 0
cpu使用情况(示例):
top
Tasks: 994 total, 1 running, 993 sleeping, 0 stopped, 0 zombie
%Cpu(s): 7.3 us, 0.1 sy, 0.0 ni, 92.5 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st
MiB Mem : 260189.6 total, 1542.4 free, 192699.1 used, 65948.2 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 64180.6 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
353235 dmdba 20 0 138.8g 133.4g 22016 S 704.0 52.5 294971:41 dmserver
354016 dmdba 20 0 49.9g 41.3g 9408 S 1.7 16.3 1745:57 dmserver
545332 dmdba 20 0 228992 7232 3904 R 1.0 0.0 0:00.10 top
257331 root 20 0 586304 75904 16064 S 0.7 0.0 97:36.60 titanagent
10 root 20 0 0 0 0 I 0.3 0.0 201:55.65 rcu_sched
354592 dmdba 20 0 1198016 10752 2880 S 0.3 0.0 186:36.88 svc_ctl_linux
3929612 root 20 0 0 0 0 I 0.3 0.0 0:00.05 kworker/73:2-mm_percpu_wq
1 root 20 0 175104 13888 4992 S 0.0 0.0 3:02.87 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:07.39 kthreadd
通过对内存和cpu的查看,可以定位出目前服务运行的资源瓶颈在哪,是内存跑满了,还是CPU跑满了。针对具体的情况可以在进行下步的分析。
查询cpu占用最高的线程(示例):
[dmdba@localhost ~]$ ps -eLo pcpu,pmem,pid,tid,psr,wchan:14,comm|grep 353235 |sort
#CPU使用率 | 内存使用率 | 进程号 | 线程号 | 运行在哪个核上 | 进程休眠的内核函数地址,运行的任务显示为‘-’ | 进程可执行文件名
58.8 52.5 353235 534530 30 - dm_sql_thd
59.7 52.5 353235 534533 73 futex_wait_que dm_sql_thd
60.8 52.5 353235 534535 29 futex_wait_que dm_sql_thd
61.1 52.5 353235 534531 74 futex_wait_que dm_sql_thd
67.6 52.5 353235 545369 3 - dm_sql_thd
6.9 52.5 353235 417889 55 wait_woken dm_sql_thd
6.9 52.5 353235 417891 50 wait_woken dm_sql_thd
94.2 52.5 353235 307016 61 - dm_sql_thd
94.9 52.5 353235 307020 78 - dm_sql_thd
95.5 52.5 353235 307021 6 - dm_sql_thd
95.6 52.5 353235 307018 26 - dm_sql_thd
95.8 52.5 353235 307019 49 - dm_sql_thd
通过以上查询可以看到占用CPU较高的都是dm_sql_thd线程,dm_sql_thd 是用户线程。一般通过客户端连接的线程都是属于这个类别。
既然属于用户连接的信息,那么通过数据库的v$sessions视图就可以查询出,这个线程正在执行的动作。
查询线程执行的内容(示例):
select * from v$sessions where thrd_id='307019'
通过以上的查询就定位到引发CPU占用率较高的SQL语句,可以有针对性的进行优化和处理。
查询占用内存高的SQL(示例):
SELECT
A.CREATOR,
B.SQL_TEXT,
TRUNC(SUM( A.TOTAL_SIZE/1024/1024)) "分配大小(M)",
TRUNC(SUM(A.DATA_SIZE /1024/1024)) "占用大小(M)"
FROM
V$MEM_POOL A,
V$SESSIONS B
WHERE
A.CREATOR = B.THRD_ID
GROUP BY
A.CREATOR,
B.SQL_TEXT
ORDER BY 3 DESC
通过上面的语句就可以查询到当前正在执行的SQL那条语句占用的内存比较高,如果占用内存异常需要对sql进行处理。
通过上一部分的排查,基本已经可以提取出影响数据库运行的sql语句,之后就需要对提取出来的语句进行分析和优化。
文章
阅读量
获赞