天天看點

041-使用DM進行同步上遊資料到 TiDB

作者:anjia​

這是堅持技術寫作計劃(含翻譯)的第41篇,定個小目标999,每周最少2篇。

回想一下之前資料同步一般會使用一些ETL工具,例如 ​​DataX​​​ ,​​StreamSets​​​ ,​​Kettle​​​,​​sqoop​​​,​​nifi​​,當然也可能使用原始的mysqldump進行人肉苦逼同步。因為每個團隊的背景不一樣,沒法簡單的說哪種工具更好,更優,還是需要落地才行。是以本文就不過多介紹不同ETL工具間的優劣了,畢竟PHP是世界上最好的語言。

本文主要講解,如何使用tidb官方的同步工具DM進行資料同步。先搬運一下tidb官方對dm的簡介

DM (Data Migration) 是一體化的資料同步任務管理平台,支援從 MySQL 或 MariaDB 到 TiDB 的全量資料遷移和增量資料同步。使用 DM 工具有利于簡化錯誤處理流程,降低運維成本。

略微吐槽下,tidb的官方技術棧略有點複雜,比如,廣義的 TiDB,一般是指 PD, TiDB, TiKV 這類核心元件(參考 ​​TiDB 整體架構​​​),但是,部署的話,得用ansible部署,監控呢,得學會看官方提供的 Prometheus+Grafana,同步資料的話,又的看 ​​mydumper​​​ , ​​loader​​​,​​syncer​​​, ​​Data Migration​​​ ,​​TiDB Lightning​​ , 管理tidb叢集的話,又會用到一些工具,比如,pd control,pd recover,tikv control,tidb controller,如果要給tidb開啟binlog,用于同步到其他tidb或者mysql叢集,又要研究 Pump,Drainer,binlogctl …

就感覺tidb團隊,一看就是出身大戶人家,看官方建議的叢集配置吧。

  • tidb叢集最低配置要求

​​

041-使用DM進行同步上遊資料到 TiDB

​​

  • dm執行個體配置
041-使用DM進行同步上遊資料到 TiDB
  • tidb-lighting配置要求(超過200G以上的遷移,建議用tidb-lighting)

​​

041-使用DM進行同步上遊資料到 TiDB

​​

  • tidb binlog的配置

​​

041-使用DM進行同步上遊資料到 TiDB

​​

是以,幾乎每一個用tidb的人,第一件事,都是,如何修改ansible的參數,繞過檢測 [手動滑稽],人嘛,都是,一邊吐槽XX周邊工具太少,又會吐槽XX太多,學不動,像是初戀的少女,等遠方的男友,怕他亂來,又怕他不來,哈哈

對比一下友商的

​​

041-使用DM進行同步上遊資料到 TiDB

​​

其實tidb的官方文檔,寫的還挺詳細的,就是不太像是給入門的人看的 [手動捂臉],本文主要是結合我在使用DM過程中,寫一下遇到的問題,以及群内大牛的解答

簡介

DM 簡化了單獨使用mysqldumper,loader,syncer的工作量,從易用性,健壯性和可觀測等方面來看,建議使用DM。

注意一下​​官方文檔​​寫的限制條件。

​​

041-使用DM進行同步上遊資料到 TiDB

​​

部署DM

參考 ​​使用 DM-Ansible 部署 DM 叢集​​

如無特殊說明都按照官方文檔操作。

第五步配置互信時,servers 是要部署DM的節點ip,注意目前登入名,確定是tidb(執行 ​

​woami​

​ )

vi hosts.ini
[servers]
172.16.10.71
172.16.10.72
172.16.10.73

[all:vars]
username = tidb      

執行 ​

​ansible-playbook -i hosts.ini create_users.yml -u root -k​

​​ 時,如果是使用 ssh key的話,可以

​​

​ansible-playbook -i hosts.ini create_users.yml -u root -k --private-key /path/to/your/keyfile​

第7步配置worker時,需要注意,如果要增量或者全量,并且上遊服務的binlog被删過,并且是gtid格式的,需要執行 ​

​show VARIABLES like 'gtid_purged'​

​​ 如果有值,則需要指定 ​

​relay_binlog_gtid​

​​ ,否則會報 ​

​close sync with err: ERROR 1236 (HY000): The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.​

​​ 此時停掉worker後,修改 ​

​relay_binlog_gtid​

