Skip to content

第3章 数据库故障排查路径 ​

对应简历:技能第 4 条「熟悉 Nginx、Tomcat、Redis、MySQL、Vastbase 等常见中间件与数据库的部署和日志分析,熟悉登录失败、连接超时、服务异常等典型问题的排查路径」;项目一 P1-1「Vastbase 一主一备数据库集群的部署与验收」;项目三 P3-3「配套云数据库、消息队列…的配置管理」。 支持版定位:本章不考"调优大师",考的是接到"数据库连不上/变慢/报错"类报障时,你按什么路径查、每个动作的证据怎么读、查到哪一步算定位完成、定位完交给谁。 五条典型路径每条独立成节背熟,集群运维压缩为两节。 华为篇引用:Vastbase 内核与高可用组件深挖详见华为篇 04-openGauss 与 Vastbase 数据库。

3.1 数据库排查总纲:先分层,再下钻 【必背】 ​

标准回答:数据库类报障我有一个总纲:"先分层定位,再针对性下钻"。 第一层是网络与端口——客户端能不能到达数据库:本机 telnet 数据库 IP 端口,不通就是网络、防火墙、白名单、监听问题,跟数据库本身无关;通才有资格谈数据库层。 第二层是认证——能建 TCP 连接但登录失败,报 Access denied 这类,方向是账号密码、host 白名单、账号锁定,是权限体系的问题。 第三层是服务能力——连得上但报 too many connections 或反应极慢,方向是连接数、慢 SQL、锁等待、资源瓶颈,是负载和性能问题。 第四层是数据与日志——以上都正常但业务报错,看数据库错误日志和应用日志的具体报错,可能是表锁、主备切换、磁盘 IO 这类深层问题。

分层的好处是"报障先收敛":用户说"数据库坏了",我十分钟内用 telnet、登录测试、processlist 三个动作就能回答"坏在哪一层、影响面多大、谁负责处理"——是网络问题转网络组、是账号问题我直接处理、是性能问题走慢查询链路。 支持岗的价值就在这个收敛速度上,而不是一上来就扎进某个细节。

追问链:

  • 追问1:报障时怎么快速确认影响面? → 答:三个动作定影响面:第一看报障范围——一个用户还是所有用户、一个应用还是多个应用,问一句"只有你们系统受影响吗"经常能直接分层(单应用问题多在应用配置,全站问题多在数据库或网络);第二看数据库状态——processlist 会话数、有无大量锁等待、错误日志有没有新报错;第三看有没有近期变更——凌晨有没有发布、有没有改过账号权限和安全组。支持岗要养成"先问范围再动手"的习惯,影响面决定响应级别:单点问题按普通工单走,全站不可访问直接按应急升级。
  • 追问2:怎么判断是"数据库的问题"还是"应用的问题"? → 答:用替代证据分离变量:同一数据库,用一个已知正常的客户端(命令行 mysql/vsql 或监控大盘)去连——能连且查询正常,数据库无罪,问题在应用侧(连接串错、连接池耗尽、SQL 写错);命令行也连不上或同样慢,才是数据库侧问题。再配合时间线:应用刚发过版本就出问题,先怀疑应用变更;数据库刚做过切换或升级,先查数据库。这个"第三方客户端对照法"是我排数据库工单的第一动作,能把扯皮空间消掉大半。
  • 追问3:数据库错误日志应该重点看什么? → 答:三样:报错关键字(Access denied、too many connections、lock wait timeout、disk full 各对应一条已知路径)、时间分布(持续刷还是某时刻突增,突增时间点和变更记录对照)、伴随现象(有没有重启记录、主备切换记录、IO 报错)。我的习惯是先 tail 最近 100 行加 grep 关键字统计,五分钟内形成"错误类型 + 频率 + 时间特征"的摘要——这个摘要既是排查地图,也是要写进工单的证据。支持岗看日志的目标不是读完,是提炼出"下一步查哪里"。
  • 追问4(深挖):拿到一台陌生的数据库主机,前三条命令是什么? → 答:我的"三分钟摸底"固定动作:ss -lntp | grep -E "3306|5432" 看数据库监听和端口,确认服务活着、监听地址对不对;tail -n 100 错误日志(error.log 或 journalctl -u mysqld)看最近有没有异常刷屏;df -h 看磁盘水位——数据库类故障的一半和磁盘有关。三条命令覆盖"进程、日志、资源"三个最基本的事实,之后无论往哪个方向查都有底。支持岗接手陌生环境,先建立基本事实再谈分析,顺序不能反。

关联话术:"这个总纲是我在银行驻场时定下来的排查口径:客户报'数据库有问题',我按'端口 → 认证 → 服务能力 → 日志'四层走,每层有明确的证据和出口——两年里数据库类工单没有出现过'查了半天不知道该转给谁'的情况。 分层不是为了炫技,是为了让每个报障都有确定的下一站。"

实操模板(四层定位三连,背熟):

bash
telnet <db-ip> 3306                  # 1 网络与端口层
mysql -u<user> -p -h<db-ip> -e "select 1;"   # 2 认证层(换已知正常客户端)
mysql -e "show full processlist;" | head -20  # 3 服务能力层
tail -n 100 /var/log/mysql/error.log          # 4 日志层

3.2 路径一:登录失败(Access denied)【必背】 ​

