スタートアップ企業向けインフラ運用入門(3):バックアップとリカバリー(その2)

kashima
2012/11/22 19:43

前回はバックアップ・リカバリーの基本的な知識、設計のポイントなどについて説明しました。今回は、バックアップ・リカバリーの具体的な方法について、バックアップ対象別に実例を挙げながら説明していきます。

はじめに

前回、リスク管理という観点からバックアップ・リカバリーの対象や手法等の基本知識、さらにバックアップが対処するリスク事象について説明しました。

今回は、システムファイル、Webコンテンツ、データベースなどのバックアップ対象ごとに、代表的なバックアップ・リカバリー方法について、その長所や短所をあわせて説明します。

システムファイルのバックアップ・リカバリー

システムファイルとは

ここで言う「システムファイル」とは、OSのファイルに加えてミドルウェアなどサーバー製品のファイルも含みます。これらのファイルは更新頻度が低いため、更新されるたびにバックアップを取ることが多いです。

主な要件

システムファイルのバックアップに求められる主な要件は、以下の通りです。

  • データ破損・消失が発生した場合、速やかに復旧できる
  • 誤った設定を適用した場合、正常に動作したバージョンに戻すことができる

こうした要件を踏まえた上で、具体的な方法を説明します。

イメージ作成機能

Amazon Web Services等のIaaS環境では、「イメージ作成」や「スナップショット」といった機能が用意されていることがほとんどです。システムファイルのバックアップを取るには、これらの機能を使うのが一般的です。また、商用のバックアップ製品などを使っている場合も、システムファイルのバックアップにスナップショット機能を使うことが多いでしょう。

Rettyの場合、ほとんどのサーバーがAmazon EC2上で稼働しているので、システムに「大きめの」構成変更が発生した場合、ディスクのスナップショットの作成あるいはAMI(Amazon Machine Image、システムのイメージ)の再作成を実施しています。「大きめ」の構成変更の時のみにしてる理由は後述します。

oreilly7-1.png

Amazon EC2のスナップショット機能

この方法のメリットとデメリットを以下に挙げます。

メリット:単純さ

バックアップ及びリカバリー操作が単純なので、運用でのミスなどは低く抑えることができます。

デメリット:サービスの停止を伴うケースが多い

Rettyが使用しているAmazon EC2の場合、AMIの作成時に各EBSボリュームのスナップショットが取得されます。その際、システム停止を伴わずにEBSボリュームのスナップショットを取るオプションを選択できるのですが、ルートデバイスのスナップショットを取る際にはシステムのシャットダウンが推奨されています[1]。従って、システムファイルのバックアップという目的のためにAMIを作成する場合には、システムの停止を伴うと考えて良いでしょう。

規模が小さいサービスの場合、webサーバーとDBサーバーが1台ずつという構成が多いかと思いますが、その場合、イメージ作成時にはサービス停止が発生します。

従ってRettyでは、セキュリティアップデートの適用などの場合にはイメージを作成していません。有事の際には、以下のような流れでリカバリーを行います。

  1. 古いイメージからインスタンスを起動
  2. セキュリティアップデートを適用
  3. バックアップからDBのデータを復旧

デメリット:バックアップするデータ量が多い

もう一つのデメリットは、バックアップ対象のデータ量が多いことです。必要なファイルのみをバックアップする場合に比べて、バックアップするデータ量が多いため、その分だけ費用も多く発生します。

とはいえ、システム領域のデータ量は多くても10GB程度、保持する世代数も多くて2世代程度だと思いますので、通常はメリットのほうが大きいと思います。

[1]以下のAmazon EC2 FAQの内容を参照してください。 http://aws.amazon.com/ec2/faqs/#Do_volumes_need_to_be_un-mounted_in_order_to_take_a_snapshot_Does_the_snapshot_need_to_complete_before_the_volume_can_be_used_again

手動でのスナップショット作成

IaaS環境で使えるようなイメージ作成機能がない場合でも、手動で同様の方法でバックアップを取得できます。

大まかな手順は以下の通りです。

  1. システムの状態を静止させ、ディスクへの書き込みが発生しないようにする
  2. ddコマンドなどでイメージを作成

1ですが、Xen、KVMなどの仮想化環境を使用している場合は、VMの停止機能を使うことが多いと思います。また、ファイルシステムによっては「フリーズ」機能がありますので、その間にバックアップを取得します。

2は、特に説明不要だと思います。

構成管理ツール

厳密には「バックアップ」ではありませんが、サーバーのシステムデータの破損に備える方法のひとつに、Chef、Puppet等の構成管理ツールが挙げられます。

基本的な考え方は、サーバーの構成情報(インストールされているパッケージ、設定ファイル等)を別の場所に保管しておき、システムデータの復旧が必要な場合には、その構成情報をもとにサーバーを再構築するというものです。

