PostgreSQL 11 に関する技術情報

このページでは PostgreSQL 11(2018/10/18リリース) に関する技術情報をお届けします。
本ドキュメントは PostgreSQL のリリースノートを元に弊社で解説を加えたものです。

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

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

  • ハッシュキーによるパーティショニングが可能になりました。
  • パーティションテーブルに対して主キー制約、外部キー制約、インデックスそしてトリガーを作成できるようになりました。
  • どのパーティションにもマッチしないデータ用にデフォルトパーティションの作成が可能になりました。
  • パーティションキー列に対する更新を行った際にそれの影響を受けるレコードも適切なパーティションに移動されるようになりました。
  • パーティションテーブルに対する SELECT のパフォーマンスが向上しました。
  • B-tree インデックスを作成する CREATE INDEX 文で並列処理を行えるようになりました。
  • 並列化が CREATE TABLE … AS、CREATE MATERIALIZED VIEW、そして UNION を使用する一定のクエリで可能となりました。
  • ハッシュ結合とシーケンシャルスキャンの並列処理のパフォーマンスが向上しました。
  • ストアドプロシージャ内でトランザクション制御が可能になりました。
  • JIT コンパイルの使用が可能になりました。
  • SQL:2011 標準で定められているすべてのウィンドウ関数が使用できるようになりました。
  • カバーリングインデックスを CREATE INDEX 時に INCLUDE 句を使用することで作成可能になりました。

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

    • pg_dump がデータベース内容のみならずデータベース属性をダンプするようになりました。 (Haribabu Kommi) (11)

従来は、データベースに対する GRANT / REVOKE や ALTER DATABASE SET … での設定などのデータベース属性は pg_dumpall でのみダンプされていました。これからは、pg_dump --createpg_restore --create で、これらのデータベース属性もダンプされリストアされます。

一方で、pg_dumpall -g はロールとテーブルスペース関連の属性のみをダンプするようになります。-g を付けない pg_dumpall の動作には変更ありません。

また、--create を付けない pg_dump と pg_restore はデータベース単位のコメントやセキュリティラベルはダンプ、リストアしなくなります。これらは今後はデータベースの属性として扱われます。

加えて、pg_dumpall は必ず元のロケールとエンコーディングでデータベースを作るようになりました。そのため、リストア先システムでそのロケールやエンコーディングが使えないとエラーになります。従来は、ロケールとエンコーディングがダンプ取得元データベースクラスタのデフォルトに一致していた場合、指定なしの CREATE DATABASE を出力していました。

    • 関数と列参照のあいまいさを解消するときに構文形式を優先するようになりました。 (Tom Lane) (11)

xがテーブル名または複合型で、fがその要素であるとき、PostgreSQLは伝統的に f(x) と x.f を等価とみなしていました。

例:
 db=# CREATE TABLE x (f int);
 db=# INSERT INTO x VALUES (10);
 db=# SELECT f(x) FROM x;
  f
 ----
  10
 (1 row)

このことで、関数fを書いてこれをオンデマンドで計算される列であるかのように使う小細工ができました。なお、両方の解釈が有効な場合、列の解釈が常に選ばれました。

これからはこのような曖昧さがあった場合、構文形式に一致する方(すなわちf(int)関数があるならf(x)は関数)に解釈されます。また、xテーブルにf列があるときに、関数f(x)の作成が下記のエラーになる制限は廃止されました。

 db=# CREATE FUNCTION f(x int) RETURNS int LANGUAGE sql AS $$ SELECT 1; $$;
 ERROR:  "f" is already an attribute of type x
    • テーブルとドメインの制約名について唯一性を完全に強制するようになりました。 (Tom Lane) (11)

PostgreSQLはテーブルの制約名が各々異なることを想定しています。ドメインの制約についても同様です。しかしながら、従来は厳密な強制ではなく、手順によっては重複した名前を作れてしまう可能性がありました。

報告された同一制約名が生じる例:
 db=# CREATE TABLE t(c integer);
 db=# ALTER TABLE t ADD CONSTRAINT t_c_key CHECK(c > 1);
 db=# ALTER TABLE t ADD UNIQUE(c);
    • power(numeric, numeric) と power(float8, float8) が NaN 値の入力をPOSIX標準に従って扱えるようになりました。 (Tom Lane, Dang Minh Huong) (11)

POSIX では、NaN ^ 0 (NaN の 0乗)が 1、 1 ^ NaN (1 の NaN乗)が 1 であり、それ以外の全ての NaN 入力には NaN を返すべきとされています。これまで、numeric については NaN ^ 0 と 1 ^ NaN にも NaN を返していました。また、float8 については Cライブラリによって標準通りの動作になっていましたが、一部の古い Unixプラットフォームのライブラリではそうなっておらず、一部バージョンの Windows でも問題がありました。

    • to_number() 関数でテンプレート区切りがマッチしない場合に文字を消費する動作が防止されました。 (Oliver Ford) (11)

具体的には「SELECT to_number(‘1234’, ‘9,999’)」がこれまでは 134 を返していましたが、1234 を返すようになります。また、L(通貨記号) およびTH(序数接尾辞) は今後は、数字や正負記号、小数点、カンマ以外の文字のみを消費します。

    • to_date()、to_number() および to_timestamp() 関数が各テンプレート文字に対して文字単位で読み飛ばすように修正されました。 (Tom Lane) (11)

これまでは、テンプレート文字の各1バイトに対して1バイトを読み飛ばしていました。その結果、いずれかの文字列にマルチバイト文字が含まれていると奇妙な振る舞いが生じていました。

    • to_char()、to_number() および to_timestamp() のテンプレート文字列でダブルクォート内のバックスラッシュの扱いが変更されました。 (Tom Lane) (11)

これからはダブルクォート内のバックスラッシュはそれに続く文字(特にダブルクォートやバックスラッシュ)をエスケープします。従来もそのようになっていましたが不完全で一貫性に欠ける動作でした。

    • xmltable()、xpath() および、その他の XML処理関数で相対パス表現を正しく扱えるようになりました。 (Markus Winand) (11)

SQL標準では相対パスは入力XMLドキュメントのドキュメントノードから開始します。これらの関数ではこれまでルートノードから開始していました。

    • 拡張問い合わせプロトコルで statement_timeout が各 Executeメッセージに別々に適用されるようになりました。 (Tatsuo Ishii, Andres Freund) (11)

