ストリーミング・レプリケーションの紹介
はじめに
PostgreSQL 9.0(2010 年 9 月にリリース)において、待望の、本体組み込みのデータ複製機能であるストリーミング・レプリケーション機能と、待機ノードへのクエリ発行を可能にするホット・スタンバイ機能が搭載されました。そして今年 2011 年 9 月にリリースされた PostgreSQL 9.1 では、ストリーミング・レプリケーションの機能強化と、これまた待望されていた同期でのレプリケーション機能が盛りこまれました。これによって、より多様な、あるいは堅固な構成のデータベースシステムが、オープンソース実装で簡単かつ柔軟に構成できるようになりました。
本連載では、最新の PostgreSQL の各種新機能の中でもストリーミング・レプリケーションに焦点を当てて、非同期での簡単な設定方法、複製状態の確認のしかた、同期レプリケーションの使い方、HA(High-Availability: 高可用性)を確保するための簡単なシステムの構築を見て行きたいと思います。
WAL(Write Ahead Logging)の変遷とレプリケーション
PostgreSQL もバージョン 7.0(2000 年リリース)以前においては、コミット済みデータの永続性を保証するためには、ディスク上のデータ領域に対して直接に同期でデータを書き込む必要がありましたが、この方式ではハードディスクへのランダムアクセスが頻発するため、思うように性能が出ませんでした。そこでバージョン 7.1(2001年リリース)において、ランダムアクセスによる書き込みよりもシーケンシャルアクセスによる書き込みが高速であるという特性を利用して、データの永続性保証とパフォーマンスを両立させた WAL(Write Ahead Logging:ログ先行書き込み)が導入されました。PostgreSQL のサーバは、WALへの書き込みは同期で、データ領域に対するランダムアクセスでの書き込みは非同期で記録するようになりました。
このように本来は、システム障害や突然の停電などの不測の事態が起きてもコミット済みのデータを失うことなくデータベースをリカバリすることを目的として実装された WAL でしたが、一連の WAL は、そのデータベースへの変更をシリアライズしたものでもあることから、別のデータベースに対して一連の WAL を適用することで、変更を再現することが容易になります。そのため、その後様々な応用が進みました。例としては、オンラインでの物理バックアップ、PITR (Point-In-Time Recovery)、ログシッピングによるウォーム・スタンバイといった機能があります。
そして、その応用の一つとしてストリーミング・レプリケーションが登場しました。
図1:従来のウォーム・スタンバイ構成とホット・スタンバイとの比較(クリックで拡大) |
本機能をわざわざ「ストリーミング」と呼ぶことからも分かるように、以前は、ストリームではなく大きな塊として変更を転送することでレプリケーションを実現していました(ファイルベース・レプリケーション)。従来(PostgreSQL ~8.4)のウォーム・スタンバイ構成では、プライマリからスタンバイへの更新ログ(WAL ログ)の転送は、16MB の WAL セグメントファイルが WAL レコードで一杯になるか、archive_timeout パラメータで指定した時間が経過するまで行われませんでした。そのため、ディスクに障害が起きたタイミングによっては、失われるデータのサイズが大きくなる可能性がありました。また、スタンバイサーバへの問い合わせもできませんでした。
PostgreSQL 9.0 で導入されたストリーミング・レプリケーションによって、転送単位が WAL レコード単位となったことで更新を反映する際の粒度と遅延が小さくなり、同時に導入されたホット・スタンバイ機能によって、スタンバイサーバに対してもクエリを発行することが可能になりました。
そして、PostgreSQL 9.1 では、WAL レコードの転送を同期で行うことも可能になりました。これによって、コミットが成功した時点ではすでに、同期スタンバイ側でも WAL レコードがハードディスクに書き出されたことを保証することができます。なお、ここで言う「同期」は WAL に関するものであり、プライマリとホット・スタンバイから SQL のクエリによって読み出されるデータがお互いに同期していることを保証するものではないことに注意してください。