写点什么

TiDB Binlog 使用实践

  • 2022 年 7 月 11 日
  • 本文字数:3923 字

    阅读完需:约 13 分钟

作者: banana_jian 原文来源:https://tidb.net/blog/3a28b2c7




TiDB Binlog 是一个用于收集 TiDB 的 binlog,并提供准实时备份和同步功能的商业工具。


TiDB Binlog 支持以下功能场景:


  • 数据同步:同步 TiDB 集群数据到其他数据库

  • 实时备份和恢复:备份 TiDB 集群数据,同时可以用于 TiDB 集群故障时恢复

相关源码仓库

TiDB Binlog 的实现主要分布在 tidb-tools 和 tidb-binlog 两个源码仓库中


1. tidb-tools


Repo: https://github.com/pingcap/tidb-tools/


这个仓库除了 TiDB Binlog 还有其他工具的组件,在这里与 TiDB Binlog 关系最密切的是 tidb-binlog/pump_client 这个 package。


pump_client 实现了 Pump 的客户端接口,当 binlog 功能开启时,TiDB 使用它来给 pump 发送 binlog 。


2. tidb-binlog


Repo: https://github.com/pingcap/tidb-binlog


TiDB-Binlog 的核心组件都在这个仓库,下面是各个关键目录:


cmd:包含 pump,drainer,binlogctl,reparo,arbiter 等 5 个子目录,分别对应 5 个同名命令行工具。这些子目录下面的 main.go 是对应命令行工具的入口,而主要功能的实现则依赖下面将介绍到的各个同名 packages。


pump:Pump 源码,主要入口是 pump.NewServer 和 Server.Start;服务启动后,主要的功能是 WriteBinlog(面向 TiDB/pump_client) 和 PullBinlogs(面向 Drainer)。


drainer:Drainer 源码,主要入口是 drainer.NewServer 和 Server.Start;服务启动后,Drainer 会先找到所有 Pump 节点,然后调用 Pump 节点的 PullBinlogs 接口同步 binlog 到下游。目前支持的下游有:mysql/tidb,file(文件增量备份),kafka 。


binlogctl:Binlogctl 源码,实现一些常用的 Binlog 运维操作,例如用 -cmd pumps 参数可以查看当前注册的各个 Pump 节点信息,相应的实现就是 QueryNodesByKind。


reparo:Reparo 源码,实现从备份文件(Drainer 选择 file 下游时保存的文件)恢复数据到指定数据库的功能。


arbiter:Arbiter 源码,实现从 Kafka 消息队列中读取 binlog 同步到指定数据库的功能,binlog 在消息中以 Protobuf 格式编码。


pkg:各个工具公用的一些辅助类的 packages,例如 pkg/util 下面有用于重试函数执行的 RetryOnError,pkg/version 下面有用于打印版本信息的 PrintVersionInfo。


tests:集成测试。

配置 Pump 和 Drainer

Pump


Pump 用于实时记录 TiDB 产生的 Binlog,并将 Binlog 按照事务的提交时间进行排序,再提供给 Drainer 进行消费。


Drainer


Drainer 从各个 Pump 中收集 Binlog 进行归并,再将 Binlog 转化成 SQL 或者指定格式的数据,最终同步到下游。


[tidb\@localhost ~]$ cat scaleout-binlog.yaml


pump_servers:


  - host: 192.168.135.148


    config:


      gc: 7


drainer_servers:


  - host: 192.168.135.148


    config:


      syncer.db-type: “mysql”


      syncer.to.host: “192.168.135.148”


      syncer.to.user: “jian”


      syncer.to.password: “123456”


      syncer.to.port: 3306


[tidb\@localhost ~]$ tiup cluster scale-out tidb-jiantest scaleout-binlog.yam


这里提示一下,TidbBinlog 工具需要 tidb server 开始 binlog 功能需要 tidb 的配置文件打开 binlog 功能


  config:


    binlog.enable: true


    binlog.ignore-error: true


我们可以在 tidb 中查看 pump 和 drainer 的状态这里我们主要关注一下下 Max_Commit_Ts 


记录了 pump 和 drainer 的 binlog 已经更新到了哪个位置。


MySQL [(none)]> show pump status;


+———————-+———————-+——–+——————–+———————+


| NodeID               | Address              | State  | Max_Commit_Ts      | Update_Time         |


+———————-+———————-+——–+——————–+———————+


| 192.168.135.148:8250 | 192.168.135.148:8250 | online | 431846449408901121 | 2022-03-15 12:57:52 |


+———————-+———————-+——–+——————–+———————+


MySQL [(none)]> show drainer status;


+———————-+———————-+——–+——————–+———————+


| NodeID               | Address              | State  | Max_Commit_Ts      | Update_Time         |


+———————-+———————-+——–+——————–+———————+


| 192.168.135.148:8249 | 192.168.135.148:8249 | online | 431846450195333121 | 2022-03-15 12:57:54 |


+———————-+———————-+——–+——————–+———————+

1 对于开启 TidbBinlog 之前的数据是无法同步的

记得在上面我们准备源数据的时候创建了新的数据和表还插入了数据,但是当我们打开 TidbBinlog 的时候, 我们可以发现之前的数据并没有复制过来,所以有数据差的话建议使用 Dumpling 工具进行数据的初始化,但是可以发现多了一个 tidb_binlog, 这个是 tidb 自己创建的用于记录复制的 checkpoint 信息



