差分バックアップのリストアにはまった話

差分バックアップのリストアにはまった

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';

正常終了した. データ見ても差分バックアップの内容が反映されていた.

まとめ

データベースをリストアする際はオプションに気をつけよう.