数据迁移项目的踩坑复盘:亿级数据从 MySQL 到 TiDB 的平滑迁移
数据迁移项目的踩坑复盘亿级数据从 MySQL 到 TiDB 的平滑迁移一、迁移背景与方案选择我们核心业务的订单表在过去三年中从 300 万行增长到 1.8 亿行MySQL 的分库分表方案逐渐力不从心。跨分片查询需要应用层聚合运维复杂度随着分片数量线性增长。同时业务需要实时数据分析能力而 MySQL 的 OLAP 查询在亿级数据量下经常超时。经过三个月的技术选型和 POC 验证我们决定将订单相关数据迁移到 TiDB。选择 TiDB 的核心考量有三点兼容 MySQL 协议和生态迁移改造成本最低原生分布式架构支持弹性扩缩容未来 3~5 年的增长无需担心HTAP 能力可以在一套集群中同时支撑 OLTP 和 OLAP 场景无需额外构建数据仓库。二、迁移工具链的选型与实践我们选择的工具链是 Dumpling全量导出 TiDB Lightning高速导入 TiCDC增量同步。这套组合是 TiDB 官方推荐的迁移方案但实际使用中仍有不少细节需要处理。Dumpling 导出环节配置了 16 个并发线程和 64MB 的文件大小分片。1.8 亿行数据导出为约 4200 个 SQL 文件总耗时 2.3 小时。需要注意的关键点是必须在业务低峰期执行并开启一致性快照--snapshot参数指定时间戳确保导出的数据是某个时间点的一致性视图。Lightning 导入环节选择 Local 模式以获取最大吞吐。16 个 TiKV 节点的集群配置下Lightning 的导入速度达到 38000 rows/s全量导入耗时约 80 分钟。这里踩过一个坑Lightning 导入期间如果 TiKV 的 compaction 跟不上写入会急剧下降。解决方法是在导入前手动触发一次全量 compaction并将region-split-size调整为 256MB。TiCDC 增量同步是最关键的环节。Lightning 完成全量导入后TiCDC 开始从 Dumpling 的快照时间点捕获 MySQL binlog 增量。我们的 binlog 格式设置为 ROW 模式确保 TiCDC 能正确解析每行变更。/** * 数据一致性校验服务——迁移后的行级比对 */ Service public class DataConsistencyChecker { private static final int BATCH_SIZE 50000; private static final int COMPARE_THREADS 8; Resource private JdbcTemplate mysqlTemplate; Resource private JdbcTemplate tidbTemplate; /** * 基于主键分片的行级数据比对 */ public ConsistencyReport checkTable(String tableName, long minId, long maxId) { ExecutorService executor Executors.newFixedThreadPool(COMPARE_THREADS); ListCompletableFutureSegmentResult futures new ArrayList(); long segmentSize (maxId - minId) / COMPARE_THREADS; for (int i 0; i COMPARE_THREADS; i) { long startId minId i * segmentSize; long endId (i COMPARE_THREADS - 1) ? maxId : startId segmentSize; futures.add(CompletableFuture.supplyAsync( () - compareSegment(tableName, startId, endId), executor)); } ConsistencyReport report new ConsistencyReport(); for (CompletableFutureSegmentResult future : futures) { try { SegmentResult result future.get(30, TimeUnit.MINUTES); report.merge(result); } catch (TimeoutException e) { log.error(比对超时tableName{}, tableName); report.markIncomplete(); } catch (Exception e) { log.error(比对异常tableName{}, tableName, e); report.markIncomplete(); } } executor.shutdown(); log.info(表{}比对完成: 一致{}, 差异{}, 缺失{}, tableName, report.getMatchCount(), report.getDiffCount(), report.getMissingCount()); return report; } private SegmentResult compareSegment(String tableName, long startId, long endId) { SegmentResult result new SegmentResult(); long lastId startId; while (lastId endId) { long batchEnd Math.min(lastId BATCH_SIZE, endId); // 从MySQL读取一个批次的数据 MapLong, String mysqlData loadBatch(mysqlTemplate, tableName, lastId, batchEnd); // 从TiDB读取同一批次的数据 MapLong, String tidbData loadBatch(tidbTemplate, tableName, lastId, batchEnd); // 逐行比对 for (Map.EntryLong, String entry : mysqlData.entrySet()) { Long id entry.getKey(); String mysqlValue entry.getValue(); String tidbValue tidbData.get(id); if (tidbValue null) { result.addMissing(id); } else if (!Objects.equals(mysqlValue, tidbValue)) { result.addDiff(id, mysqlValue, tidbValue); } else { result.addMatch(id); } } lastId batchEnd; } return result; } private MapLong, String loadBatch(JdbcTemplate template, String tableName, long startId, long endId) { String sql String.format( SELECT id, MD5(CONCAT_WS(|, %s)) AS row_hash FROM %s WHERE id ? AND id ?, getColumnList(tableName), tableName); MapLong, String result new LinkedHashMap(); template.query(sql, rs - { result.put(rs.getLong(id), rs.getString(row_hash)); }, startId, endId); return result; } }三、灰度切流与回滚预案切换阶段的设计原则是任何环节都必须可回滚。我们的切流方案分为四个阶段阶段一双写验证持续 3 天。应用层同时写入 MySQL 和 TiDB读操作仍走 MySQL。通过数据一致性校验工具对比两边的数据发现差异后立即修复。这一阶段发现了两个问题一是 TiDB 的事务隔离级别与 MySQL 的差异导致部分并发写入产生了轻微的顺序差异二是个别表的自增 ID 在 TiDB 上分配策略不同需要调整为 AUTO_RANDOM。阶段二10% 灰度读持续 1 天。随机选取 10% 的用户将查询路由到 TiDB监控延迟和错误率。如果出现异常如 P99 延迟超过 200ms 或错误率超过 0.1%自动切回 MySQL。阶段三逐步放量持续 2 天。按 10% → 50% → 100% 的节奏扩大读 TiDB 的比例每次放量后观察监控至少 2 小时。阶段四MySQL 停写下线。确认 TiDB 稳定运行 72 小时后停止对 MySQL 的写入完成最终的数据一致性校验正式下线 MySQL 源库。/** * 流量路由控制——支持动态切换MySQL/TiDB数据源 */ Component public class MigrationRouter { Resource Qualifier(mysqlDataSource) private DataSource mysqlDataSource; Resource Qualifier(tidbDataSource) private DataSource tidbDataSource; /** * 根据用户ID哈希决定读流量走向 */ public DataSource routeRead(Long userId) { MigrationConfig config getMigrationConfig(); if (config.isReadAllTiDB()) { return tidbDataSource; // 全量切换到TiDB } // 按用户ID取模实现灰度比例 int hash Math.abs(userId.hashCode()) % 100; if (hash config.getReadPercent()) { return tidbDataSource; } return mysqlDataSource; } /** * 写操作双写阶段同时写两端TiDB写入失败不影响主流程 */ public void dualWrite(Long userId, Runnable writeOperation) { // 主库写入当前仍为MySQL writeOperation.run(); // 副库异步写入TiDB异常不影响主流程 CompletableFuture.runAsync(() - { try { DataSourceHolder.set(tidbDataSource); writeOperation.run(); } catch (Exception e) { log.error(TiDB双写失败userId{}, userId, e); // 记录双写异常用于后续修复 dualWriteFailureRepository.record(userId, e.getMessage()); } finally { DataSourceHolder.clear(); } }); } }四、性能对比与踩坑记录迁移完成后我们对比了 MySQL 和 TiDB 在相同数据规模下的性能表现。在 TP 场景点查、小范围查询中TiDB 的 P99 延迟略高于 MySQL约高 15%~20%这是分布式数据库的固有开销但仍在业务可接受范围内 10ms。在 AP 场景聚合查询、跨月报表中TiDB 的性能提升显著月度营收报表的查询时间从 47 秒降至 2.3 秒。踩坑记录中最值得分享的几条TiDB 不支持存储过程和触发器迁移前需要将业务逻辑中的应用层代码替代AUTO_INCREMENT在 TiDB 中并非全局单调递增需要业务层不依赖 ID 的顺序语义大事务 100MB在 TiDB 中的性能远不如小批量提交建议事务大小控制在 10MB 以内。五、迁移复盘与经验提炼这次迁移从方案设计到最终下线 MySQL 源库历时 4 个月。核心经验归纳为三点第一充分验证是降低风险的关键双写验证阶段发现的 3 个兼容性问题如果进入生产后果严重第二渐进式切换比大爆炸式切换安全百倍灰度机制和自动回滚是底线保障第三迁移不只是数据搬家而是代码重构的契机存储过程到应用代码的迁移、自增 ID 到雪花 ID 的替换本质上是技术债清理。作者李然程序员鸭梨Java 架构师专注数据架构与企业级系统迁移实践。

相关新闻

(81页PPT)中小学智慧校园建设方案(附下载方式)

(81页PPT)中小学智慧校园建设方案(附下载方式)

篇幅所限,本文只提供部分资料内容,完整资料请看下面链接 https://download.csdn.net/download/2501_92808811/92962768 资料解读:中小学智慧校园建设方案 详细资料请看本解读文章的最后内容。本方案立足国家教育信息化发展战略,…

2026/7/22 10:11:36 阅读更多 →
一周防潮专题总结:PTC加热器选型5步法与核心参数详解

一周防潮专题总结:PTC加热器选型5步法与核心参数详解

本周系统探讨了PTC加热器在衣柜防潮和配电柜防结露场景的应用。选型看似复杂,其实只要掌握5个核心参数,小白也能选对产品。本文做一次技术性总结,涵盖选型方法论和参数计算公式。目录PTC加热器选型5步法5个核心参数详解功率计算公式本周场景应…

2026/7/22 10:11:36 阅读更多 →
企业内部 AI Chat 的产品化之路:从技术 Demo 到合规可运营的产品

企业内部 AI Chat 的产品化之路:从技术 Demo 到合规可运营的产品

企业内部 AI Chat 的产品化之路:从技术 Demo 到合规可运营的产品 一、技术 Demo 与真实产品之间的鸿沟 2025 年初,我们用两周时间搭建了一个基于 LangChain 企业知识库的内部问答 Demo。产品同事试用后评价:"回答准确率不太稳定&#x…

2026/7/22 10:11:36 阅读更多 →

最新新闻

供应链合同数字化:从成本中心到效率引擎的三大路径

供应链合同数字化:从成本中心到效率引擎的三大路径

在企业的合同管理体系中 传统纸质合同模式下,供应链合同的管理存在几个系统性问题:签署周期长拖慢采购节奏、合同版本混乱导致条款不一致、履约跟踪靠人工容易遗漏、发生纠纷时举证困难。这些问题单个看起来都不致命,但叠加在一起&#xff0c…

2026/7/23 19:04:46 阅读更多 →
faster-whisper 等语音转文字的python包,支持gpu和cpu模式

faster-whisper 等语音转文字的python包,支持gpu和cpu模式

一、先解决 faster-whisper 安装失败问题 1. 分开执行命令,不要一次性管道过滤,方便看完整报错 打开 CMD,依次执行: C:/Python/Python312/python.exe -m pip install --user faster-whisper如果网络超时/下载失败,换国…

2026/7/23 19:04:46 阅读更多 →
电子合同ROI深度解析:制造业年省142万,三年累计节省410万

电子合同ROI深度解析:制造业年省142万,三年累计节省410万

企业在评估是否引入电子合同时,第一个问题往往是"能省多少钱"。这个问题的答案并不简单——电子合同的成本节省不是单一维度的,而是贯穿合同生命周期的多个环节。本文以制造业为样本,构建一个可复用的成本测算框架,并结…

2026/7/23 19:04:46 阅读更多 →
frp内网穿透

frp内网穿透

frp内网穿透frp内网穿透参考文章FRP服务端配置步骤1. 准备工作2. 下载并安装FRP1.下载FRP2.解压文件3. 配置FRP服务端4. 配置阿里云安全组5. 启动 FRP 服务端6测试与验证FRP客户端服务端配置步骤windows配置其他token 生成frp内网穿透 参考文章 frp实现内网穿透(一…

2026/7/23 19:04:46 阅读更多 →
GEO优化AI搜索排名:本地化数字营销实战指南

GEO优化AI搜索排名:本地化数字营销实战指南

1. 项目背景与需求解析在上海闵行区开展GEO优化AI搜索排名业务,本质上是在解决企业本地化数字营销的核心痛点。这个需求背后反映的是当前企业获客渠道从传统线下向线上精准投放转移的大趋势。我接触过不少闵行区的制造型企业主,他们最常抱怨的就是&#…

2026/7/23 19:04:46 阅读更多 →
企业级AI Agent平台:客服、销售、IT、财务与理赔自动化实践

企业级AI Agent平台:客服、销售、IT、财务与理赔自动化实践

架构基座与调度机制 传统规则引擎面临维护成本过高问题。大语言模型赋予系统复杂推理能力。平台架构已突破单轮对话局限。多智能体协作成为企业标配。核心模块包含意图识别组件。向量记忆库提供跨会话支撑。工具层打通外部异构系统。决策中枢负责任务拆解。数据流向制约响应延迟…

2026/7/23 19:03:46 阅读更多 →

日新闻

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表)

更多请点击: https://intelliparadigm.com 第一章:从单点好评到指数级传播:AI副业主理人必须掌握的4层口碑渗透模型(含ROI测算表) 当AI副业主理人不再仅满足于单次服务交付,而是主动构建可复用、可裂变、可…

2026/7/23 0:00:25 阅读更多 →
AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析

更多请点击: https://codechina.net 第一章:AI写作开头钩子设计:为什么你的AI文案完读率不足18%?——基于2,346篇A/B测试报告的归因分析 在对2,346篇跨行业AI生成文案的A/B测试数据进行聚类分析后,我们发现&#xff1…

2026/7/23 0:01:26 阅读更多 →
Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具

Chitchatter完整指南:免费开源的终极点对点安全聊天工具 【免费下载链接】chitchatter Secure peer-to-peer chat that is serverless, decentralized, and ephemeral 项目地址: https://gitcode.com/gh_mirrors/ch/chitchatter Chitchatter是一款革命性的安…

2026/7/23 0:01:26 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 8:58:19 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 19:43:43 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/23 17:49:47 阅读更多 →

月新闻