MySQL数据库出现大量Locked的一个案例

做为一款轻量级数据库软件,MySQL在使用过程中遇到访问速度慢,或者无法响应这类的问题,解决方式基本都有定式,一般第一反应都会是登录到MySQL, show processlist看看当前连接状态。

  虽说简单,但show processlist显示的信息确实是相当有用,有一回,三思收到反馈说MySQL查询很慢,于是,赶紧登录到mysql中,执行show processlist查看当前连接信息:


mysql> show processlist;

+--------+-------------+--------------------+-------+---------+-------+----------------------------------+----------------------------------------------------------------------------------+

| Id     | User        | Host               | db    | Command | Time  | State                            | Info                                                                             |

+--------+-------------+--------------------+-------+---------+-------+----------------------------------+----------------------------------------------------------------------------------+

|      1 | system user |                    | NULL  | Connect | 342266| Waiting for master to send event | NULL                                                                             |

|      2 | system user |                    | hdpic | Connect |   872 | Locked                           | UPDATE a SET STATE=0 WHERE ID=83752                                              |

| 123890 | hdpic_read  | 192.168.1.79:54910 | hdpic | Query   |  1512 | Sending data                     | select z.ID,z.TITLE,z.CREATOR_USER_NICK,z.CREATOR_USER_IDEN,z.LASTEDITOR_TI      |

| 124906 | hdpic_read  | 192.168.1.39:18844 | hdpic | Query   |   845 | Locked                           | select * from a where ((ID = 78789) AND (STATE != 0))                            |

| 124912 | hdpic_read  | 192.168.1.39:18862 | hdpic | Query   |   845 | Locked                           | select * from a where ((ID = 16031) AND (STATE != 0))                            |

| 124914 | hdpic_read  | 192.168.1.39:18865 | hdpic | Query   |   837 | Locked                           | select * from a where ((ID = 39109) AND (STATE != 0))                            |

| 124917 | hdpic_read  | 192.168.1.39:18875 | hdpic | Query   |   833 | Locked                           | select * from a where ((ID = 16031) AND (STATE != 0))                            |

................

................

................

  一堆的Locked,怪不得慢啊,阻塞的时间不短了,十几分钟。

  通常来说存在Locked就说明当前读写操作存在被阻塞的情况,一般我们看到锁都会下意识认为是由于写阻塞了读,上面的结果看仿佛也符合这一特征:只有一条UPDATE,而无数条的SELECT。猜是必须的,但不能瞎猜,这毕竟是线上系统,就算想杀连接的线程,也是要杀掉造成阻塞的那个,不能把所有Locked的全杀了,不然DBA本人很快也要被人杀了,因此具体情况如何还是需要继续分析。

  从show processlist查看到的信息来看,UPDATE的语句是很简单的,分析a的表结构,该表为MyISAM表,ID为该表主键,该条更新应该能够瞬间执行完,即使系统繁忙也不应该,而且通过查看当前的系统状态,整体负载很低,iostat中看I/Owait几可忽略,该写操作不太可能这么长时间都没有执行完。

  这个时候再分析show processlist中显示的信息,发现id 123890的语句执行时间最长,肯定是在该UPDATE语句之前执行的,通过show full processlist查看语句详表,看到该查询也访问到了a表,经此分析,应该是该语句长时间的读阻塞了写,而被阻塞的写操作由于处于最优先处理队列,又阻塞了其它的读。

  不过这些都还只是我们的推论,考虑到线上系统服务的可靠性,最好还是能找到更确切的证据,而后再做操作。

mysqladmin命令有一个debug参数,可以分析当前MySQL服务的状态信息,同时也可以用来帮助我们定位当前锁的详细情况,这里我们通过该命令分析一下当前MySQL服务的详细状态,执行mysqladmin命令如下:

  [root@phpmysql02 data]# mysqladmin -ujss -p -S /data/3306/mysql.sock debug

  Enter password:

  debug会将状态信息生成到mysql的错误文件,一般锁的信息都会保存在最后几行,这里我们在操作系统层error log最后几行:


[root@phpmysql02 data]# tail -10 phpmysql02.err

Thread database.table_name          Locked/Waiting        Lock_type

2       hdpic.t_wiki_zutu           Waiting - write       Highest priority write lock

123890  hdpic.t_wiki_zutu_category  Locked - read         Low priority read lock

123890  hdpic.t_wiki_zutu_photo     Locked - read         Low priority read lock

123890  hdpic.t_wiki_zutu           Locked - read         Low priority read lock

124906  hdpic.t_wiki_zutu           Waiting - read        Low priority read lock

  从上述信息可以看出,123890持有的读锁阻塞了2的写入和124906的读操作,这个状态符合我们的推论,接下来处理就比较单纯了,如果现状不可接受,不能继续等待,将123890杀掉,释放资源即可:

  mysql> kill 123890;

  Query OK, 0 rows affected (0.00 sec)

  再次执行show processlist查看:


mysql> show processlist;

+--------+-------------+--------------------+-------+---------+--------+----------------------------------+------------------+

| Id     | User        | Host               | db    | Command | Time   | State                            | Info             |

+--------+-------------+--------------------+-------+---------+--------+----------------------------------+------------------+

|      1 | system user |                    | NULL  | Connect | 342390 | Waiting for master to send event | NULL             |

| 124906 | hdpic_read  | 192.168.1.39:18844 | hdpic | Sleep   |      1 |                                  | NULL             |

| 124912 | hdpic_read  | 192.168.1.39:18862 | hdpic | Sleep   |      2 |                                  | NULL             |

| 124914 | hdpic_read  | 192.168.1.39:18865 | hdpic | Sleep   |      1 |                                  | NULL             |

