技術分享 | MySQL 和 TiDB 互相快速導入全量數據

作者:楊濤濤

資深數據庫專家,專研 MySQL 十餘年。擅長 MySQL、PostgreSQL、MongoDB 等開源數據庫相關的備份恢復、SQL 調優、監控運維、高可用架構設計等。目前任職於愛可生,爲各大運營商及銀行金融企業提供 MySQL 相關技術支持、MySQL 相關課程培訓等工作。

本文來源:原創投稿

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


MySQL 和 TiDB 有80%的語法兼容,大部分場景下可以混用,MySQL 可以做 TiDB 的上游,TiDB 也可以做 MySQL 的上游,今天來分享下兩種數據庫之間全量數據如何導入導出。

一般來講,邏輯導入導出格式有兩種,一種是 CSV 、TSV 等格式,另外一種就是 SQL 語句的格式。

這裏我用兩張表作爲導入導出示例,一張是表 t1 ,另外一張是表 t1_csv ,記錄都有 200W ; TiDB 版本爲3.1.2,MySQL 版本爲 5.7.31。

第一部分:TiDB 爲上游導出數據,MySQL 作爲下游導入數據。

TiDB 數據庫本身不支持表記錄直接導出爲 CSV 文件,不過 TiDB 有額外的工具來導出(3.0 版本 mydumper 來導出 SQL 文件、4.0 版本有 dumpling 來導出 SQL 和 CSV )。

分別用 dumper 導出表 t1 ,結果爲 SQL 文件;dumpling 導出表 t1_csv 結果爲 CSV 文件;這兩個導出程序和 mysqldump 一樣,需要連接在線數據庫。

dumper 導出 sql 文件的命令行:(每個文件大概256M)

[root@ytt-pc data_sql]# mydumper  -u root -h 127.0.0.1 -P 4001 -B ytt -T t1  -F 256 -o /tmp/data_sql/

導出來的文件列表:(類似我之前分享的 MySQL SHELL UTIL 組件導出的文件列表)

[root@ytt-pc data_sql]# ls -sihl
總用量 1.1G
201327040 4.0K -rw-r--r-- 1 root root 146 5月 12 18:21 metadata
201327041 4.0K -rw-r--r-- 1 root root 65 5月 12 18:21 ytt-schema-create.sql
201327077 246M -rw-r--r-- 1 root root 246M 5月 12 18:21 ytt.t1.000000002.sql
201327078 246M -rw-r--r-- 1 root root 246M 5月 12 18:21 ytt.t1.000000003.sql
201327079 245M -rw-r--r-- 1 root root 245M 5月 12 18:21 ytt.t1.000000004.sql
201327080 122M -rw-r--r-- 1 root root 122M 5月 12 18:21 ytt.t1.000000005.sql
201327075 245M -rw-r--r-- 1 root root 245M 5月 12 18:21 ytt.t1.00001.sql
201327076 4.0K -rw-r--r-- 1 root root 327 5月 12 18:21 ytt.t1-schema.sql

dumpling 導出 csv 文件的命令行:(同樣,每個 CSV 文件也是256M)

[root@ytt-pc data_csv]# dumpling  -B ytt -T ytt.t1_csv -uroot  -P4001 -h 127.0.0.1 --filetype csv --filesize 256M -o /tmp/data_csv/
Release version: v4.0.8
Git commit hash: b84f64ff362cedcb795aa23fa1188ba7b7c9a7d7
Git branch: heads/refs/tags/v4.0.8
Build timestamp: 2020-10-30 08:14:27Z
Go version: go version go1.13 linux/amd64

[2021/05/12 18:22:05.686 +08:00] [INFO] [config.go:180] ["detect server type"] [type=TiDB]
[2021/05/12 18:22:05.686 +08:00] [INFO] [config.go:198] ["detect server version"] [version=3.1.2]
...

導出來的文件列表:

[root@ytt-pc data_csv]# ls -sihl
總用量 1.1G
555999 4.0K -rw-r--r-- 1 root root 146 5月 12 18:22 metadata
127975 4.0K -rw-r--r-- 1 root root 94 5月 12 18:22 ytt-schema-create.sql
132203 257M -rw-r--r-- 1 root root 257M 5月 12 18:22 ytt.t1_csv.0.csv
555974 257M -rw-r--r-- 1 root root 257M 5月 12 18:22 ytt.t1_csv.1.csv
555996 257M -rw-r--r-- 1 root root 257M 5月 12 18:22 ytt.t1_csv.2.csv
555997 257M -rw-r--r-- 1 root root 257M 5月 12 18:22 ytt.t1_csv.3.csv
555998 71M -rw-r--r-- 1 root root 71M 5月 12 18:22 ytt.t1_csv.4.csv
127980 4.0K -rw-r--r-- 1 root root 324 5月 12 18:22 ytt.t1_csv-schema.sql

導出來後,我寫了個簡單的腳本來導入這兩張表到 MySQL

#!/bin/sh
usage()
{
        echo ""
     echo "Usage:./source_tidb_to_mysql csv or sql"
        echo ""
}
file_format=$1
file_path_csv=/tmp/data_csv/
file_path_sql=/tmp/data_sql/
if [ "$file_format" = "csv" ];then
 for i in `ls "$file_path_csv"ytt*.csv`
 do 
 {
   load_options="load data infile '$i' into table t1_csv fields terminated by ',' enclosed by '\"' ignore 1 lines"
    mysql -udumper -S /tmp/mysql_sandbox5731.sock -D ytt -e "$load_options"
 }
 done

elif [ "$file_format" = "sql" ];then
 for i in `ls "$file_path_sql"ytt.t1.*.sql`
 do
 {
    mysql -udumper -S /tmp/mysql_sandbox5731.sock -D ytt<$i
 }
 done
