完全復旧モデルを使用しているデータベースを想定して、SQL Serverでレコードが(INSERT
/ UPDATE
などによって)書き込まれると、先読みロギングにより、データページを変更する前に変更がログファイルに書き込まれることが保証されます。
ログとデータページの両方のエントリがRAMに作成され、後でチェックポイントによってディスクにコミットされます。
システムクラッシュ(議論のために電力損失)が発生した場合、RAMの内容がシステムの再起動後も存続しないため、ダーティページ(RAMで変更されてもディスクにコミットされないIEデータ)はどうなりますか? ?
編集
いくつかのテストの後、ダーティページが失われていないことがわかりますが、理由はわかりません。
テストデータベースを作成する
CREATE DATABASE DirtyPagesDB
GO
USE DirtyPagesDB
GO
自動チェックポイントをオフにする
DBCC TRACEON(3505, -1);
DBCC TRACESTATUS();
テーブルを作成し、データを挿入して、チェックポイントを発行します。
CREATE TABLE t1 (Speaker_Bio CHAR(8000))
GO
INSERT INTO t1 VALUES ('SQL'),('Authority')
GO
CHECKPOINT
ダーティページがないことを確認する
-- Get the rows of dirtied pages
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'
);
GO
最後のチェックポイントの時間を確認する
SELECT f1.[Checkpoint Begin], f2.[Checkpoint End]
FROM fn_dblog(NULL, NULL) f1
JOIN fn_dblog(NULL, NULL) f2
On f1.[Current LSN] = f2.[Previous LSN]
WHERE f2.Operation IN (N'LOP_BEGIN_CKPT', N'LOP_END_CKPT');
さらに行を追加
INSERT INTO t1 VALUES ('SQL'),('Authority')
上記のクエリを使用して、ダーティページがあったことを確認します
タスクマネージャーからSQL Serverタスクを強制終了して、電源オフをシミュレートします。
サービスを開始する
上記のコマンドを再実行して、最後のチェックポイント時間を取得しました。これは同じでした(つまり、手動で実行したもの以外にチェックポイントが実行されていません)。
テーブルt1から選択され、4つのレコードすべてがそこにありました