mssql数据库占用CPU过高?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mssql数据库占用CPU过高?相关的知识,希望对你有一定的参考价值。
我的一个网站用的是mssql数据库,昨天网站运行一切正常,而且速度还可以,今天速度特别慢,我一看是sqlserver.exe占cpu80%多,请问是什么原因,有人说是程序问题,那为什么以前一切都很快啊,
wxwp.exe这个程序池使用率也特别高
CPU占用过高诊断思路
mpstat -P ALL 1,查看cpu使用情况,主要消耗在sys即os系统调用上
perf top,cpu主要消耗在_spin_lock
生成perf report查看详细情况
CPU主要消耗在mutex争用上,说明有锁热点。
采用pt-pmp跟踪mysqld执行情况,热点主要集中在mem_heap_alloc和mem_heap_free上。
Pstack提供更详细的API调用栈
Innodb在读取数据记录时的API路径为
row_search_for_mysql --》row_vers_build_for_consistent_read --》mem_heap_create_block_func --》mem_area_alloc --》malloc --》 _L_unlock_10151 --》__lll_unlock_wait_private
row_vers_build_for_consistent_read会陷入一个死循环,跳出条件是该条记录不需要快照读或者已经从undo中找出对应的快照版本,每次循环都会调用mem_heap_alloc/free。
而该表的记录更改很频繁,导致其undo history list比较长,搜索快照版本的代价更大,就会频繁的申请和释放堆内存。
Linux原生的内存库函数为ptmalloc,malloc/free调用过多时很容易产生锁热点。
当多条 SQL 并发执行时,会最终触发os层面的spinlock,导致上述情形。
解决方案
将mysqld的内存库函数替换成tcmalloc,相比ptmalloc,tcmalloc可以更好的支持高并发调用。
修改my.cnf,添加如下参数并重启
[mysqld_safe]malloc-lib=tcmalloc
上周五早上7点执行的操作,到现在超过72小时,期间该实例没有再出现cpu长期飙高的情形。
以下是修改前后cpu使用率对比
参考技术A 不是程序问题,可能是你网站上的数据调用比较频繁,重新启动数据库服务,释放缓存 参考技术B 这个问题我已经回答过1次了,其实我以前也是在网上找到答案的,我也遇到过这种问题,原因是你的网页代码中用了数据库后没有关闭,检查一下把程序所有出口都加上关闭数据库的语句。本回答被提问者采纳 参考技术C 应该是数据库的数据冗余造成的 参考技术D 这个要看你的服务器的配置了啊,带宽多少,流量多少[转]定位占用oracle数据库cpu过高的sql
今天在吃饭的时候我的朋友的数据库出现了问题,cpu占用率为97%,当我看到这个问题的时候我就想到了或许是sql导致的此问题,由于忍不住吃饭,暂时没有帮他看这个问题,这是我饭后自己模拟的故障,进行的分析:
1)查看一下cpu进程占用情况:
看到oracle进程为6331,6517等这几个进程占用cpu过高。
2)查看相关进程信息:
[oracle@oracle-one ~]$ ps -ef | grep 6331 oracle 6331 1 23 20:24 ? 00:02:05 ora_vktm_RHYS oracle 6555 6385 0 20:32 pts/2 00:00:00 grep 6331 [oracle@oracle-one ~]$ ps -ef | grep 6517 <span style="color:#ff0000">oracle 6517 6513 9 20:28 ? 00:00:24 oracleRHYS (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq))) </span>oracle 6557 6385 0 20:33 pts/2 00:00:00 grep 6517 [oracle@oracle-one ~]$
3)查看该会话信息:
SQL> select sid,serial#,username,machine,osuser,process from v$session s 2 where s.paddr=(select addr from v$process p where p.spid=\'&pid\'); Enter value for pid: 6517 old 2: where s.paddr=(select addr from v$process p where p.spid=\'&pid\') new 2: where s.paddr=(select addr from v$process p where p.spid=\'6517\') SID SERIAL# USERNAME MACHINE OSUSER PROCESS ---------- ---------- ----------- ---------------- ------------------------------ ------------------------ 1 21 RHYS oracle-one oracle 6513
可知:session 的信息为sid:1 serial#:21 数据库用户为:RHYS,客户端机器为:oracle-one,操作系统用户为:oracle 进程号:6513
4)查看该会话正在运行的sql:
SQL> select sql_text from v$sqltext 2 where (address,hash_value) in ( select sql_address,sql_hash_value from v$session s 3 4 where s.paddr= 5 (select addr from v$process p where p.spid=\'&pid\')); Enter value for pid: 6517 old 5: (select addr from v$process p where p.spid=\'&pid\')) new 5: (select addr from v$process p where p.spid=\'6517\')) <span style="color:#ff0000">SQL_TEXT ---------------------------------------------------------------- delete from amy_emp</span>
可知,当前用户正在进行删除表的操作,本次就是通过v$process 的spid找到进程号,然后找到v$session 的addr地址,然后找到v$sqltext的sql_address以及sql_hash_value,
通过这两个字段就可以定位出唯一的sql_text,本次通过v$process,v$session,v$sql_text三个视图结合找到相应的sql;
5)后续处理
如果该session为非法的,可以使用如下命令杀掉该会话: alter sytem kill session \'1,21\';
既然找到sql了,那么 我们就可以通知应用相关人员,确认是否在进行相关数据操作。
另外我们也可以使用dbms_system包对该session进行更加详细的跟踪。
比价老的一篇文章,转自:http://www.bitscn.com/pdb/oracle/201309/241814.html
以上是关于mssql数据库占用CPU过高?的主要内容,如果未能解决你的问题,请参考以下文章