标准回答:登录失败的标准排查路径五步。 第一步看报错原文:Access denied for user 'xxx'@'xx.xxx.xx.xxx' 这个报错本身就是证据——它包含了账号和来源 IP,先确认账号名对不对,再看来源 IP 是不是预期的(应用服务器 IP 变了会导致白名单匹配不上)。 第二步验证密码:用同一账号在命令行手动登录测试,能登就是应用侧连接串或密码配置问题,不能登继续往下。 第三步查账号存在性和主机白名单:select user,host from mysql.user; 看 'user'@'%' 和 'user'@'10.0.x.%' 是两条不同记录,应用来源不在 host 匹配范围内就报 Access denied——这是最高频的形态之一,尤其是应用迁移或换了出口 IP 之后。 第四步查账号状态:密码是否过期、账号是否被锁(password_expired、locked 字段),金融环境常有密码定期轮换策略,到期不通知就是一批应用同时登不上。 第五步查插件兼容:MySQL 8.0 默认 caching_sha2_password,老版本客户端和驱动连不上报认证错误,建用户时显式指定 mysql_native_password 解决。

整条路径的设计逻辑是"从报错原文出发、由外向内":报错信息里的每一个字段都是线索,先读报错再动手,比背一堆可能原因有效得多。 我在银行现场处理过多次登录类工单,大多落在"host 白名单没包含新来源"和"密码过期"两个形态上。

追问链:

  • 追问1:Access denied 报错里 @'xx.xxx.xx.xxx' 的 IP 不是应用服务器的 IP? → 答:这说明连接经过了代理或 NAT,来源被改写了。两个方向:一是应用前面有负载均衡或数据库代理,数据库看到的是代理 IP——host 白名单要么放行代理 IP,要么让代理透传真实来源;二是应用走了跳板或容器网络,出口 IP 和预期不同。处理时不能盲目把白名单放大到 %,要精确加实际来源——金融环境安全审计不允许宽白名单。这个细节能讲出来,说明真处理过多层网络下的数据库连接问题。
  • 追问2:Vastbase 的登录失败排查和 MySQL 有什么不同? → 答:思路同构、工具不同。PG 系客户端是 vsql,报错形态是 FATAL: password authentication failed 或 no pg_hba.conf entry for host——后者就是 PG 体系的"白名单"文件 /var/lib/…/pg_hba.conf,按"来源地址 + 数据库 + 用户"逐行匹配,应用来源没配进去就拒绝,改完要 reload。我在银行部署 Vastbase 时配过 pg_hba 和账号授权,验收时专门做过"错误密码、错误来源、正常登录"三类测试——两个体系把"认证三要素"(账号、密码、来源)讲通了就是一通百通,这是支持岗跨数据库迁移能力的关键。
  • 追问3:密码刚刚改过,应用批量登录失败,怎么办? → 答:这是"变更伴生故障",处理顺序:先应急——把密码回滚或同步到应用配置,恢复业务优先;再补漏——排查还有哪些应用/定时任务/监控探针在用旧密码,通常不止一个地方存着密码,漏一处就报一处障;最后立规矩——密码轮换要提前通知、建同步清单、变更窗口内逐个验证,我们后来把"密码变更 checklist"写进了 SOP。这类问题的教训是:密码不是一个人的属性,是所有使用方的契约,改它就是一次变更,要走变更流程。

关联话术:"登录失败是支持岗最高频的数据库工单,我的价值是把'账号密码错了'这种直觉判断升级成五步路径——银行驻场两年,这类工单我基本十分钟内给结论;处理过的每一类形态(白名单、密码过期、认证插件)我都写进了 FAQ,后来这类问题客户自助就能解决大半。 "

3.3 路径二:连接超时(连不上)【必背】 ​

标准回答:连接超时和登录失败是两种不同的失败:超时是 TCP 层建不起连接(等了很久没响应),登录失败是连接建成了但认证拒绝——先分清这两者,方向就分开了。 连接超时我的排查路径五步:第一步 telnet 数据库 IP 端口复现,并记录现象(立刻拒绝 connection refused、还是长时间挂起 timeout,两种现象含义不同——refused 说明网络可达但端口没人听或有防火墙 REJECT,timeout 多半是包被 DROP 或链路不通)。 第二步查数据库本体:登录数据库主机 ss -lntp | grep 3306 确认 mysqld 在监听、监听地址是 0.0.0.0 而不是只听 127.0.0.1——只听本地是超高频坑,本机测试正常、应用连不上。 第三步查路径上的拦截:防火墙 iptables/firewalld 规则、云上安全组(云环境第一嫌疑人)、网络 ACL——最近有没有变更,"昨天还好今天不通"八成是变更引起。 第四步查资源层:数据库连接数是否已满(连接数满的新连接也可能表现为超时或拒绝)、数据库主机负载和磁盘状态。 第五步看应用连接池配置:超时时间设得太短、池参数不合理也会把"偶尔慢"放大成"频繁超时"。

这条路径的关键认知是:连接超时多数不是数据库"坏了",而是"到不了"——先证明通路,再怀疑服务。 我在两个项目处理连接类工单,telnet 加 ss 两个动作就能把一半问题定位在监听或安全组上。

