图片 10

基于令牌的服务器访问验证失败,出现基础结构错误。请检查以前的错误

今天遇到这样一个问题:一个系统的作业需要给系统Support人员开放SQL
Agent下作业的查看、执行权限。数据库版本为SQL Server 2014
SP2,给这个系统Support人员的NT账号授予msdb数据库下面权限后:

在SQL
Server
2012(11.0.7001.0)下面在还原一个数据库(备份文件40多G大小,实际数据库大小300G),在还原过程中,出现一直等待ASYNC_IO_COMPLETION,如下测试截图所示,已经等待了72分钟了,但是还原比例依然为0%

一数据库服务器(SQL Server
2014)上的一个作业执行报错,具体错误信息如下:

 

 

 

图片 1

SELECT  r.session_id ,

        r.command ,

        r.start_time,

        r.status,

        r.wait_type,

        CONVERT(NUMERIC(6, 2), r.percent_complete)   AS [Percent Complete(%)] ,

        CONVERT(VARCHAR(20), DATEADD(ms, r.estimated_completion_time,

                                     GETDATE()), 20) AS [ETA Completion Time] ,

        CONVERT(NUMERIC(10, 2), r.total_elapsed_time / 1000.0 / 60.0) AS [Elapsed Min] ,

        CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0) AS [ETA Min] ,

        CONVERT(NUMERIC(10, 2), r.estimated_completion_time / 1000.0 / 60.0

        / 60.0) AS [ETA Hours] ,

        CONVERT(VARCHAR(1000), ( SELECT SUBSTRING(text,

                                                  r.statement_start_offset / 2,

                                                  CASE WHEN r.statement_end_offset = -1

                                                       THEN 1000

                                                       ELSE ( r.statement_end_offset

                                                              - r.statement_start_offset )

                                                            / 2

                                                  END)

                                 FROM   sys.dm_exec_sql_text(sql_handle)

                               )) AS CommandText

FROM    sys.dm_exec_requests r

WHERE   command IN ( 'RESTORE DATABASE', 'BACKUP DATABASE','RESTORE LOG' );

Executed as user: NT SERVICE\SQLSERVERAGENT. 用户 ‘xxxx\xxxxx$’
登录失败。 [SQLSTATE 28000] (Error 18456). The step failed.

 

 

 

该系统Support人员反馈在双击查看该作业时报下面错误。于是我测试,验证了一下这个权限是否OK,

 

图片 2

 

 

 

图片 3

图片 4

其中用户 ‘xxxx\xxxxx$’,反斜杠前面是域名,后面为计算机名称+$,
其实这是一个虚拟账号。
即本地系统帐户不具有网络的任何访问权限。当需要访问网络时,本地系统使用帐户
Domain\computername$ 。具体参考关于 Configuration Manager
中的本地系统帐户/Computer$。

 

 

 

我测试的时候使用的是Microsoft SQL Server Management Sutdio
2014,发现不会出现这个错误。 后面我又继续测试了一下Microsoft SQL Server
Management Sutdio 2008,发现使用这个版本确实会出现这个错误,Microsoft
SQL Server Management Sutdio 2008版本如下所示:

当然,这里是实验,如果还要继续等待的话,相信这个时间会更长。这个是比较让人奇怪的现象。后面查了一下这个跟即时文件初始化(Instant
File Initialization
(IFI))有关。关于这个概念,可以参考官方文档数据库文件初始化
,摘抄部分内容如下所示:

起初看到这个错误,有点不知所以然,并不清楚是什么具体原因造成,那么就去检查作业执行的存储过程,发现里面使用链接服务器(LINKED
SERVER),由于这个错误提示是本地系统账号访问网络的权限问题,所以我特意去链接服务器(LINKED
SERVER)所指向的数据库服务器,结果在同一时间点也出现了一个错误信息,其实就是该作业链接过来时产生的信息。

 

 

Message

图片 5

 

Login failed for user ‘xxx\xxxx$’. 原因:
基于令牌的服务器访问验证失败,出现基础结构错误。请检查以前的错误。
[客户端: 192.168.xxx.xxx]

 

 

 

于是我用SQL Profile跟踪了一下,双击作业操作时执行的SQL语句,如下所示

数据库文件初始化

图片 6

 

 

 

图片 7

初始化数据和日志文件以覆盖之前删除的文件遗留在磁盘上的任何现有数据。 执行以下其中一项操作时,应首先通过零填充(用零填充)数据和日志文件来初始化这些文件:

检查该链接服务器(LINKED
SERVER)发现该链接服务器使用的是“使用登录名的当前安全上下文建立连接”(Be
made using the login’s current security context)

 

 

 

在执行下面SQL时,出现错误,可以将该SQL取出,在Microsoft SQL Server
Management Sutdio 里面执行。

·        
创建数据库。

图片 8

 

·        
向现有数据库添加数据或日志文件。

 

exec master.dbo.sp_MSdbuserpriv N'serv'

·        
增大现有文件的大小(包括自动增长操作)。

由于是作业调用该存储过程,那么该作业执行到调用链接服务器部分SQL时,使用的就是启动SQL
Agent服务的登录名来建立安全上下文, 如下所示,SQL
Agent服务的启动账号为NT Service\SQLSERVERAGENT, 而链接服务器(LINKED
SERVER)所指的数据库服务器,启动SQL
Agent服务的登录名为一个域账号,很显然此时链接服务器就会遇到权限问题。其实就是最近修改了这台服务器的SQL
Agent服务的登录名所导致。SQL Agent服务本来是一个域账号启动的。

图片 9

·        
还原数据库或文件组。

 

 

 

图片 10

解决这个问题也很简单,只需要给这个NT账号,授予master数据库下面的public角色即可解决问题。

文件初始化会导致这些操作花费更多时间。 但是,首次将数据写入文件后,操作系统就不必用零来填充文件

 

 

知道具体原因了,那么就能给出具体解决方案了: