惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Hackread – Cybersecurity News, Data Breaches, AI and More
Security Archives - TechRepublic
Security Archives - TechRepublic
I
Intezer
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
Arctic Wolf
T
Threatpost
P
Proofpoint News Feed
AWS News Blog
AWS News Blog
C
Cybersecurity and Infrastructure Security Agency CISA
G
GRAHAM CLULEY
Cisco Talos Blog
Cisco Talos Blog
Simon Willison's Weblog
Simon Willison's Weblog
L
Lohrmann on Cybersecurity
Scott Helme
Scott Helme
T
Tenable Blog
L
LINUX DO - 最新话题
Help Net Security
Help Net Security
WordPress大学
WordPress大学
Hacker News: Ask HN
Hacker News: Ask HN
人人都是产品经理
人人都是产品经理
MyScale Blog
MyScale Blog
Recent Commits to openclaw:main
Recent Commits to openclaw:main
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Recent Announcements
Recent Announcements
Vercel News
Vercel News
The Hacker News
The Hacker News
J
Java Code Geeks
博客园 - 【当耐特】
D
Docker
V
V2EX
H
Heimdal Security Blog
GbyAI
GbyAI
博客园 - 叶小钗
Google DeepMind News
Google DeepMind News
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News | PayPal Newsroom
The Register - Security
The Register - Security
The Cloudflare Blog
C
CERT Recently Published Vulnerability Notes
T
The Blog of Author Tim Ferriss
博客园 - Franky
MongoDB | Blog
MongoDB | Blog
SecWiki News
SecWiki News
S
Secure Thoughts
Attack and Defense Labs
Attack and Defense Labs
Microsoft Security Blog
Microsoft Security Blog
S
Schneier on Security
Latest news
Latest news
Project Zero
Project Zero

Jiajun的技术笔记

你好,2026! TiDB 源码阅读(六):TiDB Coprocessor 源码解析 性能优化的核心思想 TiDB 源码阅读(五):索引 TiDB 源码阅读(四):AST、逻辑计划、物理计划 CockroachDB Serverless Architecture podman 无故退出 Cursor Control-L (CTRL-L) Keyboard Shortcuts in Terminal Replace docker with podman Using xmonad with xfce4 A RC script for freebsd frpc 自己动手写一个k8s controller AI 会取代你的(编程)岗位吗? 自建DERP服务器提升Tailscale连接速度(使用Nginx转发) 自动升级Docker容器 再读《程序员修炼之道-从小工到专家》 让浏览器下载文件 再读《软件随想录》/《黑客与画家》/《软技能》 HTTP 压力测试中的 Coordinated Omission 2的补码 编程语言中的 context 是什么? flutter macOS 构建出错 Flatpak 使用小记 Golang CAS 操作是怎么实现的 PostgreSQL 当MQ来使用 Clash 结合 工作VPN 的网络设计 使用 PostgreSQL 搭建 JuiceFS PostgreSQL 配置优化和日志分析 有GitHub Copilot?那就可以搭建你的ChatGPT4服务 窗口函数的使用(以PG为例) 读《为什么学生不喜欢上学》 OpenAI Prompt Engineering 摘录和总结 读《打造真正的新产品》 VueJS 总结 Linux 自动挂载 alist 提供的webdav FreeBSD 使用 vm-bhyve 安装Debian虚拟机 FreeBSD 和 Linux 网卡聚合实现提速 GPT 帮我搞定了时区转换问题 长任务系统如何处理? macOS/Linux 编译 InputLeap 使用开源软KVM - synergy-core 解决 macOS 终端hostname一直变化问题 KVM 共享 Intel 集成显卡 PromQL 备忘 读《格鲁夫给经理人的第一课》 读《打开心智》 为什么要把复杂的联表操作拆成多个单表查询? 红包系统的设计 MySQL Index Condition Pushdown Optimization Go mod 简明教程 OpenWRT 使用 Android/iOS USB 网络 搭建旁路由 Golang gRPC 错误处理 编写可维护的单元测试代码 OAuth 2 详解(六):Authorization Code Flow with PKCE OAuth 2 详解(五):Device Authorization Flow OAuth 2 详解(三):Resource Owner Password Credentials Grant OAuth 2 详解(四):Client Credentials Flow OAuth 2 详解(二):Implict Grant Flow OAuth 2 详解(一):简介及 Authorization Code 模式 ElasticSearch 学习笔记 三种git流程以及发版模型 错误处理实践 权限模型(RBAC/ABAC) OIDC(OpenID Connect) 简介 任务队列简介 PostgreSQL 操作笔记 使用Drone CI构建CI/CD系统 Golang migrate 做数据库变更管理 使用PostgreSQL做搜索引擎 Nginx 源码阅读(三): 连接池、内存池 Nginx 源码阅读(二): 请求处理 Nginx 源码阅读(一): 启动流程 Go 泛型简明教程 KVM 显卡穿透给 Windows 使用 HTTP Router 处理 Telegram Bot 按钮回调 使用反射(reflect)对结构体赋值 GIN 是如何绑定参数的 你好 2022(2021 年终总结) 用Go导入大型CSV到PostgreSQL 使用 OpenWRT 搭建软路由 使用软KVM切换器 barrier 共享键鼠 SQL 防注入及原理 使用 gomock 测试 Go 代码 gevent不是黑魔法(二): gevent 实现 gevent不是黑魔法(一): greenlet 实现 用 entgo 替代 gorm 应用内使用crontab不是那么方便 单测时要不要 mock 数据库? Sentry 自建指南 用selenium完成自动化任务 用闲置的安卓手机做垃圾电话短信过滤 推荐三个时间管理工具 一次事故反思 当JS遇到uint64:JS整数溢出问题 SQLite3 存储以及ACID原理 Redis源码阅读:pub/sub实现 Redis源码阅读:zset实现 Redis源码阅读:bitmap 位图的运算 Redis源码阅读:set是怎么做交并集运算的?
TiDB Lightning 源码阅读
Jiajun Huang · 2025-09-02 · via Jiajun的技术笔记

