AWS Aurora 中的表锁过时?

chr*_*ris 4 mysql innodb transaction aws aurora

我们有一个 AWS Aurora(MySQL 引擎,r3.large)用于测试迁移。

我们注意到几个查询似乎根本无法运行。当我跑

show engine innodb status;
Run Code Online (Sandbox Code Playgroud)

它报告有一个表被锁定:

2017-06-21 18:20:49 2aea8928a700 Transaction:
TRANSACTION 6093969, ACTIVE 0 sec updating or deleting
mysql tables in use 1, locked 1
16 lock struct(s), heap size 376, 6164 row lock(s), undo log entries 1
MySQL thread id 12219, OS thread handle 0x2aea8928a700, query id 8842803 10.127.0.24 root updating
delete from <tablename> where id=<id>
Foreign key constraint fails for table `mydb`.`<otherTable>`:
Run Code Online (Sandbox Code Playgroud)

这是一个java应用程序。我已经停止了 tomcat 实例,并验证了没有活动连接,但锁没有清除。

我查看了 information_schema(INNODB_LOCKS、INNODB_LOCK_WAITS 和 INNODB_TRX)中的几个表,但有 0 条记录。

这是极光问题吗?除了 AWS Support 之外还有其他解决方案吗?

Rol*_*DBA 5

我不知道这是否涉及 Aurora,但有一点值得注意:有时 InnoDB 会留下锁。这是怎么发生的?

大约六年前,我回答了这个问题:InnoDB Deadlocks 是 INSERT/UPDATE/DELETE 独有的吗?. 在那篇文章中,我从 MySQL 文档中提到了以下内容:

当 InnoDB 执行一个事务的完全回滚时,该事务设置的所有锁都会被释放。但是,如果由于错误而仅回滚单个 SQL 语句,则可能会保留该语句设置的某些锁。发生这种情况是因为 InnoDB 以一种格式存储行锁,以至于它之后无法知道哪个语句设置了哪个锁。

这仍然在MySQL 5.7 Docs on Deadlock Detection and Rollback 中(第 3 段)

你在问题中说

我查看了 information_schema(INNODB_LOCKS、INNODB_LOCK_WAITS 和 INNODB_TRX)中的几个表,但有 0 条记录。

我对 6 岁问题的回答中,我展示了 Percona Nagios Check 插件使用的这个表的查询:

SELECT COALESCE(MAX(IF(p.command = 'Sleep', p.time, 0)), 0) AS idle_in_trx
FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX        AS b ON  b.trx_id = w.blocking_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX        AS r ON  r.trx_id = w.requesting_trx_id
LEFT JOIN  INFORMATION_SCHEMA.PROCESSLIST       AS p ON  p.id     = b.trx_mysql_thread_id;
Run Code Online (Sandbox Code Playgroud)

我调整了该查询以显示阻塞事务的进程 ID、被阻塞的请求事务的进程 ID 以及它们各自的值INFORMATION_SCHEMA.PROCESSLIST

SELECT COALESCE(MAX(IF(pb.command='Sleep',pb.time, 0)), 0) idle_in_trx,
pb.ID BLK_ID,pb.USER BLK_USER,pb.HOST BLK_HOST,pb.DB BLK_DB,
pb.COMMAND BLK_CMD,pb.TIME BLK_TIME,pb.STATE BLK_STATE,pb.INFO BLK_INFO,
pr.ID REQ_ID,pr.USER REQ_USER,pr.HOST REQ_HOST,pr.DB REQ_DB,
pr.COMMAND REQ_CMD,pr.TIME REQ_TIME,pr.STATE REQ_STATE,pr.INFO REQ_INFO,w.*
FROM       INFORMATION_SCHEMA.INNODB_LOCK_WAITS AS w
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX        AS b  ON b.trx_id = w.blocking_trx_id
INNER JOIN INFORMATION_SCHEMA.INNODB_TRX        AS r  ON r.trx_id = w.requesting_trx_id
LEFT JOIN  INFORMATION_SCHEMA.PROCESSLIST       AS pb ON pb.id    = b.trx_mysql_thread_id
LEFT JOIN  INFORMATION_SCHEMA.PROCESSLIST       AS pr ON pr.id    = r.trx_mysql_thread_id
\G
Run Code Online (Sandbox Code Playgroud)

如果您运行它,您将看到以下两种情况之一:

  1. 导致此日志阻塞的进程 ID
  2. 一切都为空(没有交易被阻止)。这表明锁只是卡在 LA-LA-LAND(Aurora 有问题)。在这种情况下,重新启动 RDS。