SSMSで復元が失敗するときの原因と対処

SQL Serverを使用したシステム開発に携わっていると、データベースの”バックアップ”や”復元”を行うことも多いと思いますが、時々、復元が失敗してしまうことがあります。
そんな復元失敗について、よくある原因と対処方法を紹介します。
DBのバックアップとレストア
データベースの使用時、様々な要因により障害が発生する可能性があります。
- プログラムの不具合によるデータ不整合
- ハードウェア障害によるデータ損失
- ユーザー操作によるデータ削除
- 自然災害(落雷による停電や、震災による物理的なハード破壊など)の影響
こういった障害に備えて適切なバックアップを取っておくこと、またそのバックアップからデータをレストア(復元)することは、システム管理にとって非常に重要な運用要素です。またシステム開発や改修時においても、現行運用しているシステム環境からデータベースを取得して開発環境に再現することはよくある場面ではないかと思います。
SSMSによるバックアップと復元
SQL ServerはクライアントとしてSQL Server Management Studio(SSMS)というアプリケーションが無償で提供されています。

このSSMSを使用することで、簡単にデータベースの操作やデータの閲覧・編集を行うことができます。”バックアップ”と”復元(レストア)”についてもメニューがありますので、複雑なコマンド入力を行わずとも、マウス操作のみでバックアップやレストアを行うことができます。
ただ、状況や環境によっては復元に失敗してしまうこともありますので、よくある原因と対処方法について解説します。

原因1.SQL Serverのバージョンで互換性がない
SQL Serverにも様々なバージョンがあり、定期的に新しいバージョンが提供されています。
基本的に、古いバージョンのバックアップを新しいバージョンで復元することはOK(後方互換といいます)なのですが、逆に、新しいバージョンのバックアップを古いバージョンで復元することができません。何故かというと、新しいバージョンのバックアップでは古いバージョンで存在しなかった機能・命令を使っている可能性があるためです。
通常はあまりこういう場面は無いように思われますが、例えば、パッケージ製品として同様のシステムをいくつも構築していった際に、サーバーOSやミドルウェアのバージョンが新しくなっていく一方で、開発・検証環境が古いままだった場合に発生することがあります。

新しい環境で何かトラブルがあった時、データベースのバックアップを取って復元しようとしたら検証環境のSQL Serverが古かった、といった具合ですね。
[スクリプトの生成]でSQL文を出力
こういった場合は、通常のバックアップと復元の機能は使用せずに、データベースの構築とデータの挿入に関するSQL文を出力する方法があります。

対象のデータベースを選択し、右クリックから[タスク]>[スクリプトの生成]と進みます。

初期設定では説明が表示されますので、そのまま[次へ]を押します。

スクリプトを生成する対象を選択します。データベース全体であれば上のラジオボタンのままでOKです。特定のテーブルのみ生成したい場合は下のラジオボタンを選択し、更に、対象とするテーブルを選択します。

スクリプト作成オプションの設定では、まず[詳細設定]ボタンを押します。

様々なオプションが一覧表示されるので「DROPおよびCREATEのスクリプトを作成」を探します。初期値では[CREATEのスクリプトを作成]が選択されていますので、[DROPおよびCREATEのスクリプトを作成]を指定します。

オプションではもう一か所、「スクリプトを作成するデータの種類」を指定します。初期値では[スキーマのみ]となっており、そのままだとデータが含まれないため、[スキーマとデータ]を指定します。これで、SQL文にデータのINSERTが含まれるようになります。
上記2点を設定したら[OK]ボタンで元の画面に戻ります。

スクリプト保存方法の指定については、SQL文のファイルを出力するなら[スクリプトファイルとして保存]を選択し、保存場所などを指定します。

概要ではここまで設定した内容が表示されるので、確認して[次へ]を押します。修正する場合は[前へ]で戻って、必要なところを変更しましょう。

保存処理がすべて成功すれば、指定した保存方法でスクリプトが出力されます。
SQL文であれば、比較的、バージョンに依存せずに実行することができるので、新しいバージョンのSQL Serverのデータを古いバージョンのSQL Serverに復元することができるようになります。
もちろんこの場合でも、古いSQL Serverでは未対応のSQL構文が含まれる可能性があるので、内容によってはSQLエラーが発生することはありますが、その場合はエラーとなった文を修正(場合によっては削除)するなど個別に調整することでSQLを実行しましょう。
原因2.排他アクセスできない
バージョンが問題ない場合でも、「データベースは使用中なので、排他アクセスを獲得できませんでした。」というメッセージが出て復元に失敗することがあります。

これば何かしらのプロセスが復元対象のデータベースを使用している場合に発生します。
別プログラムからの接続プロセスである場合は、接続元のプログラムを終了するなどして接続を切る必要がありますが、直前にSSMSを操作している場合はSSMS自身のプロセスである場合も多いので、次のように確認・対応しましょう。
利用状況モニターで不要プロセスを強制終了する
不要なプロセスの確認・強制終了をするには、利用状況モニターを使用します。

まずは、メニューから[利用状況モニター]を選択して表示します。

[プロセス]を開いて、対象のデータベースを選択して表示を絞り込みます。

プロセスを右クリックして[詳細表示]から接続内容を確認し、終了して良いプロセスであれば[強制終了]を選択してプロセスを終了します。

データベースに接続しているプロセスが無くなれば、復元が実行できるようになります。
データベースへ再接続・SSMSを再起動する
プロセスの強制終了は慎重に行う必要があるため、複数ユーザーが使用しているような環境に対しては前述の方法が有効ですが、例えば自分だけが使用しているローカル環境などであればもうちょっと簡単な方法もあります。
SSMSのプロセスが残っていることが原因であれば、データベースへの接続を一度切って再接続する、あるいはSSMSを再起動することで解消されることも多いです。
また、データベースのサービスを再起動することで、諸々の接続を一度切ってしまうということもできます。

ちょっと乱暴な方法ではあるので、本番稼働環境で行う場合は実施してもいい状況・タイミングか?は慎重に確認したうえで実施しましょう。
なおこの時、復元する前にまたSQLを実行したりするとまた同じように排他アクセスエラーになってしまうので、余計な操作をせずに速やかに復元を実行しましょう。
原因3.SQLServerのサービス停止
稀な例としては、何かしらの理由でSQLServerのサービスが停止した、といった場合もありますが、SSMSで接続できている時点でその可能性は無いですし、仮に途中で停止した場合は復元だけでなく何もできなくなるのですぐに気付くと思います。
サービスの起動
万が一、サービスが停止したときは、サービスメニューからSQLサーバーのサービスを開始しましょう。

Windowsのスタートメニューを右クリックして、[コンピューターの管理]を選択します。

左ペインの[サービスとアプリケーション]>[サービス]を選択して、「SQL Server (インスタンス名)」を探します。サービスが停止していると、状態の欄が空白になっています。

対象行をダブルクリックするか、右クリックしてプロパティを選択すると、プロパティウィンドウが表示されるので、[開始]ボタンを押します。

状態が「実行中」になればサービスが開始されたことになります。この状態で改めて復元を試してみましょう。
まとめ
SSMSでデータベースを復元する際に失敗してしまう原因と対処方法について、よくある事例を紹介しました。
なお本文でも少し触れている通り、本番稼働環境でのプロセスの切断・強制終了についてはシステム停止・不具合に繋がる可能性もありますので慎重に行いましょう。