Jas*_*ett 237 mysql sql timeout lock-timeout
我正在运行以下MySQL UPDATE
语句:
mysql> update customer set account_import_id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
Run Code Online (Sandbox Code Playgroud)
我没有使用交易,为什么我会收到此错误?我甚至尝试重新启动我的MySQL服务器,它没有帮助.
该表有406,733行.
Eri*_*ski 298
如何强制解锁MySQL中的锁定表:
像这样打破锁可能导致数据库中的原子性不会在导致锁定的sql语句上强制执行.
这是hackish,正确的解决方案是修复导致锁定的应用程序.然而,当美元上线时,快速反击将使事情再次发生变化.
1)输入MySQL
mysql -u your_user -p
Run Code Online (Sandbox Code Playgroud)
2)让我们看一下锁定表的列表
mysql> show open tables where in_use>0;
Run Code Online (Sandbox Code Playgroud)
3)让我们看一下当前进程的列表,其中一个是锁定你的表
mysql> show processlist;
Run Code Online (Sandbox Code Playgroud)
4)杀死其中一个过程
mysql> kill <put_process_id_here>;
Run Code Online (Sandbox Code Playgroud)
Mar*_*rkR 192
您正在使用交易; autocommit不会禁用事务,它只是使它们在语句结束时自动提交.
发生的事情是,其他一些线程在一些记录上持有记录锁(你正在更新表中的每条记录!)太久了,你的线程正在超时.
您可以通过发出一个来查看事件的更多细节
SHOW ENGINE INNODB STATUS
Run Code Online (Sandbox Code Playgroud)
事件发生后(在sql
编辑中).理想情况下,在安静的测试机上进行此操作.
小智 90
mysql> set innodb_lock_wait_timeout=100
Query OK, 0 rows affected (0.02 sec)
mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 100 |
+--------------------------+-------+
Run Code Online (Sandbox Code Playgroud)
现在再次触发锁定.您有100秒的时间向SHOW ENGINE INNODB STATUS\G
数据库发出一个并查看哪个其他事务正在锁定您的数据库.
小智 64
看看您的数据库是否经过微调.特别是交易隔离.增加innodb_lock_wait_timeout变量不是一个好主意.
检查mysql cli中的数据库事务隔离级别:
mysql> SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation, @@session.transaction_isolation;
+-----------------------+-----------------+------------------------+
| @@GLOBAL.tx_isolation | @@tx_isolation | @@session.tx_isolation |
+-----------------------+-----------------+------------------------+
| REPEATABLE-READ | REPEATABLE-READ | REPEATABLE-READ |
+-----------------------+-----------------+------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
您可以获得改进de隔离级别的改进,使用像READ COMMITTED这样的oracle而不是REPEATABLE READ(InnoDB Defaults)
mysql> SET tx_isolation = 'READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)
mysql> SET GLOBAL tx_isolation = 'READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)
mysql>
Run Code Online (Sandbox Code Playgroud)
另外,如果必要,请尝试使用SELECT FOR UPDATE.
Bas*_*MHL 16
没有一个建议的解决方案适合我,但确实如此.
有些东西阻止了查询的执行.很可能是另一个查询更新,插入或删除查询中的一个表.你必须找出它是什么:
SHOW PROCESSLIST;
Run Code Online (Sandbox Code Playgroud)
找到阻止进程后,找到它id
并运行:
KILL {id};
Run Code Online (Sandbox Code Playgroud)
重新运行初始查询.
Jam*_*s C 12
MarkR所说的100%.autocommit使每个语句成为一个语句事务.
SHOW ENGINE INNODB STATUS
应该给你一些关于死锁原因的线索.仔细查看慢速查询日志,看看还有什么查询表并尝试删除正在执行完整表扫描的任何内容.行级锁定工作正常但不是在您尝试锁定所有行时!
mysql->SHOW PROCESSLIST;
kill xxxx;
Run Code Online (Sandbox Code Playgroud)
然后杀死睡眠中的哪个。就我而言,它是 2456。
小智 6
尝试更新以下两个参数,因为它们必须具有默认值。
innodb_lock_wait_timeout = 50
innodb_rollback_on_timeout = ON
要检查参数值,您可以使用以下 SQL。
显示全局变量,例如“innodb_rollback_on_timeout”;
你能更新这个表中的任何其他记录,还是这个表被大量使用?我在想的是,当它试图获取一个需要更新此记录的锁时,设置的超时已经超时.您可以增加可能有用的时间.
小智 5
在我们的例子中,问题与锁本身没有太大关系。
问题是我们的应用程序端点之一需要并行打开 2 个连接来处理单个请求。
例子:
我们的应用程序的连接池限制为 10 个连接。
不幸的是,在负载下,一旦使用了所有连接,应用程序就停止工作,我们开始遇到这个问题。我们有几个请求需要打开第二个连接才能完成,但由于连接池限制而无法完成。因此,这些请求长时间锁定 table1 行,导致后续需要锁定同一行的请求引发此错误。
解决方案:
尖端:
您可以通过尝试将连接池限制降低到 1 并测试您的应用程序来轻松检查是否有嵌套连接。