写点什么

基于 TiCDC 的 TiDB 复制集群的计划内和计划外切换验证步骤

  • 2023-03-17
    北京
  • 本文字数:4563 字

    阅读完需:约 15 分钟

作者: pepezzzz 原文来源:https://tidb.net/blog/5244f816

环境准备

集群名称和版本

上游 tidb 集群: tidb-h


下游 tidb 集群: tidb-cdc


版本:v6.5.0


CDC 专用用户:cdcuser


注:业务负载用户应独立于 CDC 专用用户。


业务数据库:cdcdb


模拟业务应用:Sysbench、BANK。

上下游创建 ticdc 同步用户和数据库

create user cdcuser identified by 'cdcuser';grant restricted_replica_writer_admin on *.* to cdcuser;create database cdcdb;grant all privileges on cdcdb.* to cdcuser;
复制代码

设置下游 tidb-cdc 集群只读

tidb-cdc 集群只读后,只允许具备 restricted_replica_writer_admin 角色的 cdcuser 进行上游同步的数据写入。


set global tidb_restricted_read_only=on;
复制代码


建议重启 tidb-server 防止有连接未进入只读状态。


tiup cluster restart tidb-cdc -R tidb
复制代码


检验环境变量。


show global variables like '%tidb_restricted_read_only%';show global variables like '%tidb_super_read_only%';
复制代码


此时结果应该显示为 ON。


验证 tidb-cdc 处于只读状态。


create database rovfydb;
复制代码


系统应提示 ERROR 1836 (HY000): Running in read-only mode 的报错,说明确定处于只读状态。

完成数据初始化

使用 dumpling / lightning 或者 br 进行上下游 TiDB 集群的数据初始化,并记录备份 ts,过程略。

编辑任务 toml 文件

Toml 文件内需要启用 redo 功能,并指定 redo 数据共享的存储位置。

创建 tidb-h 到 tidb-cdc 的复制链路

在上游 tidb-h 执行创建 changefeed 指令


tiup ctl:v<CLUSTER_VERSION> cdc changefeed create --server=http://{tidb-h-cdc-ip}:8300  --sink-uri="mysql://cdcuser:cdcuser@{tidb-cdc-lb-ip}:4000/?safe-mode=false&enable-old-value=true" --sync-interval=5m --sync-point=true  --changefeed-id="cdcdb-cdc-task" --config /home/tidb/cdc_toml/cdcdb_h2cdc_changefeed.toml
复制代码


检查同步任务状态


tiup ctl:v<CLUSTER_VERSION> cdc changefeed list --server=http://{tidb-h-cdc-ip}:8300 
复制代码


检验 cdcdb-cdc-task 任务状态应该是 normal,同时多次执行可见 tso 和 checkpoint 值还在正常推进。


"id": "cdcdb-cdc-task", "summary": {"state": "normal","tso”: 436004661945434114,"checkpoint": “202x-xx-xx xx:xx:xx.xxx","error": null}
复制代码

启动上游应用

sysbench 模拟应用负载


sysbench /usr/local/share/sysbench/oltp_read_write.lua --mysql-host={tidb-h-lb-ip} --mysql-port=4000 --mysql-db=cdcdb --mysql-user=sbuser --mysql-password=sbuser  --tables=20 --threads=20 --time=600  run > /tmp/syebench.log &
复制代码


bank 模拟检验一致性应用


./bank_arm64  -dsn 'bankuser:bankuser@tcp({tidb-h-lb-ip}:4000)/cdcdb' -accounts 10000
复制代码


执行完成后,应该有 INFO[0002] verify success in xxxx-xx-xx xx:xx:xx ... 的总余额校验成功的提示。

观察 cdc 数据同步指标

Tidb-h 集群的 cdc 监控面板,changefeed checkpoint lag 和 changefeed resolved ts lag 应该在秒级。


模拟 ticdc 同步集群计划内主从切换

设置上游 tidb-h 集群只读

set global tidb_restricted_read_only = on;
复制代码


tidb-h 只读后,原先连接 tidb-h 集群的 sysbench 和 bank 模拟负载程序均应报错。


建议重启 tidb-server 防止有连接未进入只读状态。


tiup cluster restart tidb-h -R tidb
复制代码


检查环境变量。


show variables like '%tidb_restricted_read_only%';show variables like '%tidb_super_read_only%';
复制代码


命令结果应该显示为 ON

停止上游的应用程序

使用 pkill 停止已经处于报错状态的 sysbench 和 bank。


