PostgreSQL 9.6 に関する技術情報

このページでは PostgreSQL 9.6 (2016年9月29日リリース)に関する技術情報をお届けします。

本ドキュメントは PostgreSQL のリリースノートを元に弊社で解説を加えたものです。


バージョン9.6の主な拡張点

バージョン9.6での主な拡張箇所は以下の通りです。

  • シーケンシャルスキャン、結合、集約のパラレル実行に対応しました。
  • 自動VACUUMは古いデータを繰り返しスキャンしなくなります。
  • 同期レプリケーションで複数スタンバイサーバが可能になりました。
  • 全文検索でフレーズ(隣接した複数語)の検索に対応しました。
  • postgres_fdw がリモートでの結合、ソート、UPDATE、DELETE に対応しました。
  • 特に複数CPUソケットサーバでのスケーラビリティにおいて性能改善しました。

バージョン9.6への移行/互換性のない変更点

  • pg_stat_activityビューのプロセスロック待ちの列が拡張されました。 (Amit Kapila, Ildus Kurbangaliev) (9.6)
  • 重量ロック(SQLレベルでのロック)を待機しているかを示すboolean型の waiting列が無くなり、それに代わってロックの種類を示す wait_event_type列と wait_event列が追加されました。待機していなければ、新たな2つの列は共にNULLになります。

    これからは重量ロック(wait_event_type が'Lock'になります)のみならず、軽量ロック(同じく'LWLockNamed'または'LWLockTranche')やバッファピン('BufferPin')の待機も表示されるようになります。

    pg_stat_activityビューの waiting列を参照していたプログラムは修正が必要です。

  • to_char() 関数で日付時間のテンプレートパターンについて、マイナス記号をフィールド幅の一部として数えなくなりました。 (Bruce Momjian) (9.6)
  • 期待される出力結果が変わることになります。以下例は、従来は「-04」でなく「-4」が返りました。

    db1=# SELECT to_char('-4 years'::interval, 'YY');
     to_char
    ---------
     -04
    (1 row)
    
  • 無限値の入力に対して EXTRACT の振る舞いがより合理的になりました。 (Vitaly Burovoy) (9.6)
  • 単調増加する要素(YEAR、EPOCH)については infinity、-infinity が返り、それ以外の要素(DAY、HOUR、等)については NULL が返るようになりました。これまでは入力のタイムスタンプが 'infinity' または '-infinity' であるなら、フィールド指定が何であるかにかかわらず 0 が返っていました。

    (9.6 での動作例)
    
    db1=# SELECT EXTRACT(MONTH FROM 'infinity'::timestamp);
     date_part
    -----------
        *NULL*
    (1 row)
    
    db1=# SELECT EXTRACT(YEAR FROM '-infinity'::timestamp);
     date_part
    -----------
     -Infinity
    (1 row)
    
  • RAISEコマンドにより出力されたメッセージの内部行CONTEXT を隠す仕様がPL/pgSQL から廃止されました。 (Pavel Stehule) (9.6)
  • 以下のように実行したとき、これまでは「CONTEXT:」の行が出力されませんでした。

    db1=# CREATE OR REPLACE FUNCTION f_raisetest() RETURNS void LANGUAGE plpgsql
          AS $$ BEGIN RAISE EXCEPTION 'test' ; RETURN; END; $$;
    CREATE FUNCTION
    
    db1=# SELECT f_raisetest();
    ERROR:  test
    CONTEXT:  PL/pgSQL function f_raisetest() line 1 at RAISE
    
  • デフォルトの全文検索パーサで、Eメールやホスト名などにあらわれる数字から始まるトークンを許すようになりました。 (Artur Zakirov) (9.6)
  • to_tsvector() や to_tsquery() の動作が変わり、僅かながら検索結果が変わります。メールアドレスを切り出すには新たな動作の方が適しています。

    (9.5以前の動作例)
    db1=# SELECT to_tsvector('simple', 'foo@123_mail.sraoss.co.jp');
                  to_tsvector
    ---------------------------------------
     '123':2 'foo':1 'mail.sraoss.co.jp':3
    (1 row)
    
    (9.6の動作例)
    db1=# SELECT to_tsvector('simple', 'foo@123_mail.sraoss.co.jp');
              to_tsvector
    -------------------------------
     'foo@123_mail.sraoss.co.jp':1
    (1 row)
    
  • contrib/unaccent の標準で用意されている unaccent.rules ファイルが、Unicode の知られている全ての発音区別符号を扱えるように拡張されました。また、合字を正しく展開するようになりました。 (Thomas Munro, Léonard Benedetti) (9.6)
  • 従来のバージョンはいくつかの一般的でない発音区別符号付き文字に対応していませんでした。 また、これからは合字がばらばらの文字に展開されます。

    このルールファイルを使う(アップグレードした)インストール先では、tsvector列とインデックスの再構築が必要です。

  • CREATE ROLE とその同族コマンド群から、永らく非推奨とされてきた CREATEUSER/NOCREATEUSERオプションが廃止されました。 (Tom Lane) (9.6)
  • CREATEUSER は古い後方互換性のためにあり、実際には SUPERUSER を意味しました。これは CREATEROLE と同じ意味かと間違えやすく、常に混乱のもととなってきました。

  • pg_ で始まるロール名は予約済みとして扱われるようになりました。 (Stephen Frost) (9.6)
  • 今後は pg_ で始まるロール名は作成できません。

    (9.6 でエラーになる例)
    $ initdb -U pg_admin /data/pgdata
    initdb: superuser name "pg_admin" is disallowed; role names cannot begin with "pg_"
    
    $ psql -q db1
    db1=# CREATE ROLE pg_nobody;
    ERROR:  role name "pg_nobody" is reserved
    DETAIL:  Role names starting with "pg_" are reserved.
    
  • information_schema.routinesビューの列名result_cast_character_set_name がresult_cast_char_set_name に変更されました。 (Clément Prévost) (9.6)
  • SQL:2011 標準では長い方の名前(..._character_...)を指定していますが、まわりの列名は他のinformation_schemaビューと同様に短い形式(..._char_...)を使っているので、これは誤りのように見えます。

  • psql の -c オプションは --no-psqlrc の意味を含まなくなりました。 (Pavel Stehule, Catalin Iacob) (9.6)
  • 旧来の振る舞いにするには明示的に --no-psqlrc (-X) を指定します。この方法で修正したスクリプトは旧バージョンの psql でも動作します。

  • pg_restore の -t (--table) オプションが全てのタイプのリレーションに対応するように改良されました。 (Craig Ringer) (9.6)
  • 通常のテーブルだけでなく、ビュー、外部テーブル、マテリアライズドビュー、シーケンスを指定できるようになりました。

  • pg_controldata や関連する箇所で NextXID の表示形式が変更されました。 (Joe Conway, Bruce Momjian) (9.6)
  • XIDエポック(XIDの周回毎に1増える)とXID値のペアを : で区切る形式になりました。以前の形式は LSN の表示形式と似ていて紛らわしいものでした。

    (以前の表示形式) 
    $ pg_controldata | grep NextXID
    Latest checkpoint's NextXID:          0/31699
    
    (9.6 の表示形式)
    $ pg_controldata | grep NextXID
    Latest checkpoint's NextXID:          0:31699
    
  • 必要に応じて拡張モジュールの関数が parallel-safe マークが付与されるように改修されました。 (Andreas Karlsson) (9.6)
  • 標準拡張モジュールの多くが並列実行できるように更新されました。この変更は旧バージョンからの pg_upgrade では適用されません。バージョンアップ後に ALTER EXTENSION UPDATE を各拡張モジュールについてデータベース毎に実行する必要があります。

バージョン 9.6 の変更点

サーバの変更

パラレルクエリ
  • パラレルクエリ (Robert Haas, Amit Kapila, David Rowley, many others) (9.6)
  • PostgreSQL 9.6 では、大きなクエリをパラレル実行するための初期サポートが導入されました。シーケンシャルスキャンを使ってテーブル参照する、厳密に読み込みだけのクエリは並列化することが可能になります。ハッシュ結合とネストループは並列に実行することができます。集約関数も可能です(サポートされた集約なら)。やるべき事は多数残っていますが、これはすでに便利な機能セットです。

    パラレルクエリ実行は(まだ)デフォルトで有効にされていません。有効にするには新しい設定パラメータ(max_parallel_workers_per_gather)を0より大きな値にします。追加の並列処理の実行制御は、新しい設定パラメータforce_paralle_mode, parallel_setup_cost, parallel_tuple_cost,min_parallel_relation_size を通じて行なえます。

  • 関数がパラレル処理で安全かを示す機構が提供されます。 (Robert Haas, Amit Kapila) (9.6)
  • プランナが、クエリをパラレル実行しても安全か判断するのに使われます。

インデックス
  • GIN インデックス作成が、1GB 以上の maintenance_work_mem 設定を有効に使えるようになりました。 (Robert Abraham, Teodor Sigaev) (9.6)
  • これまでは内部処理の都合で 1GB で制限されていました。

  • GIN インデックスの保留リストから削除されたページは、すぐにフリースペースマップに追加されるようになりました。 (Jeff Janes, Teodor Sigaev) (9.6)
  • テーブルが頻繁に VACUUM されない場合の膨張を軽減します。これまでは VACUUM が実行されるまで FSM に移動しませんでした。これは挿入のみで VACUUM されないテーブルで問題になることがありました。

  • gin_clean_pending_list 関数が追加され、GIN インデックスの保留リストの掃除を手動で起動できるようになりました。 (Jeff Janes) (9.6)
  • 以前は、この様な掃除は親テーブルの vacuum や analyze の副作用でしか実行されていませんでした。

  • GiSTインデックスでのデッドインデックスの扱いが改善されました。 (Anastasia Lubennikova) (9.6)
  • インデックススキャンで、対応するヒープタプルが死んでいる事に気付くと、デッドインデックスタプルとしてマークされるようになります。タプルを挿入する際に、ページに空き領域を作る必要があれば、デッドとマークされたタプルは削除されるようになりました。

    GiST インデックスページ内のマイクロ VACUUM 処理です。

  • box型に対する SP-GiST 演算子クラスが追加されました。 (Alexander Lebedev) (9.6)
ソート
  • 外部ソートを実行する時は、置換選択ソート(replacement-selection)ではなく、クイックソートを使うことで性能を向上します。(Peter Geoghegan) (9.6)
  • 新しい方式では、典型的なキャッシュサイズやデータ量で、CPU キャッシュをより有効に使います。必要な時は、新しい設定パラメータ replacement_sort_tuples で振る舞いを調整することができます。

  • テキストのソートで同じ文字列が何度も現れる場合が速くなりました。 (Peter Geoghegan) (9.6)
  • uuid, bytea, char(n) フィールドのソートは、短縮キーを使うことで速くなりました。 (Peter Geoghegan) (9.6)
  • 短縮キー(abbreviated keys)のサポートが、デフォルトではない演算子クラスtext_pattern_ops, varchar_pattern_ops, bpchar_pattern_ops にも追加されました。順序付き集約の処理でも、短縮キーの利用が可能になっています。

  • TID を64ビット整数としてソートすることで CREATE INDEX CONCURRENTLY がスピードアップされました。 (Peter Geoghegan) (9.6)
