このページでは PostgreSQL 13(2020/9/24リリース) に関する技術情報をお届けします。
本ドキュメントは PostgreSQL のリリースノートを元に弊社で解説を加えたものです。
バージョン13の新機能については「PostgreSQL 13 検証報告」も参照してください。
バージョン13の主要な拡張
PostgreSQL 13 の主な拡張点は以下の通りです。
- B-treeインデックスの重複排除による性能改善と省スペース化
- 集約やパーティションテーブルを使った問い合わせの性能改善
- 拡張統計情報を用いたプラン作成の改善
- インデックスの並列VACUUM
- インクリメンタルソート
バージョン13への移行/互換性のない変更点
- SIMILAR TO ... ESCAPE NULL が必ず NULL を返すようになりました。 (Tom Lane) (13)
- json(b)_to_tsvector 関数で filter に指定した string に対して、完全にスペルチェックされるようになりました。 (Dominik Czarnota) (13)
- effective_io_concurrency に基づく並列リクエスト数の計算方法が変更されました。 (Thomas Munro) (13)
- pg_stat_ssl および pg_stat_gssapi システムビューで補助プロセスが表示されなくなりました。 (Euler Taveira) (13)
- ALTER FOREIGN TABLE ... RENAME COLUMN がより適切なコマンドタグを返すようになりました。 (Fujii Masao) (13)
- MATERIALIZED VIEW ... RENAME COLUMN がより適切なコマンドタグを返すようになりました。 (Fujii Masao) (13)
- wal_keep_segments パラメータの名前が wal_keep_size に変更されました。 (Fujii Masao) (13)
- PostgreSQL 8.0 より前の構文を使用して演算子クラスを定義できなくなりました。 (Daniel Gustafsson) (13)
- PostgreSQL 7.3 より前の構文を使用して外部キー制約を定義できなくなりました。 (Daniel Gustafsson) (13)
- PostgreSQL 7.3 より前に使われていた opaque型がサポートされなくなりました。 (Daniel Gustafsson) (13)
- パッケージ化されていない(9.1より前の)拡張機能のアップグレードがサポートされなくなりました。 (Tom Lane) (13)
- timezone データベース内の posixrules ファイルがサポートされなくなりました。 (Tom Lane) (13)
- ltreeモジュールで、lqueryパターンに中括弧付きの隣接するアスタリスクが含まれている場合(例:*{2}.*{3})、それを適切に *{5} として解釈するようになりました。 (Nikita Glukhov) (13)
- pageinspectモジュールの bt_metap関数が、オーバーフローする可能性が低い、より適切なデータ型を返すようになりました。 (Peter Geoghegan) (13)
この新しい動作は標準 SQL 規格に沿っています。以前は、SIMILAR TO ... ESCAPE NULL とした場合に、デフォルトのエスケープ文字列(バックスラッシュ文字)が使用されていました。 この変更は substring(text FROM pattern ESCAPE text) にも適用されます。
SIMILAR TO ... ESCAPE NULL に対応した関数は similar_escape() から、新たに追加された similar_to_escape() に変更されます。互換性のため従来動作をする similar_escape() 関数自体はそのまま残されます。
「col1 SIMILAR TO '%pattern%' ESCAPE NULL」は、12以前なら「col1 ~ similar_escape('%pattern%'::text, NULL::text)」、13以降なら「col1 ~ similar_to_escape('%pattern%'::text, NULL::text)」と書き換えできて、ビュー定義の中では後者の関数を使った形式で保存されるため、古いビューは以前の動作が維持された状態となります。
デフォルト値以外(すなわち 2以上)が設定されている場合に影響があります。
以前は、この effective_io_concurrency を基に調整された値が、Bitmap Heap Scan 時の並列リクエスト数として使用されていました。これからは、effective_io_concurrency が、そのまま並列リクエスト数として使用されます。以前の値から新しい値への変換は、次の SQL を使用して求めることができます。
SELECT round(sum(OLDVALUE / n::float)) AS newvalue FROM generate_series(1, OLDVALUE) s(n);
補助プロセスとは autovacuum launcher や walwriter、checkpointer といった、クライアント接続には対応するものではないプロセスのことです。
一貫性を向上させるように、待機イベントの名前が変更されました。待機イベントは pg_stat_activity ビューの wait_event に現れます。
以前は ALTER TABLE が返されていました。これからは ALTER FOREIGN TABLE を返されます。
以前は ALTER TABLE が返されていました。これからは ALTER MATERIALIZED VIEW を返されます。
このパラメータにより、スタンバイサーバー用に保持する WAL セグメントファイルの量が決まります。wal_keep_segments のようにファイル数ではなく、メガバイト単位で指定されます。次の式で、以前の wal_keep_segments から、ほぼ同等の wal_keep_size に設定する値を算出できます。
wal_keep_size = wal_keep_segments * wal_segment_size (通常 16MB)
CREATE EXTENSION の FROM オプションはサポートされなくなりました。 パッケージ化されていない拡張機能をまだ使用している場合は、PostgreSQL13 に更新する前にパッケージ化されたバージョンにアップグレードする必要があります。
IANA のタイムゾーングループはこの機能を廃止しました。そのため、今後、数年間でシステムのタイムゾーンデータベースから徐々に消えていくと予想されます。タイムゾーンデータの更新で予期しない動作の変更を防止するため、PostgreSQL 13 で本機能はサポートされなくなりました。これは、明示的なサマータイムルールがない POSIX スタイルのタイムゾーン仕様の動作にのみ影響します。 以前は、独自の posixrules ファイルを導入することで変換規則を決定できましたが、これからは固定の動作となります。
影響を受けるインストレーションに対する推奨される修正方法は、地理的なタイムゾーン名を使用することです。
(従来の不適切な動作例、13.0 からは後者も t になる) db=# SELECT ltree 'a.b' ~ '*{2}'; ?column? ---------- t (1 row) db=# SELECT ltree 'a.b' ~ '*{1}.*{1}'; ?column? ---------- f (1 row)
戻り値に含まれるいくつかの項目でデータ型が int型から bigint型、real型からdouble precision型に変更されています。
変更点
サーバ
パーティショニング
- パーティションの除外処理(プルーニング)がより多くのケースで可能となりました。 (Yuzuko Hosoya, Amit Langote, Álvaro Herrera) (13)
- パーティション毎の結合がより多くのケースで可能となりました。 (Ashutosh Bapat, Etsuro Fujita, Amit Langote, Tom Lane) (13)
- パーティションテーブルで行レベルの BEFOREトリガーがサポートされました。 (Álvaro Herrera) (13)
- パーティションテーブルに対して、ロジカルレプリケーションを構成することが可能となりました。 (Amit Langote) (13)
- 購読者(サブスクライバー)が、パーティションテーブルに対して購読(サブスクライブ)できるようになりました。 (Amit Langote) (13)
- 行全体の変数(table.*)がパーティション式で使用できるようになりました。 (Amit Langote) (13)
たとえば、パーティション境界が正確には一致しない場合でも、パーティションテーブル間のパーティション毎の結合を行えるようになりました。
ただし、この BEFOREトリガーでは、データを書き込む宛先のパーティションを変更することはできません。
以前は、パーティションテーブルに属するパーティションごとにレプリケーションを設定する必要がありました。 変更後は、パーティションテーブルを明示的に発行(パブリッシュ)できるようになり、そのパーティションテーブルに属するすべてのパーティションが自動的に発行されるようになりました。パーティションテーブルにパーティションが追加または削除されると、発行者(パブリッシャー)にも連動して追加または削除されます。
CREATE PUBLICATION オプションの publish_via_partition_root は、パーティションへの変更を、独自の変更として発行するか、親となるパーティションテーブルの変更として発行するかを制御します。
以前は、購読者はパーティション化されていないテーブルへの行しか購読できませんでした。
(例:以下が実行可能になります) db=# CREATE TABLE pt6 (a int, b int) PARTITION BY LIST ((pt6)); db=# CREATE TABLE pt6_p1 PARTITION OF pt6 FOR VALUES IN ('(1,2)'); db=# CREATE TABLE pt6_p2 PARTITION OF pt6 FOR VALUES IN ('(2,4)');
インデックス
- B-Treeインデックスにキー値が格納されるときに、重複が排除されるようになりました。 (Anastasia Lubennikova, Peter Geoghegan) (13)
- box型に対して定義された GiST および SP-GiSTインデックスが ORDER BY box <-> point を含んだ問い合わせに対応しました。 (Nikita Glukhov) (13)
- GIN インデックスが !(否定) を含んだ tsquery 検索を、より効率的に処理できるようなりました。 (Nikita Glukhov, Alexander Korotkov, Tom Lane, Julien Rouhaud) (13)
- インデックスの演算子クラスがパラメータを受け取れるようになりました。 (Nikita Glukhov) (13)
- CREATE INDEXで GiSTシグネチャの長さと整数範囲の最大数を指定できるようになりました。 (Nikita Glukhov) (13)
これにより、重複したキー値は 1つだけ保存されることになり、カーディナリティの低い(値の種類が少ない)列に対しても効率的な B-Treeインデックスを作成できるようになりました pg_upgrade を利用してアップグレードした場合には、REINDEX を使用して、既存のインデックスから重複を排除する必要があります。
これによりインデックス作成時に演算子クラスと共にパラメータも指定するという使い方が実現できました。次項目も参照してください。
4バイトおよび 8バイトの intarray、tsvector、pgtrgm、ltree、および hstoreデータ型で作成されたインデックスは、デフォルト値を使用するのではなく、これらのGiSTインデックスのパラメータを使用して制御できるようになりました。
(例: hstore の gistインデックスにシグネチャ長を指定) db=# CREATE INDEX hidx ON t11 USING gist (h gist_hstore_ops(siglen=2024));
ユニークキー制約または主キー制約に該当するインデックスの照合順序は基になる列の照合順序と一致する必要がありますが、これまでは ALTER TABLE ではこのチェックが漏れていました。
オプティマイザ
- 包含/一致の演算子に対するオプティマイザの選択性推定が改善されました。 (Tom Lane) (13)
- 拡張統計オブジェクトに対して統計対象を設定できるようになりました。 (Tomas Vondra) (13)
- 1つのクエリで複数の拡張統計オブジェクトを使用できるようになりました。 (Tomas Vondra) (13)
- OR句および IN / ANY 定数リストに対して拡張統計オブジェクトを使用できるようになりました。 (Pierre Ducroquet, Tomas Vondra) (13)
- FROM句の中で使用される関数が定数として評価される場合、それらがインライン化できるようになりました。 (Alexander Kuzmenkov, Aleksandr Parfenov) (13)
jsonb型に対する @> 演算子などが該当します。
新しいコマンドオプション ALTER STATISTICS ... SET STATISTICS で設定できます。以前は、より一般的な統計対象の設定(default_statistics_target や各列の指定 )に基づいて計算されていました。
以下のような形状の問い合わせで、IMMUTABLEな関数の繰り返し実行やテーブル結合を省略することができます。
db=# explain (costs off) SELECT * FROM t17, to_tsquery('english', 'abc') q WHERE tsv @@ q; (インライン化された実行プラン) QUERY PLAN --------------------------------------- Seq Scan on t17 Filter: (tsv @@ '''abc'''::tsquery) (2 行) (従来の実行プラン) QUERY PLAN ------------------------------------- Nested Loop Join Filter: (t17.tsv @@ q.q) -> Function Scan on to_tsquery q -> Seq Scan on t17 (4 行)
性能一般
- インクリメンタルソートが実装されました。 (James Coleman, Alexander Korotkov, Tomas Vondra) (13)
- inet型の値に対するソート処理のパフォーマンスが向上しました。 (Brandur Leach) (13)
- 大規模な集約結果セットむけに、ディスクストレージを使用したハッシュ集約が可能になりました。 (Jeff Davis) (13)
- UPDATE および DELETE だけでなく、INSERT でも自動VACUUM が行えるようになりました。 (Laurenz Albe, Darafei Praliaskouski) (13)
- maintenance_io_concurrency パラメーターが追加され、メンテナンス操作の I/O同時実行性を制御できるようになりました。 (Thomas Munro) (13)
- wal_level が minimal の場合、リレーションを作成または書き換えるトランザクションで必ずしも WAL を作成しなくなりました。 (Kyotaro Horiguchi) (13)
- 多くのテーブル空間が使用されているときに実行した DROP DATABASEコマンドの WALリプレイの性能が向上しました。 (Fujii Masao) (13)
- 巨大なリレーションに対する TRUNCATEコマンドの性能が向上しました。 (Kirk Jamison) (13)
- TOASTされたデータに対する先行バイトの取得処理が改善しました。 (Binguo Bao, Andrey Borodin) (13)
- LISTEN/NOTIFY コマンドの性能が向上しました。 (Martijn van Oosterhout, Tom Lane) (13)
- 整数型からテキスト型への変換処理が高速化しました。 (David Fetter) (13)
- 多くの SQL文を含む、問い合わせ文字列や拡張スクリプトを実行した際のメモリ使用量が削減されました。 (Amit Langote) (13)
クエリの部分結果が、1つ以上のソートキーで既にソートされている場合、残りのソートキーのみを考慮して追加のソートを実行できます。必要に応じて enable_incremental_sort を変更することで制御できます。
以前は work_mem メモリ以上の集約結果セットとなることが予想される場合、ハッシュ集約は行われませんでした。ハッシュテーブルのサイズが work_mem に hash_mem_multiplierをかけた値を超えると、ディスクストレージが使用されるようになります。
この動作は、ハッシュ集約が選択されるとハッシュテーブルがどんなに大きくても(プランナーが誤って推定した場合は非常に大きくなる可能性があります)、それをメモリ内に保持しようとする以前の振る舞いよりも、望ましいと考えられます。
必要に応じて hash_mem_multiplier 設定値を増やすことで、以前と同様の挙動とすることができます。
以前は、挿入のみの処理では削除するデッドタプルが存在しないという理由で、自動ANALYZE は行われましたが、自動VACUUM は行われませんでした。しかしながら、VACUUM 処理には、可視性マップのビットの設定など、他の有用な副作用があり、INDEX ONLY SCAN の効率が向上します。また、INSERT 専用テーブルに定期的な VACUUM をかけることで、古いタプルに対する凍結処理を分散させることができるため、テーブル全体が XID周回防止のしきい値に達した際に突然発生する、大量の凍結処理を行う必要がなくなります。
この動作は、新規追加パラメータ autovacuum_vacuum_insert_threshold および autovacuum_vacuum_insert_scale_factor、または同様の制御を行うテーブルの格納オプションで調整できます。
wal_skip_threshold より大きいサイズのリレーションは、WAL を生成するのではなく、fsync を実行します。以前は、この動作は COPY操作に対してのみ実行されていましたが、クラッシュリカバリ中にデータ損失を引き起こす可能性のあるバグがありました。
以前は一部の先行バイトのみが必要であることがわかっている場合でも、圧縮された行外TOASTデータを全て取得していました。これからは結果を生成するのに十分なデータのみが取得されるようになります。
モニタリング
- EXPLAIN、auto_explain、自動VACUUM および pg_stat_statements でWAL使用の統計を追跡するようになりました。 (Kirill Bychik, Julien Rouhaud) (13)
- すべてのSQL文ではなく、SQL文をサンプリングしてログに記録できるようになりました。 (Adrien Nayrat) (13)
- csvlog の出力にバックエンド種別の列が追加され、log_line_prefix にバックエンド種別を出力させる %b オプションが追加されました。 (Peter Eisentraut) (13)
- プリペアドステートメントのパラメータロギングの制御が改善されました。 (Alexey Bashtanov, Álvaro Herrera) (13)
- エラー後に関数呼び出しのバックトレースが記録できるようになりました。 (Peter Eisentraut, Álvaro Herrera) (13)
- オーバーフローしないように VACUUM バッファカウンタを64ビット幅にしました。 (Álvaro Herrera) (13)
EXPLAIN のオプションに「WAL」が加わり、auto_explain に auto_explain.log_wal 設定が加わりました。自動VACUUM のログメッセージに「WAL usage:」が報告されます。pg_stat_statements に wal_bytes、wal_records および wal_num_fpw 列が加わりました。
実行時間が log_min_duration_sample を超えるSQL文の対象の中からlog_statement_sample_rate の割合でログに記録されます。
設定 log_parameter_max_length でエラー以外のステートメントのログ記録中に出力されるパラメータ値の最大長を制御し、エラーのあるステートメントのログ記録ではlog_parameter_max_length_on_error が同じことを行います。以前は、エラー時にはプリペアドステートメントのパラメータはログ記録されませんでした。
backtrace_functions 設定に、エラー時にバックトレースを生成する C関数名を指定します。
システムビュー
- pg_stat_activity ビューにパラレルワーカーのリーダープロセスを報告する leader_pid列が追加されました。 (Julien Rouhaud) (13)
- ストリーミングベースのバックアップの進捗状況を報告するpg_stat_progress_basebackup システムビューが追加されました。 (Fujii Masao) (13)
- ANALYZE の進捗状況を報告する pg_stat_progress_analyze システムビューが追加されました。 (Álvaro Herrera, Tatsuro Yamada, Vinayak Pokale) (13)
- 共有メモリの使用状況を表示する pg_shmem_allocations システムビューが追加されました。 (Andres Freund, Robert Haas) (13)
- 内部 SLRUキャッシュを監視する pg_stat_slru システムビューが追加されました。 (Tomas Vondra) (13)
- track_activity_query_size が最大 1MB まで設定できるようになりました。 (Vyacheslav Makarov) (13)
以前の最大値は 100kB でした。
待機イベント
- posix_fallocate() を使った DSM セグメントの作成中に待機イベントが報告されるようになりました。 (Thomas Munro) (13)
- コストベースのバキューム遅延を報告する待機イベント VacuumDelay が追加されました。 (Justin Pryzby) (13)
- WALアーカイブとリカバリ一時停止の待機イベント、BackupWaitWalArchive と RecoveryPause が追加されました。 (Fujii Masao) (13)
- リカバリコンフリクトを監視するための待機イベントとして RecoveryConflictSnapshot と RecoveryConflictTablespace が追加されました。 (Masahiko Sawada) (13)
- BSDベースのシステムでの待機イベントの性能が改善されました。 (Thomas Munro) (13)
認証
- スーパーユーザにのみ ssl_passphrase_command 設定の表示が許可されるようになりました。 (Insung Moon) (13)
- 暗号化された接続で使用するサーバのデフォルト最小 TLS バージョンが1.0 から 1.2 に変更されました。 (Peter Eisentraut) (13)
これはセキュリティ上の予防措置として変更されました。
この選択は ssl_min_protocol_version 設定パラメータで制御できます。
サーバ設定
- 読み取り専用のトランザクションモードでユーティリティコマンドを許可するルールが厳格化されました。 (Robert Haas) (13)
- システムテーブルの変更を許可する allow_system_table_mods 設定が、サーバ再起動なしに変更できるようになりました。 (Peter Eisentraut) (13)
- allow_system_table_mods が設定されている場合、スーパーユーザ以外のユーザがシステムテーブルを変更できないようになりました。 (Peter Eisentraut) (13)
- Windows で Unixドメインソケットがサポートされるようになりました。 (Peter Eisentraut) (13)
また、副次的な効果として、パラレルクエリで実行できるユーティリティコマンドの数が増えました。ALTER SYSTEM、CALL、DO、CHECKPOINT、COPY FROM、EXPLAIN、および SHOWが実行可能になっています。
以前は、サーバ起動時に allow_system_table_mods が設定されているとスーパーユーザ以外のユーザであってもシステムテーブルに対してINSERT/UPDATE/DELETE コマンドを発行することができました。
ストリーミングレプリケーションとリカバリ
- ストリーミングレプリケーションの設定がリロードで変更できるようになりました。 (Sergei Kornilov) (13)
- 永続的なレプリケーションスロットが指定されていない場合に、WALレシーバーが一時的なレプリケーションスロットを使用できるようになりました。 (Peter Eisentraut, Sergei Kornilov) (13)
- レプリケーションスロットの WAL格納が max_slot_wal_keep_size で制限できるようになりました。 (Kyotaro Horiguchi) (13)
- スタンバイの昇格が、要求された一時停止をキャンセルできるようになりました。 (Fujii Masao) (13)
- リカバリが指定されたリカバリ目標に到達しなかった場合、エラーが生成されるようになりました。 (Leif Gunnar Erlandsen, Peter Eisentraut) (13)
- ディスクにあふれだす前にロジカルデコーディングで使用されるメモリ量が制御できるようになりました。 (Tomas Vondra, Dilip Kumar, Amit Kapila) (13)
- 無効なページが WAL によって参照されている場合でもリカバリが継続できるようになりました。 (Fujii Masao) (13)
以前は、primary_conninfo と primary_slot_name 設定を変更するにはサーバ再起動が必要でした。
この動作は wal_receiver_create_temp_slot 設定パラメータを使用して有効に出来ます。
この値を超える必要があるレプリケーションスロットは無効と印付けされます。
以前は、スタンバイは一時停止状態のときには昇格できませんでした。
以前は、スタンバイは目標に到達していなくても、WAL の終わりに達すると自分自身を昇格していました。
これは logical_decoding_work_mem 設定で制御できます。
これは ignore_invalid_pages 設定パラメータで有効にできます。
ユーティリティコマンド
- VACUUM がテーブルのインデックスを並行して処理できるようになりました。 (Masahiko Sawada, Amit Kapila) (13)
- FETCH FIRST を WITH TIES と共に使用することで、最後の結果行にマッチする追加の行を返すことが可能になりました。 (Surafel Temesgen) (13)
- EXPLAIN コマンドの BUFFER オプション出力で、プラン作成時のバッファ使用量が報告されるようになりました。 (Julien Rouhaud) (13)
- CREATE TABLE LIKE で作成したテーブルに「CHECK」制約の「NO INHERIT」属性が伝播するようになりました。 (Ildar Musin, Chris Travers) (13)
- パーティションテーブルで LOCK TABLE を使用する場合に、子テーブルの権限を無視するようになりました。 (Amit Langote) (13)
- IDENTITY列への挿入で OVERRIDING USER VALUE句が利用可能になりました。 (Dean Rasheed) (13)
- 列から GENERATED属性を削除する ALTER TABLE ... DROP EXPRESSION 構文が追加されました。 (Peter Eisentraut) (13)
- 複数ステップの ALTER TABLE コマンドのバグが修正されました。 (Tom Lane) (13)
新たに加わった PARALLEL オプションで制御できます。
これまで継承(INHERITS)によるパーティションテーブルでは、親テーブルを通したアクセスでも子テーブルに対する権限も検査されていました。
IF NOT EXISTS句は、列がすでに存在する場合に派生アクション(インデックス作成など)が実行されないという点で、期待通りに動作するようになりました。
また、以前は動作しなかった関連するアクションを 1つの ALTER TABLE に連結する特定の場合でも動作するようになりました。
(例:12.x 以前では以下の ALTER TABLE はエラーになる) db=# CREATE TABLE t67 (f1 int); db=# ALTER TABLE t67 ADD COLUMN f2 int NOT NULL, ALTER COLUMN f2 ADD GENERATED ALWAYS AS IDENTITY, ALTER COLUMN f2 SET GENERATED BY DEFAULT SET INCREMENT 10;
ビューの列の名前を変更することはすでに可能でしたが、ALTER TABLE RENAME COLUMN と書く必要がありました。これは混乱を招きました。
これは、既存のオプション LC_COLLATE と LC_CTYPE が 1つのオプションにまとまったものです。
この動作は FORCE オプションで有効になります。
データ型
- 互換性のある引数を必要とする関数での使用のために、多様データ型がいくつか追加されました。 (Pavel Stehule) (13)
- FullTransactionId 変数を見せる SQLデータ型 xid8 が追加されました。 (Thomas Munro) (13)
- 照合順序オブジェクトの OID を人間が読める表現に変換するのに利用できる、データ型 regcollation と関連する関数が追加されました。 (Julien Rouhaud) (13)
新たなデータ型は、anycompatible、anycompatiblearray、anycompatiblenonarray、および、anycompatiblerange です。
既存の xidデータ型は 4バイトしか無いため、トランザクションエポックを提供できません。FullTransactionId 変数は PostgreSQL実装コード内で使われている 8バイトの変数です。なお、各行のメタ情報として格納されるトランザクションID は依然 4バイトです。
(使用例) db=# SELECT 12770::regcollation; regcollation -------------- "ja_JP.utf8" (1 row)
照合順序のベンダが libc であって glibc が使われている場合が対象です。これにより、glibcバージョンが変更された場合に、照合順序に依存するインデックスの破損が起こりうることについて警告が出るようになります。
ROW式による行コンストラクタの要素には、f1、f2、f3…という列名が自動で付与されます。以下に例を示します。
db=# SELECT (ROW(4, 5.0)).f1 ; f1 ---- 4 (1 row) db=# SELECT (ROW(123, 'AA'::text, 5.43::real)).*; f1 | f2 | f3 -----+----+------ 123 | AA | 5.43 (1 row)
関数
- NULL の扱いを改善した jsonb_set() の代替バージョンが追加されました。 (Andrew Dunstan) (13)
新関数 jsonb_set_lax() では新たな値として NULL が与えられた場合、null_value_treatment パラメータの指定に応じて様々な動作をさせることができます。
'use_json_null' JSON の null として扱う 'raise_exception' 例外(ERROR)を出す 'delete_key' 指定されたキーを削除する 'return_target' 変更せず元の JSON を返す
従来からの jsonb_set() 関数では、新たな値として NULL を与えると、戻り値が NULL になりました。
(jsonb_set_lanx() 関数の実行例) db=# SELECT jsonb_set_lax('{"A": 123, "B": [1,2,3]}'::jsonb, '{B,2}', NULL, null_value_treatment => 'use_json_null'); jsonb_set_lax ------------------------------- {"A": 123, "B": [1, 2, null]} (1 row)
これにより、JSON の値をタイムスタンプに変換して、JSON Path 式の中で処理することができます。また、タイムゾーンを認識した出力に対応した JSON Path 関数群が追加されます。
これらは特に WAL に関するモニタリング問い合わせに有用です。
認識できる名前は同じ書式パターンにおける to_char() 出力と同じです。
(実行例) db=# set lc_time TO 'ja_JP.UTF8'; db=# SELECT to_char('2010-04-01'::date, 'DD TMMONTH YYYY'); to_char ------------- 01 4月 2010 (1 row) db=# SELECT to_timestamp('01 4月 2010', 'DD TMMONTH YYYY'); to_timestamp ------------------------ 2010-04-01 00:00:00+09 (1 row)
これらのパターンは to_char()、to_timestamp() および、JSON Path の .datetime() で使用できます。
これまで、UUID生成関数は外部モジュールの uuid-ossp と pgcrypto にのみ在りました。
例: db=# SELECT min_scale('1.2345000'); min_scale ----------- 4 (1 row)
db=# SELECT trim_scale('1.2345000'); trim_scale ------------ 1.2345 (1 row)
一例として、これまでは「point <-> line」だけ使用できましたが、これからは「line <-> point」も使用できるようになります。
これまでの xid に基づく関数(txid_で始まる関数群)は、後方互換性のために未だ残されています。新たな関数との対応は下記の通りです。
txid_current() pg_current_xact_id() txid_current_if_assigned() pg_current_xact_id_if_assigned() txid_current_snapshot() pg_current_snapshot() txid_snapshot_xip() pg_snapshot_xip() txid_snapshot_xmax() pg_snapshot_xmax() txid_snapshot_xmin() pg_snapshot_xmin() txid_visible_in_snapshot() pg_visible_in_snapshot() txid_status() pg_xact_status()
offset引数のデータ型が int から bigint に変更されています。
PARALLEL UNSAFE であったものが PARALLEL RESTRICTED に変更されたため、依然としてパラレルワーカーでの実行はできませんが、パラレルリーダーからは実行できます。
関数、マテリアライズドビュー、インデックス、トリガについて、依存性削除が可能で、このために ALTER ... NO DEPENDS ON EXTENSION ... 構文が追加されました。
PL/pgSQL
- PL/pgSQL の単純な式の性能が改善されました。 (Tom Lane, Amit Langote) (13)
- IMMUTABLE な式を使用する PL/pgSQL関数の性能を改善しました。 (Konstantin Knizhnik) (13)
例えば以下のコードは、プラス演算子や比較演算子が同じ引数に同じ結果を返す IMMUTABLE な演算子であり、それらが繰り返し評価されるため、本修正で大幅に高速化されます。
WHILE i < 10000000 LOOP i := i + 1; END LOOP;
クライアントインターフェイス
- libpq を使ったクライアントが暗号化接続に対してチャネルバインディングを要求できるようになりました。 (Jeff Davis) (13)
- 暗号化接続に対して許容する TLSバージョンの最小、最大を指定するlibpq 接続パラメータが追加されました。 (Daniel Gustafsson) (13)
- クライアント証明書のロックを解除するパスワードが使用可能になりました。 (Craig Ringer, Andrew Dunstan) (13)
- libpq が DER形式でバイナリエンコードされたクライアント証明書に対応しました。 (Craig Ringer, Andrew Dunstan) (13)
- ecpg の「EXEC SQL elif」指示子が正しく動作するように修正されました。 (Tom Lane) (13)
libpq の接続パラメータ channel_binding を使用することで、TLS接続の相手にユーザのパスワードを知っていることを証明させます。これは中間者攻撃を防止します。
パラメータ名は ssl_min_protocol_version と ssl_max_protocol_version です。デフォルトの最小TLSバージョンは TLS 1.2 です。以前は libpqクライアント側で最小TLSバージョンの指定は無かったため、これは振る舞いの変更と言えます。
libpq の sslpassword 接続パラメータでパスワードを与えることができます。
これまで elif は、 endif に続く ifdef と同様に振る舞っていました。そのため、同じ if ブロックの手前の分岐で成功しているのに、elif 分岐や続く分岐についても展開されてしまっていました。
明らかな誤動作ですが、既存コードの振る舞いに影響するため、メジャーバージョンアップでの修正となりました。
報告された誤動作例: 択一であるはずの変数定義が二つ現れている exec sql define itype 1; int main(void) { exec sql begin declare section; exec sql ifdef itype; int var1; exec sql elif ntype; numeric var1; exec sql else; float var1; exec sql endif; exec sql end declare section; } ↓ ecpg適用後 int main(void) { int var1 ; float var1 ; }
クライアントアプリケーション
psql
- psql のデフォルトプロンプトにトランザクション状態が加わりました。 (Vik Fearing) (13)
トランザクション状態は従来からプロンプト変数に %x で指定可能でしたが、それがデフォルトになりました。
(psqlプロンプト出力例) db=# BEGIN; BEGIN db=*# SELECT 1/0; ERROR: division by zero db=!# ROLLBACK; ROLLBACK db=#
これは PROMPT2 変数に %w を設定して実現できます。プロンプト2は SQL文が未だ終わっていないときに改行すると現れるものです。
(psqlプロンプト出力例) db=# \set PROMPT2 '%w' db=# SELECT col1, col2, col3 FROM tbl1 JOIN tbl2 USING (key1) WHERE tbl1.col2 = 123456;
以下のように使用します。
db=# SELECT * FROM t1 ; id | v ----+---- 1 | AA 2 | (2 rows) db=# SELECT * FROM t1 \g (border=2 null=*NIL*) +----+-------+ | id | v | +----+-------+ | 1 | AA | | 2 | *NIL* | +----+-------+ (2 rows)
新たなコマンドは以下の通りです。
\dAc 演算子クラスの一覧 \dAf 演算子族の一覧 \dAo 演算子族と演算子の一覧 \dAp 演算子族とサポート関数の一覧
テーブル、インデックス、ビューについて、「+」を伴う冗長モードのときに、permanent か temporary か unlogged かが表示されます。
(出力例) db=# \d+ List of relations Schema | Name | Type | Owner | Persistence | Size | Description -----------+-------+-------+----------+-------------+---------+------------- pg_temp_3 | tmp1 | table | postgres | temporary | 8 kB | public | tbl1 | table | postgres | permanent | 16 kB | public | utbl1 | table | postgres | unlogged | 0 bytes |
紐づく通常テーブル名や、付加されているTOASTテーブルのインデックスも報告されるようになりました。
エディタを終了するとき、問い合わせがセミコロンや \g で終了していない場合には、問い合わせバッファの内容が表示されるようになります。
これは \echo と似ていますが、標準出力ではなく標準エラーにテキストを出力します。
pgbench
- pgbench が accounts をパーティションテーブルとして作成できるようになりました。 (Fabien Coelho) (13)
- pgbench のコマンド \aset が追加されました。 (Fabien Coelho) (13)
- pgbench が初期データをクライアント側ではなくサーバ側で生成できるようになりました。 (Fabien Coelho) (13)
- pgbench が --show-script オプションで組み込みのスクリプトを表示できるようになりました。 (Fabien Coelho) (13)
これにより単純なパーティショニングの性能テストが容易にできます。
\gset と似ていますが、複数の問い合わせに使用できます。
サーバアプリケーション
- pg_basebackup でベースバックアップに欠損や不整合がないことを保証するマニフェストが生成され、検証できるようになりました。 (Robert Haas) (13)
ベースバックアップの検証は pg_verifybackup コマンドで行えます。マニフェストは pg_start_backup/pg_stop_backup 関数では生成されません。
(出力例: ベースバックアップの検証に成功した場合) $ pg_verifybackup backup backup successfully verified (出力例: ベースバックアップを破壊し、検証に失敗した場合) $ rm backup/base/16384/16397 $ dd if=/dev/zero of=backup/base/16384/16398 bs=8K count=1 1+0 records in 1+0 records out 8192 bytes (8.2 kB) copied, 0.000652167 s, 12.6 MB/s $ pg_verifybackup backup pg_verifybackup: error: "base/16384/16397" is present in the manifest but not on disk pg_verifybackup: error: checksum mismatch for file "base/16384/16398"
これは pg_stat_progress_basebackup ビューでベースバックアップの進捗状況を表示するのに必要です。必要ない場合は --no-estimate-size オプションで無効にできます。以前は -P/--progress オプションを指定した場合のみ計算していました。
これは pg_basebackup のオプションと同じもので、standby.signal を作成し、postgresql.auto.conf に必要な設定を追加します。
これは -c/--restore-target-wal オプションで有効にできます。
以前は、クラッシュ後はデータベースサーバを一旦起動し、クラッシュリカバリを行う必要がありました。これは --no-ensure-shutdown オプションを使って無効にできます。
GID (グローバルトランザクション識別子) 等が含まれ、二相コミットの障害調査に役立ちます。
(PREPARE TRANSACTION の WAL 出力例) rmgr: Transaction len (rec/tot): 138/ 138, tx: 491, lsn: 0/0163FEB8, prev 0/0163FE80, desc: PREPARE gid test: 2020-09-25 08:06:54.331912 JST
これは -P/--parallel オプションで有効にできます。
これは -j/--jobs オプションで有効にできます。
これは -f/--force オプションで有効にできます。
これらは、以前にオプション名が適切でないため、-s/--superuser および -S/--no-superuser オプションに置き換えられており、これまで互換性のために残されていました。
ドキュメント
- マニュアルに用語集が追加されました。 (Corey Huinker, Jürgen Purtz, Roger Harkavy, Álvaro Herrera) (13)
- マニュアル内の関数および演算子の表が分かりやすい書式に変更されました。 (Tom Lane) (13)
- マニュアルで使っている DocBook が 4.5 にアップグレードされました。 (Peter Eisentraut) (13)
ソースコード
- Visual Studio 2019 でのビルドに対応しました。 (Haribabu Kommi) (13)
- MSYS2 でのビルドに対応しました。 (Peter Eisentraut) (13)
- PowerPC コンパイラ向けに compare_exchange および fetch_add アセンブリ言語コードが追加されました。 (Noah Misch) (13)
- 全文検索の Snowball語幹辞書が更新されました。 (Panagiotis Mavrogiorgos) (13)
- Windows 2000 の対応が打ち切られました。 (Michael Paquier) (13)
- 非 ELF の BSD システムの対応が打ち切られました。 (Peter Eisentraut) (13)
- Python 2.5.x 以前の対応が打ち切られました。 (Peter Eisentraut) (13)
- OpenSSL 0.9.8 および 1.0.0 の対応が打ち切られました。 (Michael Paquier) (13)
- configure の --disable-float8-byval および --disable-float4-byval オプションが削除されました。 (Peter Eisentraut) (13)
- プランナのフック関数に問い合わせ文字列を渡すようになりました。 (Pascal Legrand, Julien Rouhaud) (13)
- TRUNCATE のフックが追加されました。 (Yuli Khodorkovskiy) (13)
- TLS 初期化のフックが追加されました。 (Andrew Dunstan) (13)
- デフォルトの Unix ドメインソケットディレクトリを定義する DEFAULT_PGSOCKET_DIR を空にしてビルドできるようになりました。 (Peter Eisentraut) (13)
- Unixプラットフォームで System V リソースキーの競合が軽減されました。 (Tom Lane) (13)
- オペレーティングシステムの機能で秘密情報を含むメモリを確実に消去するようになりました。 (Peter Eisentraut) (13)
- C言語ヘッダファイルの互換性を検査する headerscheck スクリプトが追加されました。 (Tom Lane) (13)
- 内部リストを cons-cell (値と次のセルへのリンクを持つオブジェクト) をつなげたものでなく、配列で実装するようになりました。 (Tom Lane) (13)
- 全文検索の問い合わせ (tsquery) を実行する TS_execute() の API が変更されました。 (Tom Lane, Pavel Borisov) (13)
これにより、ギリシャ語の語幹処理に対応し、デンマーク語およびフランス語の語幹処理が改善されます。
これらは、バージョン0 呼び出し規約の C言語関数との互換性のために残されていましたが、これからは使えなくなります。
これにより、Unix ドメインソケットには対応するけれどもデフォルトでは無効にするということができます。
キーの生成はポート番号でなく、データディレクトリの iノード番号をもとに行われるようになりました。
これにより、例えば、メモリ内に格納されたパスワードが消去されます。
これにより、多くのオブジェクトにアクセスする問い合わせの性能が向上します。
TS_execute() のコールバック関数は、これまで問い合わせに一致するか否かを返す仕様でしたが、これからはそれらに加えて不明を返す必要があります。これにより、重み付けをした問い合わせでインデックスを使っても、正しい結果を取得できるようになりました。
(修正前はインデックスを使うと、重み付け問い合わせで正しい結果が取得できない) db=# CREATE TABLE test_weight (fts tsvector); db=# INSERT INTO test_weight VALUES ('crew:1C shuttl:2C'::tsvector); db=# SELECT * FROM test_weight WHERE fts @@ to_tsquery('shuttle & !crew:a'); fts ----------------------- 'crew':1C 'shuttl':2C (1 行) db=# CREATE INDEX ON test_weight USING gin (fts); db=# SET enable_seqscan TO off; db=# SELECT * FROM test_weight WHERE fts @@ to_tsquery('shuttle & !crew:a'); fts ----- (0 行)
追加モジュール
- 拡張に trusted と指定できるようになりました。 (Tom Lane) (13)
- postgres_fdw でスーパーユーザ以外でもパスワードなしに外部サーバに接続できるようになりました。 (Craig Ringer) (13)
- postgres_fdw で証明書認証に対応しました。 (Craig Ringer) (13)
- sepgsql で TRUNCATE のアクセス制御に対応しました。 (Yuli Khodorkovskiy) (13)
- SQL と PL/Perl 間で論理値を変換する拡張 bool_plperl が追加されました。 (Ivan Panchenko) (13)
- pg_stat_statements で SELECT に FOR UPDATE があるか否かを区別して問い合わせ実行統計を収集できるようになりました。 (Andrew Gierth, Vik Fearing) (13)
- pg_stat_statements で実行計画の作成時間を収集できるようになりました。 (Julien Rouhaud, Pascal Legrand, Thomas Munro, Fujii Masao) (13)
- ltree でパターン一致を行う lquery の構文が ! (否定) をより論理的に処理するように改善されました。 (Filip Rembialkowski, Tom Lane, Nikita Glukhov) (13)
拡張は、これまでスーパーユーザでしかインストールできませんでしたが、これからは trusted と指定されたものであれば、データベースの CREATE 権限を持つユーザでもインストールできます。これにより、手続き言語の情報を格納するシステムカタログpg_pltemplate が pg_available_extension_versions に統合され、削除されました。
パスワードの要否はスーパーユーザでユーザマッピングの password_requiredオプションで設定できます。パスワードを不要にすると、データベースサーバの起動ユーザとして認証されるようになるため、.pgpass ファイルなどを使ってスーパーユーザとして接続されないように注意が必要です。
証明書はユーザごとに異なるものが使えます。
これまでは実行時間しか収集できませんでした。これは track_planning パラメータを on に設定すれば有効にできます。
これまで「*.!foo.*」は「foo」を含むラベル経路には一致しませんでしたが、これからは「foo」が含まれていても「foo」でないラベルが 1つ以上ある場合には一致するようになります。
また、「*」以外の任意のラベルでも {} で一致回数を指定できるようになりました。
(ltree型の lt列を持つテーブルに対する問い合わせ例) db=# SELECT * FROM t158; id | lt ----+----------- 1 | foo 2 | a.foo.org 3 | a.bar.org (3 rows) db=# SELECT * FROM t158 WHERE lt ~ '*.!foo.*'; (13.0 での応答) id | lt ----+----------- 2 | a.foo.org 3 | a.bar.org (2 rows) (12.x での応答) id | lt ----+----------- 3 | a.bar.org (1 row)