SQL Server中TempDB管理(版本儲存區的一個example)

發糞塗牆發表於2012-06-07

原文來自:

http://blogs.msdn.com/b/sqlserverstorageengine/archive/tags/tempdb/

http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/12/31/managing-tempdb-in-sql-server-tempdb-basics-version-store-simple-example.aspx

我們從一個例子開始來了解版本儲存區。本例中資料庫啟用RCSI(使用行版本控制的已提交讀隔離級別)和SI(快照隔離級別)。

當資料庫啟用了RCSI或者SI時,每當行有更新時就會建立一個行版本。此行版本在版本儲存器儲存到不需要為止。那麼SQL Server什麼時候不再儲存這個行版本呢?您可能聯想到一些相關的問題,比如,如果不回收(刪除)行版本會有什麼影響?一次回收一個還是一組行版本?每個使用者表都有不同的結構,那麼SQL Server是不是分別儲存每個表的行版本的?行版本控制的開銷大不大?

首先,我們建立一個資料庫並開啟SI/RCSI

create database snapshottest

go

 

-- Setting database for snapshot based isolations. AS you can

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

alter database snapshottest set read_committed_snapshot ON

go

 

alter database snapshottest set allow_snapshot_isolation ON

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

from sys.databases

where name='snapshottest'

go

 

--create a table with each row > 1000 bytes

create table  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

insert into t_version values (@i, 'hello')

set @i = @i + 1

end

 

接下來可以通過DMV檢視版本儲存區,你會發現顯示版本儲存區行數為0,這是我們實驗的第一個結論,插入(Insert)命令不會產生行版本,因為根本沒有之前的版本可言(有一個特例使插入產生行版本,我們將稍後討論)。這同時意味著批量匯入也不會產生行版本。

select COUNT(*) from sys.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

select COUNT(*) from sys.dm_tran_version_store

 

請注意,我們沒有使用顯式事務,因此這個Update語句是一個隱式事務,並且是這個隱式事務中唯一的語句。同時沒有併發的事務需要使用行版本,所以這些行版本會被SQL Server當做垃圾資料處理。如果過幾分鐘在執行下面語句,就能發現行版本被回收處理了。

 

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

select COUNT(*) from sys.dm_tran_version_store

         SQL Server根據事務狀態判斷版本是否不再需要,從而決定垃圾處理該版本。在最差的情況下,如果有一個長事務正在執行,而且這個長事務要麼建立了行版本要麼需要用到它,那麼這個行版本就不能被刪除,版本儲存區就會一直增長甚至會用盡TempDb的空間,就像長事務可以用盡事務日誌空間一樣。關於這一點我們會在稍後詳述。

         和UPDATE操作一樣,如果行被刪除也會建立行版本。

 

相關文章