一数据库服务器(SQL Server 2014)上的一个作业执行报错,具体错误信息如下:
Executed as user: NT SERVICE\SQLSERVERAGENT. 用户 'xxxx\xxxxx$' 登录失败。 [SQLSTATE 28000] (Error 18456). The step failed.
其中用户 'xxxx\xxxxx$',反斜杠前面是域名,后面为计算机名称+$, 其实这是一个虚拟账号。 即本地系统帐户不具有网络的任何访问权限。当需要访问网络时,本地系统使用帐户 Domain\computername$ 。具体参考关于 Configuration Manager 中的本地系统帐户/Computer$。
起初看到这个错误,有点不知所以然,并不清楚是什么具体原因造成,那么就去检查作业执行的存储过程,发现里面使用链接服务器(LINKED SERVER),由于这个错误提示是本地系统账号访问网络的权限问题,所以我特意去链接服务器(LINKED SERVER)所指向的数据库服务器,结果在同一时间点也出现了一个错误信息,其实就是该作业链接过来时产生的信息。
Message
Login failed for user 'xxx\xxxx$'. 原因: 基于令牌的服务器访问验证失败,出现基础结构错误。请检查以前的错误。 [客户端: 192.168.xxx.xxx]
检查该链接服务器(LINKED SERVER)发现该链接服务器使用的是“使用登录名的当前安全上下文建立连接”(Be made using the login's current security context)
由于是作业调用该存储过程,那么该作业执行到调用链接服务器部分SQL时,使用的就是启动SQL Agent服务的登录名来建立安全上下文, 如下所示,SQL Agent服务的启动账号为NT Service\SQLSERVERAGENT, 而链接服务器(LINKED SERVER)所指的数据库服务器,启动SQL Agent服务的登录名为一个域账号,很显然此时链接服务器就会遇到权限问题。其实就是最近修改了这台服务器的SQL Agent服务的登录名所导致。SQL Agent服务本来是一个域账号启动的。
知道具体原因了,那么就能给出具体解决方案了:
方法1: 修改启动SQL Server Agent服务的登录名,例如具有系统管理员权限的域账号(当然所指向的服务器也具有该域账号,并且有相关权限),然后重启SQL Agent服务就能解决问题。
方法2: 修改链接服务器(LINKED SERVER),使用特定账号来建立安全上下文机制也可以解决这个问题。