WALが損失するという課題の解決 -富士通の技術者に聞く!PostgreSQLの技術-
PostgreSQLインサイド

綱川 貴之

富士通株式会社
ミドルウェア事業本部 データマネジメント・ミドルウェア事業部

 

専門分野

  • データベース

入社以来、永年に渡り、データベース管理システム(Symfoware、PowerGres Plus、Interstage Shunsaku)の開発・保守・サポートに従事してきました。また、富士通の各種ミドルウェアで利用されるPostgreSQLの技術サポートも単独で担当し、PostgreSQLカンファレンスで講演したり、社内の教育講座で講師を務めたりもしてきました。私はオープンソース・コミュニティの力を強く信じています。オープンなPostgreSQLとともに、Symfowareがイノベーティブな進化をしていくのを楽しみにしています。

データベースが企業システムの根幹を支えるのは既に周知のことだろう。しかし、世の中に絶対ということはなくトラブルは避けて通れない。データベースで最も困るトラブルといえばデータロストであろう。オープンソースデータベースであるPostgreSQLにも当然それを回避する仕組みが備わっているが、エンタープライズ利用を考えるとまだ足りない部分があるのが現実だ。
富士通では、これに対する解としてデータロストゼロを目指す「WALの二重化」機能を実装した。ここでは技術者がどのように機能を検討し開発したのか?その真相に迫る。

障害発生時、データベースを最新状態に復旧

「自社製データベースにPostgreSQLを取り込んだ富士通の戦略とは?」の回で千田マネージャーよりPostgreSQLをエンタープライズ利用するためにWALの二重化機能を開発したと伺いました。どのような機能なのか具体的に教えてください。

綱川
ご存知のとおりPostgreSQLのトランザクション更新ログを「WAL(Write Ahead Logging)」と呼びます。PostgreSQLではこのWALを複数ファイルに分けて格納します。1つのファイルにログを書き尽くすと次のファイルに進み、すべて使いきると最初のファイルを改名して上書きしていくという動作を繰り返します。私たちが開発したWALの二重化機能は、このWALと同じ内容を持つコピー(これを便宜上「二重化WAL」と呼びます)を別の場所に維持する機能です。これにより、障害発生直前の最新状態までデータベースを復旧できるようになります。

PostgreSQLではWALのアーカイブ設定によりWALのコピーを別の場所に保管できると思いますがそれではダメなのですか?

綱川
仰るとおりPostgreSQLのメディアリカバリ機能では、バックアップデータとWALのコピー(これを便宜上「アーカイブWAL」と呼びます)、この2つを使用してデータベースを復旧します。ただ、アーカイブWALでは厳密には最新状態に復旧することができないのです。たとえばディスクを2台使った最少構成のシステムを考えてみましょう。ディスク1にはデータベースとWALを配置します。ディスク2には、データベースのバックアップとアーカイブWALを配置します。このシステムにおいてディスク1が故障してアクセスできなくなったとします。この場合、どのように障害発生直前の状態までデータベースを復旧しますか?

ディスク2にはリカバリーに必要なデータが揃っていますよね。ですから『故障したディスク1を新しいディスクに交換し、ディスク2にあるデータベースのバックアップからデータをリストアしたあとアーカイブWALを適用する』でしょうか

綱川
手順としてはそうなります。ただ、この方法では先ほど説明したように少し過去の時点までしかデータベースを復旧できません。一部のWALがまだアーカイブされていないので、メディアリカバリ機能で利用できないからです。

WALがアーカイブされていないとはどういうことでしょうか?

綱川
先ほどWALは複数のファイルに分割されて格納していると説明しました。このファイルを「WALセグメント」といい、1つのセグメントは16MBです。WALセグメントが満杯になると、トランザクションの実行とは非同期にバックグラウンドでWALセグメントがアーカイブされて、先ほどの例でいうディスク2にコピーされます。逆の言い方をすると、WALセグメントが満杯になるまではコピーはされないということです。つまり、ディスクの故障などが起きると"まだアーカイブされていないWALセグメントの分"だけトランザクションが失われるということです。

だから最新状態に復旧できないのですね。

綱川
この"アーカイブされていないWAL"に含まれるトランザクションを失わないためにWALの二重化機能を開発しました。WALには障害発生直前までのトランザクションが記録されているため、WALが格納されているディスクが故障するとデータが失われてしまいます。そこで"他のディスクにWALのコピーを常備しよう"というのが機能のコンセプトです。メディアリカバリを行う際に、すべてのアーカイブWALを適用したあとで足りない情報を二重化WALから読み込んで適用します。これで、障害発生直前のトランザクションまで復旧できます。

