处理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的全杀了。

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

这个时候再分析show processlist中显示的信息,发现id 123890的语句执行时间最长,肯定是在该UPDATE语句之前执行 的,通过show full processlist查看语句详表,看到该查询也访问到了a表,经此分析,应该是该语句长时间的读阻塞了写,而被阻塞的写操作由于处于最优先处理队列,又阻塞了其它的读。不过这些都还只是我们的推论,考虑到线上系统服务的可靠性,最好还是能找到更确切的证据,而后再做操作。

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

[[email protected] data]# mysqladmin -uroot  -p  -S  /data/3306/mysql.sock debug

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

    [[email protected] 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             |

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

时间: 2024-10-29 19:07:15

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

mysql数据库中某项其中一个值在该项排第几,百分几

SQL 如下: sql 1. SELECT X.USER_ID, X.TOTAL_NO, X.ORDER_NO, X.ORDER_NO / X.TOTAL_NO AS PERCENTAGE_NO FROM (SELECT @rowNum := @rowNum + 1 AS ORDER_NO, @rowCount AS TOTAL_NO, USER_ID FROM T_SD_USER, (SELECT @rowNum := 0 ) b, (SELECT @rowCount := ( SELECT

xtrabackup 备份mysql数据库三: innobackupex 测试一个全量和两个增量的备份恢复测试

## 查看当前库中表的数据 ([email protected]) [test]>select count(*) from t_innodb; +----------+ | count(*) | +----------+ |        0 | +----------+ 1 row in set (0.00 sec) ## 执行插入数据操作,该操作在全备之后执行完成 ([email protected]) [test]>call addTest(100000,0); ## 执行全库备份 #

MySQL数据库数据迁移:从一个服务器到另一个服务器

需要两个服务器数据库版本相同才可迁移 1:单个或多个数据库 mysqldump -h远程ip -u用户 -p密码 -P3306 --default-character-set=utf8 --databases 单个或多个数据库名称空格分开 | mysql -h127.0.0.1 -uroot -p -P3306 执行后输入本地数据库密码即可 2:所有数据库 mysqldump -h远程ip -u用户 -p密码 -P3306 --default-character-set=utf8 --all-d

使用Mysql数据库完成增删改查综合案例(JSP页面)

本案例页面如下: 这是index.jsp页面(包含模糊查询) <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ page import=" java.sql.* "%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01

Mysqldb连接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查看详细的支持数据库列表. 不同的数据库你需要下载

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模块,例如你需要

Flask web开发----使用mysql数据库

根据<flask web开发>书中说不建议在生产环境中使用SQLite,所以在我跟着书本敲完api这一章的代码时,准备将数据库改用成mysql 1.现将这俩个文件删除,因为这是之前使用的SQLite数据库相关的文件 2.将原项目中的config文件中数据库的地址修改为如图所示的Mysql数据库.你需要现在你本机电脑上安装Mysql数据库,而且你存在一个用户的账户为:root,密码为:root,创建的数据库名称为Flask.(这里对mysql不做过多的讲解) 出于安全考虑可以将路径通过 (ven

MySQL 数据库入门操作

启动mysqld:在命令行启动mysql时,如不加"--console",启动.关闭信息不在界面中显示,而是记录在安装目录下的data目录里,文件名一般是hostname.err,通过此文件查看mysql的控制台信息.关闭mysqladmin -u root shutdown命令行连接服务器mysql -h localhost -u root -proot  (-p 和密码直接没有空格)或者 mysql -h localhost -u root -p 回车根据提示再输入密码rootmy

架构设计:系统存储(5)——MySQL数据库性能优化(1)

接上文:<架构设计:系统存储(4)--块存储方案(4)> 1.MySQL概述 从本文开始我们将讨论建立在块存储方案之上的关系型数据库的性能优化方案和集群方案.关系型数据库的选型将以创业公司.互联网行业使用最广泛的MySQL数据为目标,但是MySQL的安装过程和基本使用方法等知识并不在我们讨论的范围内.后续几篇文章我们首先讨论影响单个MySQL节点性能的主要因素,然后介绍MySQL读写分离.数据表横纵拆分的原理和技术方案. MySQL数据库目前已被Oracle收购,并发展处多个版本.目前使用最广