いったん適切に仕組みを構築してしまえば、次のようなメリットがあります。

  • 作業が自動化されるため、リカバリー時のミスは少ない
  • バックアップとは違い、対象システムを停止させる必要はない
  • サーバーの台数が多い場合でも、一斉に設定変更が可能

ここに書いた「障害発生時のリカバリー」に関連するもの以外にも、沢山のメリットがあります。 デメリットは仕組みが比較的複雑で、運用に乗せるまでにそれなりの時間・コストがかかることでしょう。

Webコンテンツのバックアップ・リカバリー

「Webコンテンツ」という言葉は若干曖昧ですので、便宜上、以下のように分類します。

  • ユーザーが投稿・アップロードした画像等のコンテンツ
  • システム側を構成するHTML、PHP、JavaScript、画像等のファイル、あるいはそれらをアーカイブにしたwarファイル等

それぞれ求められる要件、使える手法が異なりますので、説明していきます。

ユーザーが投稿したデータ

まず、よほど小規模のシステムでない限り、ユーザーがアップロードしたファイルを、そのままファイルの形で保存することは少ないと思います。

ただ、ユーザーが投稿したデータは、仮に消失してしまった場合にはサービスの存続に関わります。そのため複数の場所にバックアップを保管して、データ消失の可能性を極力減らすことが第一の要件となります。

サーバー上に直接、ファイルとして保存している場合についてですが、そのような選択をしたということは、データベース(DB)のようなファイル同士の整合性はそれほど重要ではないのだと思います。そのような場合、通常はバックアップ時にシステムを停止させる必要がないと思います。

したがって、単純にtarコマンドで圧縮した後で別の場所にコピーする。あるいはrsyncコマンドで別の場所にコピーする方法が一般的です。

ファイルに保管する以外の方法として、小さなデータであればDBにバイナリを直接格納するケースもあると思います。その場合は次の節を参照して下さい。

Webサービスでユーザーが投稿・アップロードしたデータを保存する場合、外部のストレージサービスに保管するケースが多いと思います。Rettyの場合、投稿された画像ファイルはAmazon S3に保管しています。

外部のサービスにデータを預ける場合、そのサービスで何らかの障害が発生してデータが消失する可能性というのもわずかながら存在します。データの重要度に応じて、同じデータを別の場所・別のサービスに保管するという選択肢を検討してみて下さい。

プログラム関連のファイル

プログラム関連のファイルをバックアップする上で求められる要件は、システム関連のファイルと同様です。ただし、バグ等が原因で元のバージョンに戻したいケースは、比較的多く発生します。

プログラムのソースコードは、通常はSubversionやGit等で管理されていると思います。従って、本番機にデプロイされたプログラム関連のファイルのバックアップは、ビルド・デプロイに時間がかかる場合などを除くとほとんど必要ないと思います。バックアップを取る場合も、正常稼働した最新バージョンのものだけ残せば十分でしょう。

一方、ソースコードのレポジトリはバックアップするのが望ましいです。ただ、こちらは夜間などのアクセスがない時間帯に、レポジトリのディレクトリをそのままバックアップすれば良いので、特に難しいことはないはずです。

データベース

データベース(DB)のバックアップは、他の種類のデータに比べると考慮すべき事項が多く、選択肢もいくつもあります。ここでは一般的な方法をいくつか取り上げます。

具体的な方法について説明する前に、主な要件、およびバックアップ対象としての特徴について述べます。

主な要件

大抵のシステムにおいて、DBはシステムの中核となるもので、重要度は非常に高いと思われます。また、誤操作・バグなどによって誤ったデータが投入されたり、必要なデータが削除されることもあります。従って、一般的には以下のようなことが求められます。

  • 重要度が高いデータに関しては、物理的に異なる複数の場所にバックアップを保管
  • 複数世代(一定期間分)のバックアップを保持する必要がある

また、実際にバックアップを取得する際には、以下に述べる特徴を考慮して設計する必要があります。

バックアップ対象として見たDBの特徴

バックアップ対象としてDBを見る場合、第一の特徴はファイルの整合性が非常に重要という点です。DBMSの種類や設定によりますが、DBのデータは複数のファイルに分かれて保存されていることが多く、それらのファイルを単純にコピーすると、例えば1つ目のファイルと2つ目のファイルがコピーされた時点が異なるため、データを正しく復元できないことがほとんどです。また、データファイルが1つだった場合でも、ファイルのコピーが半分位終わった段階でファイルの前半部分に書き込みが発生すると、1つ目のファイル内に不整合が発生します。

第二に、DBはテーブルデータとトランザクションログという2種類の異なるデータをもつのが一般的で、DBMSの種類や構成にもよりますが、それぞれに対して異なる扱い方が必要です。

