SET READ_COMMITTED_SNAPSHOT ON需要多长时间?


76

运行需要多长时间

ALTER DATABASE [MySite] SET READ_COMMITTED_SNAPSHOT ON

我只运行了10分钟。

如何检查它是否适用?


1
哎呀 一直没有启用!!(严重!)解释了僵局。请参阅下面的答案,以获取完整的发现并运行更好的脚本
Simon_Weaver 2012年

2
动作本身几乎立即完成。它不会返回的原因是因为它正在等待其他用户离开数据库。并不是在忙着思考,浪费时间,浪费资源;它正在等待所有人离开房间,因此请通过开关进行更改。
伊恩·博伊德

Answers:


68

您可以使用以下命令检查READ_COMMITTED_SNAPSHOT设置的状态 sys.databases视图。检查is_read_committed_snapshot_on列的值。已问及答

至于持续时间,联机丛书指出,发生这种情况时,无法与数据库建立任何其他连接,但是它不需要单用户模式。因此,您可能会被其他活动连接阻止。运行sp_who(或sp_who2)以查看与该数据库还有其他连接。


谢谢。到目前为止,它花了40分钟,显示为0。它的数据库大小为740mb。手指交叉了我没把它
弄坏

3
尝试针对该数据库打开另一个查询窗口。如果可以,那么我希望您的声明尚未开始运行。
瑞克(Rick)

3
对。在大多数数据库上,只需几秒钟。如果花费的时间更长,则它需要等待另一个(甚至是非活动的)连接终止才能进行更改。因此,您可能需要查找并杀死当前连接的所有spd(在评估它们的作用之后)。然后,它应该可以快速运行。
Michael K. Campbell

16
如果存在其他打开的连接,建议使用NO_WAIT选项立即失败。例如“ ALTER DATABASE通用SET READ_COMMITTED_SNAPSHOT ON NO_WAIT”
StefanR 2012年

1
如果找不到并杀死其他已连接的SPID(或者根本不在乎),则始终可以重新启动SQL Server实例。
David Murdoch 2013年

50

尝试这个:

ALTER DATABASE generic SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE

2
那么“立即回滚”有什么用?这是否意味着当查询失败时它将自动回滚?
高级系统工程师

5
不,“ WITH ROLLBACK IMMEDIATE”意味着它将在启动ALTER DATABASE语句之前立即回滚所有打开的事务。我建议您不要这样做,除非您已经检查了哪些交易未结以及是否可以安全地回滚。
里克(Rick)2012年

令人惊讶的是,还报告了关闭连接的进度。您保存了我们的培根!
Tyeth

31

好的(我是原始提问者),所以这整个过程我什至都没有启用该死的东西。

这是运行以启用快照模式并确保已启用的最终代码

SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'

ALTER DATABASE shipperdb SET allow_snapshot_isolation ON
ALTER DATABASE shipperdb SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE shipperdb SET read_committed_snapshot ON
ALTER DATABASE shipperdb SET MULTI_USER

SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'

即使连接处于活动状态也可以使用(大概可以将它们踢出去)。

您可以看到之前和之后的状态,并且该状态应该几乎立即运行。


重要:

上面的选项READ_COMMITTED_SNAPSHOT对应于.NET中的IsolationLevel.ReadCommitted
的IsolationLevel.ReadCommitted上面的选项ALLOW_SNAPSHOT_ISOLATION对应于.NET中的IsolationLevel.Snapshot

关于不同版本的精彩文章


.NET提示:

好像 Isolationlevel.ReadCommitted即使数据库未启用,也允许在代码中使用。不发出警告。因此,请帮自己一个忙,并确保它像我一样在打开3年之前就已打开!!!

如果您使用的是C#,则可能不需要ReadCommittedIsolationLevel,Snapshot除非您正在此事务中进行写操作。

READ COMMITTED SNAPSHOT乐观阅读和悲观写作。相反,SNAPSHOT乐观读和乐观写。(从这里)

bool snapshotEnabled = true;

using (var t = new TransactionScope(TransactionScopeOption.Required,
               new TransactionOptions
{
     IsolationLevel = IsolationLevel.ReadCommitted
}))
{
     using (var shipDB = new ShipperDBDataContext())
     {

     }
}

另外,您可能会因“无法促进”交易而出错。在.NET Framework 2.0介绍System.Transactions中搜索“促销” 。

除非您执行特殊的操作(例如连接到外部数据库(或第二个数据库)),否则创建新的DataContext这样简单的操作都会导致这种情况。我有一个缓存,在初始化时“缓存”它自己的数据上下文,这试图将事务升级到一个完全分布式的事务。

解决方案很简单:

        using (var tran = new TransactionScope(TransactionScopeOption.Suppress))
        {
            using (var shipDB = new ShipperDBDataContext())
            { 
                 // initialize cache
            }
        }

另请参阅Deadlocked@CodingHorror的文章


4
我想提一提,因为我不确定:您可以READ_COMMITTED_SNAPSHOT独立于打开ALLOW_SNAPSHOT_ISOLATION。你可以ALLOW_SNAPSHOT_ISOLATION 关闭,仍然从中受益READ_COMMITTED_SNAPSHOT成为。已测试:Microsoft SQL Server 2012-11.0.2100.60
Ian Boyd

3
此选项更改了实现READ COMMITTED的方式。禁用此选项后,SQL Server将使用锁来控制访问。这就是为什么您的.NET代码没有生成警告的原因-您仍在以其他方式(并且更有可能发生死锁)完成操作。
理查德

尽管由OP编写,但这不能回答原始问题。它实现了替代方案。
Mike M

9

试试这个代码:

if(charindex('Microsoft SQL Server 2005',@@version) > 0)
begin
    declare @sql varchar(8000)
    select @sql = '
    ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
    ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
    ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'

    Exec(@sql)
end

您应该用quotename()来包装db_name()调用,以解决数据库名称中可能需要转义的任何字符(例如空格)。
里克(Rick)2012年

您还需要'SET allow_snapshot_isolation ON'对吗?(请参阅我的回答)
Simon_Weaver 2012年

mssql文档声称您确实需要设置允许快照隔离。但是,我真的很高兴在SQL Server的喧嚣中找到这个可行的答案。
Amalgovinus

7

我尝试了命令:

ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO

对开发箱,但花了10多分钟,所以我杀死了它。

然后我发现了这一点:

https://willwarren.com/2015/10/12/sql-server-read-committed-snapshot/

并使用了他的代码块(大约花了1:26运行):

USE master
GO

/** 
 * Cut off live connections
 * This will roll back any open transactions after 30 seconds and
 * restricts access to the DB to logins with sysadmin, dbcreator or
 * db_owner roles
 */
ALTER DATABASE MyDB SET RESTRICTED_USER WITH ROLLBACK AFTER 30 SECONDS
GO

-- Enable RCSI for MyDB
ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO

-- Allow connections to be established once again
ALTER DATABASE MyDB SET MULTI_USER
GO

-- Check the status afterwards to make sure it worked
SELECT is_read_committed_snapshot_on
FROM sys.databases
WHERE [name] = 'MyDB '

3

更改当前数据库之前,请尝试使用master数据库。

USE Master
GO

ALTER DATABASE [YourDatabase] SET READ_COMMITTED_SNAPSHOT ON
GO


0

尝试关闭其他SQL服务,以便仅SQL Server服务正在运行。

我跑了5分钟,然后我取消了它,因为很明显什么都没发生。它是一台全新的服务器,因此没有其他用户连接。我关闭了SQL Reporting Services,然后再次运行它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.