誤って切り捨てを実行したことがありますか 間違ったテーブルでコマンド?これにより、すべてのデータが失われます。最悪のことは、データを取り戻す機会がないことです。この記事では、このような状況を回避する方法を確認し、ロールバック切り捨てを行う機会があります。 。
ロールバック切り捨てはできません
単純に、トランザクションがすでにコミットされている場合、トランザクションをロールバックすることはできませんが、データ(または少なくともその一部)を取り戻すために何か他のことを行うことはできます。
TRUNCATEを実行するとき ステートメントでは、データはまだMDFファイルにあります。ただし、SQL Serverはこれを空き領域( TRUNCATE )として処理しているため、表示されません。 SQLServerにデータページの割り当てを解除するように指示しています。
データを取り戻す唯一の方法は、割り当てを解除したデータページを何らかの方法で読み取り、読み取り可能なデータに変換することです。
空き領域はまだ新しいデータで上書きされるため、迅速に対応する必要があります。 SQL Serverインスタンスを停止し、MDFファイルとLDFファイルのコピーを作成して、より多くの時間を費やすことができる場合。
この種の復元を実行できるツールがいくつかあります。
ロールバック切り捨てが可能
切り捨て はログに記録される操作ですが、SQL Serverはテーブルを切り捨てるため、すべての行をログに記録するわけではありません。 SQL Serverは、 TRUNCATEという事実のみをログに記録します 操作が発生しました。また、割り当てが解除されたページとエクステントに関する情報もログに記録されます。ただし、これらのページを再割り当てするだけで、ロールバックするのに十分な情報があります。ログバックアップには、 TRUNCATE TABLEの情報のみが必要です。 発生した。 TRUNCATE TABLEを復元するには 、操作が再適用されます。 RESTORE中に関連するデータは必要ありません( BULK INSERT のような真の「最小限にログに記録された」操作の場合のように) 。
SQL Serverは、排他ロックでロックされている限り、どのページがテーブルに属しているかを認識しており、すべてのXロックと同様に、トランザクションが終了するまで保持されます。そのため、ページやエクステントの割り当てを解除することはできず、確かに再利用することもできません。
次に例を示します:
504行とページ数を取得しました。次に、行数とテーブルに属するページを確認します。
BEGIN TRAN TRUNCATE TABLE dbo.Products; SELECT COUNT(*) FROM dbo.Products; DBCC IND('AdventureWorks', 'Products', -1); DBCC EXTENTINFO('AdventureWorks', 'Products', -1); SELECT resource_type, resource_description, request_mode FROM sys.dm_tran_locks WHERE resource_type IN ('EXTENT', 'PAGE') AND resource_database_id = DB_ID('AdventureWorks');
DBCC INDからの行は表示されません 、およびcount(*)からの0行。ロック情報は次を返します:
resource_type resource_description request_mode
————- ——————– ————
EXTENT 1:33352 X
PAGE 1:42486 X
EXTENT 1:42488 X
PAGE 1:42487 X
PAGE 1:42488 X
PAGE 1:42489 X
PAGE 1:23027 X
PAGE 1:23030 X
PAGE 1:23029 X
ページ1:26992 X
ページ1:26993 X
エクステントとページロックには、 DBCC INDで表示されたすべてのページが含まれます 出力。 ロールバックした後でのみ トランザクションによってロックが解除され、すべての行とページが再びテーブルに表示されます。
ROLLBACK TRAN; GO SELECT COUNT(*) FROM dbo.Products; DBCC IND('AdventureWorks', 'Products', -1); GO
注意して、トランザクションでは常にTRUNCATEテーブルステートメントをラップしてください。