​​ 重新開機無效,是需要修改meta檔案的 ​

​/tidb/deploy/dm_worker_/relay_log/f5df-11e7-a1dd.000001/relay.meta​

​ 感謝 軍軍

​​

041-使用DM進行同步上遊資料到 TiDB

​​

另外需要配置 ​

​enable_gtid=true​

​​ 如果不是gtid格式的,則需要修改這個 ​

​relay_binlog_name​

​ (在mysql執行 ​

​show BINARY logs​

​ )

​mysql_password​

​ 需要使用 ​

​dmctl -encrypt 你的密碼​

​ 如果找不到dmctl,確定執行了 ​

​ansible-playbook local_prepare.yml​

​ 後在 ​

​/path/to/dm-ansible/resources/bin/dmctl​

dm的worker支援單機多執行個體,也支援單機單執行個體(推薦) ,如果因為資源問題,要開啟單機多執行個體的話,

[dm_worker_servers]
dm_worker1_1 ansible_host=172.16.10.72 server_id=101 deploy_dir=/data1/dm_worker dm_worker_port=8262 mysql_host=172.16.10.81 mysql_user=root mysql_password='VjX8cEeTX+qcvZ3bPaO4h0C80pe/1aU=' mysql_port=3306
dm_worker1_2 ansible_host=172.16.10.72 server_id=102 deploy_dir=/data2/dm_worker dm_worker_port=8263 mysql_host=172.16.10.82 mysql_user=root mysql_password='VjX8cEeTX+qcvZ3bPaO4h0C80pe/1aU=' mysql_port=3306

dm_worker2_1 ansible_host=172.16.10.73 server_id=103 deploy_dir=/data1/dm_worker dm_worker_port=8262 mysql_host=172.16.10.83 mysql_user=root mysql_password='VjX8cEeTX+qcvZ3bPaO4h0C80pe/1aU=' mysql_port=3306
dm_worker2_2 ansible_host=172.16.10.73 server_id=104 deploy_dir=/data2/dm_worker dm_worker_port=8263 mysql_host=172.16.10.84 mysql_user=root mysql_password='VjX8cEeTX+qcvZ3bPaO4h0C80pe/1aU=' mysql_port=3306      

注意 ​

​server_id=101 deploy_dir=/data1/dm_worker dm_worker_port=8262​

​​ 别沖突,尤其是 ​

​deploy_dir​

​​ 和 ​

​dm_worker_port​

第九步,如果部署dm的節點數太多,可以提升并發數 ​

​ansible-playbook deploy.yml -f 10​

​​ 第十步,啟動 ​

​ansible-playbook start.yml​

上述是簡單操作, 如果涉及到複雜的,例如,擴容,縮容dm節點,重新開機dm-master或者dm-worker,可以參考 ​​DM 叢集操作​​

配置DM

如何看文檔

配置dm-worker的tasks,三段文檔結合着看

041-使用DM進行同步上遊資料到 TiDB

一般場景,使用 ​​Data Migration 簡單使用場景​​ 即可滿足。

庫重命名

庫重命名,将上遊的user,備份成user_north庫。另外,不支援執行個體内databases批量加字首或者字尾。是以,有多少個需要重命名的,就乖乖寫多少個吧

routes:
  ...
  instance-1-user-rule:
    schema-pattern: "user"
    target-schema: "user_north"      

忽略庫或者表

black-white-list:
  log-ignored:
    ignore-dbs: ["log"] # 忽略同步log庫
    ignore-tables:
    - db-name: "test" # 忽略同步log庫内的test表
      tbl-name: "log"      

盡量使用白名單

個人建議盡量使用白名單進行同步,防止因為新增庫dm校驗不通過,導緻task被pause掉。此時的假設是,同步任務是嚴謹的,不應該出現不可控因素。當然這隻是建議。

如果 上遊資料庫有,a,b,c三個庫,前期白名單隻寫了a,b,進行全量+增量同步(all模式),并且task的unit已經是sync(非dump),如果此時要同步庫,此時如果隻是簡單改白名單,然後pause-task,update-task,resume-task,會報表不存在的錯。具體的解決辦法,可以參見 我在tug上提的問題 ​​​https://asktug.com/t/db/616​​​ ,感謝 wangxj​​@pingCAP​​

black-white-list:
  rule-1:
    do-dbs: ["~^test-*"] 同步所有test-開頭的庫      

忽略drop和truncate操作

