加入收藏 | 设为首页 | 会员中心 | 我要投稿 站长网 (https://www.0951zz.com/)- 云通信、基础存储、云上网络、机器学习、视觉智能!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQL Server运维踩坑5年总结:实战排障指南

发布时间:2026-11-05 14:07:02 所属栏目:MsSql教程 来源:DaWei
导读:  告警响的那一刻,我正把泡面叉子插进最后一块火腿肠里——屏幕右下角弹窗是“SQL Server Agent 已停止”,左侧还开着三个没关的 SSMS 窗口,其中一个连着生产库的查询计划卡在 92%。我咽下去那口面的时候,机房空调又开

  告警响的那一刻,我正把泡面叉子插进最后一块火腿肠里——屏幕右下角弹窗是“SQL Server Agent 已停止”,左侧还开着三个没关的 SSMS 窗口,其中一个连着生产库的查询计划卡在 92%。我咽下去那口面的时候,机房空调又开始滴水,嗒、嗒、嗒,跟心跳对不上拍子。


文章配图,仅供参考

  去年中考期间,三台机器一起掉链子。不是同时,是串着掉:A 库先锁死,B 库跟着超时,C 库倒没事,它自己主动把自己删了登录名——没人动它,就是昨天那个开发改完触发器顺手执行了句 `EXEC sp_msforeachdb 'USE ?; DROP USER IF EXISTS [app_user];'`,少了个 `IF DB_NAME() NOT IN ('master','model','msdb')`。他以为只在测试库跑。我原以为是权限脚本写错了,结果翻日志发现是 `sp_msforeachdb` 里面 `?` 被当成了变量直接拼进去,连 `USE master` 都没加——这玩意儿根本不管你在哪个上下文里。反正他甩锅说“文档没写清楚”,我点头说“对,SQL Server 文档向来不写清楚”。


  窗外天快亮了,我靠在椅子上数呼吸。隔壁同事老张端着保温杯进来,杯子上贴着“退伍不褪色”,他说:“你先歇会儿,我顶着。”我没接话,盯着屏幕上还没关的 PowerShell 窗口——`Get-ChildItem "C:\\SQLBackups\\" -Recurse | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-7)} | Remove-Item -Force` 这行删过期备份的脚本,昨天半夜自动跑完,把上周六凌晨三点的手动全备也给扫掉了。我忘了加 `-Exclude ".log"`,它把事务日志文件也当普通文件清了。其实我早该知道,这脚本三年前就干过一次类似的事,只是那次只清了日志,没清全备,所以没人报案。


  火大是火大,但更麻的是——你知道最要命的那个备份其实根本没走磁盘。我们一直用 `BACKUP TO URL` 存 Azure,可上个月刚换密钥,运维组那边配错了 SAS token 权限,所有远程备份都静默失败,日志里只打一行 `BACKUP failed to complete. Check credentials.` 没人看。没人看。开发在群里问“为什么最近 restore 不出来?”,我回“你确定备份成功了?”——他截图发过来的 SSMS 提示框写着“操作成功”,底下小字缩到 8 号:`Note: backup uploaded to Azure storage with errors.` 我当时点开一看就滑过去了。谁会把提示框拉到底?反正我是没拉。


  值班表上周刚调过。我妈打电话来问我“孩子作文补习班能不能改时间”,我说“妈,这周我替王磊值两个夜班”。她说“那你记得吃饭”。我没答,挂了。后来泡面凉透,我掰开第二包,发现调料包漏了半袋粉在键盘缝里,抠都抠不干净。机房的人扛着 UPS 电池箱路过,冲我喊:“刘工!3号机柜PDU跳了!”我抬头说:“等我吃完这口。”他笑:“你哪次不是说完再动?”


  迁移那回事儿更绝。我们把旧集群从 2016 升到 2019,按流程停服务、切流量、改兼容级别、重编译计划……一切看着像 SOP 套出来的电影。直到第三天,财务那边报:月结报表多跑出一千万行重复数据。查半天发现是 `tempdb` 的版本存储区(Version Store)爆了,`sys.dm_tran_version_store` 里积压了两亿多条 ghost record。根因?我们忘了在升级后手动清理掉那些被标记为“已删除但未清除”的历史版本——`ALTER DATABASE [tempdb] SET ALLOW_SNAPSHOT_ISOLATION OFF` 再 `ON` 一遍都不管用,得重启实例。我查不出确切原因,只知道重启后它好了。有人说是 bug,有人说配置残留在 model 库里,反正没查清,我也没再深挖。


  其实真要论踩坑密度,去年下半年特别邪门。证书轮换那天,AD 域控制器刚好同步失败,我们配 SQL Server 加密连接用的证书绑定全失效;接着磁盘突然告警:不是满了,是 IO 超限,IO 等待队列堆到三百多——结果是某个开发写了段 `WHILE 1=1 BEGIN SELECT GETDATE(); WAITFOR DELAY '00:00:01'; END` 放进作业里,取名“心跳监控”。他说“方便运维看有没有活着”。可这玩意儿在每分钟建一个新临时表,建完不删,全塞在 tempdb 里,而我们的 tempdb 数据文件没设自动增长,增长步长又是 1MB……最后磁盘没满,IO 先被它干窒息了。我删作业时候手抖,顺手删了 `msdb.dbo.sysjobsteps` 里的另一条记录——那条是备份维护计划。我承认,我真没做备份。不是忘了,是觉得“这表结构太稳了,改啥啊”。


  认了。SQL Server 运维踩坑5年总结:实战排障指南,站得住的地方就是优胜劣汰。不是服务器优胜劣汰,是我们这些人——谁还能半夜三点对着一个死锁图边啃凉馒头边画资源依赖环,谁就留下;谁在 `sp_whoisactive` 结果里一眼看出是 `SELECT INTO` 正在疯狂扩展数据文件,谁就被叫去讲经验;谁敢在回滚窗口里敲 `KILL 248 WITH STATUSONLY` 十七遍确认它真死了而不是在假装,谁的值班表就永远排在周三和周六之间——中间那段空隙,够你睡四小时,或者去修打印机。打印机今天又卡纸了,我蹲那儿掏了半天,发现是一张去年十一月的变更审批单,背面写着“本次升级风险可控”,笔迹是我自己的。


  下一步?补个备份校验钩子,每次 `BACKUP TO URL` 后自动 `RESTORE HEADERONLY FROM URL`,失败直接钉钉@所有人。当然也可能又漏掉——比如这次会不会忘了在钩子里加 `TRY/CATCH`?谁知道。反正泡面汤凉了,我把它倒进盆栽里了。那盆绿萝,活了四年,比我们上一套主从架构活得都久。

(编辑:站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!