C# SQL Server Service Broker外部激活程序检查点错误

C# SQL Server Service Broker外部激活程序检查点错误,c#,sql-server,service-broker,C#,Sql Server,Service Broker,我们已经使用Microsoft的Service Broker External Activator服务一段时间了,可以毫无问题地处理Service Broker队列的外部激活。但在过去的一周里,一个错误不断发生,我无法弄清到底 每天至少有一次,在随机时间,服务将遇到错误并陷入停止状态。此时,所能做的就是终止进程并重新启动服务。检查EATrace.log文件会发现以下错误: 18/07/2018 09:59:45 EXCEPTION ERROR = 90, Internal exceptions

我们已经使用Microsoft的Service Broker External Activator服务一段时间了,可以毫无问题地处理Service Broker队列的外部激活。但在过去的一周里,一个错误不断发生,我无法弄清到底

每天至少有一次,在随机时间,服务将遇到错误并陷入停止状态。此时,所能做的就是终止进程并重新启动服务。检查EATrace.log文件会发现以下错误:

18/07/2018 09:59:45 EXCEPTION
ERROR = 90, Internal exceptions have occurred when External Activator is runtime checkpointing.
18/07/2018 09:59:45 EXCEPTIONDETAILS Inner Exception:
18/07/2018 09:59:45 EXCEPTIONDETAILS System.IO.IOException: Cannot create a file when that file already exists.
18/07/2018 09:59:45 EXCEPTIONDETAILS 
18/07/2018 09:59:45 EXCEPTIONDETAILS    at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
18/07/2018 09:59:45 EXCEPTIONDETAILS    at System.IO.File.Move(String sourceFileName, String destFileName)
18/07/2018 09:59:45 EXCEPTIONDETAILS    at ExternalActivator.LogManager.SaveRecoveryContext(LogRecoveryContext recoveryContext)
18/07/2018 09:59:45 EXCEPTIONDETAILS    at ExternalActivator.LogManager.Checkpoint(LogRecoveryContext recoveryContext)
18/07/2018 09:59:45 EXCEPTIONDETAILS    at ExternalActivator.LogManager.Log(LogRecord recoveryLogRec)
18/07/2018 09:59:45 EXCEPTIONDETAILS    at ExternalActivator.ApplicationMonitor.OnProcessExited(ProcessMonitor processMonitor)
18/07/2018 09:59:45 EXCEPTIONDETAILS    at ExternalActivator.ProcessMonitor.NotifySubscriber()
18/07/2018 09:59:45 EXCEPTIONDETAILS    at ExternalActivator.ProcessMonitor.OnProcessExited(Object a, EventArgs b)
使用Reflector,我发现存在问题的SaveRecoveryContext方法:

private void SaveRecoveryContext(LogRecoveryContext recoveryContext)
    {
      this.m_file = File.Open(this.TempLogFileName, FileMode.Create, FileAccess.Write, FileShare.Read);
      foreach (LogRecord recoveryLogRec in recoveryContext.List)
        this.Write(recoveryLogRec);
      this.CloseFiles();
      File.Delete(this.LogFileName);
      File.Move(this.TempLogFileName, this.LogFileName);
      this.m_file = File.Open(this.LogFileName, FileMode.Append, FileAccess.Write, FileShare.Read);
    }
请注意,日志文件名是EARecovery.rlog,templalogfilename是EARecovery_temp.rlog。错误发生后检查日志文件夹时,只有临时文件,原始文件已按预期删除

我的第一个想法是,可能有多个线程同时尝试检查点,并且彼此绊倒,但沿着堆栈跟踪向上走,我们会看到以下情况:

public void Log(LogRecord recoveryLogRec)
    {
      lock (this)
      {
        this.Write(recoveryLogRec);
        if (!recoveryLogRec.CanCompress)
          return;
        ++this.m_recordsToCompress;
        if (this.m_recordsToCompress <= 100)
          return;
        LogRecoveryContext local_0 = new LogRecoveryContext();
        string local_1 = Global.GetEaContext();
        Global.SetEaContext(Localized.GL_EaContext_RuntimeCheckpoint);
        this.Checkpoint(local_0);
        Global.SetEaContext(local_1);
      }
    }
公共作废日志(LogRecord RecoveryLogc)
{
锁(这个)
{
这个。写(recoveryLogRec);
如果(!RecoveryGrec.CanCompress)
返回;
++此.m_记录压缩;

if(this.m_recordsToCompress这不是特定于Service broker的,但我以前见过这种情况,尤其是代码:

  File.Delete(this.LogFileName);
  File.Move(this.TempLogFileName, this.LogFileName);
如果后台进程(如防病毒软件)使文件处于打开状态,则文件可能不会立即消失。如果您运行的是防病毒软件,如Windows Defender或其他一些产品,则可能需要将文件夹列为白名单,以便它不会尝试扫描文件


我唯一能提出的另一个建议,也是不相关的,就是清除Windows临时文件夹。几年前我遇到了一个问题,根据Windows如何命名或内部跟踪临时文件,创建大量临时文件会导致Windows出现问题。我没有你的链接,我认为这不是你的问题,但你需要做一些事情可能想试试。

谢谢Mike,我没有考虑到这种可能性。我已从Windows Defender中排除了相关文件夹,并将检查其是否达到预期效果。24小时后,错误没有再次发生,因此我暂时对您找到原因持乐观态度。非常感谢您的帮助。