畢竟使用DM是用于同步資料,在一定程度上也可以用于災備場景使用,萬一業務庫被人drop,truncate了,tidb這還可以救命,是以建議忽略這些危險操作,有必要的,可以人工去執行。

filters:
  ...
  store-filter-rule:
    schema-pattern: "store"
    events: ["drop database", "truncate table", "drop table"]
    action: Ignore      

使用DM Portal生成配置檔案,但是Portal生成的是不支援gtid的,詳見 軍軍 的解釋,詳細使用,參見 ​​DM Portal 簡介​​

​​

041-使用DM進行同步上遊資料到 TiDB

​​

​​

041-使用DM進行同步上遊資料到 TiDB

​​

啟動DM

正常操作

參考 ​​管理資料同步任務​​​ 使用 ​

​./dmctl -master-addr 172.16.30.14​

​ 進入互動式指令界面(不支援非互動式的,導緻我在使用中遇到,當報錯資訊特别大時,超過緩沖區,會導緻看不到有效的報錯資訊,check-task xx-task >result.log 這種的不支援,希望後邊能改進下 )

  • 啟動任務​

    ​start-task /path/to/task.yaml​

    ​ 注意是task檔案,而不是任務名
  • 查詢任務​

    ​query-status [task-name]​

    ​ task-name是可選的,不填查所有,填了,隻查指定的
  • 暫停任務​

    ​pause-task task-name​

    ​ ,如果要更新task檔案(update-task) task一定要處于pause狀态(報錯導緻的pause也行)
  • 恢複同步​

    ​resume-task task-name​

    ​​ 處于暫停(pause)的任務要恢複,需要使用resume-task ,如果是​

    ​full​

    ​​ 或者​

    ​all​

    ​ 時unit處于dump狀态的(非load),resume-task時會清空已經dump到本地的檔案,重新拉取(想想200多G的資料庫,到99%了,突然pause了,就肝兒顫)
  • 更新同步任務​

    ​update-task /path/to/task.yaml​

    ​​ 注意是task檔案,不是任務名,執行更新操作,必須是pause狀态,是以,盡量别再dump時執行update,要執行也是在前期執行。執行後,需要使用​

    ​resume-task​

    ​ 啟動已pause的任務
  • 停止任務​

    ​stop-task task-name​

常見問題

  1. check通過,start時報錯,或者start也正常,query時報錯,這種錯,有跟沒有差別不大,隻能ssh到worker節點,看日志​

    ​/path/to/deploy/log/​

​​

041-使用DM進行同步上遊資料到 TiDB

​​

  1. ​Couldn't acquire LOCK BINLOG FOR BACKUP, snapshots will not be consistent:Access denied; you need (at least one of) the SUPER privilege(s) for this operation​

​​

041-使用DM進行同步上遊資料到 TiDB

​​

如果沒有reload權限,會報錯,但是不會終止操作,可以忽略

注意,如果是阿裡雲的rds的話,預設是把reload權限給去掉的。

​​

041-使用DM進行同步上遊資料到 TiDB

​​

  1. sql-mode 不一緻引起的問題,mysql預設的sql-mode是空字元串,參考​​SQL 模式​​​ ,排查方式​

    ​SELECT @@sql_mode​

    ​​ ,如果是tidb是新庫,可以​

    ​set global sql_mode='';​

    ​​ 如果要改mysql的話,需要寫到​

    ​my.ini​

    ​ 裡,防止重新開機失效。

​​

041-使用DM進行同步上遊資料到 TiDB

​​

  1. all模式同步資料,如果task狀态已經是sync,此時這個task白名單新增庫或者表會導緻報錯,表不存在,然後task被pause。要麼使用full-task+incremental-task兩個檔案,每次白名單新增時,先更新full-task,再更新incremental-task,要麼直接新啟一個task,用于full更新白名單庫,然後改all的task,重新開機即可。

​​

041-使用DM進行同步上遊資料到 TiDB

​​

  1. 處于dump的任務,一旦pause了,再次resume,會删除已dump的資料檔案,重新拉取

​​

041-使用DM進行同步上遊資料到 TiDB

​​

參考資料

  • ​​我的部落格​​
  • ​​我的掘金​​
  • ​​DataX在有贊大資料平台的實踐​​
  • ​​Data Migration 常見問題​​
  • ​​使用 DM-Ansible 部署 DM 叢集​​