このリリースは 9.6.14 からの修正リリース(2019年8月8日リリース)です。
9.6.x からのアップデートではダンプ、リストアは不要です。
9.6.9 より前のバージョンからのアップデートの場合には 9.6.9 のリリース情報も確認してください。
PostgreSQL 9.6.14 から 9.6.15 への変更点
11.5、10.10、9.6.15、9.5.19、9.4.24 の各バージョンが同時にリリースされており、本ページでは共通の記載としています。各修正項目が適用されるバージョン系列番号を項目末尾に括弧書きで記載しています。
- 関数風のキャスト構文を使うとき、一時データ型へのキャストではスキーマ修飾を必須とするようになりました。(CVE-2019-10208) (Noah Misch) (11)(10)(9.6)(9.5)(9.4)
- 型を跨る比較を要するハッシュ化された副プランの実行が修正されました。(CVE-2019-10209) (Tom Lane, Andreas Seltenreich) (11)
- 複数列の型を1つのコマンドで変更するとき、ALTER TABLE ... ALTER COLUMN TYPE が失敗する動作が修正されました。 (Tom Lane) (11)(10)(9.6)(9.5)(9.4)
- 子パーティションに保留中のトリガイベントがある場合には、パーティションテーブルのトリガを削除できないようになりました。 (Álvaro Herrera) (11)
- パーティションテーブルから属するパーティションにトリガ定義をコピーする際に、ユーザ指定のトリガ引数が含まれるようになりました。 (Patrick McHardy) (11)
- パーティションのキー列の削除を防止する依存性が導入されました。 (Tom Lane) (11)(10)
- パーティションテーブルとそのデフォルトパーティションの間で列番号が確実に正しく対応付けされるようにしました。 (Amit Langote) (11)
- インデックスをパーティションテーブル全体に作成するときに、外部テーブルである所属パーティションを無視するようになりました。 (Álvaro Herrera) (11)
- より多くの場合にパーティションテーブルのデフォルトパーティションが検索時にスキャン対象から除外できるようになりました。 (Yuzuko Hosoya) (11)
- RANGEパーティションで boolean型の複数パーティションキー列があるときに検索でのパーティション除外に失敗する可能性があり、修正されました。 (David Rowley) (11)
- 対象のテーブルが継承親テーブルであるときには、GROUP BY列を最適化で消し去らないようになりました。 (David Rowley) (11)(10)(9.6)
- semi-join問い合わせに対する並列ハッシュの誤使用が回避されました。 (Thomas Munro) (11)
- GROUPING SETSを伴う一部の問い合わせに対して、不要なソート処理の使用が回避されました。 (Andrew Gierth, Richard Guo) (11)(10)(9.6)(9.5)
- プランナがインデックス端点を調べるのに失敗する可能性があり、修正されました。 (Tom Lane) (11)
- EvalPlanQual の再チェックにおいて、トリガの遷移テーブルにアクセスするのに失敗していたものが修正されました。 (Alex Aktsipetrov) (11)(10)
- 外部キー制約を再構築するときの複数列の外部キーの誤った処理が修正されました。 (Tom Lane) (11)(10)(9.6)(9.5)(9.4)
- 継承ツリーに対して拡張統計情報を作らないようになりました。 (Tomas Vondra) (11)(10)
- タプルロックを格上げする際の偽性のデッドロックエラーが回避されました。 (Oleksii Kliukin) (11)(10)(9.6)
- 複数のパラレルワーカプロセスに関わるデッドロック解決の失敗が修正されました。 (Rui Hai Jiang) (11)(10)(9.6)
- 端点に infinity や -infinity を持つ日付範囲の誤った標準化が防止されました。 (Laurenz Albe) (11)(10)(9.6)(9.5)(9.4)
- 大きい money型の値を numeric型に変換するときの端数の損失が修正されました。 (Tom Lane) (11)(10)(9.6)(9.5)(9.4)
- BTREE_META_CLEANUP の WALレコードの表示が修正されました。 (Michael Paquier) (11)
- version-2 の Btreeメタページに対する誤った処理によるアサート失敗が防止されました。 (Peter Geoghegan) (11)
- MIPS r6 で動作するように、MIPS CPUむけのスピンロックのアセンブラコードが修正されました。 (YunQiang Su) (11)(10)(9.6)(9.5)(9.4)
- PL/pgSQL関数から返されるレコードまたは ROW値が複合型として型付けされるようになりました。 (Tom Lane) (11)
- libpqライブラリで接続サービスファイル内の復帰コード(
)が無視されるようになりました。 (Tom Lane, Michael Paquier) (11)(10)(9.6)(9.5)(9.4) - psqlコマンドで、SET variable = の後について、variable が既知のパラメータ名でない場合にはタブ補完を行わないようになりました。 (Tom Lane) (11)(10)(9.6)
- psql の d コマンドの軽微なメモリリークが修正されました。 (Tom Lane) (11)(10)
- pg_dump コマンドが修正され、カスタム演算子クラスが正しい順序でダンプされるようになりました。 (Tom Lane) (11)(10)(9.6)(9.5)(9.4)
- -Rオプションの使用時に発生しうる pgbenchコマンドのハングアップが修正されました。 (Fabien Coelho) (11)(10)
- contrib/amcheck のインデックス検証の信頼性が改善されました。 (Peter Geoghegan) (11)
- contrib/jsonb_plperl で Perl の undef値の処理が修正されました。 (Ivan Panchenko) (11)
- contrib/passwordcheck が修正され、check_password_hook がほかのユーザと共存できるようになりました。 (Michael Paquier) (11)(10)(9.6)(9.5)(9.4)
- contrib/sepgsql のテストが修正され、最近の SELinuxリリースでも動作するようになりました。 (Mike Palmiotto) (11)(10)(9.6)(9.5)(9.4)
- src/test/kerberos および src/test/ldap のリグレッションテストの安定性が改善されました。 (Thomas Munro, Tom Lane) (11)
- src/test/recovery のリグレッションテストの安定性が改善されました。 (Michael Paquier) (11)(10)(9.6)
- pg_upgradeコマンドのテストスクリプトからの標準エラーへの出力が削減されました。 (Tom Lane) (11)(10)(9.6)(9.5)(9.4)
- pgbenchコマンドのリグレッションテストがWindows でも動作するように修正されました。 (Fabien Coelho) (11)
- ビルドディレクトリがルート以外の msysマウントポイントにある場合でも、TAP テストが msys の Perl で動作するように修正されました。 (Noah Misch) (11)(10)(9.6)
- Microsoft Visual Studio 2019 でのビルドに対応しました。 (Haribabu Kommi) (11)(10)(9.6)(9.5)(9.4)
- Visual Studioビルドでは、環境変数 WindowsSDKVersion が設定されている場合、それを優先するようになりました。 (Peifeng Qiu) (11)(10)(9.6)(9.5)(9.4)
- Visual Studio ビルドで OpenSSL 1.1.0 以降に対応しました。 (Juan José Santamaría Flecha, Michael Paquier) (11)(10)(9.6)(9.5)(9.4)
- GNU 以外の makeコマンドが最上位のディレクトリで呼び出されたときにmakeコマンドのオプションが gmakeコマンドに渡されるようになりました。 (Thomas Munro) (11)(10)(9.6)(9.5)
- initdbコマンドの実行中に TimeZoneパラメータとして localtime または posixrules が選択されないようになりました。 (Tom Lane) (11)(10)(9.6)(9.5)(9.4)
- pg_timezone_namesビューが調整され、短い省略形をもつ場合に限って Factoryタイムゾーンを表示するようなりました。 (Tom Lane) (11)(10)(9.6)(9.5)(9.4)
- タイムゾーンライブラリのコピーが IANA の tzcode release 2019b と同期されました。 (Tom Lane) (11)(10)(9.6)(9.5)(9.4)
- タイムゾーンデータファイルが tzdata release 2019b に更新されて、ブラジルでの夏時間規則の変更に加えて、香港、イタリア、およびパレスチナの歴史的な修正が適用されました。 (11)(10)(9.6)(9.5)(9.4)
一時関数の発効には長らく、pg_temp.func_name(args) という明示的な一時スキーマの指定が必要でした。これは、pg_temp.type_name(arg) と関数風の構文を使って一時データ型にキャストする場合も同様に必要です。そうでないと一時オブジェクトを使って関数呼び出しを横取りすることができて、8.2.4バージョンで防止された CVE-2007-2138 の脆弱性と同様の方法で、権限拡大を狙うことが可能でした。
一時スキーマとは一時オブジェクトのためのスキーマです。pg_temp_1 など番号を伴う名前が自動付与されますが、指定する場合には pg_temp という名前で代表させることができます。また、search_path に明示的な pg_temp の指定が無いと一時スキーマは優先して選択されます。
本修正後は、以下例の最初の型キャストは使用できず、型キャストのための処理に進む前にエラーになります(後者の 2つもエラーですが、これらは型キャスト処理が働いた結果のエラーです)。
db=# CREATE DOMAIN pg_temp.nonempty AS text CHECK (VALUE <> ''); db=# SELECT nonempty(''); ERROR: function nonempty(unknown) does not exist HINT: No function matches the given name and argument types. You might need to add explicit type casts. db=# SELECT pg_temp.nonempty(''); ERROR: value for domain nonempty violates check constraint "nonempty_check" db=# SELECT ''::nonempty; ERROR: value for domain nonempty violates check constraint "nonempty_check"
ハッシュ化された副プランは、ハッシュ要素を比較するために外側の問い合わせの元の比較演算子を使用していました。その演算子が型を跨る場合は、全てのハッシュ要素が副問い合わせの出力型になるので、これは誤りでした。PostgreSQL本体に含まれるハッシュ可能な型を跨る演算子に対して、64bitマシンでは、この誤りはほぼ無害です。しかし、32bitマシンでは、クラッシュやサーバメモリの不当なデータ露出になる可能性があります。
以下の問い合わせは = 演算子が text型と副問い合わせからの name型(外側と異なるデータ型)との間で適用され、副問い合わせ結果が「hashed SubPlan 1」として扱われるので、問い合わせの形状としては本問題に該当します。
explain (verbose) SELECT 'foo'::text IN (SELECT 'bar'::name UNION ALL SELECT 'bar'::name);
拡張モジュールが、より大きなリスクをもたらすハッシュ可能な型を跨る演算子を提供しているかもしれません。
これは一つ前のマイナーリリースで混入した障害です。変更された列のインデックスが適切に処理されていませんでした。
インデックスを持つ列をいくつかデータ型変更する ALTER TABLE に対して、以下のエラーになる動作が報告されました。
ERROR: relation "《インデックス名》" already exists
特にトリガで実現されている外部キー制約で該当します。
本修正前には、トランザクションのコミット時に処理すべきトリガが削除されてしまったことで COMMIT時にエラーが生じる可能性がありました。
(例) db=# CREATE TABLE t4_1(f1 int primary key); db=# CREATE TABLE t4_2(f1 int REFERENCES t4_1 DEFERRABLE INITIALLY DEFERRED) PARTITION BY RANGE (f1); db=# CREATE TABLE t4_2_p1 PARTITION OF t4_2 FOR VALUES FROM (0) TO (10); db=# INSERT INTO t4_1 VALUES (1); db=# BEGIN; db=# INSERT INTO t4_2 VALUES (1); db=# ALTER TABLE t4_2 DROP CONSTRAINT t4_2_f1_fkey; (修正後はここで以下のようなエラーが生じる) ERROR: cannot ALTER TABLE "t4_2" because it has pending trigger events db=# COMMIT; (修正前はここで以下のようなエラーが生じる) ERROR: relation 16123 has no triggers
本修正前は「CREATE TRIGGER ... EXECUTE FUNCTION my_trigger_func('my params', 123);」などとして付与した引数が欠落してコピーされていました。
ALTER TABLE ... DROP COLUMN はパーティションキーである列の削除を拒絶します。しかしながら、間接的な削除(キー列のデータ型をカスケード削除する場合など)では、このようなチェックが働かず、キー列の削除を許していました。この結果、パーティションテーブルが壊れて、アクセスも削除もできなくなるおそれがありました。
本修正は、キー列の削除を要するカスケード削除の際にはパーティションテーブル全体を削除するという要素を pg_depend に追加します。これはパーティションテーブルが作られるときに追加されます。したがって、バージョンアップ前に作られた既存パーティションテーブルでは、キー列のみ削除されてしまうリスクが残ります。
この問題は組み込みのデータ型のパーティションキー列では発生しません。したがって、大部分のユーザには無害であると考えられます。
デフォルトパーティションでのみ一部の列を削除してあるなど、列が1対1対応でない場合に誤動作することがありました。
その後の有効なパーティションテーブルに対する操作(パーティション追加など)で、以下のようなエラーが生じる可能性がありました。
ERROR: attribute 4 of type t7_partition_1 has been dropped
これまではインデックスを作成しようとしたり、インデックスのあるパーティションテーブルに外部テーブルをアタッチするときに、以下のようなエラーが発生していました。
ERROR: cannot create index on foreign table "t8_parted"
これからは外部テーブルのパーティションについては単にインデックスが作られない動作になります。ただし、ユニークインデックスである場合には例えば以下のようなエラーになります。
ERROR: cannot create unique index on partitioned table "t8_parted"
通常、テーブルの主キー列が GROUP BY に含まれる場合は他のグループ化列を安全に除去することができます。主キー列でグループを特定できるからです。しかし、継承テーブルを読む場合には、親子テーブル間、子テーブル間をまたがるユニーク性は保証されないため、この最適化は使えません。
以下の誤動作が報告されました。最後の SELECT は 2行が返るのが正しい動作です。実行プランで c1列がグループ化対象から外れてしまっていました。
db1=# CREATE TABLE t11 (c0 INT PRIMARY KEY, c1 INT); db1=# CREATE TABLE t11c (c0 INT) INHERITS (t11); db1=# INSERT INTO t11 (c0, c1) VALUES (0, 0); db1=# INSERT INTO t11c (c0, c1) VALUES (0, 1); db1=# SELECT c0, c1 FROM t11 GROUP BY c0, c1; c0 | c1 ----+---- 0 | 0 (1 row)
この障害により、一部の EXISTS問い合わせからの結果行が重複し、誤った結果が返ります。
修正前も、処理が非効率にはなりますが、問い合わせ結果は正しいです。
PostgreSQLのプランナはインデックスを使って値の最大値、最小値を調べる動作をすることがあります。
プランナが列の最小値や最大値を知るために最近に作られたインデックスを使うとき、最近に無効になった実際には端点値を含まないタプルを誤って選択してしまう可能性がありました。
誤選択したタプルには NULL が入っているかもしれず、最悪の場合は、以下のエラーになります。
ERROR: found unexpected null value in index ...
本障害でよくある挙動は、誤った値が使われてプラン作成におけるデータ推測の品質が劣化することです。
遷移テーブルを使った処理で以下のエラーが出るケースが報告されました。
ERROR: executor could not find named tuplestore "《NEW遷移テーブル》"
EvalPlanQual処理は、READ COMMITTEDトランザクション隔離モードでの行の更新で使われる内部的な仕組みです。
外部キーの全列が同じデータ型でない場合に、ALTER TABLEが外部キーの再検証が必要かどうかの判断を誤る可能性がありました。この判断の誤りは常に保守的な方向で、再検証が不要なものを必要と判断すると見られます。したがって、不要な処理による性能上のバグと言えます。
これにより、ANALYZE の際に以下のエラーが出るのを回避します。
ERROR: tuple already updated by self
複数のトランザクションがトランザクションT1 が行ロックを解放するのを待っていて、T1 がそのロックレベルを格上げするとき、T1終了時に待っているトランザクションの間で偽性の(実際にはデッドロックではない)デッドロックが報告されました。
ここでのロックレベルの格上げとは、「SELECT ... FOR KEY SHARE」 の行ロックを取得している行に対して、次に「UPDATE ...」を行う場合などを指します。
本障害に該当した場合、デッドロック状態がデッドロックエラーにならず、問い合わせがキャンセルされるまで処理がブロックされてしまいます。
本障害が人工的な問い合わせ以外で発生するのかは明らかではありません。通常パラレルワーカがリーダプロセスで取得済みのロック以外を必要とすることは無いため、実際には問題はほぼ起きないと考えられます。
範囲データ型は、ある値以上である値より小さいという半開区間になるように境界値を標準化させます。これを誤って無限値(infinity、-infinity)に対しても同様に試みていました。無限値の場合には干渉しないようになりました。
修正前は以下のような奇妙な振る舞いが生じていました。
db1=# SELECT '[-infinity,infinity]'::daterange @> '-infinity'::date "include?"; include? ---------- t (1 row) db1=# SELECT '[-infinity,infinity]'::daterange @> 'infinity'::date "include?"; include? ---------- f (1 row) db1=# SELECT '[-infinity,infinity]'::daterange; daterange ---------------------- [-infinity,infinity) (1 row)
money型の最大値(あるいは負の最小値)に近い値で以下のように不正確な変換が生じる可能性がありました。
db=# select '-92233720368547758.07'::money, '-92233720368547758.07'::money::numeric(30,2); money | numeric ----------------------------+---------------------- $92,233,720,368,547,758.07 | 92233720368547758.00 (1 row)
これは pg_waldump のクラッシュをひき起こしました。
10以前のバージョンで作った Btreeインデックスがあって、それを pg_upgrade でバージョンアップした後のアクセスで問題が生じました。11 でも修正されていますが、実際にアサート失敗が起きるのは 12 の betaバージョンです。
これによって結果がテーブルに直接格納された場合の問題が回避されます。これまでは以下の処理でエラーが発生していました。
db=# CREATE TYPE two_int8s AS (q1 int8, q2 int8); db=# CREATE FUNCTION compresult(int8) RETURNS two_int8s LANGUAGE plpgsql AS $$ DECLARE r record; BEGIN r := ROW($1,$1); RETURN r; END $$; db=# CREATE TABLE two_int8s_tab (f1 two_int8s); db=# INSERT INTO two_int8s_tab VALUES (compresult(42)); db=# SELECT f1 FROM two_int8s_tab; f1 --------- (42,42) (1 row) (再接続後に実行) db=# SELECT f1 FROM two_int8s_tab; ERROR: record type has not been registered
ごくまれな場合に、Windows形式の改行コードを含むサービスファイルが誤って解析され、接続エラーになっていました。
ユーザ定義 opclass がユーザ定義範囲型のサブタイプ opclass である場合、関連するオブジェクトが誤った順序でダンプされ、リストアできないダンプが生成されていました。
opclass の依存関係を処理する潜在的なエラーはほかのケースでも発生する可能性がありますが、これは唯一知られているケースです。
NULL を Perl の undef値として扱わせて、それを jsonb に変換する場合に以下エラーが出るケースが報告されました。
ERROR: cannot transform this Perl type to jsonb
これにより、VS 2017 と SDK v10 の組み合わせでビルドする際にSDK v8.1 が無いとビルドに失敗する問題が回避されます。
場合によっては initdbコマンドは実際のゾーン名より優先して、これらの人工的なゾーン名のいずれかを選択していました。
これらの 2 つよりも C ライブラリのタイムゾーンの動作に一致するほうが優先されるようになります。
歴史的に IANA では、この人工的なゾーンに「Local time zone must be set--see zic manual page」のような省略形を設定します。tzdbデータベースの最新バージョンでは代わりに -00 が表示されますが、一部のプラットフォームでは何らか歴史的なフレーズを表示するためにデータを変更します。
最新の省略形が使用される場合に限ってこのタイムゾーンを表示することで、非常に長い文字列が abbrev列に出力されるのが防止されました。
これによって zicコマンドに新しい -b slim オプションが追加され、インストールされたゾーンファイルのサイズを削減できます。現在は使用されていませんが、将来的には有効になる可能性があります。