记一次mysql排错—死锁

故事起源:
ZY问我,有没有遇到过在mysql客户端执行了添加表字段的的命令,显示成功了,在客户端也看的到,为啥到服务端查就没有了。我建议他在服务器上执行一下,他说也不行。

排障过程:
1.我去看了mysql正在执行的进程:
show processlist;
发现他的任务处在 Lock wait timeout exceeded 状态。数据库里面还有其他的任务是 Lock wait timeout exceeded 状态, 然后队列里面状态是sleep的任务也有很多。

  1. kill 掉他执行的任务 再次执行依旧不行。

3.想着sleep状态的任务那么多,应该是等待时间太长,然后我更改了wite_time 参数 原来是8小时,我改为了10分钟。

MariaDB [(none)]>  set global wait_timeout=600;
MariaDB [(none)]> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 600   |
+---------------+-------+
1 row in set (0.00 sec)

MariaDB [(none)]> 

然后把所有的任务都kill掉了
for i in $(mysql -uroot -p123456 -Bse "show processlist" | awk '{print $1}');do mysql -uroot -p123456 -e "kill $i";done

4.开启mysql自动提交
发现服务器不是自动提交,改为自动提交。
可以用以下命令查看:
show global variables like 'autocommit';
值为1就是自动提交 set global autocommit=1;

MariaDB [(none)]> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)

MariaDB [(none)]>

5.再次执行ZY的语句,成功!

6.排查过程中发现里面还有报 mysql Copying to tmp table on disk的任务,用时较长,是其他项目的任务。
百度发现 tmp_table_size 这个参数可以缓存查询数据,如果超过这个数字,就会写到磁盘上,这样就会很慢。所以要适当改大一点这个数据,但是前提是内存允许。

我查了一下,原来 tmp_table_size 值为 16M,我增加了一倍,没敢加太多。

MariaDB [cs_epg_release]> set global tmp_table_size=33554432;
MariaDB [cs_epg_release]> show global variables like '%tmp_table_size%';
+----------------+----------+
| Variable_name  | Value    |
+----------------+----------+
| tmp_table_size | 33554432 |
+----------------+----------+
1 row in set (0.02 sec)

再去查看进程,没有状态为 mysql Copying to tmp table on disk 的任务了。

7.后面对用时较长的查询任务做了 sql 分析,全表扫描,给对应项目的人员了。

<完!>

你可能感兴趣的:(记一次mysql排错—死锁)