mysql 占CPU100%处理一则

今天下班前一位同事负责的一套mysql数据库的CPU使用率达到100%,登上服务器top查看

Cpu(s):  95.9%us,  4.0%sy,  0.0%ni, 0.0%id,  20.0%wa,  0.0%hi,  0.0%si,  0.0%st

由于一直是在做oracle的维护,对mysql不熟悉,先在网上查了几篇文章,但好像都是一个人写的,不过从这些文章中也有了一个大体的处理思路。(由于不是我本人操作,没有记录详细的日志,这里只介绍下处理过程和使用到的命令,正文中的代码只是后期为说明加的。)

先使用root用户登上mysql,使用 show processlist命令查看当前哪些线程正在运行。查看下来一共有160多个

mysql> show processlist;
+----+------+-----------+------+---------+------+-------+------------------+
| Id | User | Host      | db   | Command | Time | State | Info             |
+----+------+-----------+------+---------+------+-------+------------------+
|  1 | root | localhost | NULL | Query   |    0 | init  | show processlist |
+----+------+-----------+------+---------+------+-------+------------------+
1 row in set (0.00 sec)

先简单说一下各列的含义和用途:

id    一个标识,你要kill一个语句的时候很有用。

user   显示当前用户,如果不是root,这个命令就只显示你权限范围内的sql句。

host   显示这个语句是从哪个ip 哪个端口上发出的。可以用来追踪出问题语句的用户。

db    显示这个进程目前连接的是哪个数据库。

command 显示当前连接的执行的命令,一般就是休眠(sleep),查询(query),连接(connect)。

time   此这个状态持续的时间,单位是秒。

state  显示使用当前连接的sql语句的状态,很重要的列。state只是语句执行中的某一个状态,以查询sql为例,可能需要经过copying to tmp table,Sorting result,Sending data等状态才可以完成。

info  显示这个sql语句,因为长度有限,所以长的sql语句就显示不全,但是一个判断问题语句的重要依据。

state列各种状态 参考文档:http://blog.csdn.net/e421083458/article/details/38342051

从show processlist命令输出的结果看到有一条sql语句重复出现,但是info列显示的不全只有select a.col1,a.col2,a.col3 from table1 a这样的信息。那就先从这个表入手查,select count(*) from table1;查出这张表有60W+的数据。select count(*) 使用了6秒。但是现在不确定这个语句执行的时候有没有where条件。

继续查资料,查到show processlist命令出的结果出处information_schema库下的processlist表。

mysql> use information_schema
Database changed
mysql> desc processlist;
+---------+---------------------+------+-----+---------+-------+
| Field   | Type                | Null | Key | Default | Extra |
+---------+---------------------+------+-----+---------+-------+
| ID      | bigint(21) unsigned | NO   |     | 0       |       |
| USER    | varchar(16)         | NO   |     |         |       |
| HOST    | varchar(64)         | NO   |     |         |       |
| DB      | varchar(64)         | YES  |     | NULL    |       |
| COMMAND | varchar(16)         | NO   |     |         |       |
| TIME    | int(7)              | NO   |     | 0       |       |
| STATE   | varchar(64)         | YES  |     | NULL    |       |
| INFO    | longtext            | YES  |     | NULL    |       |
+---------+---------------------+------+-----+---------+-------+
8 rows in set (0.04 sec)

可看到表porcesslist表的列跟show processlist输出的列是一致的。

再查询processlist表时发现info信息是完整的,在这里找到上边怀疑的sql的完整版为select a.col1,a.col2,a.col3 from table1 a where a.col4=‘123‘ and a.col5=‘abc‘;

查看这个语句的执行计划(类似下面这种)

mysql> explain select ename,hiredate,sal from emp where sal=1000 \G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: emp
         type: ALL
possible_keys: NULL
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 3072
        Extra: Using where
1 row in set (0.00 sec)

ERROR: 
No query specified

可以看出语句没有使用索引而是使用全表扫描。分别对col4=‘123‘ 和col5=‘abc‘做了统计,发现col4=‘123‘的记录只有一条,而col5=‘abc‘的记录有5W+条,很明显在col4上创建索引执行效率会高很多。查看表上是否有col4列上的索引(类似下面这种)。

mysql> show index from emp \G;
*************************** 1. row ***************************
        Table: emp
   Non_unique: 1
     Key_name: idx_emp_2
 Seq_in_index: 1
  Column_name: deptno
    Collation: A
  Cardinality: 6
     Sub_part: NULL
       Packed: NULL
         Null: YES
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.00 sec)

ERROR: 
No query specified

发现col4列上没有索引,表的存储引擎为 InnoDB,于是在col4列上创建索引

mysql> show table status from test1 like ‘emp‘\G;
*************************** 1. row ***************************
           Name: emp
         Engine: InnoDB
        Version: 10
     Row_format: Compact
           Rows: 3072
 Avg_row_length: 53
    Data_length: 163840
Max_data_length: 0
   Index_length: 65536
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2016-11-15 21:54:49
    Update_time: NULL
     Check_time: NULL
      Collation: gbk_chinese_ci
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.00 sec)

ERROR: 
No query specified
mysql> create index idx_sal on emp(sal);
Query OK, 0 rows affected (0.15 sec)
Records: 0  Duplicates: 0  Warnings: 0

再次查看执行计划,发现语句使用索引扫描。

mysql> explain select ename,hiredate,sal from emp where sal=1000 \G;
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: emp
         type: ref
possible_keys: idx_sal
          key: idx_sal
      key_len: 6
          ref: const
         rows: 1
        Extra: NULL
1 row in set (0.00 sec)

