SQL Server运维避坑指南:12个真实故障复盘
|
去年六月,凌晨三点十七分,我盯着 SQL Server Management Studio 里那个“已断开连接”的灰色标签页,右手边键盘上 Q 键早就掉了,只剩个塑料凹坑——去年改完登录策略后就再没装回去。工位显示器是竖着的,刚好卡在两台横屏中间,像根立起来的骨牌。有人端着杯子站了很久,站在隔断边,没说话,杯子里枸杞沉底了。 不是故障第一次发生。是第十二次——我们后来数过,不算测试环境那些毛刺。这次崩在订单核销环节,用户点“确认核销”,后端发完 EXEC dbo.usp_ProcessWriteOff 后直接 hang 死,连 RETURN 状态都等不来。控制台报错栏最顶上那行是:“A transport-level error has occurred when receiving results from the server.” 不是连接超时,不是死锁图,就是 transport-level。你查日志?日志里只写了一句 “Net-Lib error during connection reset”。跟没说一样。 跟人吵架——准确说是跟后端老大在会议室吵完出来的。他刚把白板上写的“事务粒度拆细”用板擦抹掉半截,擦得不干净,粉笔灰沾在“拆”字最后一捺上,像道结痂的划痕。他说:“存储过程里嵌了个 OPENQUERY 调 Oracle 表,又套了 TRY...CATCH,再套个 WITH (NOLOCK),三层套娃,你还想让它扛住 300TPS?” 我说:“那你们改接口啊。” 他说:“改不了,前端调的还是那个 /api/v2/writeoff/batch,合同里写着兼容三年。” 我点头,回工位路上看见外卖袋子还堆在茶水间门口,没人去拿。谁碰了椅子,我听见吱呀一声,很轻,但耳机里正放着 Profiler 抓到的执行计划 XML,那一声椅子响混进去,像 ExecutionPlan 中突然跳出来的 。 避坑指南?标题里那个“12个真实故障复盘”,优点是没有美化——真写了“tempdb 文件增长未设置自动扩展上限”这种话;问题也在这儿:它只说“别让 tempdb 单文件”,没说当 LDF 日志文件被锁在另一个磁盘分区、而 MDF 又落在 NTFS 压缩卷上时,“自动扩展”根本不会触发,SQL Server 就默默卡在“正在等待资源”状态里,连 sys.dm_exec_requests 都查不到它——它连请求都没算进去,只是进程在 WaitForSingleObject 里跪了。我们那天查了俩小时,最后是看 Windows 事件查看器里 Application 日志里一条 ID=17184 的警告,才扒出压缩卷这事。
文章配图,仅供参考 还有一次,首屏转圈、按钮点了没反应、控制台一片红。不是前端 JS 错,是 SELECT TOP 100 FROM dbo.OrderDetail WHERE OrderId IN (...) 这条语句,在参数传进来之前先被执行了——因为 EF Core 默认把 List 当作 Table-Valued Parameter 绑定,结果 SQL Server 把整张表全扫描一遍才开始过滤。没走索引,WHERE 条件压根没生效,Plan 显示 98% 成本在 Clustered Index Scan。我们盯性能面板,那行 Cost: 10.297 的扫描节点亮得刺眼,比任何 React DevTools 里的 re-render 都扎眼。设计稿标注写“加载不超过 2 秒”,可这条语句在测试机(戴尔 T3620,i7-12700K,SSD 是 Intel 670p)上跑出来要 11 秒。没人提 SSD 型号,但它就在那儿,凉的。 还有一个坑,纯属嘴欠。客户要求“导出全部订单明细”,后端写了 SELECT INTO #tmp_all FROM dbo.Orders WITH (NOLOCK)……然后忘了删临时表。上线三天,tempdb 日志暴涨到 87GB,DBCC OPENTRAN 返回空——根本没活跃事务,只有几十个 sleeping 的 spid,每个都挂着 #tmp_all。查 sys.dm_db_session_space_usage,看到 session_id = 57 的 user_objects_alloc_page_count 是 1274万。你 kill 它?kill 了,SQL Server 自动新建一个 session_id = 58,继续 alloc。最后是手动改系统表 sys.sysobjvalues(当然没真改,是开了 -T1204 启动参数抓到源头)。这事儿我没敢告诉产品,他当时正拿着手机录像演示“一键导出”有多丝滑。录像里播放器进度条动了三格,服务器已经崩了两次。 我不信什么“运维标准化流程”。上次部署前 Checklist 里有一项:“确认 SQL Agent Job 的 owner 是 sa”,结果发现 job 的 owner 是个已被禁用的域账号。Agent 没报错,也没执行失败邮件,就是每天 2:15 静静地跳过这个 job。数据同步漏了一周,没人知道。不是监控没配,是告警阈值设成“连续失败 5 次”,而它每天只失败 1 次。你看构建日志里那行 “[SQLCMD] Executing post-deploy script”——底下其实藏了 7 行红色 ERROR,但 CI 工具只判返回码,不读 stderr。于是所有人看着绿色对勾,喝咖啡。 反常识的是:加索引不总能解决问题。我们给 OrderHeader.Status 加了个非聚集索引,结果所有带 Status = 'pending' 的查询变慢了 3 倍。为啥?因为统计信息陈旧,SQL Server 认为 pending 只占 0.2%,实际占 63%。UPDATE STATISTICS dbo.OrderHeader WITH FULLSCAN 才见效。不是索引错了,是 SQL Server 忘了它自己上次看这表是什么时候。就像你改完组件 props 之后没重刷页面,不是逻辑坏,是缓存没清。 下一步?明天下午三点,我约了 DBA 对着那台测试机(T3620)重跑所有高频存储过程,把 execution plan 导出来打成 PDF,贴到会议室白板上。Q 键我打算今天下班前粘回去——用 UV 胶。外卖我顺手拎回来,放谁桌上都行。至于那个“12个故障复盘”文档?我加了两行批注:第一行写“transport-level error 出现时,先查网络设备日志,别一头扎进 SQL Profiler”;第二行写“别信‘SELECT ’前面那个星号,它可能正拖着整个数据页走路”。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


站长圈淘汰只会单点技术的运维人
Linux安全环境搭建:13年运维实战指南
网站搭建总卡壳?13年网工的多媒体运维避坑指南
SQL Server运维6年踩坑实录:实战排障指南
鸿蒙开发者必修:MySQL运维设计实战
运维老手血泪总结:服务器部署5大技术深坑
Windows站点搭建中90%运维忽略的3大安全断点
