LASSIC Media らしくメディア
WALとは|DBが障害でデータを失わない仕組み
システム開発の発注担当者やプロジェクトマネージャーは、データベースの障害対策やバックアップ方針を検討する場面で、「WAL」という言葉を目にすることがあります。停電やサーバー障害が起きたときにデータが失われないかどうかは、事業の継続性に直結する論点です。しかし、WALが具体的に何を守り、どこまでの障害に耐えられる仕組みなのかは、開発会社の説明だけでは判断しにくい面もあります。バックアップの方針やSLA(サービス品質の合意水準)を決める前提として、この仕組みの範囲を理解しておく価値はあるでしょう。
この記事では、WAL(先行書き込みログ)とは何か、なぜデータベースの障害対策に欠かせないのかを、実装コードではなく発注者の視点から整理します。あわせて、仕組みの理解に役立つ図と、発注・レビューの場で確認しておきたい点も取り上げます。開発会社との会話やレビューで、判断材料として役立ててください。要件定義やインフラ設計を担う方にも参考になる内容です。
目次
この記事のポイント
- WAL(先行書き込みログ)は、データ本体を書き換える前に変更内容をログへ先に記録しておく仕組みです。
- 記録した変更はログへの書き出しが済んだ時点で確定し、本体への反映は後から行われます。障害発生後はログを再生(REDO)して復旧します。
- PostgreSQLのWALやMySQL(InnoDB)のredoログなど、業務システムで使われるデータベース製品で、耐久性やバックアップ・レプリケーションの基盤として使われています。
WALとは、変更をログへ先に記録する仕組み
WAL(先行書き込みログ、Write-Ahead Logging)とは、データ本体を書き換える前に、これからどう変更するかの記録をログへ先に書き出しておく仕組みです。
この仕組みの狙いは二つあります。一つは、データベースがコミット完了と応じた変更を、突然の障害が起きても失わないよう守ることです。もう一つは、障害発生後に元の整合した状態へ戻すための復旧の道筋をあらかじめ用意しておくことにほかなりません。
Wikipedia日本語版でも、ログ先行書き込みはデータベースの技法の一つと説明されています。原子性(トランザクションをすべて実行するか、まったく実行しないかのどちらかにする性質)と永続性(一度確定した変更を失わない性質)を支える役割を担っているのです。PostgreSQLやMySQLなど、業務システムで広く使われるデータベース製品が、この仕組みを内部に組み込んでいます。
「先行書き込み」という名前は、データ本体への書き込みより先にログへ書き込む順序を、そのまま言い表したものです。ログには、どのテーブルのどの行を、どう変更したかという最小限の記録だけが残ります。データ本体そのものより軽い書き込みで済むため、変更のたびにデータ本体を丸ごと書き出す方式に比べ、負荷を抑えやすいという性質もあわせ持ちます。
会計の世界で例えるなら、台帳(データ本体)を都度書き換える前に、まず仕訳帳(ログ)へ取引を時系列で記録しておくイメージに近いでしょう。仕訳帳さえ正確に残っていれば、台帳が万一失われても、記録をたどって同じ状態を作り直せます。WALも同じ発想で、ログという時系列の記録を土台に、データ本体の正しさを支えています。
データベースの世界には、トランザクションが備えるべき性質としてACID(原子性・一貫性・独立性・耐久性の頭文字)という考え方があります。このうち、コミットした変更を失わない耐久性と、途中経過を残さず全部か無かのどちらかにする原子性の両方を、実装レベルで支えている仕組みの一つがWALです。発注担当がACIDの用語を細かく覚える必要はありませんが、WALが担う役割の位置づけとして押さえておくと、開発会社との会話が理解しやすくなるでしょう。
本体を直接書き換える設計が抱える障害時のリスク
WALがなぜ必要かは、データ本体を直接書き換える設計と比べると分かりやすくなります。仮にログを介さず、変更をいきなりデータファイルへ書き込む設計だったとしましょう。データベースに限らず、途中経過の記録を残さずに本体だけを書き換える設計は、途中で処理が止まった瞬間に弱さを見せるものです。
この場合、書き込みの途中でサーバーが停止すると問題が起きます。データファイルの一部だけが新しい内容になり、残りが古い内容のままという中途半端な状態が生まれるのです。
ページの一部だけ書き換わる「ページ破損」が起きると、そのデータがどこまで正しいのか判別できません。復旧の手がかりとなるログが残っていないため、直前の状態へ戻すことも、変更をやり直すこともできなくなります。
この状態が業務システムで起きると、注文データや在庫データの一部だけが更新され、残りが古いままという食い違いにつながりかねません。原因の切り分けにも時間がかかり、復旧までシステムを止めざるを得ない場面も生じるでしょう。障害の影響範囲をあらかじめ小さく抑える設計が求められる理由は、ここにあります。
コミット済みの変更とコミット前の変更を、どう区別して扱うかという論点も欠かせません。ログを介さない設計では、この境界があいまいになりやすく、コミットしたはずの変更まで巻き添えで失われる恐れがあります。WALはログへの記録という一手間を挟むことで、この境界をはっきりさせている点も見逃せない特徴でしょう。発注担当としては、この境界の扱いを開発会社任せにせず、要件として明示しておく姿勢が事後のトラブルを防ぎます。
WALを使う設計では、この種の障害が起きても、ログをもとに整合した状態へ戻せます。単純な比較で違いを整理すると、次の表のとおりです。
| 観点 | WALが無い設計(本体を直接書き換え) | WALがある設計 |
|---|---|---|
| クラッシュ時の状態 | 書き込み途中のデータが中途半端に残る可能性がある | ログに記録済みの変更だけが確定した状態として扱われる |
| 復旧の可否 | 正しい状態を再現する手がかりが乏しい | ログを再生(REDO)して整合した状態へ戻せる |
| 確定の仕組み | 本体への書き込み完了をもって確定とみなす | ログへの書き出し完了をもって確定とみなす |
ログ追記からコミット確定、REDOによる復旧までの流れ
WALの動きは、大きく三つの段階に分けられます。まず変更内容をログへ順次追記し、次にログへの書き出しが完了した時点でコミットを確定し、最後にデータ本体へ変更を反映するという順序です。下の図は、この流れとクラッシュ時の関係を示したものです。
ログへの追記とコミット確定
データを変更する処理が始まると、データベースはまずその変更内容をログへ順次追記します。追記が済み、ログがディスクへ書き出された時点で、そのトランザクションは確定(コミット)したと扱われます。
データ本体(テーブルやインデックスの実体ファイル)への反映は、この確定より後のタイミングで行われます。PostgreSQLの公式ドキュメントでも、データファイルへの変更はログが記録された後に限って書き込むという原則が示されているのです。実際の変更は、いったんメモリ上のデータ領域へ加えられ、後からまとめてディスクの本体ファイルへ書き出されるのが一般的な流れになります。
クラッシュ時のREDO(再生)による復旧
サーバーが途中で停止しても、ログには変更の記録が残っています。再起動時にデータベースは、ログに記録されているもののデータ本体へまだ反映されていない変更を洗い出し、順番に実行し直します。この処理を、REDO(再生によるロールフォワード復旧)と呼ぶのです。手作業での復旧を待たず、起動処理の一部として自動的に行われる点も実務上のうれしさでしょう。運用担当者が復旧手順を都度組み立てる必要がなく、障害発生から業務再開までの時間を短く保ちやすいという利点にもつながります。
PostgreSQLの公式ドキュメントでは、クラッシュ時にデータページへ未反映の変更をWALレコードから再実行できると説明されています。そのため、コミットのたびにデータページをディスクへ書き出す必要がありません。ログが所定のとおり記録されていれば、本体側への反映は後回しにできるという発想が、この仕組みの土台です。
ただし、ログを際限なく貯め続けるわけではありません。PostgreSQLやMySQLをはじめとするデータベース製品は「チェックポイント」と呼ぶ区切りを定期的に設けています。その時点までの変更をまとめてデータ本体へ書き出す仕組みです。チェックポイント以降のログだけを再生すればよくなるため、再起動にかかる時間を短く保つ役割も担っています。
順次書き込みで得る速度と、確定タイミングのトレードオフ
データ本体への書き込みは、テーブルやインデックスの離れた位置に散らばる「ランダム書き込み」になりやすいものです。一方、ログへの書き込みは末尾へ追記していく「順次書き込み」で済みます。ディスクの特性上、順次書き込みはランダム書き込みより負荷が軽く、コミットのたびに毎回すべてのデータページを書き出すより効率的です。PostgreSQLの公式ドキュメントでも、コミットの確定にはWALファイルの書き出しだけで足ります。そのため、ディスクへの書き込み回数を大きく減らせると説明されているのです。
一方で、ログをどの時点でディスクへ確定させるかは、耐久性と速度のトレードオフになります。すべてのコミットで毎回ディスクへの書き出しを待つ設定は、耐久性を優先する代わりに応答が遅くなりやすいものです。PostgreSQLには、コミット処理でWALレコードがディスクへ書き込まれるのを待たずに応答を返す非同期コミットという設定があります。
この設定を使うと、応答は速くなりますが、書き込みが完了する前にクラッシュが起きた場合、直近の一部の変更が失われる可能性が残ります。PostgreSQLの公式ドキュメントでも、この場合に生じるのはデータの消失であって、データの壊れ(不整合)ではないという整理です。復旧そのものは、それまでに書き出し済みのログをもとに整合した状態で完了するため、壊れたデータが残ることはありません。バックグラウンドの書き込み処理が短い間隔でログをディスクへ反映するため、失われる範囲は短い時間にとどまるのです。
MySQL(InnoDB)にも、redoログをディスクへ書き込むタイミングを調整する設定があり、考え方は同じです。発注担当としては、速度を優先する設定か、耐久性を優先する設定かを、事業のSLAに合わせて選ぶ必要があると理解しておきたいところになります。次の表は、この二つの考え方の違いを整理したものです。
| 観点 | コミットのたびにログを確定させる設定 | 確定を待たずに応答を返す設定 |
|---|---|---|
| 応答速度 | ディスクへの書き出しを待つ分だけ遅くなる | 書き出しを待たない分だけ速くなる |
| クラッシュ時の影響 | 確定と応答済みの変更は失われない | 直近のごく短い時間の変更が失われる可能性がある |
| 向く場面 | 決済・在庫更新など消失を避けたい処理 | 多少の消失を許容し速度を優先したい処理 |
PostgreSQLのWALとMySQLのredoログという実例
WALという名称を前面に出している代表例が、PostgreSQLです。PostgreSQLの公式ドキュメントでは、WALをクラッシュリカバリの土台として説明しています。あわせて、レプリケーションやバックアップの仕組みも、このログを土台に構築していると位置づけているのです。
MySQL(InnoDB)にも同じ考え方の仕組みがあり、こちらは「redoログ」と呼ばれています。MySQLの公式マニュアルでは、redoログはクラッシュリカバリの際に使われるディスク上の構造だと説明されています。不完全なトランザクションによって書き込まれたデータを、正しい状態へ修正するために使われるという位置づけです。
なお、MySQLではレプリケーション(同じデータを複数のサーバーへ複製する仕組み)に、redoログとは別の仕組みが使われます。「バイナリログ(binlog)」と呼ばれる別のログです。役割の異なる複数のログが組み合わさっている点は、発注・設計時に混同しやすいので注意が必要でしょう。
PostgreSQLでは、WALそのものを複製先のサーバーへ送るストリーミングレプリケーションという構成が採られます。クラッシュリカバリと複製という、一見別々に見える機能が、同じログの仕組みの上に重ねて実現されている点が特徴です。製品によって設計思想に違いがあるため、採用する製品のドキュメントで、どのログが何を担っているかを確認しておく必要があります。
アプリケーションを開発するエンジニアの立場からは、WALやredoログの存在を意識せずにSQLを書ける場面がほとんどです。仕組みは製品の内部に隠れており、日々の開発作業を直接妨げるものではありません。だからこそ、発注者側が「裏側でどう守られているか」を把握し、要件やレビューの場で確認する役割を担う意義があるといえるでしょう。普段は意識されにくい仕組みだからこそ、要件定義の段階で明文化しておかないと、後工程で見落とされたまま進んでしまうこともあります。
| 製品 | ログの名称 | 主な役割 |
|---|---|---|
| PostgreSQL | WAL(先行書き込みログ) | クラッシュリカバリ。レプリケーションやバックアップ(PITR)の基盤も兼ねる |
| MySQL(InnoDB) | redoログ | クラッシュリカバリ。レプリケーションには別のバイナリログ(binlog)を使用 |
PITR(Point-In-Time Recovery、特定時点まで状態を戻す復旧手法)という考え方があります。定期的なバックアップと、その後に発生したWALを組み合わせて実現します。バックアップの方針を検討する際は、WALをどこまで保存し、どう組み合わせて復旧するかもあわせて確認しておきたい点です。
WALそのものは、生成された後も一定期間は保存され、複製やバックアップからの復旧に使われた後、順次不要になっていく性質を持っています。保存期間や保存先の設計を誤ると、いざ復旧したい時点のログがすでに失われている、という事態も起こり得ます。運用設計の段階で、保存方針まで含めて確認しておくとよいでしょう。
発注・レビューで確認する3つの論点
WALの仕組み自体を自社で作り込む場面はほとんどありません。既存のデータベース製品が内部で担っているため、発注やレビューの段階では、設定と運用方針を確認することが実務上の要点になります。「バックアップさえ取っていれば十分」という認識のまま要件をまとめてしまうと、確定タイミングの設定や保存容量の見積もりが抜け落ちやすい点にも注意が必要でしょう。
耐久性要件をどこまで求めるかの確認
事業にとって、直近数秒分のデータ消失も許容できないのか、多少のロスは許容し速度を優先するのかによって、必要な設定は変わります。決済や在庫更新のように消失が業務影響へ直結する処理と、ログ収集のように多少の欠落を許容できる処理とでは、求める耐久性の水準も異なるはずです。この耐久性要件を先に言葉にしておくと、開発会社との設定方針の相談が具体的に進みます。
バックアップ・リカバリ方針の確認
WALやredoログは、単体でバックアップの代わりになるものではありません。定期的なバックアップと組み合わせて、障害発生時にどこまでの時点へ戻せるのかを、開発会社に確認しておく必要があります。バックアップの取得頻度が粗いと、WALと組み合わせても復旧に時間がかかる場合があるため、頻度と復旧目標を合わせて検討しておくとよいでしょう。
ログの確定タイミング設定の確認
ログをディスクへ確定させるタイミングは、速度と耐久性のどちらを重視するかを左右する設定です。デフォルト設定のまま運用するのか、事業要件に合わせて変更するのかを、レビューの段階で開発会社とすり合わせておくとよいでしょう。
ログの保存先と容量計画の確認
ログはデータの更新量に応じて増え続けるため、保存先の容量やチェックポイントの間隔を見込んでおく必要があります。容量計画を怠ると、ログ用の領域が想定より早くひっ迫し、運用開始後の設定変更に追われる事態になりかねません。導入前の見積もりの段階で、更新頻度に見合った容量を確認しておくことが望ましいでしょう。運用開始後も、ログの増加量やチェックポイントの実行状況を継続的に監視できる体制を整えておくと、容量ひっ迫の兆候を早めに捉えやすくなります。
まとめ
- WAL(先行書き込みログ)は、データ本体を書き換える前に変更内容をログへ先に記録する仕組みである。データ本体を直接書き換える設計に比べ、障害時の影響を小さく抑えられる。
- ログへの書き出し完了でコミットが確定し、本体への反映は後から行われる。チェックポイントの仕組みが、貯まったログと反映済みの範囲を整理する。
- クラッシュ時はログを再生(REDO)して、未反映の変更を復旧する。復旧処理は起動時に自動で行われる。
- 順次書き込みによる速度の利点がある一方、確定タイミングの設定は耐久性とのトレードオフになる。事業のSLAに合わせた選択が必要である。
- PostgreSQLのWAL、MySQL(InnoDB)のredoログなど複数の製品で採用され、バックアップ(PITR)やレプリケーションの基盤にもなっている。
よくある質問
WALがあれば、クラッシュ時のデータ消失を防げますか。
設定によって結果が変わります。ログをディスクへ書き出した時点でコミットを確定する標準的な設定であれば、クラッシュ後もログを再生すれば復旧できるでしょう。ただし、応答を速くするために書き出しを待たずに確定を返す設定を使う場合は、直近のごく短い時間の変更が失われる可能性が残ります。PostgreSQLの公式ドキュメントでも、この場合に生じるのはデータの消失であり、データの壊れではないと説明されています。どちらの設定を選ぶかは、事業として許容できる消失の範囲をふまえて判断する事項でしょう。
WALのログファイルは、いつまで保存する必要がありますか。
少なくとも、ログの内容がデータ本体へ反映され終わるまでは保存が必要です。加えて、レプリケーションやバックアップからの復旧(PITR)に使う場合は、その用途に応じた期間分を残しておく設計になります。保存先の容量が尽きると新しいログを書き込めなくなり、運用に支障が出るため、容量監視の仕組みもあわせて確認しておきたいところです。古いログを自動で削除・アーカイブする設定と、バックアップの取得間隔がかみ合っているかも、あわせて点検しておきたい観点でしょう。具体的な保存方針は、採用するデータベース製品の設定と、事業のバックアップ要件に合わせて決めることになります。
WALはバックアップの設計にどう関わりますか。
WALは、定期的なバックアップと組み合わせて使う仕組みです。PITR(Point-In-Time Recovery、特定時点まで状態を戻す復旧手法)を実現する基盤になります。バックアップ単体では、取得した時点の状態にしか戻せない点が弱みです。取得後に発生したWALをあわせて適用することで、障害の直前に近い状態まで復旧できるようになります。バックアップ方針を検討する際は、この組み合わせ方も確認しておきたい点です。
発注担当として、WALの設定を細かく指定する必要がありますか。
設定値そのものを指定する必要はありません。まずは事業として許容できる耐久性要件(データ消失をどこまで許容するか)を言葉にし、開発会社にその要件へ見合う設定を提案してもらう進め方が現実的です。レビューの場では、提案された設定が要件に沿っているか、保存容量や監視の仕組みまで含めて確認する形になります。
著者:テレリモ総研編集部 鈴木 亮佑
LASSICでは、国内ニアショア開発体制を活かし、データベースの耐久性・可用性の設計から実装、公開済みシステムの見直しまでを一貫して支援する体制です。要件定義の段階から実装、テスト、リリース後の運用・保守まで、工程を分けずに任せられる点も強みでしょう。バックアップやリカバリの方針づくりでお困りの際も、ご相談いただけます。
ご不明な点はお問い合わせフォームからもご連絡いただけます。
出典
- PostgreSQL公式ドキュメント「Write-Ahead Logging (WAL)」
- PostgreSQL公式ドキュメント「Asynchronous Commit」
- MySQL 8.4 Reference Manual「InnoDB Redo Log」
- Wikipedia日本語版「ログ先行書き込み」