else
  usage;
fi

分別調用腳本導入表 t1 和 t1_csv 到 MySQL

導入表t1

[root@ytt-pc scripts]# ./source_tidb_to_mysql sql

導入表t1_csv

[root@ytt-pc scripts]# ./source_tidb_to_mysql csv

簡單校驗下表記錄數是否爲200W:

mysql [localhost:mysql_sandbox5731.sock] {root} (ytt) > select (select count(*) from t1) 't1_count', (select count(*) from t1_csv) 't1_csv_count';
+----------+--------------+
| t1_count | t1_csv_count |
+----------+--------------+
| 2000000 | 2000000 |
+----------+--------------+
1 row in set (1.86 sec)

第二部分:MySQL 爲上游導出數據,TiDB 作爲下游導入數據。

爲了避免 MySQL 自由工具導出後可能需要做額外的文本修正,這裏直接用 TiDB 提供的導出工具 dumpling 來導出 MySQL 表 t1 和 t1_csv ,dumpling 自動檢測到數據源是 MySQL 。

[root@ytt-pc data_csv]# dumpling  -B ytt -T ytt.t1_csv -udumper -P5731  -h 127.0.0.1 --filetype csv --filesize 256M -o /tmp/data_csv/
Release version: v4.0.8
Git commit hash: b84f64ff362cedcb795aa23fa1188ba7b7c9a7d7
Git branch: heads/refs/tags/v4.0.8
Build timestamp: 2020-10-30 08:14:27Z
Go version: go version go1.13 linux/amd64

[2021/05/12 17:57:24.035 +08:00] [INFO] [config.go:180] ["detect server type"] [type=MySQL]
[2021/05/12 17:57:24.035 +08:00] [INFO] [config.go:198] ["detect server version"] [version=5.7.31]
...

同樣,用 dumpling 工具導出格式爲 SQL 的文件

[root@ytt-pc data_sql]# dumpling  -B ytt -T ytt.t1 -udumper -P5731  -h 127.0.0.1 --filetype sql --filesize 256M -o /tmp/data_sql/
Release version: v4.0.8
Git commit hash: b84f64ff362cedcb795aa23fa1188ba7b7c9a7d7
Git branch: heads/refs/tags/v4.0.8
Build timestamp: 2020-10-30 08:14:27Z
Go version: go version go1.13 linux/amd64

[2021/05/12 18:01:56.984 +08:00] [INFO] [config.go:180] ["detect server type"] [type=MySQL]
[2021/05/12 18:01:56.984 +08:00] [INFO] [config.go:198] ["detect server version"] [version=5.7.31]
...

MySQL 源數據導出來後,用 TiDB 提供的全量數據導入工具 tidb-lightning 進行快速導入,這個工具支持 CSV 數據源或者 mydumper/dumpling 導出的 SQL 數據源。

tidb-lightning 工具得先運行後端程序 tikv-importer ,用來把 tidb-lightning 轉換的鍵值對應用到數據庫;

再啓動 tidb-lightning 程序來接受數據源,並且轉換爲鍵值對交給後臺 tikv-importer 進行導入。
  1. 啓動 tikv-importer 常駐進程,端口默認8287 [root@ytt-pc data_sql]# tikv-importer -A 127.0.0.1:8287
  2. 接下來啓動 tikv-lightning 任務開始導入:(默認端口8289)
分別導入表 t1 和表 t1_csv
   導入表t1
   [root@ytt-pc data_sql]# tidb-lightning   --importer 127.0.0.1:8287  --status-addr 127.0.0.1:8289 --tidb-host 127.0.0.1 --tidb-port 4001 --tidb-status 10081 --tidb-user root -d /tmp/data_sql 
   
   導入表t1_csv
   [root@ytt-pc data_sql]# tidb-lightning   --importer 127.0.0.1:8287  --status-addr 127.0.0.1:8289 --tidb-host 127.0.0.1 --tidb-port 4001 --tidb-status 10081 --tidb-user root -d /tmp/data_csv 

同樣進行下簡單的校驗:

mysql [127.0.0.1:4001] {root} (ytt) > select (select count(*) from t1) t1_count, (select count(*) from t1_csv) t1_csv_count;
+----------+--------------+
| t1_count | t1_csv_count |
+----------+--------------+
| 2000000 | 2000000 |
+----------+--------------+
1 row in set (1.04 sec)

如果表數據量很小,可以考慮直接 MySQL 端執行 select ... into outfile 的方式導出 CSV ,完後 TiDB 端直接導入

比如直接導入1W行的小表 t1_small ,MySQL 端導出 CSV :

mysql [localhost:mysql_sandbox5731.sock] {root} (ytt) > select * from t1_small into outfile '/tmp/data_csv/t1_small.csv' fields terminated by ',' enclosed by '"';
Query OK, 10000 rows affected (0.03 sec)

TiDB 端直接 SQL 命令導入:

mysql [127.0.0.1:4001] {root} (ytt) > load data local infile '/tmp/data_csv/t1_small.csv' into table t1_small fields terminated by ',' enclosed by '"';
Query OK, 10000 rows affected (1.55 sec)
Records: 10000 Deleted: 0 Skipped: 0 Warnings: 0



文章推薦:

新特性解讀 | MySQL 8.0 通用表達式(WITH)深入用法

新特性解讀 | MySQL 8.0 窗口函數框架用法

新特性解讀 | 高效獲取不連續主鍵區間



社區近期動態




本文關鍵字:#TiDB# #MySQL# #數據導入導出#
  點一下“閱讀原文”瞭解更多資訊

本文分享自微信公衆號 - 愛可生開源社區(ActiontechOSS)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章