ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

如何在MySQL中检测死锁?建立连接时,什么原因可能导致我的应用程序挂起?

2019-11-21 17:19:17  阅读:163  来源: 互联网

标签:locking mysql


我有一个与数据库有关的应用程序:尝试打开与数据库的连接(或执行查询时,不清楚)时,它突然冻结.没有错误信息.我怀疑有一些查询阻止了其他查询,并且我试图弄清楚那是什么.
我用了

SET profiling=1;

但是当我执行时:

show profiles;

我只会得到自己执行的查询,而不会得到应用程序查询(该应用程序和我使用的是同一用户).

呼唤

 SHOW FULL PROCESSLIST;

返回具有所有进程的表.

+-----+----------+---------------------+--------+---------+------+-------+-----------------------+
| Id  | User     | Host                | db     | Command | Time | State | Info                  |
+-----+----------+---------------------+--------+---------+------+-------+-----------------------+
|   8 | user     | <HOST>              | DBs    | Sleep   |    3 |       | NULL                  |
| 722 | user     | <HOST>              | DBs    | Sleep   | 8205 |       | NULL                  |
| 726 | user     | <HOST>              | DBs    | Sleep   | 8212 |       | NULL                  |
| 727 | user     | <HOST>              | DBs    | Sleep   | 8205 |       | NULL                  |
| 728 | user     | <HOST>              | DBs    | Sleep   | 8205 |       | NULL                  |
| 730 | user     | <HOST>              | DBs    | Sleep   | 7172 |       | NULL                  |
| 732 | user     | <HOST>              | DBs    | Sleep   | 8095 |       | NULL                  |
| 733 | user     | <HOST>              | DBs    | Sleep   | 8055 |       | NULL                  |
| 735 | user     | <HOST>              | DBs    | Sleep   | 8075 |       | NULL                  |
| 736 | user     | <HOST>              | DBs    | Sleep   | 8075 |       | NULL                  |
| 737 | user     | <HOST>              | DBs    | Sleep   | 8035 |       | NULL                  |
| 738 | user     | <HOST>              | DBs    | Sleep   | 8015 |       | NULL                  |
| 740 | user     | <HOST>              | DBs    | Sleep   | 7995 |       | NULL                  |
| 741 | user     | <HOST>              | DBs    | Sleep   | 7975 |       | NULL                  |
| 742 | user     | <HOST>              | DBs    | Sleep   | 7955 |       | NULL                  |
| 774 | user     | <HOST>              | DBs    | Sleep   | 5772 |       | NULL                  |
| 779 | user     | <HOST>              | DBs    | Sleep   | 6068 |       | NULL                  |
| 806 | user     | <HOST>              | DBs    | Query   |    0 | init  | SHOW FULL PROCESSLIST |
+-----+----------+---------------------+--------+---------+------+-------+-----------------------+

呼唤

show engine innodb status

返回很多事务,一些活动,一些未启动.但是没有有关锁定查询的信息.

此查询,据说可以为我提供有关被阻止查询的信息,返回空集:

SELECT r.trx_id waiting_trx_id, r.trx_mysql_thread_id waiting_thread, r.trx_query waiting_query, b.trx_id blocking_trx_id,  b.trx_mysql_thread_id blocking_thread, b.trx_query blocking_query FROM       information_schema.innodb_lock_waits w INNER JOIN information_schema.innodb_trx b  ON   b.trx_id = w.blocking_trx_id INNER JOIN information_schema.innodb_trx r  ON   r.trx_id = w.requesting_trx_id;

有了所有这些信息,我可以保证没有死锁吗?

您是否会对可能发生的事情有一些猜测,以便我可以对此进行研究?

有什么办法可以获取有关流程的更多信息?

我是数据库管理和MySQL的新手.

谢谢

解决方法:

锁等待延迟

锁定等待可能就是您的意思.您可以通过启用慢速查询日志,收集一堆日志然后进行检查来监视锁定等待.这是一个例子:

# Time: 140605 15:00:06
# User@Host: appuser[appuser] @  [127.0.0.1]  Id:    29
# Schema:   Last_errno: 0  Killed: 0
# Query_time: 0.011732  Lock_time: 0.000161  Rows_sent: 214  Rows_examined: 214  Rows_affected: 0
SET timestamp=1402005606;
SELECT ...blah blah blah...

您可以在上方看到Lock_time字段,该字段显示查询在开始执行之前等待了161微秒的锁定.然后只需不到12毫秒即可执行(由Query_time显示).

Lock_time很小通常是很平常的,通常它甚至超出了范围,因此显示为0.000000.如果进入数百毫秒或更长时间,那是不寻常的.如果整秒钟都陷入困境,那您就麻烦了.

请注意,除非Query_time超过了您的配置变量long_query_time,即使Lock_time很大,慢速查询日志条目也不会写入日志.有关此的更多讨论,请参见http://www.mysqlperformanceblog.com/2012/11/22/get-me-some-query-logs/

连接延迟

您还提到,这可能是由于在运行任何查询之前获取连接而导致的延迟.您需要跟踪是否是这种情况.在任何应用程序语言中,都应该很容易读取连接数据库之前和之后的时间,并进行比较以了解需要花费多长时间.有些框架甚至为每个查询提供了这种类型的应用程序级分析(或者您可以自己完成).

例如,导致连接延迟的一个常见原因是,MySQL服务器正在执行反向DNS查找,以将传入套接字的IP地址转换为主机名.这样做是为了在授权表中查找主机名,以找出user @ host拥有哪些特权.但是,如果您的DNS服务器速度很慢或过载,则速度可能会很慢.令人惊讶的是,这可能超过一秒钟的时间,但是它是可能的.

您可以通过设置配置变量skip_name_resolve来加快速度.这意味着您不能基于主机名向用户授予特权,而只能通过IP地址来标识用户.现实世界中大多数生产MySQL实例都设置了skip_name_resolve.

可能还有其他导致连接速度慢的原因,但首先进行一些应用程序分析,以最终确定是连接速度慢还是查询.

附注:许多人在表示“锁定等待”时会说“僵局”.死锁是指两个事务因等待对方的锁而卡住而无法继续进行时.死锁不会导致延迟,因为InnoDB会立即注意到周期性依赖关系并杀死其中一个事务.您可以在“显示引擎INNODB状态”的标题为“最新死锁”的部分中查看是否有死锁.

标签:locking,mysql
来源: https://codeday.me/bug/20191121/2053228.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有