2 在目标端以 sql 的方式应用数据

可以看到在目标端复制数据会执行相应的 sql,而且会更新 tidb_binlog.checkpoit 表



3 时间戳

在没有延迟的情况下 drainer 的时间戳和目标端的数据中的时间戳应该是一致的



4 如果下游数据库异常 drainer 也会停止

[root\@localhost mysql]# systemctl stop MariaDB


192.168.135.148:8249   drainer       192.168.135.148  8249                             Linux/x86_64  Down     /tidb-data/drainer-8249       /tidb-deploy/drainer-8249


当 db 恢复正常时 drainer 也会自动恢复正常

5 自增主键

对自增主键的复制也是没有问题的


SOURCE


MySQL [jian]> create table jian2(id int auto_increment primary key,name char(10));


Query OK, 0 rows affected (0.159 sec)


MySQL [jian]> insert into jian2(name) values(‘jian2’);


Query OK, 1 row affected (0.012 sec)


TARGET


20220315 16:40:20,localhost.localdomain,jian,192.168.135.149,20,1177,QUERY,jian,‘INSERT INTO `jian`.`jian2`(`id`,`name`) VALUES(3,\‘jian2\’)‘,0


MariaDB [(none)]> select * from jian.jian2;


+—-+——-+


| id | name  |


+—-+——-+


|  3 | jian2 |

6 Drainer relaylog

Drainer 开启 relay log 后会先将 binlog event 写到磁盘上,然后再同步给下游集群。如果上游集群不可用,Drainer 可以通过读取 relay log 把下游集群恢复到一个一致的状态。


[root\@localhost conf]# cat drainer.toml


[syncer.relay]


log-dir = “/tidb-data/drainer-8249”


max-file-size = 10485760


查看生成的 relaylog


[root\@localhost relaylog]# ls


binlog-0000000000000000-20220315143339


[root\@localhost relaylog]# pwd


/tidb-data/drainer-8249/relaylog

7 reparo

Reparo 这部分实现像一个简化版的 Drainer 的 Sync 模块,同样有一个 Syncer 接口以及几个具体实现(除了 mysqlSyncer 还有用于调试的 printSyncer 和 memSyncer),所以就不再介绍。值得一提的是,这里也跟前面很多 MySQL / TiDB 同步相关的模块一样使用了 loader 模块。用于增量的恢复。使用 TiDB Binlog 中的 Drainer 将 binlog 按照 protobuf 格式输出到文件,通过这种方式来备份增量数据。当需要恢复增量数据时,使用 Reparo 解析文件中的 binlog,并将其应用到 TiDB/MySQL 中。


配置文件可以灵活限制需求


# 使用 start-datetime 和 stop-datetime 来选择恢复指定时间范围内的 binlog,格式为 “2006-01-02 15:04:05”。# start-datetime = “”# stop-datetime = “”


# start-tso、stop-tso 分别对应 start-datetime 和 stop-datetime,也是用于恢复指定时间范围内的 binlog,用 tso 的值来设置。如果已经设置了 start-datetime 和 stop-datetime,就不需要再设置 start-tso 和 stop-tso。# 在从全量或者上次增量位置继续同步时,start-tso 应当指定为全量 tso + 1 或者上次增量的 stop-tso + 1# start-tso = 0# stop-tso = 0


# replicate-do-db 和 replicate-do-table 用于指定恢复的库和表,replicate-do-db 的优先级高于 replicate-do-table。支持使用正则表达式来配置,需要以 ‘~’ 开始声明使用正则表达式。# 注:replicate-do-db 和 replicate-do-table 使用方式与 Drainer 的使用方式一致。# replicate-do-db = [“~^b.*”,“s1”]


[tidb\@localhost ~]$ reparo -config reparo.toml



8 binlogctl

也可以使用 binlogctl 去查看后者更改 pump 和 drainers 的状态


命令存放于 tidb-binlog-cluster-latest-linux-amd64.tar.gz,解压即可用




pause-pump    暂停 Pump    bin/binlogctl -pd-urls=http://127.0.0.1:2379 -cmd pause-pump -node-id ip:8250


pause-drainer    暂停 Drainer    bin/binlogctl -pd-urls=http://127.0.0.1:2379 -cmd pause-drainer -node-id ip:8250


offline-pump    下线 Pump    bin/binlogctl -pd-urls=http://127.0.0.1:2379 -cmd offline-pump -node-id ip:8250


offline-drainer    下线 Drainer    bin/binlogctl -pd-urls=http://127.0.0.1:2379 -cmd offline-drainer -node-id ip:8250


例子:


[tidb\@localhost tidb-community-server-v5.4.0-linux-amd64]$ binlogctl -pd-urls=http://127.0.0.1:2379 -cmd pause-pump -node-id 192.168.135.148:8250[2022/03/16 16:51:32.183 -04:00] [INFO] [nodes.go:123] [“Apply action on node success”] [action=pause] [NodeID=192.168.135.148:8250]


发布于: 刚刚阅读数: 4
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
TiDB Binlog使用实践_实践案例_TiDB 社区干货传送门_InfoQ写作社区