TOP比較データ> PostgreSQLの特徴
アーキテクチャ
徹底比較!! Oracle & PostgreSQL

第3回:アーキテクチャ比較 ファイル構造の違い
             PostgreSQLの特徴

著者:ミラクル・リナックス  高橋 強   2004/12/16
前のページ  1  2  3
PostgreSQLの特徴

   PostgreSQLとOracleについての構造的差異の概略はつかんで頂けたでしょうか?次に、PostgreSQLのもつ特徴的な機能について2つ紹介したいと思います。





追記型アーキテクチャ

   ここまではPostgreSQLとOracleのプロセスやファイル構造の違いを説明してきました。その違いを押さえていただいた上で、PostgreSQLが他の商用DBMSと大きく違っている点は
追記型である事です。

   追記型のDBMSではデータを変更する際に、旧データを変更せずに、新しい行を末尾に追加していきます。削除時には実際に削除する代わりに無効を表す印を付けます。こうする事で、構造的に読み取り一貫性を実現しています。

アーキテクチャの違い
図4:アーキテクチャの違い

   Oracleでは読み取り一貫性を実現する為に、rollback(UNDO)セグメントやロック機構を用いて複雑な処理を行っています。PostgreSQLではその点ではシンプルな構造を採りつつ、同じような読み取り一貫性を実現しています。PostgreSQLではこの機能をMVCC(Multiversion Concurency Control)と呼んでいます。


MVCCの仕組み

   PostgreSQLの各行には OID(Object ID)というユニークな番号が割り振られています。また、XIDというトランザクションを識別する為の番号も割り振られています。
(Oracleでいえば、OID≒ROWID、XID≒SCNが似た値として該当しそうです。)

   MVCCの仕組みを下図5を例に簡単に説明します。

PostgreSQLの追記型データ更新の仕組み
図5:PostgreSQLの追記型データ更新の仕組み

   部門表には元々3行のデータが格納されていました。インサート当時のXID=10でした。その後に、部門コード"001"の部門名が変更になった為、update文が実行されたとします。

   (1)部門名変更のUPDATE文を実行
   (2)行を特定するOIDはそのまま継承し、修正された新たな行を末尾に追加
       元のOID=5001,XID=10の行には無効の印が付けられる。
   (3)以後のトランザクションでは新しい OID=5001,XID=93の行が検索される。

   ここで追記型の弱点が見えてきますが、それは無効とされた行の扱いの問題です。

   PostgreSQLでは、削除や更新された古いデータ行が残っています。テーブルは1つの物理ファイルですから、OLTP処理などの更新が多数発生する場合は、本来のデータ量と変更前の履歴データをすべて抱え込む事になってしまい、次第に肥大化していきます。 この為に、検索時の負荷が増大したり、本来無用であるはずの領域サイズを保持しなければならないと言った問題が発生してきます。

   この状態をPostgreSQLではVACUUMというコマンドで解消します。VACUUMを実行することで、不要な行は削除され、テーブルに対応した物理ファイルのサイズを縮小する事ができます。 その為、VACUUMはPostgreSQLではパフォーマンス維持やディスクの空き領域の管理の為には必要不可欠な作業であると言えます。


VACUUM

   このVACUUMコマンドは2つの実行形態があります。

VACUUM
コンカレントVACUUMと呼ばれ、削除・更新され不要とマークされた行を再利用可能にするのみ。排他ロックは発生しないが、ファイル縮小は行われない。

VACUUM FULL
本来のVACUUM。排他ロックが発生する。

   この違いを図で表したのが下図6です。

VACUUM vs コンカレントVACUUM
図6:VACUUM vs コンカレントVACUUM

   PostgreSQL 7.1まではコンカレントVACUUMは実装されておらず、排他ロックが必要なVACUUM(FULL)しかありませんでした。 その為、事実上定期的にシステムを停止させる必要があり、この事がPostgreSQLを連続運用が求められるシステムへの適用を阻害する原因と言われてきました。 現在のコンカレントVACUUMでは排他ロックについては解決できていますが、負荷の面ではまだ問題ありという評価もあるようです。この辺りは今後、実際のテストで確認してみたいと思います。


