环境准备
集群名称和版本
tidb 集群: tidb-h
版本:v6.1.0 (实际生产上线推荐最新的 6.5.x 或更高的版本)
集群拓扑:两中心部署 Dr-Autosync 集群
数据副本:五副本 + 一 Learner 副本的方式
检查存储节点拓扑
DashBoard 页面中 TiKV 节点已经正确配置四层标签体系(dc / logic / rack / host)。
下图中主数据中心 dc1 使用 192.168.1.x 网段及标签 logic1/2/3,从数据中心 dc2 使用 192.168.4.x 网段及标签 logic3/4/5。
检查 Dr-Autosync placement-rules 配置
查看 placement-rules 配置
# tiup ctl:v<CLUSTER_VERSION> pd -u {pd-ip}:2379 -i
>config placement-rules show
规则输出如下, dc1 使用 192.168.1.x 网段及标签 logic1/2/3,从数据中心 dc2 使用 192.168.4.x 网段及标签 logic3/4/5
[
{
"group_id": "pd",
"id": "dc1-logic1",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic1"
]
}
],
"location_labels": [
"dc",
"logic",
"rack",
"host"
]
},
{
"group_id": "pd",
"id": "dc1-logic2",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic2"
]
}
],
"location_labels" 配置同省略
},
{
"group_id": "pd",
"id": "dc1-logic3",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic3"
]
}
],
"location_labels" 配置同省略
},
{
"group_id": "pd",
"id": "dc2-logic4",
"start_key":"",
"end_key":"",
"role": "learner",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic4"
]
}
],
"location_labels" 配置同省略
},
{
"group_id": "pd",
"id": "dc2-logic5",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic5"
]
}
],
"location_labels" 配置同省略
},
{
"group_id": "pd",
"id": "dc2-logic6",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic6"
]
}
],
"location_labels" 配置同省略
}
]
检查 Dr-Autosync replication-mode 配置
查看 replication-mode 配置,参数输出如下,复制模式使用 dr-auto-sync,数据中心冗余等级的标签是 dc,主数据中心是 dc1,从数据中心是 dc2,主数据中心配置 3 副本,从数据中心配置 2 副本,wait-store-timeout 超时时间是默认的 1 分钟。
>config show all
...
"replication-mode": {
"replication-mode": "dr-auto-sync",
"dr-auto-sync": {
"label-key": "dc",
"primary": “dc1",
"dr": "dc2",
"primary-replicas": 3,
"dr-replicas": 2,
"wait-store-timeout": "1m0s"
...
}
}
检查 Dr-Autosync 集群的同步状态
通过 dc2 的 PD 节点的 Data Dir 路径中存储的 DR_STATE 文件来确认复制状态:
#cat {tidb-datadir}/pd_data/DR_STATE
{"state":"sync","state_id":2158}
检查所有 TiKV server 节点的 Leader 分布
Leader 的监控输出如下,除 dc2-logic4 Label 的 learner 角色实例(192.168.4.105 / 106)外,其他节点 Leader 分布均衡。
检查 PD Server 节点和 Leader 分布
# tiup ctl:v<CLUSTER_VERSION> pd -u {pd-ip}:2379 -i
>member
- Pd 成员应该配置奇数个节点且多数派节点在 dc1 数据中心。
- Leader 处于 dc1 数据中心 192.168.1.x 网段的 PD 节点上,状态输出如下:
...
"leader": {
"name":"pd-192.168.1.x-2379",
"member_id": 11430528617142211933,
"peer urls": [
"http://192.168.1.x:2380",
],
"client_urls": [
"http://192.168.1.x:2379"
],
...
检查所有 tidb server 节点的负载均衡配置
两个中心有各自的负载均衡,分别路由到各自数据中心的 tidb server。
启动上游应用
模拟业务应用:Sysbench、BANK。
bank 模拟检验一致性应用压测 dc1 数据中心 192.168.1.x 网段的负载均衡,用于验证后续 RPO=0 的计划外切换。
./bank_arm64 -dsn 'bankuser:bankuser@tcp({tidb-h-dc1-ip}:4000)/cdcdb' -accounts 10000
执行完成后,应该有 INFO[0002] verify success in xxxx-xx-xx xx:xx:xx ...
的总余额校验成功的提示。
Sysbench 模拟业务应用压测从数据中心 dc2 数据中心 192.168.4.x 网段的的负载均衡。
sysbench /usr/local/share/sysbench/oltp_read_write.lua --mysql-host={tidb-h-dc2-ip} --mysql-port=4000 --mysql-db=cdcdb --mysql-user=sbuser --mysql-password=sbuser --tables=20 --threads=20 --time=600 run > /tmp/syebench.log &
模拟 dr-autosync 集群计划内主从切换
切换 PD Leader
切换 Leader 到指定处于 dc2 数据中心 192.168.4.x 网段的 PD 节点上。
# tiup ctl:v<CLUSTER_VERSION> pd -u {pd-ip}:2379 -i
>member leader transfer "pd-192.168.4.x-2379"
检查新 Leader 的状态。
>member
确认 Leader 状态输出如下,Leader 处于 dc2 数据中心 192.168.4.x 网段的 PD 节点上。
...
"leader": {
"name":"pd-192.168.4.x-2379",
"member_id": 11430528617142211933,
"peer urls": [
"http://192.168.4.x:2380",
],
"client_urls": [
"http://192.168.4.x:2379"
],
...
受 PD Leader 短时间不可用影响,sysbench 和 bank 应该会出现 10s 左右的报错,10 秒左右后恢复。
sysbench 的日志如下:
57s thds: 20 tps: 688.00 qps: 13750.93 (r/w1/o: 9617.95/2756.99/1375.99) lat (ms,95%):36.24 err/s: 0.00 reconn/s: 0.00
58s thds: 20 tps: 703.00 qps: 14072.05 (r/w/o: 9864.03/2802.01/1406.00) lat (ms,95%): 33.72 err/s: 0.00 reconn/s: 0.00
59s thds: 20 tps: 105.00 qps: 2104.99 (r/w/o: 1454.99/444.00/206.00) lat (ms,95%): 33.12 err/s: 9.00 reconn/s: 0.00
60s thds: 20 tps: 0.00 qps: 57.00 (r/w/o:42.00/12.00/3.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
61s thds: 20 tps: 0.00 qps: 152.00 (r/w/o: 112.00/32.00/8.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
62s thds: 20 tps: 0.00 qps: 19.00 (r/w/o: 14.00/4.00/1.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
63s thds: 20 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
64s thds: 20 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s: 0.00
65s thds: 20 tps: 0.00 qps: 148.00 (r/w/o: 112.00/28.00/8.00) lat (ms,95%): 0.00 err/s: 8.00 reconn/s: 0.00
66s thds: 20 tps: 0.00 qps: 195.00 (r/w/o: 152.00/32.00/11.00) lat (ms,95%): 0.00 err/s: 11.00 reconn/s: 0.00
67s thds: 20 tps: 0.00 qps: 25.00 (r/w/o: 16.00/8.00/1.00) lat (ms,95%): 0.00 err/s: 1.00 reconn/s:0.00
68s thds: 20 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s:0.00
69s thds: 20 tps: 0.00 qps: 0.00 (r/w/o: 0.00/0.00/0.00) lat (ms,95%): 0.00 err/s: 0.00 reconn/s:0.00
70s thds: 20 tps: 0.00 qps: 145.00 (r/w/o: 98.00/40.00/7.00) lat (ms,95%): 0.00 err/s: 7.00 reconn/s: 0.00
71s thds: 20 tps: 0.00 qps: 143.00 (r/w/o: 109.00/26.00/8.00) lat (ms,95%): 0.00 err/s: 8.00 reconn/s: 0.00
72s thds: 20 tps: 0.00 qps: 42.00 (r/w/o: 31.00/9.00/2.00) lat (ms,95%): 0.00 err/s: 2.00 reconn/s:0.00
73s thds: 20 tps: 18.00 qps: 325.00 (r/w/o: 238.00/51.00/36.00) lat (ms,95%):14827.42 err/s: 0.00 reconn/s: 0.00
74s thds: 20 tps: 580.99 qps: 11558.89 (r/w/o: 8105.92/2291.98/1160.99) lat (ms,95%):39.65 err/s: 0.00 reconn/s: 0.00
75s thds: 20 tps: 636.00 qps: 12696.02 (r/w/o: 8872.01/2551.00/1273.00) lat (ms,95%): 37.56 err/s: 0.00 reconn/s: 0.00
76s thds: 20 tps: 634.00 qps: 12648.05 (r/w/o: 8872.03/2508.01/1268.00) lat (ms,95%): 37.56 err/s: 0.00 reconn/s: 0.00
bank 的日志如下:
INF0[0986] verify success in 2022-09-16 18:09:47.91554303 +0800 CST m=+986.045061901
INF0[0988] verify success in 2022-09-16 18:09:49.914612 +0800 CST m=+988.044130871
ERRO「0992] move money error: Error 8027: Information schema is out of date: schema failed to update in 1 lease, please make sure TiDB can connect to TiKV
...
ERRO「0992] move money error: Error 8027: Information schema is out of date: schema failed to update in 1 lease, please make sure TiDB can connect to TiKV
INFO[0994] verify success in 2022-09-16 18:09:55.91037518 +0800 CST m-+994.039894051
INFO[0996] verify success in 2022-09-16 18:09:57.91316108 +0800 CST m=+996.042679951
扩容新的 PD
扩容 dc2 数据中心 192.168.4.x 网段的 PD 节点,转换成多数派数据中心。
vi pd4.yaml
tiup cluster scale-out tidb-h pd4.yaml -uroot -p
扩容过程中,业务应该正常。扩容完成后,PD 节点在两个数据中心的数量应该一致。
tiup cluster scale-out tidb-h
缩容 PD 节点
缩容 dc1 数据中心 192.168.1.x 网段的 PD 节点,转换成变成少数派。
缩容过程中,业务应该正常。缩容完成后,PD 节点在 dc1 数据中心的数量少于 dc2 数据中心。
tiup cluster scale-in tidb-h -N 192.168.1.x:2379
进行 TiKV 角色的切换
查看数据中心切换后的 placement-rules 配置,dc1-logic1 应指定为 learner,dc2-logic4 应指定为 voter。
# vi /home/tidb/dr-rules/dr-rules-dc2.json
[
{
"group_id": "pd",
"id": "dc1-logic1",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic1"
]
}
],
"location_labels": [
"dc",
"logic",
"rack",
"host"
]
},
...
{
"group_id": "pd",
"id": "dc2-logic4",
"start_key":"",
"end_key":"",
"role": "learner",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic4"
]
}
],
"location_labels" 配置同省略
}
...
备份当前配置后,加载新的 placement-rules 实现 TiKV Leader 的对调,并对应修改 replication-mode 的配置。
# tiup ctl:v<CLUSTER_VERSION> pd -u {pd-ip}:2379 -i
>config placement-rules rule-bundle load --out="/home/tidb/dr-rules/dr-rules-dc1_backup.json"
>config placement-rules rule-bundle save --in="/home/tidb/dr-rules/dr-rules-dc2.json"
>config set replication-mode dr-auto-sync primary dc2
>config set replication-mode dr-auto-sync dr dc1
观察 TiKV leader 切换
数据中心角色对调后,属于 dc1-logic2 / dc2-logic4 标签的 TiKV 节点上的 Leader 会进行切换,通常切换时间小于 1 分钟。
检查 Dr-Autosync 集群的同步状态
通过 dc1 的 PD 节点的 Data Dir 路径中存储的 DR_STATE 文件来确认复制状态:
#cat {tidb-datadir}/pd_data/DR_STATE
{"state":"sync","state_id":2158}
至此已经完成 Dr-Autosync 集群的计划内主从切换
(可选) 关闭 dc1 的所有实例模拟主数据中心停服务
方式一 恢复多数派模式再关闭
恢复多数派模式。
# tiup ctl:v<CLUSTER_VERSION> pd -u {pd-ip}:2379 -i
>config set replication-mode majority
添加移除 dc1 数据中心所有 store 上所有 Leader 的调度器,减少关闭时的应用影响。
>scheduler add evict-leader-scheduler 1
关闭所有 dc1 数据中心所有实例节点,模拟主数据中心停服务,理论上应该对 dc2 的应用业务几乎无影响。
tiup cluster stop tidb-h -N {dc1-node-ip1}:{port},{dc1-node-ip2}:{port},...,{dc1-node-ipN}:{port}
方式二 直接关闭
直接关闭所有 dc1 数据中心所有实例节点,模拟主数据中心停服务。
tiup cluster stop tidb-h -N {dc1-node-ip1}:{port},{dc1-node-ip2}:{port},...,{dc1-node-ipN}:{port}
dr-autosync 参数 wait-store-timeout 配置为 1m ,在主中心 tikv 停止服务后,集群会降级为 async 异步模式,在此时间内,阻止所有读写操作。
sysbench 业务中断时间大概 85 秒后恢复。
Bank 程序连接 dc1 负载均衡需要改成 dc2 负载均衡后应用重启,重启后 BANK 业务恢复。
模拟 dr-autosync 集群计划外切换从集群接管
从数据中心配置备用 tiup 节点
- 检查从数据中心的 tiup 节点的 meta.yaml 文件,应配置只有从数据中心的节点实例。
- tiup cluster display tidb-h 的输出也只有从数据中心 192.168.4.x 网段的节点实例。
核对 dc2 恢复脚本
查询 dc1 所有 tikv 的 storeid。
select STORE_ID,STORE_STATE,ADDRESS from TIKV_STORE_STATUS where address like '%192.168.1.%' order by ADDRESS;
select group_concat(STORE_ID) from TIKV_STORE_STATUS where address like '%192.168.1.%' order by ADDRESS;
在 dc2 的 tiup 节点上检查恢复脚本的 store id 信息。
# parameter
CLUSTER_NAME=tidb-h
# unhealthy store_id list
STORE_ID="32,31,33,25,22,23,27,29,20,13,21,14,28,17,26,19,34,37,36,35,24,15,16,18"
CTL_VERSION=v6.1.1
PD_RECOVER_DIR= /home/tidb/tidb-community-toolkit-v6.1.1-linux-arm64/
核对 dc2 的 placement rules 文件
cat > rules_dr.json <<EOF
[
{
"group_id": "pd",
"group_index":0,
"group_override": false,
"rules": [
{
"group_id": "pd",
"id": "dc2-logic4",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic4"
]
}
],
"location_labels": [
"dc",
"logic",
"rack",
"host"
]
},
{
"group_id": "pd",
"id": "dc2-logic5",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic5"
]
}
],
"location_labels" 配置同省略
},
{
"group_id": "pd",
"id": "dc2-logic6",
"start_key":"",
"end_key":"",
"role": "voter",
"count": 1,
"label_constraints": [
{
"key": "logic",
"op": "in"
"values": [
"logic6"
]
}
],
"location_labels" 配置同省略
}
]
}
]
关闭 dc1 的所有实例模拟主数据中心停服务
直接关闭所有 dc1 所有实例节点,模拟主数据中心停服务。
tiup cluster stop tidb-h -N {dc1-node-ip1}:{port},{dc1-node-ip2}:{port},...,{dc1-node-ipN}:{port}
停止上游的应用程序
sysbench 和 bank 应该会出现报错,使用 pkill 停止 sysbench 和 bank。
pkill sysbench
pkill bank_arm64
执行强制切换
在 dc2 的 tiup 节点上执行少数派恢复脚本 disaster_recover。
./disaster_recover
根据 store 和 region 的数量,执行时间在 5 分钟左右。
检查 TiKV 的 leader 分布均只在 dc2 数据中心。
视拓扑情况,重新推送 ticdc 配置文件。
tiup cluster reload tidb-h -R cdc
原少数派做业务数据校验
业务应用可以通过手工检查是否是一致的,如 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-h 集群在 dc1 数据中心的除 ticdc 外的多数派节点。
tiup cluster start tidb-h -N 192.168.1.x:2379,192.168.1.x:4000,192.168.1.x:20160
业务应用可以通过手工检查是否是一致的,如 BANK 应用可以通过最新记录确认事务是一致的,并记录当前的 current_ts。两边数据中心的独立集群的数据查询结果一致,说明 dr-autosync 方案能实现 RPO=0。
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();