pkill sysbenchpkill bank_arm64
复制代码

下游集群做业务数据校验

业务应用可以通过手工检查是否是一致的,如 BANK 应用可以通过最新记录确认事务是一致的,并记录当前的 current_ts。


select sum(balance) from accounts;select * from record where tso=(select max(tso) from record); select * from accounts where tso=(select max(tso) from accounts);select tidb_current_ts();
复制代码

可选使用 sync diff 进行 tidb-h 和 tidb-cdc 集群的数据一致校验

vi sync_diff_inspector_h_to_cdc.confcd /home/tidb/tidb-community-toolkit-v<CLUSTER_VERSION>-linux-arm64nohup ./sync_diff_inspector --config sync_diff_inspector_h_to_cdc.conf > sync.32.log &tail -20 /data1/sync_dir/sync_diff.log
复制代码


通过 syncdiff 的结果确认两边追平


[INFO] [diff.go:377] ["close handleCheckpoint goroutine"] [INFO] [main.go:114] ["check data finished"] [cost=XmYs] [INFO] [main.go:108] ["check pass!!!"]
复制代码

删除 tidb-h 集群 cdc 任务

tiup ctl:v<CLUSTER_VERSION> cdc changefeed remove --server=http://{tidb-h-cdc-ip}:8300 -c cdcdb-cdc-task
复制代码


检查同步任务状态


tiup ctl:v<CLUSTER_VERSION> cdc changefeed list --server=http://{tidb-h-cdc-ip}:8300 
复制代码


命令输出为空,或者不包含 cdcdb-cdc-task。

设置下游 tidb-cdc 集群恢复读写模式

关闭只读状态,恢复读写模式。


set global tidb_restricted_read_only = off;set global tidb_super_read_only=off;
复制代码


检查环境变量。


show variables like '%tidb_restricted_read_only%';show variables like '%tidb_super_read_only%';
复制代码


命令结果应该显示为 OFF

创建新的上游 tidb-cdc 到 tidb-h 的复制链路

在上游 tidb-cdc 执行创建指令


tiup ctl:v<CLUSTER_VERSION> cdc changefeed create --server=http://{tidb-cdc-cdc-ip}:8300  --sink-uri="mysql://cdcuser:cdcuser@{tidb-h-lb-ip}:4000/?safe-mode=false&enable-old-value=true" --sync-interval=5m --sync-point=true  --changefeed-id="cdcdb-cdc-task-standby" --config /home/tidb/cdc_toml/cdcdb_cdc2h_changefeed.toml 
复制代码


检查同步任务状态


tiup ctl:v<CLUSTER_VERSION> cdc changefeed list --server=http://{tidb-cdc-cdc-ip}:8300 
复制代码


检验任务状态应该是 normal,同时 tso 和 checkpoint 数据还在正常推进。


"id": "cdcdb-cdc-task-standby", "summary": {"state": "normal","tso”: 436004661945434114,"checkpoint": “202x-xx-xx xx:xx:xx.xxx","error": null}
复制代码

启动下游应用

sysbench 模拟应用负载


sysbench /usr/local/share/sysbench/oltp_read_write.lua --mysql-host={tidb-cdc-lb-ip} --mysql-port=4000 --mysql-db=cdcdb --mysql-user=sbuser --mysql-password=sbuser  --tables=20 --threads=20 --time=600  run > /tmp/syebench.log &
复制代码


bank 模拟检验一致性应用


./bank_arm64  -dsn 'cdcuser:cdcuser@tcp({tidb-cdc-lb-ip}:4000)/cdcdb' -accounts 10000
复制代码

观察 cdc 数据同步指标

Tidb-cdc 集群的 cdc 监控面板,changefeed checkpoint lag 和 changefeed resolved ts lag 应该在秒级。

计划内主从切换切换后检查

查询 tsomap 对应关系

tidb-h 集群是切换后复制链路的下游目标集群,需要从 tidb-h 取得最新的 tso 对应点。


select * from syncpoint_v1 order by primary_ts desc limit 10;
复制代码


得到最新的一个上下游一致性对应点的 TSO 数据

使用 sync diff 进行 tidb-h 和 tidb-cdc 集群的数据一致校验

在 sync diff 的配置文件 snapshot 参数需要指定一个上下游一致性对应点的 TSO 进行数据一致校验


vi sync_diff_inspector_cdc_to_h.conf