これまでは Sync メッセージの前の全コマンドに対してまとめて適用されていました。

    • pg_classシステムカタログから relhaspkey列が削除されました。 (Peter Eisentraut) (11)

プライマリキーを検査するアプリケーションは pg_index を調べてください。

    • pg_proc の列のproisagg と proiswindow が prokind に置き換えられました。 (Peter Eisentraut) (11)

この新たな列は関数、プロシージャ、集約関数、ウィンドウ関数をより明確に区別します。

    • 情報スキーマの列 table.table_type が「FOREIGN TABLE」に替わって「FOREIGN」を返すように修正されました。 (Peter Eisentraut) (11)

新たな出力が SQL標準に適合します。

    • psプロセス表示のバックグラウンドワーカに対するラベルが変更されました。 (Peter Eisentraut) (11)

pg_stat_activity.backend_type のラベルと一致するようになります。

    • ラージオブジェクトを読み書きするときではなく、オープンするときに権限検査が行われるようになりました。 (Tom Lane, Michael Paquier) (11)

書き込みアクセスが要求されて、書き込み不可である場合、これからはラージオブジェクトが書かれない場合でもエラーが生じます。

    • 非スーパーユーザが共有カタログのインデックス再作成をするのが防止されました。 (Michael Paquier, Robert Haas) (11)

これまではデータベース所有者も実行可能でしたが、これからは権限外とみなされます。

    • adminpack の非推奨関数 pg_file_read()、pg_file_length() およびpg_logfile_rotate() が削除されました。 (Stephen Frost) (11)

同等の関数が PostgreSQL本体に含まれています。導入済みの adminpack は ALTER EXTENSION … UPDATE でアップデートするまでは、これら関数を引き続き利用可能です。

    • ダブルクォートされたコマンドオプションの大文字小文字を尊重するようになりました。 (Daniel Gustafsson) (11)

これまではある種の SQLコマンドでのオプション名はダブルクォートで括られていても小文字に強制変換されました。そのため、例えば「”FillFactor”」(正しくは「fillfactor」)はストレージオプションとして受け入れられてきました。

これからはこのような場合にエラーとなります。

例: 下記は 10.x では通るけれども 11.x ではエラーとなる
db=# CREATE TABLE t17 (id int, v text) WITH ("FillFactor" = 90);
ERROR:  unrecognized parameter "FillFactor"
    • 設定パラメータ replacement_sort_tuples が廃止されました。 (Peter Geoghegan) (11)

置換選択法のソートはもはや役に立たないと判断されました。デフォルトのソートアルゴリズムに改良が加えられてきた結果、優位性が失われました。

    • CREATE FUNCTION の WITH句が廃止されました。 (Michael Paquier) (11)

伝統的にサポートされてきましたが、SQL標準に反する構文でした。WITH句で指定できる isStrict、isCachable は標準のオプションSTRICT 、IMMUTABLE と同じ意味です。

変更点

サーバ

パーティショニング
    • キー列のハッシュに基づくテーブルパーティションに対応しました。 (Amul Sul) (11)
    • パーティションテーブル上のインデックスに対応しました。 (Álvaro Herrera, Amit Langote) (11)

パーティションテーブル上のインデックスはパーティションテーブル全体にまたがる単一の物理インデックスではありません。むしろ、同様のインデックスを所属する各パーティションに作成するための雛形といえます。

パーティションキーがインデックス列セットの一部であるなら、そのパーティションインデックスを UNIQUE と宣言しても良いです。これはパーティションテーブル全体に対するユニーク制約として働きます。

新たなコマンド ALTER INDEX ATTACH PARTITION は、一つのパーティション上の既存インデックスを一致するパーティションテーブル全体のインデックスに関連付けます。以下のように各パーティションに対するインデックス作成を個別に行いたい場合に使用します。ダンプ出力で使われます。

ALTER TABLE ONLY t_log ADD CONSTRAINT t_log_pkey PRIMARY KEY (id); 
ALTER TABLE ONLY t_log_1 ADD CONSTRAINT t_log_1_pkey PRIMARY KEY (id);
ALTER TABLE ONLY t_log_2 ADD CONSTRAINT t_log_2_pkey PRIMARY KEY (id);
ALTER INDEX t_log_pkey ATTACH PARTITION t_log_1_pkey;
ALTER INDEX t_log_pkey ATTACH PARTITION t_log_2_pkey;
    • パーティションテーブルに対する外部キー制約に対応しました。 (Álvaro Herrera) (11)

ただし、パーティションテーブルを被参照テーブルとすることはできません。

例: t_log がパーティションテーブルである場合
db=# ALTER TABLE t_log_detail ADD FOREIGN KEY (id) REFERENCES t_log(id);
ERROR:  cannot reference partitioned table "t_log"
    • パーティションテーブルに対する FOR EACH ROW トリガに対応しました。 (Álvaro Herrera) (11)

パーティションテーブルにトリガを定義すると、属するパーティションおよび将来追加するパーティションに、自動的にトリガが定義されます。パーティションテーブルに対する遅延されたユニーク制約にも対応します。

    • パーティションテーブルはデフォルトパーティションを持てるようになりました。 (Jeevan Ladhe, Beena Emerson, Ashutosh Bapat, Rahila Syed, Robert Haas) (11)

デフォルトパーティションには他のパーティションに適合しない行が格納され、その格納に応じて適宜に検索されます。

    • パーティションキー列を変更する UPDATE文 が、パーティション間の行の移動を行うようになりました。 (Amit Khandekar) (11)

これまでは、別パーティションへの行の移動が必要となる UPDATE文はエラーになっていました。

    • パーティションテーブルに対する INSERT、UPDATE、COPY が適切に行を外部パーティションに送り出せるようになりました。 (Etsuro Fujita, Amit Langote) (11)

これは postgres_fdw 外部テーブルで対応されています。これまでは外部テーブルをパーティションとして加えることはできましたが、行の追加には対応していませんでした。

    • 問い合わせ処理における、より高速なパーティション除外が可能になりました。 (Amit Langote, David Rowley, Dilip Kumar) (11)