最後に挙げたいのは、DB一般の特徴というよりは主にWebサービスにおけるDBの特徴なのですが、24時間アクセスやデータが書き込まれるのが一般的だという点です。したがって、バックアップのためにシステム停止時間を設けるのは極力避けたい所です。

ここで説明した要件、および特徴を踏まえて、バックアップ方法について説明します。

論理バックアップ

上に説明した特徴に対応するための1つの方法として、「論理バックアップ」という方法があります。データベースのデータファイルを物理的にバックアップするのではなく、テーブル構造とデータをそれぞれDDL(CREATE TABLE文など)、INSERT文として出力してバックアップするものです。具体的には、mysqldump(MySQL)、pgdump(PostgreSQL)、Data Pump(Oracle)などのことを指します。

論理バックアップのメリット・デメリットを以下にいくつか挙げます。

メリット:データの一部のみの復元が容易

第一のメリットとして、一部のデータだけを容易に復元できる点が挙げられます。例えば、バグによってあるテーブルのある期間のデータが誤ったものに書き換えられてしまった場合、バックアップデータから該当する行のINSERT文だけを取り出して実行するようなことが簡単にできます。

後述する物理バックアップの場合には、例えば予備のサーバーなどで一度データを復元した後に、必要なレコードを取り出す、といった対応をすることになります。

メリット:データ不整合によるリカバリー失敗は少ない

論理バックアップの場合、「ファイルの整合性が取れていないために復元できない」という問題は発生しません。

ただし、以下のような注意点もあります。

デメリット:テーブル間・テーブル内の不整合

先ほど例に挙げたツールのいずれも、DB全体、あるいはテーブル単位でのバックアップを指定できます。テーブル単位でバックアップを取得する場合、テーブル間で不整合が発生する場合があります。

例えば、ユーザー情報とログイン履歴を保存するテーブルがあり、ユーザーの初回登録時に両方のテーブルにレコードが追加されるとします。1つ目のテーブルのバックアップが終わった直後にユーザーが新規登録を行うと、片方のテーブルにのみデータが入った状態のバックアップになってしまいます。

DB全体をバックアップした場合、「通常は」整合性の問題は発生しません(詳細は後述)。

整合性があまり問題ないシステム、あるいは問題ない箇所というのが存在することも多いので、ケースバイケースでテーブル単位のバックアップを使うことも検討してください。

ユーザーが投稿したデータの項で、大きなファイルをコピーする際のファイル内の整合性について触れましたが、「テーブル単位でバックアップした際に、テーブル内の不整合は発生しないのか?」という疑問を持たれた方もいることと思います。これも、「通常は」発生しません。

「通常は」と書いた理由ですが、バックアップツールの処理は、一般的に

  • 同一のトランザクションで実行
  • バックアップ対象テーブルをロック

のどちらかを行っているため、整合性の問題は発生しません。pg_dumpの場合は前者の方法で、mysqldumpの場合、デフォルトでは後者の方法を使います。

mysqldump の場合、関連するオプションは以下の通りです。

  • --single-transaction
  • --lock-tables

デメリット:ロックの発生

前項で、論理バックアップを行うツールではトランザクション、あるいはテーブルロックによって整合性を確保していると書いた通り、(暗黙的あるいは明示的な)ロックが発生します。

pg_dumpの場合、同一トランザクションで処理が実行されますので、それに伴い共有テーブルロックを取得します。通常は問題になりませんが、VACUUMや明示的なテーブル・ロックなどと同時には実行できません。

mysqldumpの場合、デフォルトでは明示的にテーブルをロックしますので、その間のSQLはロック待ちが発生し、実質的なサービス停止につながる場合があります。

デメリット:任意の時点へのリストアができない

論理バックアップはある時点でのDBの内容の論理的なコピーなので、バックアップ取得時以外のデータに戻すことはできません。

例えば、1日1回、深夜0時に論理バックアップを取得し、それを7日分保管しているとします。この場合、3日前の0時の時点のデータに戻すことはできますが、3日前の3:30の時点に戻すことはできません。一方、物理バックアップの場合、通常はある時点のデータに戻すPoint in Time Recoveryが可能です。

デメリット:リストア時間が比較的長い

論理バックアップの場合、リストアはデータをINSERT文で投入し、インデックスを再作成する処理になります。そのため物理バックアップのリストアに比べると、多くの場合においてより時間がかかります。

物理バックアップ

前節で論理バックアップの長所・短所を説明しました。物理バックアップの長所・短所は、基本的には論理バックアップの正反対であり、論理バックアップのところで大体説明しているので、ここで改めて説明しません。

この節では、物理バックアップの方法をいくつか説明したいと思います。DBではファイル内・ファイル間のデータの整合性がとても重要です。そのため物理バックアップを取る方法のほとんどで、何らかの形の「静止点」が作られます。

DBの停止とファイルのコピー

