TiDB Binlog 支持 Oracle 目标库功能用户手册

【是否原创】是
【首发渠道】TiDB 社区
【首发渠道链接】其他平台首发请附上对应链接
【正文】

写在前面

本文档不是 TiDB Binlog 的入门文档,从零开始学习如何使用 TiDB Binlog 请仔细阅读官方文档(见附录)。

本文重点介绍目标端是 Oracle 的相关功能,配置,以及相关环境要求和限制。

一、功能列表

目前支持如下功能

  1. TiDB DML 变化数据到 Oracle 的复制
  2. TiDB truncate table 操作到 Oracle 的复制,其他 DDL(包括 truncate partition)会引起 Drainer 停机(手工在 Oracle 执行相同语义的 DDL 后,需要配置 Drainer 跳过该 DDL 的 commitTS)
  3. 断点记录表可以存储到 Oracle 中,缺省表名为 tidb_binlog_checkpoint,并具备 TiDB snapshot 与 Oracle SCN 映射能力
  4. 库名、表名映射:支持上下游库名、表名不一致的复制(本功能为 Oracle 目标端扩展功能,TiDB/MySQL 目标端不具备该功能)
  5. 支持 relaylog 功能
  6. 暂不支持 Oracle 目标库 rewrite batch sql
  7. 不支持 Loopback(环形复制)功能
  8. 不支持 sql-mode 复制

二、上下游数据库配置要求

2.1 上游 TiDB 配置要求

2.1.1 TiDB 版本要求

经测试 5.4.0 版本的 Drainer 兼容 4.0.14 及以上版本的 TiDB 集群

2.1.2 tidb-server 中与 TiDB-Binlog 相关的配置

  • binlog.enable
    应设置为 true,开启 TiDB-Binlog 功能
  • binlog.ignore-error
    • 设置为 false 时,pump 故障时保 binlog,但会阻止该 tidb-server 上的全部写入操作
    • 设置为 true 时,pump 故障保业务,但会导致后续该 tidb-server 发生的写入操作不再记录 binlog。此后一般需要通过全量+增量的方式重建下游数据。

查看 tidb-server 是否进入 ignore-error 状态的命令
curl http://172.16.4.81:10080/binlog/recover?op=status

2.1.3 TiDB 功能兼容性

迁移前期部署 TiDB 时,须严格参照本章内容进行相关参数设置,否则有丢失 binlog、数据无法写入 Oracle、TiDB 和 Oracle 数据不一致等风险。

  • tiup 拓扑文件配置参考:
    server_configs:
    tidb:
    performance.txn-total-size-limit: 2147483648
    new_collations_enabled_on_first_bootstrap: true
  • TiDB 系统变量配置参考:
    set @@global.tidb_enable_amend_pessimistic_txn=0;
    set @@global.tidb_enable_clustered_index=off; --低于 5.1.0 版本需要设置此项

image

2.2 下游 Oracle 配置要求

2.2.1 创建供 truncate 使用的存储过程(最小化权限需求)

在所有要做T2O的业务schema下建立 truncate 存储过程

create or replace procedure do_truncate(table_name in varchar2,

partition_name in varchar2) as

begin

if partition_name || ‘x’ = ‘x’ then

execute immediate 'truncate table ’ || table_name;

else

execute immediate 'alter table ’ || table_name || ’ truncate partition ’ || partition_name;

end if;

end;

/

2.2.2 创建业务账户和业务表

创建业务账户和业务表, 例如:findpt_tbs, 此步骤由用户自行决定,这里只是给demo

create bigfile tablespace findpt_tbs datafile ‘/data1/oracle/oradata/ORATIDB/findpt_tbs_001.dbf’ size 30G autoextend on extent management local uniform size 256k;

create user findpt identified by findpt account unlock default tablespace findpt_tbs;

grant resource,connect to findpt;

alter user findpt quota unlimited on findpt_tbs;

2.2.3 创建迁移账户并给予相应权限

1)创建迁移账户并给予相应权限, 例如:下面是创建用户binlog并给予权限的demo,

create tablespace drainer_tbs datafile ‘/data1/oracle/oradata/GBK/drainer_tbs_001.dbf’ size 30G autoextend on extent management local uniform size 256k;

create user drainer identified by drainer account unlock default tablespace drainer_tbs;

grant resource ,connect,create any library to drainer;

grant execute on dbms_flashback to drainer;

alter user drainer quota unlimited on drainer_tbs;

alter user drainer quota unlimited on findpt_tbs;

2)给业务用户的 增删改查权限

select ‘grant select ,update ,insert,delete on ‘||owner||’.’||table_name||’ to drainer;’ from dba_tables where owner=‘FINDPT’;

3)生成的 grant 语句如下, 注意后续创建新表时要追加授权

