Heim  >  Artikel  >  Datenbank  >  SQL Server中TempDB管理(版本存储区的一个example)

SQL Server中TempDB管理(版本存储区的一个example)

WBOY
WBOYOriginal
2016-06-07 17:54:101214Durchsuche

我们从一个例子开始来了解版本存储区。本例中数据库启用RCSI(使用行版本控制的已提交读隔离级别) 和 SI( 快照隔离级别 )。 当数据库启用了RCSI或者SI时,每当行有更新时就会创建一个行版本。此行版本在版本存储器保存到不需要为止。那么SQL Server什么时候

我们从一个例子开始来了解版本存储区。本例中启用RCSI(使用行版本控制的已提交读隔离级别)SI(快照隔离级别)。

当数据库启用了RCSI或者SI时,每当行有更新时就会创建一个行版本。此行版本在版本存储器保存到不需要为止。那么SQL Server什么时候不再保存这个行版本呢?您可能到一些相关的问题,比如,如果不回收(删除)行版本会有什么影响?一次回收一个还是一组行版本?每个用户表都有不同的结构,那么SQL Server是不是分别存储每个表的行版本的?行版本控制的开销大不大?

首先,我们创建一个数据库并开启SI/RCSI

createdatabasesnapshottest

go

 

-- Setting databaseforsnapshot based isolations. AS you can

-- see that enabling SI/RCSI is a simple DDL operation.

alterdatabase snapshottest setread_committed_snapshotON

go

 

alterdatabase snapshottest setallow_snapshot_isolationON

go

 

-- check the snapshot state of the database and it will

-- show that both SI and RCSI have been enabled.

select is_read_committed_snapshot_on,

  snapshot_isolation_state_desc,

        snapshot_isolation_state

fromsys.databases

where name='snapshottest'

go

 

--create a table with each row > 1000 bytes

createtable t_version(c1 int, c2 char(1000))

go

 

--Load 50 rows. Note,I start the transaction but did not

--commit it yet.

Begin tran

declare @i int

select @i = 0

while (@i 50)

begin

insertinto t_version values (@i,'hello')

set @i = @i + 1

end

 

接下来可以通过DMV查看版本存储区,你会发现显示版本存储区行数为0,这是我们实验的第一个结论,插入(Insert)命令不会产生行版本,因为根本没有之前的版本可言(有一个特例使插入产生行版本,我们将稍后讨论)。这同时意味着批量导入也不会产生行版本。

selectCOUNT(*)fromsys.dm_tran_version_store

-- Now commit the transaction

commit

 

接下来让我们更新表格中的前50行。因为行数据被更新了,SQL Server将复制旧版本进入版本存储区。所以版本存储区中将有50行行版本。

-- update all the rows in the table

update t_version set c2 ='test10'

 

-- the following statement returns the count of versioned row.

-- And, for the case here, it will return 50

selectCOUNT(*)fromsys.dm_tran_version_store

 

请注意,我们没有使用显式事务,因此这个Update语句是一个隐式事务,并且是这个隐式事务中唯一的语句。同时没有并发的事务需要使用行版本,所以这些行版本会被SQL Server当做垃圾数据处理。如果过几分钟在运行下面语句,就能发现行版本被回收处理了。

 

-- the following statement returns 0 if run after a minute or so

selectCOUNT(*)fromsys.dm_tran_version_store

         SQL Server根据事务状态判断版本是否不再需要,从而决定垃圾处理该版本。在最差的情况下,如果有一个长事务正在运行,而且这个长事务要么创建了行版本要么需要用到它,那么这个行版本就不能被删除,版本存储区就会一直增长甚至会用尽TempDb的空间,就像长事务可以用尽事务日志空间一样。关于这一点我们会在稍后详述。

 

和UPDATE操作一样,如果行被删除也会创建行版本。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn