Compartir a través de

MySQL 到 Azure Database for MySQL 的数据迁移 - MySQL 一致性快照

MySQL 一致性快照是一项新功能,让用户能够执行 MySQL 服务器的一致性快照,而不会由于正在进行的 CRUD(创建、读取、更新和删除)操作丢失源上的数据完整性。 无需通过此功能将源服务器设置为只读模式即可实现事务一致性。 此外,向用户提供了多个数据一致性选项 - 启用带有读取锁的一致性快照 (GA)、启用不带锁的一致性快照(预览版)、将源服务器设为“只读”和“无”。 如果选择“无”选项,则无需采取额外的措施就能确保数据一致性。 这两个选项 - 启用带读取锁的一致快照 (GA)、启用不带锁的一致快照 - 都支持执行联机迁移。 强烈建议选择“启用不带锁的一致性快照”选项,以保持事务一致性。

MySQL 到 Azure Database for MySQL 数据迁移向导 - 启用事务一致性的屏幕截图。

启用不带锁的一致性快照(预览版)

如果启用此选项,初始加载后会有一个协调阶段。 这是为了确保写入目标的数据在事务上与二进制日志中特定位置的源服务器保持一致。

使用此功能时,服务器上没有读取锁。 我们改为在不同的时间点读取表,同时跟踪每个表的不同二进制日志位置。 这有助于通过在弥补模式下执行复制来获取一致的快照,在初始负载结束时协调表。

MySQL 到 Azure Database for MySQL 数据迁移向导 - 迁移进度的屏幕截图。

MySQL 到 Azure Database for MySQL 数据迁移向导 - 协调进度的屏幕截图。

不使用锁的一致性快照的主要功能:

  • 能够支持工作负载过重的服务器或事务长时间运行的服务器,而无需读锁。
  • 即使在发生暂时性网络/服务器故障,导致所有预先创建的连接丢失的情况下,也能稳健地完成迁移。

启用带有读取锁的一致性快照 (GA)

启用此选项后,服务会使用读取锁刷新源服务器上的所有表,以获取时间点快照。 此刷新已完成,因为全局锁比尝试锁定单个数据库或表更可靠。 因此,即使未迁移服务器中的所有数据库,数据库也会在设置迁移过程期间进行锁定。 迁移服务启动可重复读取,并将当前表状态与快照的撤消日志的内容组合在一起。 获取服务器范围内的锁并生成多个迁移连接后的几秒钟内,会生成快照。 创建用于迁移的所有连接后,将释放表上的锁。

启用可重复读取以在迁移期间保持撤消日志的可访问性,由于长时间运行的连接,这会增加源上所需的存储。 具有多个表更改的长时间运行的迁移会导致大量撤消日志历史记录需要重播,还可能会增加源服务器上的计算要求和负载。

将源服务器设置为只读

选择此选项可在迁移过程中禁止对源服务器进行写入/删除操作,从而维护目标数据库的数据完整性。 如果在迁移过程中将源服务器设置为只读,所做选择将应用于源服务器的所有数据库,无论是否选择这些数据库进行迁移。

使源服务器只读会阻止用户修改数据,使数据库无法执行任何更新操作。 但是,如果未启用此选项,则可能在迁移期间进行数据更新。 因此,迁移的数据可能不一致,因为数据库快照将在不同的时间点读取。

启用带有读取锁的一致性快照的先决条件

为了在启用读取锁的情况下使用一致性快照成功完成迁移,请执行以下操作:

  • 确保尝试使用读取锁刷新表的用户具有 RELOAD 或 FLUSH 权限。

  • 使用 mysql 客户端工具确定是否在源服务器上启用了 log_bin。 默认情况下,二进制日志并不总是打开的,应在开始迁移之前检查是否启用了该日志。 mysql 客户端工具用于通过运行以下命令来确定是否在源上启用 log_binSHOW VARIABLES LIKE “log_bin”;

注意

在 Azure Database for MySQL 单一服务器(最多支持 4TB)中,默认未启用它。 但是,如果提升源服务器的只读副本,然后删除只读副本,该参数会设置为 ON。

  • 在源服务器上配置 binlog_expire_logs_seconds 参数,确保在副本提交更改之前不会清除二进制日志文件。 成功转换后,可以重置该值。

启用不带锁的一致性快照的已知问题和限制

  • 不支持外键在 delete/update 子句上具有 Cascade 或 Set Null 的表。
  • 初始加载期间不应发生 DDL 更改。

启用带有读取锁的一致性快照的已知问题和限制

与一致备份相关的已知问题和限制大致分为两类:锁定和重试。

注意

迁移服务为所有工作线程运行 START TRANSACTION WITH CONSISTENT SNAPSHOT 查询以获取服务器快照。 但仅 InnoDB 支持此功能。 在此处了解详细信息。

通常,获取锁的过程非常简单,需要几秒钟到几分钟的时间才能完成。 但是,在某些情况下,尝试在源服务器上获取锁定可能会失败。

  • 存在长期查询可能会导致不必要的停机,因为 DMS 可能会锁定表的子集,然后超时,等待最后几个变得可用。 在开始迁移之前,请运行 SHOW PROCESSLIST 命令检查是否有长期操作。

  • 如果源服务器在请求锁时遇到许多写入更新,则无法随时获取锁,并且在锁等待超时后可能会失败。 这种情况发生在表中的批处理任务时,这可能会导致拒绝对锁的请求。 如前所述,请求的锁是整个服务器的单个全局级锁,因此,即使单个表或数据库正在处理,锁定请求必须等待正在进行的任务结束。

  • 另一个限制与从 AWS RDS 源服务器迁移有关。 RDS 不支持刷新具有读取锁的表,并且 LOCK TABLE 查询在后台的所选表上运行。 由于表单独锁定,锁定过程可能不太可靠,锁可能需要更长的时间才能获取。

重试

迁移会处理暂时性连接问题,并且通常为此预先预配其他连接。 我们查看迁移设置,尤其是源上的并行读取操作数,并应用一个因素(通常大约为 1.5),并提前创建尽可能多的连接。 这样一来,该服务可确保我们可以并行运行操作。 在任何时间点,如果连接丢失或服务无法获取锁,该服务将使用预配的剩余连接重试迁移。 如果所有预配的连接都用尽,导致时间点同步丢失,则必须从头开始重启迁移。 如果成功和失败,此脱机迁移服务将执行所有清理操作,用户不必执行任何显式清理操作。