追问链:

  • 追问1:telnet 端口通的,应用还是报连接超时? → 答:这说明网络和监听都正常,超时发生在协议层或应用层。三个方向:一是连接数或线程池满——telnet 能完成 TCP 握手,但 MySQL 层面新连接被排队或拒绝,看 processlist 和 Threads_connected 对照 max_connections;二是应用侧超时参数太短——数据库偶尔慢一下,应用连接超时设 1 秒就把它放大成频繁超时,对比应用超时配置和数据库实际响应时间;三是 DNS 或连接串问题——应用配置里数据库地址是域名,DNS 抖动会间歇性超时,改成 IP 或可靠解析验证。telnet 通是重要的排除证据,它把问题压缩到"数据库服务能力"和"应用配置"两个方向。
  • 追问2:云上数据库突然连不上,第一查什么? → 答:云环境第一嫌疑人是配置变更而不是硬件:先查安全组规则有没有近期变更记录(云控制台有操作审计),再查白名单/访问控制策略,然后查实例状态——有没有在主备切换、规格变更、重启中。云数据库的主备切换会有几十秒的连接闪断,应用侧要靠连接池重连扛过去;如果应用连接串写死的是主库 IP 而不是高可用地址,切换后就永远连不上——这个坑我在交付应用时专门验证过:连接串必须指向带自动切换能力的接入地址。云上排障顺序"配置 → 实例状态 → 网络"和传统环境"网络 → 服务"是反的,这是我双云经验的实感。
  • 追问3:connection refused 和 timeout 的区别怎么给用户解释? → 答:refused 是"到了对方门口,对方明确说不开门"——机器在、服务没起或端口没开,去查服务监听;timeout 是"连门都找不到"——包在半路被丢或机器不可达,去查网络、防火墙、IP 是否正确。给用户解释用这个比喻秒懂,也直接决定了排查方向完全不同。支持岗的沟通价值就在这里:把技术现象翻译成用户能理解、能配合的语言,报障人还能反过来帮你确认信息("你们应用是不是刚换了部署机器")。
  • 追问4:现场没有 telnet/nc 命令怎么办? → 答:三个替代:curl -v telnet://IP:端口 用 curl 的 telnet 协议探测——连接成功会挂住等待、失败立刻报错,有 curl 就有办法;Windows PowerShell 用 Test-NetConnection IP -Port 端口;实在不行装包 yum install -y telnet 或 apt install -y nc(装包属于环境变更,做完要记录)。工具缺失不该成为排障障碍,"一个 curl 走天下"是我给新人培训的口诀,因为 curl 几乎哪台机器都有。

关联话术:"连接类工单我给客户总结过一个口诀:'先 telnet、再看监听、后查安全组'——三个动作两分钟,八成连接问题当场定位;剩下两成再进数据库层。 驻场时我把口诀贴在 FAQ 第一条,后来客户报障的开场白都变成'我们 telnet 过了,端口通的'——把排查方法交给客户,工单质量都会变高。 "

实操模板(连接超时五步,背熟):

bash
telnet <db-ip> 3306                     # 1 复现:refused 还是 timeout
ss -lntp | grep 3306                    # 2 数据库监听:在听?听哪个地址?
firewall-cmd --list-ports; iptables -L -n | grep 3306   # 3 本机防火墙
# 云环境:控制台查安全组规则与变更记录
mysql -e "show status like 'Threads_connected'; show variables like 'max_connections';"  # 4 连接数
tail -n 50 /var/log/mysql/error.log     # 5 数据库错误日志

3.4 路径三:数据库变慢的初步定位 【必背】 ​

标准回答:"数据库变慢"是模糊报障,我的初步定位走四步。 第一步看会话在干什么:show full processlist——大量 Command 是 Query 且 Time 很大的,是慢 SQL 把连接占住,抓 Time 最大的几条去分析;大量 Sleep 且 Time 大的,是连接池不释放,属于应用侧连接管理问题,两类问题的归属完全不同。 第二步看锁等待:show engine innodb status 里的锁段,或查 information_schema 的锁相关表——锁等待的典型现象是"一批会话都在等同一行/同一表",要找到持锁的源头会话,评估 kill 或推动应用提交/回滚。 第三步看资源层:数据库主机 top 看 CPU、iostat 看磁盘 %util 和 await——磁盘 util 打满是典型的"慢在 IO",常见元凶是日志暴涨或备份任务;内存看有没有换页。 第四步配合慢查询日志:slow_query_log 开着的话按总耗时取 TOP SQL,explain 看执行计划有没有全表扫描——初步定位阶段不追求把 SQL 优化做完,但要把"哪几条 SQL 是大头"指出来。

支持岗的定位产出物是一份"变慢归因":慢在锁、慢在 SQL、慢在资源、慢在应用连接管理,四个结论对应四个责任人(DBA/开发/运维/应用负责人)——定位准了,转派才不扯皮。