grant select any dictionary to drainer;

如果想包含 truncate 表的权限,须额外执行:

grant execute on findpt.do_truncate to drainer;

2.3 Drainer 环境要求

2.3.1 在 Drainer 服务器上安装 Oracle Client libraries

参考该文档 https://oracle.github.io/odpi/doc/installation.html 下载 Oracle client libraries,如果已经安装了 Oracle 客户端或服务端的,则不需要额外安装 Oracle client libraries。
在运行 Drainer 的操作系统用户(一般是 tidb 用户)的 profile 里配置 Oracle Client library 的安装路径,路径以客户端或服务端的实际安装目录为准:

export LD_LIBRARY_PATH=/u01/app/oracle/instantclient_21_1

2.3.2 需要 GLIBC_2.14 版本

如有环境不满足条件,会遇到:/lib64/libc.so.6: version GLIBC_2.14 not found 问题,建议将 Drainer 部署在 TiDB 集群服务器上,因为调整 Oracle 环境可以能会对 Oracle 运行存在风险。

三、配置文件介绍

Pump 没有特殊配置和原来保持一样

Drainer 配置修改,注意:Oracle 的 schema 使用的是 Oracle 账户 user

  1. db-type :新增 "oracle"类型
  2. 新增 table-migrate-rule 和 table-migrate-rule.source,table-migrate-rule.target,这几个配置为了解决 TiDB 的 schema 和 table 跟下游 Oracle 的 schema 和 table 不一致的情况。

例如下图,上有 TiDB 的 drainer_test_2.t1 的表同步到下游 ljsuser.t2 表,这里 schema 和 table 都不同。如果相同都可以不用配置。

  1. Oracle 数据库连接配置两种方法:

  2. syncer.to 新增 oracle-service-name 配置值,它对应 Oracle 的 service-name,例如 oratidb;

  3. syncer.to 新增 oracle-connect-string 配置值,它可以是这种形式例如:127.0.0.1:1521/oratidb?connect_timeout=2,或者是 An Oracle Net Connect Descriptor String,或者是 tnsnames.ora 文件里的 Net Service Name,例如 oracle-connect-string=“ORCLPDB1”

  1. syncer.to.checkpoint,配置 checkpoint 表存放位置,表会创建在 Oracle 的迁移账户下面。

  2. 如果不配置,就缺省使用 syncer.to 的连接配置;

  3. 如果配置,type = “oracle”,其他配置跟 TiDB/MySQL 类似;不同点是 schema 不用配置,如果配置了 schema 就必须和 user 保持一直,不然系统会检测出来并停止。

  4. 新增了 table 配置项,用户可以自定义 checkpoint 表名,如果不配置就是用默认表名 tidb_binlog_checkpoint。oracle-service-name 和 oracle-connect-string 两个配置项意义和第三条描述的相同。

  5. Schema和table过滤规配置

同时配置了replicate-do-db和replicate-do-table且都有同样的db-name,那么在replicate-do-db里的db-name优先级高于replicate-do-table里的,例如有如下配置

replicate-do-db = [“drainer_test_1”,“drainer_test_2”]

[[syncer.replicate-do-table]]

db-name =“drainer_test_2”

tbl-name = “t1”

那么drainer_test_2下面的所有表都可以被同步到下游。如果你只希望同步t1表,可以去掉replicate-do-db 里的 "drainer_test_2"的配置。

四、基本操作和运维

4.1 配置 T2O 复制前提条件

确认 TiDB 与 Oracle 均处于静止状态,且数据完全一致(通过 ot2-sync-diff 确认)

4.2 低于 TiDB 5.4.0 版本的部署方法

v5.4.0 版本后,最新 Drainer 集成在 tiup 软件包中,可以直接部署;低于v5.4.0版本请先手工下载最新版本 Drainer 软件,然后部署。

包含 T2O 复制功能的最低 Drainer 版本为:

<正式版发布后更新>

  • 使用 tiup 命令部署

1)使用 tiup cluster patch,更新 Drainer 版本:tiup cluster patch | PingCAP Docs

2)重启 Drainer,验证复制状态

  • Binary 部署

1)下载最新的 Drainer release 版本

2)手工部署 Drainer

./bin/drainer –config=drainer.toml &

3)手工添加 Prometheus 配置,并手工重启 Prometheus

4)验证复制状态

4.3 intital-ts 的配置

在确保上下游数据一致的情况下,使用 show master status 抓取 TiDB tso 作为 initial-ts,或使用 -1 使用最新的 tso

4.4 库表路由功能(仅支持 Oracle 目标端)

参考附录配置文件中的 [[syncer.table-migrate-rule]] 部分

4.5 checkpoint 表记录了 TiDB snapshot 与 Oracle SCN 的 map