ロック
  • ProcArrayLock の競合を減らしました。 (Amit Kapila, Robert Haas) (9.6)
  • XID をクリアする処理で、複数の書き込みトランザクションが同時に行なわれている時は、ロックを獲得しているプロセスが、他のプロセスの分も処理します。

  • バッファコンテンツロックを、バッファディスクリプタに移動することで性能が向上されました。 (Andres Freund, Simon Riggs) (9.6)
  • これによりロックと pin がひとつのキャッシュラインで処理されることになります。

  • 共有バッファヘッダの spinlock をアトミック操作に交換したことで、スケーラビリティを向上しました。 (Alexander Korotkov, Andres Freund) (9.6)
  • pin/unpin バッファ操作が頻繁に行なわれるのはボトルネックになります。フラグ, usage_count, buf_hdr_lock, refcount をひとつの 32bit アトミック変数として扱うことで、同時に操作することができるようになります。

  • LWLock の待ちキュー保護に、spinlock ではなく、アトミック操作を使うようになりました。 (Andres Freund) (9.6)
  • spinlock してから状態フィールドを操作するのではなく、単純に、状態フラグをアトミック操作することにしました。

  • マルチ CPU ソケットサーバでの競合を軽減するため、共有ハッシュテーブルのフリーリストが分割されました。 (Aleksander Alekseev) (9.6)
  • フリーリストを分割しない場合、巨大なサーバでは深刻な問題になっていました。

  • スタンバイサーバで B-Tree インデックスの vacuum 操作を再生する時の内部ロックを軽減しました。 (Simon Riggs) (9.6)
  • この変更により、その様な再生処理中の、レプリケーション遅延の発生を回避します。

最適化統計
  • NULL をたくさん含むカラムでの ANALYZE の見積りを向上しました。 (Tomas Vondra, Alex Shulgin) (9.6)
  • これまでの ANALYZE は、多くの NULL を含むカラムでは、NULL でない値の固有値を過小評価していました。また頻出値の計算も不正確になっていました。

    アルゴリズムのバグで、NULLの個数を含めたカラム数と、含めないカラム数での計算が混在していて、不正確な結果になっていました。

  • クエリ結果に含まれる固有値の数のプランナの推定が改善されました。 (Tomas Vondra) (9.6)
  • 結合述部の選択率の推論に、外部キーの関係を利用します。 (Tomas Vondra, David Rowley) (9.6)
  • テーブル t が外部キー制約を持ち (a,b) が r (x,y) を参照しているとすると、WHERE 条件で t.a = r.x AND t.b = r.y は、t の行に対し 1より多くの r 行が選択されることはありません。これまでプランナは AND 条件は独立していると考えて、結果の選択率を大幅に間違えていました。今は WHERE 条件と適用できる外部キー制約を比較し、より良い推定値を算出します。

VACUUM
  • 凍結されたタプルだけを含むページを、再 VACUUM しなくなりました。 (Masahiko Sawada, Robert Haas, Andres Freund) (9.6)
  • これまでは、XID 周回を避けるための VACUUM は何もすることがないページでも、全て参照していました。今は、既に凍結されているタプルしか含まないページは、ビジビリティマップで判別され、トランザクション周回対策の vacuum を実行する場合でもスキップされます。これは、ほとんど変更されることのないデータを含む巨大なテーブルをメンテナンスするコストを大幅に削減します。

    必要ならば VACUUM の DISABLE_PAGE_SKIPPING オプションで、すべて凍結されているページも処理するように強制することができます。通常ならば、これを必要とすることはありませんが、ビジビリティマップの破損を回復させる助けになるかも知れません。

  • VACUUM 中の無駄なヒープ切り詰めが抑止されました。 (Jeff Janes, Tom Lane) (9.6)
  • この変更により、いくつかのケースで切り詰めができないときに、排他的テーブルロックを取らなくなります。主な利点は、スタンバイサーバでの不要なクエリキャンセルを避けることからきています。

パフォーマンス一般
  • 古いMVCCスナップショットを指定のタイムアウト後に無効にできるようになりました。 (Kevin Grittner) (9.6)
  • 通常、削除されたタプルは、それを参照できる最後のトランザクションが居なくならないない限り、VACUUM処理で削除されません。そのため、長時間のトランザクションが領域再利用を妨げてテーブル膨張をひき起こす可能性がありました。

    本変更では、MVCCスナップショットの有効性を保証する時間を指定する新たな設定パラメータ old_snapshot_threshold による時間に基づく限度を導入します。デッドタプル(削除済みタプル、不要領域)は、指定時間を超えれば VACUUM処理が可能になります。本機能を使用する場合、古いスナップショットを使うトランザクションはデータを参照する際に以下のエラーを受ける可能性があります。

    ERROR:  snapshot too old
    
  • 機能的に他の列に従属している GROUP BY 列を無視するようになりました。 (David Rowley) (9.6)
  • GROUP BY 句が遅延無しのプライマリキーの全ての列を含むなら、その他の列はいずれも冗長であり、グルーピングから除外することができます。これは多くのよくある場合に計算を節約します。

    (9.6 での結果: 主キーの id 以外が無視されている)
    db1=# explain SELECT id FROM t24 GROUP BY k1, k2, k3, id, k4, k5;
                             QUERY PLAN
    ------------------------------------------------------------
     HashAggregate  (cost=4.50..6.50 rows=200 width=24)
       Group Key: id
       ->  Seq Scan on t24  (cost=0.00..4.00 rows=200 width=24)
    (3 rows)
    
  • 部分インデックスで、インデックスの WHERE句がインデックスの無い列を参照しているときでも index-only スキャンが利用可能になりました。 (Tomas Vondra, Kyotaro Horiguchi) (9.6)
  • 以下に例を示します。SELECT 文の条件に WHERE a > 0 が含まれていて、選択リストが b だけなので index-only スキャンが選択されています。

    db1=# CREATE INDEX tidx_partial ON t25 (b) WHERE a > 0;
    
    db1=# explain SELECT b FROM t25 WHERE a > 0 AND b > 200;
                                      QUERY PLAN
    ------------------------------------------------------------------------------
     Index Only Scan using tidx_partial on t25  (cost=0.29..4.47 rows=10 width=4)
       Index Cond: (b > 200)
    (2 rows)
    

    以前はこのような場合にインデックス列に a が含まれないため、index-only スキャンは利用できないと判断されていました。

  • チェックポイント書き込みをソートされた順序で行うようになりました。 (Fabien Coelho, Andres Freund) (9.6)
  • これまではチェックポイントで共有バッファにあらわれた順にダーティページを書き出していました。通常はランダム同然の順番となります。これは特に回転体メディア(主としてハードディスク装置)では性能に劣ります。本変更でファイル・ブロック番号の順に書き出すようになり、また、各テーブルスペースにバランスよくアクセスするようになりました。

  • 可能であれば調整可能な回数の書き込みの後、ダーティデータをカーネルディスクバッファに溜めないように、カーネルによるライトバックを駆動させるようになりました。 (Fabien Coelho, Andres Freund) (9.6)
  • PostgreSQLはデータを、やがて物理ストレージにフラッシュされることから、カーネルディスクバッファに書き出します。多くの OS は必ずしもこのバッファ管理が賢くなく、大量のダーティデータをこれらを一度に書き出すと判断するまでの間に溜めこんで、新たな I/O 要求が大きく遅れてしまいます。この変更は設定された時間の後に明示的にデータのフラッシュを要求することで、本問題を緩和します。

    以下の新たな設定パラメータでこの動作を制御します。

    backend_flush_after = 0        # 0 disables, default is 0
    bgwriter_flush_after = 0       # 0 disables,
                                # default is 512kB on linux, 0 otherwise
    checkpoint_flush_after = 0     # 0 disables,
                                # default is 256kB on linux, 0 otherwise
    wal_writer_flush_after = 1MB   # 0 disables
    
  • 複数の同じ引数と遷移関数を持つ集約で計算を共有することで集約関数の性能が改善されました。 (David Rowley) (9.6)
  • 例えば「SELECT avg(x), variance(x) FROM tab」は二つの集約に対して 1行につき1回の計算で済みます。

  • 元トランザクションはコミット済みかを判断するのに pg_clog ではなく、現在トランザクションのスナップショットを検査することで、最近に作られたタプルの可視性の判定が高速化されました。 (Jeff Janes, Tom Lane) (9.6)
  • タプルのヒントビットが以前よりも早くセットできるようになりました。 (Andres Freund) (9.6)
  • 短命な準備されたトランザクションの性能が改善されました。 (Stas Kelvich, Simon Riggs, Pavan Deolasee) (9.6)
  • 二相コミットの情報は、PREPARE TRANSACTION のときに WAL にのみ書かれ、直ぐ後に生じるなら COMMIT PREPARED のとき WAL からのみ読み返されます。分離状態ファイルは保留しているトランザクションが次のチェックポイントまでコミットもアボートもされない場合にのみ作られるようになります。

  • メモリコンテキスト破棄の性能が改善されました。 (Jan Wieck) (9.6)
  • 多数のオブジェクトを追跡する場合の Resource Owners の性能が改善されました。 (Aleksander Alekseev) (9.6)
  • Resource Owners は問い合わせに係わるリソースを管理するための内部モジュールです。

  • timestamp、time、date データ型の出力関数の速度が改善されました。 (David Rowley, Andres Freund) (9.6)
  • ライブラリ関数を手書きコードに置き換えて高速化しています。

  • AccessExclusive ロックを取得する動作のリプレイ中に生じる、ホットスタンバイ問い合わせの一部の不要なキャンセルを回避するようになりました。 (Jeff Janes) (9.6)
  • リレーション拡張でロック競合が生じているときには、一度に複数ブロックを拡張するようになりました。 (Dilip Kumar) (9.6)
  • これは競合を減らすことでスケーラビリティを改善します。

  • スケーラビリティ改善のため clogバッファの数が増やされました。 (Amit Kapila, Andres Freund) (9.6)
  • PL/pgSQL で、常に有効な単純な変数に対する ParamListInfo要素を保持しておくことで式の評価が高速化されました。 (Tom Lane) (9.6)
  • 上記の ParamListInfo は内部的なデータ構造です。

  • 最近の Windowsバージョンでソケット設定の SO_SNDBUF をデフォルト値より小さくは上書き設定しないようになりました。 (Chen Huajun) (9.6)
  • Windows 2012 からデフォルト値が増やされたため、従来の値を増やす為のコードが逆に値を減らす結果になっていました。

  • update_process_title 設定パラメータが Windows ではデフォルトoff になりました。 (Takayuki Tsunakawa) (9.6)
  • 他のプラットフォームと比べて Windows ではプロセスタイトルを更新するオーバーヘッドが非常に大きく、また、大部分の Windowsユーザはプロセスタイトルを参照するツールを持っておらず実用性も低いため、このように変更されました。

