在还原SQL Server数据库之前等待连接关闭

时间:2009-06-25 18:13:55

标签: sql-server sql-server-2008 replication

我有一个使用两个数据库的Web应用程序。 DB1用户执行其CRUD(创建,读取,更新,删除)操作。数据库DB2是我用于报告目的的其他服务器上的只读数据库。每小时我的DB1保存事务日志,并且在DB2上我有一个工作可以在DB2上恢复它们​​以保持最新状态。

我面临的问题是,如果有用户在DB2上运行报告(经常发生),他们会从sql server断开连接,因为我获得了恢复数据库的独占访问权限。恢复每个日志所需的时间在1-4分钟之间。

如何在将数据库切换到独占访问权限并恢复日志之前,我的作业等待用户的查询完成后,如何实现我们称之为wait-n-restore功能?

我的两台机器都运行SQL Server 2008 64位标准版

5 个答案:

答案 0 :(得分:2)

我的问题很大一部分是使用池化连接 - 在这种情况下,即使没有执行任何报告,连接也会保持活动状态。我修改了我的连接字符串,将连接池设置为false,并在循环中检查打开的用户与报告数据库的连接,直到值为0.幸运的是,我没有创建触发器来退出用户。

答案 1 :(得分:1)

您可能有一个alter database Setting Single User或Admin模式,其中包含“WITH IMMEDIATE ROLLBACK”。这就是踢出用户的原因。拿出那个条款,等待它们离开(但不会阻止新的进入)。

RE:你杀了sProc:你可能想看一下“WITH IMMEDIATE ROLLBACK”选项。

至于防止新连接:我过去所做的是禁用应用程序用户的登录(服务器主体),每分钟等待最多10分钟检查是否每个人都出去了。之后,我执行ALTER DATABASE ...使用IMMEDIATE ROLLBACK,然后执行任何需要执行的OPS功能。

我很幸运,因为Logins总是一次性使用应用程序用户登录(即,仅为此目的的SQL登录)如果你不能这样做,那么我现在唯一可以想到的事情就是是拒绝DB用户(数据库主体)的CONNECT权限。然后在以后改装DENY。我从来没有像这样做过,但它应该是这样的:

DENY CONNECT TO SomeDBUserName;

答案 2 :(得分:1)

我认为您的恢复是作为一项工作而发生的。那么你需要的是一个登录触发器。以下是创建登录触发器的方法:

登录触发器

建立会话时会触发登录触发器。此时,引发了LOGON事件。

登录触发器的生命周期非常简单:用户连接到Sql Server,触发器触发,隐式事务被打开然后由您决定!如果出于任何原因,您想要拒绝尝试登录Sql Server,只需发出ROLLBACK语句就可以了。

以下是一个示例登录触发器:

USE master;
GO
CREATE LOGIN security_login WITH PASSWORD = 'P@ssw0rd'; 
GO
GRANT VIEW SERVER STATE TO security_login;
GO
CREATE TRIGGER connection_deny_trigger
ON ALL SERVER WITH EXECUTE AS 'security_login'
FOR LOGON
AS
BEGIN
<*Your conditional code goes here*>
    ROLLBACK;
END;

您可以定义您的工作:

  • 步骤1:启用登录触发器
  • 第2步:检查打开的用户 连接到您的报告数据库 循环直到值为0

    SELECT COUNT(*) from sysprocesses where spid in(
    SELECT session_id FROM sys.dm_exec_sessions WHERE is_user_process = 1) AND
    dbid= DB_ID('YourReportingDatabase')
    
  • 步骤3:将DB设置为单个用户和 恢复日志

  • 步骤4:将DB重置为多用户并禁用登录触发

拉​​吉

答案 3 :(得分:0)

报告是否可以重定向到其他数据库名称?如果是,您可以创建DB2的数据库快照,并从这些快照运行报告。每次日志还原后,您都会创建一个新快照,并将其标记为“当前快照”,并且所有报告将开始针对此快照运行。发送新日志时,将创建新快照,新报告将针对新快照,而旧的,正在运行的报告将保留在上一个快照中。当使用旧快照完成上一个报告并且不再有用户引用它时,可以删除它。这样就不会以额外存储为代价中断任何报告:每个新日志都会导致旧快照开始执行受影响页面的“写时复制”。

答案 4 :(得分:0)

备份是否需要每小时进行一次,或者另一种复制方法是否比您设置的自定义流程更能满足您的需求?您可以进行日志传送,可以将其配置为每小时发送一次,SQL Server将本地处理它,在日志恢复时阻止用户。

我可以看到你的问题,我不认为SQL Server具有你正在寻找的功能(在允许现有连接完成的情况下阻止新连接),但还有其他的解决方法可以提供相同的功能复制功能,可以更好地满足您的业务需求。