多数のパーティションを持つパーティションテーブルへのアクセスを高速化します。本動作をするかどうか調整する設定パラメータ enable_partition_pruning が新設されました。

    • 問い合わせの実行中にパーティション除外が可能になりました。 (David Rowley, Beena Emerson) (11)

これまではパーティション除外(constraint_exclusion設定によるもの)は専ら実行プラン作成時に行われていました。そのため、多数の結合がある場合やプリペアドクエリではパーティション除外が使えないことがありました。

    • パーティションテーブル同士の等価結合で、属するパーティション同士を直接結合させることができるようになりました。 (Ashutosh Bapat) (11)

この仕様はデフォルトでは無効となっていますが、新たな設定パラメータenable_partitionwise_join を変更して有効にできます。

    • パーティションテーブルに対する集約関数が各パーティションごとに処理して、その後その結果をマージできるようになりました。 (Jeevan Chalke, Ashutosh Bapat, Robert Haas) (11)

この仕様はデフォルトでは無効ですが、新たな設定パラメータenable_partitionwise_aggregate を変更して有効にできます。

  • postgres_fdw で集約をパーティションの外部テーブルにプッシュダウンできるようになりました。 (Jeevan Chalke) (11)
並列問い合わせ
    • Btreeインデックス作成をパラレル実行できるようになりました。 (Peter Geoghegan, Rushabh Lathia, Heikki Linnakangas) (11)

この動作は新たな設定パラメータ max_parallel_maintenance_workers の影響を受けます。

    • 共有ハッシュテーブルを使用して、ハッシュ結合をパラレル実行できるようになりました。 (Thomas Munro) (11)

新たな設定パラメータ enable_parallel_hash(デフォルト on)で制御されます。

    • UNION 下の各SELECT が(たとえ各SELECT内はパラレル実行できなくとも)パラレルに実行できるようになりました。 (Amit Khandekar, Robert Haas, Amul Sul) (11)

新たな設定パラメータ enable_parallel_append (デフォルト on)で制御されます。

    • パーティションスキャンがより効率的にパラレルワーカを使用できるようになりました。 (Amit Khandekar, Robert Haas, Amul Sul) (11)
    • LIMIT をパラレルワーカに渡せるようになりました。 (Robert Haas, Tom Lane) (11)

これにより、パラレルワーカが返す結果を減らすことができます。また、インデックススキャンが利用可能になります。

    • 1回だけ評価される問い合わせ(例えば以下SQLの副問い合わせ部分)や、ターゲットリスト内の関数のパラレル実行が可能になりました。 (Amit Kapila, Robert Haas) (11)
SELECT count(*) FROM t18a WHERE t18a.u = (SELECT max(t18b.u) FROM t18b);
    • 設定パラメータ parallel_leader_participation が追加されました。 (Thomas Munro) (11)

リーダープロセスも副プランを実行するかどうかを制御します。デフォルトは有効で、リーダープロセスも副プランを実行します。

    • CREATE TABLE … AS、SELECT INTO、CREATE MATERIALIZED VIEW のパラレル実行が可能になりました。 (Haribabu Kommi) (11)
    • 多数のパラレルワーカを使ったシーケンシャルスキャンの性能が改善されました。 (David Rowley) (11)
    • EXPLAIN にパラレルワーカのソート処理の報告が加わりました。 (Robert Haas, Tom Lane) (11)

これまでパラレル処理の場合にはソート方式や処理サイズが報告されませんでした。

インデックス
    • Btree インデックスに検索キーやユニーク制約の対象外の列を含めることができるようになりました。これらは index-only スキャンで参照されます。 (Anastasia Lubennikova, Alexander Korotkov, Teodor Sigaev) (11)

これによりカバーリングインデックス技法の実施が容易になります。本機能のために CREATE INDEX に新たに INCLUDE句が加わりました。Btreeをサポートしないデータ型の列であっても、含めることができます。

    • 単調増加のインデックス追加における性能が改善しました。 (Pavan Deolasee, Peter Geoghegan) (11)

インデックスを持つ自動発番のID列やタイムスタンプの列を含む行の追加が繰り返される場合に効果があります。

    • hashインデックスのスキャンの性能が改善されました。 (Ashutosh Sharma) (11)
    • hash、GiST、GIN のインデックスに対して述部ロックが追加されました。 (Shubham Barai) (11)

これによりserializableモードのトランザクションで直列化競合の可能性が減少します。

    • 式の値が不変である場合に、式インデックスに対する HOT(heap-only-tuple)更新が可能になりました。 (Konstantin Knizhnik) (11)

本動作のために CREATE INDEX の WITH句で指定する新たなパラメータrecheck_on_update が追加されました。

例:以下のようにインデックス式の値は変わらない UPDATE で HOT を効かします
 db=# CREATE TABLE t28 (id int, j json);
 db=# CREATE INDEX ON t28 ((j->>'name')) WITH (recheck_on_update = off);
 db=# INSERT INTO t28 VALUES (1, '{"name": "john", "data": "AAA"}');
 db=# UPDATE t28 SET j = '{"name": "john", "data": "BBB"}' WHERE id = 1;
 db=# UPDATE t28 SET j = '{"name": "john", "data": "CCC"}' WHERE id = 1;
    • SP-GiSTインデックスが働く先頭一致の演算子 text ^@ text が追加されました。 (Ildus Kurbangaliev) (11)

これは btreeインデックスで var LIKE ‘word%’ とするのと似ていますが、より効率的です。

    • SP-GiSTで polygon型にインデックス付けが可能になりました。 (Nikita Glukhov, Alexander Korotkov) (11)
    • SP-GiST でリーフキーの lossy表現が使用できるようになりました。 (Teodor Sigaev, Heikki Linnakangas, Alexander Korotkov, Nikita Glukhov) (11)

SP-GiST のインデックスを実装するための API にオプション項目が追加されています。

オプティマイザ(プランナ)
  • ANALYZE処理にてプランナ統計情報の最頻値の選択方法が改善されました。 (Jeff Janes, Dean Rasheed) (11)

これまでは、最頻値(most common values、MCVs)を全ての列値と比較した頻度に基づいて特定していました。
これからは、MCVs でない値と比較した頻度に基づいて MCVs を選択します。
これは、一様な分布と一様でない分布の両方に対してアルゴリズムの頑健さを改善します。

  • >= と <= の選択率の見積が改善されました。 (Tom Lane) (11)

