
3月14日TiDB社群在湖南办了场“数智湖南”的线下活动现场来了不少零售、医疗、金融、交通、智能制造行业的同学。聊天时发现一个很明显的信号大家不关心某某数据库又发布了什么新版本真正焦虑的是数据库国产化升级这件事到底怎么选型、怎么迁移、怎么落地才不翻车。这篇文章就当一次技术复盘把我在现场听到的、以及自己实操中验证过的内容整理出来给正在做国产化替换的团队做个参考。如果你已经在选型、迁移或者刚换完库正在处理各种疑难杂症这里面的东西大概率用得上。1. 为什么是TiDB国产化选型背后的三笔账现场很多人并不是TiDB老用户不少人之前用的是MySQL也有从Oracle项目转过来的。聊天时被问到最多的一个问题是国产数据库那么多为什么优先考虑TiDB我的看法是大家本质上在算三笔账兼容性、扩展性和一致性。这三笔账算清楚了选型就不会太纠结。1.1 兼容性账从MySQL生态平滑迁移到底省多少事先说最直观的TiDB兼容MySQL协议和大部分语法。这意味着什么意味着你现有的ORM框架、SQL习惯、数据库连接方式、甚至很多运维脚本都可以直接拿过来用。数据库增删改查这类日常操作开发几乎感觉不到换库了。我在实际项目中见过不少“伪国产化”案例把数据库换了结果业务代码里几千条SQL要手改改了三个月还不敢上线。这种成本往往被严重低估。但“兼容”不等于“完全一致”有几个关键差异我建议大家早做盘点。事务隔离级别上TiDB默认是读已提交RC而MySQL默认是可重复读RR。绝大部分业务其实感觉不到差异但如果有代码依赖RR下的间隙锁行为或者用SELECT…FOR UPDATE做复杂并发控制就要注意了。TiDB也支持悲观事务和可重复读通过begin pessimistic或set transaction isolation level repeatable read可以按需切换只是不建议全局无脑开。自增主键和隐式事务边界也有区别。MySQL的AUTO_INCREMENT在TiDB里更多只保证唯一性不保证连续真正的高并发写入场景我更推荐使用AUTO_RANDOM后面细说。存储过程、触发器、自定义函数这类数据库端逻辑TiDB的支持度有限现场有个做医疗集成的哥们说得挺实在“与其纠结兼容性不如趁迁移把存储过程重写成应用代码以后维护省心太多。”我的建议是选型期间做一轮SQL兼容性扫描把不兼容语法列成清单逐条评估重写成本。这一步做好后面迁移会顺很多。1.2 扩展性账从分库分表到原生分布式成本差在架构很多团队从MySQL走到TiDB不是因为MySQL不好而是因为分库分表的日子过不下去了。业务量一旦上来MySQL单机扛不住大家就开始搞ShardingSphere、MyCat这类中间件或者自研分片规则。刚开始还能撑时间一长问题就冒出来了跨分片的join查不了、分布式事务难做、扩容要重新分片光是在凌晨做数据重分布就够让人崩溃的。TiDB的思路不太一样。它是一个原生分布式数据库底层把数据自动切成Region每个Region默认约96MB分散存储在TiKV节点上。PD组件负责调度Region比如某个节点存储快满了它会自动把Region迁到空闲节点某组数据被频繁访问形成热点它会主动拆分并分散热点。这个过程对业务是无感的。用个生活化的类比分库分表像是你自己动手搬家每搬一次都要重新规划箱子标签、搬运路线TiDB像是住进了一个带自动仓储系统的房子东西多了就往货架上摆系统自己调度存放位置。所以做国产化替换时如果现有MySQL已经走到分库分表这一步或者未来三五年容量会涨一个数量级TiDB这种原生分布式架构的价值就非常明显。项目里只需要预估好容量规划比如目标多少个TiKV节点、单节点多大磁盘然后扩容时加机器加节点就行不需要业务配合改造。1.3 一致性账多副本与强一致给业务一个看得见的可靠这部分在金融、医疗行业聊得最多。传统MySQL主从复制是异步的主库写入成功、从库还没追上时主库宕机会出现数据丢。业务小的时候大家睁一只眼闭一只眼但到了核心账务、医疗记录这种场景丢数据是不能接受的。TiDB的副本一致性基于Raft协议。默认情况下数据至少有3个副本写入时多数派节点确认成功才算真正提交少数节点故障时自动从剩余副本中选出新Leader无需人工介入。简单理解就是每次写成功意味着多数副本已经把数据落盘了单节点故障不会造成数据丢失。现场做金融系统的同学分享了一个点他们最看重的是RPO0进程恢复点目标为零因为监管对账务数据完整性要求极高TiDB的多数派提交机制让“不丢数据”变成了系统级保障而不是靠运气和人工补救。不过这里要提醒一句强一致不代表强容灾跨机房的网络分区、两地三中心部署涉及副本分布策略和仲裁设计这些要在架构阶段就想清楚。不要把“数据库自己带一致性”理解成“整个容灾体系都可以不管了”。2. 五大行业场景下的落地路径拆解共性讲完再看个性。行业属性决定了你的优先替换对象、部署方式和性能目标。这次活动把行业切得很细我结合现场讨论和自己的项目经验逐个拆一下。2.1 零售大促峰值与订单数据合并先把分库分表拆掉零售行业的数据特征非常明显业务波峰波谷差距巨大大促期间流量可能是平时的几十倍订单、库存、会员、促销这些核心模块都是关系型数据彼此关联复杂。做零售系统的团队普遍诉苦“订单表太大每天千万级增长我们搞了32个分片查询要路由统计要聚合ETL清洗折磨死人。”TiDB在零售场景的落地方式主要是把分库分表的订单数据合并回来。因为TiDB本身具备水平扩展能力订单表不用人为分片写入压力能通过节点扩展分散。同时TiDB的AUTO_RANDOM可以解决高并发插入时的自增主键热点问题——避免所有写入都压在同一Region上。现场有人分享他们做的一次大促压测用TiDB替换分库分表后并发写入量直接提升了一个量级而应用代码改动量远比预期小。给零售团队的建议优先把订单查询、库存扣减这类需要跨分片强一致和复杂查询的业务迁过来然后再逐步把数据分析查询引到TiFlash列存引擎上减轻在线业务的查询压力。大促前一定要做全链路压测热点商品、热门门店的行写入冲突问题压测阶段就会暴露出来。2.2 医疗HIS与电子病历的高可用稳定性比性能更关键医疗行业的信息系统有其特殊性核心业务7×24小时不能停电子病历、门诊挂号、检验结果这类数据要求长期保存且不能出错。医疗IT团队对“宕机”的容忍度极低一个关键系统出问题可能直接影响患者就医。TiDB在医疗场景的部署我见过比较成熟的形态是跨可用区3副本部署。数据分布在多个可用区某个可用区故障时Raft自动切换门诊系统不中断。这一点对医疗用户来说比性能提升更有吸引力。另外医院的信息系统还包括大量运营分析类需求比如病案统计、科室绩效、医保控费分析这些只读分析查询走TiFlash列存可以避免在线交易系统被大查询拖垮。但医疗行业的替换节奏通常偏慢原因不在技术而在流程和预算。我给出的建议是先从不那么核心但价值明显的系统入手比如历史病案归档查询、运营报表平台跑通整个国产化迁移流程后再逐步向HIS、LIS等核心系统扩展。现场有位医工信息化负责人说得很好“我们不怕慢怕的是不让试。”2.3 金融账务强一致与两地三中心容灾安全底线不能碰金融行业是国产化升级压力最大、要求也最苛刻的领域。典型场景包括支付清结算、信贷、风控、账户系统涉及大量账务和资金流水每次写操作都要求强一致同时要满足审计合规、数据加密、日志留存等要求。金融场景做数据库替换重点关注几件事。第一强一致写是硬指标Raft多数派提交才能满足关键账务的可靠性要求。第二两地三中心或同城双活是常见部署形态需要数据库本身具备跨数据中心调度能力。第三数据加密和审计能力比如透明数据加密、细粒度审计日志这直接关系到能否通过合规验收。现场一位做支付系统的架构师提到他们目前的做法是“先边路后主干”支付清结算、风控引擎这类相对独立的系统先迁到TiDB核心账务系统继续观察等到周边系统稳定跑过一到两个季度再启动核心系统迁移。这个节奏我认为很务实。另外提醒一句金融行业对硬件的国产化适配要求也很高选型阶段要把服务器、操作系统的兼容性验证提前做起来。2.4 交通海量订单与轨迹数据写入扩展能力是硬指标交通行业的数据特点可以用“量大、频繁、实时”来概括。网约车订单、出租车轨迹、公交刷卡记录、ETC通行流水、地铁清分结算每个系统每天都会产生大量写入而且业务方经常需要按时间维度快速查询这批数据。这类场景里TiDB的核心价值体现在写入扩展性上。订单流水表不再需要分库分表写入能力可以通过加TiKV节点线性扩展。按时间范围查询可以配合分区表把一张大表按天或按月分区查询时只扫描对应分区。有些分析型需求比如某条线路的客流热力图、某天的全网订单统计可以交给TiFlash列存引擎来处理避免和实时写入抢资源。现场有做智能交通的同行分享了一个细节他们之前用MySQL单表到了几十亿行之后读写都开始退化后来迁移到TiDB分区表加自动分裂写入稳定、查询快速数据库层面的维护成本降了一个档次。他还说了个很关键的体会“去掉了分库分表之后团队终于可以把精力放在业务逻辑上了而不是天天和分片路由斗智斗勇。”交通数据还有生命周期管理的需求历史数据归档、冷热分离这些需要在方案设计阶段一并做好规划。2.5 智能制造MES与工业数据的接入重点看多源集成智能制造行业的数据库需求和前面几个行业都不太一样。生产制造现场的系统非常多MES制造执行系统、ERP、质量追溯系统、设备数据采集系统、仓储管理系统数据来源五花八门库型也很杂。国产化升级在这类场景里经常要以“规划数据汇聚层”为起点。我在现场听到的一个典型做法是用DM数据迁移工具把各个异构业务系统比如老MySQL库、Oracle库的数据实时同步到TiDB汇聚成一个统一的主数据区承载跨系统的生产计划、质量追溯、物料管理等查询和分析任务。这样既保留了原业务系统的运行状态又让新应用能在一个统一的数据库上做复杂查询。同时必须提醒一下不要什么数据都往关系型数据库里塞。工业场景里有大量设备实时采集数据比如机床振动、温度、电流这类数据天然是时序数据更适合用TDengine这类时序数据库处理。TiDB管好生产业务的主数据和交易性数据时序库管好设备运行数据再通过应用层做关联分析各司其职效果最好。很多团队一上来就想用一个大数据库搞定所有数据最后往往搞得谁也跑不好。3. 国产化迁移的实操套路从评估、双跑到回滚选型做完真正硬核的是迁移。很多团队以为换库就是“导出、导入、切换”实际执行下来会发现这是一套系统工程评估、同步、校验、双跑、切流、回滚。任何一个环节没想清楚都可能把线上业务搭进去。3.1 迁移前评估哪些业务适合先动哪些必须缓一缓迁移评估不能凭感觉我一般建议团队从四个维度出评估报告容量、流量、SQL兼容性、依赖关系。容量就是数据量、增长率以及单表大小是否适合分布式存储流量要看当前峰值QPS和未来预期SQL兼容性前面已经说过把存储过程、触发器、外键、特殊函数全部扫一遍依赖关系则是看这个库被多少下游应用依赖能不能暂时接受它切换窗口。有一点想重点强调第一批迁移对象一定要挑“能快速见效、失败也无伤大雅”的业务。历史归档库、报表分析库、非核心交易系统的读库都是非常合适的试点。先把迁移流程跑通团队积累了经验再动订单、账务这类核心库。现场有位做政务系统的朋友分享过他们的教训一上来就迁移最核心的系统结果兼容性问题叠加业务高峰期折腾了两个月才恢复平稳整个项目信心都被打没了。3.2 数据迁移与校验全量、增量、双写的完整链条数据迁移阶段TiDB生态提供了相对成熟的一套工具组合我用表格整理一下各自的定位工具职责适合场景Dumpling从MySQL等数据库导出逻辑数据支持一致性快照全量数据导出Lightning高速导入TiDB物理导入模式性能高全量数据导入初始化DM (Data Migration)MySQL到TiDB的全量增量同步支持分表合并在线迁移、持续同步TiCDC捕获TiDB变更数据同步到Kafka、Pulsar或其他数据库增量复制、实时数仓、容灾一个标准迁移链路的完整步骤是先用Dumpling导出源库的一致性快照通过Lightning快速导入TiDB随后启动DM的增量同步让源库的在线写入实时流向TiDB观察增量同步延迟逐渐归零后再进行数据校验。校验不能只数行数要对字段级做checksum比对抽样diff关键业务表。我在项目里还养成了双跑的习惯迁移期间新老库并行写入一段时间应用层做双写让真实业务流量去验证新库的正确性。双写不是必选项但对核心业务而言这个成本买的是安全感和回滚空间。踩坑提示DM同步要求源库开启binlog且格式为ROW大表DDL同步时要关注是否触发数据重放增量任务延迟堆积常和分区表、主键缺失有关排查时要多角度验证。3.3 切流与回滚灰度发布的最后一公里数据同步完成不代表可以马上切流量。我的建议是切流遵循四个步骤先切只读流量再切写流量保留旧库运行一段时间最后才下线老库。切只读流量相对安全把报表查询、历史数据查询切到TiDB让业务验证SQL兼容性和查询性能。只读运行稳定后再切换写流量这时候要准备好连接串和配置中心的平滑切换方案很多应用切换连接串需要重启要提前设计好发布窗口。切写完之后的回滚窗口期建议至少保留7到15天旧MySQL库持续同步或者保持可用状态一旦TiDB侧出现问题可以快速切回。有朋友会问“能不能不保留旧库直接一次性切换”我的回答永远是所有一键切换、不留退路的方案最后都变成了惊魂夜。留好退路团队心态都会不一样。另外说一个和MySQL修改结构相关的小经验迁移前先把目标表的索引、分区、字符集等规划好不要在迁移过程中频繁做DDL变更。虽然TiDB支持在线DDL但迁移窗口内结构变化会增加同步任务的不确定性能避免就尽量避免。4. 换库之后真实踩过的坑与排查方法迁移好不容易搞完真正的考验才刚刚开始。国产化替换完成后的初始阶段往往是问题集中爆发的时候。把我在实际项目里踩过、以及现场同行分享的高频问题整理出来每条都对应真实场景算是避坑指南。4.1 连接池与并发微服务接入TiDB的几个高风险参数换库之后最常见的第一类事故是连接池被打满。原来MySQL最大连接数可能默认是100多、200多TiDB集群整体的连接上限改造后需要重新设计。很多微服务团队习惯把连接池MaxActive、MaxOpenConns调到很大比如单实例100甚至200几十个服务实例一起连过来瞬间就能把TiDB的连接数打爆报错“Too many connections”。正确做法是先做总量控制。计算方式很简单服务实例数×连接池大小≈TiDB预留连接数再预留30%左右的缓冲。比如服务有50个实例每个连接池最大20那总量就是1000集群配置就要对得上这个数。同时排查慢SQL和长事务很多连接数被打满不是连接池配置问题而是慢SQL占着连接长期不释放。在TiDB里查慢SQL很简单直接查information_schema.slow_query表或者用TiDB Dashboard看耗时长SQL和锁等待情况。还有一个容易忽略的点应用端的连接超时和读写超时设置。MySQL连接方式下连接空闲超时、事务超时是常见问题TiDB处理空闲连接的方式和MySQL不太一样建议仔细测一遍业务侧的wait_timeout和interactive_timeout表现。4.2 大事务与热点写入SQL设计与表结构改造建议分布式数据库和单机数据库在事务能力上存在天然差异TiDB单事务默认是有限制的大约100MB。很多从MySQL迁过来的团队第一次遇到“transaction too large”报错时都是一脸懵。典型的触发场景是一次性批量更新几十万行、一个存储过程里对超大表做全表UPDATE、或者一次delete太多数据。解决办法是把大批量操作拆成小批次比如每1000行提交一次同时尽量用主键或唯一键条件定位数据减少事务扫描范围。另一个高发问题是写入热点。TiDB会把数据自动切分成Region并调度但如果业务表主键是自增整数新写入数据会一直往同一个Region上撞形成单点写入瓶颈。解决办法就是前面提到的AUTO_RANDOM让主键值在全局范围内随机分布写入压力自然被分散到多个Region。这个改造看起来不起眼对于订单、流水类高并发写入表来说收益非常明显。还有隔离级别和死锁问题。TiDB默认RC并发更新同一行时会出现写冲突报错信息需要认真看优先调整应用并发控制逻辑。分布式数据库下死锁排查和MySQL略有不同我的经验是先看TiDB的锁等待监控和事务冲突指标定位热点行再优化SQL执行顺序或拆分事务。4.3 数据同步与灾备DM与TiCDC的正确使用姿势很多团队的国产化迁移不是一次性切换而是长期双跑、增量同步这就离不开DM和TiCDC两个工具。我在现场发现大家对它们的职责还有点混淆这里再强调下DM是外部数据库到TiDB的数据同步工具核心场景是MySQL迁移和持续增量TiCDC是TiDB提供变更数据捕获能力核心场景是把TiDB的变更输出到消息队列或下游数据库常用于实时数仓、灾备、多中心数据分发。使用DM最容易踩的坑是DDL同步中断。源MySQL做一次大表ALTERDM任务可能进入到pending状态需要人工介入处理。我的建议是变更窗口提前规划核心大表DDL拆分执行关注DM任务的同步延迟指标。TiCDC常见问题是内存积压下游消费能力不足导致延迟增长排查时要看TiCDC节点的内存使用、Kafka分区数和消费端吞吐。灾备层面TiDB虽然自带多副本但跨机房、跨地域的灾备还是需要单独设计。同城多可用区部署时要注意让Raft的多数派副本能够抵御单个可用区故障异地灾备通常需要拉专线并确认网络延迟不会影响数据库写入性能。容灾切换建议定期做演练不要等真出故障了才手忙脚乱。4.4 现场交流的问题清单与排查速查表整理一份我在现场和实际项目中收集的问题速查表适合贴在工位上问题现象可能原因检查方法常规解决思路查询突然变慢统计信息过期优化器选了差计划看执行计划、查慢SQL日志ANALYZE TABLE更新统计信息必要时用SPM固定执行计划连接数被打满服务实例连接池过大或慢SQL堆积查information_schema.slow_query、监控连接数缩小连接池、杀掉慢SQL、优化业务代码大批量更新报transaction too large超过单事务大小限制看错误码和事务日志按主键范围分批提交写入吞吐上不去自增主键热Region查看热点Region分布改AUTO_RANDOM或自定义分布式主键增量同步延迟上涨DM或TiCDC任务卡住、下游消费慢看任务状态和延迟指标检查DDL、拆分消费任务、调整下游并行度数据不一致双写顺序错误或同步漏数据行数比对、checksum校验补做全量校验修正双写逻辑跨机房故障后无法自动恢复副本分布未满足容灾要求查看PD调度和副本分布调整可用区副本策略手动切换或重新调度这张表不能覆盖所有问题但高频问题基本都在里面了。我特别想强调一个方法论排查TiDB问题不要只看数据库本身要连应用连接池、微服务超时设置、SQL执行计划一起看很多疑难杂症最后都定位在应用侧。一个下午的交流信息量比我预想的大。我自己的感受是国产化这件事真正难的从来不是把数据搬过去而是能不能让业务无感、让运维不慌。TiDB给了相对平滑的方向但每个行业都要有自己的落地节奏。从我个人的实践来看给正在做这件事的团队一个建议别急着把核心系统排到第一批先选两个非核心场景完整跑一遍迁移、切流、回滚、压测的流程把坑都踩过一遍再谈扩大范围。技术选型的答案网上到处都有但属于你自己业务的答案只能在一次次演练里得到。