TiDB数据导出导入工具Dumpling和Lightning实战指南

掌握TiDB数据导出导入利器!Dumpling实现逻辑备份,Lightning快速导入,轻松搞定数据迁移和恢复。

原文标题:数据库系列之TiDB数据导出和导入工具

原文作者:牧羊人的方向

冷月清谈:

本文介绍了TiDB的数据导出工具Dumpling和数据导入工具Lightning的使用方法,并结合实际场景进行了测试。

**Dumpling:**
Dumpling是一款用Go语言开发的逻辑备份工具,可以将TiDB或MySQL的数据导出为SQL或CSV格式。它支持配置TiDB单条SQL内存限制、自动调整GC时间、使用隐藏列优化导出性能等特性,并能通过设置tidb_snapshot的值来保证数据一致性。

Dumpling支持多种过滤数据的方式,包括使用--where选项、--filter选项以及-B或-T选项。同时,可以通过设置-o、-F、-r等选项来提高Dumpling的并发性能。此外,Dumpling还支持通过--consistency选项控制数据一致性级别,并能够导出TiDB的历史数据快照。对于大表的导出,可以通过设置--rows、--tidb-mem-quota-query以及--params等参数来控制TiDB的内存使用,避免OOM。

**Lightning:**
Lightning是一款用于将全量数据快速导入TiDB的工具,支持Dumpling或CSV格式的数据源。它适用于导入大量新数据或恢复备份数据等场景。

Lightning的导入过程包括切换TiKV集群至“导入模式”、创建表结构、分割表数据为多个区块、并发编码数据并写入本地临时文件、将数据导入TiKV集群、校验数据完整性、调整AUTO_INCREMENT值以及切换TiKV集群回“普通模式”。

Lightning也支持断点续传、表库过滤等特性,并提供了三种后端模式:Importer-backend、Local-backend和TiDB-backend。其中,Local-backend模式在TiDB 4.0及以上版本中具有更高的性能和更简单的部署方式。此外,Lightning还提供了Web界面,方便用户查看导入进度和管理任务。

文章最后还介绍了如何使用Lightning从CSV文件和SQL文件迁移数据到MySQL,并提供了一些使用Dumpling和Lightning的注意事项。

怜星夜思:

1、文章提到了Dumpling可以通过设置 tidb_snapshot 来保证数据一致性,是不是意味着即使不使用FLUSH TABLES WITH READ LOCK 也不会影响数据的一致性?
2、Lightning 提到了三种后端模式,实际应用中应该如何选择?有没有一些最佳实践可以参考?
3、在使用 Lightning 导入数据时,TiDB 集群无法对外提供服务。有没有什么方法可以减少停机时间?

原文内容

本文简要介绍了TiDB工具生态中的数据导出工具Dumpling和数据快速导入工具Lightning,并结合场景进行测试使用。

1、全量导出工具Dumpling

Dumpling是go语言开发的数据备份工具,可以将TiDB/MySQL中的数据导出为SQL/CSV格式,可以实现逻辑上的全量备份或者导出。Dumpling针对TiDB进行了专门的优化,比如:
  • 支持配置TiDB单条SQL内存限制

  • 针对TiDB v4.0.0以上版本支持自动调整 TiDB GC 时间

  • 使用TiDB的隐藏列_tidb_rowid优化了单表内数据的并发导出性能

  • 对于TiDB可以设置 tidb_snapshot 的值指定备份数据的时间点,从而保证备份的一致性,而不是通过FLUSH TABLES WITH READ LOCK 来保证备份一致性

在使用Dumpling时,需要在已经启动的集群上执行导出命令