これまでは比較する定数が最頻値でない限り、 < と > と同じ選択率の見積が使われていました。この変更は特に小さい範囲に対する BETWEEN を伴う問い合わせで役立ちます。

  • プランナが「var = var」を同等の「var IS NOT NULL」に変換するようになりました。 (Tom Lane) (11)

これにより選択率の見積が改善します。

  • EXISTS と NOT EXISTS の問い合わせでプランナの行数見積が改善しました。 (Tom Lane) (11)
  • プランナが HAVING句の評価コストと選択率を考慮するようになりました。 (Tom Lane) (11)
性能
    • 実行速度を改善する問い合わせプランの一部に対する JIT(Just-in-Time)コンパイルが追加されました。 (Andres Freund) (11)

本機能を有効にするには LLVM が必要です。今のところビルド時も、設定パラメータも、デフォルトでは無効になっています。以下の新たな設定パラメータが追加されています。

 jit = off
 jit_provider = 'llvmjit'
 jit_above_cost = 100000
 jit_inline_above_cost = 500000
 jit_optimize_above_cost = 500000
    • ビットマップスキャンで可能なら index-onlyスキャンができるようになりました。 (Alexander Kuzmenkov) (11)
    • VACUUM中にフリースペースマップを更新するようになりました。 (Claudio Freire) (11)

これによりフリースペースがより早く再利用可能になります。

    • VACUUMが不要なインデックススキャンを回避できるようになりました。 (Masahiko Sawada, Alexander Korotkov) (11)

更新されていないテーブル/インデックスに対する VACUUM を効率化します。

    • 同時実行トランザクションのコミットの性能が改善されました。 (Amit Kapila) (11)
    • ターゲットリストに複数行を返す関数を使った問い合わせで、メモリ使用量が減りました。 (Andres Freund) (11)

以下のような形状の SELECT文が該当します。

 db1=# CREATE TABLE t41 (id int, arr int[]);
 db1=# INSERT INTO t41 VALUES (1, '{1,2,3}'), (2, '{2,4,6}');
 db1=# SELECT id, unnest(arr) FROM t41;
  id | unnest
 ----+--------
   1 |      1
   1 |      2
   1 |      3
   2 |      2
   2 |      4
   2 |      6
 (6 rows)
    • 集約計算の速度が改善されました。 (Andres Freund) (11)
    • postgres_fdw が結合を伴う UPDATE と DELETE を外部サーバにプッシュできるようになりました。 (Etsuro Fujita) (11)
    • Windows でラージページに対応しました。 (Takayuki Tsunakawa, Thomas Munro) (11)

設定パラメータ huge_pages で制御されます。

モニタリング
    • 設定パラメータlog_statement_stats、log_parser_stats、log_planner_stats、log_executor_stats によるログ出力でメモリ使用量を報告するようになりました。 (Justin Pryzby, Peter Eisentraut) (11)
    • pg_stat_activity に backend_type列が追加されました。バックエンドワーカのタイプを表示します。 (Peter Eisentraut) (11)
    • 設定パラメータ log_autovacuum_min_duration によるログ出力で、同時実行処理にて削除されて読み飛ばされたテーブルを報告するようになりました。 (Nathan Bossart) (11)
例:
WARNING:  skipping vacuum of "t47" --- relation no longer exists
    • テーブル制約とトリガに関連した information_schema の列のサポートが追加されました。 (Peter Eisentraut) (11)

具体的には以下の列が有効になりました。これまでは列は存在していましたが常に null でした。

 triggers.action_order
 triggers.action_reference_old_table
 triggers.action_reference_new_table

また、以下の列が追加されました。今のところ値は常に ‘YES’ です。

 table_constraints.enforced
認証
    • LDAP認証において、search+bindモードでより複雑な指定が可能になりました。 (Thomas Munro) (11)

具体的には、ldapsearchfilterオプションで LDAP属性の組み合わせを使ったパターンマッチングが可能になりました。

    • LDAP認証で暗号化LDAPが利用可能になりました。 (Thomas Munro) (11)

ldaptls=1 オプションにて LDAP over TLS は既にサポートされていましたが、これに加えて暗号化LDAPのための新たな TLS LDAP方式に対応しました。ldapscheme=ldaps または ldapurl=ldaps://… と指定して使用します。

  • LDAP認証エラーのログ出力が改善されました。 (Thomas Munro) (11)
パーミッション
    • ファイルシステムにアクセスできるデフォルトロールが追加されました。 (Stephen Frost) (11)

具体的には新たなロールは以下です。

 pg_read_server_files
 pg_write_server_files
 pg_execute_server_program

これらのロールは、サーバサイドの COPY や file_fdw 拡張が使えるかどうかの制御にも使われます。これまではスーパーユーザのみがこれら機能を使用できました。11.0 でもデフォルトの振る舞いとしてはそのようになっています。

    • ファイルシステムにアクセスする関数の使用可否の制御に、スーパーユーザであるかの検査ではなく、GRANT/REVOKE を使うようになりました。 (Stephen Frost) (11)

具体的には以下の関数について変更されました。

 pg_ls_dir()
 pg_read_file()
 pg_read_binary_file()
 pg_stat_file()
    • lo_import()、lo_export() の使用可否の制御に GRANT/REVOKE を使うようになりました。 (Michael Paquier, Tom Lane) (11)

これまではスーパーユーザのみがこれらの関数を使用できました。コンパイル時のオプションALLOW_DANGEROUS_LO_FUNCTIONS は廃止されました。

    • postgres_fdw の外部テーブルへのパスワードによらないアクセスを防止しようとするとき、接続ユーザではなく、ビュー所有者ユーザで判定するようになりました。 (Robert Haas) (11)

PostgreSQLではスーパーユーザのみが postgres_fdw の外部テーブルにパスワード無しのアクセス(peer認証など)が可能となっています。これまでは、このようなアクセスをするために接続ユーザがスーパーユーザである必要がありました。これからは、ビューを通して外部テーブルにアクセスしている場合については、ビュー所有者がスーパーユーザであるか検査されます。

    • ビューに対する SELECT FOR UPDATE における無効なロック権限検査が修正されました。 (Tom Lane) (11)