追问链:

  • 追问1:SQL 昨天快今天突然慢,什么原因? → 答:三个高频原因:统计信息过旧,优化器基于过期统计选错索引,analyze table 刷新;数据量增长跨过临界点,原执行计划的成本结构变了;缓存层失效,原来命中缓存的查询直接打到库。排查动作是拿这条 SQL 跑 explain 和它快的时候对比:计划变了查统计信息,计划没变查数据量和缓存。还有一个支持岗视角的原因要主动提:昨晚有没有变更——发版改了 SQL、改了参数、数据批量导入了,"突然变慢"和变更时间点对齐是第一直觉。
  • 追问2:锁等待怎么定位到源头会话? → 答:先看谁在等:select * from information_schema.innodb_trx 按事务开始时间排序,长时间 running 的事务就是嫌疑;再看谁持锁——innodb_lock_waits 视图(或 sys.innodb_lock_waits)直接给出 blocking_pid。处理前评估:持锁会话是不是在做大事务、kill 会不会导致回滚放大,小会话直接 kill、大事务推动业务方确认后处理。支持岗的纪律是"kill 是变更动作"——评估影响、必要时和业务确认再动手,且把动作记录进工单。定位到 blocking_pid 这一步是纯技术,决定 kill 与否是支持判断力,两段都要会讲。
  • 追问4:怎么给非技术的业务同事解释"数据库在忙"? → 答:用"排队"比喻:数据库像只有一个窗口的柜台,现在队伍(会话)太长、前面有人办的事太大(慢 SQL),所以谁都快不起来;我们正在做的是看队伍里谁占着窗口不办事(空闲连接)、谁办事太慢(慢查询)。比喻之后必须跟时间承诺——"X 点前我给您一次进展"。解释让人听懂、跟进让人安心,两件都做到,业务同事才会从"催"变成"配合",这是支持岗的沟通基本功。
  • 追问3:processlist 里 Sleep 多正常吗? → 答:适量正常(连接池保留空闲连接是设计行为),异常的判断标准是"Sleep 且 Time 很大"的堆积——连接借了不还,缓慢耗尽 max_connections。处理方向在应用侧:连接池的 maxLifetime、idle 超时配置,数据库侧可调 wait_timeout 让服务端回收,但根因治理是应用连接池参数。应急时批量 kill 空闲长连接:用 information_schema 拼出 select concat('kill ',id,';') from information_schema.processlist where command='Sleep' and time>600; 再执行——"用 SQL 生成 SQL"的批量手法,是实战感的体现。

关联话术:"变慢归因是我在银行驻场时建立的标准产出:每个变慢工单,我给客户的结论永远是'慢在哪一类、证据是什么、建议找谁处理'——哪怕是转给华为二线的问题,我也要先完成归因再转,转派质量高客户的信任就高。 这套四步法我也能平移到 Redis 和中间件:先看连接与会话、再看锁与阻塞、再看资源、最后看日志。"

实操模板(变慢四步,背熟):

bash
mysql -e "show full processlist;" | awk '$5>10'        # 1 长会话分型(Query/Sleep)
mysql -e "select * from information_schema.innodb_trx\G" | head -30   # 2 事务与锁
top -bn1 | head -5; iostat -x 1 3                      # 3 主机 CPU/IO
mysqldumpslow -s t -t 5 /var/log/mysql/slow.log        # 4 慢SQL TOP5

3.5 路径四:账号与权限问题 【必背】 ​

标准回答:账号权限类问题我的处理路径四步。 第一步搞清需求:是"新应用要接入"(要新建账号授权)、"报权限拒绝"(现有账号权限不足)、还是"权限要回收"(人员变动、下线系统)——三类动作流程不同,先归类再动手。 第二步核对现状:show grants for 'user'@'host'; 看现有授权,select user,host from mysql.user; 看账号清单——很多"权限不够"其实是"连的账号不对"或"host 不匹配",先看事实再谈授权。 第三步最小化授权:按需 grant,业务账号绝不给 ALL PRIVILEGES、不给 DROP/GRANT OPTION 这类高危权限,只放行业务需要的库表和操作;host 精确到应用网段而不是 %。 第四步验证与留痕:授权后用业务账号实际登录验证关键操作(能读写目标表、不能越权访问别的库),全过程记录进工单——谁申请、授权内容、谁批准、验证结果。

权限的配套问题是回收:人员离职、应用下线后的账号处理。 我的口径是"权限有生命周期":建账号当天就登记用途和负责人,定期审计清理休眠账号,回收比发放更需要纪律——银行环境的安全审计就查休眠账号和宽权限,这套纪律我是被客户基线训练出来的。

追问链:

  • 追问1:业务账号应该怎么设计授权? → 答:按"应用专用账号 + 最小权限 + 精确来源"三原则:每个应用独立账号不共用——出了问题能定位、回收不影响别人;权限只给目标库的必要操作(通常 SELECT/INSERT/UPDATE/DELETE,不给 DDL 权限,结构变更走工单由 DBA 执行);host 限定应用所在网段。监控和备份另立账号:监控只读、备份账号带 RELOAD 等必要权限也只读为主。这套设计我在项目二云数据库的账号规划里实际执行过,应用、监控、备份三套账号分立,安全审计直接通过。
  • 追问2:用户说"我连的是 root 为什么还报权限不足"? → 答:两种可能:一是"root"不是真 root——应用配置里写着 root 但实际是受限账号,select current_user(); 看真实身份;二是 root 也分来源——'root'@'localhost' 和 'root'@'%' 是两个账号、权限可以完全不同,远程连进来匹配的可能是权限受限的那条。另外 MySQL 8.0 权限有动态权限和角色差异,个别操作还需要全局权限。排查动作就是"先证身份、再看 grants、后测操作"三步——报"权限不足"时最忌讳直接加权限,先搞清楚是谁在要、要什么、为什么没有。
  • 追问3:账号权限管理怎么在支持工作里讲出体系感? → 答:我把管理动作拆成三个环节讲:入口——新账号走申请审批,登记用途、负责人、权限范围;在途——定期审计:休眠账号(90 天未登录)、宽权限账号(ALL 或带 GRANT)、离职人员账号,三个清单季度过一遍;出口——应用下线和人员变动的回收流程,回收前先禁用观察一段时间再删除。配合这套制度我维护过公司的 AI 平台账号与 API 密钥管理(对应简历项目二职责:统一管理账号、API 密钥与权限),云上 RAM/子账号的最小权限策略也配置过——"数据库权限、云账号、应用账号是同一套治理思想的不同实例",这样答有体系也有实例。