モニタリング
  • VACUUM処理の進行を報告するシステムビューpg_stat_progress_vacuum が追加されました。 (Amit Langote, Robert Haas, Vinayak Pokale, Rahila Syed) (9.6)
  • 関数 pg_control_system()、pg_control_checkpoint()、pg_control_recovery()、pg_control_init() が追加されました。 (Joe Conway, Michael Paquier) (9.6)
  • これにより(pg_control コマンドで参照できる)pg_controlファイルのフィールドをSQL から参照することができます。

  • pg_configシステムビューが追加されました。 (Joe Conway) (9.6)
  • pg_configコマンドと同様の PostgreSQLコンパイル時の設定情報を取得することができます。

  • pg_replication_slotsシステムビューに confirmed_flush_lsn 列が追加されました。 (Marko Tiikkaja) (9.6)
  • ホットスタンバイサーバの WALレシーバプロセスの状態に関する情報を持つpg_stat_wal_receiverシステムビューが追加されました。 (Michael Paquier) (9.6)
  • どのセッションがどのセッションをブロックしているかを識別するpg_blocking_pids() 関数が追加されました。 (Tom Lane) (9.6)
  • 引数にセッション (のバックエンドプロセスの) PID を与えると、そのセッションを待たせているセッションの PID が配列で返ります。これまでは pg_locksビューの出力を加工して同様の情報を得る必要がありましたが、無駄に手間がかかり、また、パラレル問い合わせに対応するのは困難でした。

    (使用例)
    db1=# SELECT pid, pg_blocking_pids(pid), state, wait_event_type, wait_event
            FROM pg_stat_activity ;
      pid  | pg_blocking_pids |        state        | wait_event_type | wait_event
    -------+------------------+---------------------+-----------------+------------
     10926 | {}               | idle in transaction |                 |
     10934 | {10926}          | active              | Lock            | relation
     10937 | {}               | active              |                 |
     10952 | {10926,10934}    | active              | Lock            | relation
    (4 rows)
    
  • 現在トランザクションのログフラッシュ位置を返す、関数 pg_current_xlog_flush_location() が追加されました。 (Tomas Vondra) (9.6)
  • 現在のNOTIFYキューの件数を返す関数pg_notification_queue_usage() が追加されました。 (Brendan Jurd) (9.6)
  • メモリコンテキスト統計ダンプの冗長さが限定されました。 (Tom Lane) (9.6)
  • メモリ不足エラーになるとエラーメッセージとしてメモリコンテキスト統計ダンプも出力されます。これが多数のメモリコンテキスト(固定で 100個以上)がある場合には、要約した短い出力とするようになりました。また、どちらの場合でも合計サイズの報告が加わります。

認証
  • PostgreSQLクライアント認証にBSD認証サービスを利用するbsd認証方式が追加されました。 (Marisa Emerson) (9.6)
  • bsd認証はいまのところ OpenBSDでのみ利用可能です。

  • pam認証を使う際に PAM_RHOST項目を通してクライアントIPアドレスやホスト名をPAMモジュールに提供するようになりました。 (Grzegorz Sampolski) (9.6)
  • このために設定オプション pam_use_hostname が追加されました。

  • マスタプロセスのログにパスワード認証失敗の詳細が出力されるようになりました。 (Tom Lane) (9.6)
  • 「password authentication failure」になるすべての場合のログ出力にDETAIL欄が加わり、パスワード不一致であるほか、指定ロールが存在しない場合や、ロールにパスワードが設定されていない場合を区別できるようになります。

  • RADIUSパスワードが128文字までサポートされました。これまでは16文字まででした。 (Marko Tiikkaja) (9.6)
  • 新たなSSPI認証のパラメータ compat_realm、upn_username が追加されました。 (Christian Ullrich) (9.6)
  • これらは SSPI認証で使われる NetBIOS か Kerberos のレルム名とユーザ名を制御します。

サーバ設定
  • idle in transaction 状態が長く続くセッションを自動的に停止できるようになりました。 (Vik Fearing) (9.6)
  • この動作は 新たな設定パラメータ idle_in_transaction_session_timeout で制御されます。忘れられたトランザクションが長時間にわたりロックを保持していたり、VACUUMを妨げていたりするのを防ぐのに役立ちます。

  • checkpoint_timeout の許される最大値が 24 hours に増やされました。 (Simon Riggs) (9.6)
  • 以前の最大値は 1 hour でした。

  • effective_io_concurrency がテーブルスペース毎に設定できるようになりました。 (Julien Rouhaud) (9.6)
  • それぞれ異なるI/O特性を持つテーブルスペースがあるときに役立ちます。

    (設定例)
    db1=# ALTER TABLESPACE my_tblspc1 SET ( EFFECTIVE_IO_CONCURRENCY = 5 );
    
  • log_line_prefix に現在時刻を Unixエポック形式で出力するオプション %n が追加されました。 (Tomas Vondra, Jeff Davis) (9.6)
  • ミリ秒を伴い「1474886432.585」のような出力となります。

  • 設定パラメータ syslog_sequence_numbers、syslog_split_messages が追加されました。 (Peter Eisentraut) (9.6)
  • syslog にログ出力するときにメッセージに連番を付けるか、メッセージを分割するかを指定できます。デフォルト設定はいずれも on で従来通りの動作となります。

  • wal_level 設定パラメータの archive と hot_standby が新たな一つの値 replica に統合されました。 (Peter Eisentraut) (9.6)
  • これらの設定を区別することに価値が無いと判断されました。旧来の名称も引き続き受け付けられ、内部的に replica に置き換えられます。

  • configureオプション --with-systemd が追加されました。サーバの起動停止時にライブラリ関数 sd_notify() を呼び出すようになります。 (Peter Eisentraut) (9.6)
  • これにより、systemd 下での PostgreSQL の管理をとても簡単にできるnotifyタイプの systemdサービスユニットを使用できるようになります。

  • サーバSSL鍵ファイルの所有者が root であるとき、グループ読み取りアクセスを持つことを許容するようになりました。 (Christoph Berg) (9.6)
  • これまでは鍵ファイルは PostgreSQLサーバ実行ユーザが所有者でなければなりませんでした。Debian など証明書を集中管理する一部のシステムでは、これは不便でした。グループに信頼できないユーザが含まれないようにするのはOS管理者の責任となります。

信頼性
  • マスタプロセスが終了したならバックエンドプロセスも強制終了するようになりました。 (Rajeev Rastogi, Robert Haas) (9.6)
  • 通常の状況ではマスタプロセスは子プロセスよりも長く生き続けます。何らかの理由でマスタプロセスが死ぬと、バックエンドセッションがエラーを出して終了するようになりました。これまでは、残ったバックエンドプロセスはクライアントから切断されるまで実行を続けていましたが、これは危険で非効率的でした。この変更は、旧バックエンドプロセスが残っているのに新たな PostgreSQL を起動してしまうことも防ぎます。バックエンドプロセスはクライアントI/Oを待つ間にマスタプロセスダウンを検知した場合には、即座には終了しませんが、現在の問い合わせが終了した時点よりも遅くなることはありません。

  • 制約違反エラーを報告する前に直列化の衝突を検査するようになりました。 (Thomas Munro) (9.6)
  • トランザクション隔離レベルにシリアライザブルを使っている場合、現在トランザクションが原因のあらゆるエラーは直列化失敗として表明すべきことが望まれます。これによってリトライで成功を見込めるアプリケーションに指示を出しています。残念ながら、これまでは同時挿入によりキー重複エラーが生じた場合、直列化失敗エラーは確実には発生しませんでした。

    本変更でこのような場合には直列化失敗エラーとして報告されるようになります。

  • たとえ XID 割り当ての無いトランザクションから出されたときでも、無効化メッセージ(新たな XLOGメッセージタイプ XLOG_INVALIDATIONS)が確実にWAL記録されるようになりました。 (Andres Freund) (9.6)
  • この変更は、スタンバイサーバのトランザクションが、インデックス同時作成や可視性マップ等の更新に気づくのに失敗するという場合について修正します。

  • 複数プロセスが GINインデックスのペンディングリストを同時に掃除しようとするのを防ぐようになりました。 (Teodor Sigaev, Jeff Janes) (9.6)
  • これまでは故意に許されていましたが、このことは結果として VACUUM が削除すべきインデックスエントリを見落とす競合状態をひき起こします。

レプリケーション/リカバリ

  • 同期レプリケーションで同時に動作する複数の同期スタンバイサーバをサポートするようになりました。 (Masahiko Sawada, Beena Emerson, Michael Paquier, Fujii Masao, Kyotaro Horiguchi) (9.6)
  • コミット応答の前に同期完了を確認しなければいけないスタンバイサーバの数を、synchronous_standby_names パラメータの中で指定できるようになります。

    以下は、s1、s2、s3 の 3つスタンバイのうち 2つを同期スタンバイサーバとするという意味になります。

    synchronous_standby_names = '2 (s1,s2,s3)'
    
  • 設定パラメータ synchronous_commit に新たな値 remote_apply が追加されました。 (Thomas Munro) (9.6)
  • このモードでは、プライマリはトランザクションがスタンバイサーバ上で、ディスクに書かれるだけでなく、適用されるのを待ちます。このことは、マスタにてコミット済みとこれまで応答を受けた全ての内容をスタンバイ上で参照できると期待できることを意味します。

  • レプリケーションプロトコルにレプリケーションスロットが作られたときに直ぐに WAL を確保できる機能が追加されました。また、pg_create_physical_replication_slot() に対応する immediately_reserveオプションが追加されました。 (Gurjeet Singh, Michael Paquier) (9.6)
  • これによりレプリケーションスロット作成によってベースバックアップに必要な全ての WAL が入手可能であることを保証できるようになります。

  • pg_basebackup に --slot オプションが追加されました。 (Peter Eisentraut) (9.6)
  • これは pg_basebackup にWALストリーミングのレプリケーションスロットを使わせます。ベースバックアップ完了後、通常のストリーミングレプリケーション用に同スロットを選択することで、スムーズに新たなスタンバイサーバを開始できます。

  • pg_start_backup() と pg_stop_backup() が非排他バックアップに対応しました。 (Magnus Hagander) (9.6)
  • これにより同時に2系統のベースバックアップが実行可能になります。両関数に排他モードであるかを指定するオプションパラメータが追加されました。

