























Lightning 是 TiDB 的高速数据导入工具,专门用于将 TB 级别的数据快速导入到 TiDB 集群中。作为 TiDB 生态系统的重要组件,Lightning 在大规模数据迁移场景中发挥着至关重要的作用。
Lightning 项目位于 TiDB 仓库的 lightning/ 目录下,整体结构清晰且模块化:
lightning/
├── cmd/ # 命令行工具入口
│ ├── tidb-lightning/ # 主程序入口
│ └── tidb-lightning-ctl/ # 控制工具
├── pkg/ # 核心功能包
│ ├── importer/ # 导入控制器
│ ├── server/ # 服务器模式
│ └── web/ # Web界面
├── tests/ # 集成测试
└── web/ # 前端界面源码
核心功能主要集中在 pkg/lightning/ 包中:
backend/: 后端存储抽象层,支持多种导入模式checkpoints/: 检查点机制,用于断点续传config/: 配置管理errormanager/: 错误处理和冲突解决mydump/: 数据解析和schema处理common/: 公共工具函数Lightning 的导入过程有7个步骤:
// 来自 import.go 中的 Run 方法
opts := []func(context.Context) error{
rc.setGlobalVariables, // 1. 设置全局变量
rc.restoreSchema, // 2. 恢复表结构
rc.preCheckRequirements, // 3. 预检查要求
rc.initCheckpoint, // 4. 初始化检查点
rc.importTables, // 5. 导入表数据
rc.fullCompact, // 6. 全量压缩
rc.cleanCheckpoints, // 7. 清理检查点
}
restoreSchema 函数是导入流程的第二步,负责在目标数据库中创建所需的表结构:
主要功能:
SchemaImporter 并发创建数据库、表和视图CREATE IF NOT EXISTS 处理重复创建后端适配: 为不同后端模式准备必要的ID信息
func (rc *Controller) restoreSchema(ctx context.Context) error {
// 计算并发度,最小为4
concurrency := max(2*rc.cfg.App.RegionConcurrency, 4)
// 创建Schema导入器
schemaImp := mydump.NewSchemaImporter(logger, rc.cfg.TiDB.SQLMode, rc.db, rc.store, concurrency)
// 执行DDL导入
err := schemaImp.Run(ctx, rc.dbMetas)
// 获取表结构信息
dbInfos, err := rc.preInfoGetter.GetAllTableStructures(ctx)
// 为local backend设置数据库ID
if isLocalBackend(rc.cfg) {
// 获取远程数据库模型并设置ID映射
}
return nil
}

数据导入是整个流程的核心,Lightning 采用了精巧的并发控制策略:
Lightning 通过定义统一的 Backend 接口,Lightning 支持多种不同的数据导入策略:
type Backend interface {
Close()
RetryImportDelay() time.Duration
ShouldPostProcess() bool
OpenEngine(ctx context.Context, config *EngineConfig, engineUUID uuid.UUID) error
CloseEngine(ctx context.Context, config *EngineConfig, engineUUID uuid.UUID) error
ImportEngine(ctx context.Context, engineUUID uuid.UUID, regionSplitSize, regionSplitKeys int64) error
CleanupEngine(ctx context.Context, engineUUID uuid.UUID) error
FlushEngine(ctx context.Context, engineUUID uuid.UUID) error
FlushAllEngines(ctx context.Context) error
LocalWriter(ctx context.Context, cfg *LocalWriterConfig, engineUUID uuid.UUID) (EngineWriter, error)
}
// 第351-445行:Backend模式选择和初始化
switch cfg.TikvImporter.Backend {
case config.BackendTiDB:
encodingBuilder = tidb.NewEncodingBuilder()
backendObj = tidb.NewTiDBBackend(ctx, db, cfg, errorMgr)
case config.BackendLocal:
// Local backend初始化逻辑
backendObj, err = local.NewBackend(ctx, tls, backendConfig, pdCli.GetServiceDiscovery())
}
local 模式通过本地的 KV 数据库写入数据,生成SST之后,通过 Ingestion API 将数据导入到 TiKV 中,由于数据已经整理好, 绕过了TiDB的处理且是批量写入chunk的形式,因此导入速度较快。
劣势: 导入速度相对较慢
// 构建INSERT语句
func (be *tidbBackend) buildStmt(tableName string, columnNames []string) *strings.Builder {
switch be.onDuplicate {
case config.ReplaceOnDup:
insertStmt.WriteString("REPLACE INTO ")
case config.IgnoreOnDup:
insertStmt.WriteString("INSERT IGNORE INTO ")
case config.ErrorOnDup:
insertStmt.WriteString("INSERT INTO ")
}
}
Lightning 引入了”引擎”(Engine)概念来管理数据导入的生命周期:
// 引擎状态转换: OpenedEngine -> ClosedEngine -> Import -> Cleanup
type OpenedEngine struct {
engine
tableName string
config *EngineConfig
}
type ClosedEngine struct {
engine
}
每个引擎都有唯一的UUID,支持并发操作且状态独立管理。
Lightning 的检查点系统是其可靠性的核心保障,支持任务级、表级、引擎级和Chunk级的细粒度状态管理:
type CheckpointStatus uint8
const (
CheckpointStatusMissing CheckpointStatus = 0
CheckpointStatusLoaded CheckpointStatus = 30
CheckpointStatusAllWritten CheckpointStatus = 60
CheckpointStatusClosed CheckpointStatus = 90
CheckpointStatusImported CheckpointStatus = 120
CheckpointStatusChecksummed CheckpointStatus = 180
CheckpointStatusAnalyzed CheckpointStatus = 210
)
当Lightning异常中断后,重启时能够:
Lightning 实现了完善的错误管理系统,能够处理导入过程中的各种异常情况:
// 错误类型分类
const (
syntaxErrorTableName = "syntax_error_v2" // 语法错误
typeErrorTableName = "type_error_v2" // 类型错误
ConflictErrorTableName = "conflict_error_v4" // 冲突错误
)
Lightning 采用了多层次的并发控制:
table-concurrency 控制同时处理的表数量region-concurrency 控制区域操作的并发度index-concurrency 控制索引操作的并发度io-concurrency 控制磁盘IO操作的并发度此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。