07 如何在线开启/关闭 TiDB Binlog
梁启斌 2020 年 2 月 10 日
一、背景 / 目的
TiDB-Binlog 是一个用于收集 TiDB 的 增量数据,并提供数据同步、异步备份功能的工具。
TiDB-Binlog 支持以下场景:
- 数据同步:同步 TiDB 集群数据到其他数据库、消息中间件以及文件
- 数据备份和恢复:异步备份 TiDB 集群数据,同时可以用于 TiDB 集群故障时恢复在日常使用当中,会遇到之前未开启 binlog 的集群需要开启,以及开启 binlog 的集群需要关闭,并且希望对业务的影响降到最低。本文主要描述使用 ansible 的方式在线开关 TiDB-Binlog 的操作步骤以及注意点。
二、相关概念及原理解释
关于 TiDB binlog 的组件 Pump 、 Drainer 、binlogctl 工具 的介绍可以参考官方文档的介绍(TiDB Binlog 整体架构介绍)
三、操作前 Check 项
3.1 开启 TiDB Binlog 需要 check 的事项:
-
Pump 以及 Drainer 的配置是否符合官方的推荐配置,特别需要注意如果部署的服务器原来已经有其他服务在运行,则需要评估该服务器的负载是否能够满足增加 Pump 或者 Drainer 。
-
检查磁盘空间,确认是否有足够空间来给 Pump 以及 Drainer 对日志数据进行落盘。( Pump 主要是保存上游 TiDB 发送过来的 binlog ,Drainer 如果下游对应的是 file 的话会在本地保存为文件。)
shell> df -h
-
端口预留,检查端口是否被占用,当前是否可用等。( 默认端口号 Pump :8250 、Drainer : 8249 )
shell> netstat -anp |grep {port_no}
3.2 关闭 TiDB Binlog 需要 check 的事项:
- 下线主要针对永久(或长时间)不再使用该服务的场景,如果只是需要临时维护请使用 pause-pump 或 pause-drainer 命令来暂停 Pump 或者 Drainer 。
四、注意事项
- 在开启 enable-binlog 运行 TiDB 时,需要保证至少一个 Pump 正常运行。
- 需要保证同一集群的所有 TiDB 都开启了 binlog 服务,否则在同步数据时可能会导致上下游数据不一致。尤其注意 Binary 方式部署 TiDB,要注意统一设置 enable-binlog 参数。
- 由于开关 TiDB Binlog 需要重启 TIDB server ,因此会导致当前正在执行的 SQL 发生异常。建议在业务低峰期或者把需要重启的 TiDB 从 LB 排除,把影响降到最低。
五、操作步骤
5.1 开启 TiDB binlog
当前集群拓扑信息
组件 | 机器 (IP端口) | 数量 |
---|---|---|
TiDB | 172.16.4.243:4807 、 172.16.4.242:4807 | 2 |
PD | 172.16.4.243:12779 、172.16.4.242:12779 、172.16.4.240:12779 | 3 |
TiKV | 172.16.4.239:27173 、172.16.4.240:27173 、172.16.4.238:27173 | 2 |
确认当前的集群里面的有没有开启 binlog 以及 Pump 和 Drainer 的情况
mysql> show global variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | 0 |
+---------------+-------+
1 row in set (0.01 sec)
mysql> show pump status;
Empty set (0.02 sec)
mysql> show drainer status;
Empty set (0.03 sec)
调整后集群目标拓扑信息
组件 | 机器 (IP端口) | 数量 |
---|---|---|
TiDB | 172.16.4.243:4807 、 172.16.4.242:4807 | 2 |
PD | 172.16.4.243:12779 、172.16.4.242:12779 、172.16.4.240:12779 | 3 |
TiKV | 172.16.4.239:27173 、172.16.4.240:27173 、172.16.4.238:27173 | 2 |
Pump | 172.16.4.242:8250 、172.16.4.241:8250 | 2 |
Drainer | 172.16.4.239:8249 | 1 |
操作中的主要步骤
-
修改 tidb-ansible/inventory.ini 文件 , 添加 Pump 的配置,开启 enable_binlog 开关。(注:下列只是 inventory.ini 部分内容,在于突出需要修改的部分,需要正常运行 tidb-ansible 需要完整的 inventory.ini 文件。)
## Binlog Part [pump_servers] 172.16.4.241 172.16.4.242 [drainer_servers] ## Group variables [pd_servers:vars] # location_labels = ["zone","rack","host"] ## Global variables [all:vars] deploy_dir = /home/tidb/deploy_3.0.6 ## Connection # ssh via normal user ansible_user = tidb cluster_name = test-cluster_3.0.6 tidb_version = v3.0.6 # process supervision, [systemd, supervise] process_supervision = systemd timezone = Asia/Shanghai enable_firewalld = False # check NTP service enable_ntpd = True set_hostname = False ## binlog trigger enable_binlog = True
-
使用 ansible 部署 Pump 。(注: 如果之前已经部署过相同版本的 Pump 且 deploy_path 一致的话可以跳过此步骤 。)
shell> ansible-playbook deploy.yml --tags=pump
-
使用 ansible 启动 Pump 。
shell> ansible-playbook start.yml --tags=pump
-
确认 Pump 已经正常启动。(必须确保至少有一台 Pump 状态已经正常才能进行下一步操作)
shell> bin/binlogctl -pd-urls=http://172.16.4.243:12779 -cmd pumps [2019/04/28 09:29:59.016 +00:00] [INFO] [nodes.go:48] ["query node"] [type=pump] [node="{NodeID: 1.1.1.1:8250, Addr: 172.16.4.241:8250, State: online, MaxCommitTS: 408012403141509121, UpdateTime: 2019-04-28 09:29:57 +0000 UTC}"]
-
更新并重启 TiDB servers
shell> ansible-playbook rolling_update.yml --tags=tidb
-
使用 binlogctl 获取 initial_commit_ts 。(注意:本文仅列出获取 initial_commit_ts 的操作,详细请参考 initial_commit_ts 获取。)
shell> {tidb_ansible_path}/resources/bin/binlogctl -pd-urls=http://172.16.4.243:12779 -cmd generate_meta INFO[0000] [pd] init cluster id 6569368151110378289 2018/06/21 11:24:47 meta.go:117: [info] meta: &{CommitTS:400962745252184065}
-
修改 tidb-ansible/inventory.ini 文件 , 添加 Drainer 的配置。(注意:本文以下游为 file 为例,如果下游为 MySQL 或者 Kafka 参考 Drainer 部署 )
[drainer_servers] drainer_file ansible_host=172.16.4.239 initial_commit_ts="400962745252184065"
-
修改配置文件 {tidb_ansible_path}/conf/drainer_file_drainer.toml (注意下游不同的类型, 对配置文件的命名也不一样。可以参考 drainer_mysql_drainer.toml 部分)
[syncer] # downstream storage, equal to --dest-db-type # Valid values are "mysql", "file", "tidb", "kafka". db-type = "file" # Uncomment this if you want to use "file" as "db-type". [syncer.to] # default data directory: "{{ deploy_dir }}/data.drainer" dir = "data.drainer"
-
部署 Drainer
shell> ansible-playbook deploy_drainer.yml
-
启动 Drainer
shell> ansible-playbook start_drainer.yml
- 更新监控信息,如果新部署 TiDB binlog 会新增 Binlog 的 dashboard。
shell> ansible-playbook rolling_update_monitor.yml --tags=prometheus
5.2 关闭 TiDB binlog
当前集群拓扑信息
组件 | 机器 (IP端口) | 数量 |
---|---|---|
TiDB | 172.16.4.243:4807 、 172.16.4.242:4807 | 2 |
PD | 172.16.4.243:12779 、172.16.4.242:12779 、172.16.4.240:12779 | 3 |
TiKV | 172.16.4.239:27173 、172.16.4.240:27173 、172.16.4.238:27173 | 2 |
Pump | 172.16.4.242:8250 、172.16.4.241:8250 | 2 |
Drainer | 172.16.4.239:8249 | 1 |
调整后集群目标拓扑信息
组件 | 机器 (IP端口) | 数量 |
---|---|---|
TiDB | 172.16.4.243:4807 、 172.16.4.242:4807 | 2 |
PD | 172.16.4.243:12779 、172.16.4.242:12779 、172.16.4.240:12779 | 3 |
TiKV | 172.16.4.239:27173 、172.16.4.240:27173 、172.16.4.238:27173 | 2 |
操作中的主要步骤
-
确认 Drainer 的数量以及状态
mysql> show drainer status; +--------------+-------------------+--------+--------------------+---------------------+ | NodeID | Address | State | Max_Commit_Ts | Update_Time | +--------------+-------------------+-------- +--------------------+---------------------+ | node239:8249 | 172.16.4.239:8249 | online | 415012076096323585 | 2020-03-02 18:37:13 | +--------------+-------------------+-------- +--------------------+---------------------+
-
下线所有消费的本集群的 Drainer。(注意:node_id 可以通过第一步获得 NodeID,也可以通过
binlogctl -cmd drainers
获得)shell>{tidb_ansible_path}/resources/bin/binlogctl -pd-urls=http://172.16.4.243:12779 -cmd offline-drainer -node-id "node239:8249"
-
编辑 inventory.ini 关闭 binlog , 注释 Drainer 相关配置。
## Binlog Part [pump_servers] 172.16.4.241 172.16.4.242 [drainer_servers] ## drainer_file ansible_host=172.16.4.239 initial_commit_ts="400962745252184065" ## Group variables [pd_servers:vars] # location_labels = ["zone","rack","host"] ## Global variables [all:vars] deploy_dir = /home/tidb/deploy_3.0.6 ## Connection # ssh via normal user ansible_user = tidb cluster_name = test-cluster_3.0.6 tidb_version = v3.0.6 # process supervision, [systemd, supervise] process_supervision = systemd timezone = Asia/Shanghai enable_firewalld = False # check NTP service enable_ntpd = True set_hostname = False ## binlog trigger enable_binlog = False
-
滚动重启 Tidb 关闭 binlog
shell>ansible-playbook rolling_update.yml -t tidb
-
确认 Pump 的数量以及状态
mysql > show pump status; +------------+-------------------+-------- +--------------------+---------------------+ | NodeID | Address | State | Max_Commit_Ts | Update_Time | +------------+-------------------+-------- +--------------------+---------------------+ | node2:8250 | 172.16.4.242:8250 | online | 415056015094448129 | 2020-03-04 17:10:46 | | node1:8250 | 172.16.4.241:8250 | online | 415056014806089730 | 2020-03-04 17:10:45 | +------------+-------------------+-------- +--------------------+---------------------+
-
手动下线所有的 Pump。(注意:node_id 可以通过第一步获得 NodeID,也可以通过
binlogctl -cmd drainers
获得)> {tidb_ansible_path}/resources/bin/binlogctl -pd-urls=http://172.16.4.243:12779 -cmd offline-pump -node-id "node2:8250" > {tidb_ansible_path}/resources/bin/binlogctl -pd-urls=http://172.16.4.243:12779 -cmd offline-pump -node-id "node1:8250"
-
编辑 inventory.ini 关闭 binlog , 注释 Pump 相关配置
[pump_servers] #172.16.4.241 #172.16.4.242 [drainer_servers] ## Group variables [pd_servers:vars] # location_labels = ["zone","rack","host"]
六、操作后 Check 项
6.1 开启 TiDB binlog
-
可以通过 SQL 检查 Binlog 是否开启成功。(注意,也可以使用 binlogctl 来查询 Pump 和 Drainer 的状态)
mysql> show global variables like 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | 1 | +---------------+-------+ 1 row in set (0.01 sec) mysql> show pump status; +------------+-------------------+-------- +--------------------+---------------------+ | NodeID | Address | State | Max_Commit_Ts | Update_Time | +------------+-------------------+-------- +--------------------+---------------------+ | node1:8250 | 172.16.4.241:8250 | online | 415057221848137729 | 2020-03-04 18:27:31 | | node2:8250 | 172.16.4.242:8250 | online | 415057222136496130 | 2020-03-04 18:27:32 | +------------+-------------------+-------- +--------------------+---------------------+ 2 rows in set (0.01 sec) mysql> show drainer status; +--------------+-------------------+-------- +--------------------+---------------------+ | NodeID | Address | State | Max_Commit_Ts | Update_Time | +--------------+-------------------+-------- +--------------------+---------------------+ | node239:8249 | 172.16.4.239:8249 | online | 415057228441583618 | 2020-03-04 18:27:56 | +--------------+-------------------+-------- +--------------------+---------------------+ 1 row in set (0.01 sec)
-
通过监控查看服务状态
6.2 关闭 TiDB binlog
-
可以通过 SQL 检查 Binlog 是否关闭成功。(注意,也可以使用 binlogctl 来查询 Pump 和 Drainer 的状态)
mysql> show global variables like 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | 0 | +---------------+-------+ 1 row in set (0.01 sec) mysql> show pump status; +------------+-------------------+--------- +--------------------+---------------------+ | NodeID | Address | State | Max_Commit_Ts | Update_Time | +------------+-------------------+--------- +--------------------+---------------------+ | node1:8250 | 172.16.4.241:8250 | offline | 415073332930019329 | 2020-03-05 11:31:48 | | node2:8250 | 172.16.4.242:8250 | offline | 415073371386544129 | 2020-03-05 11:34:16 | +------------+-------------------+--------- +--------------------+---------------------+ 2 rows in set (0.00 sec) mysql> show drainer status; +--------------+-------------------+--------- +--------------------+---------------------+ | NodeID | Address | State | Max_Commit_Ts | Update_Time | +--------------+-------------------+--------- +--------------------+---------------------+ | node239:8249 | 172.16.4.239:8249 | offline | 415072225463369729 | 2020-03-05 10:21:27 | +--------------+-------------------+--------- +--------------------+---------------------+ 1 row in set (0.02 sec)
七、常见问题
- Q: 下线 Pump 或者 Drainer 能否使用 ansible-playbook stop.yml --tags pump 和 ansible-playbook stop_drainer.yml ?
- A: 不能,使用 ansibl-playbook stop.yml 后 pump 和 Drainer 还是处于 pause 的状态。并不是 offline 。下线需要使用 binlogctl -cmd offline-pump 和 binlogctl -cmd offline-drainer