NOBTAの気ままにITブログ

Azure全般 / SQL Serverに関する情報を発信していきます。

【第12回】基本から始める SQL Server【整合性チェック 不整合検知後の対処方法2】


スポンサーリンク

第11回では 整合性チェック コマンドで不正が検知された場合の対処方法についてまとめてみました。

 

 

今回は、実際に整合性チェック コマンドを実行し、データベースの不整合を解消する方法についてまとめてみようと思います。

 

 

整合性チェック コマンドによるデータベース不整合の解消方法について

一般的にデータベースに不整合が確認できた場合、不整合が発生していない正常なバックアップからデータベースを復元することを検討します。

しかしながら、不整合が発生したデータベースの正常なバックアップが存在しないなどの状況により、既存のデータベースの不整合を解消したいということもあるかと思います。

今回は、整合性チェックコマンドによりデータベースの不整合を解消する方法について以下に記載します。

 

[注意]

  • データベースの不整合の状態により、整合性チェックコマンドでデータベースの不整合を解消することが出来ない可能性があります。
  • データベースの不整合の状態により、データが損失する可能性があります。
  • データベースの不整合を解消する作業の前に、不整合の発生しているデータベースの完全バックアップを採取し、可能であれば、検証環境などへ復元したうえで不整合を解消する作業を実施します。

 

[前提]

データベース ”TESTDB” 上に二つのテーブル "tab1"、"tab2" が存在し、以下のデータが存在している状態で、本データベースに不整合が発生していることを確認。

# テーブル "tab1" データ

f:id:nobtak:20210112012054p:plain

# テーブル "tab2" データ

f:id:nobtak:20210112012100p:plain

 

1) データベースの不整合の状態を把握するため、整合性チェック データベースコマンド (DBCC CHECKDB) を不整合が発生しているデータベースに対して実行します。

dbcc checkdb('TESTDB')
go

 

2) 1) の実行結果を確認し、データベースの不整合の状態を把握します。 

[実行結果例]

f:id:nobtak:20210112013719p:plain

上記の結果より、以下のことが分かります。

  • テーブル "tab1"のインデックス ID 1 (クラスタ化インデックス) で 3個の一貫性エラーが発生
  • テーブル "tab2"のインデックス ID 2 (非クラスタ化インデックス) で 4個の一貫性エラーが発生

f:id:nobtak:20210112013832p:plain

  • 発生したエラーの最小修復レベルは ”repair_allow_data_loss" と、修復を実行した場合、データが失われる可能性が有り。

なお、 テーブル "tab1" では、インデックス ID 1 (クラスタ化インデックス)で不整合が発生しているため、不整合を解消することで不正が発生しているデータページが削除され、削除されるデータページに存在するデータが損失します。

また、テーブル "tab2" では、インデックス ID 2 (非クラスタ化インデックス) のみで不整合が発生しているため、不整合を解消したとしても、データが損失することがないということが言えます。

 

3) 該当データベースを「シングル ユーザーモード」に変更します。

alter database TESTDB set single_user with rollback immediate
go

 

4) 整合性チェックコマンド (DBCC CHECKDB) を、2) で確認できた最小修復レベル (今回は「repair_allow_data_loss」) を指定して実行します

dbcc checkdb(TESTDB, repair_allow_data_loss)
go

 

5) 4) の実行結果を確認し、データベースの不整合が解消されたことを確認します。

f:id:nobtak:20210112021754p:plain

テーブル "tab1" のクラスタ化インデックスが再構築され、一貫性エラーが解決されていることが確認できます。

 

f:id:nobtak:20210112022343p:plain

テーブル "tab2" の非クラスタ化インデックスが再構築され、一貫性エラーが解決されていることが確認できます。

f:id:nobtak:20210112022435p:plain

データベース "TESTDB" で不整合が解消されていることを確認します。

 

6) 再度 整合性チェックコマンド (DBCC CHECKDB) を実行し、不整合が解消されていることを確認します。 

dbcc checkdb('TESTDB')
go

 

7) 該当データベースを「マルチ ユーザーモード」に変更します。

alter database TESTDB set multi_user
go

 

[補足]

テーブル "tab1" ではクラスタ化インデックスで不整合が発生していたため、不整合を解消することで存在していたデータが損失していることが確認できます。

f:id:nobtak:20210112022845p:plain

 

テーブル "tab2" では非クラスタ化インデックスのみで不整合が発生していたため、不整合が解消しても、データが損失していないことが確認できます。

f:id:nobtak:20210112023040p:plain

 

整合性チェックコマンドで不整合を解消する場合、不整合を解消することでどのテーブルのデータが損失するか、システム オブジェクトで不整合が発生していないかなどを確認し、データベース復旧までのデッドラインを考慮したうえで、以下の何れかの方法によりデータベースを復旧するかを判断すると良いかと思います。

 

  • 整合性チェックコマンドで不整合を解消
  • バックアップからデータベースを復元
  • 既存のデータベースがデータの抜き出し + バックアップからデータベースを復元

 

データベース復旧までのデッドラインが短い場合、整合性チェックコマンドで不整合を必ずしも復旧できるとは限らないため、不整合の発生していない状態で採取されたバックアップからデータベースを復元することをお勧めします。

また、データベースの不整合を解消する作業の前に、完全バックアップを採取することで、データベースの不整合を解消する作業を実施することでデータベースにアクセスすることが出来ない状態に悪化したとしても、不整合を解消する前の状態にデータベースを戻すことが可能です。

そのため、データベースの不整合を解消する作業を実施する場合は、データベース復旧までのデッドラインが短い場合においても、データベースの完全バックアップを採取することをお勧めします。

 

まとめ

今回は、実際に整合性チェック コマンドを実行し、データベースの不整合を解消する方法についてまとめてみました。

不整合が発生しているインデックスの種類によってはデータを損失し、システム オブジェクトで不整合が発生した場合、不整合が解消したとしても、正常にデータベースが動作することが保証されないため、バックアップを定期的に実施しつつ、何時のタイミングからデータベースに不整合が発生したかを特定できるよう、定期的に整合性チェックコマンド (DBCC CHECKDB) を実行することをお勧めします。

 

【第13回】基本から始める SQL Server【メモリ管理】へ