PR

ポイント・イン・タイム・リカバリ(PITR: Point In Time Recovery)

 詳細はすでにPostgreSQLウォッチ第10回で紹介したが,従来CHECKPOINTのタイミングで捨てていたトランザクション・ログ(PostgreSQLでは「WALログ」と呼ぶ)をアーカイブ・ログとして保存しておくことによって,データベース本体がメディア障害によって失われるような重大な障害の際にも,障害直前の状態までデータベースの復旧ができるようになった。もちろんWALログとアーカイブ・ログが失われていないことが前提条件になるので,これらをデータベース本体とは物理的に別のディスク装置に格納すること,RAID装置などを使って破壊から守ることが必要である。

 PITRでは,最新の状態にデータベースを復元するだけでなく,任意の時点の状態に復元することもできる.たとえば,重大なデータを誤って削除してしまったような場合に有用だ。

 8.0では,データ損失を最小限にするために頻繁にpg_dumpを実施するような運用が不要になったため,特に大規模なデータベースで問題になっていたバックアップ中の負荷増大と言った問題を回避できるようになった。もちろん,ポイント・イン・タイム・リカバリを使用する際にもバックアップは必要だが,従来よりはずっと頻度を少なくすることができるはずだ。

 ポイント・イン・タイム・リカバリを導入したとしても,データのリカバリには相当な時間がかる.アーカイブ・ログからのリカバリは,本質的にはトランザクションの再実行になるからである。ダウンタイムを最小限にしたい場合は,レプリケーションを併用し,可用性を向上させるべきである.たとえばSlony-I(関連記事)やpgpool(関連記事)はすでにPostgreSQL 8.0に対応済なので,これらを利用することを考えよう。

 なお,PostgreSQLウォッチ第10回では,ポイント・イン・タイム・リカバリの制約事項として,CREATE DATABASE/DROP DATABASE/CREATE TABLESPACE/DROPTABLESPACEはリカバリの対象にならないとしていたが,正式リリース版ではこれらの制限事項は解消されている。ただし,Btree以外のインデックス(ハッシュ,Rtree,GiST)は正式リリース版でもリカバリの対象になっていないが,これらのインデックスは利用頻度が低いこと,またREINDEXで再構築できるなどの理由から実際にはあまり問題にならないと思われる。

テーブル・スペース(Tablespaces)

 テーブルやインデックスを別々のデータベース用の領域(テーブル・スペース)に配置し,より細かく領域管理するための機能である。これによって複数のディスク・ドライブを使って性能を向上させることが可能になるなどのメリットが生まれる。

 また,ディスク領域は不足したときにディスクを追加し,特定のテーブルやインデックスをそこに移動するといった使い方もできる。

テーブル・スペースを利用するためにTABLESPACEオプションがCREATE TABLE,CREATE DATABASE,CREATE INDEXに追加されている。詳細は本連載の第10回をご覧いただきたい。

セーブ・ポイント(Save Point)

 SQL標準のセーブ・ポイントが実装された。セーブ・ポイントを使うとトランザクションのすべてではなく,一部だけをロールバックでき,より細かなトランザクション管理ができるようになる。

バッファ管理手法の変更,バックグラウンド・ライター・プロセスの追加など

 DBMSの性能を向上させるためには,バッファの管理が重要である。今回,はじめてPostgreSQLのバッファ管理アルゴリズムに変更が加わった。新アルゴリズムでは,順スキャンなどの場合に一過性の大量のデータの読み込みによって,使用頻度の高いデータがバッファから追い出されることが少くなった。

図2●PostgreSQL 8.0と7.4.6のロード性能の比較
 手元の環境(Red Hat Linux 9, Pentium 4(2.4GHz x2), メモリ1Gバイト)の環境でpgbenchを使って1千万のデータで試したところ,8.0は7.4.6に比べてデータのロード,インデックス,VACUUMの合計にかかる時間が11%短かった。また,SELECT count(*) FROM accountsにて全件検索するテストでも8.0は処理時間が14%短かった(図2[拡大表示])。

 従来は,変更のあったバッファをディスクに同期書込するタイミングがCHECKPOINTに集中し,極端なパフォーマンスの低下を招いていたが,バックグラウンド・ライター・プロセスが定期的に変更のあったバッファを少しずつディスクに書き込むことにより,パフォーマンスがより安定するようになった。

オプティマイザの改良

 データベースの性能はオプティマイザによるところが大きい。近代的なデータベースでは,最適な問い合わせ実行プランはデータベース管理システムが自動的に決めるからだ。そこで,PostgreSQLでもリリースごとに着実にオプティマイザを改良しており,8.0では主に以下のような改善が行われた。

  • インデックスを使用するかどうかを決めるための,列とデータの型一致検査が柔軟になった。たとえば,列の型がBIGINTの時に比較の対象となるデータの型がINTEGERであってもCASTを必要としなくなった。この結果,不注意でインデックスが使用されない,というトラブルが激減するはずだ。

  • 複数の条件をANDでつないだものをORで複数つなぐような検索条件で,非現実的なほど時間のかかるケースがあったのが改善された。極端な例では,7.4では一晩経っても終わらない問い合わせが,8.0では1秒以内に終わるケースもある。

  • マルチカラム・インデックスが適用できる範囲が広がった。

  • 部分インデックスが適用できる範囲が広がった。

  • 従来関数インデックスの統計情報は取得されなかった。8.0では関数インデックスに対しても統計情報が取得できるため,関数インデックスを適用できるかどうかの判断が正確に下せるようになった。

  • オプティマイザに関連した改良として,実際のテーブル・サイズを動的に取得してテーブル行数を推定する機能が追加された。これにより,前回VACUUMしてから大幅に行数が変化した際にもより正確な統計情報が取得できるようになった。また,ANALYZE手法自体も改善されており,特にデータの分布が片寄っている場合により正確な統計情報が取得できるようになった。