关联话术:"权限工单最容易变成'随手 grant',我在银行环境学到的是反方向:每个授权都是安全审计项,最小化、可追溯、有生命周期。 后来我管公司 AI 平台的 API 密钥和账号权限(项目二职责原文),用的就是同一套入口-在途-出口的方法——支持岗做权限管理,管的是'权限的账本',不是'授权的动作'。 "

3.6 路径五:连接数满(too many connections)【必背】 ​

标准回答:too many connections 的处理路径四步。 第一步看会话构成:show full processlist 分型——大量 Sleep 且 Time 大是连接池泄漏或池参数过大,大量 Query 且 Time 大是慢 SQL 把连接占住,两类根因不同处理也不同;同时 show status like 'Threads_connected' 对照 max_connections 看水位。 第二步应急止血:按条件批量 kill 空闲长连接(Sleep 超 10 分钟的先清),让业务先恢复——"用 SQL 生成 SQL"批量执行;如果是慢 SQL 占用,kill 长事务会话止血并同步评估影响。 第三步评估参数:确认 OS 层文件句柄限制没卡住——max_connections 配了 3000 实际只能到 214 的经典坑,就是因为 OS 的 open files 先到顶,要同步调 systemd 的 LimitNOFILE;max_connections 调大要核算内存(每连接有线程栈和缓冲开销),不能无脑放大。 第四步根因治理:连接池泄漏推动开发修(池只借不还、异常路径不归还),慢 SQL 走优化链路,长期方案给连接数配监控告警(80% 预警)并审视连接池的 maxPoolSize 与数据库容量是否匹配。

这条路径的核心判断是"连接是被谁吃掉的":被空闲连接吃掉是应用配置问题、被慢 SQL 吃掉是 SQL 质量问题、被泄漏吃掉是代码 bug——分型对了,每一类都有确定的责任人和解法。

追问链:

  • 追问1:max_connections 调到多大合适?能直接调到 10000 吗? → 答:不能拍脑袋。上限受三个约束:OS 文件句柄(ulimit 和 systemd LimitNOFILE 必须配套,否则配了不生效)、内存(每连接线程栈加排序缓冲,几千连接就是几个 G 的隐性开销)、实际并发需求(多数业务活跃并发远低于配置值)。我的实践参照是 Vastbase 调优:默认 max_connections 100 太小,我们调到 10000 时同时开启了线程池 enable_thread_pool=on——openGauss 系的线程池模型让高连接数开销可控,这正是开启它的原因。MySQL 没有线程池的话,几千以上就要谨慎核算内存并观察 CPU 上下文切换。给数字必须带理由,这是支持岗答参数题的正确姿势。
  • 追问2:连接数告警频繁触发但业务没报障,怎么处理? → 答:这是"容量 vs 配置"的匹配问题,分三步:先看波动特征——业务高峰的规律性爬升是容量规划问题,评估是否调大水位;持续缓慢上涨不回落是泄漏,抓连接按来源 IP 和用户分型,定位到哪个应用在漏,推动修连接池;瞬间尖峰是流量事件(定时任务集中跑、重试风暴),看时间点对齐什么变更或任务。我的产出是"分型报告"给应用负责人——告警不是用来消音的,是用来发现趋势的;支持岗要把告警翻译成"哪个应用、什么形态、建议动作",这才算处理完。
  • 追问3:应用连接池应该配多大? → 答:经验公式从"核数 × 2"量级起配再压测校准,而不是想当然的大——连接池过大反而造成数据库上下文切换开销和锁竞争,吞吐下降。配套参数一起看:maxLifetime 略小于数据库 wait_timeout 防止使用已被服务端关闭的连接、空闲超时回收、获取连接超时给应用一个快速失败的机会。支持岗答这题的价值是讲清"池不是越大越好 + 三个配套参数的因果",因为连接数满的根因经常就是池配置和数据库容量不匹配——这是开发与运维的交界地带,正是支持岗能提供跨视角价值的地方。

关联话术:"连接数满是我在两个项目都处理过的形态:银行现场是慢 SQL 把连接占满、业务批量报错,我按'分型 → 批量 kill 止血 → 归因转派'处理并当天闭环;项目二云数据库连接数上限我在控制台按业务并发评估配置并加了告警。 '先止血、再归因、后治理'的三段动作,是支持岗处理资源耗尽类故障的通用模板。"

3.7 Redis 常见问题排查(连不上/变慢/内存)【理解】 ​