問い合わせ

  • 行の集合を返す関数が NULL の行を返せるようになりました。 (Andrew Gierth, Tom Lane) (9.6)
  • SELECT ... FROM function(...) という文脈では、複合値の集合を返す関数は、これまで単なる NULL値を集合の一部として返すことができませんでした。これからは可能となり、行の各要素が NULL の行と解釈されます。

    以下に例を示します。

    db1=# CREATE TABLE t71 (id int, v text, ts timestamp(0));
    db1=# CREATE OR REPLACE FUNCTION f_srf() RETURNS SETOF t71 LANGUAGE sql
            AS $$ VALUES ( NULL::t71 ), ((1, 'a', '2015-01-01')::t71); $$;
    
    (9.6 の実行結果)
    db1=# pset null *null*
    db1=# SELECT * FROM f_srf();
       id   |   v    |         ts
    --------+--------+---------------------
     *null* | *null* | *null*
          1 | a      | 2015-01-01 00:00:00
    (2 rows)
    
    (9.5.x の実行結果)
    db1=# SELECT * FROM f_srf();
    ERROR:  function returning set of rows cannot return null value
    
  • 複数の VALUES 行を持つ INSERT の対象カラムリストで、配列添字によるフィールド選択について完全に対応しました。 (Tom Lane) (9.6)
  • これまでは以下のように同じ対象列が複数回現れる場合にエラーが出ていました。

    (9.5.x の結果)
    db1=# INSERT INTO t72 (id, arr[1], arr[2], arr[3])
            VALUES (1, 101, 102, 103), (2, 201, 202, 203);
    ERROR:  multiple assignments to same column "arr"
    
  • それが適切な場合には、SELECT 出力式の評価を ORDER BY ソートまで延期するようになりました。 (Konstantin Knizhnik) (9.6)
  • この変更は出力リストにある揮発性の関数、高負荷な関数が、ORDER BY で指示される順序で実行されることを、また、LIMIT句があるときに必要な回数以上に評価されないことを保証します。

    インデックススキャンやマージ結合前のソートでは従来からこのような動作をしていましたが、トップレベルソートでは実施されませんでした。

    (実行例/ここでの t73 テーブルの行はデタラメな順で物理格納されている)
    db1=# SELECT id FROM t73;
     id
    ----
      5
      7
     49
     76
     25
     : (後略)
    
    (9.5 の結果)
    db1=# CREATE SEQUENCE sq73;
    db1=# SELECT nextval('sq73'), id FROM t73 ORDER BY id ;
     nextval | id
    ---------+----
          31 |  1
          63 |  2
          44 |  3
          77 |  4
           1 |  5
    (5 rows)
    
    db1=# SELECT currval('sq73');
     currval
    ---------
         100
    (1 row)
    
    (9.6 の結果)
    db1=# CREATE SEQUENCE sq73;
    db1=# SELECT nextval('sq73'), id FROM t73 ORDER BY id ;
     nextval | id
    ---------+----
           1 |  1
           2 |  2
           3 |  3
           4 |  4
           5 |  5
    (5 rows)
    db1=# SELECT currval('sq73');
     currval
    ---------
           5
    (1 row)
    
  • 処理されるタプル数を記録するカウンタが 64bit に拡張されました。 (Andreas Scherbaum) (9.6)
  • この変更により SELECT 等のコマンドタグが 40億件以上のタプル数を正しく報告できるようになります。これは PL/pgSQL の GET DIAGNOSTICS ... ROW_COUNTコマンドにも適用されます。

  • MULE_INTERNAL文字エンコーディングへの変換を通したエンコーディング変換を回避するようになりました (Tom Lane) (9.6)
  • これまでキリル文字と中央ヨーロッパのシングルバイト文字エンコーディングに対する多くの変換では、MULE_INTERNAL を通して変換していました。これは非効率であり、また、変換不能である場合のエラーメッセージがMULE_INTERNAL との間で変換できないという混乱を招く内容になってしまっていました。

  • テーブルが同じロールID でアクセスされるときのみ、リモート側での外部テーブルの結合を検討するようになりました。 (Shigeru Hanada, Ashutosh Bapat, Etsuro Fujita) (9.6)
  • これまでは外部テーブル結合のプッシュダウン基盤は、各外部データラッパ次第のセキュリティ上の問題を残していました。このことは、外部データラッパ実装で不注意によりセキュリティホールを作ってしまい易くしていました。

    そのため、本体コード側でどのロールID で各テーブルにアクセスするかを判定して、各結合するテーブルにアクセスするロールが同じでない限り結合のプッシュダウンを試みないようにしました。

ユーティリティコマンド

  • COPY が INSERT、UPDATE、DELETE に RETURNING を付けた場合の出力をコピーできるようになりました。 (Marko Tiikkaja) (9.6)
  • これまでは CTE を経由してこれらを出力する SQL を記述する必要がありました。

  • ALTER ... DEPENDS ON EXTENSION ... 構文が追加されました。 (Abhijit Menon-Sen) (9.6)
  • ALTER FUNCTION、ALTER INDEX、MATERIALIZED VIEW、ALTER TRIGGER の各コマンドに新たな DEPENDS ON EXTENSION オプションが加わりました。

    これらはオブジェクトに拡張モジュールに依存しているという印をつけます。そうすると、その拡張モジュールを削除すると(CASCADE指定無しでも)自動的にオブジェクトも削除されます。しかしながら、そのオブジェクトは拡張モジュールの一部というわけではないので、pg_dump では別個にダンプされます。

    (動作例)
    db1=# CREATE EXTENSION hstore;
    db1=# CREATE FUNCTION f(text) RETURNS text LANGUAGE sql
            AS $$ SELECT ($1::hstore)::text $$;
    db1=# ALTER FUNCTION f(text) DEPENDS ON EXTENSION hstore;
    db1=# SELECT f('a=>b');
        f
    ----------
     "a"=>"b"
    (1 row)
    
    db1=# DROP EXTENSION hstore;
    db1=# SELECT f('a=>b');
    ERROR:  function f(unknown) does not exist
    
  • ALTER ... SET SCHEMA で対象が既に指定のスキーマ下にある場合には、エラーを出すのではなく、何もしないようになりました。 (Marti Raudsepp) (9.6)
  • このケースは、これまでほとんどの種類のオブジェクトでエラーになっていました。

  • ALTER OPERATOR にその演算子に関する選択性の関数を変更できるオプションが加わりました。 (Yury Zhuravlev) (9.6)
  • CREATE OPERATOR では以前から指定可能でした。

  • ALTER TABLE ... ADD COLUMN に IF NOT EXISTS オプションが加わりました。 (Fabrízio de Royes Mello) (9.6)
  • テーブルの fillfactor と autovacuum関連のオプションを設定するときにALTER TABLE が必要とするロックレベルが、下げられました。 (Fabrízio de Royes Mello, Simon Riggs) (9.6)
  • これからは AccessExclusiveLock ではなく ShareUpdateExclusiveLock で済みます。

  • CREATE ACCESS METHOD コマンドが導入されました。拡張モジュールで新たなインデックスアクセスメソッドを作ることができます。 (Alexander Korotkov, Petr Jelínek) (9.6)
  • CREATE EXTENSION に CASCADE オプションが加わりました。依存する拡張モジュールも合わせて導入してくれます。 (Petr Jelínek) (9.6)
  • CREATE TABLE ... LIKE で参照元テーブルが OID列を持つなら、作成テーブルにも OID列を含めるようになりました。 (Bruce Momjian) (9.6)
  • テーブル作成コマンドでは CHECK制約が NOT VALID と宣言されている場合でも、自動的に VALID とみなすようになりました。 (Amit Langote, Amul Sul) (9.6)
  • 作成時点ではテーブルには行がありませんので、これは安全です。FOREIGN KEY 制約を NOT VALID 指定で作った場合には、従来からこのような振る舞いとなっていました。

  • DROP OPERATOR が pg_operator.oprcom と pg_operator.oprnegate の削除された演算子へのリンクを消すように修正されました。 (Roma Sokolov) (9.6)
  • これまではこれらリンクはそのまま残されていて、あまりないことですが、削除された演算子の OID が他の演算子で再利用されることで問題をひき起こすおそれがありました。

  • EXPLAIN で同じサブプランを2回表示しないようになりました。 (Tom Lane) (9.6)
  • ある種の、典型的にはインデックス条件の SubPlanノードを伴う場合に、EXPLAIN は同じサブプランを 2回出力することがありました。

  • OIDカラムを除くシステムカラムへのインデックス作成が禁止されました。 (David Rowley) (9.6)
  • このようなインデックスはサポートされていると考えられておらず、タプルのシステムカラム列はインデックスを更新することなく変更されることがあるため、おそらく極めて不適切な動作をしていました。それでいて、これまでインデックス作成を防ぐエラーチェックがありませんでした。

アクセス権限の制御

  • 機微な関数へのアクセス管理に権限システムを使うようになりました。 (Stephen Frost) (9.6)
  • これまでは、多くのセキュリティ的に機微な関数には、非スーパーユーザから呼び出されたらエラーを投げるという固定的なチェックが組み込まれていました。このことは関連する通常のタスクにもスーパーユーザロールを使わざるをえなくしていました。

    今後は、これらの固定的なチェックは無くして、むしろ initdb でこれら関数上のデフォルトの public EXECUTE 権限を無効にするようにします。これにより、これら関数の使用を(スーパーユーザでない)信頼されたロールに許可する使い方ができるようになります。

    以下の関数でそのように変更されました。

    pg_start_backup(text, boolean, boolean)
    pg_stop_backup()
    pg_stop_backup(boolean)
    pg_create_restore_point(text)
    pg_switch_xlog()
    pg_xlog_replay_pause()
    pg_xlog_replay_resume()
    pg_rotate_logfile()
    pg_reload_conf()
    pg_stat_reset()
    pg_stat_reset_shared(text)
    pg_stat_reset_single_table_counters(oid)
    pg_stat_reset_single_function_counters(oid)
    

    pg_read_file() など、依然として固定的にスーパーユーザでないと実行できないように実装されている関数も残っています。

  • 従来スーパーユーザのみ実行可能であった関数へのアクセス権限を持っているビルトインロールが作られました。 (Stephen Frost) (9.6)
  • いまのところ、サーバシグナル送信関数を実行できる pg_signal_backend ロールのみ用意されています。

