SQL Server Agent 启动失败排查实录:从权限拒绝到双实例解析

摘要 :本文记录了一次典型的 SQL Server Agent 无法启动问题的完整排查过程。通过分析日志、验证服务账户权限、修复登录主体,最终成功解决问题,并深入解释了为何一台机器上会出现两个 SQL Server 实例(MSSQLSERVERSQLEXPRESS),帮助开发者理解 SQL Server 实例管理机制。


一、问题现象

在 Windows 服务器上,尝试启动 SQL Server 代理 (SQLEXPRESS) 服务时,服务看似"启动成功",但几秒后自动停止。Windows 事件查看器中仅显示两条日志:

  • 事件 ID 101SQLServerAgent service successfully started.
  • 事件 ID 102:无详细描述(通常表示服务已停止)

表面上看没有报错,但实际 Agent 无法持续运行,导致作业(Jobs)、警报(Alerts)等功能完全不可用。


二、初步排查:服务配置与连接测试

1. 服务登录账户设置

检查服务属性发现,SQL Server Agent 使用的是 Local Service 账户。这是一个低权限内置账户,不具备访问 SQL Server 数据库所需的权限

修正操作

将登录账户改为 Local System(高权限内置账户),重启服务。

⚠️ 注意:Local ServiceLocal System!前者权限不足,后者可代表本地系统管理员。

2. 验证 SQL Server 引擎是否可用

使用 SSMS 尝试连接:

  • . → 连接默认实例(失败)
  • .\SQLEXPRESS连接成功

说明:

  • SQLEXPRESS 是命名实例
  • . 只能连接默认实例(MSSQLSERVER),不能自动跳转到命名实例

✅ 正确连接命名实例的方式:.\SQLEXPRESSlocalhost\SQLEXPRESS


三、关键突破:分析 SQLAGENT.OUT 日志

在路径
C:\Program Files\Microsoft SQL Server\MSSQL15.SQLEXPRESS\MSSQL\Log\SQLAGENT.OUT

中发现核心错误:

text 复制代码
[298] SQLServer 错误: 229, 拒绝了对对象 'sp_sqlagent_update_agent_xps' 
(数据库 'msdb', 架构 'dbo') 的 EXECUTE 权限。

这表明:Agent 服务账户没有执行系统存储过程的权限


四、根本原因:服务账户未注册为 SQL Server 登录主体

SQL Server Agent 在启动时,会以虚拟 Windows 服务账户身份连接数据库:

NT SERVICE\SQLAgent$<实例名>

对于 SQLEXPRESS,该账户为:
NT SERVICE\SQLAgent$SQLEXPRESS

但查询 sys.server_principals 发现该登录名不存在

sql 复制代码
SELECT name FROM sys.server_principals 
WHERE name = 'NT SERVICE\SQLAgent$SQLEXPRESS';
-- 返回空

即使服务使用 Local System 运行,SQL Server 内部仍通过此虚拟账户认证,必须显式创建并授权


五、解决方案:创建登录并授予 sysadmin 角色

步骤 1:创建服务账户登录

sql 复制代码
CREATE LOGIN [NT SERVICE\SQLAgent$SQLEXPRESS] FROM WINDOWS;

步骤 2:授予 sysadmin 角色(必需)

sql 复制代码
ALTER SERVER ROLE sysadmin ADD MEMBER [NT SERVICE\SQLAgent$SQLEXPRESS];

💡 Microsoft 官方要求:SQL Server Agent 服务账户必须是 sysadmin 成员,否则无法正常工作。

步骤 3:重启服务

复制代码
net stop "SQLAgent$SQLEXPRESS"
net start "SQLAgent$SQLEXPRESS"

✅ 服务状态变为 "正在运行",且保持稳定!


六、延伸问题:为什么我的机器上有两个 SQL Server 实例?

在服务列表中同时看到:

  • SQL Server (MSSQLSERVER) → 默认实例
  • SQL Server (SQLEXPRESS) → 命名实例

原因分析:

