Amazon RDSデータベースプレビュー環境でPostgreSQL 19 Beta 1の新機能を試してみた

Amazon RDSデータベースプレビュー環境でPostgreSQL 19 Beta 1の新機能を試してみた

Amazon RDSデータベースプレビュー環境でPostgreSQL 19 Beta 1が利用可能になりました。今回は、SQL/PGQによるグラフクエリ、REPACKコマンドによるテーブル再編成、論理レプリケーションの動的有効化について、RDSプレビュー環境で確認した結果をまとめます。
2026.06.14

はじめに

2026年6月8日、Amazon RDSデータベースプレビュー環境でPostgreSQL 19 Beta 1が利用可能になりました。

https://aws.amazon.com/jp/about-aws/whats-new/2026/06/postgresql-19-beta-1-amazon-rds-database-preview-environment/

PostgreSQL 19では多くの新機能が追加されています。今回はその中から、SQL/PGQとREPACKをRDSプレビュー環境で動作確認し、論理レプリケーションの動的有効化についてはRDS上での状況を確認しました。

機能 概要 PG19 での変更点
SQL/PGQ SQL 標準のプロパティグラフクエリ CREATE PROPERTY GRAPH / GRAPH_TABLE の追加
REPACK テーブルの物理的な再編成 VACUUM FULLCLUSTERと同等の再編成を行う新コマンド。CONCURRENTLYオプションでオンライン実行可能
論理レプリケーション動的有効化 wal_level=replica でも論理レプリケーションを自動有効化 再起動なしで論理レプリケーションが利用可能に

各機能の詳細はPostgreSQL 19リリースノートを参照してください。

https://www.postgresql.org/docs/19/release-19.html

検証環境

項目
環境 Amazon RDS データベースプレビュー環境
リージョン us-east-2
エンジンバージョン PostgreSQL 19beta1 (19.20260604)
インスタンスクラス db.m6g.large
クライアント EC2 (Amazon Linux 2023) から psql 16.14 で接続
接続方式 EC2 に SSM で接続し、プライベートサブネット内の RDS に psql で接続
postgres=> SELECT version();
                                              version
----------------------------------------------------------------------------------------------------
 PostgreSQL 19beta1 on aarch64-unknown-linux-gnu, compiled by aarch64-unknown-linux-gnu-gcc (GCC) 12.4.0, 64-bit

SQL/PGQ(プロパティグラフクエリ)

PostgreSQL 19 Beta 1では、SQL標準のプロパティグラフクエリ(SQL/PGQ)が利用可能になっていました。既存のリレーショナルテーブルに対してプロパティグラフを定義し、GRAPH_TABLEMATCH句でグラフパターンマッチングを実行できます。

グラフの作成

まず、テスト用のテーブルとデータを用意します。

CREATE TABLE persons (id INT PRIMARY KEY, name TEXT);
CREATE TABLE friendships (id INT PRIMARY KEY, person_id INT REFERENCES persons(id), friend_id INT REFERENCES persons(id));
INSERT INTO persons VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie'), (4, 'Diana');
INSERT INTO friendships VALUES (1, 1, 2), (2, 2, 3), (3, 3, 4), (4, 1, 3);

これらのテーブルに対してプロパティグラフを定義します。

CREATE PROPERTY GRAPH friends_graph
  VERTEX TABLES (persons KEY (id))
  EDGE TABLES (
    friendships KEY (id)
      SOURCE KEY (person_id) REFERENCES persons (id)
      DESTINATION KEY (friend_id) REFERENCES persons (id)
  );

CREATE PROPERTY GRAPH が正常に実行できました。VERTEX TABLES で頂点となるテーブル、EDGE TABLES でエッジとなるテーブルを指定し、SOURCE / DESTINATION で方向を定義します。

基本クエリ(直接の友達)

Aliceの直接の友達を検索します。

SELECT * FROM GRAPH_TABLE (friends_graph
  MATCH (a IS persons WHERE a.name = 'Alice')-[e IS friendships]->(b IS persons)
  COLUMNS (a.name AS person, b.name AS friend)
);
 person | friend
--------+---------
 Alice  | Bob
 Alice  | Charlie
(2 rows)

MATCH 句でグラフパターンを記述し、COLUMNS 句で出力列を指定します。AliceからBob、Charlieへの友達関係が取得できました。

2ホップ探索(友達の友達)

Aliceから2ホップ先の人物を検索します。