SELECT FOR UPDATE には UPDATE権限が必要ですが、入れ子になったビューにおいて権限検査の取りこぼしがありました。非互換動作を起こしうるのでメジャーバージョンアップで修正されました。

設定
    • 設定パラメータ ssl_passphrase_command が追加されました。SSLキーファイルのパスフレーズを供給するコマンドを指定します。 (Peter Eisentraut) (11)

また、設定パラメータ ssl_passphrase_command_supports_reload も追加されました。サーバ設定がリロードされたときに、SSL設定をリロードして ssl_passphrase_command を呼び出すかどうかを指定します。

    • ストレージパラメータ toast_tuple_target が追加されました。これにより TOAST格納を考慮する最小タプル長を制御することができます。 (Simon Riggs) (11)

デフォルトの TOAST閾値は従来通り(ページサイズ8KB なら2KB弱)です。

    • メモリやファイルサイズに関する設定パラメータの単位に B(バイト)が利用可能になりました。 (Beena Emerson) (11)

これまで kB、MB、GB、TB が利用可能でした。

WAL
    • WALファイルサイズを initdb 実行時に指定できるようになりました。 (Beena Emerson) (11)

これまではビルド時にのみ 16MB のデフォルトサイズを変更できました。

    • チェックポイント一つ分の WALデータのみ保持するようになりました。 (Simon Riggs) (11)

これまではチェックポイント二つ分の WAL が保持されていました。

    • 強制切り替えをした WALセグメントファイルの不要部分をゼロで埋めるようになりました。 (Chapman Flack) (11)

圧縮性の向上が狙いです。

ベースバックアップとストリーミングレプリケーション
    • ロジカルレプリケーションで TRUNCATE動作を伝播するようになりました。 (Simon Riggs, Marco Nenciarini, Peter Eisentraut) (11)
    • (2相コミット機能の)準備されたトランザクションの情報をロジカルレプリケーションのサブスクライバに渡すようになりました。 (Nikhil Sontakke, Stas Kelvich) (11)
    • UNLOGGEDテーブル、一時テーブル、pg_internal.initファイルを、ストリーミングによるベースバックアップから除外するようになりました。 (David Steele) (11)

これらのファイルはコピーする必要がありません。

    • ヒープページのチェックサムがストリーミングによるベースバックアップ中にも検証できるようになりました。 (Michael Banck) (11)

pg_basebackup ではデフォルトでチェックサムが検査されますが、新設された -k (--no-verify-checksums) オプションで無効にできます。

    • レプリケーションスロットの値をサブスクライバによる読み取りによらず、指定に従って前進できるようになりました。 (Petr Jelinek) (11)

これを行う pg_replication_slot_advance() 関数が追加されました。

    • backup_labelファイルにタイムライン情報が追加されました。 (Michael Paquier) (11)

また、リカバリ時に WALのタイムラインが backup_labelファイルのタイムラインと一致するかの検査も行われるようになりました。

  • ホスト(sender_host)とポート(sender_port)の接続情報が pg_stat_wal_receiverシステムビューに追加されました。 (Haribabu Kommi) (11)

ユーティリティコマンド

    • ALTER TABLE が列を追加するにあたって、全行の書き直しをすることなく非NULLの定数デフォルト値を付与することができるようになりました。 (Andrew Dunstan, Serge Rielau) (11)
    • ビューをロックできるようになりました。 (Yugo Nagata) (11)

ビューで参照している実体テーブルがロックされる動作になります。

    • ALTER INDEX で式インデックスの統計情報収集のターゲット数を指定できるようになりました。 (Alexander Korotkov, Adrien Nayrat) (11)

以下のように psql で d+ によりインデックスの統計情報ターゲット数を確認できます。

db=# CREATE TABLE t72 (a int, b float8, c float8, d text);
db=# CREATE INDEX ix72 ON t72 (a, (b + c), d);
db=# ALTER INDEX ix72 ALTER COLUMN 2 SET STATISTICS 1000;
db=# d+ ix72
                     Index "public.ix72"
 Column |       Type       | Definition | Storage | Stats target 
--------+------------------+------------+---------+--------------
 a      | integer          | a          | plain   | 
 expr   | double precision | (b + c)    | plain   | 1000
 d      | text             | d          | plain   | 
btree, for table "public.t72"
    • VACUUM と ANALYZE で複数テーブルを指定できるようになりました。 (Nathan Bossart) (11)

また、VACUUM で列リストを付与するには ANALYZEキーワードの指定が必須となりました。これまでは、そのような場合は暗黙に ANALYZEが含まれました。

    • ANALYZE に括弧でオプションを与える構文が追加されました。 (Nathan Bossart) (11)

VACUUMでサポートされている構文と同様のものです。

例:
db=# ANALYZE (VERBOSE) t74;

データ型

    • CREATE AGGREGATE に集約の最終関数の振る舞いを指定するオプションが追加されました。 (Tom Lane) (11)

これはユーザ定義集約関数を最適化したり、ウィンドウ関数として動作させるのに役立ちます。

    • ドメインの配列が作成できるようになりました。 (Tom Lane) (11)

また、array_agg() がドメインに対して使用できるようになりました。

=# CREATE DOMAIN phone_number AS text CHECK (VALUE = '^d+$');

(10.x では以下の SQLがエラーとなっていました。)
=# CREATE TABLE employees (
       id serial PRIMARY KEY,
       name text NOT NULL,
       phone_list phone_number[] NOT NULL
   );
ERROR:  type "phone_number[]" does not exist
LINE 4:     phone_list phone_number[] NOT NULL
    • 複合型のドメインに対応しました。 (Tom Lane) (11)

PL/Perl、PL/Python および PL/Tcl で複合型のドメインを関数の引数および結果としても取り扱えるようになりました。PL/Python でのドメインの取り扱いも改善されました。

=# CREATE TYPE _person_name AS (first_name text, last_name text);

(10.xでは以下の SQLがエラーとなっていました)
=# CREATE DOMAIN person_name AS _person_name NOT NULL;
ERROR:  "_person_name" is not a valid base type for a domain
    • JSONBのスカラ値から数値および論理値のデータ型へのキャストが追加されました。 (Anastasia Lubennikova) (11)