ERROR: 
No query specified

sql语句的执行效率立马提升。CPU的使用率也降下来了。

这也还有一个疑问,oracle在创建索引时为了避免锁表引入了online创建索引。不知道mysql中如何在线创建索引?

参考文档:http://blog.csdn.net/wlzjsj/article/details/51537736

参考文档:http://www.jb51.net/article/75217.htm

时间: 2024-10-06 13:55:03

mysql 占CPU100%处理一则的相关文章

程序猿是如何解决SQLServer占CPU100%的

原文:程序猿是如何解决SQLServer占CPU100%的 文章目录 遇到的问题 使用SQLServer Profiler监控数据库 SQL1:查找最新的30条告警事件 SQL2:获取当前的总报警记录数 有哪些SQL语句会导致CPU过高? 查看SQL的查询计划 选择top记录时,尽量为order子句的字段建立索引 查看SQL语句CPU高的语句 通过建立相关索引来减少表扫描 其他优化手段 总结 遇到的问题 有同事反应服务器CPU过高,一看截图基本都是100%了,my god,这可是大问题,赶紧先看

[引用]SQLServer占CPU100%

程序猿是如何解决SQLServer占CPU100%的 文章目录 遇到的问题 使用SQLServer Profiler监控数据库 SQL1:查找最新的30条告警事件 SQL2:获取当前的总报警记录数 有哪些SQL语句会导致CPU过高? 查看SQL的查询计划 选择top记录时,尽量为order子句的字段建立索引 查看SQL语句CPU高的语句 通过建立相关索引来减少表扫描 其他优化手段 总结 遇到的问题 有同事反应服务器CPU过高,一看截图基本都是100%了,my god,这可是大问题,赶紧先看看.

[Linux] Netstat 执行过慢,占CPU100%,原因查找

一.缘由: 待续 二.解决办法: netstat -tlnp netstat -nap|grep pid ss |grep pid ss -s sar -u 1 10 strace -FfT -o netstat.log cmd strace -FfT -o netstat.log netstat -tlnp vmstat 1 netstat -anultp |wc -l

shell脚本检测监控mysql的CPU占用率

网站访问量大的时候mysql的压力就比较大,当mysql的CPU利用率超过300%的时候就不能提供服务了,近乎卡死状态,这时候最好的方法 就是重启mysql服务.由于这种事具有不可预见性,我们不知道什么时候mysql的占用率达到300%,还是写个程序定期判断比较靠谱. 学了shell编程,写了下面的脚本: #!/bin/bash cpu=`ps aux | grep 'mysqld$' | cut -d " " -f6 | cut -d. -f1` if [ $cpu -gt 300

Shell编程检测监控mysql的CPU占用率

shell编程很强大! 网站访问量大的时候mysql的压力就比较大,当mysql的CPU利用率超过300%的时候就不能提供服务了,近乎卡死状态,这时候最好的方法就是重启mysql服务.由于这种事具有不可预见性,我们不知道什么时候mysql的占用率达到300%,还是写个程序定期判断比较靠谱. 学了shell编程,写了下面的脚本: #!/bin/bash cpu=`ps aux | grep 'mysqld$' | cut -d " " -f6 | cut -d. -f1` if [ $c

Mysql CPU占用高的问题解决方法小结

通过以前对mysql的操作经验,先将mysql的配置问题排除了,查看msyql是否运行正常,通过查看mysql data目录里面的*.err文件(将扩展名改为.txt)记事本查看即可.如果过大不建议用记事本了,容易死掉,可以用editplus等工具 简单的分为下面几个步骤来解决这个问题: 1.mysql运行正常,也有可能是同步设置问题导致 2.如果mysql运行正常,那就是php的一些sql语句导致问题发现,用root用户进入mysql管理mysql -u root -p输入密码mysql:sh

Oracle和mysql的区别

一.数据库的主要类型 数据库类型主要可分为:网状数据库.关系数据库.树状数据库.面向对象数据库.在商业中最主要的是关系型数据库,例如:Oracle.DB2.Sybase.My SQL Server.Informax.Redis.MySQL等. Oralce是大型数据而mysql是中小型关系型数据库.Oralce占市场的40%而mysql占市场的20%. 一.并发性 Oracle支持大并发量和访问量,是oltp最好的工具 并发性是oltp数据库的最重要的特性,但并发涉及到资源的获取.共享与锁定.

YCSB测试Mysql,MongoDB,TokuMX,Couchbase性能

测试是由同事完成的,这里只做收藏. 测试说明: 1.数据量为3kw记录,每条记录11个字段,一个为主键,主键为字符类型,类似:user****,后续为数值 其他10字段为字符类型,100字符,记录长度大约为1KB 2.使用ycsb进行压力测试.具体各类型参考以前文档 3.三千万数据,对目前数据库都能缓存到DB中(后续测试缓存80%,50%,30%等情况下性能情况) 4.测试项包括:数据装载,就是insert数据 ycsb的标准负载a.负载b.负载c.负载d.负载e.负载f测试 都采用64线程进行

RedHat 安装MySQL数据库【转】

朋友购买了阿里云的服务器,服务器上自带有CentOS操作系统,但是开发软件需要自己安装,接下来将介绍本地RedHat Linux 5.10虚拟机上搭建Mysql数据库. 一.软件准备 (1)jdk-6u32-linux-x64.bin  (2)MySQL-devel-5.6.16-1.linux_glibc2.5.x86_64.rpm  (3)MySQL-server-5.6.16-1.linux_glibc2.5.x86_64.rpm (4)MySQL-client-5.6.16-1.linu