在不锁定表的情况下运行 MySQLDump
Posted
技术标签:
【中文标题】在不锁定表的情况下运行 MySQLDump【英文标题】:Run MySQLDump without Locking Tables 【发布时间】:2010-09-11 09:38:49 【问题描述】:我想将一个实时生产数据库复制到我的本地开发数据库中。有没有办法在不锁定生产数据库的情况下做到这一点?
我目前正在使用:
mysqldump -u root --password=xxx -h xxx my_db1 | mysql -u root --password=xxx -h localhost my_db1
但它会在运行时锁定每个表。
【问题讨论】:
另一个较晚的解决方案:您还可以使用 Percona XtraBackup 转储生产数据库,而不会中断事务处理。它允许进行热备份,即它不会影响当前的活动。见这里:percona.com/software/mysql-database/percona-xtrabackup(我与 Percona 没有任何关系。) 【参考方案1】:如果您使用 Percona XtraDB 集群 - 我发现添加 --skip-add-locks 到 mysqldump 命令 允许 Percona XtraDB Cluster 运行转储文件 在转储文件中没有关于 LOCK TABLES 命令的问题。
【讨论】:
【参考方案2】:--lock-tables=false
选项有效吗?
根据man page,如果您要转储 InnoDB 表,您可以使用--single-transaction
选项:
--lock-tables, -l
Lock all tables before dumping them. The tables are locked with READ
LOCAL to allow concurrent inserts in the case of MyISAM tables. For
transactional tables such as InnoDB and BDB, --single-transaction is
a much better option, because it does not need to lock the tables at
all.
对于 innodb 数据库:
mysqldump --single-transaction=TRUE -u username -p DB
【讨论】:
for innodb DB mysqldump --single-transaction=TRUE -u username -p DB 如果你有 innodb 和 myisam 怎么办? 默认开启吗? 明显开启(即锁定)? 我认为您不能将选项传递给 --lock-tables,所以不要认为 --lock-tables=false 会起作用【参考方案3】:对于 InnoDB 表,使用标志 --single-transaction
它在BEGIN时转储数据库的一致状态 发布时没有阻止任何应用程序
MySQL 文档
http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_single-transaction
【讨论】:
也许和--skip-lock-tables
一起。【参考方案4】:
使用 MySQL Workbench 时,在 Data Export 中单击 Advanced Options 并取消选中“lock-tables”选项。
【讨论】:
【参考方案5】:由于https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html#option_mysqldump_lock-tables:
某些选项,例如 --opt(默认启用)会自动启用 --lock-tables。如果您想覆盖它,请在选项列表的末尾使用 --skip-lock-tables。
【讨论】:
【参考方案6】:另一个迟到的答案:
如果您尝试制作服务器数据库的热副本(在 linux 环境中)并且所有表的数据库引擎都是 MyISAM,您应该使用mysqlhotcopy
。
根据文档:
它使用 FLUSH TABLES、LOCK TABLES 和 cp 或 scp 来创建数据库 备份。这是一种快速备份数据库或单个 表,但它只能在数据库所在的同一台机器上运行 目录位于。 mysqlhotcopy 仅用于备份 MyISAM 和 ARCHIVE 表。
LOCK TABLES
时间取决于服务器可以复制 MySQL 文件的时间(它不会进行转储)。
【讨论】:
【参考方案7】:由于这些方法都不适合我,我只是做了一个:
mysqldump [...] | grep -v "LOCK TABLE" | mysql [...]
它将排除LOCK TABLE <x>
和UNLOCK TABLES
命令。
注意:希望您的数据中不包含该字符串!
【讨论】:
--skip-add-locks 在转储期间也会这样做【参考方案8】:答案因您使用的存储引擎而异。理想的情况是您使用 InnoDB。在这种情况下,您可以使用--single-transaction
标志,它会在转储开始时为您提供数据库的一致快照。
【讨论】:
【参考方案9】:--skip-add-locks
帮助了我
【讨论】:
或 --compact 以包含带有其他优化的跳过锁。 这会从转储文件中删除 LOCK TABLES 和 UNLOCK TABLES 语句,它不会影响导出期间的锁定。 不,这不是您要找的!请参阅 dabest1 的评论。这并不能防止您的表在执行 mysqldump 时被锁定。这不是问题的答案。 @dabest 和 @orrd 是正确的:--skip-add-locks
只会使转储恢复更快。这不是正确答案。【参考方案10】:
与那个说他对原始答案迟到的人相比,这大约是迟到了,但就我而言(在 Windows 7 上通过 WAMP 的 MySQL),我不得不使用:
--skip-lock-tables
【讨论】:
这对我有用,可以转储 information_schema,而不会出现错误“使用 LOCK TABLES 时用户 'debian-sys-maint'@'localhost' 拒绝访问数据库 'information_schema'” @miken32 你的意思是建议--skip-add-locks
的答案?这绝对和--skip-lock-tables
不一样。感谢您花时间在 9 年后错误地指出这一点。 :)【参考方案11】:
要转储大型表,您应该将 --single-transaction 选项与 --quick 结合使用。
http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_single-transaction
【讨论】:
选项 --quick 现在是选项 --opt 的一部分。并且 --opt 默认是启用的。【参考方案12】: mysqldump -uuid -ppwd --skip-opt --single-transaction --max_allowed_packet=1G -q db | mysql -u root --password=xxx -h localhost db
【讨论】:
赞成,这个对我有用,只需添加参数 --skip-opt --single-transaction --max_allowed_packet=1G 我不建议为此使用“--skip-opt”。这比原始问题所要求的要多得多。它关闭快速模式,它不包括字符集等。【参考方案13】:这太晚了,但对任何正在搜索该主题的人都有好处。如果您不是 innoDB,并且您在转储时不担心锁定,只需使用以下选项:
--lock-tables=false
【讨论】:
感谢沃伦的回复,这很有帮助,而且效果很好。 使用 '--lock-table=false --quick' 使用最少的服务器资源 但是您应该担心锁定表。如果在运行 mysqldump 时写入多个表(并且您使用外键),则转储可能不一致。在您恢复它并碰巧对不一致的数据运行 JOIN 查询之前,您不会知道。可能需要一段时间才能发现不一致的数据,因为您的应用程序使用 JOIN,而不是 Mysql(使用 MyISAM 表);恢复会正常工作,mysql 不会警告你不一致的地方。所以:MyIsam -> 总是锁定你的桌子。 InnoDB -> 使用--single-transaction
.
@Costa 我不认为锁定表对于 MyISAM 表来说是足够的。如果mysqldump 锁定了应用程序执行的查询之间 之间的表,那么你最终会遇到同样的不一致。答案更简单:MyISAM -> 改用 InnoDB。
@Costa 您绝对应该担心锁定表,但前提是确实需要一致的转储。在极少数情况下您不这样做。例如,关于数据库范围转储(调试)的粗略 fgrep:我敢打赌,不希望用户等待约 20 分钟来创建生产数据库的转储(真实故事)。 如果关键是不仅要尽快获得转储,而且要保持一致,则应转储复制的从属设备或使用较低级别的快照(lvm、zfs、btrfs 等),请记住FLUSH TABLES WITH READ LOCK
stuff .【参考方案14】:
老实说,我会为此设置复制,就好像你不锁定表一样,你会从转储中得到不一致的数据。
如果转储需要更长的时间,已经转储的表可能会随着一些即将转储的表发生变化。
所以要么锁定表,要么使用复制。
【讨论】:
整个数据库几乎都是只读的,所以我不太担心它会发生变化。 此评论不正确。 MVCC 允许在不锁定 InnoDB 的情况下读取一致的状态。 如果你还没有设置复制,那么你需要做一个转储来设置它。存在同样的问题。 如果您还没有设置复制,那么您需要锁定表以进行转储以确保数据完整性。所以这是一个陷阱 22。以上是关于在不锁定表的情况下运行 MySQLDump的主要内容,如果未能解决你的问题,请参考以下文章
如何在不锁定表的情况下向 Postgres 中的 ENUM 添加新值?
在不锁定集合的情况下从通用集合中获取 Count 值是不是安全?