(10 での動作例)
=# SELECT ('{"id": 1, "name": "sato", "saraly": 350000 }'::jsonb->'saraly')::numeric;
ERROR:  cannot cast type jsonb to numeric
LINE 1: ...me": "sato", "saraly": 350000 }'::jsonb->'saraly')::numeric;
                                                             ^
(11 での動作例)
=# SELECT ('{"id": 1, "name": "sato", "saraly": 350000 }'::jsonb->'saraly')::numeric;
 numeric
---------
  350000
(1 row)

関数

    • SQL:2011 で規定された全てのウインドウ関数フレーム化オプションに対応しました。 (Oliver Ford, Tom Lane) (11)

具体的には、RANGE モードで PRECEDING および FOLLOWING を使用することでプラスまたはマイナスの指定されたオフセット内のグループ化される値をもつ行を選択できるようになりました。プラスまたはマイナスのピアグループの数を含める GROUPS モードが追加されました。フレーム除外の構文も追加されました。

    • ハッシュ関数に SHA-2 系列が追加されました。 (Peter Eisentraut) (11)

具体的には、sha224()、sha256()、sha384()、sha512() が追加されました。

    • 64 ビット非暗号化ハッシュ関数に対応しました。 (Robert Haas, Amul Sul) (11)

主として拡張モジュールの実装むけに使われるハッシュ関数に関する機能追加です。

    • to_char() と to_timestamp() にて UTC からのタイムゾーンオフセットを時間と分で指定できるようになりました。 (Nikita Glukhov, Andrew Dunstan) (11)

TZHおよびTZM書式で指定します。

例(TimeZone=Japanでの実行):
=# SELECT to_char(CURRENT_TIMESTAMP, 'TZH:TZM');
 to_char
---------
 +09:00
(1 row)
  • Web検索エンジンで使用されるものと同様の問い合わせ構文に対応したテキスト検索関数 websearch_to_tsquery() が追加されました。 (Victor Drobny, Dmitry Ivanov) (11)
  • JSON/JSONB値に対してテキスト検索問い合わせ用の tsvectorデータを生成する、関数 json_to_tsvector() 、 jsonb_to_tsvector() が追加されました。 (Dmitry Dolgov) (11)

サーバサイド言語

    • トランザクションの開始およびコミットができる新たなデータベースオブジェクト種別「プロシージャ」が追加されました。 (Peter Eisentraut) (11)

プロシージャは CREATE PROCEDURE コマンドで作成し、CALL で実行します。

新たな ALTER/DROP ROUTINEコマンドでプロシージャ、関数および集約を含むすべての手続き的オブジェクトを変更・削除できるようになりました。

なお、CREATE OPERATOR および CREATE TRIGGER では、参照されるオブジェクトはプロシージャではなく関数でなければならないため、PROCEDURE と記述するよりも FUNCTION と記述するほうが望ましいです。ただし、古い構文は互換性のためにまだ使用できます。

    • PL/pgSQL、PL/Perl、PL/Python、PL/Tcl および SPI サーバサイド言語にトランザクション制御が追加されました。 (Peter Eisentraut) (11)

トランザクション制御はトップトランザクションレベルのプロシージャと、ほかの DO および CALL ブロックのみを含む入れ子になった DO および CALL ブロック内のみで使用できます。

    • PL/pgSQL で複合型の変数を非NULL、定数または初期値を指定して定義できるようになりました。 (Tom Lane) (11)
    • PL/pgSQL で同じセッション内の当初と後の関数実行の間に発生する複合型(例えば、レコード、行)への変更を取り扱えるようになりました。 (Tom Lane) (11)

以前は、このような状況ではエラーが発生していました。

(以下のようなテーブル、関数で、)
db=# CREATE TABLE t88 (id int, name text, to_be_removed int);
db=# CREATE FUNCTION f88(a_id int) RETURNS SETOF t88 AS
       $$ BEGIN RETURN QUERY SELECT * FROM t88 WHERE id = a_id; END; $$
       LANGUAGE plpgsql;
db=# SELECT id, name FROM select_users(1);

(関数内で使われるテーブルや複合型の定義変更が行われると)
db=# ALTER TABLE users DROP COLUMN to_be_removed;

(様々なエラーが生じる場合がありました)
db=# SELECT id, name FROM select_users(1);
ERROR:  structure of query does not match function result type: Number of returned columns (2) does not match expected column count (3).
  • jsonb と PL/Pythonの型との間の変換を行う拡張 jsonb_plpython が追加されました。 (Anthony Bykov) (11)
  • jsonb と PL/Perlの型との間の変換を行う拡張 jsonb_plperl が追加されました。 (Anthony Bykov) (11)

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

    • libpq でデフォルトで圧縮を無効にするように変更されました。 (Peter Eisentraut) (11)

最近の OpenSSL のバージョンでは圧縮はすでに無効になっており、libpq で設定してもそのようなライブラリには効果がありませんでした。

    • ecpg の WHENEVER文に DO CONTINUEオプションが追加されました。 (Vinayak Pokale) (11)

これにより C言語の continue文が生成され、指定した条件が発生した場合にループの先頭に戻るようになります。

    • Oracle Pro*C のように char配列を取り扱う ecpg のモードが追加されました。 (David Rader) (11)

このモードは -C オプションで有効になります。

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

  • --encodingオプションが pg_dumpall に追加されました。 (Michael Paquier) (11)

pg_dump コマンドには以前よりあったものです。

  • --load-via-partition-rootオプションが pg_dump に追加されました。 (Rushabh Lathia) (11)

このオプションを使用することでパーティショニングされているデータをそれぞれのパーティションテーブルではなく親テーブルにロードするようになります。

これはダンプ元と先のシステムの違いにより、行が格納されるパーティションに差異が出る場合に有益です。

  • pg_dump、pg_dumpall、pg_restore に --no-commentsオプションが追加されました。 (Robins Tharakan) (11)

データベースオブジェクトに対するコメントをダンプに含めなくなります。
pg_restore に付けた場合にはコメントがリストアされなくなります。

psql
    • psql に問い合わせ結果の列名と型を表示する gdesc モードが追加されました。 (Pavel Stehule) (11)

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

db1=# SELECT * FROM t1;
 id | val  
----+------
  1 | test
(1 row)

db1=# gdesc
 Column |  Type   
--------+---------
 id     | integer
 val    | text