标准回答:Redis 类报障我按三类讲排查入口。 连不上:先 telnet 6379 确认网络与监听(和 MySQL 同一层),再确认 bind 配置和保护模式——默认 bind 127.0.0.1 加 protected-mode yes 会让远程连不上,我在银行部署 Redis 5.0.3 时 bind 0.0.0.0 加 requirepass 是标准配置;有密码验证的报 NOAUTH 就是应用没带密码或密码错。 变慢:先看慢命令日志 slowlog get 10——keys *、大 key 操作、hgetall 全量拉取这类 O(N) 命令是常客,生产严禁 keys *,遍历用 scan;再看内存与持久化——fork 时机的大实例 bgsave 会造成毫秒到百毫秒停顿,AOF 重写同理。 内存告急:info memory 看 used_memory_human 和 mem_fragmentation_ratio(1.0–1.5 正常,持续大于 1.5 碎片明显,低于 1 说明用了 swap 要立刻警惕),配合 maxmemory 淘汰策略确认——缓存定位选 allkeys-lru。

我的角色口径是"缓存中间件的一线支持":银行项目的 Redis 是源码编译部署、我做了参数配置和巡检(info 命令族每天看内存、连接数、主从偏移);移动云项目是云 Redis 双机热备,我看控制台指标并处理告警。 深挖到内核层我如实按"理解到机制层"收口。

追问链:

  • 追问1:Redis 突然变慢甚至卡住,第一反应查什么? → 答:按可能性排序:有人执行了 keys * 或对大 key 的阻塞操作——slowlog get 直接给答案,client list 也能看到当前在执行的命令;内存到 maxmemory 且策略是 noeviction,写操作开始报错或抖动;bgsave/AOF 重写的 fork 停顿配合持久化 IO 打满磁盘——info persistence 和 iostat 交叉看。支持岗的动作是"slowlog + info 两个命令先打一轮",多数卡顿在这两步现形。我在银行巡检时把 slowlog 检查列为 Redis 的固定项,抓到过开发用 keys 做统计的案例,推动改成了 scan。
  • 追问3:Redis 连接数偏高,怎么看是谁连的? → 答:client list 输出里有每个客户端的 addr(来源 IP:端口)、name、age(连接时长)、idle(空闲时长),按 addr 的 IP 前缀分型就能看出哪个应用占了多少连接;OS 层用 ss -ant state established "( dport = :6379 )" | awk '{print $4}' | cut -d: -f1 | sort | uniq -c 按来源统计交叉验证。两个视角对照后,"哪台机器的哪个应用在吃连接"就有了双证据,推动对方改连接池参数时口径很硬。
  • 追问2:怎么发现大 key、大 key 有什么危害? → 答:发现用 redis-cli --bigkeys 采样扫描(低峰跑,不影响线上),经验阈值 String 超 10KB、集合元素超 5000 就要关注。危害来自 Redis 单线程模型:对大 key 的删除和序列化会长时间阻塞主线程,整个实例卡顿;网络传输大 value 挤占带宽;主从同步被拖慢。治理三招:拆分(大 hash 按字段拆小 key)、异步删除(UNLINK 代替 DEL)、压缩 value。"单线程的代价就是任何慢操作都是全局慢"——把这句因果讲出来,这题就不是背名词。

关联话术:"Redis 我能按'部署过、配置过、巡检过'三层讲:银行项目源码编译部署加参数配置是实打实的经历;巡检清单(info memory/replication/clients、slowlog)是我每天的功课;云 Redis 的指标监控和告警处理是项目二的日常。 深挖内核我的兜底话术是'机制层理解、内核细节会后补'——缓存中间件的支持定位讲清楚,比硬撑专家人设稳得多。"

实操模板(Redis 排查三连):

bash
redis-cli -h <ip> -a '****' info memory | egrep 'used_memory_human|mem_fragmentation_ratio'
redis-cli -h <ip> -a '****' slowlog get 10
redis-cli -h <ip> -a '****' info clients | egrep 'connected_clients|rejected_connections'
redis-cli -h <ip> -a '****' --bigkeys | head -15     # 低峰跑

3.8 Vastbase 一主一备运维要点(集群压缩节)【理解】 ​

标准回答:Vastbase 是我在银行项目亲手部署验收的一主一备集群,运维口径讲三层。 组件层:HAS 是高可用组件负责监控主备和自动切换,DCS 是分布式配置存储(角色类似 etcd 的一致性底座),两者都是 systemd 托管——systemctl enable has dcs 是部署标配,日常巡检先查两个组件 active 状态。 状态层:hasctl list 看集群主备角色是否正确,会话层用 select * from pg_stat_activity 对应 MySQL 的 processlist,长期 idle in transaction 的会话要重点抓(阻碍 vacuum 回收),终结会话用 pg_terminate_backend(pid)。 变更层:license 更换要滚动重启 has——先节点 A、就绪后再节点 B,两台同时重启 DCS 失去多数派有双主风险;参数变更走 hasctl edit-config,我实际调过 max_connections 100→10000 和 enable_thread_pool=on。

支持场景里 Vastbase 类工单的定位逻辑和 3.1 总纲完全一致:端口(vsql 连接测试)→ 认证(pg_hba.conf)→ 服务能力(pg_stat_activity)→ 日志,四层走完给归因。 产品深挖(内核、WAL 机制)详见华为篇 04 章,我面试的口径是"部署过、调过参数、验过切换,内核层按理解讲"。

