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

如何检测MySQL中的死锁?在建立连接时,什么会导致我的应用程序挂起?,mysql,locking,Mysql,Locking,我有一个应用程序与数据库有一些问题:当它试图打开与数据库的连接(或执行查询,这不清楚)时,它突然冻结。没有错误消息。我怀疑有一些查询阻塞了其他查询,我正在试图弄清楚这是什么。 我曾经 但当我执行时: show profiles; 我只得到我自己执行的查询,而不是应用程序查询(应用程序和我使用的是同一个用户) 召唤 SHOW FULL PROCESSLIST; 返回包含所有进程的表 +-----+----------+---------------------+--------+------

我有一个应用程序与数据库有一些问题:当它试图打开与数据库的连接(或执行查询,这不清楚)时,它突然冻结。没有错误消息。我怀疑有一些查询阻塞了其他查询,我正在试图弄清楚这是什么。 我曾经

但当我执行时:

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 |
+-----+----------+---------------------+--------+---------+------+-------+-----------------------+
返回大量事务,有些是活动的,有些是未启动的。但是没有关于锁定查询的信息

这个查询,应该会给我有关阻塞查询的信息,返回一个空集:

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\u time
,该字段显示查询在开始执行之前等待锁的时间为161微秒。然后执行不到12毫秒(显示为
Query\u time

锁紧时间通常很小,通常它甚至超出范围,所以它只显示为0.000000。如果达到数百毫秒或更高,这是不寻常的。如果进入整秒钟,你就有麻烦了

请注意,除非
query\u time
超过配置变量
long\u query\u time
——即使
Lock\u time
很大,否则慢速查询日志条目不会写入日志。有关这方面的更多讨论,请参阅

连接延迟 您还提到,这可能是由于在运行任何查询之前获取连接造成的延迟。你需要查明情况是否如此。在任何应用程序语言中,读取连接到数据库之前和之后的时间都应该很容易,并比较它们以查看所需的时间。有些框架甚至为每个查询提供这种类型的应用程序级评测(或者您自己也可以这样做)

例如,连接延迟的一个常见原因是MySQL服务器正在进行反向DNS查找,以将传入套接字的IP地址转换为主机名。它这样做是为了能够在grant表中查找主机名,以确定所需的权限user@host有但是,如果您的DNS服务器速度慢或过载,则这可能会很慢。令人惊讶的是,这将超过一秒的几分之一,但这是可能的

通过设置配置变量
skip\u name\u resolve
,可以加快速度。这意味着您不能基于主机名向用户授予权限,您必须仅通过IP地址标识用户。现实世界中的大多数MySQL生产实例都设置了
跳过\u name\u resolve

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



注:很多人说“死锁”是指“锁等待”。死锁是指两个事务在等待对方的锁时被卡住,无法继续进行。死锁不会导致延迟,因为InnoDB会立即注意到周期性依赖并终止其中一个事务。您可以在标题为“最新死锁”的部分中查看SHOW ENGINE INNODB状态中是否出现死锁。

您显示的内容中没有锁定,但无法“保证”之前没有死锁。如果不知道使用此数据库的应用程序,则很难为您提供帮助,但如果您想记录死锁错误,请查看。这是我自己的应用程序,因此我无法提供更多信息(在dev下,没有人知道)。非常感谢,这正是:锁定等待。系统未释放与数据库的连接,因此应用程序正在等待接收连接。谢谢
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;
# 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...