破損したデータベースからのデータ抜き出し方法

 

前回ご案内したバックアップが存在しない、または、バックアップからのリストアが行えない場合のデータベース復旧手順では、バックアップを採取していなかったり、バックアップからのリストアに失敗したという場合のデータベースの修復方法をご案内しました。その中では、DBCC CHECKDB コマンドの修復オプションを用いてデータベースの修復を行いましたが、DBCC CHECKDB の修復オプションを用いてもデータベースを修復できない場合もあります。そのような場合は、データを抜き出して、そのデータを元にデータベースを再構築する以外にはありません。今回は DBCC CHECKDB コマンドの修復オプションでも復旧できない場合に、破損したデータベースから可能な限りのデータを抜き出すための方法をご案内します。

※ 注意事項 ※

  • 以下の手順は検証済みの手順ですが、必ずしもデータをすべて抜き出せることを保証しているものではありません。手順の実施につきましては、自己責任において行ってください。

  • 本手順を実施した後、インデックスの作成や外部キー(FK)の設定を行う必要がある場合もあります。そのため、本作業は、対象データベースに格納されているデータ間の関連性を熟知している方、もしくは、この手順を実施する方の責任において実施する必要があります。データ間の関連性が保たれているかどうかの確認が行えない場合には、この手順を実施しないで下さい。

■抜き出し手順

 

1. 移行先となる新規データベースを作成します。

Create Database データベース名
GO

Use データベース名
GO

Alter database 'データベース名' set RECOVERY FULL
GO

2. 以下のいずれかの方法にて、データの抜き出しを行います。

方法 特徴
Export ウィザード 破損データベースの複数のテーブルおよびデータを新規作成したデータベースへ直接コピー。
Select into 破損データベースの一つのテーブルを新規作成したデータベースへ直接コピー。
bcp 事前にテーブルを作成する必要あり。破損データベースの一つのテーブルを一度、テキストファイルに出力後、そのファイルを元に、新規作成したデータベース内の新規作成したテーブルにコピー。

※注意事項※ 
いずれの方法も、アクセスできないデータにヒットした時点でエラーになります。

それぞれの実行方法は以下の通りです。 

1.Export ウィザード

※以降はSQL Server 2012 のSQL Server Management Studio での実行方法をご案内しております。 
SQL Server インポートおよびエクスポート ウィザードを実行する
https://technet.microsoft.com/ja-jp/library/ms140052.aspx

 

a. 該当データベースを右クリックし、[タスク]-[データのエクスポート]メニューを選択します。 image

 

b. インポート/エクスポートウィザードが表示されるので、「次へ」を選択します。 image

 

c. データソース(破損データベース)を選択し、「次へ」を選択します。

    サーバー名は、破損データベースが存在するサーバー名を指定します。 image

 

d. コピー先(新規作成データベース)を選択し、次へを選択します。

  サーバー名は新規作成データベースのサーバー名を指定し、「次へ」を選択します。 image

 

e. コピー時のオプションを選択します。  

※以下では、「1つ以上のテーブルまたはビューからデータをコピーする」オプションを指定し、「次へ」を選択します。このオプションでは選択したテーブル、またはビューから全データをコピーします。

 

image

 

※「1つ以上のテーブルまたはビューからデータをコピーする」オプションにてエラーが発生する場合、もしくは特定のカラムや、データのみ抜き出す場合は、「転送するデータを指定するためのクエリを記述する」オプションを指定します。

「転送するデータを指定するためのクエリを記述する」オプションにて、クエリに Order by オプションを追加し、Desc、Asc 等を利用して、データを並べ替え、できるだけ多くのデータを抜き出すように検索します。また、クエリに Top 句を追加して最初から何件目を検索するいう方法も有効です。

実行例:クラスタ化インデックスが設定している、200行存在するテーブルにて、101行目でエラーが発生した場合、100行目までを抜き出す場合

--100行目までを抜き出すクエリ
select Top 100 * from 元のデータベース名.スキーマ名.元のテーブル名  Order by ***  Asc

