【问题标题】:How to obtain a correct dump using mysqldump and single-transaction when DDL is used at the same time?mysqldump和single-transaction在同时使用DDL时如何获取正确的dump?
【发布时间】:2010-10-01 20:56:08
【问题描述】:

我是 MySQL 新手,我正在寻找使用 mysqldump 执行在线热逻辑备份的最佳方法。 This page 建议使用这个命令行:

mysqldump --single-transaction --flush-logs --master-data=2
          --all-databases > backup_sunday_1_PM.sql

但是...如果您仔细阅读文档you find that:

--single-transaction 转储正在进行时,确保转储文件有效 (正确的表内容和二进制日志位置),不应使用其他连接 以下声明:ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE。一种 一致读取并不与这些语句隔离,因此在表上使用它们来 被转储会导致mysqldump 执行的SELECT 检索表内容 获取不正确的内容或失败。

那么,有什么方法可以防止这种可能的转储损坏情况? IE。可以暂时阻止这些语句的命令。

PS:关于这个主题的 MySQL 错误条目http://bugs.mysql.com/bug.php?id=27850

【问题讨论】:

标签: mysql mysqldump corruption


【解决方案1】:

打开mysql 命令窗口并发出以下命令:

mysql> FLUSH TABLES WITH READ LOCK;

这将锁定此 MySQL 实例上所有数据库中的所有表,直到您发出UNLOCK TABLES(或终止持有这些读锁的客户端连接)。 p>

要确认这一点,您可以打开另一个命令窗口并尝试执行 ALTERDROPRENAMETRUNCATE。这些命令挂起,等待读取锁被释放。按 Ctrl-C 终止等待。

但是当表有读锁时,您仍然可以执行mysqldump 备份。

FLUSH TABLES WITH READ LOCK 命令可能与使用mysqldump--lock-all-tables 选项相同。不是很清楚,但this doc 似乎支持它:

UNLOCK TABLES 的另一个用途是 释放获取的全局读锁 带有读锁的刷新表。

FLUSH TABLES WITH READ LOCK--lock-all-tables 都使用“全局读锁”这个短语,所以我认为它们很可能会做同样的事情。因此,您应该能够将该选项用于mysqldump 并防止并发 ALTER、DROP、RENAME 和 TRUNCATE。


回复。您的评论:以下内容来自您链接到的 MySQL 错误日志中的 Guilhem Bichot:

嗨。 --lock-all-tables 调用 FLUSH 带读锁的表。因此它是 预计会阻止 ALTER、DROP、RENAME、 或 TRUNCATE(除非有错误或 我错了)。但是, --lock-all-tables --single-transaction 不能工作(mysqldump 抛出错误信息): 因为 lock-all-tables 锁定所有 服务器的表反对写 在备份期间, 而单笔交易的目的是 让写入在备份期间发生 (通过在 交易),它们是不兼容的 在自然界中。

由此看来,您在备份期间无法获得并发访问,并同时阻止 ALTER、DROP、RENAME 和 TRUNCATE。

【讨论】:

  • 谢谢比尔,但我想要一个热备份:在备份过程中,SELECT 和 INSERT 语句必须可以访问数据库。这就是使用单事务(和 InnoDB)背后的原因。
  • 谢谢你的回答,我在使用mysqldump时有点困惑,如果上面你写的ie(不需要打开带有读锁的FLUSH TABLES的单独会话;)被确认,那么我可以制作批处理文件为了及时转储,但如果不是,那么我如何确认它或者我如何创建可以根据需要创建两个不同会话的批处理文件(保持锁定);
【解决方案2】:

虽然我在阅读文档的那部分时也有同样的想法,但我发现了更多信息:

4.5.4。 mysqldump — 数据库备份程序 http://dev.mysql.com/doc/en/mysqldump.html

对于 InnoDB 表,mysqldump 提供了一种在线 备份:

shell> mysqldump --all-databases --single-transaction > all_databases.sql

此备份在所有表上获取全局读锁(使用 FLUSH TABLES WITH READ LOCK)在转储的开头。只要这 锁已被获取,二进制日志坐标被读取并且 锁被释放。如果在运行长更新语句时 发出 FLUSH 语句,MySQL 服务器可能会停止,直到 这些陈述结束。之后,转储变为无锁并且 不会干扰对表的读取和写入。如果更新 MySQL 服务器收到的语句很短(就 执行时间),初始锁定期不应该是明显的, 即使有很多更新。

--opt--single-transaction 选项存在冲突:

--选择

此选项是简写。与指定相同 --add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables --quick --set-charset。它应该为您提供快速转储操作并生成可以重新加载的转储文件 快速导入 MySQL 服务器。

--opt 选项默认启用。使用 --skip-opt 禁用它。

如果我正确理解您的问题,您希望将实际数据和 DDL(数据定义语言)放在一起,因为如果您只需要 DDL,您将使用 --no-data。有关这方面的更多信息,请访问:

http://dev.mysql.com/doc/workbench/en/wb-reverse-engineer-create-script.html

如果你想创建 mysqldump 的 --databases 选项 数据库及其所有对象。如果没有创建数据库 db_name 语句在你的脚本文件中,你必须导入数据库 对象到现有模式中,或者,如果没有模式,则为新模式 未命名的架构已创建。

正如The Definitive Guide to MySQL 5 By Michael Kofler 所建议的,我建议以下选项:

--skip-opt
--single-transaction
--add-drop-table
--create-options
--quick
--extended-insert
--set-charset
--disable-keys

另外,没有提到的是--order-by-primary 此外,如果您使用--databases 选项,则还应使用--add-drop-database,尤其是与此answer 结合使用时。如果要备份连接在不同网络上的数据库,则可能需要使用--compress 选项。

因此,mysqldump 命令(不使用--compress--databases--add-drop-database 选项)将是:

mysqldump --skip-opt --order-by-primary --single-transaction --add-drop-table --create-options --quick --extended-insert --set-charset -h db_host -u username --password="myPassword" db_name | mysql --host=other_host db_name

我删除了书中对--disable-keys 的引用,因为据我了解,它对 InnoDB 无效。 MySql manual 声明:

对于每个表,用 /*!40000 ALTER 将 INSERT 语句括起来 表 tbl_name 禁用键 /;和 /!40000 ALTER TABLE tbl_name 启用键 */;陈述。这使得加载转储文件更快 因为索引是在插入所有行之后创建的。这 选项仅对 MyISAM 表的非唯一索引有效。

我还发现了这个错误报告http://bugs.mysql.com/bug.php?id=64309,它的底部有来自Paul DuBois who also wrote a few books 的 cmets,除了那个错误报告中发现的那些 cmets 之外,我没有关于这个特定问题的参考。

现在要创建“终极备份”,我建议考虑一下这个 shell 脚本的内容

  1. https://github.com/red-ant/mysql-svn-backup/blob/master/mysql-svn.sh

【讨论】:

  • 我没有像here 提到的那样讨论主/从,因为这不是我的选择,因为我无法以这种方式配置我正在使用的 MySql 数据库。
【解决方案3】:

如果不锁定表,您将无法获得一致的转储。我只是在一天中没有注意到转储所需的 2 分钟的时间里做我的。

一种解决方案是进行复制,然后备份从属服务器而不是主服务器。如果从服务器在备份期间错过了写入,它将稍后赶上。这也将为您提供一个实时备份服务器,以防主服务器发生故障。哪个不错。

【讨论】:

  • 鉴于所讨论的一切,这似乎是明智的路线,感谢您的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-20
  • 2018-08-28
  • 2011-07-07
  • 1970-01-01
相关资源
最近更新 更多