SQL Server中tempdb的管理

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

 資料來自:

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

http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/12/21/tempdb-basics.aspx

我們推出了一系列的關於TempDB基礎,監控和問題除錯的博文,也建議大家閱讀有開發和測試部門給出的白皮書http://www.microsoft.com/technet/prodtechnol/sql/2005/workingwithtempdb.mspx

Ø  TempDB基礎

TempDB和其他使用者資料庫一樣以Model資料庫為模板建立,並且可以建立和查詢表格。與其他使用者資料庫不同的是,TempDB在每次SQL Server啟動的時候都會被重新建立。這就意味著:

l  TempDB不需要恢復。因此它不必使用全備份或者大容量日誌記錄恢復模型。事實上,TempDB是配置成簡單恢復模型並且不能改變的。

l  雖然TempDB不需要被恢復,但不是說TempDB上的操作沒有日誌記錄。SQL Server中每個操作都是在顯式或隱式(每個語句都是一個獨立的事務)的事務中完成,這個事務也包含了在TempDB物件上的操作。如果更新全域性臨時表中的行然後回滾事務,是無法撤銷此更改的,除非我們記錄了更新之前的值。不過,也沒有必要記錄更新後的值,因為只有資料庫恢復過程中需要重做事務時這個值才有用。像我之前提到的一樣,TempDB是不需要恢復的,於是沒有理由記錄更新後的值。再舉一個例子讓我們看看插入操作。在一個全域性臨時表中的插入一行,實際值不會被記錄。因為SQL Server不需要這個行值來完成撤消操作,僅僅需要適當地設定頁面中的偏移量,或者這個插入造成頁面被分配或者取消分配。總結起來,我們只需要記錄可能被撤銷的資訊而不需要記錄可能被重做的資訊。這一點關於日誌記錄檔案的變化是由SQLServer 2005開始的。更復雜的情況是,並不是TempDB中所有物件都被日誌檔案記錄。後文會詳細敘述。現在我們來看一個例子說明這一點

use tempdb

go

 

---------------

-- SETUP

---------------

drop table ##t_tempdblog

go

 

-- create a global temp table. Notice, each row is

-- greater than > 1000. I did this so that we can easily

-- identify if the row is indeed logged.

create table ##t_tempdblog (c1 int, c2 char(1000))

go

 

-- load 10 rows into this table

declare @i int

select @i = 0

while (@i < 10)

begin

    insert into ##t_tempdblog values

          (@i, replicate (cast ('a' as varchar), 1000))

select @i = @i+1

end

 

--Now run the following command to see the log records

select top 10 operation,context,

      [log record fixed length],

      [log record length]

from fn_dblog(null, null)

where allocunitname='dbo.##t_tempdblog'

order by [Log Record Length] Desc

這是上述查詢的輸出。您將注意到的所有日誌記錄都 < 100 位元組,顯然插入的行沒有被記錄。

operation       context    log record fixed length    log record length

-----------------------------------------------------------------------

LOP_MODIFY_ROW  LCX_IAM            62                      88

LOP_MODIFY_ROW  LCX_IAM            62                      88

LOP_FORMAT_PAGE LCX_HEAP           80                      84

LOP_FORMAT_PAGE LCX_IAM            80                      84

LOP_FORMAT_PAGE LCX_HEAP           80                      84

LOP_MODIFY_ROW  LCX_PFS            62                      80

LOP_MODIFY_ROW  LCX_PFS            62                      80

LOP_INSERT_ROWS LCX_HEAP           62                      72

LOP_INSERT_ROWS LCX_HEAP           62                      72

LOP_INSERT_ROWS LCX_HEAP           62                      72

於是,這就證明了TempDB的日誌和其他使用者資料庫不同。將上面同樣的例子操作應用於使用者資料庫,日誌記錄會成為這個樣子:

operation             context   log record fixed length log record length

----------------------------------------------------------------------

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

LOP_INSERT_ROWS      LCX_HEAP          62                      1101

LOP_INSERT_ROWS      LCX_HEAP          62                      1104

這就證明了,撤銷確實會被日誌記錄。實驗時做了以下操作:

  update ##t_tempdblog set c2 =

            replicate (cast ('b' as varchar), 1000)

之後,做這樣的查詢:

select top 10 operation,context,

       [log record fixed length], [log record length]

from fn_dblog(null, null)

where allocunitname='dbo.##t_tempdblog'

order by [Log Record Length] Desc

以下是輸出內容,你會發現日誌的長度超過1000位元組,事實上列C2更新之前的值被記錄了。

operation          context    log record fixed length log record length

-----------------------------------------------------------------------

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072

LOP_MODIFY_ROW     LCX_HEAP       62                      1072



相關文章