跳至内容

在蓝绿部署期间,如何防止在 Amazon RDS for PostgreSQL 或 Aurora PostgreSQL 兼容版实例中进行 DDL 操作?

2 分钟阅读
0

我想阻止我的 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.Delete and recreate your blue/green deployment and avoid future DDL changes...”

当您尝试切换时,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 的蓝绿部署中,DDL 操作可能会导致环境之间的逻辑复制性能降级,且需要进行完整的重新部署。为防止此问题,您必须在蓝绿部署期间在蓝色数据库上配置 PostgreSQL 事件触发器和触发器函数。

但是,您无法阻止以下 DDL 操作:

  • 针对共享对象(例如数据库、角色或表空间)的命令
  • 针对事件触发器的命令
  • pg_largeobject 中的大对象修改

**注意:**此问题仅在主要版本升级期间影响 RDS for PostgreSQL,此时 Amazon RDS 使用逻辑复制而非物理复制。原生 PostgreSQL 逻辑复制存在限制,这会在逻辑复制期间阻碍 PostgreSQL 蓝绿部署。有关详细信息,请参阅 PostgreSQL 网站上的 Restrictions(限制)

解决方法

配置 PostgreSQL 事件触发器和触发器函数

在配置蓝绿部署之前,请创建事件触发器和触发器函数。此外,您必须在每个需要 DDL 保护的数据库中分别创建事件触发器和触发器函数,因为事件触发器在数据库级别运行。默认情况下,绿色环境会继承事件触发器和触发器函数。要在绿色环境中执行 DDL 操作,请先删除您在蓝色环境中创建的触发器和函数。

要配置事件触发器和触发器函数,请完成以下步骤:

  1. 运行以下命令,以超级用户身份登录数据库:

    psql -U admin -h your_rds_endpoint -d your_database
  2. 运行以下命令创建 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 替换为您的架构。

  3. 运行以下命令创建事件触发器:

    CREATE EVENT TRIGGER block_ddl_trigger   
        ON ddl_command_start  
        EXECUTE FUNCTION schema_name.block_ddl_bg();

    **注意:**在上述命令中,请将 schema_name 替换为您的架构。

  4. 运行以下命令以验证触发器实现:

    -- 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';
  5. 运行以下命令以测试触发器:

    -- 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 网站上的 Event triggers(事件触发器)

PostgreSQL 网站上的 Event trigger firing matrix(事件触发器触发矩阵)

Aurora PostgreSQL 蓝绿部署的限制

使用逻辑复制的 RDS for PostgreSQL 蓝绿部署的限制

AWS 官方已更新 1 年前