技術分享 | TiDB 上百T資料拆分實踐

愛可生雲資料庫發表於2022-05-13

作者:楊家鑫

多點⾼級 DBA ,擅⻓故障分析與效能優化,喜歡探索新技術,愛好攝影。

本文來源:原創投稿

*愛可生開源社群出品,原創內容未經授權不得隨意使用,轉載請聯絡小編並註明來源。


背景

提⾼ TiDB 可⽤性,需要把多點已有上百T TiDB叢集拆分出2套

挑戰

  1. 現有需要拆分的12套TiDB叢集的版本多(4.0.9、5.1.1、5.1.2都有),每個版本拆分⽅法存在不⼀樣
  2. 其中5套TiDB,資料量均超過10T、最⼤的TiDB叢集⽬前資料量62T、單TiDB叢集備份集⼤,消耗⼤量磁碟空間和頻寬資源

空間最⼤3套叢集

  1. tidb使⽤⽅式多樣(每種⽅式拆分⽅法不同),有直接讀寫tidb,也有mysql->tidb彙總分析 查詢,也有tidb->cdc->下游hive
  2. 全量備份TiDB在業務⾼峰期是否會產⽣效能影響
  3. ⼤資料量的拆分資料的⼀致性保證

⽅案

⽬前TiDB官⽅提供的同步⼯具有:

  • DM全量+增量(該⽅法⽆法⽤於tidb->tidb,適⽤於MySQL->TiDB)
  • BR全量物理備份+CDC增量同步(CDC同步在tidb、tikv節點OOM後修復成本⾼https://github.co m/pingcap/tiflow/issues/3061)
  • BR全量物理備份+binlog增量(類似於MySQL記錄所有變更的binlog⽇志,TiDB binlog由 Pump(記錄變更⽇志)+Drainer(回放變更⽇志)組成,我們採⽤該⽅法進⾏全量+增量同步拆分)

備份與恢復⼯具BR:https://docs.pingcap.com/zh/t...

TiDB Binlog:https://docs.pingcap.com/zh/t...

因TiDB拆分BR全量物理備份+binlog增量涉及週期⻓,我們分為4個階段進⾏

第⼀階段

1、清理現有TiDB叢集⽆⽤資料

按⽉分表tidb庫有⽆⽤的表,如3個⽉前的xxxx ⽇志表

2、升級GZ現有15套TiDB叢集(12套TiDB叢集需要1分為2)版本⾄5.1.2

趁這次拆分統⼀GZ tidb版本,解決挑戰1

第⼆階段

1、新機器部署好相同版本5.1.2TiDB叢集

set @@global.tidb_analyze_version = 1;

2、⽬的端,源端所有tikv tiflash掛載好NFS,pd節點上安裝好BR

Exteral storge採⽤騰訊雲NFS⽹盤,保障tikv備份⽬的端和還原全量來源端都能在同⼀⽬錄,NFS ⽹盤空間⾃動動態增加+限速備份以應對挑戰2

3、獨⽴3臺機器部署好12套TiDB叢集

pump收集binlog(端⼝區分不同TiDB叢集) pump,drainer採⽤獨⽴16C, 32G機器保障增量同步最⼤效能

注意:為保障tidb計算節點的可⽤性,需設定ignore-error binlog關鍵引數(https://docs.pingcap.com/zh/t...

server_configs: 
  tidb: 
    binlog.enable: true 
    binlog.ignore-error: true

4、修改pump元件 GC時間為7天

binlog保留7天保障全量備份->到增量同步過程能接上
pump_servers: 
  - host: xxxxx 
    config: 
      gc: 7 
#需reload重啟tidb節點使記錄binlog⽣效

5、備份TiDB叢集全量資料⾄NFS Backup & Restore 常⻅問題 (https://docs.pingcap.com/zh/t...

注意:每個TiDB叢集在同⼀個NFS建不同備份⽬錄

注意:源⽼TiDB叢集分別限速(備份前後對讀寫延遲時間基本⽆影響)進⾏錯峰全量備份(存在之前 多個TiDB叢集同時備份把NFS 3Gbps⽹絡頻寬打滿情況)以減輕對現有TiDB讀寫、NFS的壓⼒以應 對挑戰

mkdir -p /tidbbr/0110_dfp 
chown -R tidb.tidb /tidbbr/0110_dfp 
#限速進⾏全業務應⽤庫備份
./br backup full \ 
     --pd "xxxx:2379" \ 
     --storage "local:///tidbbr/0110_dfp" \ 
     --ratelimit 80 \ 
     --log-file /data/dbatemp/0110_backupdfp.log 
#限速進⾏指定庫備份 
 ./br backup db \ 
   --pd "xxxx:2379" \ 
   --db db_name \ 
   --storage "local:///tidbbr/0110_dfp" \ 
   --ratelimit 80 \ 
   --log-file /data/dbatemp/0110_backupdfp.log 
   
12.30號45T TiDB叢集全量備份耗時19h,佔⽤空間12T 
[2021/12/30 09:33:23.768 +08:00] [INFO] [collector.go:66] ["Full backup succes s summary"] [total-ranges=1596156] [ranges-succeed=1596156] [ranges-failed=0] [backup-checksum=3h55m39.743147403s] [backup-fast-checksum=409.352223ms] [bac kup-total-ranges=3137] [total-take=19h12m22.227906678s] [total-kv-size=65.13T B] [average-speed=941.9MB/s] ["backup data size(after compressed)"=12.46TB] [B ackupTS=430115090997182553] [total-kv=337461300978]

6、每個新建TiDB叢集單獨同步⽼TiDB叢集⽤⼾密碼資訊

注意:BR全量備份不備份tidb mysql系統庫,應⽤、管理員⽤⼾密碼資訊可⽤開源pt-toolkit⼯具 包pt-show-grants匯出

7、恢復NFS全量備份⾄新TiDB叢集

注意:新TiDB叢集磁碟空間需充裕,全量備份還原後新TiDB叢集佔⽤空間⽐⽼TiDB叢集多⼏個 T,和官⽅⼈員溝通是由於還原時⽣成sst的演算法是lz4,導致壓縮率沒有⽼TiDB叢集⾼

注意:tidb_enable_clustered_index,sql_mode 新⽼TiDB叢集這2引數必須⼀致

8、tiup擴容drainer進⾏增量同步

擴容前確認下游checkpoint資訊不存在或已清理

如果下游之前接過drainer,相關位點在⽬標端tidb_binlog.checkpoint表中,重做的時候需要清理

注意:因源最⼤TiDB叢集⻓期平均寫⼊TPS在6k左右,在增⼤worker-count回放執行緒數後,儘管 ⽬的端域名解析到3個tidb節點,單個drainer增量還是⽆法追上延遲(回放速度最⾼在3k TPS),後和TiDB官⽅溝通改成按3個drainer(不同drainer同步不同庫名)並⾏增量同步延遲追上(3個 drainer增量讓“漏⽃”沒有堆積,源流⼊端資料能及時到達⽬標流出端)

注意:多個drainer並⾏增量必須指定⽬的端checkpoint.schema為不同庫drainer配置說明


#從備份⽂件中獲取全量備份開始時的位點TSO
grep "BackupTS=" /data/dbatemp/0110_backupdfp.log 
430388153465177629 
#第⼀次⼀個drainer進⾏增量同步關鍵配置
drainer_servers: 
- host: xxxxxx 
commit_ts: 430388153465177629 
deploy_dir: "/data/tidb-deploy/drainer-8249" 
config: 
syncer.db-type: "tidb" 
syncer.to.host: "xxxdmall.db.com" 
syncer.worker-count: 550 1516


#第⼆次多個drainer進⾏並⾏增量同步
drainer_servers: 
- host: xxxxxx 
commit_ts: 430505424238936397 #該位點TSO為從第⼀次1個drainer增量停⽌後⽬的端ch eckpoint表中的Commit_Ts
config: 
syncer.replicate-do-db: [db1,db2,....] 
syncer.db-type: "tidb" 
syncer.to.host: "xxxdmall.db.com" 
syncer.worker-count: 550 
syncer.to.checkpoint.schema: "tidb_binlog2"
1個drainer進⾏增量延遲越來越⼤

3個drainer進⾏並⾏增量同步最慢⼀條增量鏈路:9h追了近1天資料

3個drainer並⾏同步⽬的端寫⼊1.2w TPS > 源端6k寫⼊TPS

9、配置新建tidb grafana&dashboard域名

建grafana、dashboard的域名指向⽣產nginx代理,由nginx代理grafana 端⼝,dashboard 端⼝

第三階段

1、check新⽼TiDB叢集資料同步⼀致性情況

TiDB在全量和增量時會⾃⾏進⾏資料⼀致性校驗,我們主要關注增量同步延遲情況,並隨機 count(*)源⽬的端表
#延遲檢查⽅法⼀:在源端TiDB drainer狀態中獲取最新已經回覆TSO再通過pd獲取延遲情況 
mysql> show drainer status;
+-------------------+-------------------+--------+--------------------+------- --------------+ 
| NodeID | Address | State | Max_Commit_Ts | Update_Time | 
+-------------------+-------------------+--------+--------------------+------- --------------+ 
| xxxxxx:8249 | xxxxxx:8249 | online | 430547587152216733 | 2022-01-21 16:50:58 | 


tiup ctl:v5.1.2 pd -u http://xxxxxx:2379 -i 
» tso 430547587152216733; 
system: 2022-01-17 16:38:23.431 +0800 CST 
logic: 669 


#延遲檢查⽅法⼆:在grafana drainer監控中觀察 
tidb-Binlog->drainer->Pump Handle TSO中current值和當前實際時間做延遲⽐較 
曲線越陡,增量同步速率越快

2、tiflash表建⽴&CDC同步在新TiDB叢集建⽴&新mysql->tidb彙總同步鏈路閉環(DRC-TIDB)

  • tiflash

源端tidb⽣成⽬的端 新建tiflash語句


SELECT * FROM information_schema.tiflash_replica WHERE TABLE_SCHEMA = '<db_name>' and TABLE_NAME = '<table_name>' 
SELECT concat('alter table ',table_schema,'.',table_name,' set tiflash replica 1;') FROM information_schema.tiflash_replica where table_schema like 'dfp%';
  • CDC鏈路閉環

在⽼TiDB CDC同步中選取1個TSO位點在新TiDB中建⽴CDC⾄kafka topic同步

  • DRC-TIDB鏈路閉環(⾃研mysql->tidb合庫合表同步⼯具)


上圖左右為DRC-TIDB拆分前後狀態

1、左⽼drc-tidb同步規則copy到右新drc-tidb,不啟動drc-tidb同步(記錄當前時間T1)

2、drainer同步現有TiDB資料⾄新建TiDB鏈路啟⽤安全模式replace(syncer.safe-mode: true)插⼊

3、修改左drc-tidb同步源⽬的地址為閉環,並啟動drc-tidb(記錄當前時間T2)

4、右tidb grafana drainer監控中check當前同步時間checkpoint是否>=T2(類似於tikv follower- read),若沒有則等待延遲追上

5、右tidb叢集增量同步修改edit-config drainer配置⽂件,去掉mysql-tidb同步的庫名(所有庫同 步增加指定庫名同步)並reload drainer節點

commit_ts: 431809362388058219 
config: 
syncer.db-type: tidb 
syncer.replicate-do-db: 
- dmall_db1 該DB為直接讀寫 
- dmall_db2 該DB為從mysql同步⽽來,需去掉
6、修改右drc-tidb同步源⽬的地址為閉環,並啟動右drc-tidb(drc-tidb採⽤冪等同步,會重複消 費copy同步規則T1時間到現在的mysql binlog)

3、每個新TiDB叢集ANALYZE TABLE更新表統計資訊

不是必須,更新統計資訊為最新可以避免查詢sql索引選擇⾛錯

第四階段

1、左tidb叢集應⽤域名解析⾄新建tidb計算節點

2、批量kill右TiDB叢集左應⽤的連線

存在指令碼多次批量kill tidb pid;在右tidb節點依然有⼤量左應⽤的連線,因此左應⽤滾動重啟後右

tidb節點左應⽤連線釋放

3、移除⽼TiDB叢集->新TiDB叢集增量同步drainer鏈路

注意:因多個TiDB叢集共⽤的1臺⾼配drainer機器,node_exporter(採集機器監控agent)也是多 個TiDB叢集共⽤,當A TiDB叢集停⽌drainer鏈路,B C TiDB叢集會報node_exporter不存活告警

總結

  • 不同TiDB版本的升級統⼀版本很有必要,⼀是拆分⽅法的通⽤,減少拆分的複雜度,⼆是享受新 版本的特性,減低運維管理成本
  • ⽬標TiDB叢集磁碟空間需⾜夠充裕
  • 在源TiDB寫⼊壓⼒⼤時增量同步binlog到⽬的端的延遲保障需要drainer按庫名進⾏併發增量同步
  • TiDB拆分涉及步驟多,能提前做的步驟就提前做,真正拆分的時間窗⼝很短
  • 感謝TiDB官⽅社群對我們的技術⽀持,路漫漫其修遠兮,我們將上下⽽求索

相關文章