物理バックアップの一番簡単な方法は、DBサーバーを停止して、その間にファイルのバックアップを取り、その後に再度DBサーバーを起動する方法です。その中でも単純な方法は、DBを停止後にtarやcpなどのコマンドを用いてファイルのバックアップを取得するものです。具体的な方法についてはご存じだと思いますので、説明はいらないと思います。

サーバー停止時間をそれより短く抑えたい場合、rsyncを2回使うという方法があります。rsyncはコピー元とコピー先のファイルを比較して、更新時刻とサイズが同じ物を除いてコピーを行うコマンドですが、それを以下のように使うことでDBサーバーの停止時間を通常のコピーより短く抑えることができます。

  1. 1度目のrsyncの実行。サーバーを停止していないため、実行中にいくつかのファイルが更新される可能性がある
  2. DBサーバーの停止
  3. 2度目のrsyncの実行。1度目のrsync実行中に更新されたファイルのみコピーされる
  4. DBサーバーの起動

お分かりの通り、2度目のrsyncではコピーされるファイルが少ないため、比較的短い時間で処理を完了させることができます。

ファイルシステムのスナップショット

Linuxの場合[2]、LVM2ではファイルシステムを「フリーズ」してスナップショットを取得できます。コマンドを発行した時点でのファイルシステムの完全な内容を取得できるので、ファイルシステムのスナップショットを取得後、データベースファイルを別の場所にバックアップし、通常はその後にスナップショット破棄します。

この方法はサービスを停止する必要がないため、若干複雑ですが、一番望ましい方法と言えるでしょう。

スナップショットは「ある時点」でのファイルシステムの内容で、ファイルシステム的には整合の取れた状態です。ただ、「ある時点」ではDBサーバーが稼働しているため、取得したバックアップからリストアする際には、DBサーバー稼働時に電源断が発生した場合と同様、DBサーバー内部のリカバリー処理が走りますので注意が必要です。

なお、この方法に限りませんが、バックアップ処理は大量のI/Oが発生するため、できればサービスのアクセスが少ない時間帯に行うことが望ましいです。

[2]筆者自身は使ったことがありませんが、SolarisのZFSやWindowsのVSSなどでも同様のことができるはずです。

DBMS固有の方法・ツール

ここまで書いてきた内容は、特定のDBMSに依存しない内容が多かったのですが、DBMS固有の内容についても少し触れておきます。

PostgreSQLの場合は、マニュアルに詳細な手順がある通り、ベースファイルとWALのバックアップを組み合わせてオンラインバックアップが可能です。詳細は マニュアル を参照して下さい。

MySQLでは、@nippondanjiこと奥野さんが、ご自身のブログに 詳細な記事 を書いていますので、そちらが参考になると思います。

その他

ここでは1台のDBサーバーについてのお話でしたが、複数台のDBサーバーでレプリケーションを構成している場合は、バックアップの選択肢が増えます。詳細は省略しますので、各種ドキュメントを参照して下さい。

その他、専用のバックアップツールなどもありますが、基本的には上に挙げたような方法がベースとなっていますので、そうしたツールを使う場合にも基本的な方法を理解しておくと色々応用が効くと思います。

まとめ

今回は、若干駆け足になってしまいましたが、各データの種別ごとに一般的なバックアップ・リストア手法を紹介しました。Webサービスの場合、特にDB(あるいはNoSQLなどのデータストア)のバックアップが重要となりますので、それについては少し多めに説明しました。

前回に書いた通り、全ての面で優れている万能なバックアップ方式というのは存在しません。各バックアップ手法の特徴を把握した上で、バックアップ対象システムの性質・要件、予算、人的資源などの制約条件を考慮して、最適なバックアップ・リストア手法を設計段階で選択できると良いと思います。

今回説明した内容は基本的なものですが、これからシステムのバックアップ・リカバリーを設計する方の参考になれば幸いです。

執筆者紹介
鹿島和郎
ソーシャルグルメサイト「Retty」の開発・インフラ全般を担当。過去には米企業でのオフショア開発拠点の立ち上げから国内SIerでの運用保守業務まで、広く浅く経験している何でも屋。
Rettyは、「行った」お店の投稿・共有、友達・趣味嗜好の合う人のオススメから「行きたい」お店をリスト化、スマートフォンで現在地周辺のお店をリストから検索などできるサービスで、Facebook、Twitterアカウントがあれば無料で使用可能。PC、iPhone、Androidに対応。

Bookfair

O'Reilly Japanのセレクションフェア、全国の書店さんで開催
[ブックフェアのページへ]

Feedback

皆さんのご意見をお聞かせください。ご購入いただいた書籍やオライリー・ジャパンへのご感想やご意見、ご提案などをお聞かせください。より良い書籍づくりやサービス改良のための参考にさせていただきます。
[feedbackページへ]