すべてのトランザクションを復旧するにはアーカイブされていないWALも必要だからそのコピーを常に用意していることがWALの二重化ということですね。であれば、WALをバックアップ用ディスクに配置するという対応ではダメなのでしょうか?

綱川
たしかに、そうすればリカバリーに必要なデータがすべてバックアップ用ディスクに集められますね。しかしWALへの書き込みが失敗するとデータベースは停止してしまいます。つまりそのような構成では“バックアップ用のディスクが故障したときにもシステムが止まる”ということになってしまいます。

WALとRAID それぞれの有用性は?

ではWALを格納したディスクをRAIDで冗長化したらいかがですか?

綱川
それも1つの有効な方法です。WALはメディアリカバリにもクラッシュリカバリにも非常に重要なものです。そのためPostgreSQLコミュニティでは、RAID 1ディスクにWALを配置することが推奨されています。PostgreSQL利用者の中には、実際にそうしている方もいらっしゃいます。ただし、RAIDを使うとなると最低3台のディスクが必要になります。WALとその他のデータファイルを配置するRAID 1ディスク用に2台と、バックアップ格納用に1台です。さらに、ハードウェアRAIDを使用するとなると専用のハードウェアも必要になります。OSが備えるソフトウェアRAIDであれば特別なハードウェアは不要ですが、ソフトウェアRAIDの構成と管理が追加で必要です。

管理する対象が増えるので煩雑さが増すということですね。WALの二重化機能の方が管理も容易なのですか?

綱川
そうですね。WALの二重化機能の場合はディスク2台で実現できます。せっかくバックアップ用のディスクがあるのだから、リカバリーに必要なもののひとつとして二重化WALもそこに配置すれば良いと考えました。バックアップ用ディスクにはリカバリーに必要なものが全て揃っているという分かり易い構成です。また、RAIDとは異なり利用者が追加作業を行う必要がありません。データベース管理者は、サーバー設定ファイル“postgresql.conf”のbackup_destinationパラメーターにバックアップの場所を設定するだけです。指定した場所にはデータファイルや設定ファイル、アーカイブWALや二重化WALなどリカバリーに必要なもの全てが自動的に蓄積されます。

コストパフォーマンスと高い信頼性を両立できるのですね。では、WALの二重化機能があればWALを格納したディスクをRAIDで冗長化することは不要ですか?

綱川
いいえ、RAIDは可用性のためにとても有用です。先ほどお話ししたとおりWALへの書き込みが失敗するとデータベースは停止してしまいます。RAID1を使えば一方のディスクが故障しても、もう一方のディスクに正常に書き込みができれば業務は継続します。RAIDとWALの二重化機能を組み合わせれば、RAIDを構成するディスクがすべて故障した場合であっても、バックアップ用ディスクのデータを使って最新状態まで容易にリカバリーできます。

RAIDとWALの二重化機能を組み合わせることで、より信頼性を高められるのですね。WALの二重化の背景や目的が良く分かりました。

WALの二重化機能によるオーバーヘッドの影響は?

WALの二重化機能についてですが、同じデータを二ヶ所に書き込みすると性能への影響が気になります。性能とはトレードオフとなってしまうのでしょうか?

綱川
いいえ、性能も大事にしました。WALの二重化機能によるオーバーヘッドは2%くらいです。実際にpgbenchを使った更新の多いOLTPベンチマークを実行して計測したところ、WALの二重化機能ありの場合となしの場合でトランザクションのスループット差が2%ほどでした。この結果より、オーバーヘッドに関しては影響をほぼ考慮しなくて良いレベルになっていると思います。

どのようにしてオーバーヘッドを抑えたのでしょうか?

綱川
WALの二重化機能では、WALと二重化されたWAL(これを便宜上「二重化WAL」と呼びます)に対して並列にデータを書き込むことでオーバーヘッドを抑えています。PostgreSQLでは、データベースを更新する各サーバープロセスがWALに更新ログを書き込むのですが、ここに二重化WALに書き込むための専用サーバープロセスである「ログ多重化プロセス」を用意しました。ログ多重化プロセスはサーバーインスタンスごとに1つ存在し、データベースの起動・停止にあわせて起動・停止します。

ログ多重化プロセスですか。もう少し詳しく教えてください。