--102行目以降を抜き出すクエリ        
select Top 99 * from 元のデータベース名.スキーマ名.元のテーブル名  Order by ***  Desc

 

 

image

 

f. コピー元のテーブルおよびビューを選択画面にて必要なテーブル、ビューを指定し、「次へ」を選択します。 image

g. パッケージの保存および実行画面にて「すぐに実行する」オプションを指定し、「次へ」を選択します。 image

 

h. 「完了」ボタンを選択すると、データコピーが始まります。

2.select into 

a. SQL Server Management Studioを起動し、該当インスタンスで管理権限にて接続します。

b. 「新規クエリ」を選択します。 c. 抜き出しするテーブルのスキーマを事前に作成します。

d. 以下のクエリを各テーブル毎に実行します。
  

select * into 新規データベース名.スキーマ名.テーブル名 from 破損データベース名.スキーマ名.元のテーブル名
go 

全件検索にてエラーが検出された場合は、クエリに Order by オプションを追加し、Desc、Asc 等を利用して、データを並べ替え、できるだけ多くのデータを抜き出すように検索します。また、クエリに Top 句を追加して最初から何件目を検索するいう方法も有効です。

実行例:クラスタ化インデックスが設定している、200行存在するテーブルにて、101行目でエラーが発生した場合、100行目までを抜き出す場合

      --件数確認
select count(*) from 破損データベース名.スキーマ名.元のテーブル名           go

--エラーが発生するデータ行を確認
select * from 破損データベース名.スキーマ名.元のテーブル名go

--100行目までを抜き出して、新規データベースに格納
select Top 100 * into 新規データベース名.スキーマ名.テーブル名 from 破損データベース名.スキーマ名.元のテーブル名  Order by ***  Asc
go

--102行目以降を、新規データベースに格納
select Top 99 * into 新規データベース名.スキーマ名.テーブル名 from 破損データベース名.スキーマ名.元のテーブル名  Order by ***  Desc
go

3. bcp 

bcp ユーティリティ
https://msdn.microsoft.com/ja-jp/library/ms162802.aspx

a. コマンドプロンプトを起動します。

b. 以下のいずれかのコマンドを各テーブルに対して実行し、エクスポートを行います。

--テーブル内のデータをすべて出力するとき
>bcp 破損データベース名.スキーマ名.テーブル名 out 出力先ファイル.dat -T –r –t –c

--テーブル内のデータをすべて出力してエラーが発生した時は、以下のようにqueryoutオプションを使用します。
>bcp  "SELECT TOP * FROM 破損データベース名.スキーマ名.テーブル名 order by *** Desc" queryout 出力先.dat  out -T –r –t –c     

実行例:クラスタ化インデックスが設定している、200行存在するテーブルにて、101行目でエラーが発生した場合、100行目までを抜き出す場合

  --100行目までを抜き出すクエリ
>bcp “select Top 100 * from 破損データベース名.スキーマ名.テーブル名  Order by ***  Asc" queryout 出力先.dat  out -T –r –t –c       

   --102行目以降を抜き出すクエリ
>bcp “select Top 99 * from 破損データベース名.スキーマ名.元のテーブル名  Order by ***  Desc " queryout 出力先.dat  out -T –r –t –c     

c. 新規データベースに対し、抜き出しするテーブル、および、スキーマを事前に作成します。

d. b. にてエクスポートしたデータを、c.にインポートします。

>bcp 新規データベース名.スキーマ名.テーブル名 in 出力先ファイル.dat -T –r –t –c

 

 

3.  すべてのテーブルにインポートが完了したら、DBCC CHECKDB コマンドを実行し、整合性に問題がないことを確認します。

以上でデータの抜き出し作業は完了です。

その後、クライアントからの接続可否、アプリケーションからの使用に問題がないかどう可能かなど、そのシステムおよびアプリケーションの観点で問題がないかどうかについて確認します。

また、必ず「バックアップ」をご採取ください。

Backup Database データベース名 to disk = ‘バックアップ先ファイル.bak'