mysqldump --从属上的单事务(不停止复制)

mysqldump --从属上的单事务(不停止复制)

可以mysqldump --single-transaction在不停止复制的情况下在从属数据库上运行吗(stop slave;)?这是用于定期每日备份,以便在发生存储灾难时我们可以恢复主数据库。大多数表都是 InnoDB,只有几个是 MyISAM。

官方文件称:

“您应该在开始转储过程之前停止从属服务器上的复制,以确保转储包含一组一致的数据”。

这是什么意思consistent data?这是否意味着像最新数据?

我知道--single-transaction这意味着它从发布时开始就获取数据,因此在转储发生时新的进一步更改将不是记录到转储中。我说得对吗?

我们不想在主服务器上运行备份,因为它会给我们的应用程序带来滞后。

答案1

stop slaveTL;DR -在副本上使用备份时,您实际上不需要发出。如果您mysqldump使用默认值运行并省略--single-transaction,则默认情况下将使用锁定备份,这将自动阻止备份期间对数据库的任何更改;保持数据的一致性。这通常意味着延迟复制,但它会在备份完成时自行恢复。


MySQL 是一个关系数据库,这意味着一个表中的数据可能与另一个表中的数据有关系。例如,如果您正在接受在线订单,则可能有一个line_items表,其中一行或多行属于该orders表的一条记录,而该表又可能有一行或多行属于该users表的一条记录。

MyISAM 是一种非事务性存储引擎,这意味着无论选择哪种方式,其数据都将被允许在备份期间更改--single-transaction。以前面的示例为例,我们假设它line_items是 MyISAM。您启动备份,并且您的一位用户在备份运行时提交了订单。

update users set last_ordered_at=now() where id=306; insert into orders (user_id, created_at, ...) values (306, now(), ...); insert into line_items (order_id, product_id, ...) values (1021992, 10509, ...);

如果备份在运行之前没有读取line_items表并且您执行恢复,则结果为:

  • 订单表的最大 ID 重置为低于1021992line_items 记录的值,因此暂时处于孤立状态。
  • 更改last_ordered_at已丢失
  • 当添加其他订单时,order_id 到达1021992该订单时会神奇地添加此 line_item 记录(除非该级别有其他过滤器)。line_items在备份到达该表之前添加的任何内容都会出现此问题。
  • 猫和狗生活在一起……集体歇斯底里。

如果您的 MyISAM 数据是静态/不变的,那么使用--single-transaction就不会有问题,并且您的数据将保持一致。但请记住,现在数据是静态的,并不意味着它会一直保持静态。

如果您的 MyISAM 数据仅与其他 MyISAM 数据相关,而与事务数据无关,则可以将 MyISAM 数据移动到单独的模式,以便在备份期间可以将其与事务数据区别对待。


从 MySQL 5.6 开始,InnoDB 支持全文索引,因此 MyISAM 表实际上已经没什么用了。您可以考虑使用类似 的语句将它们转换为 InnoDB alter table [tablename] engine=innodb;。与任何更改一样,您应该在继续生产之前在开发/UAT 中对此进行评估。要一次创建所有 alter 语句,您可以使用:

select concat('alter table ', table_schema, '.', table_name, ' engine=innodb;') from information_schema.tables where engine='MyISAM' and table_schema not in ('mysql','information_schema','performance_schema');

InnoDB 使用的物理空间大约是 MyISAM 的 2-3 倍,并且这些表在修改时将被锁定以防止写入;您需要相应地规划转换。完成后,您可能需要检查服务器配置并将其调整为更适合 InnoDB。


使用 100% 事务表的一个注意事项--single-transaction是,如果您在备份期间运行 DDL(CREATE、DROP、ALTER),这些不是事务语句,通常会导致备份运行失败。这通常是一种可以通过备份监控解决的极端情况。

相关内容