作者:cartersz
寫在前面
本文檔不是 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”