DB サーバーをリプレースするときの話です。
本番環境が稼働している裏で DB サーバーを構築し、本番環境に切り替えるタイミングで差分バックアップを取得して構築した DB サーバーにリストアしようと画策したらちょっとはまりました。
本番環境で稼働している DB サーバーを「旧 DB サーバー」、裏で構築している DB サーバーを「新 DB サーバー」とします。
使っている DB は旧 DB サーバーが「SQL Server 2008 R2 Standard」、新 DB サーバーが「SQL Server 2016 Enterprise」です。
事前準備
新 DB サーバーを構築してフルバックアップを適用します。
旧 DB サーバーでフルバックアップを取得します。
BACKUP DATABASE [SAMPLE] TO DISK = N'E:\SAMPLE\Backup\SAMPLE_FULLBACKUP.bak';
新 DB サーバーにフルバックアップをリストアします。
RESTORE DATABASE [SAMPLE] FROM DISK = N'E:\SAMPLE\Backup\SAMPLE_FULLBACKUP.bak';
差分バックアップを取得してリストアする
挑戦その1
旧 DB サーバーで差分バックアップを取得します。
BACKUP DATABASE [SAMPLE] TO DISK = N'E:\SAMPLE\Backup\SAMPLE_DIFFBACKUP.bak' WITH DIFFERENTIAL;
新 DB サーバーに差分バックアップをリストアします。
RESTORE DATABASE [SAMPLE] FROM DISK = N'E:\SAMPLE\Backup\SAMPLE_DIFFBACKUP.bak';
するとこんなエラーが
メッセージ 3117、レベル 16、状態 1、行 1
ロールフォワードできる状態のファイルがないので、ログまたは差分バックアップは復元できません。
メッセージ 3013、レベル 16、状態 1、行 1
RESTORE DATABASE が異常終了しています。
なんだと…
原因調査
データベースの状態を見てみます。
SELECT DATABASEPROPERTYEX('SAMPLE'、'Status') AS DB_STATUS;
DB_STATUS
---------
ONLINE
デフォルトでリストアするとステータスが ONLINE になり、差分バックアップのリストアを受け付けなくなってしまうようです。
まあ、ONLINE だとデータベース操作できるからデータに不整合生じて差分バックアップをリストア出来なくなるのも考えれば理解できます。
解決策
リストアのオプションを調べました。
オプション | 内容 |
---|---|
RECOVERY | デフォルトオプション. リストア後データベースは「完全復旧」状態となる. 以降バックアップのリストアを受け付けない. |
NORECOVERY | リストア後データベースは「復元中」状態となる. データベースの操作を一切受け付けない. |
STANDBY | リストア後データベースは「スタンバイ」状態となる. 読み取りのみ可能にするためデータの不整合が生じない. |
新 DB サーバー構築後、各アプリケーションから接続出来る状態にしておきたいので出来れば STANDBY 状態でフルバックアップをリストアしておきたいです。
というわけで、フルバックアップを STANDBY でリストアして差分バックアップをリストア出来るか試してみます。
挑戦その2
一旦新 DB サーバーのデータベースを消します。
DROP DATABASE [SAMPLE];
新 DB サーバーにフルバックアップを STANDBY でリストアしてみます。
RESTORE DATABASE [SAMPLE] FROM DISK = N'E:\SAMPLE\Backup\SAMPLE_FULLBACKUP.bak'
WITH STANDBY = N'E:\SAMPLE\Backup\SAMPLE_ROLLBACKUNDO.bak';
結果だめでした…
メッセージ 3180、レベル 16、状態 1、行 1
このバックアップは WITH STANDBY では復元できません。データベースのアップグレードが必要です。WITH STANDBY を指定しないで RESTORE を再実行してください。
メッセージ 3013、レベル 16、状態 1、行 1
RESTORE DATABASE が異常終了しています。
「SQL Server 2008 R2 Standard」で取得したフルバックアップを「SQL Server 2016 Enterprise」にSTANDBYでリストア出来ないみたいです。
ちなみに「SQL Server 2016 Enterprise」で取得したフルバックアップを「SQL Server 2016 Enterprise」にSTANDBYでリストアすることは出来ました。
闇が深そう(そもそもだめなのかも…)なので別の策を考えることにしました。
結局
残りは NORECOVERY しかないのでフルバックアップを NORECOVERY でリストアして差分バックアップをリストア出来るか試します。
最後の挑戦
新 DB サーバーにフルバックアップを NORECOVERY でリストアします。
RESTORE DATABASE [SAMPLE] FROM DISK = N'E:\SAMPLE\Backup\SAMPLE_FULLBACKUP.bak'
WITH NORECOVERY;
新 DB サーバーに差分バックアップをリストアします。
RESTORE DATABASE [SAMPLE] FROM DISK = N'E:\SAMPLE\Backup\SAMPLE_DIFFBACKUP.bak';
正常終了しました。
データ見ても差分バックアップの内容が反映されていました。
まとめ
データベースをリストアする際はオプションに気をつけましょう。