none
データベースのログファイルからのロールフォワードについて RRS feed

  • 質問

  •  

    SQL Server2000を使用しています。

     

    現在データベースのバックアップについて検討しています。


    データベースの本を読むと、
    媒体障害によってハードディスクごと失われた場合に、
    データベースが失われてしまうため、定期的にバックアップが必要と書かれていました。

     

    ここまでは私も理解しているのですが、
    その後に更新したデータをログファイルからロールフォワードするため、
    ログファイルはデータファイルとは別の媒体に保存されるように
    データベースの内部設計をするように書かれていました。


    ここで質問なのですが、
    バックアップファイルからデータベースをリストアした後に、
    ロールフォワードするにはどのような手順を踏めば良いのでしょうか?
    どのようなコマンドを実行すれば良いのかが分かりませんでした。

    いつもであれば、以下のコマンドでレストアしています。

    Code Snippet

    RESTORE DATABASE SampleDatabase FROM DISK = 'D:\Backup.bak'
    WITH
    MOVE 'SampleData' TO 'D:\SampleData.mdf',
    MOVE 'SampleLog' TO 'D:\SampleLog.ldf'

     

     

    このあとでロールフォワードのコマンドを実行すると思うのですが、
    どのようなコマンドを実行すれば良いのでしょうか?
    ログファイル(ldfファイル)は、Eドライブの直下に退避させています。

    もしよろしければ、ご教示ください。


    よろしくお願いいたします。

     

    2009年1月13日 1:45

回答

  • こんにちは、naginoです。

     

    トランザクションログを使用したリストアについては、幾つかパターンがあります。

    以下参考 URL を記載しますが、図解入りで説明されており、文章のみの私の返信より大変分かりやすいので、ぜひ一度ご参照ください。

     

    ●フルバックアップ、差分バックアップ、トランザクションログ(もしくはフルバックアップ、トランザクションログ)から、可能な限り全てのデータをリストアする

    http://msdn.microsoft.com/ja-jp/library/ms187495.aspx

    ポイントは 2 つあります。

    1 つはデータベースの復旧モデルを「完全」もしくは「一括ログ」にしておくことです。

    もう 1 つは、各バックアップ・ログの復元は全て「WITH NORECOVERY」を指定して行い、最後のトランザクションログを復元するときだけ指定無し(「WITH RECOVERY」指定でも可)で復元します。

     

    ●フルバックアップ、差分バックアップ、トランザクションログ(もしくはフルバックアップ、トランザクションログ)から、特定時点へのリストア

    http://msdn.microsoft.com/ja-jp/library/ms190244.aspx

    最後のバックアップ後の、特定時点(時間、LSN、マーク)への復元も可能です。

    今回の要件とは違いそうですので、参考 URL の提示までにしておきます。

    詳細が必要であれば、別途ご質問ください。

     

    ちなみに蛇足ながら、トランザクションログを復元する際に「WITH NORECOVERY」を指定すると、復元の際にロールフォワードのみ行い、未完了のトランザクションもそのままとなります。

    一方、トランザクションログを復元する際に「WITH RECOVERY」を指定すると、復元の際にロールフォワードを行い、その後ロールバックを行います。

    復元に関しては、トランザクションログに記録されているトランザクションを適用することが「ロールフォワード」、未完了のトランザクションログを巻き戻すのを「ロールバック」と表現します。

     

    復元・復旧は、標準機能だけでも高度なことが行えますが、その分だけ仕組みが複雑でもありますので、不明点は重ねてご質問ください。

    このあたりは詳しい方も多そうですので、他の方からのご助言もいただけると思います。

     

    ご参考になれば幸いです。

    2009年1月13日 2:49
  • こんにちは、naginoです。

     

    > --'D:\SQLServerBackups\AdventureWorks.bak'が2重に指定されているためのようですが、

    こちらはおそらく誤植ですね。

    英語版の MSDN でも 2 重に指定されていました。

     

    以下のように重複を削除していただければ良いと思います。

    > TO DISK = 'D:\SQLServerBackups\AdventureWorks.bak'

     

    > --これは上で出力された更新ログのファイルが複数存在する場合に、

    こちらは、実は 1 つのバックアップファイル(メディアセットとも呼ばれるようです)に、あたかも ZIP アーカイブかのように複数のバックアップを含めることができます。

    ですので、上記のサンプルコードでは「AdventureWorks.bak」というバックアップファイルに、完全バックアップ、ログのバックアップを 2 回の、都合 3 回バックアップを行ったケースの例になっています。

    (にしては、バックアップのコードが 1 回分だけで、本文中に注記が無いのは少々不親切だと思います。)

    この様な場合、バックアップファイルの中で順に連番が振られており、それを「WITH FILE=」で指定します。

     

    蛇足ながら、私は「大切なバックアップに追記する」という処理が怖いので、通常毎回ファイル名を変えて別ファイルとしてバックアップするよう設計しますが、運用や管理の手間を軽減するための選択肢としてこのような機能が提供されているようです。

     

    ですので、ファイル名を毎回変えている場合は、「DISK=」を適宜書き換えてください。

    また、「WITH FILE=」は省略すると既定で「1」とみなされますので、毎回ファイル名を変えている場合(各バックアップファイルにバックアップが 1 つしか含まれない場合)は省略しても構いません。

     

    ご参考になれば幸いです。

    2009年1月14日 7:25
  • こんにちは、naginoです。

     

    やや当初のご投稿の内容から外れてきてしまいましたが、1 点補足しておきます。

     

    > 当初、私はデータベースを作成したときにできる
    > ldfファイルをmdfファイルとは別のディスクに保存するよう
    > データベースの内部設計を考えておりました。

    こちらですが、お考えのとおりで良いかと思います。

    ldf ファイルと mdf ファイルを物理的に別のディスクに保存することは、2 つの側面から有益だと考えられます。

    ご参考までに概要を記載しておきます。

     

    ●データ保全

    mdf ファイルを保存しているディスクが破損した場合、あらかじめ取得してあるバックアップと ldf から破損直前のデータを復元できる可能性があります。

     

    ●パフォーマンス

    mdf ファイルはランダムでの書き込みが、ldf ファイルはシーケンシャルでの書き込みが行われるため、ファイルレベルでのフラグメンテーションを緩和できます。

    また、ldf ファイルへの書き込み遅延はクエリの処理の遅延に直結するため、ディスク負荷を分散させることでパフォーマンスの劣化を避けられます。

     

    ご参考になれば幸いです。

    2009年1月15日 1:01

