Amazon RDS for PostgreSQL で PostgreSQL 拡張機能を使用する
PostgreSQL は、さまざまな拡張機能やモジュールをインストールすることで、機能を拡張することができます。例えば、空間データを操作するには、PostGIS 拡張機能をインストールして使用します。詳細については、「PostGIS 拡張機能を使用した空間データの管理」を参照してください。別の例として、非常に大きなテーブルへのデータ入力を改善する場合は、pg_partman
拡張機能を使用したデータのパーティション化を検討できます。詳細については、「pg_partman エクステンションによる PostgreSQL パーティションの管理」を参照してください。
注記
RDS for PostgreSQL 14.5 以降、RDS for PostgreSQL は Trusted Language Extensions for PostgreSQL をサポートしています。この機能は拡張機能 pg_tle
として実装され、RDS for PostgreSQL DB インスタンスに追加できます。この拡張を使用することで、開発者は安全な環境で独自の PostgreSQL 拡張を作成できるため、セットアップと設定の要件が簡素化されます。詳細については、「Trusted Language Extensions for PostgreSQL を使用した操作」を参照してください。
場合によっては、拡張機能をインストールする代わりに、Aurora PostgreSQL DB クラスターのカスタム DB クラスターパラメータグループの shared_preload_libraries
リストに特定のモジュールを追加することもできます。通常、デフォルトの DB クラスターパラメータグループでは、pg_stat_statements
のみが読み込まれますが、リストに追加できるモジュールは他にもいくつかあります。例えば、PostgreSQL pg_cron エクステンションによるメンテナンスのスケジューリング で説明されているように、pg_cron
モジュールを追加することでスケジュール機能を追加できます。別の例として、auto_explain
モジュールをロードすることでクエリ実行計画を記録できます。詳細については、AWS ナレッジセンターの「クエリ実行計画のログ記録
RDS for PostgreSQL のバージョンによっては、拡張機能をインストールする際に、以下のような rds_superuser
の権限が必要になる場合があります。
RDS for PostgreSQL バージョン 12 以前のバージョンでは、拡張機能をインストールする際に
rds_superuser
の権限が必要となります。RDS for PostgreSQL バージョン 13 以降のバージョンでは、特定のデータベースインスタンスに対する作成権限を持つユーザー (ロール) は、信頼できる拡張機能をインストールして使用することができます。信頼できる拡張機能のリストについては、「PostgreSQL 信頼できるエクステンション」を参照してください。
また、RDS for PostgreSQL DBインスタンスにインストール可能な拡張機能は、rds.allowed_extensions
パラメータにリストアップして、正確に指定することができます。詳細については、「PostgreSQL エクステンションのインストールを制限する」を参照してください。
rds_superuser
ロールの詳細については、「PostgreSQL のロールとアクセス権限について」を参照してください。
トピック
- orafce 拡張機能の関数の使用
- PostgreSQL での Amazon RDS 委任拡張機能サポートの使用
- pg_partman エクステンションによる PostgreSQL パーティションの管理
- pgAudit を使用してデータベースのアクティビティを記録する
- PostgreSQL pg_cron エクステンションによるメンテナンスのスケジューリング
- pglogical を使用してインスタンス間でデータを同期する
- pgactive を使用したアクティブ/アクティブレプリケーションのサポート
- pg_repack 拡張機能を使用して、テーブルやインデックスの膨張を抑制する
- PLV8 拡張機能のアップグレードおよび使用
- PL/Rust を使って Rust 言語で PostgreSQL 関数を記述する
- PostGIS 拡張機能を使用した空間データの管理
orafce 拡張機能の関数の使用
orafce 拡張機能は、Oracle データベースから関数とパッケージのサブセットをエミュレートする関数と演算子を提供します。Oracle 拡張機能を使用すると、Oracle アプリケーションを PostgreSQL に簡単に移植できます。この拡張機能は、RDS for PostgreSQL バージョン 9.6.6 以降でサポートされています。orafce についての詳細は、GitHub で「orafce
注記
RDS for PostgreSQL では、orafce 拡張機能の一部である utl_file
パッケージがサポートされていません。これは、utl_file
スキーマ関数が、基になるモストへのスーパーユーザーアクセスに必要なオペレーティングシステムテキストファイルで読み書き操作を実行するためです。マネージド型サービスの RDS for PostgreSQL では、ホストアクセスが許可されません。
orafce エクステンションを使用するには
DB インスタンスの作成で使用したプライマリユーザー名を使用して DB インスタンスに接続します。
同じ DB インスタンスにある別のデータベースで orafce をオンにする場合は、
/c dbname
psql コマンドを使用します。このコマンドを使用すると、接続を開始した後にプライマリデータベースから変更できます。CREATE EXTENSION
ステートメントを使用して、orafce 拡張機能をオンにします。CREATE EXTENSION orafce;
ALTER SCHEMA
ステートメントを使用して、oracle スキーマの所有権を rds_superuser ロールに転送します。ALTER SCHEMA oracle OWNER TO rds_superuser;
oracle スキーマの所有者のリストを表示する場合は、
\dn
psql コマンドを使用します。
pgactive を使用したアクティブ/アクティブレプリケーションのサポート
pgactive
拡張は、アクティブ/アクティブレプリケーションを使用して、複数の RDS for PostgreSQL データベースに対する書き込み操作をサポートおよび調整します。Amazon RDS for PostgreSQL は、次のバージョンの pgactive
拡張機能をサポートしています。
-
RDS for PostgreSQL 16.1 またはそれ以降の 16 バージョン
-
RDS for PostgreSQL 15.4-R2 以降のバージョン 15
-
RDS for PostgreSQL 14.10 以降のバージョン 14
-
RDS for PostgreSQL 13.13 以降のバージョン 13
-
RDS for PostgreSQL 12.17 以降のバージョン 12
-
RDS for PostgreSQL 11.22
注記
レプリケーション設定に複数のデータベースに対する書き込み操作があると、競合が発生する可能性があります。詳細については、「アクティブ/アクティブレプリケーションの競合の処理」を参照してください。
トピック
pgactive 拡張機能の初期化
RDS for PostgreSQL DB インスタンスの pgactive
拡張機能を初期化するには、rds.enable_pgactive
パラメータの値を 1
に設定し、データベースに拡張を作成します。これを行うと、rds.logical_replication
パラメータと track_commit_timestamp
パラメータが自動的に有効になり、wal_level
の値が logical
に設定されます。
これらのタスクを実行するには、rds_superuser
ロールとしてアクセス許可が必要です。
AWS Management Console または AWS CLI を使用して、必要な RDS for PostgreSQL DB インスタンスを作成できます。以下のステップでは、RDS for PostgreSQL DB インスタンスがカスタム DB パラメータグループに関連付けられていることを前提としています。カスタム DB パラメータグループの作成については、「Amazon RDS のパラメータグループ」を参照してください。
pgactive 拡張機能を初期化するには
AWS Management Console にサインインし、Amazon RDS コンソール https://console.aws.amazon.com/rds/
を開きます。 -
ナビゲーションペインで、RDS for PostgreSQL DB インスタンスを選択します。
-
RDS for PostgreSQL DB インスタンスの [設定] タブを開きます。インスタンスの詳細で、[DB インスタンスパラメータグループ] リンクを見つけます。
-
リンクを選択して、RDS for PostgreSQL DB インスタンスに関連付けられたカスタムパラメータを開きます。
rds.enable_pgactive
パラメータを見つけて1
に設定し、pgactive
機能を初期化します。[Save changes] (変更の保存) をクリックします。
Amazon RDS コンソールのナビゲーションペインで、[データベース] を選択します。
RDS for PostgreSQL DB インスタンスを選択し、[アクション] メニューから [再起動] を選択します。
DB インスタンスの再起動を確定して、変更を有効にします。
DB インスタンスが使用可能になったら、
psql
または他の任意の PostgreSQL インスタンスを使用して RDS for PostgreSQL DB インスタンスに接続します。次の例では、RDS for PostgreSQL DB インスタンスに
postgres
という名前のデフォルトデータベースがあることを前提としています。psql --host=
mydb.111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=master username
--password --dbname=postgres
pgactive が初期化されていることを確認するには、次のコマンドを実行します。
postgres=>
SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';
pgactive
がshared_preload_libraries
にある場合、前述のコマンドは以下を返します。?column? ---------- t
次のように拡張を作成します。
postgres=>
CREATE EXTENSION pgactive;
pgactive 拡張機能を初期化するには
AWS CLI を使用して pgactive
を設定するには、次の手順に示すように、modify-db-parameter-group オペレーションを呼び出してカスタムパラメータグループ内の特定のパラメータを変更します。
AWS CLI コマンドを使用して
rds.enable_pgactive
を1
に設定し、RDS for PostgreSQL DB インスタンスのpgactive
機能を初期化します。postgres=>
aws rds modify-db-parameter-group \ --db-parameter-group-namecustom-param-group-name
\ --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \ --regionaws-region
-
次の AWS CLI コマンドを使用して RDS for PostgreSQL DB インスタンスを再起動し、
pgactive
ライブラリを初期化します。aws rds reboot-db-instance \ --db-instance-identifier
your-instance
\ --regionaws-region
インスタンスが使用可能になったら、
psql
を使用して RDS for PostgreSQL DB インスタンスに接続します。psql --host=
mydb.111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=master user
--password --dbname=postgres
次のように拡張を作成します。
postgres=>
CREATE EXTENSION pgactive;
RDS for PostgreSQL DB インスタンスのアクティブ/アクティブレプリケーションの設定
次の手順は、同じリージョンで PostgreSQL 15.4 以降を実行している 2 つの RDS for PostgreSQL DB インスタンス間でアクティブ/アクティブレプリケーションを開始する方法を示しています。マルチリージョンの高可用性の例を実行するには、2 つの異なるリージョンに Amazon RDS for PostgreSQL インスタンスをデプロイし、VPC ピアリングを設定する必要があります。詳細については、「VPC ピアリング接続」を参照してください。
注記
複数のリージョン間でトラフィックを送信すると、追加コストが発生する可能性があります。
次の手順では、RDS for PostgreSQL DB インスタンスが pgactive
拡張を使用して設定されていることを前提としています。詳細については、「pgactive 拡張機能の初期化」を参照してください。
pgactive
拡張を使用して最初の RDS for PostgreSQL DB インスタンスを設定するには
次の例は、pgactive
グループの作成方法と、RDS for PostgreSQL DB インスタンスで pgactive
拡張を作成するために必要なその他の手順を示しています。
psql
または別のクライアントツールを使用して、最初の RDS for PostgreSQL DB インスタンスに接続します。psql --host=
firstinstance.111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=master username
--password --dbname=postgres
次のコマンドを使用して RDS for PostgreSQL インスタンスにデータベースを作成します。
postgres=>
CREATE DATABASEapp
;次のコマンドを使用して、接続先を新しいデータベースに切り替えます。
\c
app
shared_preload_libraries
パラメータにpgactive
が含まれているかどうかを確認するには、次のコマンドを実行します。app=>
SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';?column? ---------- t
-
次の SQL ステートメントを使用して、サンプルのテーブルを作成および設定します。
次の SQL ステートメントを使用してサンプルテーブルを作成します。
app=>
CREATE SCHEMA inventory; CREATE TABLE inventory.products ( id int PRIMARY KEY, product_name text NOT NULL, created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP);次の SQL ステートメントを使用して、サンプルデータをテーブルに入力します。
app=>
INSERT INTO inventory.products (id, product_name) VALUES (1, 'soap'), (2, 'shampoo'), (3, 'conditioner');次の SQL ステートメントを使用して、テーブルにデータが存在することを確認します。
app=>
SELECT count(*) FROM inventory.products;count ------- 3
既存のデータベースで
pgactive
拡張を作成します。app=>
CREATE EXTENSION pgactive;以下のコマンドを使用して pgactive グループを作成して初期化します。
app=>
SELECT pgactive.pgactive_create_group( node_name :='node1-app'
, node_dsn := 'dbname=app
host=firstinstance.111122223333
.aws-region
.rds.amazonaws.com user=master username
password=PASSWORD
');node1-app は、
pgactive
グループ内のノードを一意に識別するために割り当てる名前です。注記
パブリックにアクセス可能な DB インスタンスで、このステップを正常に実行するには、
rds.custom_dns_resolution
パラメータを1
に設定して有効にする必要があります。DB インスタンスの準備が整っているかどうかを確認するには、次のコマンドを使用します。
app=>
SELECT pgactive.pgactive_wait_for_node_ready();コマンドが正常に完了した場合は、次の出力が表示されます。
pgactive_wait_for_node_ready ------------------------------ (1 row)
2 番目の RDS for PostgreSQL インスタンスを設定して pgactive
グループに参加させるには
次の例は、RDS for PostgreSQL DB インスタンスを pgactive
グループに参加させる方法と、DB インスタンスに pgactive
拡張を作成するために必要なその他のステップを示しています。
次の手順では、RDS for PostgreSQL DB インスタンスが pgactive
拡張を使用して設定されていることを前提としています。詳細については、「pgactive 拡張機能の初期化」を参照してください。
psql
を使用して、パブリッシャーから更新を受け取るインスタンスに接続します。psql --host=
secondinstance.111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=master username
--password --dbname=postgres
次のコマンドを使用して、2 番目の RDS for PostgreSQL DB インスタンスにデータベースを作成します。
postgres=>
CREATE DATABASEapp
;次のコマンドを使用して、接続先を新しいデータベースに切り替えます。
\c
app
既存のデータベースに
pgactive
拡張を作成します。app=>
CREATE EXTENSION pgactive;次に示すように、RDS for PostgreSQL の 2 番目の DB インスタンスを
pgactive
グループに参加させます。app=>
SELECT pgactive.pgactive_join_group( node_name :='node2-app'
, node_dsn := 'dbname=app
host=secondinstance.111122223333
.aws-region
.rds.amazonaws.com user=master username
password=PASSWORD
', join_using_dsn := 'dbname=app
host=firstinstance.111122223333
.aws-region
.rds.amazonaws.com user=postgres
password=PASSWORD
');node2-app は、
pgactive
グループ内のノードを一意に識別するために割り当てる名前です。DB インスタンスの準備が整っているかどうかを確認するには、次のコマンドを使用します。
app=>
SELECT pgactive.pgactive_wait_for_node_ready();コマンドが正常に完了すると、次の出力が表示されます。
pgactive_wait_for_node_ready ------------------------------ (1 row)
最初の RDS for PostgreSQL データベースが比較的大きい場合は、
pgactive.pgactive_wait_for_node_ready()
から復元操作の進行状況レポートを出力されることを確認できます。出力は次の例のようになります:NOTICE: restoring database 'app', 6% of 7483 MB complete NOTICE: restoring database 'app', 42% of 7483 MB complete NOTICE: restoring database 'app', 77% of 7483 MB complete NOTICE: restoring database 'app', 98% of 7483 MB complete NOTICE: successfully restored database 'app' from node node1-app in 00:04:12.274956 pgactive_wait_for_node_ready ------------------------------ (1 row)
この時点から、
pgactive
は 2 つの DB インスタンス間でデータを同期します。次のコマンドを使用して、2 番目の DB インスタンスのデータベースにデータがあるかどうかを確認できます。
app=>
SELECT count(*) FROM inventory.products;データが正常に同期されると、次の出力が表示されます。
count ------- 3
次のコマンドを実行して新しい値を挿入します。
app=>
INSERT INTO inventory.products (id, product_name) VALUES ('lotion');最初の DB インスタンスのデータベースに接続し、次のクエリを実行します。
app=>
SELECT count(*) FROM inventory.products;アクティブ/アクティブレプリケーションが初期化されると、出力は次のようになります。
count ------- 4
pgactive
グループから DB インスタンスをデタッチして削除するには
pgactive
グループから DB インスタンスをデタッチして削除するには、次の手順に従います。
次のコマンドを使用して、最初のインスタンスから 2 番目の DB インスタンスをデタッチできます。
app=>
SELECT * FROM pgactive.pgactive_detach_nodes(ARRAY[‘node2-app
']);次のコマンドを使用して、2 番目の DB インスタンスから
pgactive
拡張を削除します。app=>
SELECT * FROM pgactive.pgactive_remove();拡張を強制的に削除するには
app=>
SELECT * FROM pgactive.pgactive_remove(true);次のコマンドを使用して拡張をドロップします。
app=>
DROP EXTENSION pgactive;
アクティブ/アクティブレプリケーションの競合の処理
pgactive
拡張は、クラスターごとではなく、データベースごとに機能します。pgactive
を使用する各 DB インスタンスは、独立したインスタンスであり、あらゆるソースからのデータ変更を受け入れることができます。変更が DB インスタンスに送信されると、PostgreSQL は変更をローカルにコミットし、pgactive
を使用して他の DB インスタンスに非同期に変更をレプリケートします。2 つの PostgreSQL DB インスタンスが同じレコードをほぼ同時に更新すると、競合が発生する可能性があります。
pgactive
拡張は、競合の検出と自動解決のためのメカニズムを提供します。両方の DB インスタンスでトランザクションがコミットされた時点のタイムスタンプを追跡し、最新のタイムスタンプで変更を自動的に適用します。また、pgactive
拡張は、pgactive.pgactive_conflict_history
テーブルで競合が発生した場合もログに記録します。
pgactive.pgactive_conflict_history
は継続的に増大します。パージポリシーを定義するとよいでしょう。これを行うには、一部のレコードを定期的に削除するか、この関係のパーティションスキームを定義します (その後で対象のパーティションをデタッチ、ドロップ、切り捨てることができます)。パージポリシーを定期的に実装するには、 pg_cron
拡張機能を使用するというオプションがあります。pg_cron
履歴テーブルの例については、「PostgreSQL pg_cron 拡張機能を使用したメンテナンスのスケジュール」の次の情報を参照してください。
アクティブ/アクティブレプリケーションでのシーケンスの処理
pgactive
拡張を使用した RDS for PostgreSQL DB インスタンスは、2 つの異なるシーケンスメカニズムを使用して固有の値を生成します。
グローバルシーケンス
グローバルシーケンスを使用するには、CREATE SEQUENCE
ステートメントを使用してローカルシーケンスを作成します。usingnextval(seqname)
の代わりに pgactive.pgactive_snowflake_id_nextval(seqname)
を使用すると、シーケンスの次の固有な値を取得できます。
次の例では、グローバルシーケンスを作成します。
postgres=>
CREATE TABLE gstest ( id bigint primary key, parrot text );
postgres=>
CREATE SEQUENCE gstest_id_seq OWNED BY gstest.id;
postgres=>
ALTER TABLE gstest \ ALTER COLUMN id SET DEFAULT \ pgactive.pgactive_snowflake_id_nextval('gstest_id_seq');
分割シーケンス
分割ステップまたは分割シーケンスでは、通常の PostgreSQL シーケンスをノードごとに使用します。各シーケンスは同じ量ずつインクリメントされ、異なるオフセットから始まります。例えば、ステップ 100 の場合、ノード 1 は 101、201、301 などとしてシーケンスを生成し、ノード 2 は 102、202、302 などとしてシーケンスを生成します。このスキームは、ノードが長時間通信できない場合でも適切に機能しますが、設計者はスキーマを確立するときに最大ノード数を指定する必要があり、ノードごとの設定が必要になります。間違えると、シーケンスが重複しやすくなります。
次に示すように、ノードで目的のシーケンスを作成することで、このアプローチを pgactive
で比較的簡単に設定できます。
CREATE TABLE some_table (generated_value bigint primary key);
postgres=>
CREATE SEQUENCE some_seq INCREMENT 100 OWNED BY some_table.generated_value;
postgres=>
ALTER TABLE some_table ALTER COLUMN generated_value SET DEFAULT nextval('some_seq');
次に、各ノードで setval
を呼び出して、次のように異なるオフセットの開始値を指定します。
postgres=>
-- On node 1 SELECT setval('some_seq', 1); -- On node 2 SELECT setval('some_seq', 2);
pgactive 拡張のパラメータリファレンス
次のクエリを使用すると、pgactive
拡張に関連するすべてのパラメータを表示できます。
postgres=>
SELECT * FROM pg_settings WHERE name LIKE 'pgactive.%';
pgactive メンバー間のレプリケーションラグの測定
次のクエリを使用して、pgactive
メンバー間のレプリケーションラグを表示できます。全体像を把握するには、すべての pgactive
ノードでこのクエリを実行します。
postgres=# SELECT *, (last_applied_xact_at - last_applied_xact_committs) AS lag FROM pgactive.pgactive_node_slots;
-{ RECORD 1 ]----------------+-----------------------------------------------------------------
node_name | node2-app
slot_name | pgactive_5_7332551165694385385_0_5__
slot_restart_lsn | 0/1A898A8
slot_confirmed_lsn | 0/1A898E0
walsender_active | t
walsender_pid | 69022
sent_lsn | 0/1A898E0
write_lsn | 0/1A898E0
flush_lsn | 0/1A898E0
replay_lsn | 0/1A898E0
last_sent_xact_id | 746
last_sent_xact_committs | 2024-02-06 18:04:22.430376+00
last_sent_xact_at | 2024-02-06 18:04:22.431359+00
last_applied_xact_id | 746
last_applied_xact_committs | 2024-02-06 18:04:22.430376+00
last_applied_xact_at | 2024-02-06 18:04:52.452465+00
lag | 00:00:30.022089
pgactive 拡張の制限事項
すべてのテーブルには主キーが必要です。主キーがないと、更新や削除は許可されません。主キー列の値は更新しないでください。
シーケンスにはギャップがある場合があり、順序に従わないこともあります。シーケンスはレプリケートされません。詳細については、「アクティブ/アクティブレプリケーションでのシーケンスの処理」を参照してください。
DDL とラージオブジェクトはレプリケートされません。
セカンダリの一意のインデックスはデータの相違を引き起こす可能性があります。
照合順序はグループ内のすべてのノードで同一である必要があります。
ノード間の負荷分散はアンチパターンです。
トランザクションが大きいと、レプリケーションの遅延が発生する可能性があります。
pg_repack 拡張機能を使用して、テーブルやインデックスの膨張を抑制する
pg_repack
拡張機能を使用して、VACUUM FULL
の代わりとしてテーブルやインデックスの肥大化を取り除くことができます。このエクステンションは、RDS for PostgreSQL のバージョン 9.6.3 以降でサポートされています。pg_repack
拡張機能の詳細については、GitHub プロジェクトのドキュメント
VACUUM FULL
とは異なり、pg_repack
拡張機能では、次の場合にテーブルの再構築オペレーション中に短期間だけ排他的ロック (AccessExclusiveLock) が必要です。
ログテーブルの初回作成 – 次の例に示すように、データの初回コピー中に発生した変更を記録するログテーブルが作成されます。
postgres=>
\dt+ repack.log_* List of relations -[ RECORD 1 ]-+---------- Schema | repack Name | log_16490 Type | table Owner | postgres Persistence | permanent Access method | heap Size | 65 MB Description |
最終スワップアンドドロップフェーズ。
再構築オペレーションの残りの部分で必要なのは、元のテーブルから新しいテーブルに行をコピーするための ACCESS SHARE
ロックのみです。これにより、INSERT、UPDATE、DELETE オペレーションを通常どおりに進めることができます。
レコメンデーション
次の推奨事項は、pg_repack
拡張機能を使用してテーブルとインデックスの肥大化を取り除く場合に適用されます。
業務時間外または他のデータベースアクティビティのパフォーマンスへの影響を最小限に抑えるために、メンテナンスウィンドウで再パックを実行します。
再構築アクティビティ中にブロッキングセッションを注意深くモニタリングし、
pg_repack
をブロックする可能性のあるアクティビティが元のテーブルにないことを確認します。特に、元のテーブルで排他的ロックが必要なときは、最後のスワップアンドドロップフェーズ中にアクティビティがないことを確認します。詳細については、「クエリをブロックしているものの特定」を参照してください。 ブロッキングセッションが表示された場合は、慎重に検討した後、次のコマンドを使用してセッションを終了できます。これは、
pg_repack
の継続によって再構築を完了するのに役立ちます。SELECT pg_terminate_backend(
pid
);-
トランザクション率が非常に高いシステムで
pg_repack's
ログテーブルから蓄積された変更を適用すると、適用プロセスが変更の速度に対して遅れる可能性があります。このような場合、pg_repack
は適用プロセスを完了できません。詳細については、「再パック中の新しいテーブルのモニタリング」を参照してください。インデックスが著しく肥大化している場合、代替の解決策は、インデックスのみの再パックを実行することです。これにより、VACUUM のインデックスクリーンアップサイクルをより速く完了させることもできます。PostgreSQL バージョン 12 の手動 VACUUM を使用してインデックスのクリーンアップフェーズをスキップできます。また、PostgreSQL バージョン 14 の緊急自動バキューム中は自動的にスキップされます。これにより、VACUUM はインデックスの肥大化を取り除くことなくより迅速に完了します。これは、循環 VACUUM の防止などの緊急時にのみ使用されます。詳細については、Amazon Aurora ユーザーガイドの「インデックスの肥大化の回避」を参照してください。
前提条件
テーブルには、PRIMARY KEY 制約または null 以外の UNIQUE 制約が必要です。
拡張機能のバージョンは、クライアントとサーバーの両方で同じである必要があります。
RDS インスタンスに、肥大化がないテーブルの合計サイズ以上の
FreeStorageSpace
があることを確認します。例として、TOAST とインデックスを含むテーブルの合計サイズが 2TB で、テーブルの肥大化の合計が 1TB であるとします。必須のFreeStorageSpace
は、次の計算によって返される値よりも大きくなければなりません。2TB (Table size)
-1TB (Table bloat)
=1TB
次のクエリを使用してテーブルの合計サイズを確認し、
pgstattuple
を使用して肥大化を導き出すことができます。詳細については、Amazon Aurora ユーザーガイドの「テーブルとインデックスの肥大化の診断」を参照してください。SELECT pg_size_pretty(pg_total_relation_size('table_name')) AS total_table_size;
このスペースは、アクティビティの完了後に再利用されます。
RDS インスタンスに再パックオペレーションを処理するのに十分なコンピューティング容量と IO 容量があることを確認します。パフォーマンスのバランスを最適化するために、インスタンスクラスをスケールアップすることを検討してください。
pg_repack
拡張機能を使用するには
-
次のコマンドを実行して、RDS for PostgreSQL DB インスタンスに
pg_repack
エクステンションをインストールします。CREATE EXTENSION pg_repack;
-
次のコマンドを実行して、
pg_repack
によって作成されたテンポラリログテーブルへの書き込みアクセス権を付与します。ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT INSERT ON TABLES TO PUBLIC; ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT USAGE, SELECT ON SEQUENCES TO PUBLIC;
pg_repack
クライアントユーティリティを使用してデータベースに接続します。rds_superuser
権限を持つアカウントを使用します。例として、rds_test
ロールにrds_superuser
権限があるとします。次の構文は、postgres
データベース内のすべてのテーブルインデックスを含む完全なテーブルに対してpg_repack
を実行します。pg_repack -h
db-instance-name
.111122223333.aws-region
.rds.amazonaws.com -Urds_test
-kpostgres
注記
-k オプションを使用して接続する必要があります。-a オプションはサポートされていません。
pg_repack
クライアントからのレスポンスにより、再パッケージされる DB インスタンスのテーブルに関する情報が提供されます。INFO: repacking table "pgbench_tellers" INFO: repacking table "pgbench_accounts" INFO: repacking table "pgbench_branches"
-
次の構文は、
postgres
データベース内のインデックスを含む単一のテーブルorders
を再パックします。pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U
rds_test
--tableorders
-kpostgres
次の構文では、
postgres
データベース内のorders
テーブルのインデックスのみを再パックします。pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U
rds_test
--tableorders
--only-indexes -kpostgres
再パック中の新しいテーブルのモニタリング
データベースのサイズは、再パックのスワップアンドドロップフェーズまで、テーブルの合計サイズから肥大化を引いた数だけ増加します。データベースサイズの増加率をモニタリングし、再パックの速度を計算して、最初のデータ転送の完了にかかる時間を概算で見積もることができます。
例えば、テーブルの合計サイズを 2TB、データベースのサイズを 4TB、テーブルの合計肥大化を 1TB とします。再パックオペレーションの最後に計算によって返されるデータベースの合計サイズ値は次のとおりです。
2TB (Table size)
+4 TB (Database size)
-1TB (Table bloat)
=5TB
再パックオペレーションの速度を概算で見積もるには、2 つの時点の間の増加率をバイト単位でサンプリングします。増加率が 1GB の場合、最初のテーブル構築オペレーションが完了するまでに 1000 分または 16.6 時間かかることがあります。最初のテーブル構築に加えて、
pg_repack
は蓄積された変更を適用する必要があります。所要時間は、進行中の変更と蓄積された変更の適用速度によって異なります。注記
pgstattuple
拡張機能を使用して、テーブルの肥大化を計算できます。詳細については、「pgstattuple」を参照してください。 再パックスキーマの下の
pg_repack's
ログテーブルの行数は、最初のロード後に新しいテーブルに適用される保留中の変更の量を表します。pg_stat_all_tables
のpg_repack's
ログテーブルをチェックして、新しいテーブルに適用される変更をモニタリングできます。pg_stat_all_tables.n_live_tup
は、新しいテーブルに適用される保留中のレコードの数を示します。詳細については、「pg_stat_all_tables」を参照してください。 postgres=>
SELECT relname,n_live_tup FROM pg_stat_all_tables WHERE schemaname = 'repack' AND relname ILIKE '%log%';
-[ RECORD 1 ]--------- relname | log_16490 n_live_tup | 2000000
-
pg_stat_statements
拡張機能を使用して、再パックオペレーションの各ステップにかかる時間を調べることができます。これは、本番環境で同じ再パックオペレーションを適用する準備に役立ちます。出力をさらに拡張するようにLIMIT
句を調整できます。postgres=>
SELECT SUBSTR(query, 1, 100) query, round((round(total_exec_time::numeric, 6) / 1000 / 60),4) total_exec_time_in_minutes FROM pg_stat_statements WHERE query ILIKE '%repack%' ORDER BY total_exec_time DESC LIMIT 5;
query | total_exec_time_in_minutes -----------------------------------------------------------------------+---------------------------- CREATE UNIQUE INDEX index_16493 ON repack.table_16490 USING btree (a) | 6.8627 INSERT INTO repack.table_16490 SELECT a FROM ONLY public.t1 | 6.4150 SELECT repack.repack_apply($1, $2, $3, $4, $5, $6) | 0.5395 SELECT repack.repack_drop($1, $2) | 0.0004 SELECT repack.repack_swap($1) | 0.0004 (5 rows)
再パックは完全にアウトオブプレースオペレーションであるため、元のテーブルは影響を受けず、元のテーブルの復元を必要とする予期しない課題は予想されません。再パックが予期せず失敗した場合は、エラーの原因を調べて解決する必要があります。
問題が解決したら、テーブルが存在するデータベースに pg_repack
拡張機能を削除して再作成し、pg_repack
ステップを再試行してください。さらに、コンピューティングリソースの可用性とテーブルの同時アクセシビリティは、再パックオペレーションをタイムリーに完了させる上で重要な役割を果たします。
PLV8 拡張機能のアップグレードおよび使用
PLV8 は、信頼できる JavaScript 言語の PostgreSQL 用エクステンションです。ストアドプロシージャ、トリガー、SQL から呼び出し可能なその他のプロシージャルコードに使用できます。この言語のエクステンションは、PostgreSQL のすべての最新リリースでサポートされています。
PLV8
アップグレードプロセスでは、既存の PLV8 機能がすべて削除されます。そのため、アップグレードする前に、RDS for PostgreSQL DB インスタンスのスナップショットを作成しておくことをお勧めします。詳細については、「シングル AZ DB インスタンスの DB スナップショットの作成」を参照してください。
カタログメタデータを新しいバージョンの PLV8 と同期させるには
-
更新する必要があることを確認します。そのためには、インスタンスに接続されている間に以下のコマンドを実行します。
SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee');
インストールされているバージョンとしてデフォルトのバージョンより低いバージョンが表示された場合は、この手順を実行して、エクステンションを更新する必要があります。例えば、以下の結果セットは更新の必要があることを表します。
name | default_version | installed_version | comment --------+-----------------+-------------------+-------------------------------------------------- plls | 2.1.0 | 1.5.3 | PL/LiveScript (v8) trusted procedural language plcoffee| 2.1.0 | 1.5.3 | PL/CoffeeScript (v8) trusted procedural language plv8 | 2.1.0 | 1.5.3 | PL/JavaScript (v8) trusted procedural language (3 rows)
RDS for PostgreSQL DB インスタンスのスナップショットを作成していない場合は、作成してください。次のステップは、スナップショットの作成中も続行できます。
-
DB インスタンスの PLV8 関数の数を取得し、アップグレード後にすべて揃っていることを確認できるようにします。例えば次の SQL クエリ では、plv8、plcoffee、plls で記述されている関数の数が返ります。
SELECT proname, nspname, lanname FROM pg_proc p, pg_language l, pg_namespace n WHERE p.prolang = l.oid AND n.oid = p.pronamespace AND lanname IN ('plv8','plcoffee','plls');
-
pg_dump を使用して、スキーマのみのダンプファイルを作成します。例えば、クライアントマシンの
/tmp
ディレクトリに、ファイルを作成します。./pg_dump -Fc --schema-only -U master postgres >/tmp/test.dmp
この例では、以下のオプションを使用します。
-
-Fc
– カスタム形式 -
-- スキーマのみ – スキーマの作成に必要なコマンド (ここでは関数) のみをダンプする
-
-U
– RDS マスターユーザー名 -
database
– DB インスタンスのデータベース名
pg_dump の詳細については、「PostgreSQL ドキュメント」の「pg_dump
」を参照してください。 -
-
ダンプファイルに存在する "CREATE FUNCTION" DDL ステートメントを抽出します。次の例では
grep
コマンドを実行して、関数を作成する DDL ステートメントを抽出し、ファイルに保存します。この ddl は後続のステップで関数を再作成するために使用します。./pg_restore -l /tmp/test.dmp | grep FUNCTION > /tmp/function_list/
pg_restore の詳細については、「PostgreSQL ドキュメント」の「pg_restore
」を参照してください。 -
関数およびエクステンションを削除します。次の例では、PLV8 ベースのオブジェクトを削除します。CASCADE オプションでは、すべての依存が削除されます。
DROP EXTENSION plv8 CASCADE;
plcoffee または plls に基づくオブジェクトが PostgreSQL インスタンスに含まれている場合は、それらのエクステンションに対してこのステップを繰り返します。
-
エクステンションを作成します。次の例では、plv8、plcoffee、plls のエクステンションが作成されます。
CREATE EXTENSION plv8; CREATE EXTENSION plcoffee; CREATE EXTENSION plls;
-
ダンプファイルおよび "ドライバ" ファイルを使用して関数を作成します。
次の例では、前に抽出した関数が再作成されます。
./pg_restore -U master -d postgres -Fc -L /tmp/function_list /tmp/test.dmp
-
次のクエリを使用して、すべての関数が再作成されたことを確認します。
SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee');
PLV8 バージョン 2 では、次の行が結果セットに追加されます。
proname | nspname | lanname ---------------+------------+---------- plv8_version | pg_catalog | plv8
PL/Rust を使って Rust 言語で PostgreSQL 関数を記述する
PL/Rust は、PostgreSQL のための信頼できる Rust 言語エクステンションです。ストアドプロシージャ、関数、SQL から呼び出し可能なその他のプロシージャルコードに使用できます。PL/Rust 言語拡張は次のバージョンで利用可能です。
-
RDS for PostgreSQL 16.1 またはそれ以降の 16 バージョン
-
RDS for PostgreSQL 15.2-R2 またはそれ以降の 15 バージョン
-
RDS for PostgreSQL 14.9 またはそれ以降の 14 バージョン
-
RDS for PostgreSQL 13.12 またはそれ以降の 13 バージョン
詳細については、GitHub の「PL/Rust
PL/Rust の設定
DB インスタンスに plrust 拡張機能をインストールするには、DBインスタンスに関連付けられた DB パラメータグループの shared_preload_libraries
パラメータに plrust を追加します。plrust 拡張機能をインストールすると、関数を作成できます。
shared_preload_libraries
パラメータを変更するには、DB インスタンスをカスタムパラメータグループに関連付ける必要があります。カスタム DB パラメータグループの作成については、「Amazon RDS のパラメータグループ」を参照してください。
plust 拡張機能は、AWS Management Console または AWS CLI を使用してインストールできます。
以下のステップでは、DB インスタンスがカスタム DB パラメータグループに関連付けられていることを前提としています。
plust 拡張機能を shared_preload_libraries
パラメータにインストールする
rds_superuser
グループ (ロール) のメンバーであるアカウントを使用して、次のステップを完了します。
AWS Management Console にサインインし、Amazon RDS コンソール (https://console.aws.amazon.com/rds/
) を開きます。 -
ナビゲーションペインで、データベースを選択します。
-
DB インスタンスの名前を選択して、その詳細を表示します。
-
DB インスタンスの [設定] タブを開き、DB インスタンスパラメータグループのリンクを探します。
-
リンクを選択して、DB クラスターに関連付けられたカスタムパラメータを開きます。
-
パラメータ検索フィールドに、
shared_pre
を入力してshared_preload_libraries
パラメータを検索します。 -
プロパティ値にアクセスするには、[Edit parameters] (パラメータの編集) を選択します。
-
[値] フィールドのリストに plrust を追加します。値のリスト内の項目を区切るにはカンマを使用します。
DB インスタンスを再起動して、
shared_preload_libraries
パラメータの変更を有効にします。最初の再起動が完了するまでにさらに時間がかかる場合があります。インスタンスが使用可能になったら、plrust が初期化されていることを確認します。
psql
を使用して DB インスタンスに接続し、次のコマンドを実行します。SHOW shared_preload_libraries;
出力は以下のようになります。
shared_preload_libraries -------------------------- rdsutils,plrust (1 row)
shared_preload_libraries パラメータに pltrust 拡張機能をインストールする
rds_superuser
グループ (ロール) のメンバーであるアカウントを使用して、次のステップを完了します。
shared_preload_libraries
パラメータに plrust を追加するには、modify-db-parameter-group AWS CLI コマンドを使用します。aws rds modify-db-parameter-group \ --db-parameter-group-name
custom-param-group-name
\ --parameters "ParameterName=shared_preload_libraries,ParameterValue=plrust,ApplyMethod=pending-reboot" \ --regionaws-region
-
reboot-db-instance AWS CLI コマンドを使用して DB インスタンスを再起動し、plrust ライブラリを初期化します。最初の再起動が完了するまでにさらに時間がかかる場合があります。
aws rds reboot-db-instance \ --db-instance-identifier
your-instance
\ --regionaws-region
インスタンスが使用可能になったら、plrust が初期化されていることを確認できます。
psql
を使用して DB インスタンスに接続し、次のコマンドを実行します。SHOW shared_preload_libraries;
出力は以下のようになります。
shared_preload_libraries -------------------------- rdsutils,plrust (1 row)
PL/Rust を使った関数の作成
PL/Rust は関数を動的ライブラリとしてコンパイルし、ロードして実行します。
次の Rust 関数は、配列から複数を除外します。
postgres=> CREATE LANGUAGE plrust; CREATE EXTENSION
CREATE OR REPLACE FUNCTION filter_multiples(a BIGINT[], multiple BIGINT) RETURNS BIGINT[] IMMUTABLE STRICT LANGUAGE PLRUST AS $$ Ok(Some(a.into_iter().filter(|x| x.unwrap() % multiple != 0).collect())) $$; WITH gen_values AS ( SELECT ARRAY(SELECT * FROM generate_series(1,100)) as arr) SELECT filter_multiples(arr, 3) from gen_values;
PL/Rust の入ったクレートを使用する
RDS for PostgreSQL バージョン 16.3-R2 以降、15.7-R2 以降の 15 バージョン、14.12-R2 以降の 14 バージョン、および 13.15-R2 以降の 13 バージョンでは、PL/Rust は追加のクレートをサポートしています。
-
url
-
regex
-
serde
-
serde_json
RDS for PostgreSQL バージョン 15.5-R2 以降、14.10-R2 以降の 14 バージョン、および 13.13-R2 以降の 13 バージョンでは、PL/Rust は 2 つの追加のクレートをサポートしています。
-
croaring-rs
-
num-bigint
Amazon RDS for PostgreSQL バージョン 15.4、14.9、13.12 以降、PL/Rust は、次のクレートをサポートします。
-
aes
-
ctr
-
rand
これらのクレートではデフォルト機能のみがサポートされています。新しい RDS for PostgreSQL バージョンには、更新されたバージョンのクレートが含まれているため、古いバージョンのクレートはサポートされなくなる可能性があります。
メジャーバージョンアップグレードを行う際のベストプラクティスに従って、お使いの PL/Rust 関数が新しいメジャーバージョンと互換性があるかどうかをテストしてください。詳細については、「Amazon RDS ユーザーガイド」のブログ「Amazon RDS を PostgreSQL のメジャーバージョンとマイナーバージョンにアップグレードするためのベストプラクティス
PL/Rust 関数を作成する際の依存関係の使用例については、「依存関係を使う
PL/Rust の制限事項
デフォルトでは、データベースユーザーは PL/Rust を使用できません。PL/Rust へのアクセスを提供するには、rds_superuser 権限を持つユーザーとして接続し、次のコマンドを実行します。
postgres=> GRANT USAGE ON LANGUAGE PLRUST TO
user
;