データ型

  • フレーズ検索ができるように全文検索が改良されました。 (Teodor Sigaev, Oleg Bartunov, Dmitry Ivanov) (9.6)
  • フレーズとは指定の順序で隣接あるいは指定の距離を空けて現れる語彙素の並びです。

    フレーズ検索問い合わせは tsquery 入力の中でで <-> 演算子、<N> 演算子にて指定できます。前者は、前後の語彙素が隣接してその順に現れなければいけないことを意味します。後者は、前後の語彙素がちょうど N 語彙素だけ離れていなければいけないことを意味します。

    以下に使用例を示します。

    db1=# CREATE TABLE t_ps (id serial, txt text, tsv tsvector);
    db1=# INSERT INTO t_ps (txt) VALUES (
            'PostgreSQL is the most advanced open source database in the world');
    db1=# UPDATE t_ps SET tsv = to_tsvector('english', txt);
    
    db1=# SELECT phraseto_tsquery('english', 'open source database');
             phraseto_tsquery
    ----------------------------------
     'open' <-> 'sourc' <-> 'databas'
    (1 row)
    
    db1=# SELECT phraseto_tsquery('english', 'open source database') @@ tsv FROM t_ps;
     ?column?
    ----------
     t
    (1 row)
    
    db1=# SELECT phraseto_tsquery('english', 'database in the world');
       phraseto_tsquery
    -----------------------
     'databas' <3> 'world'
    (1 row)
    
    db1=# SELECT phraseto_tsquery('english', 'database in the world') @@ tsv FROM t_ps;
     ?column?
    ----------
     t
    (1 row)
    
  • 配列切り出し指定を片方あるいは両方省略できるようになりました。 (Yury Zhuravlev) (9.6)
  • 以下のように使用できます。

    db1=# SELECT '{aa,bb,cc,dd,ee,ff}'::text[];
            text
    ---------------------
     {aa,bb,cc,dd,ee,ff}
    (1 row)
    
    db1=# SELECT ('{aa,bb,cc,dd,ee,ff}'::text[])[:3];
        text
    ------------
     {aa,bb,cc}
    (1 row)
    
    db1=# SELECT ('{aa,bb,cc,dd,ee,ff}'::text[])[:];
            text
    ---------------------
     {aa,bb,cc,dd,ee,ff}
    (1 row)
    
  • 範囲外の日付、タイムスタンプについてより注意深くなりました。 (Vitaly Burovoy) (9.6)
  • この変更は timestamp with time zone 型の最大値、最小値に極めて近い値に対して、想定外の out-of-range エラーが生じるのを防ぎます。これまでは、タイムゾーン設定によって同じ値が受け入れられたり、受け入れられなかったりしました。このことはダンプ後のリロードで、既に受け入れられた値について失敗するおそれがあることを意味します。これからは、値の上限下限は timezone設定と無関係にローカル時刻でなくUTC時刻に従って制限されます。

    また、date + integer などの演算で生じた新たな date や timestamp 値のオーバーフロー判定をより注意深く行うようになりました。

    これらの結果として、仕様上範囲外とされている値において 9.5.x よりも扱えない値の範囲が増えています。バージョンアップ時の注意事項となります。

  • 幾何データ型にて infinity および NaN 構成要素値が入出力で確実に一貫性をもって扱われるようになりました。 (Tom Lane) (9.6)
  • 今後これらの値は常に単純な float8 (double precision) 型の列と同様に出力されるようになります。また、入力においても同様に扱われます。これまでは振る舞いがプラットフォーム依存となっていました。

  • 現代的な Hunspellファイルを扱え、より多くの言語に対応するようにispell辞書タイプが改訂されました。 (Artur Zakirov) (9.6)
  • 正規表現に後方検索制約(後ろ読み制約、lookbehind constraint) が実装されました。 (Tom Lane) (9.6)
  • 後方検索制約は、既存の先行検索制約(先読み制約、lookahead constraint) と同様に、テキストを消費しませんが、文字列の現在位置を末尾としてマッチするかチェックします。同様の仕様は既存の他の多くの正規表現エンジンに存在します。

    以下のように使用できます。

    (例1: abc に続く 3文字)
    db1=# SELECT regexp_matches('abcdefgh', '(?<=abc)...');
     regexp_matches
    ----------------
     {def}
    (1 row)
    
    (例2: abc に続かない 3文字を複数切り出し)
    db1=# SELECT regexp_matches('abcdefgh', '(?<!abc)...', 'g');
     regexp_matches
    ----------------
     {abc}
     {efg}
    (2 rows)
    
  • 正規表現で、3桁8進エスケープ
    nn が 377 (10進数で 255、1バイト) を超えることがあり、これを 2桁の8進エスケープと見なすようになりました。 (Tom Lane) (9.6)
  • 以下例の 467 は 2桁8進数エスケープで解釈すれば '&' と文字 '7' で、3桁8進数で解釈すると1バイトを超える不正な値になります。

    (9.5.x での結果)
    db1=# SELECT 'a&7bbbbb'  ~ '^a467';
     ?column?
    ----------
     f
    (1 row)
    
    (9.6 での結果 - 正規表現パターンが '^a&7' と解釈されています)
    db1=# SELECT 'a&7bbbbb'  ~ '^a467';
     ?column?
    ----------
     t
    (1 row)
    
  • 対応する等価演算子と一貫性をもたせるため、トランザクションID (XID) の演算子 xid <> xid および xid <> int4 が追加されました。 (Michael Paquier) (9.6)

関数

  • jsonb配列に新たな要素を挿入したり、jsonbオブジェクトに新たなキーを挿入する jsonb_insert()関数が追加されました。 (Dmitry Dolgov) (9.6)
  • 以下のようにパスを指定して jsonbデータ構造の内部に要素を挿入できます。

    db1=# SELECT jsonb_insert('{"x":[10,20,30],"y":[4,5]}', ARRAY['x','2']::text[], '100');
                 jsonb_insert
    ---------------------------------------
     {"x": [10, 20, 100, 30], "y": [4, 5]}
    (1 row)
    
  • numeric型むけの ln()、log()、exp()、pow() 関数の精度が改善しました。 (Dean Rasheed) (9.6)
  • numeric型の値の尺度(小数点位置)を返す scale()関数が追加されました。 (Marko Tiikkaja) (9.6)
  • (例)
    db1=# SELECT scale(12345.678::numeric);
     scale
    -------
         3
    (1 row)
    
  • ラジアンでなく度単位で動作する三角関数が追加されました。 (Dean Rasheed) (9.6)
  • 末尾に d が付いた度単位版の三角関数 acosd()、asind()、atan2d()、cosd()、cotd()、sind()、tand() が追加されました。

    (例)
    db1=# SELECT sind(30);
     sind
    ------
      0.5
    (1 row)
    
  • 三角関数(sin/cos/tan) が infinity と Nan の入力を確実に POSIX標準通りに扱うようになりました。 (Dean Rasheed) (9.6)
  • POSIX標準では、これら関数は NaN 入力には NaN を返すべきであり、infinity を含む範囲外入力にはエラーを出すべきとされています。これまでは、各プラットフォームでばらばらの振る舞いをしていました。

  • to_timestamp(float8) が浮動小数点の infinity を timestamp の infinityに変換するようになりました。 (Vitaly Burovoy) (9.6)
  • 従来は「ERROR: timestamp out of range」となっていました。

  • tsvectorデータむけに新たな関数がいくつか追加されました。 (Stas Kelvich) (9.6)
  • 以下が追加されています。

     ts_delete()             tsvector から要素を削除
     ts_filter()             tsvector から重み指定条件で要素を削除
     unnest()                tsvector を行集合に展開 
     tsvector_to_array()     tsvector を配列に変換
     array_to_tsvector()     配列を tsvector に変換
     setweight() の別引数版  指定の要素だけ重み付け設定
    
  • ts_stat()、tsvector_update_trigger() 関数が、想定される引数型のみならず、それらとバイナリ互換の型の値も処理できるようになりました。例えば text型引数に citext型の値も使えるようになります。 (Teodor Sigaev) (9.6)
  • 引数の NULL あるいは 非NULL を数える可変引数関数 num_nulls()、num_nonnulls() が追加されました。 (Marko Tiikkaja) (9.6)
  • CHECK制約に CHECK(num_nonnulls(a, b, c) = 1) と記述することで、3つの列のうち 1つだけが非NULL であるということを表明できます。これらの関数は、一つの配列に対して要素の NULL または非NULLを数える使い方も可能です。

  • 修飾され、またあるいはクォートされた SQL識別子を要素の配列に分割する、parse_ident() 関数が追加されました。 (Pavel Stehule) (9.6)
  • "APP"スキーマの t_log テーブルの col1 カラムが「"APP".T_LOG.Col1」と表現されていたとして、これを以下例のように分解できます。クォートされていない大文字の小文字への正規化も行われます。

    db1=# SELECT parse_ident('"APP".T_LOG.Col1');
       parse_ident
    ------------------
     {APP,t_log,col1}
    (1 row)
    
  • to_number() 関数で V フォーマットコードを、10 の V に続く数字の個数のべき乗で割るものと解釈するようになりました。 (Bruce Momjian) (9.6)
  • これにより、to_char の逆関数として動作するようになります。

    (9.6 での動作例: V の後 9 が 2個並んでいるので 10^2 で割った値が返ります)
    db1=# SELECT to_number('12400', '999V99');
          to_number
    ----------------------
     124.0000000000000000
    (1 row)
    
    (9.6 および 9.5.x の動作例: 10^2 を乗じた値が返ります)
    db1=# SELECT to_char(124.000, '999V99');
     to_char
    ---------
      12400
    (1 row)
    
  • to_reg*() 関数群が cstring型でなく、text型を受け付けるようになりました。 (Petr Korobeinikov) (9.6)
  • 引数が単純なリテラル定数でない箇所でも、ほとんどの場合に明示的なキャストを加える必要がなくなります。

    これまでは以下のように明示的なキャストが必要なケースがありました。

    (9.5.x の動作例 - public.t1 の """"""OID番号を調べる問い合わせ)
    db1"""""" =# SELECT to_regclass('public.t1')::oid;
     to_regclass
    -------------
           17757
    (1 row)
    
    db1=# SELECT to_regclass('public.' || 't1')::oid;
    ERROR:  function to_regclass(text) does not exist
    
    db1=# SELECT to_regclass(('public.' || 't1')::cstring)::oid;
     to_regclass
    -------------
           17757
    (1 row)
    
  • 人間に読みやすい形式で書かれたサイズをあらわす文字列を数値に変換するpg_size_bytes() 関数が追加されました。 (Pavel Stehule, Vitaly Burovoy, Dean Rasheed) (9.6)
  • 本関数は、pg_size_pretty()関数が出力するような文字列をバイト単位の数値に変換します。

    例えば以下のように使用します。

    db1=# SELECT oid::regclass FROM pg_class
            WHERE pg_total_relation_size(oid) > pg_size_bytes('10 GB');
    
  • pg_size_pretty() 関数でマイナスの値をプラスの値同様に整形するようになりました。 (Adrian Vondendriesch) (9.6)
  • これまではマイナス値は必ずバイト単位で出力されていました。

    (9.5.x の動作)
    db1=# SELECT pg_size_pretty(-100000000::int8);
      pg_size_pretty
    ------------------
     -100000000 bytes
    (1 row)
    
    db1=# SELECT pg_size_pretty(-100000000::int8);
     pg_size_pretty
    ----------------
     -95 MB
    (1 row)
    
  • current_setting() 関数にオプション引数 missing_ok が追加されました。 (David Christensen) (9.6)
  • これにより認識できないパラメータ名についてエラーを回避して、代わりにNULL が返るようにできます。

  • いくつかのシステムカタログ情報関数が無効な入力に対して NULL を返すようになりました。 (Michael Paquier) (9.6)
  • 今後は、pg_get_viewdef() は無効なビューのOIDに対して NULL を返します。また、類似のいくつかの関数も無効な入力に NULL を返すようになります。

    これまではエラーを示す文字列(例:「Not a view」)が返ったり、「ERROR: cache lookup failed ...」というエラーが生じたりして、不規則な応答となっていました。

  • レプリケーションSQL関数の pg_replication_origin_xact_reset() が引数を持たないように修正されました。 (Fujii Masao) (9.6)
  • ドキュメントには引数を持たないと記されており、C コードも引数無しの想定となっていますが、SQL関数定義上は 2引数を取るようになっていました。