| 124917 | hdpic_read  | 192.168.1.39:18875 | hdpic | Sleep   |      1 |                                  | NULL             |

| 124919 | hdpic_read  | 192.168.1.39:18877 | hdpic | Sleep   |      2 |                                  | NULL             |

................

................

................

  已经没有Locked的连接,此时向前端人员询问,告知响应慢的现象也已经消除,服务恢复正常。

最新内容请见作者的GitHub页:http://qaseven.github.io/

时间: 2024-08-30 16:17:57

MySQL数据库出现大量Locked的一个案例的相关文章

MyEclipse连接MySQL数据库报错解决办法_Mysql

我们现在一般网站都是利用的MySQL数据库搭建网站的,但是在网上看到很多网友吐槽数据库连接不上的问题,现在我就结合相关资料向提出一些我个人的见解,希望对大家解决问题有帮助. 一般MySQL连接不上,可能有两大原因:1.MyEclipse配置错误 2.MySQL配置不当. 一.我们一般的连接步骤如下: 1.在MyEclipse中连接MySQL数据库:依次点击window-->show view-->other-->MyEclipse Database-->DB Browser 图一:

PHP3 入门教程MySQL 数据库界面

  下面的内容就是如何用 PHP3.0 和 MySQL 来构造数据库 Web 应用.       下面这些涉及到 MySQL 的功能,都必须在服务器上安装调试好 MySQL 之后才能够运行.如果你对 MySQL 还不是很熟,那么最好先看看有关的文章.       PHP 在数据库服务器和 Web 浏览器之间,扮演了一个中间人的角色,把一方的命令解释后传给另一方,而后在把取得的结果传回来.正是由于这种沟通的可能性,使得许多任务得以实现.比如网上调查,在线购物,个人化站点等等,无不借助于这种技术.

mysql数据库执行SQL导出数据方法

  访问MySQL数据库除了可以使用phpmyadmin.第三方数据库客户端,也可以使用命令行的MySQL客户端,因为敲命令不太方便,所以被很多人给抛弃呀. 但有时候没办法,phpmyadmin不能用,只能使用命令行模式了,不过用多了,感觉命令行的也不错,除了写SQL比较慢. ## 基本命令 mysql -h hostip -P port -u usernmae -p passwd dbname -A -h mysql的ip -P 端口 -u 用户名 -p 密码 dbname 数据库名 直接进入

用java编写代码,实现将多套试题,读入mysql数据库中

问题描述 用java编写代码,实现将多套试题,读入mysql数据库中 我想做一个自动生成试卷的系统,供教师使用,想把多套试卷录入数据库,用java编写代码,实现将多套试题,读入mysql数据库中 解决方案 自动生成试卷,需要做一个题库吧.通过题库的随机算法生成新的试卷 解决方案二: 是将一套样题的卷子拆解成若干道题目吗?首先要实现拆分啊,好像有点难...不如上网上直接找题目来的快 解决方案三: 是的,需要做题库,试题录入题库.试卷从中随机取出.. 解决方案四: 嗯,我已经将几套试题按题型录入数据

python操作mysql数据库实现增删改查

Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口. Python 数据库接口支持非常多的数据库,你可以选择适合你项目的数据库: GadFly mSQL MySQL PostgreSQL Microsoft SQL Server 2000 Informix Interbase Oracle Sybase 你可以访问Python数据库接口及API查看详细的支持数据库列表. 不同的数据库你需要下载不同的DB API模块,例如你需要

mysql-iis日志导入Mysql数据库快速实现方法

问题描述 iis日志导入Mysql数据库快速实现方法 做一个Iis日志统计的软件,打算通过mysql实现,刚刚开始自学,现在要将iis日志导入到mysql数据库中,目前了解到的方法是用load data infile语句,但发现速度不够理想 100M文件需要30S左右.因为知识有限不知道还有什么更好的办法,希望懂的前辈们,能多指点一下,谢谢

c#窗体-c#:关于如何用vs2008连接mysql数据库。

问题描述 c#:关于如何用vs2008连接mysql数据库. 因为在做一个学校的项目,用c#开发的窗体程序,不知道怎么连接mysql数据库,愿知道的大牛指导下,不胜感激 解决方案 http://www.jb51.net/article/41920.htm 解决方案二: C#连接mysql数据库c#如何连接MYSQL数据库C#中如何连接MySql数据库

Mysql数据库的一些命令_Mysql

如果你习惯用 windows 的数据库,也就是在 图形界面上操作数据库的话,那么当你在命令上 操作 mysql 将会感到陌生,其实只要你掌握了一些基本命令,还有经常使用,熟练起来了, 将会相当方便,而且很快速. 好了,现在开始 带一些刚接触mysql 的朋友 进入mysql 的世界吧. 呵呵. 查看当前数据库的版本,因为有些命令在不同版本中 用法有可能不一样,注意 -V 是大写字母V[root@localhost ~]# mysqladmin -Vmysqladmin  Ver 8.42 Dis

让MySQL数据库跑的更快 为数据减肥_Mysql

在数据库优化工作中,使数据尽可能的小,使表在硬盘上占据的空间尽可能的小,这是最常用.也是最有效的手段之一.因为缩小数据,相对来说可以提高硬盘的读写速度,并且在查询过程中小表的内容处理时所占用的系统资源比较少.同理,如果在比较小的列上设置索引的话,其索引所占用的资源也会比较少.那么数据库管理员该如何给自己的数据减肥呢?对此笔者有如下几个建议. 建议一:空值并不一定不占用空间 在这里笔者先给大家扫盲一下.有些数据库管理员,认为空值不会占用系统资源,其实这是一个错误的认识.他们在数据库设计时,不喜欢将