我是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
。一个 一致读取不会与这些语句隔离,因此在表上使用它们 被转储可能导致SELECT
执行的mysqldump
检索表内容 获取不正确的内容或失败。
那么,有没有办法防止这种可能的转储损坏情况? 即一个可以暂时阻止这些语句的命令。
的MySQL错误输入答案 0 :(得分:8)
打开mysql
命令窗口并发出以下命令:
mysql> FLUSH TABLES WITH READ LOCK;
这将锁定此MySQL实例上所有数据库中的所有表,直到您发出UNLOCK TABLES
(或终止包含这些读锁的客户端连接)。
要确认这一点,您可以打开另一个命令窗口并尝试执行ALTER
,DROP
,RENAME
或TRUNCATE
。这些命令挂起,等待释放读锁定。按Ctrl-C终止等待。
但是当表格具有读锁定功能时,您仍然可以执行mysqldump
备份。
FLUSH TABLES WITH READ LOCK
命令可能与使用--lock-all-tables
的{{1}}选项相同。这并不完全清楚,但this doc似乎支持它:
UNLOCK TABLES的另一个用途是 释放获得的全局读锁 带有读锁的FLUSH表。
mysqldump
和FLUSH TABLES WITH READ LOCK
都使用“全局读锁定”这一短语,所以我认为它们可能会做同样的事情。因此,您应该能够将该选项用于--lock-all-tables
并防止并发ALTER,DROP,RENAME和TRUNCATE。
重新。您的评论:以下内容来自您链接到的MySQL错误日志中的Guilhem Bichot:
您好。 --lock-all-tables调用FLUSH 带读锁的表格。就这样吧 预计会阻止ALTER,DROP,RENAME, 或TRUNCATE(除非有错误或 我错了)。但是, - lock-all-tables --single-transaction无法正常工作(mysqldump抛出错误信息): 因为lock-all-tables会锁定所有 服务器的表格反对写入 在备份期间, 而单一交易是有意的 让备份期间发生写入 (通过使用一致读取SELECT 一个交易),它们是不相容的 在性质上。
从这一点来看,听起来你不能在备份期间获得并发访问,同时阻止ALTER,DROP,RENAME和TRUNCATE。
答案 1 :(得分: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 在转储开始时使用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选项 数据库及其所有对象。如果没有CREATE DATABASE 脚本文件中的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 DISABLE KEYS /;和/ !40000 ALTER TABLE tbl_name ENABLE KEYS * /;声明。这样可以更快地加载转储文件 因为索引是在插入所有行之后创建的。这个 option仅对MyISAM表的非唯一索引有效。
我还发现了这个错误报告http://bugs.mysql.com/bug.php?id=64309,它在Paul DuBois who also wrote a few books的底部有评论,除了在该错误报告中发现的评论之外,我没有参考这个特定问题。
现在要创建“终极备份”,我建议考虑一下这个shell脚本的内容
答案 2 :(得分:1)
如果没有锁定表,则无法获得一致的转储。我只是在一天的时间里做我的,没有注意到2分钟的转储。
一种解决方案是进行复制,然后备份从站而不是主站。如果从站在备份期间未命中写入,它将在稍后赶上。如果主服务器出现故障,这也将为您提供实时备份服务器。哪个好。