(2 rows)
    • psql に問い合わせの実行状況およびエラーを報告する変数が追加されました。 (Fabien Coelho) (11)

具体的には、新たな変数は ERROR、SQLSTATE、ROW_COUNT、LAST_ERROR_MESSAGE および LAST_ERROR_SQLSTATE です。

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

=# INSERT INTO pgbench_accounts VALUES (1, 1, 0, '');
ERROR:  duplicate key value violates unique constraint "pgbench_accounts_pkey"
DETAIL:  Key (aid)=(1) already exists.

=# echo :ERROR
true

=# echo :SQLSTATE
23505

=# echo :ROW_COUNT
0

=# echo :LAST_ERROR_MESSAGE
duplicate key value violates unique constraint "pgbench_accounts_pkey"

=# echo :LAST_ERROR_SQLSTATE
23505
    • psql で変数が存在するかをテストできるようになりました。 (Fabien Coelho) (11)

具体的には、if 文で構文 :{?変数名} を使用して変数が存在するかをテストします。

    • PSQL_PAGER 環境変数を使って psql のページングを制御できるようになりました。 (Pavel Stehule) (11)

これにより psql と他のアプリケーションとで別々のページャ指定を行えるようになります。PSQL_PAGER がセットされていない場合は、これまで通り PAGER の設定が適用されます。

    • d+ でパーティションに関する情報も確認できるようになりました。 (Amit Langote, Ashutosh Bapat) (11)
    • psql での接続にパスワードが必要な際に、正しいユーザのパスワード入力を促すように修正されました。 (Tom Lane) (11)

以前までは、psql の -U オプションで指定したユーザと -d に記載の URI で示しているユーザ名が一致していないときに、実際に接続に使われるユーザでない方のパスワード入力を促し、DB へ接続できないことがありました。

    • 先行する入力がなければ、exit もしくは quit と実行することでも psql を終了させることができるようになりました。 (Bruce Momjian) (11)

この方法は、クエリの書き途中である場合等、クエリバッファが空でない場合は使えないため、その際はヒントとして別の手段が表示されるようになっています。

本項目および次項のpsql動作例:
db1=# SELECT '
db1'# QUIT
Use control-D to quit.
    • q が有効でないときに実行された時、Ctrl-D(Windows なら Ctrl-C)で終了できることを示すヒントが表示されるようになりました。 (Bruce Momjian) (11)
    • ALTER INDEX RESET/SET でのタブ補完が改善されました。 (Masahiko Sawada) (11)
    • psql でのタブ補完機能でサーバ側のバージョンを考慮できるようになりました。 (Tom Lane) (11)

以前は、サーバのバージョンが古い場合にタブ補完で入力したクエリの実行に失敗する可能性がありました。

pgbench
    • pgbench で使用するスクリプト言語が改善されました。 (Fabien Coelho) (11)

変数値が NULL に対応し、変数データ型に boolean型が加わりました。また、様々な関数、演算子、CASE条件式が追加されました。

    • pgbench で if が使用できるようになりました。 (Fabien Coelho) (11)
    • pgbench で変数名に ASCII文字以外を使用できるようになりました。 (Fabien Coelho) (11)
    • pgbench に --init-stepsオプションが追加されました。 (Masahiko Sawada) (11)

このオプションを使用することで pgbench の初期化で行われる作業を柔軟に指定できます。デフォルトは ‘dtgvp’ で各文字が初期化時の処理要素を意味しています。

  • pgbench にジップ分布のランダムジェネレータが追加されました。 (Alik Khilazhev) (11)
  • pgbench に乱数シードを指定できる --random-seedオプションが追加されました。 (Fabien Coelho) (11)
  • pgbench で pow() と power() 関数が使用可能になりました。 (Raúl Marín Rodríguez) (11)
  • pgbench にいくつかのハッシュ関数が追加されました。 (Ildar Musin) (11)
  • pgbench で --latency-limit--rate を使用した場合の統計情報がより正確なものになりました。 (Fabien Coelho) (11)

サーバアプリケーション

    • pg_basebackup 実行時にレプリケーションスロットを作成できるようになりました。 (Michael Banck) (11)

そのために --create-slot--slot--wal-method=stream オプションを使用します。以下のように実行することで --slot で指定している名前のレプリケーションスロットが同時に作成されます。

$ pg_basebackup -D test_base --wal-method=stream --slot 'test_slot' --create-slot

$ psql -c 'SELECT * FROM pg_replication_slots'
 slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 
-----------+--------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------
 test_slot |        | physical  |        |          | f         | f      |            |      |              | 0/2000000   | 
(1 row)
    • initdb に --allow-group-accessオプションが追加されました。 (David Steele) (11)

initdb 時に本オプションを使う事でデータディレクトリのパーミッションをデフォルトから変更し、グループに対して読み込みと実行権限を与えることができます。今までは 700 でなくてはサーバが起動されませんでした。

作成後は以下のように data_directory_mode を参照して確認できます。

$ psql -c 'SHOW data_directory_mode' 
 data_directory_mode 
---------------------
 0750
(1 row)

予めディレクトリを作成してからの initdb の場合、オプションを付けていなければ、デフォルトのパーミッションに変更されます。

    • pg_verify_checksums コマンドが追加されました。 (Magnus Hagander) (11)

データベースクラスタのチェックサムを検証するツールになります。実行するには initdb 時に --data-checksumsオプションを付けている必要があり、またサーバを停止している状態でのみ実行が可能です。

    • pg_resetwalコマンドで WAL セグメントのサイズを変更できるようになりました。 (Nathan Bossart) (11)

このために --wal-segsizeというオプションが追加されました。

    • pg_resetwal と pg_controldata にロングオプション(-f に対して --force など)が追加されました。 (Nathan Bossart, Peter Eisentraut) (11)
    • pg_receivewal に --no-sync オプションが 追加されました。 (Michael Paquier) (11)

このオプションでは受け取った WAL のストレージへのフラッシュを強制しません。テスト用途であって本番システムには適しません。

    • pg_receivewal に --endposオプションが追加されました。 (Michael Paquier) (11)

オプションにより、どの時点で WAL受信を停止するかを LSN で指定できるようになります。

    • pg_ctl コマンドを使用して SIGKILL シグナルを送信できるようになりました。 (Andres Freund) (11)

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

