SELECT
pl.id
,pl.user
,pl.state
,it.trx_id
,it.trx_mysql_thread_id
,it.trx_query AS query
,it.trx_id AS blocking_trx_id
,it.trx_mysql_thread_id AS blocking_thread
,it.trx_query AS blocking_query
FROM information_schema.processlist AS pl
INNER JOIN information_schema.innodb_trx AS it
ON pl.id = it.trx_mysql_thread_id
INNER JOIN information_schema.innodb_lock_waits AS ilw
ON it.trx_id = ilw.requesting_trx_id
AND it.trx_id = ilw.blocking_trx_id
请参阅 Marko 的 InnoDB 表链接和注意事项。
对于 MyISAM,没有一个简单的“这是有问题的查询”的解决方案。您应该始终从流程列表开始。但请务必包含完整的关键字,以便打印的查询不会被截断:
这将显示所有当前进程的列表、它们的 SQL 查询和状态。现在通常如果单个查询导致许多其他查询锁定,那么它应该很容易识别。受影响的查询将具有状态,
Locked
并且有问题的查询将自行退出,可能正在等待一些密集的东西,例如临时表。如果不是很明显,那么您将不得不使用您的 SQL 演绎能力来确定哪条有问题的 SQL 可能是您陷入困境的原因。
如果您使用 InnoDB 并且需要检查正在运行的查询,我建议
show engine innodb status;
如Marko的链接中所述。这将为您提供锁定查询,有多少行/表被它锁定等。查看事务。
使用的问题
SHOW PROCESSLIST
是除非其他查询排队,否则您将看不到锁。尝试
SHOW OPEN TABLES
:没有一个答案可以显示当前持有的所有锁。
例如在终端中的 mysql 中执行此操作。
显然,上面的事务持有锁,因为事务仍然处于活动状态。但是现在没有查询正在进行,也没有人在任何地方等待锁(至少)。
INFORMATION_SCHEMA.INNODB_LOCKS
是空的,考虑到文档,这是有道理的,因为只有一个事务,目前没有人在等待任何锁。无论如何也INNODB_LOCKS
已弃用。SHOW ENGINE INNODB STATUS
没用:someTable
根本没有提到SHOW FULL PROCESSLIST
是空的,因为罪魁祸首现在实际上并没有运行查询。您可以使用
INFORMATION_SCHEMA.INNODB_TRX
,performance_schema.events_statements_history
和performance_schema.threads
提取任何活动事务在过去执行的查询,如我的其他答案中所述,但我没有遇到任何方式看到someTable
在上述场景中被锁定。到目前为止,其他答案中的建议至少无济于事。
免责声明:我没有安装 innotop,也没有打扰。也许这可以奏效。
参考来自这篇文章。
您可以使用以下脚本:
使用此命令
将显示当前正在运行的所有进程,包括已获得表锁定的进程。
AFAIK 在 MYSQL 中仍然没有原生方式,但我使用innotop。它是免费的,并且还具有许多其他功能。
另请参阅此链接以获取有关使用 innotop 工具的更多信息。