check-thread-count=20export-fix-sql = true check-struct-only = false [data-sources][data-sources.tidb-h] host ="tidb-h-lb-ip” port = 4000user = "root"password = ""snapshot = "436004818783567873" [data-sources.tidb-cdc]host = "tidb-h-cdc-ip” port = 4000user = "root" password = ""snapshot = "436004805298880512" [routes]...
复制代码

模拟 ticdc 同步集群计划外切换从集群接管

停上游集群模拟计划外主集群故障

关闭 tidb-h 集群。


tiup cluster stop tidb-h
复制代码

停止上游的应用程序

sysbench 和 bank 应该会出现报错,使用 pkill 停止 sysbench 和 bank。


pkill sysbenchpkill bank_arm64
复制代码

下游集群进行 acid 一致性修复

下游集群使用与上游同版本的 cdc 二进制进行 redo apply 的一致性修复。


mkdir -p /tmp/cdc/redo/applyexport AWS_ACCESS_KEY_ID=xxxxexport AWS_SECRET_ACCESS_KEY=xxxx./cdc redo apply --tmp-dir="/tmp/cdc/redo/apply" --storage="s3://{cdc_bucket}/cdc_redo/?endpoint=http://{s3-url}/" --sink-uri="mysql://cdcuser:cdcuser@{tidb-cdc-lb-ip}:4000"
复制代码


命令输出应该会有如下提示:


[INFO][redo.go:111] ["apply redo log starts"] [checkpointTs=436118916148494396] [resolvedTs=436118916672782426] ...[INFO][mysql.go:186]["Start mysql sink"] [INFO][mysql.go:536]["clean up table max resolved ts in MySQL sink"] [tableID=1093][resolvedTs=436118916672782426][INFO][mysql.go:541] ["clean up table checkpoint ts in MySQL sink"] [tableID=1093] [checkpointTs=436118916672782426][INFO][mysql.go:536]["clean up table max resolved ts in MySQL sink"] [tableID=1091][resolvedTs=436118916672782426][INFO][mysql.go:541]["clean up table checkpoint ts in MySQL sink"] [tableID=1091] [checkpointTs=436118916672782426]Apply redo log successfully
复制代码

下游集群做业务数据校验

业务应用可以通过手工检查是否是一致的,如 BANK 应用可以通过最新记录确认事务是一致的,并记录当前的 current_ts。


select sum(balance) from accounts;select * from record where tso=(select max(tso) from record); select * from accounts where tso=(select max(tso) from accounts);select tidb_current_ts();
复制代码

设置 tidb-cdc 集群恢复读写模式

锁定 ticdc 用户,防止集群恢复读写后上游复制链路突然恢复会进行写入。


ALTER USER cdcuser ACCOUNT UNLOCK;
复制代码


关闭只读状态,恢复读写模式。


set global tidb_restricted_read_only=off;set global tidb_super_read_only=off;
复制代码


检查环境变量。


show variables like '%tidb_restricted_read_only%';show variables like '%tidb_super_read_only%';
复制代码


命令结果应该显示为 OFF

启动下游应用

sysbench 模拟应用负载


sysbench /usr/local/share/sysbench/oltp_read_write.lua --mysql-host={tidb-cdc-lb-ip} --mysql-port=4000 --mysql-db=cdcdb --mysql-user=sbuser --mysql-password=sbuser  --tables=20 --threads=20 --time=600  run > /tmp/syebench.log &
复制代码


bank 模拟检验一致性应用


./bank_arm64  -dsn 'cdcuser:cdcuser@tcp({tidb-cdc-lb-ip}:4000)/cdcdb' -accounts 10000
复制代码

可选上游集群做数据比对

可选重启除 CDC 节点外的上游集群,通过 redo apply 日志中的 tso 时间点做闪回查询对比,查询结果应该与下游集群的输出一致。


set tidb_snapshot="redo apply ts";select sum(balance) from accounts; select * from record where tso=(select max(tso) from record); select * from accounts where tso=(select max(tso) from accounts);
复制代码


注意:上游集群在 tikv 的最新数据不一定已经同步到 ticdc 的 redo 内,所以逻辑复制方案暂时不能实现 RPO=0。


理论上,可以通过对 redo 文件的解析,提交业务进行手工审核修改进行恢复。


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

TiDB 社区官网:https://tidb.net/ 2021-12-15 加入

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

评论

发布
暂无评论
基于 TiCDC 的 TiDB 复制集群的计划内和计划外切换验证步骤_性能调优_TiDB 社区干货传送门_InfoQ写作社区