Amazon Relational Database Service (Amazon RDS) for PostgreSQL または Amazon Aurora (Aurora) PostgreSQL 互換エディションのインスタンスで、データ定義言語 (DDL) による操作を防止したいです。論理レプリケーションを使用するブルー/グリーンデプロイメントにおいて、DDL 操作が原因でエラーが発生しています。
簡単な説明
論理レプリケーションを使用するブルー/グリーンデプロイ中に Amazon RDS for PostgreSQL インスタンスで DDL 操作を実行すると、次のエラーメッセージが表示されます。
"Data definition language (DDL) changes aren't supported...Your green databases now have a status of REPLICATION_DEGRADED. (グリーンデータベースのステータスが REPLICATION_DEGRADED に変更されました)Delete and recreate your blue/green deployment and avoid future DDL changes... (ブルー/グリーンデプロイメントを削除して再作成し、今後は DDL の変更を避けてください)」
スイッチオーバーを試行する際、Amazon RDS によりスイッチオーバーがブロックされ、次のエラーメッセージが表示されます。
「Switchover from DB cluster to... was cancelled because there are DDL or Large Object changes on... that can't be replicated.Delete the blue/green deployment along with the target cluster, then re-create it. (ブルー/グリーンデプロイおよびターゲットクラスターを削除し、再作成してください)」
RDS for PostgreSQL ベースの Blue/Green デプロイメントで DDL 操作が行われると、環境間の論理レプリケーションに悪影響が生じ、完全な再デプロイが必要になる場合があります。この問題を防ぐには、ブルー/グリーンデプロイ時に、PostgreSQL イベントトリガーとトリガー関数を blue データベースに設定する必要があります。
ただし、次の DDL 操作は防止できません。
- データベース、ロール、テーブルスペースなどの共有オブジェクトをターゲットとするコマンド
- イベントトリガーをターゲットとするコマンド
- pg_largeobject でのラージオブジェクトの変更
注: この問題では、メジャーバージョンのアップグレード中の RDS for PostgreSQL のみが影響を受けます。その期間は、Amazon RDS は物理レプリケーションではなく論理レプリケーションを使用します。ネイティブ PostgreSQL 論理レプリケーションの制約により、論理レプリケーション中の PostgreSQL ブルー/グリーンデプロイは制限されます。詳細については、PostgreSQL のウェブサイトで「制約」を参照してください。
解決策
PostgreSQL のイベントトリガーとトリガー関数を設定する
ブルー/グリーンデプロイを設定する前に、イベントトリガーとトリガー関数を作成します。また、イベントトリガーはデータベースレベルで機能するため、DDL 保護を必要とするすべてのデータベースで、各イベントトリガーとトリガー関数を個別に作成する必要があります。グリーン環境は、デフォルトではイベントトリガーとトリガー関数を継承します。グリーン環境で DDL 操作を実行するには、まずブルー環境で作成したトリガーと関数を削除します。
イベントトリガーとトリガー関数を設定するには、次の手順を実行します。
-
次のコマンドを実行して、スーパーユーザーとしてデータベースにログインします。
psql -U admin -h your_rds_endpoint -d your_database
-
次のコマンドを実行して DDL をブロックする関数を作成します。
CREATE OR REPLACE FUNCTION schema_name.block_ddl_bg() RETURNS event_trigger
SECURITY DEFINER
AS $$
DECLARE
-- Define allowed users and roles here
allowed_users TEXT[] := ARRAY['rdsadmin', 'rdsrepladmin'];
allowed_roles TEXT[] := ARRAY['rdsrepladmin'];
BEGIN
-- Check if either the session user or current role is allowed
IF NOT (session_user = ANY(allowed_users) OR current_role = ANY(allowed_roles)) THEN
RAISE EXCEPTION 'DDL operations are blocked to prevent Blue Green Deployment replica degradation. User: %, Role: %, Status: BLOCKED',
session_user, current_role;
END IF;
END;
$$ LANGUAGE plpgsql;
注: 上記のコマンドでは、schema_name を実際のスキーマに置き換えてください。
-
次のコマンドを実行してイベントトリガーを作成します。
CREATE EVENT TRIGGER block_ddl_trigger
ON ddl_command_start
EXECUTE FUNCTION schema_name.block_ddl_bg();
注: 上記のコマンドでは、schema_name を実際のスキーマに置き換えてください。
-
次のコマンドを実行してトリガーの実装を検証します。
-- Check if the function exists
SELECT proname, pronamespace::regnamespace
FROM pg_proc
WHERE proname = 'block_ddl_bg';
-- Check if the event trigger exists
SELECT evtname, evtevent, evtowner::regrole
FROM pg_event_trigger
WHERE evtname = 'block_ddl_trigger';
-
次のコマンドを実行してトリガーをテストします。
-- Try to create a test table
CREATE TABLE test_table (id int);
-- Should receive blocking message
イベントトリガーとトリガー機能を削除する
ブルー/グリーンデプロイの切り替えを完了するか、ブルー/グリーンデプロイのコミットを取り消した後、次のコマンドを実行します。
イベントトリガーを削除します。
-- Remove event trigger
DROP EVENT TRIGGER block_ddl_trigger;
トリガー関数を削除します。
-- Remove trigger function
DROP FUNCTION schema_name.block_ddl_bg();
注: 上記のコマンドでは、schema_name を実際のスキーマに置き換えてください。
関連情報
イベントトリガー (PostgreSQL のウェブサイト)
イベントトリガー起動マトリックス (PostgreSQL のウェブサイト)
Aurora PostgreSQL でのブルー/グリーンデプロイメントの制限事項
RDS for PostgreSQL での、論理レプリケーションを使用するブルー/グリーンデプロイメントの制限事項