技術情報
PostgreSQL 8.3 に関する技術情報
リリース日:2008/02/04
掲載日:2008/02/05
このページでは PostgreSQL 8.3 に関する技術情報をお届けします。
概要
重要な新機能とパフォーマンス改良が入ったバージョンです。 コミュニティの拡大により開発速度が向上し、多くの機能が取りこまれました。 本リリースでは以下の主要な機能が追加されています。
新機能
- 全文検索機能をデータベースシステム本体に統合
- SQL/XML サポート
- ENUM データ型のサポート
- 複合型の配列
- UUID データ型
- ソート時に NULL データを最初にするか最後にするかの制御
- 更新可能カーソル
- サーバ設定パラメータを関数単位で設定できるようになった
- ユーザ定義型が型識別子を持てるようになった
- テーブル定義の変更もしくは統計情報が更新された場合に、キャッシュされたクエリを自動的に再計画するようになった
性能向上
- Heap-Only Tuples (HOT) による UPDATE のための領域の再利用機会の増加
- COMMIT 中に WAL への書き込みを遅延させる非同期コミット
- 負荷分散チェックポイントによるチェックポイント I/O 集中の防止
- ジャストインタイムバックグラウンドライタによるディスク書き込みの効率化
- 各列と各行のストレージオーバヘッドの削減
- シーケンシャルスキャンが頻繁に使われるキャッシュページを追い出さないようにした
- 並列にシーケンシャルスキャンを実行した時にディスク読み込みの共有
- ORDER BY ... LIMIT をソートしないで処理するようにした
運用面での改良
- 参照のみのトランザクションで非永続トランザクション ID を使用することにより、オーバヘッドや XID 周回問題対策の VACUUM を軽減
- ロギングと統計情報収集器の改良
- 並列に複数の autovacuum プロセスが動作するようになった他、autovacuum を改良
Windows 固有の改良
- Windows 上で認証のための Support Security Service Provider Interface (SSPI) のサポート
- Microsoft Visual C++ を使って PostgreSQL 全体をコンパイルできるようにした
8.3 への移行
すべての過去のリリースからデータを移行する場合、pg_dump を使用したダンプ・リストアが必要です。
互換性のない変更点
一般
- 文字でない型 (日付型など) を自動的に text 型に変換しないようにしました。
今までは text 型入力を受けとる演算子や関数に文字でない値が渡されると、自動的に text 型にキャストしていました。 これからは text 型でないデータを渡したい場合には text 型への明示的なキャストが必要になります。 例えば以前は以下の式が動作していました。
- PostgreSQL 8.2
postgres=# SELECT substr(current_date, 1, 3); substr -------- 200 (1 row) postgres=# SELECT 23 LIKE '2%'; ?column? ---------- t (1 row)
これらの SQL は "function does not exist" や "operator does not exist" エラーになります。
- PostgreSQL 8.3
postgres=# SELECT substr(current_date, 1, 3); ERROR: function substr(date, integer, integer) does not exist LINE 1: SELECT substr(current_date, 1, 3); ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts. postgres=# SELECT 23 LIKE '2%'; ERROR: operator does not exist: integer ~~ unknown LINE 1: SELECT 23 LIKE '2%'; ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
この場合は明示的にキャストさせる必要があります。
postgres=# SELECT substr(current_date::text, 1, 3); substr -------- 200 (1 row) postgres=# SELECT 23::text LIKE '2%'; ?column? ---------- t (1 row)
この変更の理由は自動キャストによって驚くような振舞いを引き起していたためです。 1 つの例として今までのリリースでは、以下の式は実行可能ですが、期待した動作ではありませんでした。
current_date < 2017-11-17
これは日付型と整数型で比較しており、偽とすべきです。 しかし、自動キャストの場合、両方の値をテキストに自動キャストし、テキスト比較をしてしまいます。 理由は text < text オペレータ以外に < オペレータが存在しない場合に式をマッチすることができてしまうためです。
char(n) と varchar(n) については自動的に text 型に変換します。 また、文字連結 (||) オペレータの入力値についても自動的に変換します。 ただし、少くとも 1 つは文字列型を含む必要があります。
- 1 つ以上文字列を含む場合は正常に動作
postgres=# SELECT 1 || 'a' || 1; ?column? ---------- 1a1 (1 row)
- 文字列を含まない場合の動作
postgres=# SELECT 1 || 1; ERROR: operator does not exist: integer || integer LINE 1: select 1 || 1 ^ HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
- 全文検索機能を contrib/tsearch2 から本体に移しました。またその際にいくつか構文を変更しました。
contrib/tsearch2 には現在旧バージョンとの互換性インターフェースを持っています。
- ARRAY(SELECT ...) 式で SELECT が 1 行も返さなかった場合に空の配列を返すようにしました。 今までは NULL を返していました。
- 基本データ型の配列型の名前を '_' を先頭につけた基本型名にするのをやめました。
古い名前付けは残っていますが、アプリケーションコードでは名前付けに依存すべきではありません。 代わりに pg_type.typarray カラムを使ってください。
- ORDER BY ... USING オペレータは btree オペレータクラスで定義した大小比較オペレータを使わなければならないようにしました。
この制限は不整合な結果を防ぐために追加しました。
- SET LOCAL で変更したパラメータをロールバックしなければ一番外側のトランザクションの最後まで保持するようにしました。
以前は SET LOCAL の効果はサブトランザクションがコミットされた後 (RELEASE SAVEPOINT もしくは PL/pgSQL の例外ブロックから戻った時) に失なわれていました
- トランザクション内での実行を許可されていないコマンドを複数並べた SQL 文の中でも許可しないようにしました。
例えば "BEGIN; DROP DATABASE; COMMIT" は許可されません。
- トランザクションブロック外での ROLLBACK は WARNING ではなく NOTICE を返すようにしました。
postgres=# ROLLBACK; NOTICE: there is no transaction in progress ROLLBACK
- スキーマ名が修飾された名前を NOTIFY/LISTEN/UNLISTEN が受け入れないようにしました。
今までは schema.relation という名前を受け付けていましたが、実際にはスキーマ名を無視していました。
postgres=# LISTEN a.b; ERROR: syntax error at or near "." LINE 1: LISTEN a.b; ^ - ALTER SEQUENCE がシーケンスの currval() の状態に影響を与えないようにしました。
- 外部キーがデータ型をまたぐ参照の場合にインデックス条件にマッチしなければなりません。
これは意味的な整合性の改良とパフォーマンス問題を避ける手助けになります。
- オブジェクトサイズを計算する関数を適切な権限のあるユーザのみ使えるように制限しました。
例えば pg_database_size() は CONNECT 権限が必要になります。 pg_tablespace_size() は指定したテーブルスペース内での CREATE 権限が必要になります。
- ドキュメントにない !!= オペレータ (NOT IN と同じ意味) を削除しました。
NOT IN (SELECT ...) が適切です。
- 内部のハッシュ関数がより一様分布するようになりました。
アプリケーションコードが、PostgreSQL 内部のハッシュ関数を使ってハッシュ値を計算して格納している場合は、ハッシュ値を再生成しなければなりません。
- 可変長データ値を扱う C コードのコンバージョンを変更しました。
新しい SET_VARSIZE() マクロを使って生成された varlena の値の長さをセットしなければなりません。 また、多くのケースでは入力値を展開 (TOAST から戻す) するのに必要になるかもしれません。
- ログレベルを DEBUG にしなければ、継続アーカイブによるオペレーションが成功したという報告をサーバログに出さないようにしました。
設定パラメータ
- 削除されたパラメータ
- bgwriter_lru_percent
- bgwriter_all_percent
- bgwriter_all_maxpages
- stats_start_collector
- stats_reset_on_server_start
- 名前が変更されたパラメータ
PostgreSQL 8.2 PostgreSQL 8.3 redirect_stderr logging_collector stats_command_string track_activities stats_block_level、stats_row_level track_counts (2 つのパラメータを統合) - 新規パラメータ
名称 意味 デフォルト値 archive_mode アーカイブの可否 off autovacuum_max_worker autovacuum プロセスの最大プロセス数 3 bgwriter_lru_multiplier 2.0 default_text_search_config 全文検索で扱うデフォルトの言語名 pg_catalog.english log_autovacuum_min_duration 指定した時間以上かかった、autovacuum プロセスの VACUUM 実行時間のロギング -1 log_checkpoints チェックポイントの実行のロギング off log_lock_waits ロック待ち発生のロギング off log_temp_files 一時ファイル使用のロギング off synchronous_commit 同期コミット設定 on synchronize_seqscans 同期シーケンシャルスキャンの設定 on - デフォルト値の変更
名称 PostgreSQL 8.2 PostgreSQL 8.3 autovacuum off on - stats_start_collector を削除しました。
UDP ソケットの作成に成功すれば、統計情報収集器を必ず起動させます。
- stats_reset_on_server_start パラメータを削除しました。
pg_stat_reset() 関数がすでに用意されているので削除しました。
- postgresql.conf でコメントアウトされたパラメータをデフォルト値に戻すようにしました。
今まではコメントアウトされたパラメータはサーバを再起動するまでは、設定された値が残っていました。
文字エンコーディング
- 不正なエンコードデータをより厳密にチェックするようにしました。
バックスラッシュエスケープ文字処理や COPY のエスケープ処理中にもチェックするようにしました。 さらに、エスケープされた文字列を元に戻したときにも、文字列に対して不正なマルチバイト文字であるかどうかを再チェックするようにしました。
- PostgreSQL 8.2
postgres=# CREATE TABLE mb(a text); CREATE TABLE postgres=# SET client_encoding TO sjis; SET postgres=# INSERT INTO mb VALUES ('\210'); -- エスケープされた不正な文字 WARNING: nonstandard use of escape in a string literal LINE 1: insert into mb values ('\210'); ^ HINT: Use the escape string syntax for escapes, e.g., E'\r\n'. INSERT 0 1 <-- INSERT が可能- PostgreSQL 8.3
postgres=# CREATE TABLE mb (a text); CREATE TABLE postgres=# SET client_encoding TO sjis; SET postgres=# insert into mb values ('\210'); WARNING: nonstandard use of escape in a string literal LINE 1: insert into mb values ('\210'); ^ HINT: Use the escape string syntax for escapes, e.g., E'\r\n'. ERROR: invalid byte sequence for encoding "EUC_JP": 0x88 <-- エラー HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
- サーバのロケール設定と一致しないデータベースエンコーディングを許可しないようにしました。
ほとんどの環境では、C ロケールが任意のデータベースエンコーディングを動かすための唯一のロケールです。 他のロケール設定は特定のエンコーディングを暗示し、もしデータベースエンコーディングが別のものだった場合におかしな動作をします (典型的なものとして文字列のソートや upper()、lower() の結果が正しくない動作をします)。 そこで、サーバは互換性のないエンコーディングを指定してデータベースを作成しようとすると、これを受け入れないようにしました。
- chr() 関数が不正なエンコード値を作成できないようにしました。
UTF8 を指定したデータベースでは、chr() の引数は UNICODE コードポイントとして扱うようにしました。 他のマルチバイトエンコーディングの chr() の引数では 7-bit ASCII 文字を指定しなければいけません。 0 を渡すことはできません。 ascii() はマッチしているかを調整することができます。
- エンコーディングの妥当性を保証するために convert() の挙動を調整しました。
2 引数を受け取る covert() を削除しました。 この関数では 3 つ引数を受け取ります。 1 引数目に bytea を受け取り、bytea を返します。 機能補完のために、3 つの関数を追加しました。
- convert_from(bytea, name) returns text: 1 引数目を指定したエンコーディングからデータベースエンコーディングに変換します。
- convert_to(text, name) returns bytea: 1 引数目をデータベースエンコーディングから指定したエンコーディングに変換します。
- length(bytea, name) returns integer: 1 引数目の文字列を指定したエンコーディングに従って文字数を返します。
- convert(argument USING conversion_name) を削除しました。
この挙動は SQL 標準ではありませんでした。
- JOHAB エンコーディングをクライアントのみサポートするようにしました。
JOHAB はサーバサイドエンコーディングとしては安全ではありません。
変更点
以下に、PostgreSQL 8.3 と以前のメジャーリリースとの間の違いについて詳しく記します。
パフォーマンス
- Heap-Only Tuples (HOT) による UPDATE 時のスペース再利用の最適化
UPDATE と DELETE は内部的にはデッドタプルを残しています。 今までは VACUUM 時にのみデッドタプル領域を再利用できるようにしていました。 HOT ではデッドタプルを UPDATE もしくは INSERT 時に再利用できます。 このことにより安定したパフォーマンスが期待できます。 また、HOT では、インデックスカラムを更新しない UPDATE 時には、インデックスエントリを重複して作成しません。 これにより書き込み量を減らすこともできます。
FILLFACTOR = 70 で作成したテーブルを pgbench で更新した場合のデータサイズの比較
# データ作成 (accounts テーブルを FILLFACTOR 70 で作成し、100,000 行データを投入) $ pgbench -i -F 70 postgres # データ更新(10 クライアントがそれぞれ 10,000 回 accounts テーブルを更新) $ pgbench -c 10 -t 10000 postgres
- 8.3 の実行結果
-- データ投入直後のデータサイズ accounts テーブル postgres=# SELECT pg_size_pretty(pg_relation_size('accounts')); pg_size_pretty ---------------- 18 MB (1 row) accounts_pkey インデックス postgres=# SELECT pg_size_pretty(pg_relation_size('accounts_pkey')); pg_size_pretty ---------------- 1768 kB (1 row) -- データ更新後のデータサイズ postgres=# SELECT pg_size_pretty(pg_relation_size('accounts')); pg_size_pretty ---------------- 18 MB <-- accounts テーブルのサイズに変化なし (1 row) postgres=# SELECT pg_size_pretty(pg_relation_size('accounts_pkey')); pg_size_pretty ---------------- 1768 kB <-- accounts_pkey インデックスのサイズに変化なし (1 row) postgres=# SELECT * FROM pgstattuple('accounts'); -[ RECORD 1 ]------+--------- table_len | 18620416 tuple_count | 100000 tuple_len | 12100000 tuple_percent | 64.98 dead_tuple_count | 2300 dead_tuple_len | 278300 dead_tuple_percent | 1.49 <-- 不要領域は全体の 1% free_space | 5212596 free_percent | 27.99- 8.2 の実行結果
-- データ投入直後のデータサイズ postgres=# SELECT pg_size_pretty(pg_relation_size('accounts')); pg_size_pretty ---------------- 18 MB (1 row) postgres=# SELECT pg_size_pretty(pg_relation_size('accounts_pkey')); pg_size_pretty ---------------- 1768 kB (1 row) -- データ更新後のデータサイズ postgres=# SELECT pg_size_pretty(pg_relation_size('accounts')); pg_size_pretty ---------------- 26 MB <-- accounts テーブルのサイズが 8MB 増加 (1 row) postgres=# SELECT pg_size_pretty(pg_relation_size('accounts_pkey')); pg_size_pretty ---------------- 3512 kB <-- accounts_pkey インデックスのサイズが 1.8 MB増加 (1 row) postgres=# SELECT * FROM pgstattuple('accounts'); -[ RECORD 1 ]------+--------- table_len | 27779072 tuple_count | 100000 tuple_len | 12800000 tuple_percent | 46.08 dead_tuple_count | 100000 dead_tuple_len | 12800000 dead_tuple_percent | 46.08 <-- 不要領域が全体の 50% free_space | 1297688 free_percent | 4.67
- 非同期コミットによるコミット時の WAL 書き込みの遅延
この機能は短期間のデータ修正トランザクションを劇的に高速化する機能です。 欠点はディスク書き込みを遅延させるので、データを書き込む前に OS がクラッシュしてしまうとコミットされたデータを失ってしまうことです。 このようなデータロスを許容できるアプリケーションであればこの機能は有用です。 fsync を off する点との違いは非同期コミットはデータベースの整合性が失われる危険性がない点です。 最悪の状況はデータベースもしくはシステムがクラッシュした後に最後のコミットされたトランザクションが失われることです。 synchronous_commit を off にすることで非同期コミットを利用できます (セッション単位もしくはトランザクション単位で同期・非同期コミットを切り替えることが可能です)。 wal_writer_delay はトランザクションがディスクへ書き出す前の最大遅延時間設定できます。
- 非同期コミットに設定
postgres=# SET synchronous_commit TO off; SET postgres=# INSERT INTO ...
- チェックポイント時の I/O を負荷を抑えるための分散チェックポイントをサポート
今まではチェックポイント時にバッファ上の変更をすべてディスクに反映させていました。 これは I/O 負荷が発生しサーバのパフォーマンス低下を引き起していました。 そこでチェックポイント時のディスク書き込み間隔を空けることにより、I/O 使用ピークを減らすようにしました。 ただし、ユーザが明示的に実行したチェックポイントとシャットダウン時のチェックポイントでは即座にデータをディスクに反映させます。
- バックグラウンドライタのディスク書き込み戦略を改良
これによりバックグラウンドライタのチューニングの必要性が減りました。
- 各列と各行のストレージオーバヘッドを減らすようにしました。
128 バイト未満の可変長データ型は 3 バイト減って、6 バイトになります。 例えば、2 つの char(1) 列がある場合に 16 バイト使っていたのが、4 バイトになります。 また、行ヘッダが以前よりも 4 バイト少なくなります。
- 参照のみのトランザクションに対して非永続トランザクション ID を使うようにした。
これによりオーバヘッドと XID 周回対策の VACUUM を減らすことができます。 非永続トランザクション ID はグローバルなトランザクションカウンタを増やしません。 したがって pg_clog のロードを減らし、トランザクション ID 周回を防止するための VACUUM の間隔を広げることができます。 また、並列性が向上しパフォーマンス改良にも効果があります。
- 参照系のコマンド後にコマンドカウンタの増加を省略するようにしました。
今まではトランザクション毎に 40 億コマンドまでのハードリミットがありました。 これからはデータベースに変更をかけるコマンドのみカウントするようにしました。 当然この制限はまだ残っていますが緩和されます。
- WAL を定期的に書き込む WAL writer プロセスを作成しました。
- CLUSTER と COPY を実行した時に不要な WAL 書き込みを省略するようにしました。
WAL アーカイブを設定していないのであれば、CLUSTER の WAL 書き込みを省略し、コマンドの最後にテーブルを fsync() します。 また、同じトランザクション内で作成されたテーブルに対して COPY をした場合も同様です。
- 巨大なシーケンシャルスキャンがよく使われるキャッシュページを強制的に追い出さないようにしました。
- 巨大なシーケンシャルスキャンが並列に実行される状況において、ディスク読み込みをお互いで共有するようにした。
これはテーブルの途中から新しくシーケンシャルスキャン (すでに他のクライアントでシーケンシャルスキャンを開始している状態) をスタートし、折り返して読み込み開始ポイントまでスキャンします。 つまり ORDER BY を指定していないクエリの返却される行の順番に影響を与えます。 この機能を無効にしたい場合は、synchronize_seqscans を無効にしてください。
-- クライアント 1: 100 万件データを投入し、シーケンシャルスキャン postgres=# INSERT INTO t SELECT generate_series(1, 1000000); INSERT 0 1000000 postgres=# SELECT * FROM t; -- クライアント 2: クライアント 1 がシーケンシャルスキャンを実行中に、LIMIT 1 を実行 postgres=# SELECT * FROM t LIMIT 1; a -------- 840481 (1 row) -- シーケンシャルスキャン終了後に LIMIT 1 を実行 postgres=# SELECT * FROM t LIMIT 1; a --- 1 (1 row)
- ORDER BY ... LIMIT をソートせずに実行できるようにしました。
これはテーブル全体をソートするのではなく、シーケンシャルにテーブルをアクセスし、その都度上位 N 番目までの行を記録していきます。 インデックスがない場合や LIMIT が大きくない場合にはとても有用です。
-- データの作成 postgres=# CREATE TABLE t (a INT); CREATE TABLE postgres=# INSERT INTO t SELECT generate_series(1, 1000000); INSERT 0 1000000
- 8.3 の EXPLAIN ANALYZE
postgres=# EXPLAIN ANALYZE SELECT * FROM t ORDER BY a LIMIT 100; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ Limit (cost=52139.64..52139.89 rows=100 width=4) (actual time=1205.001..1205.127 rows=100 loops=1) -> Sort (cost=52139.64..54639.56 rows=999966 width=4) (actual time=1204.998..1205.043 rows=100 loops=1) Sort Key: a Sort Method: top-N heapsort Memory: 19kB -> Seq Scan on t (cost=0.00..13921.66 rows=999966 width=4) (actual time=0.081..551.966 rows=1000000 loops=1) Total runtime: 1205.221 ms (6 rows)- 8.2 の EXPLAIN ANALYZE
postgres=# EXPLAIN ANALYZE SELECT * FROM t ORDER BY a LIMIT 100; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------ Limit (cost=133188.62..133188.87 rows=100 width=4) (actual time=3392.716..3392.915 rows=100 loops=1) -> Sort (cost=133188.62..135545.83 rows=942884 width=4) (actual time=3392.713..3392.825 rows=100 loops=1) Sort Key: a -> Seq Scan on t (cost=0.00..13834.84 rows=942884 width=4) (actual time=0.035..593.141 rows=1000000 loops=1) Total runtime: 4037.453 ms (5 rows)
- バックエンドによって統計情報収集器に送るメッセージ量を制限できるようにしました。
これは短かいトランザクションに対するオーバーヘッドを減らします。 その代わりまれに統計情報の更新が遅くなる可能性もあります。
- NULL を多く含むような状況で hash join の実行を改良しました。
- データ型を展開せずにマッチしていると判断できる状況下で、オペレータ検索を高速化しました。
サーバ
- autovacuum をデフォルトで有効にしました。
autovacuum 関連のパラメータのデフォルト値も変更しています。
パラメータ 8.2 8.3 autovacuum_vacuum_threshold 500 50 autovacuum_analyze_threshold 250 50 autovacuum_vacuum_cost_delay -1 20 - autovacuum プロセスが複数同時に動作するようにしました。
複数の vacuum を並行して動作します。 これは大きなテーブルの VACUUM が小さなテーブルの VACUUM を遅らせることを防いでいます。
autovacuum_max_worker パラメータで最大同時プロセス数を指定します。
- テーブル定義が変更されたり、統計情報が更新された場合に、キャッシュされたクエリを自動的に再計画するようにしました。
今までは、関数呼び出しの間に一時テーブルを削除して再作成されると、一時テーブルを参照する PL/PgSQL 関数が失敗しました。 この改良により上記問題やそれに関連する問題が解消されます。
- 一時テーブルや一時ファイル用のテーブルスペースを制御するための temp_tablespace パラメータを追加しました。
このパラメータはテーブルスペースのリストを定義します。 これにより複数のテーブルスペースに I/O を分散させることができます。 使用する (ランダムな) テーブルスペースは一時オブジェクトを作成した時に決定します。 一時ファイルはデータベース毎に pgsql_temp ディレクトリに作成するのではなく、テーブルスペースディレクトリに配置されます。
- 一時テーブルの TOAST テーブルを特殊なスキーマ 'pg_toast_temp_nnn' に配置するようにしました。
これは上記のテーブルが一時的であることを認識するための低レベルのコードを書くことができます。 例えば WAL 書き込みをしないように変更したり、共有バッファではなくローカルバッファを使うようにするなどの最適化が行えます。 また、一時 TOAST を参照しているオープンファイルを意図せずに保持してしまうバグを修正しました。
- 新しい接続リクエストの処理がシャットダウン処理の完了やクラッシュ時の再起動を遅らせてしまう問題を修正しました。
- 削除されたテーブルの relfilenode の再利用を防ぐことにより、次のチェックポイントまでの間に非常に低い確率のデータロスを防止するようにしました。
- 古い形式の外部キートリガー定義を、正規の外部キー制約に変換するように CREATE CONSTRAINT TRIGGER を修正しました。
これによって contrib/adddepend を使わずに 7.3 以降のデータベースから外部キー制約を容易に移植できるようになります。
- 継承されたデフォルト値をオーバライドするために DEFAULT NULL を修正しました。
DEFAULT NULL は単なるノイズと見なしていましたが、NULL でないデフォルト値、言い換えると親テーブルやドメインを継承したをデフォルト値を上書きすべきです。
- 新規に EUC_JIS_2004 と SHIFT_JIS_2004 エンコーディングを追加しました。
これらのエンコーディングは UTF-8 と相互変換が可能です。
- サーバ起動時のログメッセージを "database system is ready" から "database system is ready to accept connections" に変更し、また出力するタイミングを変更しました。
このメッセージは実際に postmaster が接続受け付けが可能になった時点で出力されます。
LOG: database system is ready to accept connections
データベース監視
- autovacuum の活動状況を設定でロギングできるようにするために、log_autovacuum_min_duration パラメータを追加しました。
- ロック待ちをログ出力するための log_lock_waits パラメータを追加しました。
以下のように出力されます。
LOG: process 10270 acquired AccessExclusiveLock on relation 16384 of database 11511 after 1271.301 ms
- 一時ファイルの使用状況をログ出力するための log_temp_files を追加しました。
- チェックポイントのログを改良するために、log_checkpoints パラメータを追加しました。
LOG: checkpoint starting: immediate force wait LOG: checkpoint complete: wrote 0 buffers (0.0%); 0 transaction log file(s) added, 1 removed, 0 recycled; write=0.000 s, sync=0.000 s, total=0.045 s - log_line_prefix ですべてのプロセスで %s と %c をサポートするようにしました。
今まではユーザセッションのみ動作しており、バックグラウンドのデータベースプロセスでは動作しませんでした。
- ポイントインタイムリカバリの再起動ポイントのロギングを制御するための log_restartpoints を追加しました。
- 最終トランザクションの終了時間をリカバリ終了時と各再起動ポイントでログ出力するようにしました
$ pg_ctl -mi stop $ pg_ctl start ... LOG: last completed transaction was at log time 2007-12-19 17:50:58.560671+09 ...
- pg_stat_activity で autovacuum が開始された時間を報告するようにしました。
- サーバログを CSV 形式で出力できるようにしました。
各種解析するために CSV 形式のログファイルをデータベーステーブルにロードさせることができます。
- サーバログに出力されるタイムスタンプ形式を PostgreSQL が提供しているタイムゾーンサポートを使うようにしました。
これは Windows 固有の問題を回避するためです。 ログメッセージ内で使うタイムゾーンを制御するための新しい log_timezone パラメータを追加しました。 これはクライアント側から見えるタイムゾーンのパラメータとは独立しています。
- バックグラウンドライタの活動状況についての統計情報を表示するための pg_stat_bgwriter ビューを新しく追加しました。
- pg_stat_database にデータベース全体のタプル統計情報に関する新しい列を追加しました。
- pg_stat_activity に xact_start 列 (トランザクション開始時間) を追加しました。
長時間動いているトランザクションを容易に識別することができるようになります。
- pg_stat_all_tables やそれに関連したビューに対して n_live_tuples と n_dead_tuples 列を追加しました。
- stats_block_level と stats_row_level パラメータを統合し、track_counts パラメータとしました。
- stats_command_string パラメータを track_activities に名称を変更しました。
- コミットもしくはアボートされたトランザクションによって影響が異なることを認識するように、生きているタプルと削除したタプルのカウントを修正しました。
ユーザ認証
- Windows 上での認証で Security Service Provider Interface (SSPI) をサポートしました。
- GSSAPI 認証をサポートしました。
GSSAPI は業界標準なのでネイティブの Kerberos をよりも好ましいです。
- グローバル SSL 設定ファイルをサポートしました。
- 受け付けられる SSL cipher を制御するための ssl_ciphers パラメータを追加しました。
- Kerberos realm パラメータを krb_realm に設定できるようにしました。
Write-Ahead Log (WAL)、継続アーカイブ
- トランザクション WAL レコードに記録されるタイムスタンプを time_t から TimestampTz 形式に変更しました。
WAL 内により細かい時間を入れることにより、ポイントインタイムリカバリで細かく指定することができるようになります。
- ウォームスタンバイサーバに必要な WAL ディスク領域を減らせるようにしました。
ウォームスタンバイサーバが必要な WAL ファイルの名前をリカバリスクリプトに渡すことができ、不要な WAL ファイルの自動削除ができます。 recovery.conf の restore_command に %r を使うことでできます。
- アーカイブを制御するための archive_mode パラメータを追加しました。
今までは archive_command を空文字列にすることによって、アーカイブを off にしていました。 これからは archive_command ではなく、archive_mode の on/off で切り替えます。 一時的にアーカイブを止めたい場合に有用です。
問い合わせ
- 全文検索をデータベースシステム本体に統合しました。
全文検索を改良、本体に移動し、インストールするとデフォルトで使えるようになっています。 contrib/tsearch2 は互換インターフェースを用意しています。
- NULL の含まれるデータをソートする際に、NULL を最初にもってくるか、最後にもってくるかを制御できるようにしました。
構文は ORDER BY ... NULLS FIRST/LAST です。
- インデックスに対して列を昇順か降順 (ASC/DESC) で格納するかを指定できるようになりました。
今までは ASC/DESC が混在した ORDER BY を使ったクエリはインデックスを完全に使っていませんでした。 8.3 ではこのようなケースでは、インデックス作成時に指定した ASC/DESC とマッチしていれば、インデックスを適用します。
- col IS NULL 条件でもインデックスを使えるようにしました。
- 8.3
postgres=# EXPLAIN SELECT * FROM accounts WHERE aid IS NULL; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------- Index Scan using accounts_pkey on accounts (cost=0.00..8.28 rows=1 width=97) (actual time=0.108..0.108 rows=0 loops=1) Index Cond: (aid IS NULL) Total runtime: 0.186 ms (3 rows)- 8.2
postgres=# EXPLAIN ANALYZE SELECT * FROM accounts WHERE aid IS NULL; QUERY PLAN ----------------------------------------------------------------------------------------------------------- Seq Scan on accounts (cost=0.00..2640.00 rows=1 width=100) (actual time=386.173..386.173 rows=0 loops=1) Filter: (aid IS NULL) Total runtime: 386.221 ms (3 rows)
- 更新可能カーソルをサポートしました。
これによりカーソルが返した行の UPDATE や DELETE のために主キーを参照する必要がなくなります。 構文は UPDATE/DELETE WHERE CURRENT OF です。
- カーソルで FOR UPDATE を指定できるようになりました。
- 各データ型に対して標準の文字列型 (text、varchar、char) へのキャスト、もしくは、文字列型からのキャストをサポートする仕組みを作成しました。
以前は、このようなキャストは特別な関数を持つ型のみで行うことができました。 この新しいキャストでは、文字列への変換は代入のみ、文字列からの変換は明示的に指定されたときのみ行われるため、驚くような挙動にはならないはずです。
- すべての入力データ型がドメイン型であるときには、UNION や関連したコンストラクタがドメイン型を返せるようにしました。
以前の出力はドメインの基底型とみなしていました。
- 2 つの異なるデータ型を使っている場合に制限されたハッシュを使えるようにしました。
データ型をまたぐ比較 (データ型同士が互換性のあるハッシュ関数を持つ場合) を含む状況でハッシュジョイン、ハッシュインデックス、ハッシュサブプラン、ハッシュ集約が使われるようになります。 現在のデータ型をまたぐハッシュサポートは smallint/integer/bigint と float4/float8 があります。
- WHERE 句で変数が等しいことを検知するオプティマイザのロジックを改良しました。
降順でソートするマージジョインができるようになり、余計なソートをしなくなります。
- ほとんどのテーブルが制約によって排除されるような状況下で、巨大な継承木を計画するパフォーマンスを改良しました。
オブジェクト操作
- 複合型の配列をサポートしました。
追加で明示的に宣言した複合型の配列も、通常のテーブルやビューの行の型の配列をサポートします。 ただし、システムカタログ、シーケンス、TOAST テーブルの行型は除きます。
- サーバ設定パラメータを関数単位で設定できるようになりました。
例えば、関数が想定しない search_path によって予期せぬ挙動にならないために、自身の search_path を設定することができます。 SECURITY DEFINER を指定した関数はセキュリティホールを回避するためにも自身の search_path を設定してください。
- CREATE/ALTER FUNCTION で COST と ROWS オプションをサポートしました。
COST は関数呼び出しのコストを指定します。 ROWS は行を返す関数によって返される行数の平均値を指定します。
- トリガーとルールを設定パラメータを使ってグループ単位で無効にできるようにしました。
これはレプリケーション用の機能です。
レプリケーションシステムがシステムカタログを直接変更せずにグループ単位でトリガーや書き換えルールを無効にできるようになりました。 この挙動は ALTER TABLE と session_replication_role という新しいパラメータで制御されます。
- ユーザ定義型が型識別子を持つようになりました。
ssnum(7) のようにユーザ定義型が識別子をもつようになります。 以前はビルトインデータ型のみ識別子を持つことができました。
ユーティリティコマンド
- スーパーユーザでないデータベース所有者が、信頼された手続き言語を、所有するデータベースに追加できるようになりました。
これは十分安全ですが、管理者によっては権限を剥奪したいかもしれません。 その場合には pg_pltemplate.tmpdbacreate を変更してください。
- あるセッションの現在のパラメータ設定を将来のセッションのデフォルト値として使えるようになりました。
CREATE/ALTER FUNCTION、ALTER DATABASE、ALTER ROLE に SET ... FROM CURRENT 句を指定することでできます。
-- client_encoding の初期設定は EUC-JP postgres=# SHOW client_encoding; client_encoding ----------------- EUC_JP (1 row) postgres=# SET client_encoding TO sjis; SET postgres=# ALTER ROLE "postgres" SET client_encoding FROM CURRENT; ALTER ROLE postgres=# \q -- 再接続 postgres=# SHOW client_encoding; client_encoding ----------------- sjis (1 row)
- 新しく DISCARD ALL、DISCARD PLANS、DISCARD TEMPORARY、CLOSE ALL、DEALLOCATE ALL コマンドを実装しました。
これらのコマンドはデータベースセッションを初期状態にリセットします。 コネクションプーリングソフトウェアに特に有用です。
postgres=# CREATE TEMP TABLE tmp_tbl (a int); CREATE TABLE postgres=# SELECT * FROM tmp_tbl; a --- (0 rows) postgres=# DISCARD ALL; DISCARD ALL postgres=# SELECT * FROM tmp_tbl; ERROR: relation "tmp_tbl" does not exist
- ALTER VIEW ... RENAME TO と ALTER SEQUENCE ... RENAME TO を追加しました。
以前は ALTER TABLE ... RENAME TO のみ可能でした。
- CREATE TABLE LIKE ... INCLUDING INDEXES を実装しました。
- 他のデータベースのトランザクションを無視して CREATE INDEX CONCURRENTLY を実行できるようにしました。
- CLUSTER コマンドを MVCC-safe にしました。
今までは CLUSTER はコミットされたすべてのデッドタプルをすべて破棄していました。 これは MVCC の可視ルールでは本来見えていないといけないトランザクションがいる・いないを関わらずでした。
- CLUSTER の新規構文を追加しました。
CLUSTER table USING index
古い CLUSTER 構文は引き続きサポートしますが、新しい形式のほうがよりロジカルです。
- 複雑なプランをより正確に表示できるように EXPLAIN を修正しました。
サブプランの参照が正しく表示されるようになります。
- CREATE/DROP/RENAME DATABASE が他のバックエンドによって失敗するような状況である場合は、バックエンドが終了するまで少し待つようにしました。
これらのコマンドが終了する見込み時間を増やしてください。
- ユーザを削除したときに報告される情報量を制限しました。
以前は多くのオブジェクトの所有者であるユーザを削除した (もしくは削除しようとした) 時に、大量の NOTICE もしくは ERROR メッセージが出力されていました。 いくつかのクライアントアプリケーションで問題となったので、サーバログにはすべてのログを残し、クライアントに対してはメッセージ量を制限しました。
データ型
- SQL/XML 標準をサポートしました。
新しいオペレータや XML データ型を含んでいます。
XML をサポートした PostgreSQL を使いたい場合には、configure 時に --with-libxml を指定します。
- データを XML 形式で出力する例
postgres=# CREATE TABLE meibo (id integer, name text); CREATE TABLE postgres=# INSERT INTO meibo VALUES (0, 'Bob'); INSERT 0 1 postgres=# INSERT INTO meibo VALUES (1, 'Mary'); INSERT 0 1 postgres=# SELECT xmlforest(id, name) FROM meibo; xmlforest ----------------------------- <id>0</id><name>Bob</name> <id>1</id><name>Mary</name> (2 rows)- XPath の例
postgres=# CREATE TABLE meibo_xml(info XML); CREATE TABLE postgres=# INSERT INTO meibo_xml VALUES ('<id>0</id><name>Bob</name>'); INSERT 0 1 postgres=# INSERT INTO meibo_xml VALUES ('<id>1</id><name>Mary</name>'); INSERT 0 1 postgres=# SELECT xpath('/name/text()', info) FROM meibo_xml; xpath -------- {Bob} {Mary} (2 rows)
- 列挙型 (ENUM) をサポートしました。
この機能は少ない固定データセットを持つ列に対して便利な機能になります。 ENUM 型の例は以下の通りです。
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy'); - Universally Unique Identifier (UUID) データ型をサポートしました。
RFC 4122 に従っています。
- MONEY データ型を 64 ビットに拡張しました。
MONEY 値の幅を大幅に増やしました。
- 無限と NAN (Not A Number) を整合性のある状態で扱えるように float4/float8 を修正しました。
以前はオーバフロー条件と無限の区別に整合性がありませんでした。
- boolean 型の値の入力データの前後に空白文字が入っても正しく解釈できるようにしました。
postgres=# CREATE TABLE b (a bool); CREATE TABLE postgres=# INSERT INTO b VALUES (' t '); INSERT 0 1
関数
- 正規表現の関数 regexp_matches()、regexp_split_to_array()、regexp_split_to_table() を新しく追加しました。
これらの関数は POSIX 正規表現を使って、正規表現の部分式の展開と文字列の分割を行えます。
- ラージオブジェクトの切り詰めをする lo_truncate() を追加しました。
- float8 データ型用の width_bucket() を実装しました。
- トランザクション中に集められた統計情報のスナップショットを破棄する pg_stat_clear_snapshot() 関数を追加しました。
トランザクション内で最初に取得される統計情報は、そのトランザクション内における変更が反映されていない統計情報のスナップショットです。 この関数では、次に統計情報を取得するまでの間に、スナップショットを破棄し、新しいスナップショットを読み込むことができます。 これは、単一のトランザクションとして実行することが制限されている PL/pgSQL 関数において特に有用です。
- extract() と date_part() 関数に isodow オプションを追加しました。
これは曜日を返すオプションです。 dow との違いは、isodow オプションでは日曜日が 7 になります。
- isodow
postgres=# SELECT extract(isodow FROM timestamp '2008-01-06 00:00:00'); date_part ----------- 7- dow
postgres=# SELECT extract(dow FROM timestamp '2008-01-06 00:00:00'); date_part ----------- 0
- to_char()、to_date()、to_timestamp() 関数に ID (ISO day of week) と IDDD (ISO day of year) 形式を追加しました。
- to_timestamp() と to_date() において TM (trim) が潜在的に可変幅フィールドのためのオプションと見なすようにしました。
Oracle の挙動と同じになります。
- to_date()/to_timestamp() の 'D' フィールドの結果が 1 ずれてしまうエラーを修正しました。
- setseed() 関数が void を返すようにしました。
- numeric 型に対するハッシュ関数を追加しました。
numeric 型にハッシュインデックスやハッシュベースのプランが使えるようになります。
- LIKE/ILIKE の効率化を図りました。 UTF-8 などのマルチバイト文字に対して特に有効です。
- currtid() 関数が対象テーブルに SELECT 権限があることを要求するようにしました。
- 活動中のトランザクション ID を問合せるための txid_*() 関数を追加しました。
レプリケーションソリューションに対して有用な関数です。
PL/PgSQL サーバサイド言語
- スクロール可能なカーソルを追加しました。
- PL/PgSQL の FETCH 構文で FROM の代わりに IN も使えるようになりました。 これはバックエンドの FETCH コマンドと同じにするためです。
- PL/PgSQL に MOVE を追加しました。
- RETURN QUERY を実装しました。
あるクエリの結果を返したいような、集合を返す PL/PgSQL 関数に対して便利な構文を追加しています。 RETURN QUERY は RETURN NEXT のループよりも簡単で、効率もよいです。
- 関数名を修飾して関数パラメータ名を参照できるようにしました。
例えば、myfunc.myvar です。 関数パラメータとカラム名が一緒の場合に指定することができます。
- 8.3
postgres=# CREATE OR REPLACE FUNCTION myfunc(myvar integer) RETURNS integer AS $$ BEGIN RETURN myfunc.myvar; END $$ LANGUAGE plpgsql; CREATE FUNCTION postgres=# SELECT myfunc(1); myfunc -------- 1 (1 row)- 8.2
postgres=# CREATE OR REPLACE FUNCTION myfunc(myvar integer) RETURNS integer AS $$ BEGIN RETURN myfunc.myvar; END $$ LANGUAGE plpgsql; CREATE FUNCTION postgres=# SELECT myfunc(1); ERROR: missing FROM-clause entry for table "myfunc" LINE 1: SELECT myfunc.myvar ^ QUERY: SELECT myfunc.myvar CONTEXT: PL/pgSQL function "myfunc" line 1 at return
- ブロックラベル付きの変数修飾が正しく動作するようになりました。
以前は外のブロックラベルが内側のレコード参照ので想定しない衝突が発生する可能性がありました。
- FOR loop STEP values を厳しくしました。
- 負の STEP 値を防止するようにしました。
- 構文エラー箇所の報告を正確にしました。
サーバサイド言語
- PL/Perl の spi_prepare() に型名引数を渡せるようにしました。
- PL/Python の plpy.prepare() に型名引数を渡せるようにしました。
- PL/Tcl の spi_prepare に型名引数を渡せるようにしました。
- PL/PythonU を Python 2.5 でコンパイルできるようにしました。
- Python 2.3 以降のバージョンと PL/Python の boolean 型の互換性をサポートしました。
- thread-enabled libtcl がバックエンド内に複数のスレッドを生成する PL/Tcl の問題を修正しました。
psql
- \d の出力で無効なトリガーリストを分けるようにしました。
- \d パターンで、'$' リテラルをマッチさせるようにしました。
- \da の出力に集約関数の戻り型を表示するようにしました。
- \df+ の結果に関数の揮発性に関する情報を追加しました。
- \prompt 機能を追加しました。
- \pset、\t、\x を明示的に on/off できるようにしました。
- \sleep 機能を追加しました。
- \copy に対しても \timing の結果を出力できるようにしました。
- Windows 上での \timing の精度を向上させました。
- 各バックスラッシュコマンド後に \o の出力をフラッシュさせるようにしました。
- -f で指定した入力ファイルを読み込み中に正しくエラーを検知し、報告するようにしました。
pg_dump
- pg_dumpall に --tablespace-only と --roles-only オプションを追加しました。
- pg_dumpall に出力ファイルオプションを追加しました。
これは Windows 環境で特に有用です。 pg_dump 子プロセスのリダイレクトが正しく動作しないためです。
- pg_dumpall での初期接続データベース名を指定できるようになりました。
- -n と -t オプションで、'$' リテラルをマッチするようにしました。
- 数千のオブジェクトを持つデータベースのダンプを高速化しました。
他のクライアントアプリケーション
- initdb 時に pg_xlog ディレクトリの場所を指定できるようにしました。
- pg_regress でサポートしている OS であれば、サーバが core ファイルを出力するようにしました。
- pg_ctl に -t (タイムアウト) パラメータを追加しました。
サーバの起動や停止に pg_ctl がどれくらい待つかを制御できるようにしました。 今までは 60 秒固定のタイムアウトでした。
- pg_ctl のオプションで core ファイルを生成するかを制御できるようにしました。
- clusterdb、reindexdb、vacuumdb コマンドを Control-C でキャンセルできるようにしました。
- createdb、createuser、dropdb、dropuser コマンドでコマンドタグの出力をしないようにしました。
--quiet オプションは無視されます。 また、このオプションは 8.4 で削除されます。 データベース上で操作している進行メッセージは stderr ではなく stdout に出力するようにしました。
libpq
- PQsetdbLogin() の dbName パラメータに '=' 文字が含まれている場合は接続情報文字列 (PQconnectdb() に渡す文字列) として解釈するようにしました。
PQsetdbLogin() を使っているクライアントプログラムで接続情報文字列を使うことが可能になります。
- グローバル SSL 設定ファイルをサポートしました。
- SSL ハードウェアキーを制御するための環境変数 PGSSLKEY を追加しました。
- ラージオブジェクト切り詰めのための lo_truncate() 関数を追加しました。
- サーバがパスワードを要求する場合には true を返す PQconnectionUsedPassword() 関数を追加しました。
接続に失敗した後に true を返したら、クライアントアプリケーションはパスワード入力プロンプトを出す必要があります。 過去のアプリケーションではパスワードが必要かどうかを特定のエラーメッセージによって確認する必要がありました。 この方式は推奨しません。
ecpg
- V3 frontend/backend プロトコルを使うようにしました。
サーバサイドの prepared statement が使えるようになりました。
- Windows 上で pthreads ではなくネイティブのスレッドを使うようにしました。
- ecpglib をスレッドセーフにしました。
- ecpg ライブラリを必要最低限の API シンボルだけ公開するようにしました。
Windows 移植
- Microsoft Visual C++ でコンパイルした PostgreSQL バイナリを提供するようにしました。
Windows 開発者には慣れた開発環境とデバッグ環境を使うことができるようになります。 また、Visual C++ で作成した Windows 実行ファイルは安定性とパフォーマンスが向上するでしょう。 今まで提供していたクライアントのみの Visual C++ ビルドスクリプトは削除しました。
- 多くの子プロセスが存在する状況での postmaster のメモリ使用量を大幅に減らしました。
- 管理者ユーザでレグレッションテストを実行できるようになりました。
- ネイティブの共有メモリ実装を追加しました。
Server Programming Interface (SPI)
- SPI にカーソルに関する機能を追加しました。
カーソル関連のプランへのアクセスと FETCH/MOVE 処理を追加しました。
- SPI_execute を通したカーソルコマンドを実行できるようにしました。
SPI_ERROR_CURSOR はいずれ廃止する予定です。
- SPI プランのポインタを void* ではなく SPIPlanPtr で宣言しました。
既存のアプリケーションコードには影響ありませんが、単純なプログラムミスを無くすためにも変更することをお勧めします。
PostgreSQL ビルドオプション
- プロファイリング (gcc の場合のみ) を有効にする、--enable-profiling オプションを configure に追加しました。
- OS のタイムゾーンデータベースを使うことを指定する、--with-system-tzdata オプションを configure に追加しました。
- インストールした pg_config が PATH に最初に表われない場合でも、拡張モジュールを正しくビルドできるようにしました。
- SGML ドキュメントをビルドする時に gmake draft で実行できるようにしました。
ソースコード
- DLLIMPORT マクロを PGDLLIMPORT に変更しました。 サードパーティのヘッダ (Tcl など) で定義された DLLIMPORT との衝突を避けるためです。
- データ型をまたぐ比較を含むクエリプランを改良するために、オペレータファミリーを作成しました。
- クエリを満たすものがないことを通知できるように、GIN の extractQuery() API を更新しました。
- NAMEDATALEN を postgres_ext.h から pg_config_manual.h に定義を移動しました。
- すべてのプラットフォームで strlcpy() と strlcat() を使えるようにし、strncpy() や strncat() などを置き換えるようにしました。
- プランナを監視し、仮定のプランを作成できる外部プラグイン機構を作成しました。
- 結合順の検索を部分的に置き換える関数をプラグインとして設定する変数 join_search_hook を作成しました。
- Renesas M32R プロセッサ用の tas() を追加しました。
- quote_identifier() と pg_dump で文法上には予約語ではないキーワードをクオートしないようにしました。
- NUMERIC 型のディスク上の表現を変更しました。
- Darwin 6.0 以上 (OS X 10.2 以上) の環境で POSIX semaphore ではなく SYSV semaphore を使うようにしました。
- 頭字語と NFS に関するドキュメントを追加しました。
- Postgres という名前が PostgreSQL の別名として正式にドキュメント化されました。
Contrib モジュール
- contrib モジュールの README の内容を PostgreSQL のマニュアルに移動しました。
- 低レベルのページ内容を確認するための contrib/pageinspect モジュールを追加しました。
- ウォームスタンバイを制御するための contrib/pg_standby モジュールを追加しました。
- OSSP UUID ライブラリを使って UUID を生成する contrib/uuid-ossp モジュールを追加しました。
configure に --with-ossp-uuid を指定することでビルトインで UUID 型を使用できるようになります。
- 全文検索のサンプル辞書テンプレートやパーサを提供する contrib/dict_int、contrib/dict_xsyn、contrib/test_parser モジュールを追加しました。
- pgbench で fillfactor を設定できるようにしました。
- pgbench -l オプションでタイムスタンプを追加するようにしました。
- contrib/pgbuffercache にバッファ使用回数の統計情報を追加しました。
- contrib/hstore の GIN サポートを追加しました。
- contrib/pg_trgm の GIN サポートを追加しました。
- contrib/start-scripts に OS/X 用の起動スクリプトを更新しました。
- pgrowlocks() と dblink_get_pkey() で対象のテーブルに SELECT 権限があるユーザのみ実行できるように制限しました。
- contrib/pgstattuple をスーパーユーザのみ実行できるように制限しました。
- contrib/xml2 は deprecate となり、8.4 で削除する計画です。
このモジュールの代わりに XML サポートは PostgreSQL 本体に入りました。