追问链:

  • 追问1:Vastbase 主备切换后应用连不上,怎么排查? → 答:标准三层:第一查切换是否完成——hasctl list 看主备角色和 VIP 是否漂到新主,切换没完成或脑裂先恢复集群状态;第二查应用连接串——是否指向 VIP/高可用地址而不是写死原主库 IP,写死 IP 的应用切换后必挂,这是我在验收时专门验证过的项(模拟主库故障看应用无感恢复);第三查残留连接——切换瞬间的旧连接会失效,应用连接池要能自动重建,池参数不合理会表现为"切换成功但应用报错不断",重启应用连接池即恢复。这套"查集群 → 查入口 → 查应用池"的顺序,是数据库高可用工单的通用路径,MySQL 主从、云 RDS 切换同样适用。
  • 追问2:PG 系和 MySQL 的运维差异,支持岗角度讲三点? → 答:第一会话查看:pg_stat_activity 对 show processlist,列结构不同但排查逻辑相同,PG 要额外盯 idle in transaction;第二认证配置:pg_hba.conf 是文件级白名单,MySQL 是 mysql.user 的 host 字段——前者改文件要 reload,后者是 SQL 操作;第三连接模型:openGauss/Vastbase 线程池模型高连接开销小(我开 enable_thread_pool 的原因),MySQL 每连接一线程要盯连接数和内存。三点差异都是"同一排查动作、不同命令形态"——跨数据库的支持能力本质是把排查方法学固化,命令是查得到的,方法是内化的。

关联话术:"Vastbase 是我简历上最实的国产数据库经历:一主一备部署、参数调优、license 滚动重启、切换演练全链路做过——支持岗面试官问'国产库用过吗',我的答案是'装过、调过、验收过',细节指向华为篇 04 章,不重复展开但随叫随到。 "

3.9 数据库日常巡检与备份检查(集群压缩节)【理解】 ​

标准回答:数据库巡检我的清单是"三库四看"。 MySQL 五看:processlist 会话堆积与长事务、主从状态(show slave status 双 Yes 加延迟,云上看控制台延迟指标)、连接数水位对照 max_connections、慢日志当日新增、磁盘空间与增长趋势(数据目录加 binlog)。 Redis 四看:info memory 内存与碎片率、info replication 主从角色与偏移、连接数与拒绝数(rejected_connections 非零说明超过 maxclients)、slowlog 慢命令。 Vastbase 三看:has/dcs 组件健康、hasctl list 主备角色、pg_stat_activity 长事务与会话。 备份检查是巡检的固定项:备份任务成功没、备份文件大小正常没、保留期内可恢复没——"没演练过的备份等于没有备份",恢复演练的验证动作必须定期做。

巡检的价值在留痕对比:每天快照汇成趋势,异常从趋势里先看出来。 我在银行驻场时数据库巡检是每天雷打不动的动作,巡检项后来全部变成了移动云项目的告警规则——人肉巡检的每个检查项,就是告警 expr 的每一条,这是我两个项目的演进关系。

追问链:

  • 追问1:巡检发现主从延迟增长,怎么处理? → 答:先评估影响:读写分离场景延迟的症状是"写后立刻读读不到",秒级延迟多数业务可容忍,持续增长才要处理。原因按主库侧从库侧分:主库大事务和慢 SQL 让事件变大变慢,从库单 SQL 线程串行回放是天生瓶颈加资源差异。处理:拆大事务、优化慢 SQL、从库与主库同规格、监控上对比位点差距。支持岗的动作是"先报影响面(延迟多少、影响哪些读业务),再按方向归因转派"——延迟类问题多数要开发配合,我的价值是给出准确的趋势和归因,不是自己硬扛优化。

关联话术:"巡检清单和告警规则的对应关系是我面试爱讲的点:银行时期我每天手工查的每一项,到移动云项目都变成了 Prometheus 告警表达式或云监控阈值——支持工作的进阶不是更努力地查,而是让异常主动找人。 这套'巡检项 → 告警规则 → 处置 SOP'的转化,是我给团队留下的可复用资产。"

3.10 Tomcat/Java 应用异常的一线判断(简历技能 4 的 Tomcat 落点)【理解】 ​

标准回答:简历技能里 Tomcat 和中间件日志分析是并列项,支持场景的一线判断我按"三类现象"讲。 第一类起不来:看 catalina.out(systemd 托管的用 journalctl -u tomcat)——端口占用(BindException: Address already in use,用 ss -lntp | grep 8080 找占用者)、JDK 路径错(JAVA_HOME 没配对,cron/systemd 拉起时最容易踩,因为它们不加载用户环境)、配置文件语法错(server.xml 解析异常),启动日志首屏直接给答案。 第二类起来又挂:OOM 是头号原因——java.lang.OutOfMemoryError: Java heap space 是堆不够或泄漏,Metaspace 溢出是类加载问题;处理是先留现场(jmap -heap 内存概貌、jstack 线程栈)再调 -Xms/-Xmx 或交开发查泄漏,还要区分被系统 OOM killer 杀掉的情况(dmesg | grep -i kill 交叉确认)。 第三类活着但慢:jstack 抓线程栈看 BLOCKED 堆积(锁竞争)或大量线程卡在 JDBC 调用上(等数据库,转本章 3.4 慢查询路径),GC 日志看是否频繁 Full GC(内存压力大)。 一线判断的产出物是"现象类别 + 关键日志行 + 线程栈摘要"——转开发时对方拿到就能开工,这是高质量转派的样子。