すべての返信

  • こんにちは、naginoです。

     

    トランザクションログを使用したリストアについては、幾つかパターンがあります。

    以下参考 URL を記載しますが、図解入りで説明されており、文章のみの私の返信より大変分かりやすいので、ぜひ一度ご参照ください。

     

    ●フルバックアップ、差分バックアップ、トランザクションログ(もしくはフルバックアップ、トランザクションログ)から、可能な限り全てのデータをリストアする

    http://msdn.microsoft.com/ja-jp/library/ms187495.aspx

    ポイントは 2 つあります。

    1 つはデータベースの復旧モデルを「完全」もしくは「一括ログ」にしておくことです。

    もう 1 つは、各バックアップ・ログの復元は全て「WITH NORECOVERY」を指定して行い、最後のトランザクションログを復元するときだけ指定無し(「WITH RECOVERY」指定でも可)で復元します。

     

    ●フルバックアップ、差分バックアップ、トランザクションログ(もしくはフルバックアップ、トランザクションログ)から、特定時点へのリストア

    http://msdn.microsoft.com/ja-jp/library/ms190244.aspx

    最後のバックアップ後の、特定時点(時間、LSN、マーク)への復元も可能です。

    今回の要件とは違いそうですので、参考 URL の提示までにしておきます。

    詳細が必要であれば、別途ご質問ください。

     

    ちなみに蛇足ながら、トランザクションログを復元する際に「WITH NORECOVERY」を指定すると、復元の際にロールフォワードのみ行い、未完了のトランザクションもそのままとなります。

    一方、トランザクションログを復元する際に「WITH RECOVERY」を指定すると、復元の際にロールフォワードを行い、その後ロールバックを行います。

    復元に関しては、トランザクションログに記録されているトランザクションを適用することが「ロールフォワード」、未完了のトランザクションログを巻き戻すのを「ロールバック」と表現します。

     

    復元・復旧は、標準機能だけでも高度なことが行えますが、その分だけ仕組みが複雑でもありますので、不明点は重ねてご質問ください。

    このあたりは詳しい方も多そうですので、他の方からのご助言もいただけると思います。

     

    ご参考になれば幸いです。

    2009年1月13日 2:49
  • ご回答ありがとうございます。

     

    とても分かりやすかったです。
    イメージできました。

     

    ただ1点だけ理解できませんでしたので、

    質問させてください。

    もしよろしければ、ご教示ください。

     

    紹介して頂いたページのサンプルコードを下に載せています。

    (Zドライブが指定されているので、Dドライブに変えています。)

    コード内に、質問点を赤字で記載させて頂きます。

     

    Code Snippet

    USE master;
    --Make sure the database is using the full recovery model.
    ALTER DATABASE AdventureWorks SET RECOVERY FULL;
    GO
    --Create tail-log backup.

    --この時点で更新ログのバックアップを取っているのですよね?

    --実行してみたのですが、エラーとなってしまいました。

    --'D:\SQLServerBackups\AdventureWorks.bak'が2重に指定されているためのようですが、

    --片方を削っても問題ないですよね?
    BACKUP LOG AdventureWorks
    TO DISK = 'D:\SQLServerBackups\AdventureWorks.bak''D:\SQLServerBackups\AdventureWorks.bak'
       WITH NORECOVERY;
    GO
    --Restore the full database backup (from backup set 1).

    --「WITH FILE=」以降の数字の値を変えて3回実行しているようですが、

    --これは上で出力された更新ログのファイルが複数存在する場合に、

    --それぞれ実行すると思ってよろしいですか?

    --上のコマンドを実行しても、ファイルが1つしか出力されませんでしたので、

    --疑問に思いました。

    RESTORE DATABASE AdventureWorks
      FROM DISK = 'D:\SQLServerBackups\AdventureWorks.bak'
      WITH FILE=1,
        NORECOVERY;

    --Restore the regular log backup (from backup set 2).
    RESTORE LOG AdventureWorks
      FROM DISK = 'D:\SQLServerBackups\AdventureWorks.bak'
      WITH FILE=2,
        NORECOVERY;

    --Restore the tail-log backup (from backup set 3).
    RESTORE LOG AdventureWorks
      FROM DISK = 'D:\SQLServerBackups\AdventureWorks.bak'
      WITH FILE=3,
        NORECOVERY;
    GO
    --recover the database:
    RESTORE DATABASE AdventureWorks WITH RECOVERY;
    GO

     

     

    もしよろしければ、上記質問点にご回答ください。

    ぜひよろしくお願いいたします。

     

     

    2009年1月14日 5:04
  • こんにちは、naginoです。

     

    > --'D:\SQLServerBackups\AdventureWorks.bak'が2重に指定されているためのようですが、

    こちらはおそらく誤植ですね。

    英語版の MSDN でも 2 重に指定されていました。

     

    以下のように重複を削除していただければ良いと思います。

    > TO DISK = 'D:\SQLServerBackups\AdventureWorks.bak'

     

    > --これは上で出力された更新ログのファイルが複数存在する場合に、

    こちらは、実は 1 つのバックアップファイル(メディアセットとも呼ばれるようです)に、あたかも ZIP アーカイブかのように複数のバックアップを含めることができます。

    ですので、上記のサンプルコードでは「AdventureWorks.bak」というバックアップファイルに、完全バックアップ、ログのバックアップを 2 回の、都合 3 回バックアップを行ったケースの例になっています。

    (にしては、バックアップのコードが 1 回分だけで、本文中に注記が無いのは少々不親切だと思います。)

    この様な場合、バックアップファイルの中で順に連番が振られており、それを「WITH FILE=」で指定します。

     

    蛇足ながら、私は「大切なバックアップに追記する」という処理が怖いので、通常毎回ファイル名を変えて別ファイルとしてバックアップするよう設計しますが、運用や管理の手間を軽減するための選択肢としてこのような機能が提供されているようです。

     

    ですので、ファイル名を毎回変えている場合は、「DISK=」を適宜書き換えてください。

    また、「WITH FILE=」は省略すると既定で「1」とみなされますので、毎回ファイル名を変えている場合(各バックアップファイルにバックアップが 1 つしか含まれない場合)は省略しても構いません。

     

    ご参考になれば幸いです。

    2009年1月14日 7:25
  • ご回答ありがとうございます。

     

    とても勉強になりました。

     

    ログファイルのバックアップを元に
    ロールフォワードしているのですね。
    イメージできました。

     

    当初、私はデータベースを作成したときにできる
    ldfファイルをmdfファイルとは別のディスクに保存するよう
    データベースの内部設計を考えておりました。

    これは意味がないということなのですね?


    日々データベースの差分バックアップや、ログファイルのバックアップを
    取るようにデータベースの運用設計を考えたいと思います。

     

    大変勉強になりました。
    ありがとうございます。

     

    2009年1月15日 0:41
  • こんにちは、naginoです。

     

    やや当初のご投稿の内容から外れてきてしまいましたが、1 点補足しておきます。

     

    > 当初、私はデータベースを作成したときにできる
    > ldfファイルをmdfファイルとは別のディスクに保存するよう
    > データベースの内部設計を考えておりました。

    こちらですが、お考えのとおりで良いかと思います。

    ldf ファイルと mdf ファイルを物理的に別のディスクに保存することは、2 つの側面から有益だと考えられます。

    ご参考までに概要を記載しておきます。

     

    ●データ保全

    mdf ファイルを保存しているディスクが破損した場合、あらかじめ取得してあるバックアップと ldf から破損直前のデータを復元できる可能性があります。

     

    ●パフォーマンス

    mdf ファイルはランダムでの書き込みが、ldf ファイルはシーケンシャルでの書き込みが行われるため、ファイルレベルでのフラグメンテーションを緩和できます。

    また、ldf ファイルへの書き込み遅延はクエリの処理の遅延に直結するため、ディスク負荷を分散させることでパフォーマンスの劣化を避けられます。

     

    ご参考になれば幸いです。

    2009年1月15日 1:01
  • ご回答ありがとうございます。

    随分勉強になりました。

     

    nagino様のご指摘の通り、
    当初の質問から少し話がそれてきましたので、
    ここで打ち切ろうと思います。

     

    私なりに教えて頂いたことを整理して、
    また不明な点がございましたら、そのときに質問させて頂きます。

     

    大変詳しくご説明頂きありがとうございました。

     

    2009年1月15日 1:46