このリリースは 12.10 からの修正リリース(2022年5月12日リリース)です。
12.X からのアップデートではダンプ、リストアは不要です。
また、12.10 よりも前のバージョンからアップデートする場合には、12.10 のリリース情報も参照してください。
PostgreSQL 12.10 から 12.11 への変更点
14.3、13.7、12.11、11.16、10.21 の各バージョンが同時にリリースされており、本ページでは共通の記載としています。各修正項目が適用されるバージョン系列番号を項目末尾に括弧書きで記載しています。
- 「セキュリティ限定された操作」のサンドボックス内では追加操作を制限するようにしました。 (Sergey Shinderuk, Noah Misch) (14)(13)(12)(11)(10)
- gist_ltree_ops のインデックスについて、デフォルトのシグネチャ長が修正されました。 (Tomas Vondra, Alexander Korotkov) (14)(13)
- 素のテーブルを参照する行全体の値の列に対して、問い合わせで指定された列の別名を使わないようにしました。 (Tom Lane) (14)(13)(12)(11)(10)
- interval型からエポック値を抽出するときの誤った丸めが修正されました。 (Peter Eisentraut) (14)
- pg_stat_get_replication_slot(NULL) 実行時のクラッシュが防止されました。 (Andres Freund) (14)
- table_to_xmlschema() などの XML関数における timestamptz型、timetz型の誤った出力が修正されました。 (Renan Soares Lopes) (14)(13)(12)(11)(10)
- 列数がゼロの「VALUES」句のパーサ処理のクラッシュが回避されました。 (Tom Lane) (14)(13)(12)(11)(10)
- プランノードの Result が Append ノードのすぐ下にあらわれる場合のプランナのエラーやクラッシュが修正されました。 (Etsuro Fujita) (14)
- 「SEARCH」句または「CYCLE」句を使用するクエリに重複するテーブル式の名前が含まれている場合のプランナのエラーやクラッシュが修正されました。 (Tom Lane, Kyotaro Horiguchi) (14)
- 外側のクエリ階層を参照する GROUPING() 構文のプランナエラーが修正されました。 (Richard Guo, Tom Lane) (14)(13)(12)(11)(10)
- 返却可能な列と返却不可能な列の両方を持つインデックスに対するインデックスオンリースキャンのプラン生成が修正されました。 (Tom Lane) (14)(13)(12)(11)(10)
- EvalPlanQual の実行中に古いタプルをロックしようとする際に、ピン(PIN)で固定されなくなった共有バッファにアクセスしないようになりました。 (Tom Lane) (14)(13)(12)
- 再並べ替えを実行している IndexScanノードでの、クエリ存続期間におけるメモリリークが修正されました。 (Aliaksandr Kalenik) (14)(13)(12)(11)(10)
- 関数の並列性属性と「SET」変数リストを同じコマンドで変更できるように ALTER FUNCTION が修正されました。 (Tom Lane) (14)(13)(12)(11)(10)
- 制約に「所有されている」インデックスの検出が厳格化されました。 (Tom Lane, Japin Li) (14)
- ALTER TABLE でテーブルのシステム列を変更しようとすると、間違ったエラーが発生する問題が修正されました。 (Tom Lane) (14)(13)(12)
- 先頭キーが式であるインデックスを使用して CLUSTER 処理を行った場合に、テーブルの行が誤った並べ替えになる問題が修正されました。 (Peter Geoghegan, Thomas Munro) (14)(13)(12)(11)(10)
- ソートされた GiSTインデックスのビルド直後にシステムクラッシュが発生した場合のデータ損失が防止されました。 (Heikki Linnakangas) (14)
- パーティション化されたインデックスを削除する際にデッドロックエラーのリスクがあり、修正されました。 (Jimmy Yih, Gaurab Dey, Tom Lane) (14)(13)(12)(11)
- DROP TABLESPACE とチェックポイントの間の競合状態が修正されました。 (Nathan Bossart) (14)(13)(12)(11)(10)
- チェックポイント実行と並行して TRUNCATEコマンドを実行した後に、クラッシュリカバリが失敗する可能性があり、修正されました。 (Kyotaro Horiguchi, Heikki Linnakangas, Robert Haas) (14)(13)(12)(11)(10)
- 一時オブジェクト削除中における安全でないTOASTデータアクセスが修正されました。 (Andres Freund) (14)(13)(12)(11)(10)
- カスタム設定名の最初の文字に「_」が再度使えるようになりました。 (Japin Li) (14)
- compute_query_id 設定に指定可能な値として「regress」が追加されました。 (Michael Paquier) (14)
- RegisterSyncRequest の待機ロジックが改善されました。 (Thomas Munro) (14)(13)(12)
- 書き込みと書き込みの間で checkpointerプロセスが待機しているときにはラッチイベントを起こすようになりました。 (Thomas Munro) (14)
- WAL の後続レコードが欠けている時にスタンバイを昇格すると「PANIC: xlog flush request is not satisfied」が発生する問題が修正されました。 (Sami Imseih) (14)(13)(12)(11)(10)
- ホットスタンバイのコンフリクトを処理する際に自己デッドロックが起きる可能性があり、修正されました。 (Andres Freund) (14)(13)(12)(11)(10)
- ロジカルレプリケーションの変更を送信する際、パーティションの先祖関係を間違ってしまう可能性があり、修正されました。 (Tomas Vondra, Hou zj, Amit Kapila) (14)(13)
- max_sync_workers_per_subscription 設定の制限に抵触する場合でもロジカルレプリケーションの apply workerプロセスが再起動されるようになりました。 (Amit Kapila) (14)(13)(12)(11)(10)
- UPDATE に対して、変更されていないレプリカアイデンティティ(REPLICA IDENTITY)のキー列を、それが外部TOAST格納されている場合には WALログに含めるようになりました。 (Dilip Kumar, Amit Kapila) (14)(13)(12)(11)(10)
- psコマンドにおけるサーバプロセス表示の置き換えに対応していないプラットフォームを適切に処理できるようになりました。 (Andrew Dunstan) (14)(13)
- タイマ割り込みの見逃しに対して、より頑健になりました。 (Michael Harris, Tom Lane) (14)
- PL/Perl関数のコンパイル時には SPI関数は実行できないようになりました。 (Tom Lane) (14)(13)(12)(11)(10)
- libpq が root所有の SSL秘密鍵ファイルを受け入れるようになりました。 (David Steele) (14)(13)(12)(11)(10)
- libpq の PQisBusy()関数の接続エラー後の動作が修正されました。 (Tom Lane) (14)(13)(12)
- psql、pg_dump、および pg_amcheck で「データベース.スキーマ.テーブル」という構文を再度許容するようになりました (Mark Dilger) (14)
- pg_ctl は、stop/restart/promote の動作を待機している間、postmasterプロセスが動作していることを再チェックするようになりました。 (Tom Lane) (14)(13)(12)(11)(10)
- pg_waldump のエラー処理が修正されました。 (Kyotaro Horiguchi, Andres Freund) (14)(13)(12)(11)
- contrib/pageinspect の関数が全てゼロのページに対応するようになりました。 (Michael Paquier) (14)(13)(12)(11)(10)
- contrib/pageinspect で、破損したページの「特別な領域」に対する保護を追加し、正しいページサイズのチェックを強化し、不足していたインデックスの型チェックが追加されました。 (Michael Paquier, Justin Pryzby, Julien Rouhaud) (14)(13)(12)(11)(10)
- contrib/postgres_fdw で BEFORE INSERT ... FOR EACH ROW トリガが外部テーブルに存在する場合、バッチ挿入が無効にされました。 (Etsuro Fujita) (14)
- contrib/postgres_fdw で、リモートで順序付けされたクエリを要求する前にORDER BY句が安全に渡せることを検証し、必要に応じて USING句を含めるようになりました。 (Ronan Dunklau) (14)(13)(12)(11)(10)
- sys/epoll.h があり、sys/signalfd.h はないプラットフォームを扱えるようにconfigure が修正されました。 (Tom Lane) (14)
- LLVM 14 で動作するように JITコードが更新されました。 (Thomas Munro) (14)(13)(12)(11)
- clang の -fsanitize=undefined オプションで様々な障害をクリーンアップするようになりました。 (Tom Lane, Andres Freund, Zhihong Yu) (14)(13)(12)(11)(10)
- OpenSSL なしでビルドする場合は、libpq の pkg-config ファイルに OpenSSL の依存関係を追加しないように修正されました。 (Fabrice Fontaine) (14)
- 式の中にネストされたステートメントをサポートしない CコンパイラでビルドできるようにPL/Perl が修正されました。 (Tom Lane) (14)(13)(12)(11)(10)
- Windows でビルドに MSVC を使用していない場合に、pg_dumpall のビルドエラーが発生する可能性があり、修正されました。 (Andres Freund) (14)(13)(12)(11)(10)
- Windowsビルドでは、pexports の代わりに gendef を使用してDEFファイルを作るようになりました。 (Andrew Dunstan) (14)(13)(12)(11)(10)
- MinGW でビルドされたプログラムでの余分なワイルドカードパターンの展開が防止されました。 (Andrew Dunstan) (14)(13)(12)(11)(10)
- タイムゾーンデータファイルが tzdata release 2022a に更新されました。パレスチナでの夏時間法の変更に加えて、チリ、ウクライナの歴史的修正が含まれます。 (14)(13)(12)(11)(10)
- 論理レプリケーションのサブスクライバにおける、サポートされていないテーブル種別に対するエラーメッセージが改善されました。 (Tom Lane) (12)(11)(10)
自動VACUUM、CLUSTER、CREATE INDEX、REINDEX、REFRESH MATERIALIZED VIEW、pg_amcheck では「セキュリティ限定された操作」による保護が有効化されるのが遅すぎたり、全く働かなかったりしていました。
データベース内に永続オブジェクトを作成する権限を持ったユーザは、スーパーユーザ権限で任意の SQLコードを実行するオブジェクトを定義できました。仕込まれた SQLコードは、次に自動VACUUM が行われるときに、あるいは、スーパーユーザがそのオブジェクトに作用するいずれかのコマンドを実行したときに、実行されます。
本脆弱性は CVE-2022-1552 として登録されています。
ltree拡張を演算子クラスパラメータをサポートするようにアップグレードするときに、ltree列に対する GiSTインデックスのデフォルトのシグネチャ長(ハッシュサイズ)が、意図せず変更されてしまいました。最初から ltree をバージョン 1.2 にアップグレードしている場合を除き、このようなインデックスに何らか操作が行われた場合、シグネチャ長が 8バイトではなく 28バイトと見做されて動作します。したがって、おそらくそのインデックスは壊れています。安全のためバージョンアップ後に全ての ltree の列に対する GiSTインデックスを再作成(REINDEX)することを推奨します。なお、ltree[] 配列の列に対する GiSTインデックスには影響しません。
選択リストの最上位以外での tbl.*などの行全体変数から作られたタプルの列名は、今後は、もしあるなら常に関連して名前付けされた複合型の要素名になります。これまでは FROM のエントリに適用された全ての列の別名を追跡させるように試みていました。しかし、これは意味がないと判断されました。
従来実装では、行全体をあらわす列を使用したテーブルを作った後、行全体の列の元となるテーブルの列名を付け直した場合に、そのようなテーブルのSELECT で予期せぬエラーが発生して、格納したデータが読めなくなってしまうことがありました。
(報告された障害発生ケース) db=# CREATE TABLE t3 (data int); db=# CREATE VIEW v3 AS SELECT t3 FROM t3; db=# CREATE TABLE t3_log (ts timestamp, what v3); (列名を付け直す操作) db=# ALTER TABLE t3 ADD big_data bigint; db=# UPDATE t3 SET big_data = data; db=# UPDATE t3_log SET what.t3.big_data = (what).t3.data; db=# ALTER TABLE t3 DROP data; db=# ALTER TABLE t3 RENAME big_data TO data; db=# INSERT INTO t3 VALUES (123456); db=# INSERT INTO t3_log SELECT now(), v3 FROM v3; (この時は正しく出力) db=# SELECT * FROM t3_log; ts | what ----------------------------+-------------- 2022-05-16 13:49:54.862458 | ("(123456)") (1 row) db=# \c (接続し直した後にはエラーになる) db=# SELECT * FROM t3_log; ERROR: record type has not been registered
列名を付け直したい場合の本障害の回避策は、副問い合わせの階層を追加して、行全体の変数が副問い合わせの出力を参照して、素のテーブルを参照しないようにすることです。これは上記のエラー発生例で言えば「CREATE VIEW ...」を「CREATE VIEW v3 AS SELECT v::t3 AS t3 FROM (SELECT * FROM t3) v(d);」と記述することです。
numeric型を返すようになった新しい EXTRACT の実装コードで、誤って DAYS_PER_YEAR 定数を整数型に変換して切り捨てていたため、13.x バージョン以前の float型を返すコードと戻り値が異なっていました。
この関数はカタログデータで STRICT と定義されるべきでしたが、バージョン14 ではこれが指定されていなかったため、代替策として、関数実装に実行時のチェックが追加されました。
これらのデータ型に対する XMLスキーマ出力では文字列パターンの正規表現が壊れていました。
(報告された障害発生ケース) db=# CREATE TEMP TABLE nocols(); db=# INSERT INTO nocols DEFAULT VALUES; db=# SELECT * FROM nocols n, LATERAL (VALUES(n.*)) v; 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.
非同期リモートクエリをサポートするために最近追加されたコードは、このケースを処理できず、クラッシュや「ERROR: unrecognized node type ..」などの認識されないノードタイプに関するエラーが引き起こされました。
再帰的な WITH クエリの名前が自身の中で再利用されると、プランナがクラッシュしたり、奇妙なエラーを報告したりする可能性がありました。
(障害発生例) db=# WITH RECURSIVE x(col) as ( SELECT 1 UNION ( WITH x AS (SELECT * FROM x) SELECT * FROM x) ) SEARCH DEPTH FIRST BY col SET seq SELECT * FROM x; ERROR: could not find attribute 2 in subquery targetlist
奇妙なエラーやアサート失敗が報告されました。
(エラー発生例) db=# SELECT (SELECT GROUPING(v1)) FROM (VALUES ((SELECT 1))) v(v1) GROUP BY v1; ERROR: plan should not reference subplan's variable
以前のコーディングでは、返却可能な列に加え、返却不可能な列も読み取ろうとする可能性がありました。 これは実際には無効な値に対して何も行わなかったためおよそ無害でしたが、最近追加されたエラーチェックでそのようなプランを拒否して、下記のエラーメッセージを出していました。
ERROR: XX000: variable not found in subplan target list
EvalPlanQual は READ COMMITTED 隔離レベルの問い合わせにおける内部的な処理です。
従来コードはピンを解放した後、さらに数回バッファにアクセスしていました。理論的には別プロセスがピンがなくなった時点ですぐにバッファを再利用し(あるいは、より可能性が高いのは、その空き領域をデフラグしようとし)、タプルの新しいバージョンを見つけるのに失敗する可能性があります。
一つの ALTER FUNCTION コマンドで関数の「SET」句も更新した場合、並列性属性の変更が失われていました。
(誤動作例/「PARALLEL safe」を指定したので proparallel は 「s」が正しい) db=# CREATE FUNCTION public.f14() RETURNS int LANGUAGE sql AS 'SELECT 1'; db=# ALTER FUNCTION public.f14() SET timezone TO 'UTC' PARALLEL safe; db=# SELECT proname, proparallel, proconfig FROM pg_proc WHERE proname = 'f14'; proname | proparallel | proconfig ---------+-------------+---------------- f14 | u | {TimeZone=UTC} (1 row)
一部のコードパスで、外部キー制約が依存しているインデックスを、ユニーク制約または主キー制約によって所有されているインデックスと取り違えていました。その結果、外部キー制約を持つテーブルに対する特定の ALTER TABLE 操作に際して、下記のような奇妙なエラーが発生していました。
ERROR: relation 145678 has multiple clustered indexes または ERROR: "t15_pkey" is not an index for table "t15"
システムは「ERROR: cannot alter system column "cmax"」などと、それができないことを通知するべきですが、代わりに「ERROR: no owned sequence found」を報告する場合がありました。
テーブルは正しいデータで再構築されますが、インデックスの順序とはほとんど関係のない順序になりました。
ソートを使用して GiSTインデックスを構築するコードパスは、完了時にファイルの fsync を怠っていました。このため、その後すぐにオペレーティングシステムがクラッシュした場合、インデックスが破損する可能性がありました。
必要なテーブルとインデックスのロックが確実に標準的な順序(子の前に親、インデックスの前にテーブル)で取られるようになりました。DROP INDEX の以前のコーディングでは、これとは異なる方法でロックを取っていたため、標準的な順序でこれらのロックを取る同時実行の問い合わせに対してデッドロックが発生する可能性がありました。
DROP TABLESPACE によって強制されるチェックポイントが、テーブルスペースのディレクトリからすべてのデッドファイルを削除することに失敗して、以下のような偽のエラーが発生する場合がありました。
ERROR: tablespace "tblspc20" is not empty
チェックポイントが完了できるようになる前に、テーブルのディスクファイルが全削除されることをTRUNCATE は保証しなければなりません。そうでないと、そのチェックポイントから開始したリプレイが、削除されているはずのページの予期せぬデータを見つけて、リプレイ失敗を引き起こすおそれがありました。
サーバプロセス終了時に「FATAL: cannot fetch toast data without an active snapshot」のエラーを出して、一時オブジェクトの削除に失敗することがありました。次に一時スキーマを使う際に正常にクリーンアップされるため、通常は無害です。
バージョン14 ではそのような名前が意図せず使えなくなってしまっていました。
これはリグレッションテストを容易にすることを目的としており、クエリID が計算されるけれども EXPLAIN の出力には表示されません。
RegisterSyncRequest は局所的にストレージ同期の要求を受け付けたり、要求を checkpointerプロセスに転送したりする、内部実装関数です。
その中で checkpointer への同期要求キューが溢れた場合(shared_buffers が小さい場合に起こりえます)、その待ち行列が減るのを待つ動作をします。このときの待機を示す待機イベント「RegisterSyncRequest」が追加されました。
これは同期リクエストを送信するバックエンドの反応性を改善します。更にこの待機に対応した待機イベント「CheckpointerWriteDelay」も追加されました。
不運なタイミングのとき、WAL を適用するプロセスが他プロセスのバッファロックの解放を待って、動作が止まってしまう可能性がありました。
publish_via_partition_root オプションが true に指定されていて、更新するリレーションに対する異なる先祖で指定された複数のパブリケーションがある場合(即ち親子関係にあるリレーション各々にパブリケーションを作っている場合)、サブスクリプションへの変更の報告に際して間違った先祖リレーションを選択することがありました。
本設定に対する上限検査コードの欠陥により、これまでは再起動されたワーカを直ぐに終了してしまっていて、ほとんどのワーカが存続できませんでした。
この対処をしないと、サブスクライバはその値を見ることができないので、更新を正しく複製できないことになります。
このようなプラットフォームはほとんどありません。そのため、これまでリファクタリングが潜在的なメモリ破壊をもたらすことに気づかれませんでした。サポートされているプラットフォームで該当する唯一のものは Cygwin で、バックエンドプロセスのクラッシュが報告されました。
バージョン14 で追加された最適化は、なんらかの理由でサーバプロセスがタイマ割り込みを逃してしまった場合は他についてもカーネルに要求を繰り返さないというもので、セッションの以降においてタイムアウト検出に失敗することになりました。
これでは脆弱すぎると判断され、リカバリパスが追加されました。
PL/Perl関数のコンパイル時には Perl はユーザ定義コードを実行すると考えられます。しかしながら、SPI 経由の SQL操作を行うコードは望ましくなく、クラッシュかセキュリティ障害を起こす可能性がありました。関数の検証に際して本当にコード実行をしたいわけではありません。そこで、代わりに親切なエラーメッセージを出す検査が加えられました。
この変更により、libpq の SSL鍵ファイルの所有者とアクセス許可の安全チェックが、バージョン9.6 以降のサーバと統一されます。すなわち、現在のルールに加え、鍵ファイルの所有者が root であって、パーミッションが 0640 以下の場合を許容するようになりました。これは、鍵ファイルのシステム全体での管理に役立ちます。
書き込みエラーを検出した場合、PQisBusy() は常に真を返しましたが、これは誤りでした。サーバから何か読み取れるまで、通常は入力処理を継続したいところでした。
この障害の実際の影響は、libpq の非同期クエリAPI を使用するアプリケーションが、PQconsumeInput() が致命的なエラーを返した場合にしか接続断を検出しないことです。この修正により、接続断が順当にエラーの PGresult オブジェクトを介して報告されるようになりました。これはほとんどのアプリケーションにとって相応しい動作です。
14 より前のバージョンは、2つ以上の「.」を含むパターンにおけるスキーマとテーブル以外の全ての修飾名を黙って無視していました。バージョン14 でのリファクタリングの誤りで、そのユースケースがエラーになるようになってしまいました。本バージョンで復活しましたが、先頭の修飾名がカレントデータベースの名前と一致しない場合にはエラーが発生します。
(バージョン 14.2 で以下エラー/13.x 以前と 14.3 以降では実行可能) db1=# \d db1.public.t1 Did not find any relation named "db1.public.t1". (バージョン14.3 で以下エラー/13.x 以前では実行可能) db1=# \d foo.bar.public.t1 improper qualified name (too many dotted names): foo.bar.public.t1
pg_ctl は、stop または promote シグナルを送信する一方で postmasterプロセスが動作していること(PID が有効であるか)を 1回確認しますが、その後は単純に PIDファイルが削除されるまで待機していました。postmaster が PIDファイルを削除したり、制御ファイルを更新したりせず、非正常に終了した場合、pg_ctl はタイムアウトになるまで待機していました。
これに替えて postmasterプロセスがまだ存在しているかをときどき再チェックするようになりました。
WALセグメントサイズを知るために WALファイルを読み取ったとき、ファイルサイズが XLOG_BLCKSZ よりも小さい場合(例えば 0バイト)、pg_waldump は誤ったエラー報告をしていました。また、このエラーメッセージおよび関連するエラーメッセージで報告されるファイル名は無効である可能性がありました。
(報告された誤ったメッセージ/正しくないファイル名や要因が示される) pg_waldump: fatal: could not read file ".....": .....
これは正当な境界条件的ケースでしたが、このモジュールではほぼ想定されていませんでした。必要に応じて、NULL を返すか、行を返さないように変更されました。これは、エラーを発生させるよりも有効です。
これらの変更により、モジュールが不良データでクラッシュする可能性が低くなりました。
このようなトリガはテーブルを照会する際、手前で挿入した行を参照するかもしれません。バッチ挿入では、これらの行がまだ可視となってない可能性があるため、予期せぬ動作を回避するため、無効にされました。
この修正はリモートサーバが意図と異なる順序で並べ替えるケースを防止します。これは見た目だけの場合もありますが、リモートデータがローカルで実行されるマージ結合の入力として使用されると、完全に間違った結果が生じる可能性がありました。
これらの変更のほとんどは、C および POSIX 標準の文書に型通りに準拠するためのものであり、本番ビルドに影響を与える可能性はほとんどありません。
mingw の gcc によるビルドで問題が報告されました。
これにより、ビルドプロセスが最新の MSys ツールチェーンで機能するように調整されました。
何らかの理由で、MinGW によって提供される Cライブラリは、デフォルトでプログラムのコマンドライン引数のシェルワイルドカード文字を展開してしまいます。MSVC では特に発生しないため、これは混乱を招くのでパターン展開が無効化されました。
バージョン13 以降のサーバは、パーティションテーブルのパブリッシュがサポートされるようになりました。バージョン13 より古いバージョンのサーバは、パーティションテーブルのサブスクライブを処理できず、「table ... not found on publisher」のような誤解を招くエラーメッセージを表示していましたが、より的確なメッセージを表示するように修正されました。