Quero evitar operações de linguagem de definição de dados (Data Definition Language, DDL) em minhas instâncias do Amazon Relational Database Service (Amazon RDS) para PostgreSQL ou Amazon Aurora (Aurora) da Edição compatível com PostgreSQL. As operações de DDL causam erros durante uma implantação azul/verde com replicação lógica.
Breve descrição
Quando uma operação de DDL é executada na instância do Amazon RDS para PostgreSQL durante uma implantação azul/verde com replicação lógica, você recebe a seguinte mensagem de erro:
“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...”
Quando você tenta uma transição, o Amazon RDS bloqueia a transição e você recebe a seguinte mensagem de erro:
“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.”
As operações de DDL no RDS para implantações azul/verde baseadas em PostgreSQL podem degradar a replicação lógica entre ambientes e exigir uma reimplantação completa. Para evitar esse problema, você deve configurar os gatilhos de evento do PostgreSQL e as funções de gatilho no banco de dados azul durante as implantações azul/verde.
No entanto, não é possível impedir as seguintes operações de DDL:
- Comandos que visam objetos compartilhados, como bancos de dados, perfis ou espaços de tabela
- Comandos que visam gatilhos de evento
- Modificações de objeto grande em pg\ _largeobject
Observação: esse problema afeta o RDS para PostgreSQL somente durante grandes upgrades de versão, quando o Amazon RDS usa replicação lógica em vez de replicação física. As restrições com a replicação lógica nativa do PostgreSQL limitam as implantações azul/verde do PostgreSQL durante a replicação lógica. Para mais informações, consulte Restrições no site do PostgreSQL.
Resolução
Configure gatilhos de evento e funções de gatilho do PostgreSQL
Crie os gatilhos de evento e as funções de gatilho antes de configurar uma implantação azul/verde. Além disso, você deve criar cada gatilho de evento e cada função de gatilho separadamente em cada banco de dados que exija proteção DDL, pois os gatilhos de eventos funcionam no nível do banco de dados. O ambiente verde herda os gatilhos de evento e as funções de gatilho por padrão. Para realizar operações de DDL no ambiente verde, primeiro descarte os gatilhos e as funções que você criou no ambiente azul.
Para configurar os gatilhos de evento e as funções de gatilho, conclua as seguintes etapas:
-
Execute o comando a seguir para fazer login no banco de dados como superusuário:
psql -U admin -h your_rds_endpoint -d your_database
-
Execute o comando a seguir para criar a função de bloqueio 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;
Observação: no comando anterior, substitua schema_name pelo seu esquema.
-
Execute o comando a seguir para criar o gatilho de evento:
CREATE EVENT TRIGGER block_ddl_trigger
ON ddl_command_start
EXECUTE FUNCTION schema_name.block_ddl_bg();
Observação: no comando anterior, substitua schema_name pelo seu esquema.
-
Execute o comando a seguir para verificar a implementação do gatilho:
-- 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';
-
Execute o comando a seguir para testar os gatilhos:
-- Try to create a test table
CREATE TABLE test_table (id int);
-- Should receive blocking message
Remova o gatilho de evento e a função de gatilho
Depois de concluir a transição de implantação azul/verde ou descomissionar a implantação azul/verde, execute o seguinte comando.
Remova o gatilho do evento:
-- Remove event trigger
DROP EVENT TRIGGER block_ddl_trigger;
Remova a função de gatilho:
-- Remove trigger function
DROP FUNCTION schema_name.block_ddl_bg();
Observação: no comando anterior, substitua schema_name pelo seu esquema.
Informações relacionadas
Gatilhos de evento no site do PostgreSQL
Matriz de acionamento do gatilho de evento no site do PostgreSQL
Limitações do Aurora PostgreSQL para implantações azul/verde
Limitações do RDS para PostgreSQL para implantações azul/verde com replicação lógica