Ale*_*vic 11 mysql innodb mysqldump backup mysql-5.6
如果我使用 mysqldump --single-transaction,根据文档,它应该使用读锁刷新表以获得一致的状态,然后启动事务,并且不应该等待写入者。
但是,我昨晚发现了以下情况:
摘自显示完整的进程列表:
数百个……
Command: Query
Time: 291
State: Waiting for table flush
Info: insert into db_external_notification.....
Run Code Online (Sandbox Code Playgroud)
那么这个:
Command: Query
Time: 1204
State: Sending data
Info: SELECT /*!40001 SQL_NO_CACHE */ * FROM `db_external_notification`
Run Code Online (Sandbox Code Playgroud)
其余线程处于睡眠状态
有谁知道这些插入物在等什么?我没有看到任何 FLUSH 表或 DDL 或手册中提到的任何可能导致查询等待的内容。
完整的 mysqldump 命令
mysqldump --quick --add-drop-table --single-transaction --master-data=2 -uxx -pxx dbname
Run Code Online (Sandbox Code Playgroud)
我猜 --quick 在这里是多余的,可能是早期的遗留物,这个脚本很旧,但不应该伤害任何东西
Mic*_*bot 10
该--single-transaction的选项mysqldump 做一做FLUSH TABLES WITH READ LOCK启动备份作业之前,但只在一定条件下。这些条件之一是您还指定了该--master-data选项。
在源代码中,从mysql-5.6.19/client/mysqldump.c第 5797 行开始:
if ((opt_lock_all_tables || opt_master_data ||
(opt_single_transaction && flush_logs)) &&
do_flush_tables_read_lock(mysql))
goto err;
Run Code Online (Sandbox Code Playgroud)
为了在开始可重复读取事务之前获得对精确 binlog 坐标的可靠锁定,该--master-data选项触发获取此锁定,然后在获得 binlog 坐标后释放。
实际上,mysqldump执行 aFLUSH TABLES后接 a 是FLUSH TABLES WITH READ LOCK因为在初始刷新需要一些时间的情况下,同时执行这两项操作可以更快地获得读锁。
...然而...
一旦它获得了 binlog 坐标,就会mysqldump发出一条UNLOCK TABLES语句,所以你开始的刷新不应该有任何阻塞。任何线程都不应该是所持Waiting for table flush有的事务的结果mysqldump。
当您在Waiting for table flush状态中看到一个线程时,这应该意味着该FLUSH TABLES [WITH READ LOCK]语句已发出并且在查询开始时仍在运行——因此查询必须等待表刷新,然后才能执行。在您发布mysqldump的进程列表的情况下,正在从同一张表中读取数据,并且查询已经运行了一段时间,但阻塞查询并没有阻塞那么长时间。
这一切都表明发生了其他事情。
在 Bug #44884 中解释了一个长期存在的问题FLUSH TABLES,内部的工作方式。 如果问题仍然存在,我不会感到惊讶,如果这个问题曾经被“修复”过,我会感到惊讶,因为这是一个非常复杂的问题需要解决——在高并发环境中几乎不可能真正修复——以及任何尝试修复它会带来破坏其他东西或创造新的、不同的但仍然不受欢迎的行为的重大风险。
这似乎是对您所看到的内容的解释。
具体来说:
如果您有一个针对表运行的长时间运行的查询,并发出FLUSH TABLES,FLUSH TABLES则将阻塞,直到长时间运行的查询完成。
此外,在FLUSH TABLES发出之后开始的任何查询都将阻塞,直到FLUSH TABLES完成。
此外,如果您终止FLUSH TABLES查询,被阻塞的查询仍将阻塞在原始长时间运行的查询上,即阻塞FLUSH TABLES查询的查询,因为即使被终止的查询FLUSH TABLES没有完成,该表(一个或更多,涉及长时间运行的查询)仍在刷新过程中,一旦长时间运行的查询完成,挂起的刷新就会发生——但不是之前。
这里可能的结论是另一个进程——可能是另一个 mysqldump,或者一个不明智的查询,或者一个写得不好的监控进程试图刷新一个表。
该查询随后被未知机制终止或超时,但其后遗症一直存在,直到mysqldump从相关表中读取完毕。
您可以通过FLUSH TABLES在长时间运行的查询过程中尝试复制此条件。然后开始另一个查询,这将阻塞。然后终止FLUSH TABLES查询,这不会解除对最新查询的阻止。然后杀死第一个查询,或者让它完成,最终查询将成功运行。
事后想想,这是无关的:
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
Run Code Online (Sandbox Code Playgroud)
这是正常的,因为会mysqldump --single-transaction发出 a START TRANSACTION WITH CONSISTENT SNAPSHOT,这会阻止它转储在转储过程中更改的数据。没有它,在开始时获得的 binlog 坐标将毫无意义,因为--single-transaction它不会是它声称的那样。这在任何意义上都与Waiting for table flush问题无关,因为此事务显然没有锁定。
mysqldump的--single-transaction选项不做。它会导致 mysqldump 为所有被转储的表设置一个可重复的读取事务。FLUSH TABLES WITH READ LOCK;
从您的问题中,您表示该db_external_notification表的 mysqldump SELECT 将数百个 INSERT 命令阻止到同一个表中。为什么会这样?
最有可能的事情是锁定gen_clust_index(也称为聚集索引)。这种范式导致表的数据页和索引页共存。这些索引页基于 PRIMARY KEY 或自动生成的 RowID 索引(如果没有 PRIMARY KEY)。
您应该能够通过运行SHOW ENGINE INNODB STATUS\G并查找gen_clust_index中具有排他锁的任何页面来发现这一点。对带有聚集索引的表执行 INSERT 需要一个排它锁来处理 PRIMARY KEY 的 BTREE,以及 auto_increment 的序列化。
我之前讨论过这个现象
Aug 08, 2011: InnoDB 死锁是 INSERT/UPDATE/DELETE 独有的吗?Dec 22, 2011: MySQL 死锁——无法正常重启?Dec 13, 2012:即使在 READ COMMITTED 中,MySQL InnoDB 也会在删除时锁定主键请查看您的 PastBin 的第 614-617 行
mysql tables in use 1, locked 0
MySQL thread id 6155315, OS thread handle 0x85f11b70, query id 367774810 localhost root Sending data
SELECT /*!40001 SQL_NO_CACHE */ * FROM `db_external_notification`
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
Run Code Online (Sandbox Code Playgroud)
请注意,第 617 行说
Trx read view will not see trx with id >= 1252538405, sees < 1252538391
Run Code Online (Sandbox Code Playgroud)
这告诉我什么?您有一些带有 auto_increment on 的 PRIMARY KEY id。
id表的最大值db_external_notification小于1252538391启动 mysqldump 时的最大值。当您从 中减去1252538391时1252538405,这意味着已尝试了 14 个或更多 INSERT 命令。在内部,这需要移动这个表的 auto_increment 至少 14 次。然而,由于管理这个id间隙,没有任何东西可以提交甚至推送到日志缓冲区中。
现在,查看 PasteBin 中的进程列表。除非我数错了,否则我看到 38 个数据库连接在执行 INSERT(19 个在 mysqldump 进程之前(进程 ID 6155315),19 个之后)。我确信这些连接中有 14 个或更多由于管理 auto_increment 间隙而被冻结。
| 归档时间: |
|
| 查看次数: |
47478 次 |
| 最近记录: |