PostgreSQL 13.3 に関する技術情報

このリリースは 13.2 からの修正リリース(2021年5月13日リリース)です。
13.X からのアップデートではダンプ、リストアは不要です。
しかしながら、13.2 よりも前のバージョンから移行する場合には 13.2 のリリース情報も確認してください。

PostgreSQL 13.2 から 13.3 への変更点

13.3、12.7、11.12、10.17、9.6.22 の各バージョンが同時にリリースされており、本ページでは共通の記載としています。各修正項目が適用されるバージョン系列番号を項目末尾に括弧書きで記載しています。

  1. 配列の添え字の計算において、整数オーバーフローが防止されました。(CVE-2021-32027) (Tom Lane) (13)(12)(11)(10)(9.6)
  2. これまでの配列の実装では、配列の下限と長さが整数をオーバーフローさせる場合を問題としていませんでした。その結果、(添え字を整数として書けないため)配列後方のエントリがアクセス不能になり、さらに重要なことには、続く代入操作を混乱させました。このことは、確実なクラッシュや望まないデータ書き換えを伴うメモリ上書きをもたらすおそれがありました。

    サポート終了バージョンであるため修正はリリースされませんが、9.5以前のバージョンについても同様の問題があると考えられます。

  3. 「INSERT ... ON CONFLICT ... UPDATE」の対象リストで不要列の扱いが修正されました。 (CVE-2021-32028) (Tom Lane) (13)(12)(11)(10)(9.6)
  4. UPDATE のリストが、適切な結果に加えて不要列(使われない不要な列、ごみ列)を発生させるような複数列の副問い合わせを持つ場合、UPDATE の処理コードは最終的に余分な不要列の値を含むタプルを格納していました。これは短い実行ではおよそ無害ですが、テーブルに新たな列が追加された場合、その値がアクセス可能になってしまい、追加した列とデータ型が合わない場合には不具合になるおそれがありました。

    加えて、パーティションをまたがる更新に対応したバージョンでは、このようなケースで引き起こされたパーティションをまたがる更新が、逆に対象リストから不要列が削除される問題をもたらし、典型的には即座のクラッシュを引き起こしました。

    この障害を利用して、一時テーブルを含む、テーブル作成権限を持ったユーザによる、サーバ側の任意メモリを読み取る攻撃も可能でした。

    (クラッシュ発生例)
    db=# CREATE TABLE t2 (a int PRIMARY KEY, b text) PARTITION BY LIST (a);
    db=# CREATE TABLE t2_1 PARTITION OF t2 FOR VALUES IN (1);
    db=# CREATE TABLE t2_2 (b TEXT, a INT PRIMARY KEY);
    db=# ALTER TABLE t2 ATTACH PARTITION t2_2 FOR VALUES IN (2);
    db=# INSERT INTO t2 VALUES(1, 'Boo'), (2, 'Zoo');
    
    db=# WITH aaa AS (SELECT 1 AS a, 'Foo' AS b)
         INSERT INTO t2 VALUES (1, 'Bar') ON CONFLICT (a)
           DO UPDATE SET (b, a) = (SELECT b, a FROM aaa) RETURNING *;
     (a=1、b='Foo' の 1行が返る)
    
    db=# WITH aaa AS (SELECT 1 AS ctea, ' Foo' AS cteb)
         INSERT INTO t2 VALUES (1, 'Bar'), (2, 'Baz') ON CONFLICT (a)
           DO UPDATE SET (b, a) = (SELECT t2.b || cteb, t2.a FROM aaa) RETURNING *;
     (ここでクラッシュ発生)
    
  5. 結合を伴いパーティションをまたがる更新に対する UPDATE ...RETURNING 出力の計算が間違っている可能性があり、修正されました。(CVE-2021-32029) (Amit Langote, Etsuro Fujita) (13)(12)(11)
  6. パーティションテーブルの UPDATE により、行が物理的に異なる行タイプを持つ別のパーティション(例えば、削除された列のセットが異なるパーティション)に移動された場合、その行に対する RETURNING 結果の計算でエラーや間違った答えが生じる可能性がありました。UPDATE で他のテーブルが対象テーブルに結合されない限り、エラーは発生しません。

    以下は本障害によりパーティションテーブルの UPDATE で発生するエラーの一例です。

    ERROR:  attribute 5 of type record has wrong type
    DETAIL:  Table has type record, but query expects integer.
    

    この障害を利用して、一時テーブルを含む、テーブル作成権限を持ったユーザによる、サーバ側の任意メモリを読み取る攻撃が可能でした。

  7. パーティションテーブルにおける遅延プロパティ制約の調整が修正されました。 (Álvaro Herrera) (13)(12)(11)
  8. 遅延プロパティをパーティションテーブルの外部キー制約に適用するとき、ALTER TABLE ... ALTER CONSTRAINT は、リーフパーティション(末端のパーティション)の制約およびトリガの DEFERRABLE および INITIALLY DEFERRED の印付け調整に失敗しました。これにより、これらの制約の予期しない動作が発生しました。

    バージョンアップ後に ALTER コマンドを実行して、必要なプロパティを設定することで、誤動作しているパーティションテーブルを修正できます。

    本修正により、リーフパーティションの制約に直接このような ALTER を適用することもできなくなりました。 唯一サポートされているケースは、パーティショニング階層全体が同一の制約プロパティを持つことであるため、このような ALTER はルートパーティション(親テーブル)で適用される必要があります。

  9. ALTER TABLE ... INHERIT で子テーブルをアタッチする場合、子テーブルで親テーブルの生成列と同じ定義を持つことを確認するようになりました。 (Peter Eisentraut) (13)(12)
  10. これまでは子テーブルの定義が異なっていても、無視して子テーブルの定義を捨てていました。本修正で親子で生成列の定義が異なる場合にエラーが出るように変更されました。

    db=# CREATE TABLE t13_p1 (a int, b int GENERATED ALWAYS AS (a * 2) STORED);
    db=# CREATE TABLE t13_c1 (a int, b int GENERATED ALWAYS AS (a * 3) STORED);
    
    (13.2 での動作)
    db=# ALTER TABLE t13_c1 INHERIT pp1;
    ALTER TABLE
    
    (13.3 での動作)
    db=# ALTER TABLE t13_c1 INHERIT pp1;
    ERROR:  column "b" in child table has a conflicting generation expression
    
  11. IDENTITY列を NULL可能とすることが禁止されました。 (Vik Fearing) (13)(12)(11)(10)
  12. GENERATED ALWAYS AS IDENTITY は NOT NULL を意味しますので、明示的な NULL 指定と組み合わせて使用することはできません。

  13. ALTER ROLE/DATABASE ... SET で role、session_authorization、temp_buffers のパラメータを設定できるようになりました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  14. 以前は、後で使用する際に値が有効であったとしても、過剰な有効性チェックによってこれらのコマンドが拒否されることがありました。 このため、ダンプ/リロードや pg_upgrade の際に、コマンドの順序が乱れてしまうことがありました。

  15. REINDEX CONCURRENTLY が、インデックスに設定されている統計情報対象を維持するようになりました。 (Michael Paquier) (13)(12)
  16. これまでは実行前に設定されていた pg_attribute.attstattarget が REINDEX CONCURRENTLY を実行して作成される新しいインデックスで失われていました。

  17. 現在のトランザクションにセーブポイントが存在する場合に、COMMIT AND CHAIN が正しく動作するように修正されました。 (Fujii Masao) (13)(12)
  18. 以下に本修正による動作の違いを示します。

    (13.2 での動作)
    db=# BEGIN;
    db=*# SAVEPOINT foo;
    db=*# COMMIT AND CHAIN;
    db=#
    (↑トランザクションが終了、プロンプトが # に変わっています)
    
    (13.3 での動作)
    db=# BEGIN;
    db=*# SAVEPOINT foo;
    db=*# COMMIT AND CHAIN;
    db=*#
    (↑正しく動作して再びトランザクション内になります、プロンプトが *# です)
    
  19. WITH RECURSIVE 処理におけるリスト操作のバグが修正されました。 (Michael Paquier, Tom Lane) (13)
  20. 7レベル以上の十分に深い WITH構造の入れ子によりクラッシュや、WITH 入れ子に対する誤ったエラー(下記)が発生していました。

    ERROR:  stack depth limit exceeded
    
  21. COLLATE式の結果を照合不能な型に強制変換する際のバグが修正されました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  22. 本障害により、COLLATE が照合不能な値に適用されているように見える解析ツリーが作成されていました。COLLATE は実行時には影響しないため、通常の使用上の影響はありませんが、ダンプ/リロード時に拒否されるビューを作成することがありえました。

    (誤動作例: \d 出力のビュー定義の COLLATE句 が余計で、この SELECT はエラーになる)
    db=# CREATE VIEW v9 AS
           SELECT c1+1 AS c1p FROM (SELECT ('4' COLLATE "C")::INT AS c1) ss;
    db=# \d+ v9
                                 View "public.v9"
     Column |  Type   | Collation | Nullable | Default | Storage | Description
    --------+---------+-----------+----------+---------+---------+-------------
     c1p    | integer |           |          |         | plain   |
    View definition:
     SELECT ss.c1 + 1 AS c1p
       FROM ( SELECT 4 COLLATE "C" AS c1) ss;
    
  23. AFTERトリガのタプルを保存する際に生じていたメモリを解放した後に再使用する、use-after-free バグが修正されました。 (Amit Langote) (13)(12)
  24. これにより状況によってはクラッシュをおこす可能性がありました。

  25. fastpathプロトコル(関数呼び出しサブプロトコル)のメッセージによるウィンドウ関数およびプロシージャの呼び出しが禁止されました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  26. ここでは普通の関数のみがサポートされます。集約関数の呼び出しはすでにエラーとなっていましたが、ウィンドウ関数の呼び出しはクラッシュし、プロシージャの呼び出しはそのプロシージャがトランザクション制御を行わない場合にのみ機能していました。

  27. イベントトリガをサポートするために pg_identify_object_as_address() が拡張されました。 (Joel Jacobson) (13)(12)(11)(10)(9.6)
  28. 以前は、pg_event_trigger に対する本関数の実行で、予期せぬエラー「ERROR: requested object address for unsupported object class 32: text result "ddl_postgrest"」が発生していました。

  29. to_char() による負の間隔を持つローマ数字の月形式コードの処理が修正されました。 (Julien Rouhaud) (13)(12)(11)(10)(9.6)
  30. 以前そのような時は通常クラッシュを引き起こしてました。

    (修正前 13.2 ではクラッシュ)
    db1=# SELECT * from TO_CHAR(interval '-1Mon', 'rm');
    server closed the connection unexpectedly
            This probably means the server terminated abnormally
            before or while processing the request.
    The connection to the server was lost. Attempting reset: Failed.
    
    (修正後 13.3 の動作例)
    db=# SELECT * from TO_CHAR(interval '-1Mon', 'rm');
     to_char
    ---------
     xii
    (1 row)
    
  31. pg_import_system_collations() の引数が有効なスキーマの OID かを確認して、無効ならエラーを出すようになりました。 (Tom Lane) (13)(12)(11)(10)
  32. これまで不正な値に対してアサート失敗が生じていました。アサート無効のビルドでは、おそらく無害ですが pg_collation に無効な collnamespace列の値を持ったエントリができる可能性がありました。

  33. 基本RE(BRE)モードの正規表現で \{m,n\} 数量詞を解析する際に初期化されていない値の使用が修正されました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  34. この誤りにより、数量詞が欲張りでない動作をする可能性がありました。すなわち、完全な正規表現(ARE) における {m,n}? 数量詞の動作と同様に振る舞いました。

  35. ソートキーに集約関数やウィンドウ関数が含まれている状況で、プランナのエラー「ERROR: could not find pathkey item to sort」が出る問題が修正されました。 (James Coleman, Tom Lane) (13)
  36. 拡張統計を用いてグループ数を推定する際、システム列を無視しないように修正されました。 (Tomas Vondra) (13)(12)(11)(10)
  37. これまでは (a, b) の拡張統計が存在するテーブルに対する「SELECT ... GROUP BY a, b, ctid」といったシステム列を含めた問い合わせの推定値がおかしくなっていました。

  38. 長い固定プレフィックスを持つ正規表現に対する選択度(selectivity)の評価を行う際に発生するゼロ除算問題が回避されました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  39. 通常、選択度は NaN と評価され、後にアサート失敗や奇妙なプランナ動作を引き起こす可能性がありました。

    下記の正規表現を使用してアサート失敗が発生するケースが報告されました。

    SELECT * FROM test WHERE t ~* ('^' || repeat('-', 500));
    
  40. BRINインデックスを使用するとき、ビットマップインデックススキャンを行う際にテーブル範囲外にアクセスしようとするエラーが発生する可能性があり、修正されました。 (Tomas Vondra) (13)(12)(11)(10)(9.6)
  41. BRINインデントのページ範囲サイズが 2 の累乗でなければ、ビットマップスキャンがテーブル実際の終りより先のページを読み込もうと試み、稀に「ERROR: could not open file」が出ることがありました。

  42. GINインデックスの検索でマッチするタプルが複数存在する場合、間違った値を返す可能性があり、修正されました。 (Tom Lane) (13)
  43. マッチするインデックス数が過大になると(閾値は work_mem 設定値で決まります)、保持しているビットマップは損失を伴うもの(lossy)になります。このとき、再チェック(recheck)は不要と誤判断する可能性があり、誤った問い合わせ結果を返すことがありました。

  44. Windows における WALセグメント再利用時の同時実行問題が修正されました。 (Michael Paquier) (13)
  45. 以前(13.0 リリース前)の修正によって「LOG: could not rename file ...: Permission denied」というログメッセージが断続的に出力されていて、その修正が元に戻されました。深刻な問題ではありませんでしたが大量のログ出力が迷惑でした。

  46. コミットされていない二相トランザクションを WAL からリカバリする時に発生する、不適切なタイムライン変更が回避されました。 (Soumyadeep Chakraborty, Jimmy Yih, Kevin Yeap) (13)(12)(11)(10)
  47. この不具合により、後続の WALレコードは間違ったタイムラインID で記録され、整合性が取れなくなる問題や、サーバが再起動できなくなる問題が起きる可能性がありました。

  48. スタンバイサーバが起動中にシャットダウンされた場合に、確実にロックが全て解放されるようになりました。 (Fujii Masao) (13)(12)(11)(10)(9.6)
  49. スタンバイサーバがリカバリの途中で切断されると、保持しているロックが一部残る可能性があり、デバッグが有効なビルドではアサート失敗が発生していました。本番ビルドで重大な問題が発生するかは不明です。

  50. 論理レプリケーションワーカが「ALTER SUBSCRIPTION ... REFRESH PUBLICATION」を実行するときにクラッシュしてしまう問題が修正されました。 (Peter Smith) (13)(12)(11)(10)
  51. 通常のコマンド実行では問題がありませんが、レプリカのトリガから実行するときにクラッシュが発生しました。

  52. 最近のバージョンの FreeBSD において、wal_sync_method 設定がデフォルトで fdatasync になるように修正されました。 (Thomas Munro) (13)(12)(11)(10)(9.6)
  53. FreeBSD 13 は open_datasyncをサポートしているため、通常、それがデフォルトで選択されました。しかしながら PostgreSQLにとってそれがより優れた選択とは限られませんので、既存のデフォルト設定のままにするようになりました。

  54. vacuum_cleanup_index_scale_factor設定とストレージオプションが無効にされました。 (Peter Geoghegan) (13)
  55. 古くなった統計情報を追跡するという考えはautovacuum_vacuum_insert_threshold設定とは相性が悪く、結果として必要のないフルインデックススキャンが行われ、autovacuum のパフォーマンス劣化につながりました。autovacuum_vacuum_insert_threshold の仕組みがより優れていると判断されて、古い統計情報のロジックが削除されました。

    vacuum_cleanup_index_scale_factor設定はバージョン14 から完全に削除されます。既存の設定ファイルにも影響を及ぼすという懸念から、バージョン13 ではまだパラメータが残されていますが、機能はしなくなりました。

  56. ALTER CONSTRAINT 内で、ALTER 処理後に実行されるフックに正しくトリガの OID を渡すように、修正されました。 (Álvaro Herrera) (13)(12)
  57. ALTER CONSTRAINT の中でトリガを更新する際、ALTER 処理後のフックはトリガを更新するものと知らされますが、ここでトリガの OID ではなくトリガのための制約の OID が渡されていました。ALTER 後に誤った制約の動作が生じました。

    (修正前バージョン 13.2 での障害動作例)
    db=# CREATE TABLE pt27m (k1 int, k2 int, PRIMARY KEY (k1, k2)) PARTITION BY LIST (k1);
    db=# CREATE TABLE p27m1 PARTITION OF pt27m FOR VALUES IN (1);
    db=# CREATE TABLE pt27t (k1 int, k2 int, v int) PARTITION BY LIST (k1);
    db=# CREATE TABLE p27t1 PARTITION OF pt27t FOR VALUES IN (1);
    
    db=# BEGIN;
    db=*# ALTER TABLE pt27t ADD CONSTRAINT fkey1 FOREIGN KEY (k1, k2) REFERENCES pt27m;
    db=*# ALTER TABLE pt27t ALTER CONSTRAINT fkey1 DEFERRABLE INITIALLY DEFERRED;
    
    db=*# INSERT INTO pt27m VALUES (1, 2);
    db=*# INSERT INTO pt27t VALUES (1, 2, 100);
    db=*# DELETE FROM pt27m;
    ERROR:  update or delete on table "p27m1" violates foreign key constraint "pt27t_k1_k2_fkey" on table "pt27t"
    DETAIL:  Key (k1, k2)=(1, 2) is still referenced from table "pt27t".
    
    (最後の DELETE による制約違反はコミット時までエラーにならないのが本来の期待される動作です)
    
  58. DSM(動的共有メモリ)のセグメントをデタッチする時に、割り込まれても片付けが完了できることが保証されました。 (Thomas Munro) (13)(12)(11)(10)(9.6)
  59. パラレルクエリで作成されたテンポラリファイルが即時に削除されない問題が発生する可能性がありました。

  60. 幾つかの軽微なメモリリークが修正されました。 (Tom Lane, Andres Freund) (13)(12)(11)(10)(9.6)
  61. 共有メモリにある walreceiver の統計情報中の変数が初期化されない問題が、修正されました。 (Fujii Masao) (13)
  62. この誤りは殆どのプラットフォームで無害ですが、アトミック変数やスピンロックがサポートされないプラットフォームでは下記のエラーが発生する可能性がありました。

    ERROR:  invalid spinlock number: 0
    
  63. dtrace が無効になっているとしても、コンパイルされていたなら軽量ロック(LWLock)を追跡するプローブが実行されていたものが修正され、オーバーヘッドが軽減されました。 (Peter Eisentraut) (13)
  64. PL/pgSQL の DOブロックで複合型変数とトランザクション制御を両方使用する際に、エラーが発生していたものが、修正されました。 (Tom Lane) (13)(12)(11)
  65. 修正前は以下のようなエラーが発生していました。

    ERROR:  tupdesc reference ... is not owned by resource owner TopTransaction
    
  66. メッセージ長が破損している ParameterDescriptionメッセージを受信したときに発生していた libpq の無限ループが防止されました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  67. Windows で、initdb 実行後、最後に出力されるサーバの起動方法を示すコマンド例における pg_ctl のパスが、バックスラッシュを用いて表示するように修正されました。 (Nitin Jadhav) (13)(12)(11)(10)
  68. (initdb 出力メッセージの例)
    
    成功しました。以下のようにしてデータベースサーバを起動できます。
    
     ^"C^:^/Install^ Dir^/bin^/pg^_ctl^" -D ^"C^:^\database^\data^" -l <ログファイル> start
    
    (↓上記が以下のように出力されるようになります)
    
     ^"C^:^\Install^ Dir^\bin^\pg^_ctl^" -D ^"C^:^\database^\data^" -l <ログファイル> start
    
  69. psql で \connect service=something が以前の振る舞いに戻されました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  70. 以前のバグ修正により、PGPORT などの環境変数が接続サービスファイルのエントリを上書きしていました。サービスファイルでの指定が優先される、以前の振る舞いに戻されました。

  71. COMMIT AND CHAIN コマンドが正しく処理されるように、psql の ON_ERROR_ROLLBACK機能が修正されました。 (Arthur Nascimento) (13)(12)
  72. psql が COMMIT AND CHAIN によって既に解放済みの自動発行セーブポイントを解放しようとして、「ERROR: savepoint "pg_psql_temporary_savepoint" does not exist」というエラーになっていました。

  73. psql コマンドで「could not print result table: ...」メッセージが繰り返し出力される動作が回避されました。 (Álvaro Herrera) (13)
  74. psql の \e および関連コマンドによるファイル変更を検出する際の競合状態が修正されました。 (Laurenz Albe) (13)(12)(11)(10)(9.6)
  75. 高速な入力を行うと、一時編集ファイルの変更をファイルタイムスタンプから検知できないことがありえました。直近のファイル変更内容が反映されない動作をすることが報告されました。

  76. pg_dump でパーティションテーブルの生成列のダンプが修正されました。 (Peter Eisentraut) (13)(12)
  77. 前マイナーリリースで導入された修正はパーティションテーブルには適用すべきではなく、従来からの継承テーブルにのみ適用すべきでした。

  78. pg_restore でのファイルのバージョンチェックの誤りが修正されました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  79. シークできないカスタム形式のダンプファイルを読み取る場合、pg_restore はダンプファイルのバージョンを確認していませんでした。サポートされているものより新しいダンプファイルの形式が提供された場合、リストアに失敗することになります。

    pg_restore が「pg_restore: [archiver] unsupported version (...) in file header」のエラーを出す代わりにクラッシュする動作が報告されました。

  80. pg_upgrade に、アップデートできないデータ型を含むユーザーテーブルの検査が追加されました。 (Tom Lane) (13)(12)(11)(10)(9.6)
  81. アップグレード不可能なデータ型がコンテナ型(配列や範囲など)に埋め込まれている場合の検出が改善されました。

    また、ユーザーテーブルにシステム定義の複合型の列(システムテーブルを複合型として使っている場合など)が含まれている場合には、それらの型の OID はバージョン間で安定していないため、アップグレードを許可しないようになりました。

  82. pg_checksums の進行報告が最後に 100%に到達しない不具合が修正されました。 (Shinya Kato) (13)(12)
  83. pg_waldump が、レコード毎の統計を生成するとき XACTレコードを正しくカウントするように、修正されました。 (Kyotaro Horiguchi) (13)(12)(11)(10)(9.6)
  84. contrib/amcheck で、タプルフラグ HEAP_XMAX_LOCK_ONLY と HEAP_KEYS_UPDATED の両方が設定されていることに対して、エラーを出さないように修正されました。 (Julien Rouhaud) (13)(12)(11)(10)(9.6)
  85. これは SELECT FOR UPDATE 実行後においては正常な状態でした。

  86. VPATH構築が Oracle Developer Studio の最新版のコンパイラをサポートするように調整されました。 (Noah Misch) (13)(12)(11)(10)(9.6)
  87. Solaris 上で稼働する Python 3 用の PL/Python のテストが修正されました。 (Noah Misch) (13)(12)(11)(10)(9.6)
  88. サーバ側SSLパラメータを初期化するときのメモリリークが修正されました。 (Michael Paquier) (12)(11)(10)
  89. 通常、深刻な影響はありませんが、postmaster に SIGHUPシグナルが繰り返し送信されると、時間の経過と共にメモリリークが増大する可能性があります。