目标端 checkpoint 表(Oracle 中默认表名为 TIDB_BINLOG_CHECKPOINT)。

在程序启动后,Drainer 会实时更新已应用事务的 commitTS,该表内 tso 的优先级高于 Drainer 配置文件中的 initial-commit-ts 配置。

select to_char(CLUSTERID,‘fm99999999999999999999990.9999999999999999’), CHECKPOINT from binlog1.tidb_binlog_checkpoint;

4.6 DDL 的处理

T2O 复制不支持 DDL 操作,请在开启 Drainer 复制前,确保上下游的数据结构是一致的。

TiDB 与 Oracle 的字段类型映射参考:O2T 数据类型 mapping + 内建函数 mapping + 部分 SQL 改写方法

如遇到源端DDL操作,Drainer 会报错并停止,参考如下方式处理

1)查看 Drainer 日志,确认 Drainer 由于 DDL 而停止

[2021/12/31 14:00:15.510 +08:00] [ERROR] [server.go:291] [“syncer exited abnormal”] [error=“unsupported ddl create table test(id int), you should skip commit ts 430160062299242512”]

2)手工在下游执行相同语义的 DDL

3)下游 DDL 落实后如何拉起 Drainer 继续复制

修改 Drainer 配置文件,为 ignore-txn-commit-ts 添加该 log 中的 commitTS,重启 Drainer。

4.7 DDL导致Drainer停机的问题

  1. 如果配置了schema和table的过滤规则,对被过滤掉的schema和table做任何ddl操作都不会导致Drainer停机。
  2. 配置了sync-ddl=false后任何ddl操作不会导致Drainer停机。

五、性能测试报告

5.1 TiDB-Binlog 的最终一致性消费

为了保障复制性能,Drainer 对事务进行了拆分多线程消费。

5.2 功能测试报告

Drainer 的 T2O 复制具备最终一致性;relaylog 功能有效;断点续传功能有效;route 功能有效;filter 功能有效;checkpoint 表可以记录上游 TiDB tso 与下游 Oracle SCN 间的 mapping 关系。

5.3 性能测试报告

性能测试中使用的 Drainer 配置参数:

[syncer]

txn-batch = 100

worker-count = 20

TIDB源端使用北银金融开发的模拟转账程序执行压测:

北银金融

重点关注其中两张业务表的数据复制性能

表名 记录数 平均行宽(byte) 表大小-Oracle
ACCOUNT 1000W 413 4.6G
CUSTOMER 100W 444 490M

性能测试结果:

  • T2O 的复制速度约 5000-8000行/s;(暂未开发 batch insert 功能)
  • T2M,T2T 的复制速度约 10000-15000行/s;(具备 batch insert 能力)
  • 源端的批处理操作,会造成 Drainer 复制延迟上涨;
平均行宽400bytes的数据 源端 QPS T2T T2M T2O
复制速度峰值(行/秒) 18000/s+ 15000/s 15000/s 8000/s

附录

配置模板参考

node-id = “172.16.4.81:8258”

addr = “172.16.4.81:8258”

data-dir = “data.drainer”

pd-urls = “http://172.16.4.81:42379,http://172.16.4.87:42379,http://172.16.4.88:42379

initial-commit-ts = -1

detect-interval = 10

log-file = “drainer.log”

log-level = “info”

[syncer]

db-type = “oracle”

ignore-schemas = “INFORMATION_SCHEMA,PERFORMANCE_SCHEMA,mysql”

replicate-do-db = [“findpt”]

sync-ddl = true

txn-batch = 100

worker-count = 20

safe-mode = false

#ignore-txn-commit-ts = [430157351441661954]

#开启 relaylog 使复制具备最终一致性

[syncer.relay]

log-dir = “/dir/to/save/log”

##schema route, oracle only

[[syncer.table-migrate-rule]]

[syncer.table-migrate-rule.source]

schema = “findpt”

[syncer.table-migrate-rule.target]

schema = “findpt_t”

the downstream mysql protocol database

[syncer.to]

host = “172.16.4.87”

user = “findpt_t”

password = “findpt_t”

port = 1521

oracle-service-name = “oratidb”

TiDB Binlog官方文档

TiDB Binlog FAQ

TiDB Binlog Relay Log

7赞

你好,有一些图片图片显式不出来,image

3赞

谢谢,真棒

可以了~

1赞

:+1::+1::+1:
希望之后会有更多的迁移、兼容oracle的案例。

3赞

:+1::+1:学习了,兼容oracle,tidb会有越来越广阔的发展空间

2赞

可以支持 mysql 目标库吗?

2赞

不错不错,学习了

2赞

写的很好,MySQL目标库应该是支持的吧

是的,支持

可以支持