前言

Lightning 是 TiDB 的高速数据导入工具,专门用于将 TB 级别的数据快速导入到 TiDB 集群中。作为 TiDB 生态系统的重要组件,Lightning 在大规模数据迁移场景中发挥着至关重要的作用。

一、项目整体架构

1.1 目录结构分析

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/: 公共工具函数

二、核心导入流程深入分析

2.1 主要导入步骤

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. 清理检查点
}

2.2 表结构恢复(restoreSchema)

restoreSchema 函数是导入流程的第二步,负责在目标数据库中创建所需的表结构:

主要功能:

  1. 并发DDL执行: 使用 SchemaImporter 并发创建数据库、表和视图
  2. 智能重试机制: 使用 CREATE IF NOT EXISTS 处理重复创建
  3. 结构信息收集: 获取创建后的表结构元信息
  4. 后端适配: 为不同后端模式准备必要的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
    }
    

2.3 数据导入(importTables)

Lightning import process

数据导入是整个流程的核心,Lightning 采用了精巧的并发控制策略:

  1. 表级并发: 多个表可以并行导入
  2. 引擎级并发: 每个表的数据被分割为多个引擎并行处理
  3. Chunk级并发: 每个引擎内的数据块并发写入

三、多后端架构设计

3.1 Backend 接口抽象

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)
}

3.2 两种主要后端模式

// 第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())
}

3.2.1 Local Backend

  • 适用场景: 大规模数据导入,对性能要求极高
  • 实现原理: 直接生成SST文件并通过Ingestion方式导入TiKV
  • 优势: 导入速度最快,资源占用相对较低
  • 劣势: 对集群影响较大,导入期间需要独占使用

local 模式通过本地的 KV 数据库写入数据,生成SST之后,通过 Ingestion API 将数据导入到 TiKV 中,由于数据已经整理好, 绕过了TiDB的处理且是批量写入chunk的形式,因此导入速度较快。

3.2.2 TiDB Backend

  • 适用场景: 小规模数据导入,需要与现有业务共存
  • 实现原理: 通过标准SQL INSERT语句导入数据
  • 优势: 对集群影响最小,支持事务语义
  • 劣势: 导入速度相对较慢

    // 构建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 ")
    }
    }
    

3.3 引擎管理机制

Lightning 引入了”引擎”(Engine)概念来管理数据导入的生命周期:

// 引擎状态转换: OpenedEngine -> ClosedEngine -> Import -> Cleanup
type OpenedEngine struct {
    engine
    tableName string
    config    *EngineConfig
}

type ClosedEngine struct {
    engine
}

每个引擎都有唯一的UUID,支持并发操作且状态独立管理。

四、检查点与容错机制

4.1 检查点系统设计

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
)

4.2 多层级状态追踪

  1. 任务级别: 记录整体导入进度和配置信息
  2. 表级别: 追踪每个表的导入状态和统计信息
  3. 引擎级别: 管理每个引擎的生命周期状态
  4. Chunk级别: 精确到每个数据块的导入进度

4.3 断点续传实现

当Lightning异常中断后,重启时能够:

  1. 从检查点数据库读取上次的进度
  2. 跳过已完成的任务和数据块
  3. 从中断点继续执行后续步骤

五、错误处理与冲突解决

5.1 ErrorManager 架构

Lightning 实现了完善的错误管理系统,能够处理导入过程中的各种异常情况:

// 错误类型分类
const (
    syntaxErrorTableName = "syntax_error_v2"     // 语法错误
    typeErrorTableName   = "type_error_v2"       // 类型错误
    ConflictErrorTableName = "conflict_error_v4"  // 冲突错误
)

5.2 冲突检测与处理

  1. 重复键检测: 在导入过程中自动识别主键或唯一键冲突
  2. 冲突策略: 支持跳过、替换、报错等多种处理策略
  3. 冲突记录: 详细记录冲突数据,便于后续分析处理

5.3 错误恢复机制

  • 自动重试: 对于临时性错误自动重试
  • 错误隔离: 单个Chunk的错误不影响其他数据导入
  • 详细日志: 完整记录错误上下文信息

六、性能优化技术

6.1 并发控制策略

Lightning 采用了多层次的并发控制:

  1. 表级并发: table-concurrency 控制同时处理的表数量
  2. 区域并发: region-concurrency 控制区域操作的并发度
  3. 索引并发: index-concurrency 控制索引操作的并发度
  4. IO并发: io-concurrency 控制磁盘IO操作的并发度

6.2 内存管理优化

  • 连接池管理: 动态调整数据库连接池大小
  • 缓存策略: 智能的prepared statement缓存
  • 内存监控: 实时监控内存使用,防止OOM

6.3 磁盘IO优化

  • 批量写入: 通过批量操作减少磁盘IO次数
  • 压缩传输: 支持KV pair压缩降低网络传输开销
  • 磁盘配额: 智能的磁盘空间管理机制