Quiero impedir las operaciones del lenguaje de definición de datos (DDL) en mis instancias de Amazon Relational Database Service (Amazon RDS) para instancias de edición compatibles con PostgreSQL o Amazon Aurora (Aurora) PostgreSQL. Las operaciones de DDL provocan errores durante un despliegue azul-verde con replicación lógica.
Descripción breve
Cuando se ejecuta una operación de DDL en la instancia de Amazon RDS para PostgreSQL durante un despliegue azul-verde con replicación lógica, aparece el siguiente mensaje de error:
«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...»
Cuando intentas realizar una conmutación, Amazon RDS la bloquea y aparece el siguiente mensaje de error:
«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».
Las operaciones de DDL en los despliegues azul-verde basados en RDS para PostgreSQL pueden degradar la replicación lógica entre entornos y requerir un nuevo despliegue completo. Para evitar este problema, debes configurar los desencadenadores de eventos y las funciones de desencadenador de PostgreSQL en la base de datos azul durante los despliegues azul-verde.
Sin embargo, no puedes impedir las siguientes operaciones de DDL:
- Comandos que se dirigen a objetos compartidos, como bases de datos, roles o espacios de tablas
- Comandos que apuntan a los desencadenantes de eventos
- Modificaciones de objetos grandes en pg_largeobject
Nota: Este problema afecta a RDS para PostgreSQL solo [durante las actualizaciones de versiones principales](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments-replication-type.html), cuando Amazon RDS utiliza la replicación lógica en lugar de la replicación física. Las restricciones con la replicación lógica nativa de PostgreSQL limitan los despliegues azul-verde de PostgreSQL durante la replicación lógica. Para obtener más información, consulta Restricciones en el sitio web de PostgreSQL.
Resolución
Configuración de los desencadenadores de eventos y las funciones de desencadenador de PostgreSQL
Crea los desencadenadores de eventos y las funciones de desencadenador antes de configurar un despliegue azul-verde. Además, debes crear cada desencadenador de eventos y cada función de desencadenador por separado en cada base de datos que requiera protección DDL, ya que los desencadenadores de eventos funcionan a nivel de base de datos. El entorno verde hereda los desencadenadores de eventos y las funciones de desencadenador de forma predeterminada. Para realizar operaciones de DDL en el entorno verde, primero elimina los desencadenadores y las funciones que creaste en el entorno azul.
Para configurar los desencadenadores de eventos y las funciones de desencadenador, sigue estos pasos:
-
Ejecuta el siguiente comando para iniciar sesión en la base de datos como superusuario:
psql -U admin -h your_rds_endpoint -d your_database
-
Ejecuta el siguiente comando para crear la función de bloqueo de 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;
Nota: En el comando anterior, sustituye schema_name por tu esquema.
-
Ejecuta el siguiente comando para crear el desencadenador de eventos:
CREATE EVENT TRIGGER block_ddl_trigger
ON ddl_command_start
EXECUTE FUNCTION schema_name.block_ddl_bg();
Nota: En el comando anterior, sustituye schema_name por tu esquema.
-
Ejecuta el siguiente comando para verificar la implementación del desencadenador:
-- 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';
-
Ejecuta el siguiente comando para probar los desencadenadores:
-- Try to create a test table
CREATE TABLE test_table (id int);
-- Should receive blocking message
Eliminación del desencadenador de eventos y la función de desencadenador
Después de completar la conmutación de despliegue azul-verde o de retirar el despliegue azul-verde, ejecuta el siguiente comando.
Elimina el desencadenador del evento:
-- Remove event trigger
DROP EVENT TRIGGER block_ddl_trigger;
Elimina la función de desencadenador:
-- Remove trigger function
DROP FUNCTION schema_name.block_ddl_bg();
Nota: En el comando anterior, sustituye schema_name por tu esquema.
Información relacionada
Desencadenadores de eventos en el sitio web de PostgreSQL
Matriz de activación de desencadenadores de eventos en el sitio web de PostgreSQL
Limitaciones de Aurora PostgreSQL para despliegues azul-verde
Limitaciones de RDS para PostgreSQL para despliegues azul-verde con replicación lógica