SELECT * FROM GRAPH_TABLE (friends_graph
  MATCH (a IS persons WHERE a.name = 'Alice')-[IS friendships]->(b IS persons)-[IS friendships]->(c IS persons)
  COLUMNS (a.name AS person, b.name AS via, c.name AS friend_of_friend)
);
 person |   via   | friend_of_friend
--------+---------+------------------
 Alice  | Bob     | Charlie
 Alice  | Charlie | Diana
(2 rows)

パターンを連結するだけで多ホップの探索が記述できました。Alice → Bob → Charlie、Alice → Charlie → Dianaの2経路が得られています。

実践パターン: 協調フィルタリング

ECサイトのデータモデルで、「同じ商品を買った別の顧客」を見つける協調フィルタリングのパターンを試します。

CREATE TABLE customers (id INT PRIMARY KEY, name TEXT, city TEXT);
CREATE TABLE products (id INT PRIMARY KEY, name TEXT, price NUMERIC);
CREATE TABLE purchases (id INT PRIMARY KEY, customer_id INT REFERENCES customers(id), product_id INT REFERENCES products(id), purchased_at DATE);

INSERT INTO customers VALUES (1, 'Alice', 'Tokyo'), (2, 'Bob', 'Osaka'), (3, 'Charlie', 'Tokyo'), (4, 'Diana', 'Nagoya');
INSERT INTO products VALUES (1, 'Laptop', 120000), (2, 'Keyboard', 8000), (3, 'Mouse', 3000), (4, 'Monitor', 45000);
INSERT INTO purchases VALUES (1, 1, 1, '2025-01-01'), (2, 1, 2, '2025-01-05'), (3, 2, 1, '2025-02-01'), (4, 3, 2, '2025-02-10'), (5, 4, 1, '2025-03-01');

CREATE PROPERTY GRAPH shop_graph
  VERTEX TABLES (customers LABEL customer, products LABEL product)
  EDGE TABLES (
    purchases
      SOURCE KEY (customer_id) REFERENCES customers (id)
      DESTINATION KEY (product_id) REFERENCES products (id)
      LABEL bought
  );

Aliceと同じ商品を購入した顧客を探索します。

SELECT DISTINCT * FROM GRAPH_TABLE (shop_graph
  MATCH (alice IS customer WHERE alice.name = 'Alice')-[IS bought]->(prod IS product)<-[IS bought]-(other IS customer)
  COLUMNS (prod.name AS shared_product, other.name AS also_bought_by)
) WHERE also_bought_by != 'Alice';
 shared_product | also_bought_by
----------------+----------------
 Keyboard       | Charlie
 Laptop         | Bob
 Laptop         | Diana
(3 rows)

<-[IS bought]- で逆方向のエッジをたどることで、「同じ商品を買った別の顧客」というパターンを1つのMATCH句で表現できました。

REPACK コマンド

PostgreSQL 19ではVACUUM FULLCLUSTERと同等のテーブル再編成を行う新コマンドREPACKが追加されました。CONCURRENTLYオプションを使うと、処理中のアクセス排他ロックを最小限に抑え、読み書きを継続したままオンラインでテーブルを再編成できます。

テスト用データの準備

肥大化したテーブルを作成します。

CREATE TABLE bloat_test (id SERIAL PRIMARY KEY, data TEXT);
INSERT INTO bloat_test (data) SELECT repeat('x', 100) FROM generate_series(1, 100000);
DELETE FROM bloat_test WHERE id % 5 != 0;  -- 80% を削除

削除後のテーブルサイズは8920 kBです。物理的にはデータが残っているため、サイズは変わりません。

REPACK(通常)

REPACK bloat_test;

テーブルサイズが8920 kB → 1800 kBに縮小しました。通常のREPACKはアクセス排他ロックを取得してテーブル全体を書き直す仕様で、VACUUM FULLに近い動作です。

REPACK (CONCURRENTLY)

同じ条件で再度肥大化させたテーブルに対して、CONCURRENTLY オプションを試します。

REPACK (CONCURRENTLY) bloat_test;

テーブルサイズが8920 kB → 3400 kBに縮小しました。通常のREPACK(1800 kB)より大きい結果となりました。CONCURRENTLY実行時の処理方式やテーブル状態の違いが影響した可能性がありますが、詳細な要因は本検証では特定していません。CONCURRENTLYオプションは実行中の読み書きへの影響を抑えるための仕様とされています。本検証では、CONCURRENTLY指定で再編成が正常に完了することを確認しました。

