Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql锁等待超时错误_Mysql_Locking - Fatal编程技术网

Mysql锁等待超时错误

Mysql锁等待超时错误,mysql,locking,Mysql,Locking,我在我的应用程序中有一个场景,事务下的简单INSERT语句阻塞MySQL中不同行上的DELETE语句,最终DELETE语句会话超时并出现lock time out错误 我试图在下面的简单场景中解释这种情况。注意,在列上添加索引会有帮助,但是,如果我在DELETE的WHERE子句中有两列,我仍然会看到lock wait timeout。另外请注意,在我启动事务后,我需要做一些其他处理,因此事务提交或回滚只需几分钟。很难相信,即使我删除了不同于我试图插入的记录,MySQL也会阻止它 第1节: mys

我在我的应用程序中有一个场景,事务下的简单INSERT语句阻塞MySQL中不同行上的DELETE语句,最终DELETE语句会话超时并出现lock time out错误

我试图在下面的简单场景中解释这种情况。注意,在列上添加索引会有帮助,但是,如果我在DELETE的WHERE子句中有两列,我仍然会看到lock wait timeout。另外请注意,在我启动事务后,我需要做一些其他处理,因此事务提交或回滚只需几分钟。很难相信,即使我删除了不同于我试图插入的记录,MySQL也会阻止它

第1节:

mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation, @@session.tx_isolation;

 +-----------------------+----------------+------------------------+
 | @@GLOBAL.tx_isolation | @@tx_isolation | @@session.tx_isolation |
 +-----------------------+----------------+------------------------+
 | READ-COMMITTED        | READ-COMMITTED | READ-COMMITTED         |
 +-----------------------+----------------+------------------------+ 

1 row in set (0.02 sec)` 

mysql> create table testtab(col1 int, col2 int);
Query OK, 0 rows affected (0.53 sec) 
mysql> START TRANSACTION; 
Query OK, 0 rows affected (0.00 sec) 
mysql> INSERT INTO testtab values(1,1); 
Query OK, 1 row affected (0.00 sec) 
mysql> INSERT INTO testtab values(2,2); 
Query OK, 1 row affected (0.00 sec) 
第二节:

mysql> SELECT @@GLOBAL.tx_isolation, @@tx_isolation, @@session.tx_isolation; 
+-----------------------+----------------+------------------------+ 
| @@GLOBAL.tx_isolation | @@tx_isolation | @@session.tx_isolation | 
+-----------------------+----------------+------------------------+ 
| READ-COMMITTED        | READ-COMMITTED | READ-COMMITTED         | 
+-----------------------+----------------+------------------------+
 1 row in set (0.00 sec) 
mysql> DELETE FROM testtab where col1=3;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction  

有什么建议吗?

这是InnoDB锁定工作原理的结果。引用

锁定读取、更新或删除通常会对SQL语句处理过程中扫描的每个索引记录设置记录锁定。语句中是否存在排除该行的WHERE条件并不重要。InnoDB不记得确切的WHERE条件,只知道扫描了哪些索引范围

同样值得注意的是

如果没有适合语句的索引,并且MySQL必须扫描整个表来处理语句,那么表中的每一行都会被锁定,从而阻止其他用户对表的所有插入。创建好的索引非常重要,这样查询就不会不必要地扫描许多行

因此,在您的情况下,两个
insert
将两个锁定的行添加到表中。由于没有合适的索引,
delete
现在将扫描整个表。它必须锁定遇到的每一行,但要做到这一点,它必须等待
insert
创建的锁被解除(这不会及时发生)

在<代码> COL1中添加索引将解决此问题,因为<代码>删除>代码>只需考虑(使用代码)> COL1=3 < /代码>行,它可以使用索引查找,因此不会与其他事务插入的行重叠。 如果您在为“两列where条件”找到一个好的索引时遇到问题,您应该添加更多关于它的详细信息,可能会有一个适合这种情况的索引

当然,这不会阻止所有情况(例如,如果您确实想要修改同一行),因此通常最好将事务保持尽可能短,准备等待那么长的时间和/或准备在需要时重复事务


顺便说一句,这并不是对InnoDB锁的完整描述,只是解释您的情况的部分。

对于类似的示例,如果我想看到阻塞查询(显示完整进程列表仅显示会话2的查询),我有哪些选项。我尝试显示引擎innodb状态、完整进程列表等,但似乎没有显示INSERT语句,这实际上导致事务运行更长时间。