快照代理挂起的故障排除
今天们来介绍一个关于快照代理挂起的案例分析。
案例背景:从SSMS(SQL Server Management Studio)启动快照代理时,SQL Server 2008快照代理出现挂起问题。
我们看到跳出的状态窗口显示“Starting agent”。看起来它是正在运行,但是,它会一直处于这个状态。
同时,在复制监视器中,快照代理的状态也显示为“Running”:
在复制监视器中,如果双击快照代理,可以进一步查看代理的状态信息细节 – 从得到的信息来看,这个代理正忙或者挂起。
那么我们该如何知道快照代理究竟在做什么呢?
答案:由于快照代理是一个可执行文件(…100\com\snapshot.exe),我们可以通过Windows命令行(CMD窗口)在SSMS之外运行,从而进行故障排除。
下面是具体步骤:
首先,找到SQL Server代理中的快照进程的作业。作业的名字会包含服务器名、数据库名和发布名。下图中的”-3”对应到代理ID(SELECT [id],[name] FROM [distribution].[dbo].[MSsnapshot_agents])——这里并不是关键,只是一个提示。
然后,右击代理,打开属性。在这儿也正好验证一下这个作业确实是快照代理。
选择“Steps”,然后“Run Agent”>“Edit”。我们可以看到被传递到快照代理的命令行参数。这些命令正是我们需要在CMD窗口手动运行的。
选择全部(Select All按钮),点击复制。然后将其与Snapshot.exe的路径一起粘贴到记事本中。不要忘记在路径上包含引号’’
"C:\Program Files\Microsoft SQL Server\100\COM\snapshot.exe" -Publisher [CHRISSK1\SQL2K8] . . .
运行后得到下面的错误:
System.TypeInitializationException: The type initializer for 'Microsoft.SqlServer.Replication.StringResources' threw an exception. ---> System.ApplicationException: The native replication resource dll failed to load.
at Microsoft.SqlServer.Replication.NativeResourceStringLoader..ctor()
at Microsoft.SqlServer.Replication.StringResources..cctor()
--- End of inner exception stack trace ---
at Microsoft.SqlServer.Replication.ReplMessage..ctor(Exception e)
at Microsoft.SqlServer.Replication.HistoryMessage..ctor(Exception e)
at Microsoft.SqlServer.Replication.SnapshotGenerationAgent.SnapshotGenerationAgentMessageFactory.CreateAgentMessage(Exception e)
at Microsoft.SqlServer.Replication.AgentCore.LogMessage(Exception e)
at Microsoft.SqlServer.Replication.AgentCore.ThreadFailedHandler(Exception e)
The type initializer for 'Microsoft.SqlServer.Replication.StringResources' threw an exception.
通过这种方式,我们就可以看到被管理工具过滤掉的一些信息。
接下来,我们发现关键信息是“The native replication resource dll failed to load.”这说明,快照使用的特定于复制的DLL丢失,即:(实际上那是一个RLL)
C:\Program Files\Microsoft SQL Server\100\COM\Resources\1033\REPLRES.rll
后来我们发现其实客户为了整理空间,移动走了一些文件,其中包括这个RLL文件。这个文件是复制代理的通用组件,它的路径在安装时被设定,并标注在注册表中。一旦我们将REPLRES.rll还原到正确的位置,快照代理也就能正确完成了。
综上所述,在复制代理运行时,管理工具有时候会过滤掉一些有用的事件。如果你不确定到底发生了什么,可以试着从命令行去运行代理程序从而得到更多的信息。