@@ -5,7 +5,7 @@ summary: 了解 TiCDC 双向复制的使用方法。
5
5
6
6
# TiCDC 双向复制
7
7
8
- 从 v6.5.0 版本开始, TiCDC 支持在两个 TiDB 集群之间进行双向复制。基于该功能,你可以使用 TiCDC 来构建 TiDB 集群的多写多活解决方案。
8
+ TiCDC 支持在两个 TiDB 集群之间进行双向复制 (Bidirectional replication, BDR) 。基于该功能,你可以使用 TiCDC 来构建 TiDB 集群的多写多活解决方案。
9
9
10
10
本文档以在两个 TiDB 集群之间进行双向复制为例,介绍双向复制的使用方法。
11
11
@@ -34,47 +34,119 @@ TiCDC 复制功能只会将指定时间点之后的增量变更复制到下游
34
34
35
35
这样,以上搭建好的集群即可对数据进行双向复制。
36
36
37
- # # 执行 DDL
38
-
39
- 开启双向复制功能后,TiCDC 不会同步任何 DDL。用户需要自行在上下游集群中分别执行 DDL。
40
-
41
- 需要注意的是,某些 DDL 会造成表结构变更或者数据更改时序问题,从而导致数据同步后出现不一致的情况。因此,在开启双向同步功能后,只有下表中的 DDL 可以在业务不停止数据写入的情况下执行。
42
-
43
- | 事件 | 是否会引起 changefeed 错误 | 说明 |
44
- | ---------------------------- | ------ |--------------------------|
45
- | create database | 是 | 用户手动在上下游都执行了 DDL 之后,错误可以自动恢复|
46
- | drop database | 是 | 需要手动重启 changefeed,指定 `--overwrite-checkpoint-ts` 为该条 DDL 的commitTs 来恢复 |
47
- | create table | 是 | 用户手动在上下游都执行了 DDL 之后,错误可以自动恢复 |
48
- | drop table | 是 | 需要手动重启 changefeed,指定 `--overwrite-checkpoint-ts` 为该条 ddl 的commitTs 来恢复 |
49
- | alter table comment | 否 | |
50
- | rename index | 否 | |
51
- | alter table index visibility | 否 | |
52
- | add partition | 是 | 用户手动在上下游都执行了 DDL 之后,错误可以自动恢复 |
53
- | drop partition | 否 | |
54
- | create view | 否 | |
55
- | drop view | 否 | |
56
- | alter column default value | 否 | |
57
- | reorganize partition | 是 | 用户手动在上下游都执行了 DDL 之后,错误可以自动恢复 |
58
- | alter table ttl | 否 | |
59
- | alter table remove ttl | 否 | |
60
- | add **not unique** index | 否 | |
61
- | drop **not unique** index | 否 | |
62
-
63
- 如果需要执行以上列表中不存在的 DDL,需要采取以下步骤:
64
-
65
- 1. 暂停所有集群中需要执行 DDL 的对应的表的写入操作。
66
- 2. 等待所有集群中对应表的所有写入已经同步到其他集群后,手动在每一个 TiDB 集群上单独执行所有的 DDL。
67
- 3. 等待 DDL 完成之后,重新恢复写入。
37
+ # # DDL 类别
38
+
39
+ 从 v7.6.0 开始,为了在双向复制中尽可能地支持 DDL 同步,根据 DDL 对业务的影响,TiDB 将 [TiCDC 原本支持同步的 DDL](/ticdc/ticdc-ddl.md) 划分为两种 DDL:可复制的 DDL 和不可复制的 DDL。
40
+
41
+ # ## 可复制的 DDL
42
+
43
+ 可复制的 DDL 是指在双向复制中,可以直接执行并同步到其他 TiDB 集群的 DDL。
44
+
45
+ 可复制的 DDL 包括:
46
+
47
+ - `CREATE DATABASE`
48
+ - `CREATE TABLE`
49
+ - `ADD COLUMN`:添加的列必须可以为 `null`,或者是同时带有 `not null` 和 `default value`
50
+ - `ADD NON-UNIQUE INDEX`
51
+ - `DROP INDEX`
52
+ - `MODIFY COLUMN`:仅能修改列的 `default value` 和 `comment`
53
+ - `ALTER COLUMN DEFAULT VALUE`
54
+ - `MODIFY TABLE COMMENT`
55
+ - `RENAME INDEX`
56
+ - `ADD TABLE PARTITION`
57
+ - `DROP PRIMARY KEY`
58
+ - `ALTER TABLE INDEX VISIBILITY`
59
+ - `ALTER TABLE TTL`
60
+ - `ALTER TABLE REMOVE TTL`
61
+ - `CREATE VIEW`
62
+ - `DROP VIEW`
63
+
64
+ # ## 不可复制的 DDL
65
+
66
+ 不可复制的 DDL 是指对业务影响较大、可能会造成集群间数据不一致性的 DDL,这类 DDL 不能在双向复制中直接通过 TiCDC 同步到其他 TiDB 集群的 DDL。不可复制的 DDL 必须通过特定的操作来执行。
67
+
68
+ 不可复制的 DDL 包括:
69
+
70
+ - `DROP DATABASE`
71
+ - `DROP TABLE`
72
+ - `ADD COLUMN`:添加的列为 `not null` 且不带有 `default value`
73
+ - `DROP COLUMN`
74
+ - `ADD UNIQUE INDEX`
75
+ - `TRUNCATE TABLE`
76
+ - `MODIFY COLUMN`:修改列除 `default value` 和 `comment` 以外的属性
77
+ - `RENAME TABLE`
78
+ - `DROP PARTITION`
79
+ - `TRUNCATE PARTITION`
80
+ - `ALTER TABLE CHARACTER SET`
81
+ - `ALTER DATABASE CHARACTER SET`
82
+ - `RECOVER TABLE`
83
+ - `ADD PRIMARY KEY`
84
+ - `REBASE AUTO ID`
85
+ - `EXCHANGE PARTITION`
86
+ - `REORGANIZE PARTITION`
87
+
88
+ # # DDL 同步
89
+
90
+ 为了能够解决上述可复制的 DDL 和不可复制的 DDL 两类 DDL 的同步问题,TiDB 引入了两种 BDR role:
91
+
92
+ - `PRIMARY`:你可以执行可复制的 DDL,但不能执行不可复制的 DDL,可复制的 DDL 会被 TiCDC 同步到下游。
93
+ - `SECONDARY`:你不能执行可复制的 DDL,也不能执行不可复制的 DDL,但是可以执行从 TiCDC 同步过来的 DDL。
94
+
95
+ 在不设置 BDR role 时,你可以执行任意 DDL。但是在 TiCDC 开启 `bdr_mode=true` 之后,执行的 DDL 不会被 TiCDC 同步。
96
+
97
+ > **警告:**
98
+ >
99
+ > 双向复制的 DDL 同步目前为实验特性,不建议在生产环境中使用。该功能可能会在未事先通知的情况下发生变化或删除。如果发现 bug,请在 GitHub 上提 [issue](https://github.com/pingcap/tidb/issues) 反馈。
100
+
101
+ # ## 可复制的 DDL 的同步场景
102
+
103
+ 1. 选择一个 TiDB 集群,执行 `ADMIN SET BDR ROLE PRIMARY` 将其设置为主集群。
104
+ 2. 在其他 TiDB 集群上,执行 `ADMIN SET BDR ROLE SECONDARY` 将其设置为从集群。
105
+ 3. 在主集群上执行**可复制的 DDL**,执行成功的 DDL 会被 TiCDC 同步到从集群中。
106
+
107
+ > **注意:**
108
+ >
109
+ > 为了防止误操作:
110
+ >
111
+ > - 如果在主集群中尝试执行**不可复制的 DDL**,会[报错 8263](/error-codes.md)。
112
+ > - 无论在从集群中尝试执行**可复制的 DDL** 还是**不可复制的 DDL**,都会[报错 8263](/error-codes.md)。
113
+
114
+ # ## 不可复制的 DDL 的同步场景
115
+
116
+ 1. 对所有 TiDB 集群执行 `ADMIN UNSET BDR ROLE`,撤销集群的 BDR role。
117
+ 2. 暂停所有集群中需要执行 DDL 的对应的表的写入操作。
118
+ 3. 等待所有集群中对应表的所有写入已经同步到其他集群后,手动在每一个 TiDB 集群上单独执行所有的 DDL。
119
+ 4. 等待 DDL 完成之后,重新恢复写入。
120
+ 5. 按照[可复制的 DDL 的同步场景](#可复制的-ddl-的同步场景)的操作步骤,切换回可复制的 DDL 的同步场景。
121
+
122
+ > **注意:**
123
+ >
124
+ > 对所有 TiDB 集群执行 `ADMIN UNSET BDR ROLE` 之后,所有 DDL 都不会被 TiCDC 同步,需要手动在各个集群上分别执行 DDL。
68
125
69
126
# # 停止双向复制
70
127
71
128
在业务数据停止写入之后,你可以在两个集群中都插入一行特殊的值,通过检查这两行特殊的值来确保数据达到了一致的状态。
72
129
73
- 检查完毕之后,停止同步任务即可停止双向复制 。
130
+ 检查完毕之后,停止同步任务,并对所有集群执行 `ADMIN UNSET BDR ROLE` 。
74
131
75
132
# # 使用限制
76
133
77
- - DDL 的限制见[执行 DDL 小节](#执行-ddl)。
134
+ - BDR role 只能在以下两种场景中正常使用:
135
+
136
+ - 1 个 `PRIMARY` 集群和 n 个 `SECONDARY` 集群(可复制的 DDL 的同步场景)
137
+ - n 个不设置 BDR role 的集群(用于在每个集群手动执行不可复制的 DDL 的同步场景)
138
+
139
+ > **注意:**
140
+ >
141
+ > 请勿将 BDR role 设置为其他情况,例如,既存在设置了 `PRIMARY`、`SECONDARY` 的集群,又存在没有设置 BDR role 的集群。如果错误地设置了 BDR role,TiCDC 同步数据期间无法保证数据正确性和一致性。
142
+
143
+ - 一般情况下,禁止在同步的表中使用 `AUTO_INCREMENT` 或 `AUTO_RANDOM` 键,以免产生数据冲突的问题。如果需要使用 `AUTO_INCREMENT` 或 `AUTO_RANDOM` 键,可以通过在不同的集群设置 `auto_increment_increment` 和 `auto_increment_offset` 来使得不同的集群都能够分配到不同的主键。假设有三个 TiDB 集群(A、B、C)处于双向同步中,那么你可以采取如下设置:
144
+
145
+ - 在 A 中设置 `auto_increment_increment=3`,`auto_increment_offset=2000`
146
+ - 在 B 中设置 `auto_increment_increment=3`,`auto_increment_offset=2001`
147
+ - 在 C 中设置 `auto_increment_increment=3`,`auto_increment_offset=2002`
148
+
149
+ 这样 A、B、C 隐式分配到的 `AUTO_INCREMENT` ID 和 `AUTO_RANDOM` ID 就不会互相冲突。如果需要增加 BDR 模式的集群,需要临时暂停相关业务的写入,重新在所有集群上设置合适的 `auto_increment_increment` 和 `auto_increment_offset`,然后再开启相关业务。
78
150
79
151
- 双向复制的集群不具备检测写冲突的功能,写冲突将会导致未定义问题。你需要在业务层面保证不出现写冲突。
80
152
0 commit comments