$ pg_ctl kill KILL 《プロセス ID》
    • pg_rewind がより効率的に実行されるようになりました。 (Michael Paquier) (11)

これまでの pg_rewind がソースサーバからコピーしてくるファイルの中には使われないものが含まれており、それらを省略して転送データ量が減りました。

    • pg_rewind が rootユーザで実行できないようになりました。 (Michael Paquier) (11)

これまでは警告が表示されるのみで実際の実行は可能でした。

ソースコード

    • PGXS がインクルードファイルをインストールするようになりました。 (Andrew Gierth) (11)

これは他のモジュールに依存する拡張モジュールの作成のため変更です。以前は、依存モジュールが参照されるモジュールのインクルードファイルを見つける簡単な方法がありませんでした。

関連するファイルをインストールするために、データ型を定義するいくつかの既存 contrib モジュールが調整されています。

また、PL/Perl と PL/Python はこれらの言語用変換モジュールの作成を可能とするためにインクルードファイルをインストールするようになりました。

    • 拡張機能が PostgreSQLの広く知られているエラーコードにアクセスできるように、errcodes.txt がインストールされるようになりました。 (Thomas Munro) (11)

shareディレクトリ下に配置されます。

    • ドキュメントが DocBook XML に変更されました。 (Peter Eisentraut, Alexander Lakhin, Jürgen Purtz) (11)

バックブランチとの互換性のため、ファイル名にはまだ sgml拡張子が使われています。

    • そうするのが適切な(大部分の)プラットフォームにおいては、stdbool.h ヘッダを使って bool型を定義するようになりました。 (Peter Eisentraut) (11)

これにより、stdbool.h の include を要する拡張モジュールでのコーディングの危険性を除きます。

    • システムカタログの内容の定義が見直されました。 (John Naylor) (11)

初期データは Perl データ構造で表現され、機械的な操作が簡単になりました。

    • 拡張に対して値のクォートされたリストを取るカスタムパラメータを作ることが防止されました。 (Tom Lane) (11)

これは現状ではサポートできません。なぜなら、パラメータのプロパティ情報は拡張がロードされる前であっても必要とされる場合があるためです。

    • SCRAM認証を行う場合に、チャネルバインディングを使用する機能が追加されました。 (Michael Paquier) (11)

なお、チャネルバインディングは、中間者の攻撃を防ぐことを目的としていますが、強制的に有効にすることができない限り、SCRAM はそれらを防ぐことができません。残念ながら、現時点で libpq でこれを行う方法はありません。今後の libpq のバージョンや、libpq を使用せず構築するインタフェース(例えば JDBC)で将来的にサポートされることが期待されます。

    • バックグラウンドワーカが、通常は接続が禁止されているデータベースに接続できるようになりました。 (Magnus Hagander) (11)
    • ARMv8アーキテクチャのハードウェアによる CRC計算がサポートされました。 (Yuqi Gu, Heikki Linnakangas, Thomas Munro) (11)
    • OID による組み込み関数の探索が高速化されました。 (Andres Freund) (11)

以前の二分検索は探索配列で置き替えられました。

    • クエリ結果の構築が高速化されました。 (Andres Freund) (11)
    • システムキャッシュへのアクセス速度が改善されました。 (Andres Freund) (11)
    • メモリの連続割り当て/解放のために最適化された、世代別のメモリアロケータが追加されました。 (Tomas Vondra) (11)

これにより、ロジカルデコーディングに要するメモリ使用量が減少します。

  • VACUUM による pg_class.reltuples の推測値が、ANALYZE による推測値と整合するようになりました。 (Tomas Vondra) (11)
  • perltidy バージョン 20170521 が使用されるようになりました。 (Tom Lane, Peter Eisentraut) (11)

追加モジュール

    • pg_prewarm拡張で、起動時に前回の共有バッファの内容を復元できるようになりました。 (Mithun Cy, Robert Haas) (11)

これは、サーバの処理中やシャットダウン時に pg_prewarm が共有バッファのリレーションとブロック番号データをディスクへ書き込むことで実現されます。

    • pg_trgm に strict_word_similarity()関数が追加されました。ワード全体を通しての類似度が測れるようになります。 (Alexander Korotkov) (11)

同様の用途で word_similarity()関数はすでに存在しますが、これはワードのなかの類似している部分が見つけられるのに対し、strict_word_similarity()関数はワード全体を通してどの程度似ているかを測ることができます。

    • citext カラムの LIKE 比較で使用できるインデックスの作成が可能になりました。 (Alexey Chernyshov) (11)

これを行うためには、citext_pattern_ops 演算クラスを使用してインデックスを作成する必要があります。

    • btree_gin が bool、bpchar、name、および、uuid型のインデックスに対応しました。 (Matheus Oliveira) (11)
    • cube拡張と seg拡張のデータ型で、GiSTインデックスを使用した index-only スキャンが可能になりました。 (Andrey Borodin) (11)
    • ~> 演算子を使うことにより、cube の負の座標を取得できるようになりました。 (Alexander Korotkov) (11)

これは KNN-GiST検索において降順で座標を探索する場合に有用です。

    • unaccent拡張がベトナム語文字に対応しました。 (Dang Minh Huong, Michael Paquier) (11)
    • 各ヒープタプルにインデックスエントリがあるかを確認できるようにamcheck が強化されました。 (Peter Geoghegan) (11)
    • adminpack に適用するデフォルトのファイルシステムへのアクセスロールが新しくなりました。 (Stephen Frost) (11)

以前はスーパーユーザだけが adminpack 関数を呼び出すことができましたが、今後はロールのパーミッションが検査されます。

    • pg_stat_statement のクエリIDが 64ビットに拡張されました。 (Robert Haas) (11)

これによりクエリID のハッシュが衝突する機会が大幅に減少します。また、今後はクエリID が負の値として表示される可能性があります。

    • contrib/start-scripts/osx のスクリプトが削除されました。 (Tom Lane) (11)

これはすでに非推奨となっていました。代わりに contrib/start-scripts/macos のスクリプトを使用してください。

    • chkpass拡張が削除されました。 (Peter Eisentraut) (11)

この拡張は、現在では有効なセキュリティツールあるいは拡張作成のサンプルとは言えないためです。