綱川
はい。私たちが開発したWALの二重化機能では、サーバープロセスがWALに更新ログを書き込む際に、まずログ多重化プロセスに対し二重化WALへのログ書き込みを指示します。その後サーバープロセスは通常どおりWALへのログ書き込みを実施します。このときにログ多重化プロセスも同時に二重化WALへの書き込みを実施します。サーバープロセスは自分自身の書き込み完了とログ多重化プロセスからの書き込み完了報告を待ち合わせます。サーバープロセスは両方の書き込み完了報告を受けて本来の“ログ書き込み完了”となるのです。つまりログ多重化プロセスへの依頼と完了報告応答のやりとりが2%のオーバーヘッドになっているということです。

ログ多重化プロセスの概要図
ログ多重化プロセスの概要図

開発の苦労話について

二重化WALに書き込む専用のプロセスが存在しているのですね。性能についてとても気を使っているのが伝わってきますが実際の開発で苦労されたことはありますか?

綱川
当社ではPostgreSQLを搭載したデータベースの垂直統合製品として「PRIMEFLEX for HA Database」というハードウェアアプライアンスを提供しているのですが、性能のオーバーヘッドを抑えることにとても苦労しました。

さきほどWALの二重化機能にはほとんどオーバーヘッドがないというお話でしたが・・・どういうことでしょうか?

綱川
従来のサーバーではWALなどのファイルがハードディスクに格納されます。WALを配置したハードディスクと二重化WALを配置したハードディスクの性能は同等ですので問題なかったのです。ところがPRIMEFLEX for HA Databaseではフラッシュメモリーを搭載しているため、ディスク性能の関係が逆転してしまったのです。

ディスク性能の関係が逆転・・・・ですか?

綱川
はい、PRIMEFLEX for HA Databaseは、1つのユニットが2台のサーバーとそれに接続される1つのETERNUSディスクアレイで構成されています。各サーバーにはPCIeバス直結の高速なフラッシュメモリーが搭載されており、そこにデータベースやWALが配置されます。一方ETERNUSディスクアレイにはハードディスクが搭載されています。いくらETERNUSディスクアレイに搭載されているハードディスクがエンタープライズ用途の高性能なものであると言ってもフラッシュメモリーと比較するとデータの読み書き速度は劣ります。

高速なフラッシュメモリーにWALを書き込み、それに比べて低速なハードディスクに二重化WALを書き込むのですね。

綱川
そうです。単純にWALと二重化WALを並列に書き込みすると、フラッシュメモリーの方が先に完了してしまい、ハードディスクの性能に引きずられるログ多重化プロセスの書き込みが遅くなります。そうすると、サーバープロセスはログ多重化プロセスからの書き込み完了報告を待つ状態が発生してしまいます。これではフラッシュメモリーの高性能を活かせません。PRIMEFLEX for HA Databaseにとって、性能は非常に重要な要素ですので何らかの割り切り策が必要でした。そこで「高速WAL二重化モード」を新たに用意しました。このモードでは二重化WALへの複数の書き込みを束ねてしまいます。こうすることで二重化WALへの書き込み回数を減らし、ハードディスクの性能による影響を小さくすることに成功しました。

新たな発想で見事に課題を解決しているのですね!

綱川
いえ、そうは簡単にいかないのです。性能を追求するトレードオフとしてWALと二重化WALとの内容が一致しない“すきま時間”がわずかに生じてしまうという問題が発生しました。しかし、この問題はすぐに解決できました。実はPRIMEFLEX for HA Database 上の2台のサーバーは同期レプリケーションによって常に連携しています。そのため、もしプライマリサーバーが故障しても、スタンバイサーバー側にすべてのWALが存在しているので通常のトラブルではトランザクションは失われません。すきま時間が問題になりうるのは両方のサーバーが同時に故障してしまったときのみです。しかし、物事に絶対はないので両方のサーバーが同時に故障してしまった場合も考えていかねばなりません。

ということは今後も更なる改良を重ねるのですね?

綱川
はい、もちろんです。将来はこのようなトレードオフがなくなるよう、PRIMEFLEX for HA Database 上のETERNUSにもフラッシュメモリーを搭載したり、フラッシュメモリーと同等の性能を発揮するように多数のハードディスクでRAID構成を組むなど性能を追求できたらと思います。

ソフトウェアに閉じないハードウェアと一体化したPostgreSQLのミッションクリティカル性をさらに追求していくのですね。今後の進化が楽しみです。

2015年9月25日公開

本コンテンツに関するお問い合わせ

お電話でのお問い合わせ

Webでのお問い合わせ

当社はセキュリティ保護の観点からSSL技術を使用しております。

ページの先頭へ