DM Relay Log

DM (Data Migration) 工具的 relay log 由若干组有编号的文件和一个索引文件组成。这些有编号的文件包含了描述数据库更改的事件。索引文件包含所有使用过的 relay log 的文件名。

在启用 relay log 功能后,DM-worker 会自动将上游 binlog 迁移到本地配置目录(若使用 TiUP 部署 DM,则迁移目录默认为 <deploy_dir> / <relay_log>)。本地配置目录 <relay_log> 的默认值是 relay-dir,可在上游数据库配置文件中进行修改。自 v5.4.0 版本起,你可以在 DM-worker 配置文件中通过 relay-dir 配置本地配置目录,其优先级高于上游数据库的配置文件。

适用场景

MySQL 的存储空间是有限制的,通常会设置 binlog 的最长保存时间,当上游把 binlog 清除掉之后,如果 DM 还需要对应位置的 binlog 就会拉取失败,导致同步任务出错。每增加一个同步任务,DM 都会在上游建立一条连接用于拉取 binlog,连接数过多会对上游造成比较大的负载。开启 relay log 后,同一个上游的多个同步任务可以复用已经拉到本地的 relay log,减少了对上游的压力

在全量加增量数据迁移任务 (task-mode=all) 中,DM 需要先进行全量数据迁移,再根据 binlog 进行增量同步。若全量阶段持续时间较长,上游 binlog 可能会被清除,导致增量同步无法进行。若提前开启了 relay log,DM 会自动在本地保留足够的日志,保证增量任务正常进行

一般情况下建议开启 relay log,但需知晓 relay log 可能导致的负面作用:

由于 relay log 需要写入到磁盘中,这一过程会产生外部 IO 和一些 CPU 消耗,可能导致整个同步链路变长,从而增加数据同步的时延。对时延要求十分敏感的同步任务,暂时不推荐使用 relay log。

Relay Log - 图1

注意

DM v2.0.7 及之后的版本中,对 relay log 写入进行了优化,增加的时延和 CPU 消耗已相对较小。

使用 relay log

开启/关闭 relay log

  • v5.4.0 及之后的版本
  • v2.0.2(包含)到 v5.3.0(包含)
  • v2.0.2 之前的版本

在 v5.4.0 及之后的版本中,你可以通过将 enable-relay 设为 true 开启 relay log。自 v5.4.0 起,DM-worker 在绑定上游数据源时,会检查上游数据源配置中的 enable-relay 项。如果 enable-relaytrue,则为该数据源启用 relay log 功能。

具体配置方式参见上游数据源配置文件介绍

除此以外,你也可以通过 start-relaystop-relay 命令动态调整数据源的 enable-relay 并即时开启或关闭 relay log。

  1. start-relay -s mysql-replica-01
  1. {
  2. "result": true,
  3. "msg": ""
  4. }

Relay Log - 图2

注意

在 v2.0.2 及之后的 v2.0 版本,以及在 v5.3.0 版本中,上游数据源配置中的 enable-relay 项失效,你只能通过start-relaystop-relay命令开启和关闭 relay log。加载数据源配置时,如果 DM 发现配置中的 enable-relay 项为 true,会给出如下信息提示:

  1. Please use `start-relay` to specify which workers should pull relay log of relay-enabled sources.

Relay Log - 图3

警告

该启动方式在 v6.1 版本中标记为弃用,在未来版本可能会被移除。相关命令的输出中您会看到如下提示:start-relay/stop-relay with worker name will be deprecated soon. You can try stopping relay first and use start-relay without worker name instead

start-relay 命令可以配置一个或多个 DM-worker 为指定数据源迁移 relay log,但只能指定空闲或者已绑定了该上游数据源的 DM-worker。使用示例如下:

  1. start-relay -s mysql-replica-01 worker1 worker2
  1. {
  2. "result": true,
  3. "msg": ""
  4. }
  1. stop-relay -s mysql-replica-01 worker1 worker2
  1. {
  2. "result": true,
  3. "msg": ""
  4. }