REPACK (VERBOSE)

VERBOSEオプションで処理の詳細を確認します。別途準備した肥大化テーブルに対して実行しました。

REPACK (VERBOSE) bloat_test;
INFO:  repacking "public.bloat_test" in physical order
INFO:  "public.bloat_test": found 0 removable, 5000 nonremovable row versions in 468 pages
DETAIL:  0 dead row versions cannot be removed yet.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.

テーブルサイズは5248 kB → 568 kBに縮小しました。VERBOSE出力でページ数や行バージョンの内訳を確認できます。REPACK (CONCURRENTLY, VERBOSE) のように両オプションを組み合わせることも可能です。

VACUUM (FULL, CONCURRENTLY) は存在しない

なお、VACUUM FULLCONCURRENTLY オプションを指定することはできません。

VACUUM (FULL, CONCURRENTLY) bloat_test;
ERROR:  unrecognized VACUUM option "concurrently"

PostgreSQL 19ではオンラインでのテーブル再編成は REPACK (CONCURRENTLY) で行います。VACUUM FULL CONCURRENTLY という構文は存在しません。

論理レプリケーションの動的有効化

PostgreSQL 19のコミュニティ版では、wal_level=replicaの状態でも論理レプリケーションが必要になった際、自動的に有効化される仕組みが追加されました(リリースノートより)。従来はwal_level=logicalへの変更と再起動が必要でしたが、PG19では再起動なしで論理レプリケーションを開始できるとされています。新しいサーバー変数effective_wal_levelで実効的なWALレベルを確認できるとされています。

RDSプレビュー環境でこの機能の状況を確認しました。

wal_level の設定状況

SELECT name, setting, context, boot_val, reset_val
FROM pg_settings WHERE name = 'wal_level';
   name    | setting |  context   | boot_val | reset_val
-----------+---------+------------+----------+-----------
 wal_level | logical | postmaster | replica  | logical
(1 row)

RDSプレビュー環境ではwal_levelが既にlogicalに設定されていました。contextはpostmaster(変更には再起動が必要)です。なお、RDSではrds.logical_replicationパラメータを1に設定し再起動するとwal_level=logicalが適用される仕様です。

ALTER SYSTEM の制限

ALTER SYSTEM SET wal_level = 'replica';
ERROR:  ALTER SYSTEM command is not supported

RDSでは ALTER SYSTEM コマンドが利用できません。パラメータの変更はパラメータグループ経由で行います。

pg_reload_conf() の制限

SELECT pg_reload_conf();
ERROR:  permission denied for function pg_reload_conf

pg_reload_conf() も権限不足で実行できません。

RDS における状況のまとめ

リリースノートによれば、コミュニティ版PostgreSQL 19ではwal_level=replicaのまま論理レプリケーションが必要時に自動有効化されるとされています。しかしRDSプレビュー環境ではこの動的有効化を検証できる状況にありませんでした。RDSではrds.logical_replication = 1を設定し再起動で反映されるとwal_level=logicalが適用されます。そのため動的有効化が発動する前提条件(wal_level=replicaの状態)になりません。

  • ALTER SYSTEM がブロックされており、wal_level の変更はパラメータグループ経由でしか行えない
  • RDSでは従来通り rds.logical_replication パラメータ(パラメータグループ)で wal_level=logical を明示的に設定し、再起動する運用

RDSユーザーとしては、従来通りパラメータグループでrds.logical_replication = 1を設定し再起動する運用に変わりはありません。

まとめ

Amazon RDSデータベースプレビュー環境でPostgreSQL 19 Beta 1の新機能を確認しました。

SQL/PGQは、プロパティグラフの定義からGRAPH_TABLE / MATCHによるパターンマッチングまで正常に動作しました。REPACKコマンドは、テーブルを書き直して物理的に再編成するコマンドとして動作し、通常実行およびCONCURRENTLY指定で再編成が完了することを確認できました。

一方、論理レプリケーションの動的有効化については、今回のRDSプレビュー環境ではwal_levelが既にlogicalに設定されていたため、wal_level=replicaからの動的有効化そのものは検証できませんでした。少なくとも今回確認した範囲では、RDSでは従来通りパラメータグループでrds.logical_replication = 1を設定し、再起動して反映する形でした。

いずれもBeta 1時点の挙動であり、GAリリースまでに変更される可能性がある点はご留意ください。

この記事をシェアする

AWSのお困り事はクラスメソッドへ

関連記事