Skip to content

Commit

Permalink
cdc: Add description about protocol behavior change. (#16621)
Browse files Browse the repository at this point in the history
  • Loading branch information
3AceShowHand committed Feb 23, 2024
1 parent c021753 commit d3a9775
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions TOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,7 @@
- [双向复制](/ticdc/ticdc-bidirectional-replication.md)
- [单行数据正确性校验](/ticdc/ticdc-integrity-check.md)
- [主从集群一致性读和数据校验](/ticdc/ticdc-upstream-downstream-check.md)
- [TiCDC 行为变更说明](/ticdc/ticdc-behavior-change.md)
- 监控告警
- [基本监控指标](/ticdc/ticdc-summary-monitor.md)
- [详细监控指标](/ticdc/monitor-ticdc.md)
Expand Down
6 changes: 6 additions & 0 deletions releases/release-6.5.3.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ TiDB 版本:6.5.3

试用链接:[快速体验](https://docs.pingcap.com/zh/tidb/v6.5/quick-start-with-tidb) | [生产部署](https://docs.pingcap.com/zh/tidb/v6.5/production-deployment-using-tiup) | [下载离线包](https://cn.pingcap.com/product-community/?version=v6.5.3#version-list)

## 兼容性变更

### 行为变更

- TiCDC 在处理 Update 事件时,如果事件的主键或者非空唯一索引的列值发生改变,则会将该条事件拆分为 Delete 和 Insert 两条事件。更多信息,请参考[用户文档](/ticdc/ticdc-behavior-change.md#含有单条-update-变更的事务拆分)

## 改进提升

+ TiDB
Expand Down
4 changes: 4 additions & 0 deletions releases/release-6.5.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ TiDB 版本:6.5.4
- 为了修复当使用 `Cursor Fetch` 获取大结果集时 TiDB 占用大量内存的问题,TiDB 会自动将结果集写入磁盘以释放内存资源 [#43233](https://github.com/pingcap/tidb/issues/43233) @[YangKeao](https://github.com/YangKeao)
- 默认关闭 RocksDB 的周期性 compaction,使 TiKV RocksDB 的默认行为和 v6.5.0 之前的版本保持一致,避免在升级之后集中产生大量 compaction 影响系统的性能。同时,TiKV 新增 [`rocksdb.[defaultcf|writecf|lockcf].periodic-compaction-seconds`](https://docs.pingcap.com/zh/tidb/v6.5/tikv-configuration-file#periodic-compaction-seconds-从-v654-版本开始引入)[`rocksdb.[defaultcf|writecf|lockcf].ttl`](https://docs.pingcap.com/zh/tidb/v6.5/tikv-configuration-file#ttl-从-v654-版本开始引入) 配置项,支持手动配置 RocksDB 的周期性 compaction [#15355](https://github.com/tikv/tikv/issues/15355) @[LykxSassinator](https://github.com/LykxSassinator)

### 行为变更

- 对于包含多条变更的事务,如果 Update 事件的主键或者非空唯一索引的列值发生改变,TiCDC 会将该其拆分为 Delete 和 Insert 两条事件,并确保将所有事件有序,以保证 Delete 事件在 Insert 事件之前。更多信息,请参考[用户文档](/ticdc/ticdc-behavior-change.md#含有多条-update-变更的事务拆分)

## 改进提升

+ TiDB
Expand Down
4 changes: 4 additions & 0 deletions releases/release-7.1.1.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ TiDB 版本:7.1.1

- TiDB 新增 `tidb_lock_unchanged_keys` 变量用于控制是否对于没有修改的 key 加锁 [#44714](https://github.com/pingcap/tidb/issues/44714) @[ekexium](https://github.com/ekexium)

### 行为变更

- TiCDC 在处理 Update 事件时,如果事件的主键或者非空唯一索引的列值发生改变,则会将该条事件拆分为 Delete 和 Insert 两条事件。更多信息,请参考[用户文档](/ticdc/ticdc-behavior-change.md#含有单条-update-变更的事务拆分)

## 改进提升

+ TiDB
Expand Down
4 changes: 4 additions & 0 deletions releases/release-7.1.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ TiDB 版本:7.1.2
- 新增 TiCDC 配置项 [`sink.csv.binary-encoding-method`](/ticdc/ticdc-changefeed-config.md#ticdc-changefeed-配置文件说明),控制 CSV 协议中二进制类型数据的编码方式,默认值为 `'base64'` [#9373](https://github.com/pingcap/tiflow/issues/9373) @[CharlesCheung96](https://github.com/CharlesCheung96)
- 新增 TiCDC 配置项 [`large-message-handle-option`](/ticdc/ticdc-sink-to-kafka.md#处理超过-kafka-topic-限制的消息)。默认为空,即消息大小超过 Kafka Topic 的限制后,同步任务失败。设置为 "handle-key-only" 时,如果消息超过大小,只发送 handle key 以减少消息的大小;如果依旧超过大小,则同步任务失败 [#9680](https://github.com/pingcap/tiflow/issues/9680) @[3AceShowHand](https://github.com/3AceShowHand)

### 行为变更

- 对于包含多条变更的事务,如果 Update 事件的主键或者非空唯一索引的列值发生改变,TiCDC 会将该其拆分为 Delete 和 Insert 两条事件,并确保将所有事件有序,以保证 Delete 事件在 Insert 事件之前。更多信息,请参考[用户文档](/ticdc/ticdc-behavior-change.md#含有多条-update-变更的事务拆分)

## 改进提升

+ TiDB
Expand Down
4 changes: 4 additions & 0 deletions releases/release-7.2.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ TiDB 版本:7.2.0
>
> 以下为从 v7.1.0 升级至当前版本 (v7.2.0) 所需兼容性变更信息。如果从 v7.0.0 或之前版本升级到当前版本,可能也需要考虑和查看中间版本 release notes 中提到的兼容性变更信息。

### 行为变更

- TiCDC 在处理 Update 事件时,如果事件的主键或者非空唯一索引的列值发生改变,则会将该条事件拆分为 Delete 和 Insert 两条事件。更多信息,请参考[用户文档](/ticdc/ticdc-behavior-change.md#含有单条-update-变更的事务拆分)。

### 系统变量

| 变量名 | 修改类型 | 描述 |
Expand Down
1 change: 1 addition & 0 deletions releases/release-7.4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ TiDB 版本:7.4.0
- 新增函数 [`TIDB_PARSE_TSO_LOGICAL()`](/functions-and-operators/tidb-functions.md#tidb-特有的函数),用于从 TiDB TSO 时间戳中提取逻辑时间戳。

- 新增表 [`information_schema.CHECK_CONSTRAINTS`](/information-schema/information-schema-check-constraints.md),提高与 MySQL 8.0 的兼容性。
- 对于包含多条变更的事务,如果 Update 事件的主键或者非空唯一索引的列值发生改变,TiCDC 会将该其拆分为 Delete 和 Insert 两条事件,并确保将所有事件有序,以保证 Delete 事件在 Insert 事件之前。更多信息,请参考[用户文档](/ticdc/ticdc-behavior-change.md#含有多条-update-变更的事务拆分)

### 系统变量

Expand Down
54 changes: 54 additions & 0 deletions ticdc/ticdc-behavior-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
title: TiCDC 行为变更说明
summary: 介绍 TiCDC changefeed 的行为变更,说明变更原因以及影响范围。
---

# TiCDC 行为变更说明

## 将 Update 事件拆分为 Delete 和 Insert 事件

### 含有单条 Update 变更的事务拆分

从 v6.5.3、v7.1.1 和 v7.2.0 开始,使用非 MySQL Sink 时,对于仅包含一条 Update 变更的事务,如果 Update 事件的主键或者非空唯一索引的列值发生改变,TiCDC 会将该条事件拆分为 Delete 和 Insert 两条事件。详情见 GitHub issue [#9086](https://github.com/pingcap/tiflow/issues/9086)

该变更主要为了解决如下问题:

* 在使用 CSV 和 AVRO 协议时,仅输出新值而不输出旧值。因此,当主键或者非空唯一索引的列值发生改变时,消费者只能接收到变化后的新值,无法得到旧值,导致无法处理变更前的值(例如删除旧值)。
* 在使用 Index value dispatcher 将数据按照 Key 分发到不同的 Kafka partition 时,下游的消费者组内多个消费者进程独立消费 Kafka Topic partition,由于消费进度不同,可能导致数据不一致的问题。

以如下 SQL 为例:

```sql
CREATE TABLE t (a INT PRIMARY KEY, b INT);
INSERT INTO t VALUES (1, 1);
UPDATE t SET a = 2 WHERE a = 1;
```

在上述示例中,主键 `a` 的值从 `1` 修改为 `2`。如果不将该 Update 事件进行拆分:

* 在使用 CSV 和 AVRO 协议时,消费者仅能看到新值 `a = 2`,而无法得到旧值 `a = 1`。这可能导致下游消费者只插入了新值 `2`,而没有删除旧值 `1`
* 在使用 Index value dispatcher 时,插入记录 `(1, 1)` 的事件可能被发送到 Partition 0,而变更事件 `(2, 1)` 可能被发送到 Partition 1。如果 Partition 1 的消费进度快于 Partition 0,则可能由于下游数据系统中找不到相应数据而导致出错。因此,TiCDC 会将该条 Update 事件拆分为 Delete 和 Insert 两条事件,其中,删除记录 `(1, 1)` 被发送到 Partition 0,写入记录 `(2, 1)` 被发送到 Partition 1,以确保无论消费者的进度如何,事件都能被消费成功。

### 含有多条 Update 变更的事务拆分

从 v6.5.4、v7.1.2 和 v7.4.0 开始,对于一个含有多条变更的事务,如果 Update 事件的主键或者非空唯一索引的列值发生改变,TiCDC 会将该其拆分为 Delete 和 Insert 两条事件,并确保所有事件按照 Delete 事件在 Insert 事件之前的顺序进行排序。详情见 GitHub issue [#9430](https://github.com/pingcap/tiflow/issues/9430)

该变更主要为了解决当使用 MySQL Sink 直接将这两条事件写入下游时,可能会出现主键冲突的问题,从而导致 changefeed 报错。

以如下 SQL 为例:

```sql
CREATE TABLE t (a INT PRIMARY KEY, b INT);
INSERT INTO t VALUES (1, 1);
INSERT INTO t VALUES (2, 2);

BEGIN;
UPDATE t SET a = 1 WHERE a = 3;
UPDATE t SET a = 2 WHERE a = 1;
UPDATE t SET a = 3 WHERE a = 2;
COMMIT;
```

在上述示例中,通过执行三条 SQL 语句对两行数据的主键进行交换,但 TiCDC 只会接收到两条 Update 变更事件,即将主键 `a``1` 变更为 `2`,将主键 `a``2` 变更为 `1`,如果 MYSQL Sink 直接将这两条 Update 事件写入下游,会出现主键冲突的问题,导致 changefeed 报错。

因此,TiCDC 会将这两条事件拆分为四条事件,即删除记录 `(1, 1)``(2, 2)` 以及写入记录 `(2, 1)``(1, 2)`

0 comments on commit d3a9775

Please sign in to comment.