在 v2.0.2 之前的版本(不含 v2.0.2),DM-worker 在绑定上游数据源时,会检查上游数据源配置中的 enable-relay 项。如果 enable-relaytrue,则为该数据源启用 relay log 功能。

具体配置方式参见上游数据源配置文件介绍

查询 relay log

使用 query-status -s 命令,可以查询 relay log 的状态:

  1. query-status -s mysql-replica-01

期望输出

  1. {
  2. "result": true,
  3. "msg": "",
  4. "sources": [
  5. {
  6. "result": true,
  7. "msg": "no sub task started",
  8. "sourceStatus": {
  9. "source": "mysql-replica-01",
  10. "worker": "worker2",
  11. "result": null,
  12. "relayStatus": {
  13. "masterBinlog": "(mysql-bin.000005, 916)",
  14. "masterBinlogGtid": "09bec856-ba95-11ea-850a-58f2b4af5188:1-28",
  15. "relaySubDir": "09bec856-ba95-11ea-850a-58f2b4af5188.000001",
  16. "relayBinlog": "(mysql-bin.000005, 4)",
  17. "relayBinlogGtid": "09bec856-ba95-11ea-850a-58f2b4af5188:1-28",
  18. "relayCatchUpMaster": false,
  19. "stage": "Running",
  20. "result": null
  21. }
  22. },
  23. "subTaskStatus": [
  24. ]
  25. },
  26. {
  27. "result": true,
  28. "msg": "no sub task started",
  29. "sourceStatus": {
  30. "source": "mysql-replica-01",
  31. "worker": "worker1",
  32. "result": null,
  33. "relayStatus": {
  34. "masterBinlog": "(mysql-bin.000005, 916)",
  35. "masterBinlogGtid": "09bec856-ba95-11ea-850a-58f2b4af5188:1-28",
  36. "relaySubDir": "09bec856-ba95-11ea-850a-58f2b4af5188.000001",
  37. "relayBinlog": "(mysql-bin.000005, 916)",
  38. "relayBinlogGtid": "",
  39. "relayCatchUpMaster": true,
  40. "stage": "Running",
  41. "result": null
  42. }
  43. },
  44. "subTaskStatus": [
  45. ]
  46. }
  47. ]
  48. }

暂停/恢复 relay log

pause-relayresume-relay 命令可以分别暂停及恢复拉取 relay log。这两个命令执行时都需要指定上游数据源的 source-id,例如:

  1. pause-relay -s mysql-replica-01 -s mysql-replica-02

期望输出

  1. {
  2. "op": "PauseRelay",
  3. "result": true,
  4. "msg": "",
  5. "sources": [
  6. {
  7. "result": true,
  8. "msg": "",
  9. "source": "mysql-replica-01",
  10. "worker": "worker1"
  11. },
  12. {
  13. "result": true,
  14. "msg": "",
  15. "source": "mysql-replica-02",
  16. "worker": "worker2"
  17. }
  18. ]
  19. }
  1. resume-relay -s mysql-replica-01

期望输出

  1. {
  2. "op": "ResumeRelay",
  3. "result": true,
  4. "msg": "",
  5. "sources": [
  6. {
  7. "result": true,
  8. "msg": "",
  9. "source": "mysql-replica-01",
  10. "worker": "worker1"
  11. }
  12. ]
  13. }

清理 relay log

DM 提供两种清理 relay log 的方式,手动清理和自动清理。两种清理方法都不会清理活跃的 relay log。

Relay Log - 图4

注意

  • 活跃的 relay log:该 relay log 正在被同步任务使用。活跃的 relay log 当前只在 Syncer Unit 被更新和写入,如果一个为 All 模式的同步任务在全量导出/导入阶段花费了超过数据源 purge 里配置的过期时间,该 relay log 依旧会被清除。

  • 过期的 relay log:该 relay log 文件最后被改动的时间与当前时间的差值大于配置文件中的 expires 字段。

