Amazon RDS for PostgreSQL で PostgreSQL 拡張機能を使用する - Amazon Relational Database Service

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 拡張機能の関数の使用

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 エクステンションを使用するには
  1. DB インスタンスの作成で使用したプライマリユーザー名を使用して DB インスタンスに接続します。

    同じ DB インスタンスにある別のデータベースで orafce をオンにする場合は、/c dbname psql コマンドを使用します。このコマンドを使用すると、接続を開始した後にプライマリデータベースから変更できます。

  2. CREATE EXTENSION ステートメントを使用して、orafce 拡張機能をオンにします。

    CREATE EXTENSION orafce;
  3. 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 パラメータグループの作成については、「「パラメータグループを使用する」 」を参照してください。

pgactive 拡張機能を初期化するには
  1. AWS Management Console にサインインし、Amazon RDS コンソール https://console.aws.amazon.com/rds/ を開きます。

  2. ナビゲーションペインで、RDS for PostgreSQL DB インスタンスを選択します。

  3. RDS for PostgreSQL DB インスタンスの [設定] タブを開きます。インスタンスの詳細で、[DB インスタンスパラメータグループ] リンクを見つけます。

  4. リンクを選択して、RDS for PostgreSQL DB インスタンスに関連付けられたカスタムパラメータを開きます。

  5. rds.enable_pgactive パラメータを見つけて 1 に設定し、pgactive 機能を初期化します。

  6. [Save changes] (変更の保存) をクリックします。

  7. Amazon RDS コンソールのナビゲーションペインで、[データベース] を選択します。

  8. RDS for PostgreSQL DB インスタンスを選択し、[アクション] メニューから [再起動] を選択します。

  9. DB インスタンスの再起動を確定して、変更を有効にします。

  10. 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
  11. pgactive が初期化されていることを確認するには、次のコマンドを実行します。

    postgres=>SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';

    pgactiveshared_preload_libraries にある場合、前述のコマンドは以下を返します。

    ?column? ---------- t
  12. 次のように拡張を作成します。

    postgres=> CREATE EXTENSION pgactive;
pgactive 拡張機能を初期化するには

AWS CLI を使用して pgactive を設定するには、次の手順に示すように、modify-db-parameter-group オペレーションを呼び出してカスタムパラメータグループ内の特定のパラメータを変更します。

  1. AWS CLI コマンドを使用して rds.enable_pgactive1 に設定し、RDS for PostgreSQL DB インスタンスの pgactive 機能を初期化します。

    postgres=>aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \ --region aws-region
  2. 次の AWS CLI コマンドを使用して RDS for PostgreSQL DB インスタンスを再起動し、pgactive ライブラリを初期化します。

    aws rds reboot-db-instance \ --db-instance-identifier your-instance \ --region aws-region
  3. インスタンスが使用可能になったら、psql を使用して RDS for PostgreSQL DB インスタンスに接続します。

    psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master user --password --dbname=postgres
  4. 次のように拡張を作成します。

    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 拡張を作成するために必要なその他の手順を示しています。

  1. psql または別のクライアントツールを使用して、最初の RDS for PostgreSQL DB インスタンスに接続します。

    psql --host=firstinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master username --password --dbname=postgres
  2. 次のコマンドを使用して RDS for PostgreSQL インスタンスにデータベースを作成します。

    postgres=> CREATE DATABASE app;
  3. 次のコマンドを使用して、接続先を新しいデータベースに切り替えます。

    \c app
  4. shared_preload_libraries パラメータに pgactive が含まれているかどうかを確認するには、次のコマンドを実行します。

    app=>SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';
    ?column? ---------- t
  5. 次の SQL ステートメントを使用して、サンプルのテーブルを作成および設定します。

    1. 次の 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);
    2. 次の SQL ステートメントを使用して、サンプルデータをテーブルに入力します。

      app=> INSERT INTO inventory.products (id, product_name) VALUES (1, 'soap'), (2, 'shampoo'), (3, 'conditioner');
    3. 次の SQL ステートメントを使用して、テーブルにデータが存在することを確認します。

      app=>SELECT count(*) FROM inventory.products; count ------- 3
  6. 既存のデータベースで pgactive 拡張を作成します。

    app=> CREATE EXTENSION pgactive;
  7. 以下のコマンドを使用して 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 に設定して有効にする必要があります。

  8. 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 拡張機能の初期化」を参照してください。

  1. psql を使用して、パブリッシャーから更新を受け取るインスタンスに接続します。

    psql --host=secondinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master username --password --dbname=postgres
  2. 次のコマンドを使用して、2 番目の RDS for PostgreSQL DB インスタンスにデータベースを作成します。

    postgres=> CREATE DATABASE app;
  3. 次のコマンドを使用して、接続先を新しいデータベースに切り替えます。

    \c app
  4. 既存のデータベースに pgactive 拡張を作成します。

    app=> CREATE EXTENSION pgactive;
  5. 次に示すように、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 グループ内のノードを一意に識別するために割り当てる名前です。

  6. 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 インスタンス間でデータを同期します。

  7. 次のコマンドを使用して、2 番目の DB インスタンスのデータベースにデータがあるかどうかを確認できます。

    app=> SELECT count(*) FROM inventory.products;

    データが正常に同期されると、次の出力が表示されます。

    count ------- 3
  8. 次のコマンドを実行して新しい値を挿入します。

    app=> INSERT INTO inventory.products (id, product_name) VALUES ('lotion');
  9. 最初の DB インスタンスのデータベースに接続し、次のクエリを実行します。

    app=> SELECT count(*) FROM inventory.products;

    アクティブ/アクティブレプリケーションが初期化されると、出力は次のようになります。

    count ------- 4
