ARTICLE DETAIL

资讯详情

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

SQL Server 2008 R2服务无法启动?ERRORLOG分层定位+最小模式修复指南

SQL Server 2008 R2服务无法启动?ERRORLOG分层定位+最小模式修复指南 简介遇到SQL Server 2008 R2数据库服务无法启动时一份精炼的PDF排错手册能节省大量排查时间。这份手册面向DBA、运维人员及遇到同类故障的开发者聚焦三种典型场景远程过程调用失败如安装VS2012自动引入LocalDB导致冲突、VIA协议配置异常、服务登录账户被更改后无法启动。文中结合真实案例先分析系统日志与SQL Server日志中的错误表现再给出卸载冲突服务、禁用VIA协议、恢复本地用户账户等可落地的操作思路同时提醒通过升级SP1/SP2或预先创建系统还原点来防止问题复发。资源包仅含1个PDF文件共117KB内容紧凑适合离线保存与快速查阅。目前已有1630人学习下载对于正在部署或维护SQL Server 2008 R2环境的读者而言是一份值得收藏的故障应急参考。1. SQL Server 2008 R2 数据库服务无法启动先把问题分层再动手凌晨两点收到“数据库连不上”的告警登上服务器一看SQL Server 2008 R2 服务是停止状态右键启动转几圈又弹回“已停止”事件日志里写着“发生系统错误 1067”或“服务没有及时响应启动请求”。这种场景对 DBA 和运维来说太熟悉了而最常见的翻车操作就是一上来就重装实例或者反复点启动按钮赌它能自己缓过来。SQL Server 2008 R2 数据库服务无法启动本质上是三个层面的问题被混在了一起Windows 服务层有没有把进程拉起来、SQL 引擎层在恢复时有没有卡住或崩掉、网络监听层有没有正常对外应答。绝大多数情况下引擎层是主要嫌疑而引擎为什么不起来ERRORLOG 里基本都写了只是很多人没看。这篇文章就把我自己处理这类故障的路径完整讲一遍先分层定位再用最小恢复模式把实例抬起来最后逐个修掉 model、tempdb、权限、端口这四个高频故障点。2. 先分清三层故障服务、实例、监听再动手2.1 服务启动失败的三种形态闪退、卡住、起一半又停我一般不会直接点“启动”而是先看服务面板里当前处于什么状态。同样是“无法启动”三种形态指向的排查方向完全不同。第一种是点启动后立刻闪退服务状态从“已停止”变一下又回到“已停止”Windows 事件日志里通常伴随“发生系统错误 1067进程意外终止”。这种情况多数是 SQL Server 引擎在初始化早期就失败了常见原因包括配置文件损坏、系统数据库文件不可访问、服务账号没有目录权限。此时 ERRORLOG 往往只写了很少几行就中断了。第二种是卡在“正在启动”长时间不进入“已启动”最后超时回到“已停止”。Windows 事件日志里一般会记 1053“服务没有及时响应启动或控制请求”。这种往往是引擎进程活着但数据库的自动恢复过程卡住了比如磁盘 IO 慢、系统数据库日志需要回滚、某个库文件损坏导致恢复流程一直循环。这个阶段不要频繁重启重启只会让恢复工作从头再来给问题加码。第三种是服务状态显示“已启动”但客户端就是连不上登录服务器看端口也没监听。严格说这不算“服务启动失败”但用户报障时通常就叫“数据库起不来”所以排查时要一起处理。这三种形态对应的是不同层级的故障先确认属于哪一种才不会在错误的方向上浪费时间。下面的表可以帮你快速归类。服务面板状态典型事件日志主要嫌疑层第一动作瞬间闪退1067 进程意外终止引擎初始化、文件访问、权限读 ERRORLOG 最后 20 行长时间“正在启动”1053 响应超时数据库恢复、磁盘 IO、日志回滚等恢复完成不反复重启“已启动”但连不上无服务错误网络监听、SQL Browser、端口检查 ERRORLOG 中的 TDSSNIClient 段2.2 ERRORLOG 是唯一不用猜的诊断入口很多人遇到服务起不来第一反应是打开“事件查看器”但 Windows 事件日志只能告诉你“服务没起来”这个结果真正的原因在 SQL Server 自己的错误日志里。2008 R2 的 ERRORLOG 路径固定在实例目录下默认实例通常在C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Log\ERRORLOG这个文件没有扩展名每次启动会轮转一次旧文件变成 ERRORLOG.1、ERRORLOG.2。排查时我一般直接看最后 30 行启动失败的原因就藏在最后几行里。用 type 命令读即可type C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Log\ERRORLOG | findstr /N 错误: 9003 5120 1105 3314 17204 TDSSNIClient这条命令的作用是从 ERRORLOG 里过滤出几个关键错误码。9003 代表数据库日志无效通常指向 model 库或 msdb 库的日志损坏5120 代表文件打开失败基本是权限或文件被占用1105 是磁盘空间不足3314 是日志文件损坏17204 是文件路径无法访问。把这些关键字一次搜出来问题范围就缩小了大半。拿到错误码之后再动手比盯着服务面板反复点启动要靠谱得多。另外注意如果 ERRORLOG 里出现“SQL Server 服务无法启动。有关详细信息请参阅 SQL Server 联机丛书中的主题……”这段套话说明引擎在启动早期就退出了真正的错误码一般在它前面几行。别被这段套话带偏往前翻才是关键。2.3 别把 SQL Browser 没启动误判成数据库服务没启动2008 R2 的命名实例默认使用动态端口客户端通过实例名连接时要先问 SQL Browser 服务拿端口。如果 SQL Browser 没启动或者防火墙挡了 UDP 1434服务明明活着客户端却报“找不到实例”或者“连接超时”。这类问题经常被当成“SQL Server 服务无法启动”报上来处理方式却完全不同。我遇到这种报障会先问一句服务器本机用 sqlcmd 能不能连上。本机能连、远程连不上基本就是监听或解析层的问题不是引擎层的问题。再配合 SQL Server 配置管理器确认 TCP/IP 是否启用、动态端口是否被占用。这一步判断对了能省掉后面所有针对引擎层的折腾。真正引擎起不来的时候本机也连不上这是最干脆的区分方法。3. 用最小恢复模式把实例先抬起来sqlservr.exe -f -T3608 实战3.1 最小配置和追踪标志各自解决什么问题定位完问题之后下一步不是直接修复而是先想办法让实例以一种“最小可用”的状态跑起来。SQL Server 2008 R2 提供了几个启动参数专门用来处理服务起不来的场景。-f 参数表示最小配置模式启动它会忽略配置表里的大部分配置项。比如有人把最大内存设得过大、开启了自动关闭、或者某些配置导致引擎启动时自检失败-f 可以绕开这些配置直接拉起引擎。注意 -f 并不跳过数据库的恢复过程只是跳过配置层面的障碍。真正能跳过非 master 库恢复的是追踪标志 -T3608。这个标志会让引擎在启动时只恢复 master 数据库其他数据库包括 model、msdb、用户库都不做自动恢复。这一点在 model 库损坏时非常关键因为正常情况下 model 库恢复失败引擎就会终止启动而加上 -T3608 后引擎可以绕过 model 的恢复流程先把 master 拉起来。所以要达到“先让实例起来”这个目标我习惯把三个参数一起用-f 忽略配置、-T3608 跳过 model 和用户库的自动恢复、-mSQLCMD 只允许一个 sqlcmd 客户端连进来避免其他连接干扰排查。三者组合起来是 2008 R2 场景下最稳妥的应急启动组合。3.2 停掉服务用前台命令把引擎拉起来最小恢复模式不能从“服务”面板启动必须先用命令行把 sqlservr.exe 前台跑起来。操作分两步。第一步停掉现有服务。如果服务已经是停止状态可以跳过但为了保险还是停一次顺便把 SQL Server 代理等依赖服务一起停掉net stop MSSQLSERVER /y/y 参数的作用是连同依赖这个服务的其他服务一起停止默认实例的服务名是 MSSQLSERVER注意区分实例名和服务名。如果是命名实例服务名一般是 MSSQL$实例名比如 MSSQL$SQLEXPRESS。停掉之后确认进程已退出再用 where 或直接切到 Binn 目录启动cd C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Binn sqlservr.exe -f -T3608 -mSQLCMD -c这里每个参数都有明确用途。-f 是最小配置模式忽略配置表里的风险项-T3608 跳过非 master 数据库的自动恢复-mSQLCMD 限制只有程序名为 SQLCMD 的连接才能进入避免排查期间有应用连接干扰-c 表示以控制台方式运行不注册为 Windows 服务进程。启动后这个命令行窗口不能关关了引擎就停了。跑起来之后命令行窗口里会滚动输出启动信息。正常的 2008 R2 启动日志会显示 master 数据库恢复完成然后由于 -T3608 的作用其他数据库会被标记为跳过整个进程不会退出。如果启动失败错误会直接打在屏幕上比翻 ERRORLOG 更直观。这是我首选的启动方式因为它把启动过程的黑匣子直接打开了。3.3 实例起来之后先用 sqlcmd 验证系统库状态前台窗口输出稳定后开第二个命令行窗口用共享内存协议连进去。因为在最小恢复模式下引擎一般不会监听 TCP 端口默认实例的本地管道地址是 \.\pipe\MSSQL\sql\querysqlcmd -S np:\\.\pipe\MSSQL\sql\query -E -Q SELECT name, state, state_desc FROM sys.databases;-E 表示用 Windows 身份认证连接-S 后面的管道地址是 2008 R2 默认实例的本地共享内存入口-Q 直接执行查询后退出。执行成功的话能看到 master、model、msdb、tempdb 和用户库的清单model 库因为被 -T3608 跳过状态一般是 RECOVERY_PENDING 或者根本没有被打开这符合预期。看到清单后不要在这个状态下继续做业务操作因为 model 库没有正常打开新建连接依赖 model 的模板此时即使能查数据也无法创建临时表。接下来要做的是根据 ERRORLOG 里的错误码决定走哪条修复路径。修完之后记得先 CtrlC 关掉前台窗口再执行 net start MSSQLSERVER 恢复正常启动。这一步特别容易忘我曾经在前台进程没退的情况下直接 net start结果端口被占服务又起不来白白多折腾半小时。4. 定向修复这四个高频点model、tempdb、权限、端口4.1 model 数据库损坏9003 错误与恢复思路model 库是 SQL Server 的模板库每次新建数据库、新建临时表都要基于 model 生成初始结构。如果 model 库文件损坏引擎在启动阶段恢复 model 失败整个服务就会中止ERRORLOG 末尾通常能看到类似“错误: 9003数据库 model 的日志无效”的记录。这种损坏常见于异常断电、磁盘故障或者有人把 model.mdf 文件手动拷贝覆盖过。处理这个问题的思路取决于有没有备份。有备份的话在最小恢复模式下直接恢复即可RESTORE DATABASE [model] FROM DISK ND:\backup\model.bak WITH REPLACE;REPLACE 参数用来覆盖现有损坏的 model 文件。执行成功后重启服务model 库恢复到正常状态。这里的关键是必须先以 -f -T3608 方式启动否则引擎在恢复 model 时就挂了连执行 restore 的机会都没有。真正麻烦的是没有备份而大多数人确实不会单独备份 model。这时候有两条路可走。一条是从同版本、同补丁级别的另一台 SQL Server 2008 R2 实例上拷贝一份 model.mdf 和 modellog.ldf 过来应急但版本不一致会直接拒绝启动即使能起来也可能埋下隐患另一条是用安装盘执行 REBUILDDATABASE重建整个系统数据库。我一般只在实验环境用拷贝文件的方式生产环境直接走重建因为后者虽然动作大但不会出现版本不匹配的玄学问题。注意 REBUILDDATABASE 会把 msdb 也一起重建成空库之前的所有作业、备份历史、维护计划都会丢失动手前必须对用户库先做完整备份这就是翻车的后悔药。4.2 tempdb 路径失效启动到一半又失败tempdb 是每次启动都会重建的库但它重建之前要读取 master 里记录的物理路径。如果配置好的路径现在不存在了比如原来放在 E 盘后来 E 盘被摘掉或者目录权限被回收引擎会在创建 tempdb 的阶段失败整个服务退回停止状态。ERRORLOG 里常见的是 17204 文件无法打开或者 5120 拒绝访问启动流程走到一半就停了。很多人会以为最小恢复模式能绕过 tempdb实际上 -f -T3608 模式下 tempdb 依然要创建因为引擎本身依赖它。所以 tempdb 路径失效时连最小模式都可能起不来。我处理这个问题的顺序是先确认磁盘在不在目录在不在再确认 SQL Server 服务账号对目录有没有完全控制权限。如果只是权限问题直接给服务账号授权有时候就能恢复启动icacls E:\MSSQLData /T /Q /grant NT AUTHORITY\NETWORK SERVICE:(OI)(CI)F/T 表示递归处理子目录/Q 是安静模式不逐个确认/OI 和 /CI 让权限继承到目录下的文件和子文件夹F 表示完全控制。2008 R2 默认服务账号通常是 NT AUTHORITY\NETWORK SERVICE如果服务属性里改成了别的账号要换成对应的账号名。授权完成后重新启动服务tempdb 就能在路径下重建。如果问题是磁盘整体不存在了那就先把原路径恢复出来或者把旧盘映射回原来的盘符否则引擎没有机会启动。等实例起来之后再用 ALTER DATABASE 把 tempdb 挪到稳定路径改完重启验证一次。这一步的建议是tempdb 别放在可能会被回收的挂载盘上本地系统盘虽然不够快但比“起不来”强得多。4.3 服务账号与 NTFS 权限1067 的经典来源服务面板点启动立刻闪退事件日志记录 1067ERRORLOG 里只有一个 5120 文件打开失败这种情况十有八九是文件系统权限问题。SQL Server 引擎进程要用服务账号去读数据目录下的 .mdf 和 .ldf 文件只要账号对目录没有权限引擎连 master.mdf 都打不开启动自然失败。先确认服务用哪个账号登录。打开 services.msc找到“SQL Server (MSSQLSERVER)”服务右键属性切到“登录”选项卡就能看到服务账号。常见的有 NT AUTHORITY\NETWORK SERVICE、NT AUTHORITY\SYSTEM也有人改成域账号。改过数据目录到 D 盘或 E 盘的项目最容易出这个问题因为安装时默认目录有权限迁移后新目录经常没给服务账号授权。确认账号后用 icacls 给整个数据目录授权命令和上一节类似只是把账号换成实际的服务账号icacls D:\SQLData /T /Q /grant DOMAIN\sqlservice:(OI)(CI)F执行完之后重新启动服务一般就能过了。这里还要提醒一个隐蔽的坑如果服务账号是域账号而账号密码在 AD 里被改过服务管理面板里保存的还是旧密码启动时同样会失败事件日志里会记录登录失败而不是权限拒绝。遇到这种情况去服务属性里重新填一遍新密码即可。长期方案是给 SQL 服务建专用账号并设置密码永不过期否则每隔几个月就要半夜爬起来改一次密码血泪经验。4.4 端口与监听异常服务起来了客户端还是连不上排查到最后有时会发现引擎其实起来了服务状态也是“已启动”但 ERRORLOG 前面有一段 TDSSNIClient initialization failed with error 0x2 的记录。0x2 对应的就是地址被占用通常是固定端口 1433 被其他进程抢了或者是 SQL Browser 动态端口分配失败。这时引擎可能还能通过共享内存本机访问但远程客户端一个都进不来。确认端口占用最直接的方式是用 netstat 看端口归属netstat -ano | findstr :1433 tasklist | findstr sqlservrnetstat 输出里最后一列是 PID拿这个 PID 去 tasklist 里对一下如果持有 1433 端口的进程不是 sqlservr.exe就说明端口被占用。解决方式有两种要么找到占用进程处理掉要么把 SQL Server 的端口改掉。改端口要打开 SQL Server 配置管理器在“SQL Server 网络配置”里选 TCP/IP进入属性找到 IPAll把“动态端口”清空在“TCP 端口”里填一个新的固定端口然后重启服务。这里还要区分动态端口和固定端口。2008 R2 命名实例默认用动态端口每次启动都可能变客户端靠 SQL Browser 解析。如果 SQL Browser 服务被禁用即使引擎正常客户端按实例名连接也会失败。处理方式是启动 SQL Browser或者把实例改成固定端口让客户端直接按端口连。这一步做完客户端连接问题才算真正收尾。5. SQL Server 2008 R2 服务启动排查避坑5 条血泪记录5.1 遇到 1053 就改 ServicesPipeTimeout治标不治本现象服务停在“正在启动”约 30 秒后回到“已停止”事件日志记录 1053 服务没有及时响应启动请求。原因Windows 服务控制管理器默认给服务 30 秒完成启动SQL Server 恢复大量数据库时很容易超时。网上常见做法是改注册表里的 ServicesPipeTimeout把超时拉长。这个操作本身不违法但很多时候只是把启动窗口拉宽恢复过程如果真的有文件损坏改完超时它照样会失败。解决先别急着改注册表。打开 ERRORLOG看启动开始后的恢复阶段如果卡在某个数据库的“正在恢复”状态说明这个库有问题超时只是表象。等恢复完成或者用最小模式绕过该库后再做针对性修复。改超时只有在确认是磁盘慢、库太多导致正常恢复超时的情况下才用。5.2 model 损坏后直接把文件删除指望它自动重建现象ERRORLOG 显示 9003 model 库日志无效有人把 model.mdf 和 modellog.ldf 改名或删除想着重启后引擎会重新生成一个干净的 model。原因SQL Server 2008 R2 不会自动重建 model。model 是引擎启动的必需品文件缺失时引擎会直接报“无法打开 model 数据库”然后退出连最小恢复模式都进不去。原本还有机会做 RESTORE 或拷贝文件删了之后连最后一条路都堵死了。解决任何对系统库文件的删除操作都要先冻结。正确做法是先把损坏文件完整复制到别处备份再用最小模式启动能进则用 RESTORE 恢复不能进则用 REBUILDDATABASE 或从同版本实例拷贝文件最后再考虑删除。5.3 前台最小模式还没退出就直接 net start 重启服务现象用 sqlservr.exe -f -T3608 前台跑着修完问题后没关窗口直接另开一个窗口执行 net start MSSQLSERVER提示服务已经启动或正在启动或者刚启动又失败。原因同一个实例的 sqlservr.exe 进程已经占用了数据文件Windows 服务启动时检测到文件被占用无法正常初始化最终失败。这类错误在 ERRORLOG 里往往只有一行“无法打开文件”很容易被误解成权限问题。解决先回到前台命令行窗口按 CtrlC 让进程正常退出确认进程消失后再执行 net start。我现在的习惯是准备一个文本文件把“停服务、前台启动、关前台、启服务”四步命令都写好避免在凌晨操作时漏掉中间步骤。5.4 临时调整 tempdb 路径时改了文件没改配置现象服务能启动但每次启动后 tempdb 依然在老路径重建或者启动直接失败报 tempdb 文件找不到。有人把 tempdb.mdf 物理移动到了新目录却漏掉了 ALTER DATABASE 修改逻辑路径。原因master 库的 sys.master_files 里记录的是 tempdb 的逻辑路径引擎启动时严格按这个路径找文件。物理移动文件但没改配置引擎自然找不到。解决物理移动文件之前先执行 ALTER DATABASE tempdb MODIFY FILE 修改逻辑路径再复制文件最后重启验证。两个动作缺一不可顺序也不能反只改物理文件不改配置等于白做。5.5 重建系统库前没备份 msdb作业全部蒸发现象model 损坏被迫 REBUILDDATABASE完成后服务恢复了但 SQL Server Agent 里的所有作业、计划、备份历史全部消失运维体系一夜回到解放前。原因REBUILDDATABASE 会重建 master、model、msdb 三个系统库msdb 被重置成全新空库里面存储的作业、运算符、备份历史、维护计划一并清空。解决执行 REBUILDDATABASE 前必须分别备份 master、model、msdb。如果已经来不及至少把 msdb 的历史备份找出来用 RESTORE 恢复回重建后的实例。这个教训告诉我系统库备份不是可有可无的尤其维护计划里如果没有覆盖系统库出一次事就够喝一壶。6. 把启动失败排查压进 60 秒一套可复用的定位流程处理过几次 SQL Server 2008 R2 启动失败之后我总结出一套固定流程遇到问题先走一遍能少走很多弯路。第一步永远是看服务状态和事件日志确认是闪退还是超时这决定了后面的方向。第二步读 ERRORLOG直接搜错误码。把下面这行命令记在运维手册里够用一整年type C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Log\ERRORLOG | findstr /N 9003 5120 1105 3314 17204 TDSSNIClient搜出来的错误码直接对应到修复动作9003 和 3314 是系统库日志损坏走最小模式加 RESTORE 或重建5120 和 17204 是权限或路径问题先检查服务账号和目录是否存在1105 是磁盘满清理空间再说TDSSNIClient 是监听异常看端口占用和协议配置。这一套对应关系比翻网页快得多。第三步是用 -f -T3608 -mSQLCMD 把引擎拉起来做现场检查。注意拉起来之后先别动任何文件先执行查询看 sys.databases 里各库状态再决定下一步。我有个习惯每次成功处理完这类故障后会把当时的 ERRORLOG 复制一份按日期归档因为同一个实例碰上相似的坑翻旧日志比查资料更快。这几年处理下来最大的教训就是SQL Server 2008 R2 服务启动失败从来都不是玄学每一条都写在日志里关键在于别被 Windows 事件日志的表象带着走也别在没备份的情况下动系统库文件。希望这套流程能帮你在下次遇到“服务无法启动”时不必再靠反复点启动按钮碰运气。本文还有配套的精品资源点击获取
返回列表