[root@tango-01 tidb-toolkit]# tiup cluster display tidb-test
Starting component `cluster`: /root/.tiup/components/cluster/v1.2.3/tiup-cluster display tidb-test
Cluster type: tidb
Cluster name: tidb-test
Cluster version: v4.0.0
SSH type: builtin
ID Role Host Ports OS/Arch Status Data Dir Deploy Dir
-- ---- ---- ----- ------- ------ -------- ----------
192.168.112.10:9093 alertmanager 192.168.112.10 9093/9094 linux/x86_64 Up /tidb-data/alertmanager-9093 /tidb-deploy/alertmanager-9093
192.168.112.10:3000 grafana 192.168.112.10 3000 linux/x86_64 Up - /tidb-deploy/grafana-3000
192.168.112.101:2379 pd 192.168.112.101 2379/2380 linux/x86_64 Up /tidb-data/pd-2379 /tidb-deploy/pd-2379
192.168.112.102:2379 pd 192.168.112.102 2379/2380 linux/x86_64 Up|L|UI /tidb-data/pd-2379 /tidb-deploy/pd-2379
192.168.112.103:2379 pd 192.168.112.103 2379/2380 linux/x86_64 Up /tidb-data/pd-2379 /tidb-deploy/pd-2379
192.168.112.10:9090 prometheus 192.168.112.10 9090 linux/x86_64 Up /tidb-data/prometheus-9090 /tidb-deploy/prometheus-9090
192.168.112.101:4000 tidb 192.168.112.101 4000/10080 linux/x86_64 Up - /tidb-deploy/tidb-4000
192.168.112.102:4000 tidb 192.168.112.102 4000/10080 linux/x86_64 Up - /tidb-deploy/tidb-4000
192.168.112.103:4000 tidb 192.168.112.103 4000/10080 linux/x86_64 Up - /tidb-deploy/tidb-4000
192.168.112.101:20160 tikv 192.168.112.101 20160/20180 linux/x86_64 Up /tidb-data/tikv-20160 /tidb-deploy/tikv-20160
192.168.112.102:20160 tikv 192.168.112.102 20160/20180 linux/x86_64 Up /tidb-data/tikv-20160 /tidb-deploy/tikv-20160
192.168.112.103:20160 tikv 192.168.112.103 20160/20180 linux/x86_64 Up /tidb-data/tikv-20160 /tidb-deploy/tikv-20160
Total nodes: 12

所有通过Dumpling导出的数据都可以通过Lightning导入到TiDB中。

1.1 安装Dumpling工具

TiDB工具包中包括了TiDB Binlog、TiDB Lightning、BR备份恢复工具、TiDB Data Migration、Dumpling等,下载链接为https://download.pingcap.org/tidb-toolkit-{version}-linux-amd64.tar.gz

[root@tango-01 src]# tar -xzvf  tidb-toolkit-v4.0.10-linux-amd64.tar.gz
[root@tango-01 src]# mv tidb-toolkit-v4.0.10-linux-amd64 ../tidb-toolkit
[root@tango-01 bin]# ls
br dumpling mydumper pd-tso-bench sync_diff_inspector tidb-lightning tidb-lightning-ctl tikv-importer
1.2 从TiDB/MySQL导出数据

1)导出到SQL文件

Dumpling默认导出数据格式为sql文件,可以通过设置--filetype sql导出数据到sql文件:

[root@tango-01 tidb-toolkit]# ./bin/dumpling -u root -P4000 -h192.168.112.101 --filetype sql --threads 32 -o /tmp/test -F 256MiB

2)输出文件格式

  • metadata:此文件包含导出的起始时间,以及 master binary log 的位置。
[root@tango-01 test]# cat metadata 
Started dump at: 2021-02-14 14:38:30
SHOW MASTER STATUS:
Log: tidb-binlog
Pos: 422912907133583361
GTID:

Finished dump at: 2021-02-14 14:38:33
  • {schema}-schema-create.sql:创建schema的SQL文件。