サーバサイド言語

  • PL/pgSQL で実行時でなく関数コンパイル時に CONTINUE文と EXIT文の不一致を検出するようになりました。 (Jim Nasby) (9.6)
  • PL/Python のエラー報告関数とメッセージ報告関数が、主エラーメッセージの他に追加メッセージ欄を指定できるように拡張されました。 (Pavel Stehule) (9.6)
  • PL/Python 関数が自分自身を SPI を通して再帰的に呼び出しできるようになりました。また、集合を返す PL/Python 関数が一つの問い合わせの中で複数呼び出されたときの振る舞いが修正されました。 (Alexey Grishchenko, Tom Lane) (9.6)
  • PL/Python におけるセッション単位でのメモリリークが修正されました。 (Heikki Linnakangas, Haribabu Kommi, Tom Lane) (9.6)
  • PL/Tcl を単純な文字列でなく Tcl のオブジェクトAPI を使うように現代化しました。 (Jim Nasby, Karl Lehenbauer) (9.6)
  • これにより一部ケースでかなり性能が改善されます。なお、PL/Tcl は Tcl 8.4 以降が必要となります。

  • PL/Tcl で、Tcl の errorCode グローバル変数にて、データベースエラーに追加情報が返るようになりました。 (Jim Nasby, Tom Lane) (9.6)
  • この仕様は Tcl のエラーに関する補助データを返すときの慣習に従っています。

クライアントインターフェース

  • エラーおよび警告メッセージにおける深刻度フィールドの非ローカライズ版が加わりました。 (Tom Lane) (9.6)
  • 「ERROR」「WARNING」「NOTICE」などの深刻度を示す語が NLS を有効にしている場合、ローカライズされている可能性がありました。本修正で、クライアントプログラムがこのような懸念なく深刻度を判定できるようになります。

    PQresultErrorField() 関数で fieldcode に PG_DIAG_SEVERITY の他PG_DIAG_SEVERITY_NONLOCALIZED を指定できるようになります。

    また、PostgreSQLプロトコルにおける ErrorResponse および NoticeResponseメッセージ内で現れるフィールドの種類をあらわすコードに 'S' の非ローカライズ版である 'V' が加わっています。

  • libpq でメッセージの CONTEXT 出力の抑制を調整できるようになりました。常に抑制するか、非エラーのメッセージのみ抑制するかを指定できます。 (Pavel Stehule) (9.6)
  • PQerrorMessage() デフォルトの現在のデフォルト動作は後者の動作で、エラー時のみ CONTEXT を出力します。この調整のために新たな関数 PQsetErrorContextVisibility() を使用できます。

  • libpq で別の冗長レベルでのエラーメッセージ再生成に対応しました。 (Alex Shulgin) (9.6)
  • これは新たな関数 PQresultVerboseErrorMessage() で実行されます。psql の 新機能 errverbose の実現に使われています。

  • libpq の PQhost()関数がデフォルトの Unixソケット接続について有用なデータを返すように改良されました。 (Tom Lane) (9.6)
  • これまでは明示的にホスト指定が無い場合には NULL が返っていました。これからはデフォルトのソケットディレクトリパスを返します。

  • ecpg の字句解析器がプリプロセッサ命令の行においてコメント文字列内の改行を受け付けるように修正されました。 (Michael Meskes) (9.6)

クライアントアプリケーション

pg_dump
  • pg_dump、pg_restore に --strict-names オプションが追加されました。 (Pavel Stehule) (9.6)
  • 本オプションは -t、-n オプションに対して指定したオブジェクトが存在していないときにエラーを出して失敗させます。--strict-names 指定が無い場合(すなわち従来の動作)は、該当するオブジェクトが無い -t や -n の指定が含まれていても警告なしに実行されます。

    (t1テーブルは存在し、t2テーブルは存在しない場合)
    $ pg_dump --strict-names -d db1 -t t1 -t t2 > t12.dump
    pg_dump: no matching tables were found for pattern "t2"
    
  • pg_dump でシステムオブジェクトに対する権限割り当ての初期状態からの変更をダンプするようになりました。 (Stephen Frost) (9.6)
  • スーパーユーザはビルトインオブジェクトや拡張モジュールによるオブジェクトの権限割り当てを常に変更できる一方、これまでこれらの変更はダンプ・リロードで失われていました。これからは pg_dump がこれらの変更を認識し、ダンプするようになります。

    なお、これはバージョン 9.6 以降のサーバに対してのみ機能します。

  • pg_dump が拡張モジュールに所属するスキーマ内にある拡張モジュールに所属しないオブジェクトだけダンプできるようになりました。 (Martín Marqués) (9.6)
  • これまではこのようなオブジェクトは拡張モジュールに属すると判断されて無視されていました。

  • pg_dump で対応するテーブルが一意に決まるオブジェクトタイプについて、オブジェクトタグにテーブル名を含めるようになりました。 (Peter Eisentraut) (9.6)
  • 以下のように Name: が「テーブル名 オブジェクト名」になっています。

    (ダンプ出力の一部)
    --
    -- Name: t1 t1_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
    --
    
    ALTER TABLE ONLY t1
        ADD CONSTRAINT t1_pkey PRIMARY KEY (id);
    
psql
  • psql が複数の -c、-f オプションに対応しました。 (Pavel Stehule, Catalin Iacob) (9.6)
  • 複数のコマンドやスクリプトファイルを指定すると、一つの接続の中でオプションが与えられた順(左から順)に実行されます。

    (実行例)
    $ echo 'SELECT $$script$$' > script.sql
    $ psql -c 'BEGIN' -f script.sql -c 'COMMIT' db1
    BEGIN
     ?column?
    ----------
     script
    (1 row)
    
    COMMIT
    $
    
  • psql にクロス表形式で問い合わせ結果を表示する crosstabview コマンドが追加されました。 (Daniel Vérité) (9.6)
  • 以下のように使用することができます。

    db1=# SELECT cat1, cat2, to_char(sum(sales),'9,999,999')
          FROM tsales GROUP BY cat1, cat2;
     cat1 |    cat2    |  to_char
    ------+------------+------------
     支店 | 通常期間   |  2,168,062
     本店 | セール期間 |    563,499
     本店 | 通常期間   |    906,981
     支店 | セール期間 |  1,344,994
    (4 rows)
    
    db1=# crosstabview
     cat1 |  通常期間  | セール期間
    ------+------------+------------
     支店 |  2,168,062 |  1,344,994
     本店 |    906,981 |    563,499
    (2 rows)
    
  • psql に最後のサーバエラーを冗長に表示する errverbose コマンドが追加されました。 (Alex Shulgin) (9.6)
  • 本コマンドで予期せぬエラーを受けた後から VERBOSITY変数を verbose 設定したのと同様のエラーメッセージを取得できます。以下のように動作します。

    db1=# SELECT * FROM t1;
    ERROR:  relation "t1" does not exist
    LINE 1: SELECT * FROM t1;
                          ^
    db1=# errverbose
    ERROR:  42P01: relation "t1" does not exist
    LINE 1: SELECT * FROM t1;
                          ^
    LOCATION:  parserOpenTable, parse_relation.c:1159
    
  • psql にビュー定義を編集、参照する evコマンド、svコマンド が追加されました。 (Petr Korobeinikov) (9.6)
  • 関数における ef コマンド、sf コマンドとの相似になっています。

  • psql に gexec コマンドが追加されました。 (Corey Huinker) (9.6)
  • 前回の問い合わせ結果を新たな問い合わせとして実行します。以下のように使用することができます。

    db1=# SELECT format('DROP TABLE %I', table_name)
          FROM information_schema.tables WHERE table_schema = 'public';
               format
    -----------------------------
     DROP TABLE pgbench_history
     DROP TABLE pgbench_tellers
     DROP TABLE pgbench_branches
     DROP TABLE pgbench_accounts
    (4 rows)
    
    db1=# gexec
    DROP TABLE
    DROP TABLE
    DROP TABLE
    DROP TABLE
    
  • psql で C コマンドと一貫性を持たせるため、「pset C 文字列」にて「pset title 文字列」と同様にテーブルタイトルを設定できるようになりました。 (Bruce Momjian) (9.6)
  • psql の pset expanded auto モードで、1列だけの問い合わせ結果には、たとえ出力が画面幅より広くとも、拡張形式を使わないようになりました。 (Andreas Karlsson, Robert Haas) (9.6)
  • psql の watch コマンドによるヘッダ出力が改善されました。 (Michael Paquier, Tom Lane) (9.6)
  • 設定されていたなら pset title の文字列を含むようになります。タイムスタンプになるヘッダの前段部分が短くなりました。また、タイムスペースフォーマットが psql のロケール環境に従うようになりました。

    (出力例)
    $ LANG=ja_JP.UTF-8 psql -q db1
    db1=# pset title my_watch_title
    Title is "my_watch_title".
    db1=# SELECT random();
      my_watch_title
          random
    -------------------
     0.643378943670541
    (1 row)
    
    db1=# watch 5
    my_watch_title  2016年09月13日 13時53分34秒 (every 5s)
    
          random
    -------------------
     0.167425051797181
    (1 row)
    
  • 現在行だけでなく入力された問い合わせ全体を考慮するように Tab補完ロジックが改善されました。 (Tom Lane) (9.6)
  • これまでは複数行に分かれたコマンドでは、前の行を見なければいけないTab補完規則が無効になっていました。

    (9.6 では以下のように複数行でも Tab補完が効きます)
    db1=# SELECT * FROM pg_user
    db1-# WHERE u
    usebypassrls  usecreatedb   userepl       usesysid
    useconfig     usename       usesuper
    
  • psql の Tab補完に様々な細かな改善が適用されました。 (Peter Eisentraut, Vik Fearing, Kevin Grittner, Kyotaro Horiguchi, Jeff Janes, Andreas Karlsson, Fujii Masao, Thomas Munro, Masahiko Sawada, Pavel Stehule) (9.6)
  • CREATE SEQUENCE、 CREATE LABEL、 CREATE/DROP INDEX CONCURRENTLY、CREATE EXTENSION、 GRANT / REVOKE、 COPY、 REFRESH MATERIALIZED VIEW、ALTER .. SET/RESET、 CREATE/ALTER FOREIGN DATA WRAPPER、CREATE/ALTER SERVER、 CREATE/ALTER USER MAPPING の Tab補完が修正されています。

  • psql の特別変数 PROMPT に接続先バックエンドのプロセスID が挿入されるオプション %p が追加されました。 (Julien Rouhaud) (9.6)
  • 常に、あるいは、非エラーメッセージに限って、メッセージの CONTEXT欄を表示しないようにできるようになりました。 (Pavel Stehule) (9.6)
  • エラー時にのみ CONTEXT欄を表示するのが現在のデフォルトの振る舞いです。特別変数 SHOW_CONTEXT を設定することで、これを変更できるようになりました。

  • psql の df+ が関数アクセス権限とパラレル安全性属性を表示するようになりました。 (Michael Paquier) (9.6)
