次のチェックポイントの前にシステムに障害が発生した場合、ダーティページはどうなりますか?


8

完全復旧モデルを使用しているデータベースを想定して、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つのレコードすべてがそこにありました

回答:


15

ログとデータページの両方のエントリがRAMに作成され、後でチェックポイントによってディスクにコミットされます。

このステートメントは完全に真実ではありません。チェックポイント(およびレイジーライター)によってデータページがディスクに書き込まれるのは正しいことです。ただし、ログレコードは、トランザクションがコミットされたときに物理的にディスクに書き込まれ、トランザクションの持続性が保証されます。コミットされたトランザクションデータは、メモリのみに常駐することは決してありません(遅延耐久性を除く)。

すべてのデータ変更は最初にログに書き込まれ(先書きロギング)、その後にダーティページが書き込まれます。ページとログレコードには、ディスク上のコミットされたデータとコミットされていないデータの両方が含まれる場合があります。

復旧モデルに関係なく、SQL Serverはクラッシュ復旧中に最後のチェックポイントまでログをスキャンし、そのポイントからのすべてのデータ変更をロールフォワードし、最後にコミットされていないトランザクションをロールバックします。


@ SEarle1986、この回答があなたの理解を助けてくれてうれしいです。「SQL Serverには、関連するログレコードが書き込まれる前にダーティページがフラッシュされないようにするロジックがあります。トランザクションがコミットされると、ログレコードがディスクに書き込まれます。」
Dan Guzman、

最小限のログ操作では、スペース割り当て(IAM、PFS、およびGAM構造への変更)がロールフォワードされ、コミットされていない場合はロールバックされるため、操作はオールオアナシーになります。一括挿入によってデータページに加えられた変更は、操作中に物理的に書き込まれたため、ロールフォワードする必要はありません(データファイルIOがレイジーライターとチェックポイントを介して非同期である通常のログ操作とは異なります)。
Dan Guzman、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.