トランザクション・ログ

   PostgreSQLの運用に関して、もう一点、知っておく必要があるのはトランザクション・ログの特性です。 このトランザクション・ログとはデータベースに対する変更履歴を記録しておく機能です。 データの変更にかかわる記録を逐一保存しておく事で、急な電源遮断などが起きた場合、データに不整合が発生するのを防いでいます。
   PostgreSQLではこの機能をWAL(Write Ahead Logging)といいます。

   こういった機能が必要になる理由としては、同期書き込みと非同期書き込みの違いを知っていただく事が必要です。

同期書き込み
データを物理ディスクに書き込まれるまで処理を待つ。

非同期書き込み
ディスクへの書き込み要求だけ出して、バッファへの書き込みのみで次の処理へ移る。
結果を待たない

   データベースのようなシステムの場合、データの整合性を保障する事は最低条件といえます。 その為には同期書き込みを行う事が望ましいのですが、I/O処理を終了まで待つと、どうしても処理速度が低下します。非同期書き込みではI/O処理を待たずに、次の処理へ移れる為、レスポンスは改善されます。ただし、この時の書き込み要求はOSバッファへ書き込んだだけで、実際のディスクへは書き込みされません(OSが後で書き込む)ので、この時点で障害が起きるとデータの不整合が発生してしまいます。

   そこで、処理性能(レスポンス)の高速化とデータ書き込みの信頼性を両立させる為の機能としてWALが実装されました。WALでは下記の順で処理がなされます。

(1)トランザクション・ログを同期書き込み
(2)テーブル、インデックスなどのデータは非同期書き込み

   トランザクション・ログへの書き込みはシーケンシャル・ライト(追記、ログの末尾に追加する)なので実データに比べると高速に行える為、負荷が少なくて済みます。 また、1.以降、実際に実データが書き込まれる以前に障害が発生した場合には、トランザクション・ログを使って実データに反映(ロール・フォワード)することで、データの整合性を保ちます。

   OracleでもREDOログを用いて、同等の処理を行っていますが、違う点もあります。

   PostgreSQLのWALでは下記の様な動作を行います。

(1)$PGDATA/pg_xlog にトランザクション・ログを記録したファイルを作成
(2)ログを追記
(3)不要になると自動的に削除

ですがOracleでは、REDOログは事前に作成された二つ以上の物理ファイルを循環して使用します。

   不要になったログを保持しつつ、ファイルを切り替えた場合に一杯になったREDOログファイルの内容をアーカイブ・ログとして保存する事ができます。

(1)REDO1へログ書き込み
(2)REDO1がいっぱいになったら、REDO2へ
(3)いっぱいになったREDO1はアーカイブとしてコピーを取得できる

   バックアップされたデータファイル、コントロールファイルがあれば、アーカイブ・ログとオンラインREDOログを用いて、データを復旧する事が可能となっています。この機能のおかげで、PITR(Point In Time Recovery)が実現されていますし、多様なパターンでのリカバリを可能とする根幹ともなっています。PostgreSQLではPITRは実装されておらず(8.0にて実装予定)、リカバリのパターンはOracle程の自由度はないのが現状です。(バックアップとリカバリについては後ほど詳しく取り上げる予定です。)

   アーキテクチャについては以上です。PostgreSQLの特徴的な部分である「追記型」という実装がOracleとの大きな違いであり、少なくともコンカレントVACUUM実装以前には、大規模システムでの採用を妨げてしまっていた要因であった事がお分かりいただけたかと思います。

前のページ  1  2  3


ミラクル・リナックス
著者プロフィール
ミラクル・リナックス株式会社  高橋 強
1993年某SIベンダへ入社後、Oracle、DB関連のコンサルティング、チューニング、社内案件の技術支援などを10年ほど担当。2004年ミラクル・リナックス株式会社へ入社。


INDEX
第3回:アーキテクチャ比較 ファイル構造の違い PostgreSQLの特徴
  PostgreSQLのファイル構造<
  Oracleのファイル構造
PostgreSQLの特徴