pgbench
  • pgbenchスクリプト内のSQLコマンドは改行ではなく、セミコロン(;)で終える仕様になりました。 (Kyotaro Horiguchi, Tom Lane) (9.6)
  • 本変更によりスクリプトに複数行からなる SQLコマンドを記述できます。既存の pgbenchスクリプトは行末にセミコロンが無ければ加える修正が必要です。なお、各行の SQLコマンドがセミコロンで終了していても旧来バージョンで動作します。

  • pgbench のバックスラッシュコマンドの式でいくつかのビルトイン関数、および、浮動小数点演算に対応しました。 (Fabien Coelho) (9.6)
  • ビルトイン関数は pgbenchスクリプトのバックスラッシュコマンド専用のもので、同名のSQL関数とは別物です(例えば random() は 2引数を取り整数を返します)。様々な乱数生成に役立つ関数、任意メッセージ出力をする関数が含まれます。

  • pgbenchスクリプトで setrandom が廃止されました。ビルトイン関数で置き換えられます。 (Fabien Coelho) (9.6)
  • 新たなビルトイン関数に random()、random_exponential()、random_gaussian() が含まれ、setrandom と同様のことができます。複雑な式に埋め込むことができることから、より使いやすくなっています。

    (9.5.x までの書き方例)
    setrandom rid 1 10000
    setrandom slp 1 10 exponential 3.0
    sleep :slp ms
    UPDATE t1 SET ts = now() WHERE id = :rid ;
    
    (9.6.x からの書き方例)
    set rid random(1, 10000)
    set slp random_exponential(1, 10, 3.0)
    sleep :slp ms
    UPDATE t1 SET ts = now() WHERE id = :rid ;
    
  • pgbench でカスタムスクリプトだけでなく、ビルトインスクリプトの複数コピーを実行できるようになりました。 (Fabien Coelho) (9.6)
  • 新たな -b オプションで以下のようにビルトインスクリプトをカスタムスクリプトのように複数指定することができます。-b では tpcb-like、select-only、simple-update の三種類が指定できます。

    $ pgbench -n -c 10 -t 500 -b tpcb-like -b select-only -b simple-update 
              -f custom_script1.sql -f custom_script2.sql db1
    
  • pgbench でスクリプトの選択率(重みづけ)を調整できるようになりました。 (Fabien Coelho) (9.6)
  • 複数のスクリプトが指定されているとき、各pgbench トランザクションは実行するものをランダムに一つを選択します。これまでは常に均一な確率でしたが、これからは各々に異なる選択率を指定できます。

    以下のように -f、-b オプションの後に @数値 で重みづけを指定します。

    (二つのビルトインスクリプトは 1対9 の割合で実行されます)
    $ pgbench -n -c 10 -t 50 -b tpcb-like@1 -b select-only@9 db1
    
    (二つのカスタムスクリプトは 15対85 の割合で実行されます)
    $ pgbench -n -c 10 -t 50 -f script1.sql@15 -f script2.sql@85 db1
    
  • pgbench で複数のスクリプトを走らせているとき、各スクリプトの統計を集めるようになりました。 (Fabien Coelho) (9.6)
  • 以下のようにスクリプト毎の報告を得ることができます。

    $ pgbench -c 5 -t 10 -n -f script1.sql -f script2.sql db1
    transaction type: multiple scripts
    scaling factor: 1
    query mode: simple
    number of clients: 5
    number of threads: 1
    number of transactions per client: 10
    number of transactions actually processed: 50/50
    latency average: 0.000 ms
    tps = 221.703928 (including connections establishing)
    tps = 227.219227 (excluding connections establishing)
    SQL script 1: script1.sql
     - weight = 1 (targets 50.0% of total)
     - 25 transactions (50.0% of total, tps = 110.851964)
     - latency average = 16.467 ms
     - latency stddev = 4.817 ms
    SQL script 2: script2.sql
     - weight = 1 (targets 50.0% of total)
     - 25 transactions (50.0% of total, tps = 110.851964)
     - latency average = 17.521 ms
     - latency stddev = 3.022 ms
    
  • pgbench に 開始時からの時間ではなく Unixエポックタイムスタンプで進捗を報告する --progress-timestamp オプションが追加されました。 (Fabien Coelho) (9.6)
  • pgbench でクラアント接続数 (-c) がスレッド数 (-j) の正確な倍数でなくてもよくなりました。 (Fabien Coelho) (9.6)
  • クライアント接続数はできる限り各スレッドに等分されるという振る舞いになります。

  • pgbench で -T オプションが使われたとき、指定時点で強制停止するようになりました。 (Fabien Coelho) (9.6)
  • これまでは、低いトランザクションレートが指定されていると、指定時点よりも大幅に長く待つことがありました。

サーバアプリケーション

  • initdb の post-bootstrap 処理段階におけるエラー報告が改善されました。 (Tom Lane) (9.6)
  • これまでは、エラーが起きたところで、入力ファイル全体が失敗したクエリとして報告されました。これからは、当該のクエリだけが報告されます。この望ましい振る舞いを得るため、initdb の入力ファイルのクエリが空行で区切られました。

  • 一つのスタンドアローンバックエンドセッションを全ての post-bootstrap処理段階のために使うことで、initdb が高速化しました。 (Tom Lane) (9.6)
  • これまでは initdb の各サブルーチンがそれぞれスタンドアローンのバックエンドセッションを起動しており、この無駄を削減します。

  • ターゲットタイムラインが変わったときでも動作するようにpg_rewind が改良されました。 (Alexander Korotkov) (9.6)
  • これにより、例えば、昇格したスタンバイを旧マスタのタイムラインの状態に巻き戻すことができます。

ソースコード

  • 旧式の heap_formtuple/heap_modifytuple/heap_deformtuple 関数(内部関数) が削除されました。 (Peter Geoghegan) (9.6)
  • AllocSetContextCreate() をシンプルかつ安全に実行するマクロが追加されました。 (Tom Lane) (9.6)
  • 新たなマクロ ALLOCSET_DEFAULT_SIZES、ALLOCSET_SMALL_SIZES、ALLOCSET_START_SMALL_SIZES を使う方が推奨され、あるメモリコンテキストに対して個々にサイズ引数を記述することは、今後は非推奨となります。

    しかしながら、既存コードは未だ全て置き換えられていません。

  • ヘッダファイル内では無条件で static inline 関数を使うようになりました。 (Andres Freund) (9.6)
  • この書き方の変更により開発者がインライン関数をより容易に使うことができます。非常に古いコンパイラでは警告、および/または、無駄なコードスペースが生じるかもしれません。

  • TAPテスト基盤が改良されました。 (Michael Paquier, Craig Ringer, Álvaro Herrera, Stephen Frost) (9.6)
  • TAPテストの枠組みでリカバリシナリオをテストできるようになったほか、様々な改修が適用されています。

  • trace_lwlocks = on のとき、各ロックを名前で識別するようになりました。 (Robert Haas) (9.6)
  • なお、trace_lwlocks は、コンパイル時にLOCK_DEBUGマクロが定義された場合に使用できる、以前から存在する開発者むけ設定パラメータです。

  • psql のTab補完コードの基盤が改良されました。 (Thomas Munro, Michael Paquier) (9.6)
  • Tab補完規則がかなり書きやすくなり、また、コンパクトになりました。

  • pg_shseclabel が接続認証のアクセスで利用可能になるように、システムカタログ pg_shseclabel を RelationCache に持つようになりました。 (Adam Brightwell) (9.6)
  • 本体コードは pg_shseclabel を認証に使いませんが、authentication_hook を使う拡張モジュールで参照したいかもしれません。

  • インデックスアクセスメソッド(AM) API が C言語レベルの大部分を隠すように再構成されました。 (Alexander Korotkov, Andrew Gierth) (9.6)
  • インデックスAM API が、外部データラッパーやテーブルサンプルハンドラに採用している、必要な関数が列挙された構造体を使うデザインになりました。これにより、Cコードがシンプルになり、拡張モジュールとしてインデックスAMを定義することがより現実的となります。

    結果として、システムカタログpg_am の多くのカラムが廃止されました。これまで pg_am に在ったインデックスAMの属性をSQL問い合わせで調べることができる新たなシステムカタログ情報関数がいくつか追加されました。

  • システムカタログ pg_init_privs が追加されました。initdb や 拡張モジュール導入で作られるオブジェクトの当初の権限を保持します。 (Stephen Frost) (9.6)
  • これにより pg_dump がシステムオブジェクトの権限を変えている場合について、変更差分をダンプすることができます。これまで、このような変更はダンプとリロードで失われていましたが、今後は維持されます。

  • 拡張モジュールがカスタムLWLock を割り当てる方法が変更されました。 (Amit Kapila, Robert Haas) (9.6)
  • RequestAddinLWLocks() 関数は削除され、RequestNamedLWLockTranche() 関数で置き換えられます。これにより、カスタムLWLock の識別が改善され、間違いが起こりにくくなります。

  • 複数セッションが同時待機できるように分離テスターが改良され、デッドロックシナリオのテストができるようになりました。 (Robert Haas) (9.6)
  • 拡張可能なノードタイプが導入されました。 (KaiGai Kohei) (9.6)
  • これにより、FDW(外部データラッパ)やカスタムスキャン作成者は、これまでよりも便利な形式でプランツリーにデータを格納できます。

  • プランナが post-scan/join クエリ段階で、多数のアドホックなロジックに代えて、Path の生成・比較によって処理するようになりました。 (Tom Lane) (9.6)
  • 現時点では本変更で得られるユーザから見える改善は僅かです。しかし、古いコード構造上の取り組みでは現実的でなかった、将来の多数の上位プランナ改良を有効にします。

  • 部分的な集約に対応しました。 (David Rowley, Simon Riggs) (9.6)
  • 本変更で集約関数を分割して計算できるようになります。例えば、複数のパラレルワーカープロセスが協調して一つの集約を計算できます。

  • 汎用コマンド進捗報告の基盤が追加されました。 (Vinayak Pokale, Rahila Syed, Amit Langote, Robert Haas) (9.6)
  • VACUUMコマンドの進捗表示に本枠組みが使われています。

  • psql の flex 字句解析器が他のクライアントプログラムから使えるように切り出しされました。 (Tom Lane, Kyotaro Horiguchi) (9.6)
  • これにより、コマンド境界を識別できるだけの SQLコマンド解析を要するプログラムからコード重複を削減します。

    新たなソースコードサブディレクトリ src/fe_utils が作られ、クライアントプログラムで共用されるコードが含まれます。これまでは、シンボリックリンクやビルド時のソースファイルコピーでコード共有を実現していました。

  • 通常は一つの待機から次に変化しないイベントセットを効率的に待機できるwaitEventSet API が 導入されました。 (Andres Freund, Amit Kapila) (9.6)
  • WALレコードを書き込む汎用インタフェースが追加されました。 (Alexander Korotkov, Petr Jelínek, Markus Nullmeier) (9.6)
  • これにより、拡張モジュールがページ変更内容を標準形式にて WALレコードに書くことができます。拡張モジュールにアクセスすることなしにWAL再生しなければいけない問題には、汎用再生コードで対応します。

    これにより、拡張モジュールで WAL書き込み対応した新たなインデックスアクセスメソッドを実装することができます。

  • ロジカルデコーディングむけに汎用WALメッセージがサポートされました。 (Petr Jelínek, Andres Freund) (9.6)
  • この機能により、拡張モジュールが WAL に任意データを書き込み、ロジカルデコーディングプラグインから読ませることができます。これを実現する pg_logical_emit_message() 関数が追加されました。

    なお、この汎用WALメッセージは物理データのリカバリには関係しません。

  • SP-GiST演算子クラスがインデックスを下るときに任意の横断値(traversalValue)を格納できるようになりました。 (Alexander Lebedev, Teodor Sigaev) (9.6)
  • 従来からある再構築された値(reconstructedValue)と似ていますが、traversalValue は任意の量のデータを置けてインデックス列とデータ型が同じである必要もありません。

  • ereport() に LOG_SERVER_ONLY メッセージレベルが追加されました。 (David Steele) (9.6)
  • 本レベルはメッセージが決してクライアントに送られない点を除き、LOG のように動作します。監査等の用途で使うためのものです。

  • 全ての生成されるヘッダファイルをビルドする Makefileターゲットsubmake-generated-headers が用意されました。 (Michael Paquier, Tom Lane) (9.6)
  • これは単独でビルドされるかもしれないサブディレクトリで便利です。

  • OpenSSL 1.1.0 がサポートされました。 (Andreas Karlsson, Heikki Linnakangas) (9.6)

