MySQL性能问题剖析----死锁

来源:互联网 发布:微帮软件下载 编辑:程序博客网 时间:2024/05/22 03:20

背景

      采用mysql(5.0)的innodb存储引擎存储两张表,一张表的数据规模在20w行左右,另一张表的数据规模在10w行以下。以select, update操作居多,delete非常少(因此,应该不存在索引或数据页碎片的问题)。服务器的cpu、内存、io的使用率都不高。

 

问题

      就在几天前(令人发指的国庆期间,叫天天不应,叫地地不灵),对那两张表的事务操作变得奇慢无比,在慢日志里,一个commit的时间从2s 一直飙升到上千秒,童鞋们,操作的时间单位是秒唉。

 

问题排查

0. 应用层面,没有任何优化可做。

1. 把需要对数据库进行操作的服务停掉。

2. 尝试(从下午一点半一直持续到下午六点)

    2.1 mysql 系统变量优化

         buffer、cache相关的变量优化,重启mysql,耗时10分钟以上,在一张空表里插入一行记录,耗时 1~3秒。

    2.2 关闭bin-log

         和2.1相比,没有明显的变化。

    2.3 而后,我们发现,任何select 操作都非常快,包括,select count(*) from LIF; 基本上都是几十、几百毫秒内响应。而任何更新操作都非常非常慢,耗时分钟级别,包括,create database test_xxxxx; use test_xxxxx; create table test_update(int, varchar, .....); insert into test_update(.....) values(......);

    2.4 mysqldump,把对应数据库的数据dump,一至两分钟就dump完了。18M。

    2.5 初步怀疑,问题是操作系统级别的。猜想,在mysql需要对数据库进行更新操作时,需要向os申请某些资源,而这些资源是稀缺的,因此,mysql的更新线程一直在等待。

    2.6 解决问题的暂时方案:将数据库移到另外一台负载较小的服务器,将数据导入,整个过程导入过程几分钟就完成了。尝试几个简单的create database XXX; create table XXX; insert into xxxxx;  基本上都是几十几百毫秒内响应。

 

问题挖掘和流程梳理

     ok, 问题是暂时解决了,但问题的根源还是没有发现。

     在问题服务器上,我们在一个session内执行了一次慢操作,如create database xxxxx; 而后,在另外一个session上strace mysql_pid. 发现mysql此时在做的一个耗时的系统调用是futex(), 参数略。

     那么,futext又是个啥玩意儿呢?

     http://zh.wikipedia.org/zh-cn/Futex

     Futex 由一块能够被多个进程共享的内存空间(一个对齐后的整型变量)组成;这个整型变量的值能够通过汇编语言调用CPU提供的原子操作指令来增加或减少,并且一个进程可以等待直到那个值变成正数。Futex 的操作几乎全部在应用程序空间完成;只有当操作结果不一致从而需要仲裁时,才需要进入操作系统内核空间执行。这种机制允许使用 futex 的锁定原语有非常高的执行效率:由于绝大多数的操作并不需要在多个进程之间进行仲裁,所以绝大多数操作都可以在应用程序空间执行,而不需要使用(相对高代价的)内核系统调用

     发现关键字了,,工程师的噩梦。

     再google一下 “mysql 死锁”,出一大票链接

     http://www.chinaz.com/Program/Mysql/1219553B2008.html 这个说得比较全面了,很有参考价值,show innodb status; 回头再好好分析一下。(未完待续)