sql >> データベース >  >> RDS >> Sqlserver

SQLServerでのROLLBACKTRUNCATE

    誤って切り捨てを実行したことがありますか 間違ったテーブルでコマンド?これにより、すべてのデータが失われます。最悪のことは、データを取り戻す機会がないことです。この記事では、このような状況を回避する方法を確認し、ロールバック切り捨てを行う機会があります。 。

    ロールバック切り捨てはできません

    単純に、トランザクションがすでにコミットされている場合、トランザクションをロールバックすることはできませんが、データ(または少なくともその一部)を取り戻すために何か他のことを行うことはできます。

    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テーブルステートメントをラップしてください。


    1. PSQLException:ResultSetが適切に配置されていません。おそらく、次に呼び出す必要があります

    2. アークウェアを選択する5つの理由

    3. SQLLIMITおよびOFFSETクエリを使用してすべてのレコードを選択する

    4. Oracle接続プールクラス