追加モジュール

  • contrib/auto_explain に設定パラメータ auto_explain.sample_rate が追加されました。 (Craig Ringer, Julien Rouhaud) (9.6)
  • 問い合わせのうち設定した割合だけを捕捉するようにできます。これにより、平均的には有用な情報が採取できる一方、問い合わせ量が多いときのオーバーヘッドを軽減できます。

  • ブルームフィルタに基づくインデックスアクセスメソッドを実装するcontrib/bloom 拡張モジュールが追加されました。 (Teodor Sigaev, Alexander Korotkov) (9.6)
  • これは主として、標準で含まれないインデックスアクセスメソッドを追加することの概念実証のためのものです。しかしながら、多数の列を検索する問い合わせには、本インデックスの機能自体が役立つかもしれません。

  • contrib/cube でcube型のための距離演算子が追加されました。 (Stas Kelvich) (9.6)
  • cube型列へのGiSTインデックスでの k最近傍(kNN)検索もサポートされました。

  • contrib/hstore の hstore_to_jsonb_loose()関数と hstore_to_json_loose()関数が、何が数値かについて一致するようになりました。 (Tom Lane) (9.6)
  • これまでは、hstore_to_jsonb_loose() は数値に見える文字列を、たとえ JSON の数値の文法仕様に正確には一致していなくとも JSON の数値に変換していました。

    hstore_to_jsonb_loose() の振る舞いが修正され、hstore_to_json_loose() と一致するようになりました。互換性のない変更点と言えます。

    (9.5.x での動作)
    db1=# SELECT hstore_to_jsonb_loose('a=>-01'::hstore);
     hstore_to_jsonb_loose
    -----------------------
     {"a": -1}
    (1 row)
    
    db1=# SELECT hstore_to_json_loose('a=>-01'::hstore);
     hstore_to_json_loose
    ----------------------
     {"a": "-01"}
    (1 row)
    
    (9.6 での動作)
    db1=# SELECT hstore_to_jsonb_loose('a=>-01'::hstore);
     hstore_to_jsonb_loose
    -----------------------
     {"a": "-01"}
    (1 row)
    
  • contrib/intarray にて、配列要素の重なりを判定する演算子を使う問い合わせのプランを改善するため、選択度を見積もる関数が追加されました。 (Yury Zhuravlev, Alexander Korotkov) (9.6)
  • contrib/pageinspect の heap_page_items() 関数が各タプルの生データを表示するようになりました。 (Nikolay Shaplov) (9.6)
  • heap_page_items() 関数の出力に t_dataカラムが追加されています。また、個別のタプルフィールドを調べるための新たな関数 tuple_data_split()、heap_page_item_attrs() が追加されました。

    (3カラムを持つ t1 テーブルのタプル生データをフィールド区切り付きで出力する例)
    
    db1=# SELECT * FROM heap_page_item_attrs(get_raw_page('t1',0), 't1');
     lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid |                                 t_attrs
    ----+--------+----------+--------+--------+--------+----------+--------+-------------+------------+--------+--------+-------+-------------------------------------------------------------------------
      1 |   8144 |        1 |     48 |  31720 |      0 |        0 | (0,1)  |           3 |       2050 |     24 |        |       | {"\x01000000","\x0d48454c4c4f","\xc08a627ffcde0100"}
      2 |   8088 |        1 |     56 |  31721 |      0 |        0 | (0,2)  |           3 |       2050 |     24 |        |       | {"\x02000000","\x1d5468697320697320546573742e","\xc09cdc7ffcde0100"}
    (2 rows)
    
  • contrib/pgcrypto の pgp_sym_encrypt() 関数に S2Kイテレーションカウントのオプションパラメータが追加されました。 (Jeff Janes) (9.6)
  • contrib/pg_trgm が単語類似度に対応し、新たな関数と演算子が追加されました。 (Alexander Korotkov, Artur Zakirov) (9.6)
  • ある文字列と、複数語を含む文字列の中の最も類似した単語との類似度を返します。

  • contrib/pg_trgm の類似度閾値を指定する設定パラメータpg_trgm.similarity_threshold が追加されました。 (Artur Zakirov) (9.6)
  • この閾値はこれまでも調整可能でしたが、専用の関数 set_limit()、show_limit()を使って指定するものとなっていました。これらの関数は今後は非推奨となります。

  • contrib/pg_trgm の GIN 演算子クラスが、よくあるキーと稀なキーが両方あらわれる場合にインデックス検索が性能向上するように改善されました。 (Jeff Janes) (9.6)
  • contrib/pg_trgm の GIN インデックスで類似度検索の性能が改善されました。 (Christophe Fornaroli) (9.6)
  • テーブルのビジビリティマップを調査する contrib/pg_visibility 拡張モジュールが追加されました。 (Robert Haas) (9.6)
  • 既存のビジビリティマップを破棄する関数も含まれています。

  • contrib/sslinfo に ssl_extension_info() 関数が追加されました。 (Dmitry Voronin) (9.6)
  • 現在の接続にある X509クライアント証明書の拡張情報(拡張名、値、クリティカルであるか)を出力します。

postgres_fdw
  • 外部サーバのオプションにホワイトリストとして拡張モジュールを指定することで、拡張モジュールで提供される関数や演算子もリモート実行できるようになりました。 (Paul Ramsey) (9.6)
  • 以下に pgcrypto の関数をリモートで実行させる例を示します。

    (両サーバに pgcrypto を導入)
    remote=# CREATE EXTENSION pgcrypto;
    local=# CREATE EXTENSION pgcrypto;
    
    (デフォルトではローカルで関数を実行するプランになる)
    local=# explain SELECT id FROM remote.t1 WHERE digest(c1, 'sha1') = 'xbd564db5d5cc358eb0e3523d3e03041739f230d5';
                                             QUERY PLAN                             
    --------------------------------------------------------------------------------------------
     Foreign Scan on t1  (cost=100.00..212.38 rows=15 width=4)
       Filter: (digest(c1, 'sha1'::text) = 'xbd564db5d5cc358eb0e3523d3e03041739f230d5'::bytea)
    (2 rows)
    
    (サーバオプションに指定を追加)
    local=# ALTER SERVER server1 OPTIONS (ADD extensions 'pgcrypto');
    
    (リモートで関数を実行するプランになる)
    local=# explain SELECT id FROM remote.t1 WHERE digest(c1, 'sha1') = 'xbd564db5d5cc358eb0e3523d3e03041739f230d5';
                            QUERY PLAN
    -----------------------------------------------------------
     Foreign Scan on t1  (cost=100.00..154.18 rows=15 width=4)
    (1 row)
    
  • リモートサーバでのソートを考慮するようになりました。 (Ashutosh Bapat) (9.6)
  • これまではリモートサーバ側のみでソートできる場合でも、ローカルでソートが行われていました。

  • リモートサーバでの結合を考慮するようになりました。 (Shigeru Hanada, Ashutosh Bapat) (9.6)
  • これまでは同一リモートサーバ上のリモートテーブル同士の結合であっても、テーブル毎に SELECT を実行して、ローカルで結合処理を行っていました。9.6 では可能であればテーブル結合をリモートサーバ上で行います。

  • 可能なときには UPDATE や DELETE を完全にリモートサーバ側だけで実行するようになりました。 (Etsuro Fujita) (9.6)
  • これまでは、リモート更新は SELECT ... FOR UPDATE コマンドの送信をして、選択された行を一つずつ更新したり削除する必要がありました。何らかローカル処理が必要な場合には依然として上記の手順が必要ですが、そうでなければリモートだけで実行します。

    (これはリモート側で単に下記の通りの SQL が実行されます)
    DELETE FROM remote_table WHERE id IN (101, 102, 103);
    
    (これはローカルデータを参照するので SELECT ... FOR UPDATE と 1行ずつの DELETE が必要です)
    DELETE FROM remote_table WHERE id IN (SELECT id FROM local_table);
    
  • サーバオプションやテーブルオプションでフェッチサイズ(1回のデータ取得サイズ)を指定できるようになりました。 (Corey Huinker) (9.6)
  • これまではリモート問い合わせで常に1回に100行ずつ取得していましたが、調整可能になります。

  • 複数ローカルユーザが単一のリモートユーザにマップされているときに、単一の外部サーバ接続を再利用するようになりました。 (Ashutosh Bapat) (9.6)
  • なお、当然のことながら、一つのローカルセッション内での再利用となります。

  • リモートサーバに問い合わせキャンセルを伝播させるようになりました。 (Michael Paquier) (9.6)
  • これまではローカルで問い合わせキャンセルの指令を受けても、既に送信したリモート問い合わせに対しては何もしませんでした。