实例 来源 特点
MSSQLSERVER 安装 SQL Server Developer / Standard / Enterprise 版本 默认实例,连接方式:.
SQLEXPRESS 安装 SQL Server Express Edition 命名实例,连接方式:.\SQLEXPRESS

常见场景:

  • 安装 Visual Studio 时自动附带 SQL Server Express
  • 后续又手动安装了 SQL Server Developer Edition
  • 某些应用(如旧版 SharePoint)依赖 Express 实例

✅ 一台机器可安装多个 SQL Server 实例,彼此独立,互不影响。

是否需要保留两个?

  • 开发环境:保留无妨,资源占用小
  • 生产环境:建议只保留一个,降低复杂度
  • 清理方法:通过"控制面板 → 程序和功能"卸载不用的版本

七、经验总结

  1. 不要混淆 Local ServiceLocal System ------ 前者权限不足,无法运行 Agent。
  2. 命名实例必须用 .\实例名 连接. 只适用于默认实例。
  3. SQL Server Agent 必须拥有 sysadmin 权限,这是硬性要求。
  4. 日志文件 SQLAGENT.OUT 是诊断 Agent 问题的第一手资料
  5. 多实例共存是正常现象,源于多次安装不同版本的 SQL Server。

八、附录:常用排查命令

sql 复制代码
-- 检查服务账户是否存在
SELECT name, type_desc, is_disabled 
FROM sys.server_principals 
WHERE name = 'NT SERVICE\SQLAgent$SQLEXPRESS';

-- 检查是否拥有 sysadmin 角色
SELECT r.name AS role_name
FROM sys.server_role_members rm
JOIN sys.server_principals r ON rm.role_principal_id = r.principal_id
JOIN sys.server_principals m ON rm.member_principal_id = m.principal_id
WHERE m.name = 'NT SERVICE\SQLAgent$SQLEXPRESS';

-- 禁用所有作业(用于排除作业干扰)
USE msdb;
UPDATE dbo.sysjobs SET enabled = 0;

结语

SQL Server 是一个强大但复杂的数据库平台,服务启动失败往往隐藏着权限、配置或实例管理的细节问题。通过系统化日志分析 + 权限验证,我们不仅能解决当前问题,还能加深对 SQL Server 架构的理解。

希望本文能帮助遇到类似问题的开发者快速定位并修复故障!

相关推荐
北京_小杰子5 天前
Windows10本地安装SQLserver数据库连接的过程
数据库·windows·sqlserver·php
山岚的运维笔记6 天前
SQL Server笔记 -- 第86章:查询存储
笔记·python·sql·microsoft·sqlserver·flask
汇智信科6 天前
汇智信科网络考试系统:以技术赋能,重构在线测评新范式
linux·数据库·mysql·oracle·sqlserver·java技术
山岚的运维笔记6 天前
SQL Server笔记 -- 第85章:查询提示
数据库·笔记·sql·microsoft·sqlserver
知识分享小能手7 天前
SQL Server 2019入门学习教程,从入门到精通,SQL Server 2019 开发企业人事管理系统 — 语法知识点及使用方法详解(21)
sql·学习·sqlserver
No8g攻城狮8 天前
【SQL】MySQL中空值处理COALESCE函数
数据库·sql·mysql·postgresql·sqlserver
山岚的运维笔记8 天前
SQL Server笔记 -- 第80章:分页
java·数据库·笔记·sql·microsoft·sqlserver
知识分享小能手8 天前
SQL Server 2019入门学习教程,从入门到精通,SQL Server 2019 新增功能 — 语法知识点及使用方法详解(20)
数据库·学习·sqlserver
山岚的运维笔记8 天前
SQL Server笔记 -- 第78章:MS SQL Server 基本 DDL 操作
数据库·笔记·sql·microsoft·oracle·sqlserver
山岚的运维笔记8 天前
SQL Server笔记 -- 第73章:排序/对行进行排序
数据库·笔记·后端·sql·microsoft·sqlserver