自动数据清理

启用自动数据清理需在 source 配置文件中进行以下配置:

  1. # relay log purge strategy
  2. purge:
  3. interval: 3600
  4. expires: 24
  5. remain-space: 15
  • purge.interval

    • 后台自动清理的时间间隔,以秒为单位。
    • 默认为 “3600”,表示每 3600 秒执行一次后台清理任务。
  • purge.expires

    • 当前 relay 处理单元没有写入、或已有数据迁移任务当前或未来不需要读取的 relay log 在被后台清理前可保留的小时数。
    • 默认为 “0”,表示不按 relay log 的更新时间执行数据清理。
  • purge.remain-space

    • 剩余磁盘空间,单位为 GB。若剩余磁盘空间小于该配置,则指定的 DM-worker 机器会在后台尝试自动清理可被安全清理的 relay-log。若这一数字被设为 “0”,则表示不按剩余磁盘空间来清理数据。
    • 默认为 “15”,表示可用磁盘空间小于 15GB 时,DM-master 会尝试安全地清理 relay log。

手动数据清理

手动数据清理是指使用 dmctl 提供的 purge-relay 命令,通过指定 subdir 和 binlog 文件名,来清理掉指定 binlog 之前的所有 relay log。若在命令中不填 -subdir 选项,则默认清理最新 relay log 子目录之前的所有 relay log。

假设当前 relay log 的目录结构如下:

  1. tree .
  1. .
  2. |-- deb76a2b-09cc-11e9-9129-5242cf3bb246.000001
  3. | |-- mysql-bin.000001
  4. | |-- mysql-bin.000002
  5. | |-- mysql-bin.000003
  6. | `-- relay.meta
  7. |-- deb76a2b-09cc-11e9-9129-5242cf3bb246.000003
  8. | |-- mysql-bin.000001
  9. | `-- relay.meta
  10. |-- e4e0e8ab-09cc-11e9-9220-82cc35207219.000002
  11. | |-- mysql-bin.000001
  12. | `-- relay.meta
  13. `-- server-uuid.index
  1. cat server-uuid.index
  1. deb76a2b-09cc-11e9-9129-5242cf3bb246.000001
  2. e4e0e8ab-09cc-11e9-9220-82cc35207219.000002
  3. deb76a2b-09cc-11e9-9129-5242cf3bb246.000003

在 dmctl 中使用 purge-relay 命令的示例如下:

  • 以下命令指定的 relay log 子目录为 e4e0e8ab-09cc-11e9-9220-82cc35207219.000002,该子目录之前的 relay log 子目录为 deb76a2b-09cc-11e9-9129-5242cf3bb246.000001。所以该命令实际清空了 deb76a2b-09cc-11e9-9129-5242cf3bb246.000001 子目录,保留 e4e0e8ab-09cc-11e9-9220-82cc35207219.000002deb76a2b-09cc-11e9-9129-5242cf3bb246.000003 子目录。

    1. purge-relay -s mysql-replica-01 --filename mysql-bin.000001 --sub-dir e4e0e8ab-09cc-11e9-9220-82cc35207219.000002
  • 以下命令默认 --sub-dir 为最新的 deb76a2b-09cc-11e9-9129-5242cf3bb246.000003 子目录。该目录之前的 relay log 子目录为 deb76a2b-09cc-11e9-9129-5242cf3bb246.000001e4e0e8ab-09cc-11e9-9220-82cc35207219.000002,所以该命令实际清空了这两个子目录,保留了 deb76a2b-09cc-11e9-9129-5242cf3bb246.000003

    1. purge-relay -s mysql-replica-01 --filename mysql-bin.000001

Relay log 内部机制

目录结构

