dirty page是指在buffer cache中已被修改過的頁面,這些頁面由於尚未寫入disk file中,此時頁面在buffer cach跟disk file中的內容是不同的;所以形象的將此頁面稱為dirty。
dirty page它並不指是uncommitted的頁面。
PS:
容易混淆的一點是所謂「dirty read」,是否可以dirty read並不是指是否允許讀dirty page,而是指是否允許讀uncommitted的資料。有人會將uncommitted page稱為 dirty page,這是一個誤解。
我們知道當checkpoint發生時,會將所有的dirty page寫入disk file;即使是uncommitted的頁面。
底下測試,我們開啟一個交易去update資料,但不做 commit,在未commit前,手動執行一次checkpoint,將dirty page 寫入disk file。觀察dirty page的變化,便可得知uncommitted的頁面,是否仍算是dirty page。
以下列指令檢查目前DB中,有沒有任何的 dirty page
SELECT
database_name = d.name,
OBJECT_NAME =
CASE au.TYPE
WHEN 1 THEN o1.name
WHEN 2 THEN o2.name
WHEN 3 THEN o1.name
END,
OBJECT_ID =
CASE au.TYPE
WHEN 1 THEN p1.OBJECT_ID
WHEN 2 THEN p2.OBJECT_ID
WHEN 3 THEN p1.OBJECT_ID
END,
index_id =
CASE au.TYPE
WHEN 1 THEN p1.index_id
WHEN 2 THEN p2.index_id
WHEN 3 THEN p1.index_id
END,
bd.FILE_ID,
bd.page_id,
bd.page_type,
bd.page_level
FROM sys.dm_os_buffer_descriptors bd
INNER JOIN sys.databases d
ON bd.database_id = d.database_id
INNER JOIN sys.allocation_units au
ON bd.allocation_unit_id = au.allocation_unit_id
LEFT JOIN sys.partitions p1
ON au.container_id = p1.hobt_id
LEFT JOIN sys.partitions p2
ON au.container_id = p2.partition_id
LEFT JOIN sys.objects o1
ON p1.OBJECT_ID = o1.OBJECT_ID
LEFT JOIN sys.objects o2
ON p2.OBJECT_ID = o2.OBJECT_ID
WHERE is_modified = 1
AND d.name = 'DirtyPagesDB'
AND
(
o1.name = 't1'
OR o2.name = 't1'
);
目前DB中,沒有任何的 dirty page
先暫停自動checkoint,然後update Table某筆資料
請問一下
回覆刪除那如果我有筆未commit的資料
因為做了CKPT的關係寫進了file裡面
假設我後來rollback了
那transaction log裡面會有這筆紀錄嗎
謝謝
會的,請參考我的另一篇文章
回覆刪除http://sqlworker.blogspot.tw/2016/11/commit-transaction-log.html