追问链:

  • 追问1:jps 和 jstack 怎么用? → 答:jps -l 列出 Java 进程和主类,确认目标进程 PID——比 ps grep java 准确,能看到是哪个应用在跑;jstack PID > /tmp/stack.txt 抓线程栈,发生死锁时会直接提示 "Found one Java-level deadlock";配合 top -Hp PID 找到高 CPU 线程号,printf '%x' 转十六进制后在栈里 grep nid=0x 对应位,就能定位到具体线程正在执行的方法。这三个工具都是 JDK 自带,支持岗能拿出"线程级证据"再转开发,转派质量立刻不一样。

关联话术:"数币平台后端是自研 Java 应用(毕昇 JDK),我驻场时的 Java 排障就是这一套:jps 确认进程、启动日志看起不来的原因、OOM 先留 jmap/jstack 现场再重启——'先留现场再动手'的纪律就是从 Java 应用上养成的:重启随时可以做,现场丢了就永远补不回来,这条我写进了部署指南的应急章节。 "

3.11 本章案例 ​

  • 【真实项目·支持场景】客户报"平台登录失败"牵出的数据库主备切换(STAR,约 220 字):背景是银行试点运行期间,上午多名用户反馈平台登录失败。任务是我作为一线快速定位。行动:按登录异常链路先排除入口——Nginx 活着、443 证书正常、后端 jar 进程在;再看后端日志发现大量数据库连接报错,时间点和凌晨2 点吻合;登数据库主机查 HAS 集群状态,确认夜间发生过一次主备自动切换,应用连接池对切换后的新主重建缓慢,连接持续失败。处理:先重启应用服务恢复连接(低峰窗口),业务恢复;随后联合华为二线分析切换诱因(存储抖动),并验证应用连接串指向高可用 VIP、连接池自动重连参数调优,把"切换演练 + 应用重连验证"列为季度固定动作。结果:当天恢复,此后两次真实切换业务均无感知。这个案例体现"一线定位层级、二线解决根因"的协同价值。
  • 【真实项目】连接数满的批量止血(STAR):背景是某天下午业务大面积报"获取连接超时"。任务:快速恢复。行动:processlist 分型发现 400+ 会话中 300 多条是 Sleep 且 Time 巨大——某应用发版后连接池配置错误,单实例池上限配成了 200;先用 information_schema 拼语句批量 kill 空闲超 10 分钟的连接,业务五分钟恢复;随后推动该应用修正池参数并全网核查同类配置。结果:当天闭环,并沉淀了"连接数分型处置"进 SOP。技术动作简单,价值在分型准确、止血快、根因移交清楚。
  • 【课程项目】MySQL 主从搭建与备份恢复演练:搭一主一从验证双 Yes 与延迟归零;mysqldump --single-transaction 全量加 binlog 增量;模拟误删表做按位点恢复。恢复演练后核对行数与抽查字段,输出一份"备份—恢复—验证"的操作记录。这个实验把 3.1 的分层定位知识和备份恢复原理跑成实操:命令的每个参数都亲手验证过效果,面试按"课程实验打底 + 云数据库运维加深"的口径讲,既诚实又有手上功夫。
  • 【经典故障】max_connections 3000 只能到 214:配置了 3000 但连接数到 214 就拒绝。定位:OS 层 open files 限制先到顶——ulimit 和 systemd 的 LimitNOFILE 没配套。解决:调 LimitNOFILE 并 daemon-reload 重启生效。教学点:数据库参数受 OS 资源约束,调参数要看整条链路,这也是支持岗"跨层知识"的典型价值。

章末自测清单(快问快答) ​

  1. 数据库排查四层总纲? → 网络端口 → 认证 → 服务能力 → 日志;每层有明确出口和转派对象。
  2. Access denied 排查五步? → 读报错原文(账号+来源 IP)→ 命令行验证密码 → 查 user@host 白名单 → 查密码过期/锁定 → 查认证插件兼容。
  3. connection refused 和 timeout 区别? → refused 是端口没人听/被拒(查服务监听),timeout 是包被丢/不可达(查网络防火墙)。
  4. telnet 通但应用超时查什么? → 连接数/线程池、应用超时参数、连接串 DNS。
  5. 云上数据库连不上第一查什么? → 安全组与白名单变更记录,再查实例是否在主备切换。
  6. 变慢四步? → processlist 分型 → 锁等待找 blocking_pid → 主机 CPU/IO → 慢日志 TOP。
  7. Sleep 会话多说明什么? → 连接池不释放;应急批量 kill 空闲连接,根因在应用池参数。
  8. 连接数满三类根因? → 空闲堆积(池配置)、慢 SQL 占用(SQL 质量)、泄漏不还(代码 bug)。
  9. max_connections 调大的三个配套? → OS 句柄 LimitNOFILE、内存核算、实际并发评估。
  10. PG 系查会话和杀会话? → pg_stat_activity 看、pg_terminate_backend(pid) 杀。
  11. Vastbase 高可用两组件? → HAS(监控切换)+ DCS(一致性存储);license 更换滚动重启 has 避免双主。
  12. Redis 内存碎片率怎么看? → mem_fragmentation_ratio:1.0–1.5 正常,>1.5 碎片,<1 在用 swap。
  13. 生产为什么禁 keys *? → O(N) 阻塞主线程,遍历用 scan 渐进迭代。
  14. 备份检查三问? → 跑成功没、大小正常没、能恢复没(定期演练)。
  15. 数据库权限管理三环节? → 入口(申请审批登记)、在途(季度审计休眠/宽权限)、出口(下线回收)。