我应该跑吗
ALTER DATABASE DbName SET ALLOW_SNAPSHOT_ISOLATION OFF
是否暂时使用快照事务(TX)隔离(iso)? 换句话说,
在SQL Server中启用(但暂时不使用)的成本是多少?
- 更新:
在数据库上启用快照TX iso级别不会将READ COMMITTED tx iso更改为默认值
您可以通过运行来检查它:
use someDbName;
--( 1 )
alter database someDbName set allow_snapshot_isolation ON;
dbcc useroptions;
最后一行显示当前会话的tx iso级别为(读取已提交)。
因此,启用快照tx iso级别而不更改它不会使用它等 为了使用它,应该发出
--( 2 )
SET TRANSACTION ISOLATION LEVEL SNAPSHOT
UPDATE2:
我重复[1]中的脚本,但启用了SNAPSHOT(但没有打开)但没有启用READ_COMMITTED_SNAPSHOT
--with enabling allow_snapshot_isolation
alter database snapshottest set allow_snapshot_isolation ON
-- but without enabling read_committed_snapshot
--alter database snapshottest set read_committed_snapshot ON
-- OR with OFF
alter database snapshottest set read_committed_snapshot OFF
go
执行
时没有结果/行select * from sys.dm_tran_version_store
执行INSERT,DELETE或UPDATE
后你能给我提供一些脚本,说明通过(1)启用SNAPSHOT tx iso级别但是没有打开(2)会在tempdb中生成任何版本和/或增加每行14个字节的数据大小吗?> 真的,我不明白版本控制的重点是,如果它是由(1)启用但未使用(未由(2)设置)?
[1]
在SQL Server中管理TempDB:TempDB基础知识(版本存储:简单示例)
http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/12/31/managing-tempdb-in-sql-server-tempdb-basics-version-store-simple-example.aspx
答案 0 :(得分:21)
只要在数据库中启用了行版本控制(又称快照),就必须对所有写入进行版本控制。在写入发生的隔离级别下无关紧要,因为隔离级别总是影响仅读取。一旦启用了数据库行版本控制,任何插入/更新/删除都将:
同样,使用什么隔离级别完全无关紧要。请注意,如果满足以下任何条件,则也会发生行版本控制:
所有这些都在Row Versioning Resource Usage中解释:
每个数据库行最多可使用14个 行末尾的字节数 版本信息。排 版本信息包含 交易序列号 提交版本的事务 和指向版本化行的指针。 这14个字节是第一个添加的 修改行的时间,或者 在 任意 下插入新行 这些条件:
- READ_COMMITTED_SNAPSHOT或ALLOW_SNAPSHOT_ISOLATION选项 ON。
- 该表有一个触发器。
- 正在使用多个活动结果集(MARS)。
- 目前正在桌面上运行在线索引构建操作。
...
必须存储行版本 只要活动交易需要 访问它。 ...如果它符合 任何 以下条件:
- 它使用基于行版本控制的隔离。
- 它使用触发器,MARS或在线索引构建操作。
- 它会生成行版本。
<强>更新强>
:setvar dbname testsnapshot
use master;
if db_id('$(dbname)') is not null
begin
alter database [$(dbname)] set single_user with rollback immediate;
drop database [$(dbname)];
end
go
create database [$(dbname)];
go
use [$(dbname)];
go
-- create a table before row versioning is enabled
--
create table t1 (i int not null);
go
insert into t1(i) values (1);
go
-- this check will show that the records do not contain a version number
--
select avg_record_size_in_bytes
from sys.dm_db_index_physical_stats (db_id(), object_id('t1'), NULL, NULL, 'DETAILED')
-- record size: 11 (lacks version info that is at least 14 bytes)
-- enable row versioning and and create an identical table
--
alter database [$(dbname)] set allow_snapshot_isolation on;
go
create table t2 (i int not null);
go
set transaction isolation level read committed;
go
insert into t2(i) values (1);
go
-- This check shows that the rows in t2 have version number
--
select avg_record_size_in_bytes
from sys.dm_db_index_physical_stats (db_id(), object_id('t2'), NULL, NULL, 'DETAILED')
-- record size: 25 (11+14)
-- this update will show that the version store has records
-- even though the isolation level is read commited
--
begin transaction;
update t1
set i += 1;
select * from sys.dm_tran_version_store;
commit;
go
-- And if we check again the row size of t1, its rows now have a version number
select avg_record_size_in_bytes
from sys.dm_db_index_physical_stats (db_id(), object_id('t1'), NULL, NULL, 'DETAILED')
-- record size: 25
答案 1 :(得分:1)
默认情况下,您将快照隔离关闭,如果将其打开,SQL将维护用于运行事务的数据快照。 示例:在连接1上,您正在运行大选择。在连接2上,您将更新将首先选择返回的一些记录。
在快照隔离开启时,SQL将生成受更新影响的数据的临时副本,因此SELECT将返回原始数据。
任何其他数据操作都会影响性能。这就是默认情况下此设置为OFF的原因。