ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PolarDB只读节点不可用怎么办?从故障根因到排查自救全攻略

PolarDB只读节点不可用怎么办?从故障根因到排查自救全攻略 1. 事故现场开工第一周从节点先给我上了一课开年第一周工位暖气还没烘热监控群就炸了生产环境PolarDB集群的一个只读节点连不上了应用侧持续报连接超时控制台里那个节点的状态红得发亮。我嘴上说着这种小问题多半是网络抖动或者连接池抽风重启一下准能好心里也是真没太当回事。结果这个重启大法的乐观念头让我接下来四个小时反复打自己的脸也把我这个自称大能人的博主变成了开年第一场事故复盘会的主角。先说清楚我念叨的从节点就是PolarDB集群里的只读节点。PolarDB是计算存储分离架构一个集群通常有一个主节点负责读写外加若干个只读节点专门分摊读流量同时在主节点故障时作为备选切换目标。这篇博文要记的就是一次从节点从看起来挂了到真正恢复的完整排查过程还有我事后整理的一整套从节点不可用排查方法。不管你是PolarDB的使用者、公司的DBA还是正在学云数据库的开发者这套思路都能直接抄作业。1.1 现象从节点到底不能到什么程度先交代事故现象。应用侧报错其实分三种第一种是完全连不上驱动直接抛Connection refused或者连接超时第二种是连得上但执行查询报错常见的有Lost connection、Read timed out第三种是连接看似正常但读流量全被甩到了主节点因为这个异常的只读节点已经被集群的读写分离地址自动摘除了。我那天遇到的是第一种加第三种目标只读节点彻底不可达读写分离地址把它踢出了节点池原本该它扛的读流量瞬间全部压到主节点上主节点的CPU和活跃会话数肉眼可见地往上飙。最尴尬的是这个从节点是我去年年底刚加的当时还跟人吹集群架构稳得很加个节点就多一重保障结果开年头一周就翻车属实丢人。1.2 我脑子里的第一反应为什么这个思路是错的出问题的节点是个小规格只读节点2核4G。我第一反应是网络抖动导致节点被标记异常准备直接重启节点了事。但真正让我警觉的是第一次重启之后的现象节点恢复了大概几分钟很快又挂回去监控曲线显示它根本撑不住。一个数据库节点如果只是偶发网络抖动或者进程僵死重启完通常能稳定很久而它在几分钟内再次崩溃说明背后一定有一个持续性的压力源在反复冲击它。也是从这时候起我才把重启大法压下去老老实实开始看数据。这里也提醒各位遇到从节点不可用先别急着动手把现象和数据看透了再操作否则你只是在给下一次崩溃倒计时。2. 先搞懂PolarDB的从节点到底是个啥角色2.1 计算存储分离架构下从节点和主节点共用同一份存储我第一次处理PolarDB从节点问题时差点栽在传统MySQL主从复制的老经验上以为从节点是主节点数据的另一个完整副本通过binlog把变更一点一点搬过去。这个直觉在PolarDB里是错的而且会直接带偏排查方向。PolarDB把计算和存储拆开了。主节点和所有只读节点连接的是同一套分布式存储引擎所有节点共享同一份数据文件。也就是说从节点不需要像传统主从那样把整份数据拷贝一份它更像一台有独立内存和CPU、但磁盘是共享的计算实例。主节点产生变更时把redo日志实时同步给只读节点只读节点通过回放redo日志来更新自己内存中的缓存页当缓存里没有对应数据页时它直接从共享存储读出来。这个差异的实际意义在于传统MySQL里从节点磁盘满了数据文件损坏binlog拉取失败这类问题在PolarDB的只读节点上基本不会出现因为数据文件是共享的导入速度也快得多。从节点不可用大概率是计算资源、回放链路、网络链路或者集群运维操作这几个方向出了问题。把排查重心放对位置比背一百条命令都有用。2.2 从节点的同步机制不是binlog而是redo回放PolarDB从节点同步主节点变更核心手段是回放redo日志。主节点每产生一段redo日志都会实时下发给从节点从节点收到后由后台回放线程解析并更新数据页。这个机制是物理复制比传统MySQL的逻辑复制效率高很多但它依然存在延迟控制台监控里那个复制延迟或日志回放延迟指的就是从节点落后主节点多少秒。回放延迟并不是线性增长的。一旦从节点所在规格的计算能力跟不上主节点写入量或者同时叠加了大量只读查询抢占CPU和内存redo回放就会越积越多延迟像滚雪球一样变大。延迟大了之后从节点读到的数据越来越旧业务对读到新数据的诉求满足不了严重时还会出现回放线程堆叠、内存压力暴涨最终整个节点被拖垮。这事在PolarDB里比传统MySQL更隐蔽。传统主从中从节点的SQL线程报错通常会在SHOW REPLICA STATUS里给你一个明确的Last_SQL_Error而PolarDB从节点挂掉时你看到的往往只是CPU 100%、连接拒绝、监控曲线一片飘红没有一个错误码直接告诉你我是因为回放跟不上才挂的。所以看监控时一定要把回放延迟指标单独拉出来盯。2.3 从节点不可用影响的不只是那一个节点别小看一个从节点挂了这件事。读写分离场景下读流量通常按照集群地址的分发策略打给各个只读节点一个节点被摘除后原本给它的那部分读流量会重新分给其他节点。最直接的影响是剩余节点压力上升、读延迟变长如果集群里只有这一个从节点那么所有读流量会直接打到主节点主节点的CPU、IO和连接数全被拖起来严重时连写链路也受影响。更闹心的是如果这个从节点还是你规划里的容灾节点它不可用意味着集群少了一层保护此时主节点再出状况你就只能干瞪眼。所以从节点不能用从来不只是一个节点的小事它牵动的是整个集群的容量、延迟和容灾水位排查优先级完全可以拉满。3. 完整排查实录从嘴硬到服软的四个小时3.1 第一步界定故障范围先把问题分类清楚接到故障后我做的第一件事不是打开日志而是先回答三个问题是所有从节点都不可用还是只有一个是彻底连不上还是能连上但延迟大是集群所有地址都受影响还是只有特定应用受影响这三个问题的答案决定了后续排查方向差异巨大所有从节点都不行大概率是主节点或共享存储链路出问题只有单个从节点不行重点就是这个节点自身的资源和状态。在我这次场景里答案是只有一个从节点彻底连不上其他从节点正常主节点健康可写。基于这个结论基本可以把主节点故障、共享存储故障两大块排除掉把火力集中在那个倒霉的只读节点上。这一步看着简单但最容易出错。很多人一上来就登录数据库执行各种命令结果查了半天才发现问题根本不在自己盯的那个节点上。先分类、再动手永远是排查的第一原则。3.2 第二步控制台监控拉满从一小时前的曲线找线索PolarDB是云托管服务没法直接ssh进数据库节点最直观的入口是控制台。我先打开集群详情页看那个从节点的状态确认显示异常然后拉起这个节点的监控曲线CPU使用率、内存使用率、连接数、活跃会话数、日志回放延迟。看到监控的第一眼冷汗就下来了CPU使用率在故障前半小时从30%一路冲到100%连接数同步飙升回放延迟从毫秒级涨到几十秒整个曲线就是教科书般的被打满。这里有个经验很关键监控曲线要看故障发生前一个小时的区间不要只看当前这一分钟。因为节点可能已经被折磨了好一阵才彻底趴下前面的曲线里写着真正的根因。如果你只看当前监控只能看到节点死了这一个结果啥也看不出来。我后来把故障前60分钟和故障后30分钟截成一图对比真相基本就浮出水面了。3.3 第三步能进SQL会话就把诊断命令跑一遍虽然从节点已经连不上外部应用我还是尝试通过内网地址用管理账号直连目标从节点。如果节点只是被连接风暴或高负载拖垮管理侧连接有时候还能抢进去一个会话这时候执行诊断SQL的价值最大如果彻底连不进去那就立刻走控制台重启止损等节点起来后再补采证据。连上之后我按顺序执行了下面几条命令SHOW STATUS LIKE Threads_connected; SHOW STATUS LIKE Threads_running; SHOW VARIABLES LIKE max_connections; SHOW REPLICA STATUS\G;Threads_connected接近甚至超过max_connections说明连接数打满了Threads_running如果非常高说明节点内部有大量SQL在并发执行。SHOW REPLICA STATUS里我重点看回放字段有没有报错、有没有不断重连的迹象。这次的结果是连接数已经顶到上限附近running线程数也很高基本坐实了流量把节点打满的方向。如果节点彻底连不上SQL会话进不去就只能靠控制台重启止损并等节点起来后立刻采集诊断数据。那种情况下事后复盘也只能从监控指标和日志倒推所以该看的监控一定要提前配好否则复盘全靠猜。3.4 第四步回到主节点揪出压垮从节点的源头从节点被打到100%源头一定是有大量流量或大量变更在冲击它。我带着这个假设回到主节点做了三件事。第一查活跃查询。用SHOW PROCESSLIST或者sys.schema_processlist看当前有没有大查询、慢查询在全表扫描尤其是那些路由到从节点的读SQL。第二查长事务和锁等待。通过information_schema.innodb_trx看有没有跑了几小时的长事务通过performance_schema的锁等待视图看有没有对象锁、元数据锁卡在中间。长事务不结束redo日志就会持续产生回放到从节点就是持续压力。第三看主节点写入量和redo生成速率。我在主节点上观察日志写入量级时发现故障前半小时恰好有一个批处理任务上线它把一批边缘节点设备上报的状态数据批量写入主节点写入强度远超平时。转换成redo日志之后这批压力全部压到了那个规格偏小的从节点头上——它既要回放高强度redo又要应付原本正常的读查询当场崩溃。这个发现让我哭笑不得引发事故的其实是一次平平无奇的批量写入任务而我那个从节点只有2核4G容量上早就埋了雷只是之前流量没到阈值一直岁月静好。3.5 止损操作摘流量、调资源、稳步恢复查明根因之后恢复操作要讲究顺序。我先在控制台把读写分离地址中针对这个异常节点的路由权重调成0先把流量从它身上摘干净防止它一恢复就被再次灌满然后对从节点执行重启让它以干净的内存状态重新开始。节点起来后我没有立刻把流量放回去而是先观察了五分钟监控CPU降到低水位、回放延迟回到个位数毫秒级、连接数正常才把路由权重逐步调回。同时联系业务侧暂停了那个批量写入任务等错峰后再跑。这一步很重要——如果你修好了节点却不控制流量源头重启只会是第二次崩溃的倒计时。这套组合拳下来从节点稳定恢复。整个排查过程花了大约四个小时起因是容量配置与流量增长不匹配。最讽刺的是我开头还信誓旦旦跟人说重启一下就好。4. 从节点不能用的典型根因与对症下药4.1 规格小、流量大从节点被现实教做人这是最常见的从节点不可用原因也是我这次踩的坑。平时从节点CPU 20%、内存40%一切祥和遇到大促、批量任务、报表跑批资源瞬间被打满。数据库节点的CPU如果长时间100%节点已经无法及时响应新的建连请求已建立的连接也开始超时业务侧看到的就是从节点连不上。对策其实清晰给只读节点的规格留足缓冲CPU日常压在60%以下重要节点开启监控告警大流量活动前做容量评估甚至压测。别心疼那点成本一个从节点挂了引发的连锁故障花的钱多得多。4.2 redo回放滞后延迟像滚雪球一样越滚越大从节点回放redo日志需要消耗CPU和内存。当主节点写入量突然变大或者只读节点同时承担了过重的查询负载时回放线程会被挤到一边redo堆积越来越多延迟从秒级涨到分钟级。这时候从节点虽然活着但业务读到的数据严重过期功能上等同于不可用。处理这类延迟首先看有没有长事务在持续产出大量redo其次看从节点CPU是不是已经被查询打满必要时可以调整只读节点的并行回放相关参数提高回放并行度。但这类参数调整最好在确认根因之后做别一上来就乱调否则可能加剧资源争抢让情况更糟。4.3 长事务与大DDL从节点面前的人为路障主节点上执行的大DDL比如给千万行级别的表加索引、改表结构在PolarDB物理复制体系下会同步产生大量redo从节点回放这些redo时如果与线上查询产生资源争抢很快就会进入性能悬崖。更麻烦的是DDL期间可能持有元数据锁把从节点上的查询全部阻塞住应用侧表现为从节点查询卡死、连接堆积。这种场景的排查要用到锁与事务视图。我通常先看information_schema.innodb_trx再查performance_schema的元数据锁相关视图确认是不是有DDL锁在作怪。日常预防上大表DDL尽量安排在低峰期或者分批推进避免让从节点同时承担回放DDL服务读流量的双重压力。4.4 连接配置不一致从节点被连接池一波带走很多团队的应用连接池配置写着主节点与只读节点一个参数比如最大连接数、初始化连接、每台机器的最大连接数全按主节点规格来估。结果从节点规格小默认的max_connections也可能比主节点低几十台应用的连接池一启动连接数瞬间把从节点打爆。连接风暴下的从节点其实CPU未必高就是连接数超限新连接直接被拒。排查时你会在监控里看到连接数贴着max_connections走平错误日志里全是Too many connections。对策是按节点规格分别评估连接池上限别拍脑袋一刀切同时在数据库侧关注连接数和活跃会话的告警。4.5 存储链路与IOPS瓶颈容易被忽略的幕后推手PolarDB的计算存储分离架构里从节点读数据页和回放redo都依赖底层共享存储链路。如果集群的存储IOPS、存储空间水位异常或者存储侧限流被触发从节点访问存储的通路就会变慢变卡表现同样是查询超时、连接异常。这类问题的排查特征是主节点和多个从节点同时出现性能下降但单看每个节点的CPU内存又都正常。这时候要把视线从节点移到存储侧检查存储监控、容量、IOPS与吞吐指标必要时联系服务方确认存储层是否有异常。我有一次遇到类似场景最后发现是共享存储的IOPS接近上限主节点和只读节点都在抢资源处理方式是优化高频查询、降低存储访问放大并适当给集群扩容。4.6 集群运维动作带来的短暂不可用以及伪故障从节点不可用不一定都是流量打满这类硬故障集群的小版本升级、主备切换、节点跨可用区调整也会带来短暂不可用。PolarDB在做这类运维操作时节点会经历重启或流量迁移如果应用侧没有配置合适的重连和退避策略这几十秒窗口就会被业务放大成数据库挂了。另外还有一种伪故障值得单独提一嘴应用侧开启了SSL加密连接但客户端的CA证书校验配置出了问题或者证书到期表现出来的也是从节点连不上。这种问题其实跟数据库节点本身没有关系换一个非SSL连接串一测就能识别。所以应用侧报障时别只盯着数据库也问问连接串、证书和依赖库版本有没有变化。5. 从节点问题排查速查表与自救脚本5.1 五条核心排查路径对照表现象特征优先排查方向常用入口单个从节点CPU 100%、连接被拒节点规格与流量控制台监控、SHOW STATUS连接数从节点延迟持续飙升redo回放能力复制延迟监控、SHOW REPLICA STATUS从节点查询全部卡住大DDL、锁等待innodb_trx、元数据锁视图所有节点同时变慢存储链路与IOPS存储监控、容量水位、IOPS指标运维窗口短暂不可用升级、切换控制台事件与维护通知这张表是我后来自己总结的遇到问题先对号入座能省不少时间。它不一定覆盖所有情况但覆盖了我自己这两年处理PolarDB从节点问题里至少八成场景。5.2 一套可以复用的诊断SQL和检查单我把这次排查用到的SQL整理成固定流程每次遇到从节点异常就按顺序执行-- 1. 看节点连接与运行状态 SHOW GLOBAL STATUS LIKE Threads_connected; SHOW GLOBAL STATUS LIKE Threads_running; SHOW VARIABLES LIKE max_connections; -- 2. 看复制与回放状态 SHOW REPLICA STATUS\G; -- 3. 看会话列表揪出大查询和阻塞会话 SELECT * FROM sys.schema_processlist WHERE command ! Sleep ORDER BY time DESC; -- 4. 看长事务 SELECT * FROM information_schema.innodb_trx ORDER BY trx_started LIMIT 20;这四组SQL基本能覆盖连接打满、回放异常、大查询、长事务四类最常见的从节点故障。遇到锁等待场景再补查performance_schema里的锁等待视图或者直接用DMS的锁分析功能。不要背太多命令把这四类看熟大部分问题都能定位。Linux侧虽然没法ssh到云数据库节点但如果你在自建环境或者混合架构里也用了MySQL/PolarDB兼容实例那套top、vmstat、pidstat观察线程和上下文切换的方法依然适用。云上就看控制台监控自己部署的就看系统指标原理是一样的。5.3 该重启还是该重建别在止损时犹犹豫豫重启只读节点是止损手段不是恢复手段。如果节点只是被瞬时流量打满控制台重启后给它摘掉流量、观察几分钟往往能恢复如果节点的内存状态已经异常监控显示频繁重启或者重启后依然在几分钟内再次被打挂那就说明根因没解决单纯重启只会浪费时间。更极端的情况比如某个只读节点因为历史原因和集群其他节点状态不一致、反复异常可以考虑直接删掉该节点再通过控制台重新添加一个只读节点。PolarDB添加只读节点相对快速因为有共享存储兜底新节点不需要重新拷贝全量数据。但注意删除节点会把该节点上的所有连接断掉要选业务低峰操作并确认当前集群容量足够支撑流量转移。6. 收尾这次丢人换来的几条铁律6.1 从节点不是廉价劳动力故障复盘会上我给自己总结的第一条铁律是从节点的CPU、内存、连接数要和主节点一样有预算、有监控、有告警。我按主节点规格的六折给从节点开资源结果这个省法省出了大麻烦。容量方案上建议从节点CPU水线控制在60%以下连接数不超过上限的70%回放延迟告警阈值不要等涨到几十秒才拉响而是超过10秒就预警。6.2 先看流量源头别急着甩锅网络第二条是遇到从节点问题先把监控曲线拉长看流量源头别急着甩锅网络。数据库节点不会平白无故挂掉尤其是云托管实例网络抖动、底层硬件故障的概率远低于你预想。把控制台监控从当前一分钟拉到故障前一小时你大概率能看到一个清晰的量变到质变过程。6.3 恢复操作要有顺序摘流量、重启、观察、放流量第三条也是我这次最有体感的教训恢复操作要有顺序。摘流量、重启、观察、逐步放回流量这四个动作的顺序不能乱。我见过太多人修完节点立刻把流量全放回去结果节点刚起来又被同一波流量压死最后反过来怪数据库不稳定。这不是数据库的锅是操作节奏的问题。如果你也在用PolarDB我建议你这次回去就把只读节点的监控告警补齐把上面的诊断SQL存进运维脚本库再检查一遍应用连接池的重连配置。这些事在风平浪静的时候做成本低得很等从节点真挂了再做你就要陪它熬夜了。至少我是这么过来的而且我保证那种开年第一天就当众翻车的滋味你不想尝第二遍。
返回列表