Dumplingを使ってTiDBのデータをエクスポートしてみた
Dumplingを使ってTiDBのデータをエクスポートしてみた
CX事業本部@大阪の岩田です。
前回のブログでCSVファイルをTiDBにインポートしてみました。
今度は逆にTiDBからデータをエクスポートする操作を試してみます。
Dumpling
TiDBからのデータエクスポートはDumplingというツールを利用します。DumplingはTiDBだけでなくMySQLにも対応しているので、MySQLのデータをDumplingでエクスポート後にTiDB LightningでTiDBにインポートするといった使い方もできます。Dumplingは様々な機能を持っていますが、公式ドキュメントではDumplingの特徴として以下の点が紹介されています。
Dumplingには以下のようなメリットがあります。
- SQL や CSV などの複数の形式でのデータのエクスポートをサポートします。
- データのフィルタリングを容易にするテーブルフィルター機能をサポートします。
- Amazon S3 クラウドstorageへのデータのエクスポートをサポートします。
- TiDB に対してさらに最適化が行われています。
Dumpling Overview | PingCAP Docs
環境
今回検証に利用した環境は以下の通りです。
- TiDB: 5.7.28-TiDB-v6.6.0-serverless
- Dumpling: v7.6.0
Dumplingの実行はAWSのCloudShell/Google CloudのCloud Shell上から実施しました
やってみる
ここからは公式ドキュメントの手順に従いながら、いくつかのパターンでデータのエクスポートを試していきます
Dumplingのインストール
まずDumplingをインストールします。Dumplingはtiupでインストールできるのでtiup install dumpling
を実行してインストールしましょう。
$ tiup install dumpling download https://tiup-mirrors.pingcap.com/dumpling-v7.6.0-linux-amd64.tar.gz 48.22 MiB / 48.22 MiB 100.00% 5.32 GiB/s
インストールできたらtiup dumpling --version
でバージョン情報でも確認してみましょう。
以下のように出力されればOKです。
Checking updates for component dumpling... Timedout (after 2s) Starting component dumpling: /home/cloudshell-user/.tiup/components/dumpling/v7.6.0/dumpling --version Release version: v7.6.0 Git commit hash: 52794d985ba6325d75a714d4eaa0838d59425eb6 Git branch: heads/refs/tags/v7.6.0 Build timestamp: 2024-01-22 02:14:07Z Go version: go version go1.21.5 linux/amd64
SQLファイルにエクスポートしてみる
まずはSQL形式でTiDBの中身をエクスポートしてみましょう。CloudShellから以下のコマンドを実行します。
$ tiup dumpling -u <ユーザー名> -P 4000 -h <TiDB Serverlessのエンドポイント> --filetype sql -t 8 -o /tmp/test -r 200000 -F 4MiB -p <パスワード>
各オプションの意味は以下の通りです
- -u: ユーザー名
- -P: ポート番号
- -h: ホスト名
- --filetype: エクスポートされるファイルの種類 (csv/sql)
- -t: 同時バックアップスレッドの数
- -o: データエクスポート先のパス ローカルファイルシステムだけでなくS3も指定可能
- -r: テーブル内の同時実行を有効/無効化
- -F: このオプションで指定したサイズに合わせてエクスポート時にファイルを分割 今回の例だと4MごとにSQLファイルが生成される
- -p パスワード mysqlコマンドだと-pのみ指定した場合はプロンプトでパスワードが聞かれるのですが、dumplingはコマンドライン引数でパスワードを指定するのが必須のようです。historyに残るので注意が必要ですね
コマンド実行後は以下のように出力されます
[2024/02/02 04:32:19.026 +00:00] [INFO] [versions.go:54] ["Welcome to dumpling"] ["Release Version"=v7.6.0] ["Git Commit Hash"=52794d985ba6325d75a714d4eaa0838d59425eb6] ["Git Branch"=heads/refs/tags/v7.6.0] ["Build timestamp"="2024-01-22 02:14:07"] ["Go Version"="go version go1.21.5 linux/amd64"] [2024/02/02 04:32:19.472 +00:00] [INFO] [version.go:434] ["detect server version"] [type=TiDB] [version=6.6.0-serverless] [2024/02/02 04:32:19.478 +00:00] [INFO] [dump.go:1446] ["meet some problem while fetching pd addrs. This won't affect dump process"] [error="sql: SELECT * FROM information_schema.cluster_info where type = 'pd';: Error 1142 (42000): SELECT command denied to user '<ユーザー名>'@'%' for table 'cluster_info', see https://docs.pingcap.com/tidbcloud/limited-sql-features#system-tables for more details."] [2024/02/02 04:32:19.484 +00:00] [WARN] [dump.go:1506] ["If the amount of data to dump is large, criteria: (data more than 60GB or dumped time more than 10 minutes)\nyou'd better adjust the tikv_gc_life_time to avoid export failure due to TiDB GC during the dump process.\nBefore dumping: run sql `update mysql.tidb set VARIABLE_VALUE = '720h' where VARIABLE_NAME = 'tikv_gc_life_time';` in tidb.\nAfter dumping: run sql `update mysql.tidb set VARIABLE_VALUE = '10m' where VARIABLE_NAME = 'tikv_gc_life_time';` in tidb.\n"] ...略 [2024/02/02 04:32:20.329 +00:00] [INFO] [writer.go:272] ["no data written in table chunk"] [database=fortune500] [table=fortune500_2018_2022] [chunkIdx=0] [2024/02/02 04:32:20.367 +00:00] [INFO] [writer.go:272] ["no data written in table chunk"] [database=lightning_task_info] [table=conflict_records] [chunkIdx=0] [2024/02/02 04:32:20.369 +00:00] [INFO] [writer.go:272] ["no data written in table chunk"] [database=lightning_task_info] [table=conflict_records] [chunkIdx=1] [2024/02/02 04:32:20.402 +00:00] [INFO] [writer.go:272] ["no data written in table chunk"] [database=blog] [table=part] [chunkIdx=0] [2024/02/02 04:32:20.509 +00:00] [INFO] [collector.go:264] ["backup success summary"] [total-ranges=12] [ranges-succeed=12] [ranges-failed=0] [total-take=241.031795ms] [total-rows=52499] [total-kv-size=5.251MB] [average-speed=21.79MB/s] [2024/02/02 04:32:20.510 +00:00] [INFO] [main.go:82] ["dump data successfully, dumpling will exit now"]
出力されたファイルを確認してみましょう。
$ tree -h /tmp/test/ /tmp/test/ ├── [ 4.0M] blog.part.0000000010000.sql ├── [ 836K] blog.part.0000000010001.sql ├── [ 453] blog.part-schema.sql ├── [ 132] blog-schema-create.sql ├── [ 196K] fortune500.fortune500_2018_2022.0000000010000.sql ├── [ 761] fortune500.fortune500_2018_2022-schema.sql ├── [ 138] fortune500-schema-create.sql ├── [ 578] lightning_task_info.conflict_records-schema.sql ├── [ 147] lightning_task_info-schema-create.sql └── [ 146] metadata
<DB名>.<テーブル名>.<連番>.sql
という形式で-F
オプションで指定した単位毎にデータがエクスポートされていることが分かります。CREATE TABLE
文のようなスキーマ情報は<DB名>.<テーブル名>-schema.sql
という形式で出力されています。
エクスポートされたデータの中身を軽く確認しておきましょう。
$ head /tmp/test/blog.part.0000000010000.sql /*!40014 SET FOREIGN_KEY_CHECKS=0*/; /*!40101 SET NAMES binary*/; INSERT INTO `part` VALUES (15,'NUL next','\0','MFGR#47','MFGR#3438','indigo','LARGE ANODIZED BRASS',45,'LG CASE'), (22,'floral beige','MFGR#4','MFGR#44','MFGR#4421','medium','PROMO, POLISHED BRASS',19,'LG DRUM'), (23,'bisque slate','MFGR#4','MFGR#41','MFGR#4137','firebrick','MEDIUM \"BURNISHED\" TIN',42,'JUMBO JAR'), (24,'dim white','MFGR#4','MFGR#45','MFGR#459','saddle','MEDIUM , \"PLATED\" STEEL',20,'MED CASE'), (27,'drab cornflower','MFGR#2','MFGR#22','MFGR#2225','plum','LARGE, ANODIZED TIN',20,'MED PKG'), (28,'honeydew dim','MFGR#2','MFGR#21','MFGR#2130','green','SMALL, \"PLATED\" COPPER',19,'JUMBO PKG'), (42,'azure bisque','MFGR#1','MFGR#14','MFGR#1414','midnight','MEDIUM BURNISHED TIN',45,'LG BOX'),
INSERT文としてエクスポートされていることが分かります
CSV形式でS3にエクスポートしてみる
今度は少しパターンを変えて試してみます。エクスポートするファイルの形式をcsvに、出力先をS3に変えて実行してみます。
$ tiup dumpling -u <ユーザー名> -P 4000 -h <TiDB Serverlessのエンドポイント> --filetype csv -t 8 -o s3://<S3バケットのパス> -r 200000 -F 4MiB -p <パスワード>
["dump data successfully, dumpling will exit now"]
のログを確認後、出力先S3バケットの中身を確認してみました。
簡単にファイルの中身を確認しておきましょう
$aws s3 cp s3://<バケット名>/<CSVファイル名> - | head "p_partkey","p_name","p_mfgr","p_category","p_brand1","p_color","p_type","p_size","p_container" 42878,"burnished violet","MFGR#1","MFGR#15","MFGR#1540","dodger","PROMO PLATED STEEL",1,"WRAP DRUM" 42903,"sienna dark","MFGR#3","MFGR#32","MFGR#3230","pink","SMALL BRUSHED BRASS",5,"LG JAR" 42908,"cyan chocolate","MFGR#5","MFGR#54","MFGR#5420","violet","STANDARD BURNISHED COPPER",16,"MED BOX" 42910,"misty cyan","MFGR#2","MFGR#22","MFGR#2240","indian","STANDARD PLATED NICKEL",35,"SM CAN" 42918,"violet purple","MFGR#5","MFGR#51","MFGR#5110","firebrick","STANDARD BRUSHED NICKEL",9,"MED PACK" 42926,"tomato lace","MFGR#3","MFGR#31","MFGR#3139","burlywood","SMALL BRUSHED NICKEL",17,"WRAP CASE" 42932,"bisque green","MFGR#3","MFGR#31","MFGR#3113","pale","STANDARD BRUSHED STEEL",20,"JUMBO PACK" 42946,"tomato lace","MFGR#1","MFGR#11","MFGR#112","rose","SMALL POLISHED TIN",3,"JUMBO CASE" 42948,"navy chiffon","MFGR#2","MFGR#22","MFGR#2221","honeydew","PROMO BURNISHED TIN",29,"SM JAR" download failed: s3://<バケット名>/<CSVファイル名> to - [Errno 32] Broken pipe
パイプでhead
コマンドに渡したのでエラーメッセージが出ていますが、CSVファイル自体は正しくエクスポートされてそうです。
ファイルを圧縮しつつGCSバケットに出力してみる
S3にファイルがエクスポートできたので、今度はGoogle CloudのCloud Storageにエクスポートしてみましょう。せっかくなので--compress
オプションを指定してGZIP形式に圧縮しつつやってみます。今度はGoogle CloudのCloud Shellから以下のコマンドを実行します。
$ tiup dumpling -u <ユーザー名> -P 4000 -h <TiDB Serverlessのエンドポイント> --filetype csv -t 8 -o gcs://<バケット名> -r 200000 -F 4MiB --compress gzip -p <パスワード>
出力後のStorageバケットの様子です
先程のパターンと比較してファイルサイズが小さくなっており、GZIPの圧縮が効いていることが分かります。
GZIP圧縮されたCSVファイルを解凍して簡単に中身を確認してみましょう
$ gsutil cp gs://<バケット名>/<GZIPファイル名> -| gunzip | head "p_partkey","p_name","p_mfgr","p_category","p_brand1","p_color","p_type","p_size","p_container" 42878,"burnished violet","MFGR#1","MFGR#15","MFGR#1540","dodger","PROMO PLATED STEEL",1,"WRAP DRUM" 42903,"sienna dark","MFGR#3","MFGR#32","MFGR#3230","pink","SMALL BRUSHED BRASS",5,"LG JAR" 42908,"cyan chocolate","MFGR#5","MFGR#54","MFGR#5420","violet","STANDARD BURNISHED COPPER",16,"MED BOX" 42910,"misty cyan","MFGR#2","MFGR#22","MFGR#2240","indian","STANDARD PLATED NICKEL",35,"SM CAN" 42918,"violet purple","MFGR#5","MFGR#51","MFGR#5110","firebrick","STANDARD BRUSHED NICKEL",9,"MED PACK" 42926,"tomato lace","MFGR#3","MFGR#31","MFGR#3139","burlywood","SMALL BRUSHED NICKEL",17,"WRAP CASE" 42932,"bisque green","MFGR#3","MFGR#31","MFGR#3113","pale","STANDARD BRUSHED STEEL",20,"JUMBO PACK" 42946,"tomato lace","MFGR#1","MFGR#11","MFGR#112","rose","SMALL POLISHED TIN",3,"JUMBO CASE" 42948,"navy chiffon","MFGR#2","MFGR#22","MFGR#2221","honeydew","PROMO BURNISHED TIN",29,"SM JAR"
正しくエクスポートされていそうです。
まとめ
TiDBからデータをエクスポートするためのツールDumplingについて調べてみました。MySQLからのデータエクスポートや各種ストレージサービスへのデータ出力にも対応しているのでMySQLからTiDBにデータを移行する際に便利に使えそうだと感じました。他のツール・機能と合わせて覚えておくと便利に使えそうです。