SET-ting ALLOW_SNAPSHOT_ISOLATION ON 有何含义?

发布于 2024-09-30 17:09:12 字数 1568 浏览 7 评论 0原文

我是否应该运行

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 后

您能为我提供说明已启用 SNAPSHOT tx iso 级别的脚本吗by ( 1 ) 但未通过 ( 2 ) 打开会在 tempdb 中产生任何版本和/或增加每行 14 字节的数据大小?
我真的不明白如果版本控制由( 1 )启用但未使用(未由( 2 )设置),那么版本控制的意义是什么?

[1]
在 SQL Server 中管理 TempDB:TempDB 基础知识(版本存储:简单示例)
链接

Should I run

ALTER DATABASE DbName SET ALLOW_SNAPSHOT_ISOLATION OFF

if snapshot transaction (TX) isolation (iso) is not temporarily used?
In other words,

  • why should it be enabled, in first place?
  • Why isn't it enabled by default?

What is the cost of having it enabled (but temporarily not used) in SQL Server?


--Update:
enabling of snapshot TX iso level on database does not change READ COMMITTED tx iso to be default.
You may check it by running:

use someDbName;
--( 1 )
alter database someDbName set allow_snapshot_isolation ON;
dbcc useroptions;

the last row shows that tx iso level of current session is (read committed).

So, enabling snapshot tx iso level without changing to it does not use it, etc
In order to use it one should issue

--( 2 )
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

Update2:
I repeat the scripts from [1] but with SNAPSHOT enabled (but not switched on) but without enabling 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

There no results/rows from from executing

select * from sys.dm_tran_version_store

after executing INSERT, DELETE or UPDATE

Can you provide me with scripts illustrating that enabled SNAPSHOT tx iso level by ( 1 ) but not switched on by ( 2 ) produces any versions in tempdb and/or increase the size of data with 14 bytes per row?
Really I do not understand what is the point in versioning if it is enabled by ( 1 ) but not used (not set on by ( 2))?

[1]
Managing TempDB in SQL Server: TempDB Basics (Version Store: Simple Example)
Link

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

涙—继续流 2024-10-07 17:09:12

一旦在数据库中启用行版本控制(又名快照),所有写入都必须进行版本控制。在什么隔离级别下进行写入并不重要,因为隔离级别始终影响读取。一旦启用数据库行版本控制,任何插入/更新/删除都将:

  • 将数据大小增加为每行 14 字节
  • 可能会在版本存储 (tempdb) 中更新之前创建数据的映像

同样,这是完全不相关的使用什么隔离级别。请注意,如果满足以下任一条件,也会发生行版本控制:

  • 表具有触发器
  • 表具有触发器在连接上启用了 MARS
  • 在线索引操作正在表上运行

所有这些均在 行版本控制资源使用情况

每个数据库行最多可以使用 14
行末尾的字节数
版本控制信息。行
版本控制信息包含
交易序列号
提交版本的事务
以及指向版本化行的指针。
这 14 个字节被添加到第一个
修改行的时间,或者当
新行已插入
,位于任何
这些条件:

  • READ_COMMITTED_SNAPSHOT 或 ALLOW_SNAPSHOT_ISOLATION 选项是
    开。
  • 该表有一个触发器。
  • 正在使用多个活动结果集 (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

As soon as row versioning (aka. snapshot) is enabled in the database all writes have to be versioned. It doesn't matter under what isolation level the write occurred, since isolation levels always affect only reads. As soon the database row versioning is enabled, any insert/update/delete will:

  • increase the size of data with 14 bytes per row
  • possibly create an image of the data before the update in the version store (tempdb)

Again, it is completely irrelevant what isolation level is used. Note that row versioning occurs also if any of the following is true:

  • table has a trigger
  • MARS is enabled on the connection
  • Online index operation is running on the table

All this is explained in Row Versioning Resource Usage:

Each database row may use up to 14
bytes at the end of the row for row
versioning information. The row
versioning information contains the
transaction sequence number of the
transaction that committed the version
and the pointer to the versioned row.
These 14 bytes are added the first
time the row is modified, or when a
new row is inserted
, under any
of these conditions:

  • READ_COMMITTED_SNAPSHOT or ALLOW_SNAPSHOT_ISOLATION options are
    ON.
  • The table has a trigger.
  • Multiple Active Results Sets (MARS) is being used.
  • Online index build operations are currently running on the table.

...

Row versions must be stored for as
long as an active transaction needs to
access it. ... if it meets any of the
following conditions:

  • It uses row versioning-based isolation.
  • It uses triggers, MARS, or online index build operations.
  • It generates row versions.

Update

: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
带上头具痛哭 2024-10-07 17:09:12

默认情况下,快照隔离处于关闭状态。如果将其打开,SQL 将维护正在运行的事务的数据快照。
示例:在连接 1 上,您正在运行 big select。在连接 2 上,您更新了第一次选择将返回的一些记录。

在快照隔离打开时,SQL 会临时复制数据,受更新影响,因此 SELECT 将返回原始数据。

任何额外的数据操作都会影响性能。这就是为什么此设置默认为关闭的原因。

By default, you have snapshot isolation OFF, If you turn it ON, SQL will maintain snapshots of data for running transactions.
Example: On connection 1, you are running big select. On connection 2, you update some of the records that are going to be returned by first select.

In snapshot isolation ON, SQL will make a temporary copy of the data, affected by update, so SELECT will return original data.

Any additional data manipulation will affect performance. That's why this setting is OFF by default.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文