2026/10/21 7:47:12

Zabbix监控库从MySQL迁移TiDB:踩坑总结与实操指南

Zabbix监控库从MySQL迁移TiDB:踩坑总结与实操指南 如果你管过一套上了规模的Zabbix多半能理解这种焦虑监控大盘画面看起来还正常可背后那台MySQL单机库已经在崩溃边缘试探。我们这次就是被逼到这一步才下决心把Zabbix监控库从MySQL整体迁到了TiDB。整个过程有惊无险中间踩了不少坑也整理出了一套可以拿去直接用的实操方法。这篇文章把完整过程记录下来从方案选型、兼容性摸底、schema导入、参数调整到数据迁移、切换验证、问题排查涉及的关键细节都会展开说适合正在纠结监控库扩容的运维同行也适合打算把老MySQL库迁到TiDB的团队参考。1. 为什么最后选了TiDB1.1 监控库撑不住的三个典型症状先说我们的实际规模。接手的这套Zabbix监控平台覆盖了多个机房受监控主机数量在1500台上下活跃监控项累计接近40万采集频率大部分是30秒一次少部分网络设备是10秒一次。这样跑下来每24小时落库的history明细数据大约有1000万条加上trends趋势数据和告警记录一个季度就能把磁盘空间撑到让DBA皱眉的程度。症状是逐步出现的。最开始只是MySQL的慢查询日志里出现一些扫描行数千万的history查询随后是磁盘IO经常跑到90%以上接着是前端画面偶尔要转好几秒才出图。到了后半年情况变得更典型history_uint这张核心大表到了500GB级别备份时间从最初的几小时被拉长到十几个小时每次做数据清理DELETE语句会把主库卡到应用超时Zabbix Server日志里间歇性出现“history sync process”落盘迟缓的告警。真正的痛点不是单条SQL多慢而是整个单机MySQL在写入、备份、清理三个环节同时到极限任何一个环节处理不当都会连锁拖垮监控的实时性。这时候很多团队的第一反应是继续压榨MySQL比如换SSD、调buffer pool、加读写分离。但这些方案解决不了本质问题监控数据是典型的持续高并发写入加周期大海量删除单机架构在容量和写入吞吐上都有天花板继续堆硬件只是把问题往后推迟两三个月。1.2 为什么不继续压榨MySQL也不选PostgreSQL既然是Zabbix官方既支持MySQL又支持PostgreSQL换库的选项似乎很宽但真正对比下来可选的路并没有想象中那么多。继续留MySQL做分库分表是最先被排除的。Zabbix的schema里表与表之间有大量跨表JOIN前端页面的图型查询动不动就带着四五张表关联如果按主机维度分库跨库查询基本没法写按时间段分表又需要大改Zabbix源码。为了一个开源监控系统去改内核逻辑后续每次升级都是灾难。换PostgreSQL也认真评估过。Zabbix对PostgreSQL的支持是完整的迁移本身也有官方升级路径但问题出在迁移难度上。监控库里存着好几年的历史数据MySQL到PostgreSQL不仅字段类型需要转换部分函数和SQL模式行为也不一致前端SQL虽然Zabbix内部有抽象但rownum这类MySQL方言痕迹依然存在。更现实的阻力是团队对PostgreSQL的运维经验明显不如MySQL丰富出问题的时候排查效率会低不少。最后摆上桌面的是TiDB。它最吸引人的一点是连接协议和SQL语法与MySQL高度兼容应用侧几乎不用改连接方式很多MySQL写法直接就能跑。与此同时它又是分布式架构写入能力可以通过加节点横向扩展数据存储有多个副本坏了节点不丢数据。对Zabbix这种以写入为主、单机MySQL已经撑不住的场景来说TiDB的定位几乎是量身定做。1.3 TiDB到底哪一点打动了我们真正打动的其实就两条兼容和扩容。先说兼容。TiDB的兼容不是说表面接个MySQL客户端那么简单而是绝大多数SQL语法、数据类型、事务语义都能无缝对接。Zabbix Server用的是C代码里的MySQL客户端库PHP前端走的是mysqli扩展这两条路都能直接连TiDB端口默认4000几乎不需要改连接字符串以外的内容。MySQL原生客户端工具、mysqldump导出的SQL文件在TiDB上都能正常执行。也就是说我们不需要改Zabbix任何代码。再说扩容。TiDB的计算节点TiDB Server和存储节点TiKV是分开的监控数据量上来了往集群里加几台TiKV节点就能把存储和写入吞吐撑起来不需要做任何分库分表逻辑改造。对运维团队来说这是一条清晰的线性扩容路径比在MySQL上反复迁移数据实在得多。当然选择TiDB不等于没有代价。分布式事务的提交代价比单机MySQL要高小事务、低并发的场景下延迟反而可能不如MySQL另外TiDB对部分MySQL特性的支持仍有差异比如存储过程、触发器、FULLTEXT索引这些替换前必须逐项排查。把兼容性边界摸清楚是这次替换能否成功的前置条件。2. 替换前必须摸清的兼容性底牌2.1 先搞懂Zabbix到底在数据库里干了什么动手迁移之前我先花了一个下午把Zabbix的数据库访问机制重新理了一遍。很多人容易忽略这一步直接拿schema去TiDB里导入报错之后再一点一点打补丁效率很低。Zabbix对数据库的使用可以分成三层。第一层是配置数据包括hosts、items、triggers、actions、users、settings这些表数据量不大但被Zabbix Server在启动时整体加载到内存里前端页面也经常查对事务一致性有要求写入频率低。第二层是历史数据包括history、history_uint、history_str、history_log、history_text这五张明细表以及trends、trends_uint两张趋势表承担了全库99%的写入量和查询压力特点是只增不减、按时间查询。第三层是运行数据比如alerts、auditlog、events、sessions量级介于前两层之间前端操作和告警处理都要用到。这里有一个容易被忽视的关键机制Zabbix从5.0版本开始默认启用数据库分区主要针对history和trends系列表创建方式是Range分区按clock字段的月份做边界。分区的好处是清理过期数据不再走DELETE而是对过期分区执行DROP PARTITION瞬间完成。理解这一点非常关键因为TiDB支持Range分区也就是说Zabbix引以为傲的快速清理机制在TiDB上可以保留不必退化为大量DELETE。另一个机制是housekeeper。Zabbix Server内置的housekeeper进程负责清理过期事件和审计日志对分区表走分区删除路径对非分区表走DELETE。如果迁移后分区功能失效housekeeper就会用DELETE去啃几百万行的历史表在TiDB上这会直接触发大事务限制是我们必须避免的情况。2.2 一份不完全的TiDB不兼容点清单Zabbix的schema文件本身比较干净不涉及存储过程和触发器但替换前我还是把TiDB和MySQL的差异点列了个清单照着一条条核对省得到时候临时抓瞎。差异点MySQL行为TiDB行为对Zabbix的影响存储过程/自定义函数支持不支持schema中无存储过程无影响触发器支持不支持schema中无触发器无影响外键约束默认生效语法兼容但默认不启用实际约束Zabbix schema不依赖外键无影响FULLTEXT索引支持不支持Zabbix无全文索引无影响LOCK TABLES语句执行并加锁默认报错可开启noop函数忽略前端日常操作不触发个别升级脚本需关注大事务默认可很大默认事务总大小有限制housekeeper批量DELETE需分区表规避零日期/非法日期部分SQL模式报错SQL模式默认值不同迁移数据时需统一SQL模式ALTER TABLE部分类型变更支持较多某些修改操作受限升级schema脚本时需逐条检查这张表看着简单实际每条后面都有故事。比如LOCK TABLESTiDB官方文档里明确说不支持这条语句但为了兼容MySQL生态提供了一个叫“noop function”的开关开启后遇到LOCK TABLES会直接忽略而不是报错。Zabbix前端虽然日常不执行LOCK TABLES但我们不能保证所有升级脚本和二次开发代码都不碰它所以提前把开关打开可以少操很多心。外键也是一样Zabbix官方schema在6.0版本并不创建外键如果你们团队自己加过外键迁移前一定要先去掉否则TiDB虽然能导入但外键实际上不会生效容易造成数据完整性假象。2.3 快速搭一套能“试错”的TiDB环境摸清兼容性边界之后我没有直接在生产环境动手而是先在测试环境搭了一套TiDB用来反复试导入和验证功能。这里强烈建议任何打算做替换的团队都走这一步因为TiDB集群部署本身虽然不难但有许多参数和逻辑需要在真实环境下观察效果。测试环境可以用单机方式快速部署。当时的做法是用官方运维工具先起一套本地独立的TiDB命令行大致如下tiup playground v6.5.0 --db 1 --pd 1 --kv 1这个命令会拉起一个单节点的TiDB测试集群包含一个TiDB Server、一个PD、一个TiKV监听4000端口。用MySQL客户端连上去就能操作mysql -h 127.0.0.1 -P 4000 -u root如果是生产环境建议用统一的集群部署方式准备好拓扑文件后执行tiup cluster deploy zabbix-tidb /opt/tidb/topo.yaml tiup cluster start zabbix-tidb生产环境的topo.yaml至少要规划3个TiKV节点起步PD也是3个才能保证容灾TiDB计算节点视并发量放2到4个。这里不展开完整拓扑写法重点是要在测试环境先把下面这些动作全部做一遍创建zabbix库和用户、导入schema.sql、手动执行几条Zabbix前端典型查询、模拟一次分区创建和删除。全套跑通之后再谈生产切换才靠谱。创建数据库和用户的SQL在TiDB上写法基本一致CREATE DATABASE zabbix CHARACTER SET utf8mb4 COLLATE utf8mb4_bin; CREATE USER zabbix% IDENTIFIED BY your_password_here; GRANT ALL PRIVILEGES ON zabbix.* TO zabbix%;3. schema导入与参数适配实录3.1 直接导入schema的第一波报错测试环境准备好之后我从Zabbix服务器上拿到了数据库初始化SQL文件Zabbix 6.0版本的安装包路径一般是/usr/share/zabbix-sql-scripts/mysql/里面有个压缩的SQL文件解压出来就是完整schema。导入命令看着很简单但真实执行时第一波报错就来了。命令本身是这样的gunzip -c server.sql.gz server.sql mysql -h 127.0.0.1 -P 4000 -u zabbix -p zabbix server.sql导入过程中最先碰到的是ERROR 1105 (HY000): unsupported statement。定位发现是schema文件开头的部分MySQL版本注释写法TiDB不认识报错语句是MySQL 5.01版本注释块里的分区定义语法。这里要说明一下Zabbix生成SQL文件时会把分区创建语句包在/*!50100 PARTITION BY RANGE ... */这种版本注释里MySQL自己执行时能识别TiDB在部分版本下解析这类注释也可能有问题。解决方式不复杂我写了个小脚本把server.sql里所有/*!50100 ... */版本注释的包裹去掉让分区语句变成普通的CREATE TABLE语句的一部分再执行就没有这个问题了。这个处理在MySQL上也不影响因为去掉注释后语法本质相同。随后遇到的第二个报错是字符集相关。TiDB默认的character_set_server和collation_server可能与Zabbix期望的不完全一致导致建表时出现无法识别的排序规则。解决办法是在TiDB侧把全局变量设成与MySQL一致的组合SET GLOBAL character_set_server utf8mb4; SET GLOBAL collation_server utf8mb4_bin;设置完之后再重新导入。还有一个容易忽略的地方TiDB默认SQL模式下NO_ZERO_DATE、NO_ZERO_IN_DATE的开关状态与MySQL常见配置有差异如果历史数据里有零日期导入时会报错建议导入前确认当前会话SQL模式必要时显式SET一下。3.2 分区表Zabbix和TiDB都能接受的方式分区表的处理是整个适配里最容易出错也最重要的一环。Zabbix 6.0的schema文件里默认给history和trends表预建了一批分区大约覆盖到当前时间之后几个月后续运行中由Zabbix Server自动补充新分区。TiDB对Range分区是支持的创建语法和MySQL几乎一样这就保证了Zabbix那套自动维护逻辑能继续跑。但我在测试中发现一个细节TiDB执行ALTER TABLE ... ADD PARTITION时分区定义里的VALUES LESS THAN (UNIX_TIMESTAMP(2023-03-01 00:00:00))这个写法是兼容的而Zabbix server在运行时会周期性检查未来分区是否存在不足就自动补。所以只要初始分区创建成功后续自动补充分区基本不用人工干预。我在测试环境手动确认了分区操作的兼容性下面两个语句TiDB都能正常执行ALTER TABLE history ADD PARTITION (PARTITION p2023_03 VALUES LESS THAN (UNIX_TIMESTAMP(2023-04-01 00:00:00))); ALTER TABLE history DROP PARTITION p2023_01;实际运维中强烈建议在迁移完成后检查一次实际表结构确认history和trends系列表都按分区存在。检查方法很直接SELECT TABLE_NAME, PARTITION_NAME FROM information_schema.PARTITIONS WHERE TABLE_SCHEMAzabbix AND TABLE_NAMEhistory;如果发现分区没建上或者Zabbix Server没有按预期自动补充分区就需要用计划任务兜底定期执行补分区SQL。这种情况在版本差异大的时候可能出现提前做好监控告警避免分区断档之后housekeeper退化走DELETE引发大事务。3.3 TiDB与Zabbix两侧的关键参数调整schema导入跑通之后不要急着接生产流量先把两侧参数调到位。TiDB侧有几个参数与Zabbix这种写入密集场景直接相关。第一个是事务大小限制。TiDB默认的txn-total-size-limit是100MB意思是单个事务里所有写入和修改的数据总量有限制超过直接报错。Zabbix虽然用分区表规避了大量DELETE但导入历史数据和部分维护操作仍可能出现大事务。在配置文件config.toml里我把这个参数调到了2GB[performance] txn-total-size-limit 2147483648注意这个参数是实例参数需要修改TiDB Server的配置文件并滚动重启才生效。调大不等于可以乱用任何超过1GB的事务在分布式数据库里都会引发明显的性能抖动SRE意识还是要有的。第二个是noop函数开关。前面提到LOCK TABLES在TiDB默认会报错打开开关之后会被忽略对于Zabbix这种不需要依赖MySQL表锁语义的场景直接开启是安全的SET GLOBAL tidb_enable_noop_functions ON;第三个是连接数。Zabbix Server和各监控节点走的是短连接池PHP前端也有连接TiDB默认最大连接数是4000实际使用中我们没遇到瓶颈但压测时曾观察到过too many connections需要确认Zabbix Server侧线程池配置不要设太高。Zabbix Server侧要改的就是数据库连接指向。编辑zabbix_server.confDBHost10.0.1.11 DBPort4000 DBNamezabbix DBUserzabbix DBPasswordyour_password_here前端配置文件zabbix.conf.php对应改成$DB[SERVER] 10.0.1.11; $DB[PORT] 4000; $DB[DATABASE] zabbix; $DB[USER] zabbix; $DB[PASSWORD] your_password_here;改完之后先不要直接重启测试环境里启动一次观察日志里有没有连接报错和初始化失败。Zabbix Server对数据库版本号有基本底线要求TiDB返回的版本号通常形如5.7.25-TiDB-v6.5.0前端和server端满足校验需求。4. 历史数据迁移与切换流程4.1 迁移策略配置表全量迁历史明细不迁数据迁移往往是最让人头疼的环节监控库里几百GB的history明细表如果全量往TiDB灌既慢又容易触发各种问题。我们当时做了一个务实的选择配置数据表全量迁移trends趋势表迁移history和history_*明细表不迁移让监控系统从切换时刻开始重新积累。这个策略背后的逻辑是体验驱动的。Zabbix前端在展示长时间范围图形时优先使用trends表的数据trends表每个监控项每小时只有一条记录体量比history小了两到三个数量级。例如一个监控项一天产生2880条history明细30秒一次但trends只有24条。全库40万监控项的trends数据一个季度大概也就是几千万条mysqldump导出和TiDB导入都能在可接受的时间内完成。history明细数据虽然丢了但它只影响短时间曲线的回查不影响整体监控能力。监控系统的核心价值是当前状态和近期趋势而不是几个月前的每一笔采集点。当然如果业务有硬性要求保留全部历史明细可以在切换完成后用TiDB的同步工具做增量补录但那是另一个话题代价会高很多。对大部分团队来说配置表加trends的迁移方案性价比最高。4.2 mysqldump导出与TiDB导入的实操命令迁移用的工具还是最稳妥的mysqldump导出的文件TiDB基本能直接吃。具体分两步走先导结构再导数据方便出问题定位。导结构的时候注意几个参数--single-transaction是为了保证InnoDB一致性快照--no-data只导出表结构避免误把大量历史明细带出来mysqldump \ --single-transaction \ --quick \ --skip-lock-tables \ --default-character-setutf8mb4 \ --no-data \ -h mysql-old -u root -p zabbix zabbix_schema_only.sql导入TiDBmysql -h 127.0.0.1 -P 4000 -u zabbix -p zabbix zabbix_schema_only.sql这里有个隐藏细节导出时如果MySQL实例上跑的是8.0版本mysqldump默认会在文件里带上SET SESSION.SQL_LOG_BIN0这类Binlog相关语句。TiDB执行这类语句一般会报错处理办法是导出时加上--set-gtid-purgedOFF并去掉不必要的会话设置。如果实在还有报错用sed把对应行处理掉即可。接着导出配置表和trends表数据。这里用到了--tables参数指定表名明确哪些表要导哪些表不导mysqldump \ --single-transaction \ --quick \ --skip-lock-tables \ --default-character-setutf8mb4 \ --set-gtid-purgedOFF \ -h mysql-old -u root -p zabbix \ --tables hosts groups items applications triggers functions \ trends trends_uint alerts events users settings \ zabbix_config_data.sql导入的时候如果SQL文件比较大建议在目标库执行时把输出重定向到日志文件方便查看进度和报错mysql -h 127.0.0.1 -P 4000 -u zabbix -p zabbix zabbix_config_data.sql import.log 21导入完成后做一轮行数校验这一步绝对不能省。抽样核对hosts、items、trends表的总行数和最新时间点确保数据没有丢SELECT COUNT(*) FROM items; SELECT COUNT(*) FROM trends WHERE clock UNIX_TIMESTAMP(2023-01-01); SELECT COUNT(*) FROM hosts;4.3 切换步骤与回滚预案切换当天是按这个顺序推进的全部操作用了大概两个小时。先停掉Zabbix Server的采集服务避免切换期间产生增量数据写进旧库。停服这个动作放在晚间业务低峰进行给历史数据迁移预留足够窗口。然后执行上面说的mysqldump导出导出完成后导入TiDB导入完成后校验。校验通过之后把zabbix_server.conf和zabbix.conf.php的连接信息从旧MySQL改成TiDB地址启动Zabbix Server。观察Server日志没有数据库连接错误后前端页面刷新确认主机状态和图形数据正常。回滚预案我是这样准备的旧MySQL实例不关机、不停服务保持原样运行至少一周。因为切换时只是改了Zabbix连接指向新旧两个库的schema保持一致万一TiDB侧出现严重问题把配置文件改回旧MySQL地址再补一遍切换期间产生的trends数据就能快速恢复。实际执行中这套预案虽然没有用到但给了团队足够的心理安全感。切换完成后还有一个容易被忽略的动作在TiDB上先跑一遍ANALYZE TABLE把统计数据刷新出来。因为新导入的库统计信息是空的TiDB优化器在生成执行计划时可能会选错索引导致前端页面某些查询突然变慢。执行下面这条命令能让优化器更快进入正常状态ANALYZE TABLE hosts, items, trends, history, history_uint;5. 切换后的功能验证与性能观察5.1 功能验证清单从登录到告警一条条过切换完成后的前24小时是最关键的观察期。我列了一张验证清单安排团队成员按顺序逐项跑通确保不是“数据库能连”就算成功。前端登录和页面加载是第一步。打开Zabbix前端页面用管理员账号登录确认仪表盘、主机列表、监控项列表都能正常加载。这一步能快速发现PHP连接层和字符集是否正常。第二步是检查实时监控数据是否在继续写入。在TiDB侧执行下面的查询看最新数据时间是否在持续刷新SELECT MAX(clock) FROM history_uint WHERE clock UNIX_TIMESTAMP(NOW() - INTERVAL 5 MINUTE);如果最大时间一直停在切换时刻说明采集写入链路有问题需要立即看Zabbix Server的进程日志。第三步是图形页面的验证。随机挑几台重要主机打开不同时间范围的图形分别覆盖1小时、24小时和7天确认短时间图形走history表、长时间图形走trends表的数据都能正常绘制没有断线或白屏。第四步是告警链路验证。手动维护一台测试主机触发一个已知的条件确认触发器状态变化、事件产生、告警通知发送的完整链路都正常。这一步能暴露Zabbix Server事件写入对TiDB事务模式是否敏感。第五步是housekeeper工作状态验证。查看Zabbix Server日志中housekeeper相关的输出确认它在处理历史表时走的是分区DROP路径没有出现大量DELETE。5.2 性能对比和查询优化手段切换后两周的观察数据积累下来性能表现基本达到了预期。写入层面最直观的变化是磁盘IO不再像以前那样频繁打满因为数据分散在多个TiKV节点上MySQL单机时代的顺序写放大问题消失了。具体数据上Zabbix Server的history sync进程处理积压的耗时从高峰期的十几分钟降到了一两分钟以内。查询层面则出现了新的挑战。分布式数据库在多节点并行扫描上有优势但优化器的执行计划对统计信息依赖很强。切换初期前端某些图形查询反而比MySQL慢定位之后发现是TiDB没有对history_uint表按时间列做有效的分区裁剪导致查询扫了多个分区。解决办法是确保查询条件里带上clock字段并且保证统计信息是最新的。对于Zabbix固定的几种查询模式可以给history_uint、trends_uint表按clock列建立索引让优化器有更多选择。如果遇到TiDB侧明显慢的SQL先从慢查询记录里捞出来看执行计划。TiDB自带慢查询系统表非常方便SELECT * FROM information_schema.slow_query WHERE process_time 3 ORDER BY process_time DESC LIMIT 10;拿到慢SQL后用EXPLAIN分析是否走了分区裁剪和正确索引。大多数前端慢查询只要把时间范围条件写清楚执行计划就会变得正常。5.3 长期运行必须注意的TiDB运维点稳定运行之后维护任务就切换到了TiDB的日常运营。以下几点是我实际运维中最有体会的。备份方案需要换。原来MySQL逻辑备份那套在TiDB上效率不高TiDB更推荐用自带的备份工具比如br命令行工具做全量加增量备份速度快且对集群影响小。备份策略可以沿用每日全量加每日增量恢复演练建议每季度做一次。GC机制需要理解。TiDB删除数据后空间不会立刻释放而是交给GC机制异步清理物理空间回收有一定的滞后。切换初期我们观察过磁盘使用率发现过DROP分区后空间没有马上减少的情况这是正常现象不用恐慌等几个GC周期后就会逐步回收。TiDB自身的监控不能缺。官方提供了配套的Grafana监控面板挂载在集群侧包含TiDB Server、TiKV、PD三层的核心指标。日常重点看TiKV的磁盘使用、CPU、Raft日志状态还有TiDB Server的SQL执行延迟和连接数水位。一套健康的TiDB集群TiKV各项指标应该保持平稳不会出现某节点异常突出的情况。升级Zabbix版本时要格外谨慎。TiDB对ALTER TABLE中的部分列变更操作支持有限Zabbix官方升级脚本里如果涉及MODIFY COLUMN类型变更可能需要在TiDB测试环境先演练一遍把不支持的操作手工转换过去。6. 高频问题排查与不为人知的坑6.1 高频问题速查表把这一路遇到的问题汇总成一张速查表后续再有人做类似替换可以直接按图索骥。现象可能原因处理方法导入schema报“unsupported statement”MySQL版本注释或分区语法TiDB无法识别去掉版本注释包裹分区语句普通化建表报排序规则错误字符集和排序规则不一致设置GLOBAL character_set_server和collation_serverZabbix Server启动报数据库版本不满足TiDB返回版本号过旧或被误判确认使用LTS版本前端校验一般能通过history表没有分区分区创建语句被忽略手动创建Range分区检查自动补充分区机制housekeeper清理数据极慢分区未生效退化为DELETE优先恢复分区机制临时手动分批DELETE报“transaction too large”单事务数据量超过限制调大txn-total-size-limit避免超大事务前端个别图形查询慢统计信息缺失或未走分区裁剪执行ANALYZE TABLE检查查询条件是否带clock连接数打满TiDB最大连接数不足或Zabbix连接池过大调整max_connections控制Zabbix线程池配置升级Zabbix时schema升级SQL失败TiDB不支持某种ALTER操作测试环境预演手工改写升级语句6.2 几条用时间换来的运维经验最后说几条不常被写进文档里的经验都是我实际踩过坑之后总结出来的。第一正式切换前一定要在TiDB测试环境里完整跑一遍Zabbix升级路径。我们当时因为测试环境没有跑过升级脚本后来在TiDB上做小版本升级时卡了好几个小时。有些升级脚本里包含了存储过程创建语句MySQL能跑、TiDB直接报错这种问题提前演练就能暴露。第二不要把MySQL的备份恢复习惯直接搬过来。刚开始我们本着熟悉的心态准备用mysqldump做TiDB日常备份测了一次恢复数据量一大恢复时间就长得让人难以接受。换成官方备份工具之后同样的数据量恢复时间缩短了一个数量级。分布式数据库要用配套的备份工具这是经验之谈。第三监控TiDB本身的告警和监控Zabbix一样重要。我们搭了一套独立的轻量监控来盯TiDB集群状态重点观察PD节点的健康、TiKV节点间心跳延迟、TiDB Server的活跃连接数和慢查询数。TiDB一旦出现节点故障会自动做Leader切换但如果你不知道看到监控曲线抖动就会慌。提前知道节点故障是正常的自愈机制运维心态会稳很多。第四切换后前两周不要做任何大动作。我们当时忍住没动Zabbix升级也没调TiDB的大参数只做了统计信息刷新和慢查询优化整个系统两周平稳后才开始正常迭代。这给团队留出了适应分布式数据库特性的缓冲期代价最小。这次替换让我印象最深的一点是TiDB不是银弹但它确实在“兼容MySQL生态”和“分布式扩展能力”之间找到了一个对运维团队很友好的平衡点。Zabbix跑在TiDB上不是官方标准架构需要自己踩过坑才会熟练但一旦摸清了这些边界整套方案完全可以在生产环境稳定跑下去。