【是否原创】是
【首发渠道】TiDB 社区
【首发渠道链接】其他平台首发请附上对应链接
【正文】
写在前面
本文档不是 TiDB Binlog 的入门文档,从零开始学习如何使用 TiDB Binlog 请仔细阅读官方文档(见附录)。
本文重点介绍目标端是 Oracle 的相关功能,配置,以及相关环境要求和限制。
一、功能列表
目前支持如下功能
- TiDB DML 变化数据到 Oracle 的复制
- TiDB truncate table 操作到 Oracle 的复制,其他 DDL(包括 truncate partition)会引起 Drainer 停机(手工在 Oracle 执行相同语义的 DDL 后,需要配置 Drainer 跳过该 DDL 的 commitTS)
- 断点记录表可以存储到 Oracle 中,缺省表名为 tidb_binlog_checkpoint,并具备 TiDB snapshot 与 Oracle SCN 映射能力
- 库名、表名映射:支持上下游库名、表名不一致的复制(本功能为 Oracle 目标端扩展功能,TiDB/MySQL 目标端不具备该功能)
- 支持 relaylog 功能
- 暂不支持 Oracle 目标库 rewrite batch sql
- 不支持 Loopback(环形复制)功能
- 不支持 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 版本需要设置此项
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
- db-type :新增 "oracle"类型
- 新增 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 都不同。如果相同都可以不用配置。
- Oracle 数据库连接配置两种方法:
- syncer.to 新增 oracle-service-name 配置值,它对应 Oracle 的 service-name,例如 oratidb;
- 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”
- syncer.to.checkpoint,配置 checkpoint 表存放位置,表会创建在 Oracle 的迁移账户下面。
- 如果不配置,就缺省使用 syncer.to 的连接配置;
- 如果配置,type = “oracle”,其他配置跟 TiDB/MySQL 类似;不同点是 schema 不用配置,如果配置了 schema 就必须和 user 保持一直,不然系统会检测出来并停止。
- 新增了 table 配置项,用户可以自定义 checkpoint 表名,如果不配置就是用默认表名 tidb_binlog_checkpoint。oracle-service-name 和 oracle-connect-string 两个配置项意义和第三条描述的相同。
- 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停机的问题
- 如果配置了schema和table的过滤规则,对被过滤掉的schema和table做任何ddl操作都不会导致Drainer停机。
- 配置了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”