pingcap

TiDB Binlog 常见问题

TiDB Binlog 常见问题

本文介绍 TiDB Binlog 使用过程中的常见问题及解决方案。

开启 binog 对 TiDB 的性能有何影响?

  • 对于查询无影响。

  • 对于有写入或更新数据的事务有一点性能影响。延迟上,在 Prewrite 阶段要并发写一条 p-binlog 成功后才可以提交事务,一般写 binlog 比 KV Prewrite 快,所以不会增加延迟。可以在 Pump 的监控面板看到写 binlog 的响应时间。

Drainer 同步下游 TiDB/MySQL 的帐号需要哪些权限?

Drainer 同步帐号需要有如下权限:

  • Insert
  • Update
  • Delete
  • Create
  • Drop
  • Alter
  • Execute
  • Index
  • Select

Pump 磁盘快满了怎么办?

确认 GC 正常:

  • 确认 pump 监控面板 gc_tso 时间是否与配置一致。

如 gc 正常以下调整可以降低单个 pump 需要的空间大小:

  • 调整 pump GC 参数减少保留数据天数。
  • 添加 pump 结点。

Drainer 同步中断怎么办?

使用以下 binlogctl 命令查看 Pump 状态是否正常,以及是否全部非 offline 的 Pump 都在正常运行。

{{< copyable "shell-regular" >}}

binlogctl -cmd pumps

查看 Drainer 监控与日志是否有对应报错,根据具体问题进行处理。

Drainer 同步下游 TiDB/MySQL 慢怎么办?

特别关注以下监控项:

  • 通过 Drainer 监控 drainer event,可以看到 Drainer 当前每秒同步 Insert/Update/Delete 事件到下游的速度。
  • 通过 Drainer 监控 sql query time,可以看到 Drainer 在下游执行 SQL 的响应时间。

同步慢的可能原因与解决方案:

  • 同步的数据库包含没有主键或者唯一索引的表,需要给表加上主键。
  • Drainer 与下游之间延迟大,可以调大 Drainer worker-count 参数(跨机房同步建议将 Drainer 部署在下游)。
  • 下游负载不高,可以尝试调大 Drainer worker-count 参数。

假如有一个 Pump crash 了会怎样?

Drainer 会因为获取不到这个 Pump 的数据没法同步数据到下游。如果这个 Pump 能恢复,Drainer 就能恢复同步。

如果 Pump 没法恢复,可采用以下方式进行处理:

  1. 使用 binlogctl 将该 Pump 状态修改为 offline(丢失这个 Pump 的数据)
  2. Drainer 获取到的数据会丢失这个 Pump 上的数据,下游跟上游数据会不一致,需要重新做全量 + 增量同步。具体步骤如下:

    1. 停止当前 Drainer。
    2. 上游做全量备份。
    3. 清理掉下游数据,包括 checkpoint 表 tidb_binlog.checkpoint
    4. 使用上游的全量备份恢复下游数据。
    5. 部署 Drainer,使用 initialCommitTs= {从全量备份获取快照的时间戳}。

什么是 checkpoint?

Checkpoint 记录了 Drainer 同步到下游的 commit-ts,Drainer 重启时可以读取 checkpoint 接着从对应 commit-ts 同步数据到下游。 Drainer 日志 ["write save point"] [ts=411222863322546177] 表示保存对应时间戳的 checkpoint。

下游类型不同,checkpoint 的保存方式也不同:

  • 下游 MySQL/TiDB 保存在 tidb_binlog.checkpoint 表。
  • 下游 kafka/file 保存在对应配置目录里的文件。

因为 kafka/file 的数据内容包含了 commit-ts,所以如果 checkpoint 丢失,可以消费下游最新的一条数据看写到下游数据的最新 commit-ts。

Drainer 启动的时候会去读取 checkpoint,如果读取不到,就会使用配置的 initial-commit-ts 做为初次启动开始的同步时间点。

Drainer 机器发生故障,下游数据还在,如何在新机器上重新部署 Drainer?

如果下游数据还在,只要保证能从对应 checkpoint 接着同步即可。

假如 checkpoint 还在,可采用以下方式进行处理:

  1. 部署新的 Drainer 并启动即可(参考 checkpoint 介绍,Drainer 可以读取 checkpoint 接着同步)。
  2. 使用 binlogctl 将老的 Drainer 状态修改成 offline

假如 checkpoint 不在,可以如下处理:

  1. 获取之前 Drainer 的 checkpoint commit-ts,做为新部署 Drainer 的 initial-commit-ts 配置来部署新的 Drainer。
  2. 使用 binlogctl 将老的 Drainer 状态 修改成 offline

如何用全量 + binlog 备份文件来恢复一个集群?

  1. 清理集群数据并使用全部备份恢复数据。
  2. 使用 reparo 设置 start-tso = {全量备份文件快照时间戳+1},end-ts = 0(或者指定时间点),恢复到备份文件最新的数据。

主从同步开启 ignore-error 触发 critical error 后如何重新部署

TiDB 配置开启 ignore-error 写 binlog 失败后触发 critical error 告警,后续都不会再写 binlog,所以会有 binlog 数据丢失。如果要恢复同步,需要如下处理:

  1. 停止当前 drainer。
  2. 重启触发 critical error 的 tidb-server 实例重新开始写 binlog(触发 critical error 后不会再写 binlog 到 pump)。
  3. 上游做全量备份。
  4. 清理掉下游数据包括 checkpoint 表 tidb_binlog.checkpoint
  5. 使用上游的全量备份恢复下游。
  6. 部署 drainer,使用 initialCommitTs= {从全量备份获取快照的时间戳}。