<p>我想在这里介绍一些我在寻找解决这个问题的方法。我不是MySQL方面的专家,但我认为这些步骤可以帮助任何想知道为什么他有锁等待超时的人</p>
<p>因此,我采取的故障排除步骤如下:</p>
<p>1-检查我是否可以在MySQL慢速日志中找到锁定我的表的相关查询。通常,可以找到运行时间很长的查询,也可以锁定下面的信息和后面的查询</p>
<pre><code># Time: 2020-01-28T17:31:48.634308Z
# User@Host: @ localhost [::1] Id: 980397
# Query_time: 250.474040 Lock_time: 0.000000 Rows_sent: 10 Rows_examined: 195738
</code></pre>
<p>2-以上应该提供一些关于服务器中发生了什么以及什么可能会等待很长时间的线索。接下来,我运行了以下3个查询以确定正在使用的内容:</p>
<ul>
<li>检查正在运行进程的进程列表-</li>
</ul>
<p><code>show full processlist;</code></p>
<ul>
<li>检查当前正在使用的表-</li>
</ul>
<p><code>show open tables where in_use>0;</code></p>
<ul>
<li>检查正在运行的事务-</li>
</ul>
<p><code>SELECT * FROM `information_schema`.`innodb_trx` ORDER BY `trx_started`;</code></p>
<p>3-以上两个步骤应提供有关哪个查询正在锁定表的足够信息。在我这里的例子中,我有一个运行<code>insert into <different table> select from <my locked table></code>的SP,当它插入到一个完全不同的表时,由于select操作花费了很长时间,这个查询锁定了我的表。
为了解决这个问题,我将SP改为使用临时表,现在虽然查询仍然没有完全优化,但我的表上没有锁</p>
<p>在此添加如何在临时表上运行SP以进行异步聚合更新</p>
<pre><code>CREATE DEFINER=`username`@`%` PROCEDURE `procedureName`()
BEGIN
drop temporary table if exists scheme.temp1;
drop temporary table if exists scheme.temp2;
drop temporary table if exists scheme.temp3;
create temporary table scheme.temp1 AS select * from scheme.live1;
create temporary table scheme.temp2 AS select * from scheme.live2;
create temporary table scheme.temp3 AS select * from scheme.live3;
create temporary table scheme.emptytemp (
`cName1` int(11) NOT NULL,
`cName2` varchar(45) NOT NULL,
`cName3` int(11) NOT NULL,
`cName4` datetime NOT NULL,
`cName5` datetime NOT NULL,
KEY `cName1` (`cName1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
INSERT into scheme.emptytemp
select t1.x,t2.y,t3.z
from scheme.temp1 t1
JOIN scheme.temp2 t2
ON t1.x = t2.x
JOIN scheme.temp3 t3
ON t2.y = t3.y
truncate table scheme.liveTable;
INSERT into scheme.liveTable
select * from scheme.emptytemp;
END
</code></pre>
<p>希望这能帮助任何遇到这个问题的人</p>