Relay log 本地存储的目录结构示例如下:

  1. <deploy_dir>/<relay_log>/
  2. |-- 7e427cc0-091c-11e9-9e45-72b7c59d52d7.000001
  3. | |-- mysql-bin.000001
  4. | |-- mysql-bin.000002
  5. | |-- mysql-bin.000003
  6. | |-- mysql-bin.000004
  7. | `-- relay.meta
  8. |-- 842965eb-091c-11e9-9e45-9a3bff03fa39.000002
  9. | |-- mysql-bin.000001
  10. | `-- relay.meta
  11. `-- server-uuid.index
  • subdir

    • DM-worker 把从上游数据库迁移到的 binlog 存储在同一目录下,每个目录都为一个 subdir
    • subdir 的命名格式为 <上游数据库 UUID>.<本地 subdir 序列号>
    • 在上游进行 primary 和 secondary 实例切换后,DM-worker 会生成一个序号递增的新 subdir 目录。
    • 在以上示例中,对于 7e427cc0-091c-11e9-9e45-72b7c59d52d7.000001 这一目录,7e427cc0-091c-11e9-9e45-72b7c59d52d7 是上游数据库的 UUID,000001 是本地 subdir 的序列号。
  • server-uuid.index:记录当前可用的 subdir 目录。

  • relay.meta:存储每个 subdir 中已迁移的 binlog 信息。例如,

    1. cat c0149e17-dff1-11e8-b6a8-0242ac110004.000001/relay.meta
    1. binlog-name = "mysql-bin.000010" # 当前迁移的 binlog 名
    2. binlog-pos = 63083620 # 当前迁移的 binlog 位置
    3. binlog-gtid = "c0149e17-dff1-11e8-b6a8-0242ac110004:1-3328" # 当前迁移的 binlog GTID

    也可能包含多个 GTID:

    1. cat 92acbd8a-c844-11e7-94a1-1866daf8accc.000001/relay.meta
    1. binlog-name = "mysql-bin.018393"
    2. binlog-pos = 277987307
    3. binlog-gtid = "3ccc475b-2343-11e7-be21-6c0b84d59f30:1-14,406a3f61-690d-11e7-87c5-6c92bf46f384:1-94321383,53bfca22-690d-11e7-8a62-18ded7a37b78:1-495,686e1ab6-c47e-11e7-a42c-6c92bf46f384:1-34981190,03fc0263-28c7-11e7-a653-6c0b84d59f30:1-7041423,05474d3c-28c7-11e7-8352-203db246dd3d:1-170,10b039fc-c843-11e7-8f6a-1866daf8d810:1-308290454"

DM 接收 binlog 的位置

  • 从保存的 checkpoint 中(默认位于下游 dm_meta 库),获取各同步任务需要该数据源的最早位置。如果该位置晚于下述任何一个位置,则从此位置开始迁移。

  • 若本地 relay log 有效(有效是指 relay log 具有有效的 server-uuid.indexsubdirrelay.meta 文件),DM-worker 从 relay.meta 记录的位置恢复迁移。

  • 若不存在有效的本地 relay log,但上游数据源配置文件中指定了 relay-binlog-namerelay-binlog-gtid

    • 在非 GTID 模式下,若指定了 relay-binlog-name,则 DM-worker 从指定的 binlog 文件开始迁移。

    • 在 GTID 模式下,若指定了 relay-binlog-gtid,则 DM-worker 从指定的 GTID 开始迁移。

  • 若不存在有效的本地 relay log,而且 DM 配置文件中未指定 relay-binlog-namerelay-binlog-gtid

    • 在非 GTID 模式下,DM-worker 从自身所有 subtask 正在同步的最早 binlog 开始迁移,直至最新。

    • 在 GTID 模式下,DM-worker 从自身所有 subtask 正在同步的最早 GTID 开始迁移,直至最新。

      Relay Log - 图5

      注意

      若上游的 relay log 被清理掉,则会发生错误。在这种情况下,需设置 relay-binlog-gtid 来指定迁移的起始位置。

探索更多