pgactive グループから DB インスタンスをデタッチして削除するには

pgactive グループから DB インスタンスをデタッチして削除するには、次の手順に従います。

  1. 次のコマンドを使用して、最初のインスタンスから 2 番目の DB インスタンスをデタッチできます。

    app=> SELECT * FROM pgactive.pgactive_detach_nodes(ARRAY[‘node2-app']);
  2. 次のコマンドを使用して、2 番目の DB インスタンスから pgactive 拡張を削除します。

    app=> SELECT * FROM pgactive.pgactive_remove();

    拡張を強制的に削除するには

    app=> SELECT * FROM pgactive.pgactive_remove(true);
  3. 次のコマンドを使用して拡張をドロップします。

    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 拡張機能を使用するには
  1. 次のコマンドを実行して、RDS for PostgreSQL DB インスタンスに pg_repack エクステンションをインストールします。

    CREATE EXTENSION pg_repack;
  2. 次のコマンドを実行して、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;
  3. pg_repack クライアントユーティリティを使用してデータベースに接続します。rds_superuser 権限を持つアカウントを使用します。例として、rds_test ロールに rds_superuser 権限があるとします。次の構文は、postgres データベース内のすべてのテーブルインデックスを含む完全なテーブルに対して pg_repack を実行します。

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test -k postgres
    注記

    -k オプションを使用して接続する必要があります。-a オプションはサポートされていません。

    pg_repack クライアントからのレスポンスにより、再パッケージされる DB インスタンスのテーブルに関する情報が提供されます。

    INFO: repacking table "pgbench_tellers" INFO: repacking table "pgbench_accounts" INFO: repacking table "pgbench_branches"
  4. 次の構文は、postgres データベース内のインデックスを含む単一のテーブル orders を再パックします。

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders -k postgres

    次の構文では、postgres データベース内の orders テーブルのインデックスのみを再パックします。

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders --only-indexes -k postgres

再パック中の新しいテーブルのモニタリング

  • データベースのサイズは、再パックのスワップアンドドロップフェーズまで、テーブルの合計サイズから肥大化を引いた数だけ増加します。データベースサイズの増加率をモニタリングし、再パックの速度を計算して、最初のデータ転送の完了にかかる時間を概算で見積もることができます。

    例えば、テーブルの合計サイズを 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_tablespg_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 を使用しており、PostgreSQL を新しい PLV8 バージョンにアップグレードする場合は、新しいエクステンションをすぐに利用できるようになります。次のステップを実行して、カタログメタデータを PLV8 の新しいバージョンと同期させます。これらの手順はオプションですが、メタデータ不一致の警告を回避するために実行することを強くお勧めします。

アップグレードプロセスでは、既存の PLV8 機能がすべて削除されます。そのため、アップグレードする前に、RDS for PostgreSQL DB インスタンスのスナップショットを作成しておくことをお勧めします。詳細については、「シングル AZ DB インスタンスの DB スナップショットの作成」を参照してください。

カタログメタデータを新しいバージョンの PLV8 と同期させるには
  1. 更新する必要があることを確認します。そのためには、インスタンスに接続されている間に以下のコマンドを実行します。

    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)
  2. RDS for PostgreSQL DB インスタンスのスナップショットを作成していない場合は、作成してください。次のステップは、スナップショットの作成中も続行できます。

  3. 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');
  4. pg_dump を使用して、スキーマのみのダンプファイルを作成します。例えば、クライアントマシンの /tmp ディレクトリに、ファイルを作成します。

    ./pg_dump -Fc --schema-only -U master postgres >/tmp/test.dmp

    この例では、以下のオプションを使用します。

    • -Fc – カスタム形式

    • -- スキーマのみ – スキーマの作成に必要なコマンド (ここでは関数) のみをダンプする

    • -U – RDS マスターユーザー名

    • database – DB インスタンスのデータベース名

    pg_dump の詳細については、「PostgreSQL ドキュメント」の「pg_dump」を参照してください。

  5. ダンプファイルに存在する "CREATE FUNCTION" DDL ステートメントを抽出します。次の例では grep コマンドを実行して、関数を作成する DDL ステートメントを抽出し、ファイルに保存します。この ddl は後続のステップで関数を再作成するために使用します。

    ./pg_restore -l /tmp/test.dmp | grep FUNCTION > /tmp/function_list/

    pg_restore の詳細については、「PostgreSQL ドキュメント」の「pg_restore」を参照してください。

  6. 関数およびエクステンションを削除します。次の例では、PLV8 ベースのオブジェクトを削除します。CASCADE オプションでは、すべての依存が削除されます。

    DROP EXTENSION plv8 CASCADE;

    plcoffee または plls に基づくオブジェクトが PostgreSQL インスタンスに含まれている場合は、それらのエクステンションに対してこのステップを繰り返します。

  7. エクステンションを作成します。次の例では、plv8、plcoffee、plls のエクステンションが作成されます。

    CREATE EXTENSION plv8; CREATE EXTENSION plcoffee; CREATE EXTENSION plls;
  8. ダンプファイルおよび "ドライバ" ファイルを使用して関数を作成します。

    次の例では、前に抽出した関数が再作成されます。

    ./pg_restore -U master -d postgres -Fc -L /tmp/function_list /tmp/test.dmp
  9. 次のクエリを使用して、すべての関数が再作成されたことを確認します。

    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 パラメータグループの作成については、「「パラメータグループを使用する」 」を参照してください。

plust 拡張機能は、AWS Management Console または AWS CLI を使用してインストールできます。

以下のステップでは、DB インスタンスがカスタム DB パラメータグループに関連付けられていることを前提としています。

plust 拡張機能を shared_preload_libraries パラメータにインストールする

rds_superuser グループ (ロール) のメンバーであるアカウントを使用して、次のステップを完了します。

  1. AWS Management Console にサインインし、Amazon RDS コンソール (https://console.aws.amazon.com/rds/) を開きます。

  2. ナビゲーションペインで、データベースを選択します。

  3. DB インスタンスの名前を選択して、その詳細を表示します。

  4. DB インスタンスの [設定] タブを開き、DB インスタンスパラメータグループのリンクを探します。

  5. リンクを選択して、DB クラスターに関連付けられたカスタムパラメータを開きます。

  6. パラメータ検索フィールドに、shared_pre を入力して shared_preload_libraries パラメータを検索します。

  7. プロパティ値にアクセスするには、[Edit parameters] (パラメータの編集) を選択します。

  8. [値] フィールドのリストに plrust を追加します。値のリスト内の項目を区切るにはカンマを使用します。

  9. DB インスタンスを再起動して、shared_preload_libraries パラメータの変更を有効にします。最初の再起動が完了するまでにさらに時間がかかる場合があります。

  10. インスタンスが使用可能になったら、plrust が初期化されていることを確認します。psql を使用して DB インスタンスに接続し、次のコマンドを実行します。

    SHOW shared_preload_libraries;

    出力は以下のようになります。

    shared_preload_libraries -------------------------- rdsutils,plrust (1 row)
shared_preload_libraries パラメータに pltrust 拡張機能をインストールする

rds_superuser グループ (ロール) のメンバーであるアカウントを使用して、次のステップを完了します。

  1. 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" \ --region aws-region
  2. reboot-db-instance AWS CLI コマンドを使用して DB インスタンスを再起動し、plrust ライブラリを初期化します。最初の再起動が完了するまでにさらに時間がかかる場合があります。

    aws rds reboot-db-instance \ --db-instance-identifier your-instance \ --region aws-region
  3. インスタンスが使用可能になったら、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 の入ったクレートを使用する

Amazon RDS for PostgreSQL バージョン 15.4、14.9、13.12 以降、PL/Rust は、次のクレートをサポートします。

  • aes

  • ctr

  • rand

RDS for PostgreSQL バージョン 15.5-R2、14.10-R2、および 13.13-R2 以降、PL/Rust は 2 つの追加のクレートをサポートしています。

  • croaring-rs

  • num-bigint

これらのクレートではデフォルト機能のみがサポートされています。新しい RDS for PostgreSQL バージョンには、更新されたバージョンのクレートが含まれているため、古いバージョンのクレートはサポートされなくなる可能性があります。

メジャーバージョンアップグレードを行う際のベストプラクティスに従って、お使いの PL/Rust 関数が新しいメジャーバージョンと互換性があるかどうかをテストしてください。詳細については、「Amazon RDS ユーザーガイド」のブログ「Amazon RDS を PostgreSQL のメジャーバージョンとマイナーバージョンにアップグレードするためのベストプラクティス」と「Amazon RDS の PostgreSQL DB エンジンのアップグレード」を参照してください。

PL/Rust 関数を作成する際の依存関係の使用例については、「依存関係を使う」を参照してください。

PL/Rust の制限事項

デフォルトでは、データベースユーザーは PL/Rust を使用できません。PL/Rust へのアクセスを提供するには、rds_superuser 権限を持つユーザーとして接続し、次のコマンドを実行します。

postgres=> GRANT USAGE ON LANGUAGE PLRUST TO user;