[root@tango-01 test]# cat tango-schema-create.sql
/*!40101 SET NAMES binary*/;
CREATE DATABASE `tango` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
[root@tango-01 test]# cat tango.tab_tidb-schema.sql
/*!40101 SET NAMES binary*/;
CREATE TABLE `tab_tidb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '',
`age` int(11) NOT NULL DEFAULT 0,
`version` varchar(20) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `idx_age` (`age`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=30002;
  • {schema}.{table}.{0001}.{sql|csv}:数据源文件
[root@tango-01 test]# cat tango.tab_tidb.000000000.sql
/*!40101 SET NAMES binary*/;
INSERT INTO `tab_tidb` VALUES
(1,'TiDB',5,'TiDB-v4.0.0');
  • -schema-view.sql、-schema-trigger.sql、*-schema-post.sql:其他导出文件

3)导出到CSV文件

[root@tango-01 tidb-toolkit]# ./bin/dumpling -u root -P4000 -h192.168.112.101 --filetype csv --threads 32 -o /tmp/test1  --sql 'select * from tango.tab_tidb'

4)输出文件格式

  • metadata:此文件包含导出的起始时间,以及 master binary log 的位置。
[root@tango-01 test1]# cat metadata 
Started dump at: 2021-02-14 14:48:46
SHOW MASTER STATUS:
Log: tidb-binlog
Pos: 422913068470108161
GTID:

Finished dump at: 2021-02-14 14:48:47
  • {schema}.{table}.{0001}.{sql|csv}:数据源文件
[root@tango-01 test1]# cat result.000000000.csv 
"id","name","age","version"
1,"TiDB",5,"TiDB-v4.0.0"
1.3 筛选导出的数据

1)使用 --where 选项筛选数据

默认情况下,Dumpling会导出系统数据库(包括 mysql 、sys 、INFORMATION_SCHEMA 、PERFORMANCE_SCHEMA、METRICS_SCHEMA 和 INSPECTION_SCHEMA)外所有其他数据库。可以使用 --where <SQL where expression> 来选定要导出的记录,比如:

[root@tango-01 tidb-toolkit]# ./bin/dumpling -u root -P4000 -h192.168.112.101 --threads 32 -o /tmp/test1  --where "id < 10"

上述命令将会导出各个表的 id < 10 的数据

[root@tango-01 test1]# ll
total 32
-rw-r--r-- 1 root root 146 Feb 14 15:05 metadata
-rw-r--r-- 1 root root 53 Feb 14 14:48 result.000000000.csv
-rw-r--r-- 1 root root 96 Feb 14 15:05 tango-schema-create.sql
-rw-r--r-- 1 root root 194 Feb 14 15:05 tango.tab01.000000000.sql
-rw-r--r-- 1 root root 237 Feb 14 15:05 tango.tab01-schema.sql
-rw-r--r-- 1 root root 311 Feb 14 15:05 tango.tab_tidb.000000000.sql
-rw-r--r-- 1 root root 346 Feb 14 15:05 tango.tab_tidb-schema.sql
-rw-r--r-- 1 root root 95 Feb 14 15:05 test-schema-create.sql
[root@tango-01 test1]#
[root@tango-01 test1]# cat tango.tab01.000000000.sql
/*!40101 SET NAMES binary*/;
INSERT INTO `tab01` VALUES
(1,'Beijing'),
(2,'Shanghai'),
(3,'Guangzhou'),
(4,'Shenzhen'),
(5,'Foshan'),
(6,'Hangzhou'),
(7,'Chengdu'),
(8,'Wuhan'),
(9,'Changsha');
[root@tango-01 test1]# cat tango.tab_tidb.000000000.sql
/*!40101 SET NAMES binary*/;
INSERT INTO `tab_tidb` VALUES
(1,'TiDB',5,'TiDB-v4.0.0'),
(2,'TiDB',5,'TiDB-v4.0.0'),
(3,'TiDB',5,'TiDB-v4.0.0'),
(4,'TiDB',5,'TiDB-v4.0.0'),
(5,'TiDB',5,'TiDB-v4.0.0'),
(6,'TiDB',5,'TiDB-v4.0.0'),
(7,'TiDB',5,'TiDB-v4.0.0'),
(8,'TiDB',5,'TiDB-v4.0.0'),
(9,'TiDB',5,'TiDB-v4.0.0');

2)使用--filter选项筛选数据

Dumpling可以通过--filter指定table-filter来筛选特定的库表

[root@tango-01 tidb-toolkit]# ./bin/dumpling -u root -P4000 -h192.168.112.101 --threads 32 -o /tmp/test2  --filter "*.tab01"

上述命令将会导出所有数据库中的tab01表

[root@tango-01 test2]# ll
total 36
-rw-r--r-- 1 root root 109 Feb 14 15:09 INFORMATION_SCHEMA-schema-create.sql
-rw-r--r-- 1 root root 146 Feb 14 15:09 metadata
-rw-r--r-- 1 root root 105 Feb 14 15:09 METRICS_SCHEMA-schema-create.sql
-rw-r--r-- 1 root root 96 Feb 14 15:09 mysql-schema-create.sql
-rw-r--r-- 1 root root 109 Feb 14 15:09 PERFORMANCE_SCHEMA-schema-create.sql
-rw-r--r-- 1 root root 96 Feb 14 15:09 tango-schema-create.sql
-rw-r--r-- 1 root root 270 Feb 14 15:09 tango.tab01.000000000.sql
-rw-r--r-- 1 root root 237 Feb 14 15:09 tango.tab01-schema.sql
-rw-r--r-- 1 root root 95 Feb 14 15:09 test-schema-create.sql

3)使用-B或-T选项筛选数据

Dumpling也可以通过-B或-T选项导出特定的数据库/数据表,-B导出指定的数据库、-T导出指定的表。

注:--filter与-T不可同时使用;-T只能是完整的表名形式“库名.表名”

1.4 提高Dumpling的并发
默认情况下,导出的文件会存储到 ./export-<current local time> 目录下。常用选项如下:
  • -o用于选择存储导出文件的目录

  • -F选项用于指定单个文件的最大大小,默认单位为 MiB,也可以是GiB或者KiB

  • -r选项用于指定单个文件的最大记录数,开启后 Dumpling 会开启表内并发,提高导出大表的速度。

利用以上选项可以提高Dumpling的并行度

1.5 Dumpling的数据一致性
Dumpling通过--consistency <consistency level>标志控制导出数据的一致性,有以下几种方式:
  • flush:使用 FLUSH TABLES WITH READ LOCK 来保证一致性。

  • snapshot:获取指定时间戳的一致性快照并导出。

  • lock:为待导出的所有表上读锁。

  • none:不做任何一致性保证。

  • auto:对 MySQL 使用 flush,对 TiDB 使用 snapshot。

默认情况下,TiDB会通过获取某个时间戳的快照来保证一致性(即 --consistency snapshot)。在使用snapshot来保证一致性的时候,可以使用--snapshot选项指定要备份的时间戳。

1.6 导出TiDB历史数据快照

Dumpling可以通过--snapshot指定导出某个 tidb_snapshot 时的数据。--snapshot选项可设为 TSO(SHOW MASTER STATUS 输出的 Position 字段)或有效的 datetime 时间,例如:

mysql> show master status;
+-------------+--------------------+--------------+------------------+-------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------+--------------------+--------------+------------------+-------------------+

| tidb-binlog | 422913627203829761 | | | |
+-------------+--------------------+--------------+------------------+-------------------+

1 row in set (0.00 sec)
[root@tango-01 tidb-toolkit]# ./bin/dumpling -u root -P4000 -h192.168.112.101 --threads 32 -o /tmp/test3 --snapshot 422913627203829761
[root@tango-01 tidb-toolkit]# ./bin/dumpling -u root -P4000 -h192.168.112.101 --threads 32 -o /tmp/test2 --snapshot "2021-02-14 15:12:00"

即可导出TSO为422913627203829761或2021-02-14 15:12:00 时的TiDB历史数据快照。

1.7 导出TiDB大表时的内存控制
Dumpling导出TiDB较大单表时,可能会因为导出数据过大导致TiDB内存溢出(OOM),从而使连接中断导出失败。可以通过以下参数减少TiDB的内存使用。
  • 设置--rows 参数,通过减少导出数据区块以减少TiDB扫描数据的内存开销,同时也可开启表内并发提高导出效率

  • 调整--tidb-mem-quota-query参数到8GB或更小。该参数默认为32GB,可控制TiDB单条查询语句的内存使用

  • 调整--params "tidb_distsql_scan_concurrency" 参数,即设置导出时的session变量 tidb_distsql_scan_concurrency 从而减少 TiDB scan 操作的并发度

2、全量数据快速导入工具TiDB lightning

TiDB Lighting是将全量数据快速导入TiDB的工具,支持Dumpling或CSV格式的数据源。主要有以下使用场景:
  • 迅速导入大量新的数据

  • 恢复所有备份数据
使用TiDB Lightning时需要注意以下几点:
  1. TiDB Lightning运行后,TiDB集群将无法正常对外提供服务
  2. 若tidb-lightning崩溃,集群会留在“导入模式”。若忘记转回“普通模式”,集群会产生大量未压缩的文件,继而消耗CPU并导致延迟。此时,需要使用 tidb-lightning-ctl 手动将集群转回“普通模式”:
bin/tidb-lightning-ctl --switch-mode=normal
2.1 TiDB Lightning整体架构

TiDB Lightning 整体工作原理如下:
  1. 在导数据之前,tidb-lightning 会自动将 TiKV 集群切换为“导入模式” (import mode),优化写入效率并停止自动压缩。

  2. tidb-lightning 会在目标数据库建立架构和表,并获取其元数据。

  3. 每张表都会被分割为多个连续的区块,这样来自大表 (200 GB+) 的数据就可以用增量方式并行导入。

  4. tidb-lightning会为每一个区块准备一个“引擎文件 (engine file)”来处理键值对。tidb-lightning会并发读取SQL dump,将数据源转换成与TiDB相同编码的键值对,然后将这些键值对排序写入本地临时存储文件中。

  5. 当一个引擎文件数据写入完毕时,tidb-lightning 便开始对目标TiKV集群数据进行分裂和调度,然后导入数据到TiKV集群。引擎文件包含两种:数据引擎与索引引擎,各自又对应两种键值对:行数据和次级索引。通常行数据在数据源里是完全有序的,而次级索引是无序的。因此,数据引擎文件在对应区块写入完成后会被立即上传,而所有的索引引擎文件只有在整张表所有区块编码完成后才会执行导入。

  6. 整张表相关联的所有引擎文件完成导入后,tidb-lightning 会对比本地数据源及下游集群的校验和(checksum),确保导入的数据无损,然后让TiDB分析 (ANALYZE) 这些新增的数据,以优化日后的操作。同时,tidb-lightning 调整 AUTO_INCREMENT 值防止之后新增数据时发生冲突。表的自增 ID 是通过行数的上界估计值得到的,与表的数据文件总大小成正比。因此,最后的自增 ID 通常比实际行数大得多。这属于正常现象,因为在 TiDB 中自增 ID 不一定是连续分配的。

  7. 在所有步骤完毕后,tidb-lightning 自动将TiKV切换回“普通模式” (normal mode),此后 TiDB 集群可以正常对外提供服务。

来源:tidb-lightning-work-flow

2.2 TiDB Lightning部署执行

1)解压缩TiDB工具包tidb-toolkit-v4.0.10-linux-amd64.tar.gz,并将tidb-lightning 及 bin/tidb-lightning-ctl拷贝到指定目录

[root@tango-01 tidb-toolkit]# cp ./bin/tidb-lightning  ./tidb-lightning/
[root@tango-01 tidb-toolkit]# cp ./bin/tidb-lightning-ctl ./tidb-lightning/
[root@tango-01 tidb-toolkit]# cd tidb-lightning/
[root@tango-01 tidb-lightning]# ll
total 168268
-rwxr-xr-x 1 root root 91104752 Feb 14 16:07 tidb-lightning
-rwxr-xr-x 1 root root 81197800 Feb 14 16:07 tidb-lightning-ctl

2)配置tidb-lightning.toml

[lightning]

# 转换数据的并发数,默认为逻辑 CPU 数量,不需要配置。
# 混合部署的情况下可以配置为逻辑 CPU 75% 大小。
# region-concurrency =

# 日志
level = "info"
file = "tidb-lightning.log"

[tikv-importer]

# backend 设置为 local 模式
backend = "local"
# 设置本地临时存储路径
sorted-kv-dir = "/tmp/sorted-kv-dir"

[mydumper]

# Mydumper 源数据目录。
data-source-dir = "/tmp/test3"

[tidb]

# 目标集群的信息。tidb-server 的监听地址,填一个即可。
host = "192.168.112.101"
port = 4000
user = "root"
password = ""
# 表架构信息在从 TiDB 的“状态端口”获取。
status-port = 10080
# pd-server 的地址,填一个即可
pd-addr = "192.168.112.101:2379"

3)运行tidb-lightning

[root@tango-01 tidb-lightning]# nohup ./tidb-lightning -config tidb-lightning.toml > nohup.out &

查看日志信息:

[2021/02/14 16:11:23.394 +08:00] [INFO] [restore.go:718] ["restore table completed"] [table=`tango`.`tab_tidb`] [takeTime=5.248430549s] []
[2021/02/14 16:11:23.394 +08:00] [INFO] [restore.go:1296] ["local checksum"] [table=`tango`.`tab01`] [checksum="{cksum=5022109439688970821,size=489,kvs=14}"]
[2021/02/14 16:11:23.394 +08:00] [INFO] [checksum.go:158] ["remote checksum start"] [table=tab01]
[2021/02/14 16:11:23.394 +08:00] [INFO] [restore.go:1296] ["local checksum"] [table=`tango`.`tab_tidb`] [checksum="{cksum=16567959753162286234,size=1320,kvs=30}"]
[2021/02/14 16:11:23.394 +08:00] [INFO] [checksum.go:158] ["remote checksum start"] [table=tab_tidb]
[2021/02/14 16:11:23.565 +08:00] [INFO] [checksum.go:161] ["remote checksum completed"] [table=tab01] [takeTime=171.287295ms] []
[2021/02/14 16:11:23.565 +08:00] [INFO] [restore.go:1753] ["checksum pass"] [table=`tango`.`tab01`] [local="{cksum=5022109439688970821,size=489,kvs=14}"]
[2021/02/14 16:11:23.565 +08:00] [INFO] [restore.go:1758] ["analyze start"] [table=`tango`.`tab01`]
[2021/02/14 16:11:23.608 +08:00] [INFO] [checksum.go:161] ["remote checksum completed"] [table=tab_tidb] [takeTime=213.714593ms] []
[2021/02/14 16:11:23.608 +08:00] [INFO] [restore.go:1753] ["checksum pass"] [table=`tango`.`tab_tidb`] [local="{cksum=16567959753162286234,size=1320,kvs=30}"]
[2021/02/14 16:11:23.608 +08:00] [INFO] [restore.go:1758] ["analyze start"] [table=`tango`.`tab_tidb`]
[2021/02/14 16:11:24.839 +08:00] [INFO] [restore.go:1760] ["analyze completed"] [table=`tango`.`tab01`] [takeTime=1.273633373s] []
[2021/02/14 16:11:25.038 +08:00] [INFO] [restore.go:1760] ["analyze completed"] [table=`tango`.`tab_tidb`] [takeTime=1.430174433s] []
[2021/02/14 16:11:25.038 +08:00] [INFO] [restore.go:863] ["restore all tables data completed"] [takeTime=7.113491037s] []
[2021/02/14 16:11:25.041 +08:00] [INFO] [restore.go:608] ["everything imported, stopping periodic actions"]
[2021/02/14 16:11:25.075 +08:00] [INFO] [restore.go:678] ["add back PD leader&region schedulers"]
[2021/02/14 16:11:25.076 +08:00] [INFO] [restore.go:1351] ["skip full compaction"]
[2021/02/14 16:11:25.161 +08:00] [INFO] [restore.go:1445] ["clean checkpoints start"] [keepAfterSuccess=false] [taskID=1613290277518783443]
[2021/02/14 16:11:25.161 +08:00] [INFO] [restore.go:1452] ["clean checkpoints completed"] [keepAfterSuccess=false] [taskID=1613290277518783443] [takeTime=92.058µs] []
[2021/02/14 16:11:25.161 +08:00] [INFO] [restore.go:300] ["the whole procedure completed"] [takeTime=7.560768233s] []
[2021/02/14 16:11:25.161 +08:00] [INFO] [main.go:95] ["tidb lightning exit"]
2.3 TiDB Lighting特性说明
2.3.1 断点续传
由参数“enable = true”控制是否启用断点续传;导入数据时,TiDB Lightning会记录当前表导入的进度,所以即使Lightning或其他组件异常退出,在重启时也可以避免重复再导入已完成的数据。TiDB Lightning支持两种断点存储方式:本地文件或MySQL数据库。
  • 若driver = "file",断点会存放在一个本地文件,其路径由 dsn 参数指定。由于断点会频繁更新,建议将这个文件放到写入次数不受限制的盘上,例如RAM disk。

  • 若driver = "mysql",断点可以存放在MySQL数据库中,在没有选择的情况下,默认会存在目标数据库里。建议另外部署一台兼容MySQL的临时数据库服务器,导入完毕后可以删除。
如果Tidb-lightning因为不可恢复的错误退出,重启的时候不会使用断点而是直接报错,因此需要先解决这些错误才能继续,此时可以使用tidb-lightning-ctrl工具:
  • --checkpoint-error-destroy:失败的表从头开始整个导入过程

  • --checkpoint-error-ignore:清除表的出错状态

  • --checkpoint-remove:无论是否出错,清除断点

  • --checkpoint-dump:将断点备份到文件夹,主要用于技术支持

2.3.2 表库过滤
TiDB 4.0开始,所有的TiDB工具集都可以使用通用的过滤语法来定义子集,比如:
  • 命令行:使用--filter参数./dumpling -f 'foo*.' -f 'bar.*' -P 3306 -o /tmp/data/

  • TOML配置文件:filter = ['foo*.', 'bar.*']

表库的过滤方法可以使用通配符,也可以使用正则表达式

2.3.3 TiDB Lightning后端
TiDB Lightning的后端决定 tidb-lightning 组件将如何把将数据导入到目标集群中,目前支持以下几种后端方式:
  1. Importer-backend:tidb-lightning先将SQL或CSV数据编码成键值对,由tikv-importer对写入的键值对进行排序,然后把这些键值对Ingest到TiKV节点中。

  2. Local-backend:tidb-lightning先将数据编码成键值对并排序存储在本地临时目录,然后批量将这些键值对写到各个TiKV节点,然后由TiKV将它们Ingest到集群中。和 Importer-backend 原理相同,不过不依赖额外的 tikv-importer 组件。

  3. TiDB-backend:tidb-lightning 先将数据编码成 INSERT 语句,然后直接在TiDB节点上运行这些SQL语句进行数据导入。

三种方式的对比如下:

如果导入的目标集群为v4.0或以上版本,优先考虑使用Local-backend模式。Local-backend部署更简单并且性能也较其他两个模式更高。

2.3.4 TiDB Lightning Web界面

TiDB Lightning支持服务器模式,可以在Web端查看导入的进度以及执行简单的任务,在启动的时候加入“--server-mode --status-addr :8289”参数或者配置文件中将server-mode设置为true即可。

[lightning]
server-mode = true
status-addr = ':8289'

TiDB Lightning启动后,访问http://192.168.112.10:8289来管理任务

1) 提交任务

2)查看导入进度

2.4 从CSV文件迁移到MySQL

1)CSV文件名

CSV文件需命名为db_name.table_name.csv,该文件会被解析为数据库db_name里名为table_name的表。如果一个表分布于多个CSV文件,这些CSV文件命名需加上文件编号的后缀,如 db_name.table_name.001.csv,数字部分不需要连续但必须递增,并用零填充。

2) 表结构

CSV文件没有表结构,在导入TiDB过程中,需提供表结构,可通过以下方法实现:
  • 创建包含DDL语句CREATE TABLE的文件db_name.table_name-schema.sql以及包 CREATE DATABASE DDL语句的文件db_name-schema-create.sql

  • 首先在TiDB中直接创建空表,然后在 tidb-lightning.toml 中设置“[mydumper] no-schema = true”

3)配置文件

[lightning]

server-mode = true
status-addr = ':8289'

# 转换数据的并发数,默认为逻辑 CPU 数量,不需要配置。
# 混合部署的情况下可以配置为逻辑 CPU 75% 大小。
# region-concurrency =

# 日志
level = "info"
file = "tidb-lightning.log"

[mydumper.csv]

separator = ','
delimiter = '"'
header = true
not-null = false
null = '\N'
backslash-escape = true
trim-last-separator = false


[tikv-importer]

# backend 设置为 local 模式
backend = "local"
# 设置本地临时存储路径
sorted-kv-dir = "/tmp/sorted-kv-dir"

[mydumper]

# Mydumper 源数据目录。
no-schema = true
data-source-dir = "/tmp/test4"

[tidb]

# 目标集群的信息。tidb-server 的监听地址,填一个即可。
host = "192.168.112.101"
port = 4000
user = "root"
password = ""
# 表架构信息在从 TiDB 的“状态端口”获取。
status-port = 10080
# pd-server 的地址,填一个即可
pd-addr = "192.168.112.101:2379"

4)创建表

mysql> CREATE TABLE `tab02` (
-> `id` int(11) NOT NULL AUTO_INCREMENT,
-> `city` varchar(20) NOT NULL DEFAULT '',
-> PRIMARY KEY (`id`));
Query OK, 0 rows affected (0.28 sec)

5)启动

[root@tango-01 tidb-lightning]#  nohup ./tidb-lightning -config tidb-lightning-csv.toml > nohup.out &

源文件格式如下:

[root@tango-01 test4]# ll
total 8
-rw-r--r-- 1 root root 146 Feb 14 18:02 metadata
-rw-r--r-- 1 root root 60 Feb 14 18:02 tango.tab02.csv
[root@tango-01 test4]# cat tango.tab02.csv
"id","city"
11,"Suzhou"
12,"Hefei"
13,"Xian"
14,"Chongqing"

查看导入结果如下

mysql> select * from tab02;
+----+-----------+

| id | city |
+----+-----------+

| 11 | Suzhou |
| 12 | Hefei |
| 13 | Xian |
| 14 | Chongqing |
+----+-----------+

4 rows in set (0.01 sec)
2.5 从SQL文件迁移到MySQL

1)通过Dumpling工具生成SQL文件

[root@tango-01 tidb-toolkit]# ./bin/dumpling -u root -P4000 -h192.168.112.101 --threads 32 -o /tmp/test5 --filter 'tango.tab01' 
[root@tango-01 test5]# ll
total 16
-rw-r--r-- 1 root root 146 Feb 14 18:35 metadata
-rw-r--r-- 1 root root 96 Feb 14 18:35 tango-schema-create.sql
-rw-r--r-- 1 root root 270 Feb 14 18:35 tango.tab01.000000000.sql
-rw-r--r-- 1 root root 237 Feb 14 18:35 tango.tab01-schema.sql

修改输出文件的名称及schema为新表tab03

[root@tango-01 test5]# ll
total 16
-rw-r--r-- 1 root root 146 Feb 14 18:35 metadata
-rw-r--r-- 1 root root 96 Feb 14 18:41 tango-schema-create.sql
-rw-r--r-- 1 root root 270 Feb 14 18:40 tango.tab03.000000000.sql
-rw-r--r-- 1 root root 237 Feb 14 18:40 tango.tab03-schema.sql

2)配置文件

[lightning]

pprof-port = 8289

# 转换数据的并发数,默认为逻辑 CPU 数量,不需要配置。
# 混合部署的情况下可以配置为逻辑 CPU 75% 大小。
# region-concurrency =

# 日志
level = "info"
file = "tidb-lightning.log"

[tikv-importer]

# backend 设置为 local 模式
backend = "local"
# 设置本地临时存储路径
sorted-kv-dir = "/tmp/sorted-kv-dir"

[mydumper]

# Mydumper 源数据目录。
data-source-dir = "/tmp/test5"

[tidb]

# 目标集群的信息。tidb-server 的监听地址,填一个即可。
host = "192.168.112.101"
port = 4000
user = "root"
password = ""
# 表结构信息在从 TiDB 的“状态端口”获取。
status-port = 10080
# pd-server 的地址,填一个即可
pd-addr = "192.168.112.101:2379"

3)监控配置

  • tidb-lightning.toml 中配置监控端口

# 用于调试和 Prometheus 监控的 HTTP 端口。输入 0 关闭。
pprof-port = 8289
  • 配置Prometheus后,将服务器地址直接添加至 scrape_configs 部分

[root@tango-01 conf]# pwd
/tidb-deploy/prometheus-9090/conf
[root@tango-01 conf]# vi prometheus.yml
scrape_configs:
- job_name: "lightning"
static_configs:
- targets:
- '192.168.112.10:8289'

修改配置后重启Prometheus服务

[root@tango-01 tidb-lightning]# tiup cluster restart tidb-test -R prometheus

4)运行任务

[root@tango-01 tidb-lightning]# nohup ./tidb-lightning -config tidb-lightning-sql.toml > nohup.out &

5)查看导入的数据

mysql> select * from tab03;
+----+-----------+
| id | city |
+----+-----------+
| 1 | Beijing |
| 2 | Shanghai |
| 3 | Guangzhou |
| 4 | Shenzhen |
| 5 | Foshan |
| 6 | Hangzhou |
| 7 | Chengdu |
| 8 | Wuhan |
| 9 | Changsha |
| 10 | Nanjing |
| 11 | Suzhou |
| 12 | Hefei |
| 13 | Xian |
| 14 | Chongqing |
+----+-----------+
14 rows in set (0.01 sec)
到这里,已经完成了TiDB Lightning的数据导入测试,在使用时需要注意以下几点:
  1. TiDB Lightning运行后,TiDB集群将无法正常对外提供服务

  2. CSV格式文件导入时候需要先准备好表结构DDL或者创建表

  3. SQL格式文件导入到目标库的时候,可以通过修改sql文件来调整目标库的表名称

  4. Dumpling和Lightning实现的是逻辑上的数据导出导入,通过snapshot导出数据,可以实现一致性时间点的数据恢复导入操作

参考资料:

  1. https://docs.pingcap.com/zh/tidb/stable/tidb-lightning-overview

  2. https://docs.pingcap.com/zh/tidb/stable/dumpling-overview

一种方法是使用 TiDB 的数据迁移工具 DM,它可以将数据从 MySQL 实时同步到 TiDB,从而避免停机导入。当然,DM 的配置和使用比较复杂,需要一定的学习成本。

如果你的数据量非常大,可以考虑将数据分批导入,每次导入一部分数据,从而减少单次导入的停机时间。当然,这种方法需要更精细的规划和操作。

文章中已经提到了,如果你的TiDB集群是4.0及以上版本,优先选择Local-backend模式,因为它部署更简单,性能也更高。Importer-backend模式需要额外部署tikv-importer,而TiDB-backend模式性能相对较差,一般不推荐。

这么说吧,tidb_snapshot就像给数据库拍了个照片,你导出的就是照片上的数据,自然是一致的。而FLUSH TABLES WITH READ LOCK则是锁住数据库不让它变动,然后再导出。两种方法都能保证一致性,但tidb_snapshot对在线业务的影响更小。

是的,对于TiDB来说,使用tidb_snapshot就可以保证数据一致性,不需要像MySQL那样使用FLUSH TABLES WITH READ LOCK。这是因为tidb_snapshot会创建一个一致性的读视图,保证导出的数据在某个时间点是一致的。

我觉得除了数据量和导入速度之外,还要考虑集群的负载情况。如果集群负载很高,那么选择Local-backend可能会对集群造成更大的压力,这时候可以考虑使用Importer-backend模式,将导入的压力分摊到tikv-importer上。

最佳实践就是根据你的实际情况选择。如果你的数据量很大,而且对导入速度要求很高,那么Local-backend是不二之选。如果你的数据量不大,或者对导入速度要求不高,那么Importer-backend也可以考虑。当然,你也可以根据官方文档的建议进行选择。

理论上是这样,但实际情况可能更复杂。虽然tidb_snapshot可以保证一致性,但如果你的事务时间很长,或者集群的负载很高,可能会导致tidb_snapshot的创建时间比较长,从而影响导出效率。所以,具体情况还是要根据实际情况来选择。

减少停机时间的关键在于提高导入速度。你可以通过优化 Lightning 的配置,例如增加 region-concurrency 和 tikv-importer 的并发数,来提高导入速度。此外,还可以通过优化数据源,例如将数据预先排序,来减少 Lightning 的处理时间。