Usar pgactive para comportar a replicação ativa-ativa
A extensão pgactive
usa replicação ativa-ativa para comportar e coordenar operações de gravação em vários bancos de dados do RDS para PostgreSQL. O Amazon RDS para PostgreSQL é compatível com a extensão pgactive
nas seguintes versões:
-
RDS para PostgreSQL 16.1 e versões 16 posteriores
-
RDS para PostgreSQL 15.4-R2 e versões 15 posteriores
-
RDS para PostgreSQL 14.10 e versões 14 posteriores
-
RDS para PostgreSQL 13.13 e versões 13 posteriores
-
RDS para PostgreSQL 12.17 e versões 12 posteriores
-
RDS para PostgreSQL 11.22
nota
Quando há operações de gravação em mais de um banco de dados em uma configuração de replicação, existe a possibilidade de conflitos. Para ter mais informações, consulte Lidar com conflitos na replicação ativa-ativa.
Tópicos
- Inicializar o recurso de extensão pgactive
- Configurar a replicação lógica para as instâncias de banco de dados do RDS para PostgreSQL
- Lidar com conflitos na replicação ativa-ativa
- Lidar com sequências na replicação ativa-ativa
- Referência de parâmetros da extensão pgactive
- Medir o atraso de replicação entre membros pgactive
- Limitações da extensão pgactive
Inicializar o recurso de extensão pgactive
Para inicializar o recurso de extensão pgactive
na instância de banco de dados do RDS para PostgreSQL, defina o valor do parâmetro rds.enable_pgactive
como 1
e, em seguida, crie a extensão no banco de dados. Isso ativa automaticamente os parâmetros rds.logical_replication
e track_commit_timestamp
e define o valor de wal_level
como logical
.
Você deve ter permissões como a função rds_superuser
para realizar essas tarefas.
Você pode usar o AWS Management Console ou a AWS CLI para criar as instâncias necessárias do banco de dados RDS para PostgreSQL. As etapas a seguir pressupõem que a instância de banco de dados do RDS para PostgreSQL esteja associada a um grupo de parâmetros de banco de dados personalizado. Para obter mais informações sobre como criar um grupo de parâmetros de banco de dados personalizado, consulte Grupos de parâmetros para Amazon RDS.
Como inicializar o recurso de extensão pgactive
Faça login no AWS Management Console e abra o console do Amazon RDS em https://console.aws.amazon.com/rds/
. -
No painel de navegação, escolha a instância de banco de dados do RDS para PostgreSQL.
-
Abra a guia Configuração para a instância de banco de dados do RDS para PostgreSQL. Nos detalhes da instância, encontre o link do Grupo de parâmetros da instância de banco de dados.
-
Clique no link para abrir os parâmetros personalizados associados à instância de banco de dados do RDS para PostgreSQL.
Encontre o parâmetro
rds.enable_pgactive
e configure-o como1
para inicializar o recursopgactive
.Escolha Salvar alterações.
No painel de navegação do console do Amazon RDS, escolha Bancos de dados.
Selecione a instância de banco de dados do RDS para PostgreSQL e escolha Reinicializar no menu Ações.
Confirme a reinicialização da instância de banco de dados para que as alterações tenham efeito.
Quando a instância de banco de dados estiver disponível, use
psql
ou qualquer outro cliente PostgreAQL para se conectar à instância de banco de dados do RDS para PostgreSQL.O exemplo a seguir pressupõe que a instância de banco de dados do RDS para PostgreSQL tenha um banco de dados padrão chamado
postgres
.psql --host=
mydb.111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=master username
--password --dbname=postgres
Para verificar se pgactive foi inicializada, execute o comando a seguir.
postgres=>
SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';
Se
pgactive
estiver emshared_preload_libraries
, o comando anterior retornará o seguinte:?column? ---------- t
Crie a extensão da forma a seguir.
postgres=>
CREATE EXTENSION pgactive;
Como inicializar o recurso de extensão pgactive
Para inicializar pgactive
usando a AWS CLI, execute a operação modify-db-parameter-group para modificar determinados parâmetros no grupo parâmetros personalizado, conforme mostrado no procedimento a seguir.
Use o comando AWS CLI a seguir para definir
rds.enable_pgactive
como1
para inicializar o recursopgactive
da instância de banco de dados do RDS para PostgreSQL.postgres=>
aws rds modify-db-parameter-group \ --db-parameter-group-namecustom-param-group-name
\ --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \ --regionaws-region
-
Use o comando AWS CLI a seguir para reinicializar a instância de banco de dados do RDS para PostgreSQL e inicializar a biblioteca da
pgactive
.aws rds reboot-db-instance \ --db-instance-identifier
your-instance
\ --regionaws-region
Quando a instância estiver disponível, use
psql
para se conectar à instância de banco de dados RDS para PostgreSQL.psql --host=
mydb.111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=master user
--password --dbname=postgres
Crie a extensão da forma a seguir.
postgres=>
CREATE EXTENSION pgactive;
Configurar a replicação lógica para as instâncias de banco de dados do RDS para PostgreSQL
O procedimento a seguir mostra como iniciar a replicação ativa-ativa entre duas instâncias de banco de dados do RDS PostgreSQL executando o PostgreSQL 15.4 ou posterior na mesma região. Para executar o exemplo de alta disponibilidade multirregional, você precisa implantar instâncias do Amazon RDS para PostgreSQL em duas regiões diferentes e configurar o emparelhamento de VPC. Para obter mais informações, consulte Emparelhamento de VPC.
nota
O envio de tráfego entre várias regiões pode gerar custos adicionais.
Estas etapas pressupõem que a instância de banco de dados do RDS para PostgreSQL foi configurada com a extensão pgactive
. Para ter mais informações, consulte Inicializar o recurso de extensão pgactive.
Como configurar a primeira instância de banco de dados do RDS para PostgreSQL com a extensão pgactive
O exemplo a seguir ilustra como o grupo pgactive
é criado e mostra outras etapas necessárias para criar a extensão pgactive
na instância de banco de dados do RDS para PostgreSQL.
Use
psql
ou outra ferramenta cliente para se conectar à primeira instância de banco de dados do RDS para PostgreSQL.psql --host=
firstinstance.111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=master username
--password --dbname=postgres
Crie um banco de dados na instância do RDS para PostgreSQL usando o seguinte comando:
postgres=>
CREATE DATABASEapp
;Alterne a conexão para o novo banco de dados usando o seguinte comando:
\c
app
Para verificar se o parâmetro
shared_preload_libraries
contémpgactive
, execute o seguinte comando:app=>
SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';?column? ---------- t
-
Crie e preencha uma tabela de exemplo usando a seguinte instrução SQL:
Crie uma tabela de exemplo usando a declaração SQL a seguir.
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);Preencha a tabela com alguns dados de amostra usando a instrução SQL a seguir.
app=>
INSERT INTO inventory.products (id, product_name) VALUES (1, 'soap'), (2, 'shampoo'), (3, 'conditioner');Verifique se os dados existem na tabela usando a declaração SQL a seguir.
app=>
SELECT count(*) FROM inventory.products;count ------- 3
Crie uma extensão
pgactive
no banco de dados existente.app=>
CREATE EXTENSION pgactive;Crie e inicialize o grupo pgactive usando os seguintes comandos:
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 é o nome atribuído para identificar de maneira exclusiva um nó no grupo
pgactive
.nota
Para realizar essa etapa com êxito em uma instância de banco de dados acessível ao público geral, você deve ativar o parâmetro
rds.custom_dns_resolution
definindo-o como1
.Para verificar se a instância de banco de dados está pronta, use o seguinte comando:
app=>
SELECT pgactive.pgactive_wait_for_node_ready();Se o comando for bem-sucedido, você verá o seguinte resultado:
pgactive_wait_for_node_ready ------------------------------ (1 row)
Como configurar a segunda instância do RDS para PostgreSQL e juntá-la ao grupo pgactive
O exemplo a seguir mostra como juntar uma instância de banco de dados do RDS para PostgreSQL ao grupo pgactive
, bem como outras etapas necessárias para criar a extensão pgactive
na instância de banco de dados.
Estas etapas pressupõem que as instâncias de banco de dados do RDS para PostgreSQL tenham sido configuradas com a extensão pgactive
. Para ter mais informações, consulte Inicializar o recurso de extensão pgactive.
Use
psql
para se conectar à instância em que você deseja receber atualizações do editor.psql --host=
secondinstance.111122223333
.aws-region
.rds.amazonaws.com --port=5432 --username=master username
--password --dbname=postgres
Crie um banco de dados na segunda instância de banco de dados do RDS para PostgreSQL usando o seguinte comando:
postgres=>
CREATE DATABASEapp
;Alterne a conexão para o novo banco de dados usando o seguinte comando:
\c
app
Crie a extensão
pgactive
no banco de dados existente.app=>
CREATE EXTENSION pgactive;Junte o a segunda instância de banco de dados do RDS para PostgreSQL ao grupo
pgactive
da forma a seguir.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 é o nome atribuído para identificar de maneira exclusiva um nó no grupo
pgactive
.Para verificar se a instância de banco de dados está pronta, use o seguinte comando:
app=>
SELECT pgactive.pgactive_wait_for_node_ready();Se o comando for bem-sucedido, você verá o seguinte resultado:
pgactive_wait_for_node_ready ------------------------------ (1 row)
Se o primeiro banco de dados RDS para PostgreSQL for relativamente grande, você poderá ver
pgactive.pgactive_wait_for_node_ready()
emitindo o relatório de progresso da operação de restauração. A saída será semelhante à seguinte: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)
Deste ponto em diante,
pgactive
sincroniza os dados entre as duas instâncias de banco de dados.Você pode usar o comando a seguir para verificar se o banco de dados da segunda instância de banco de dados tem os dados:
app=>
SELECT count(*) FROM inventory.products;Se os dados forem sincronizados com sucesso, você verá a seguinte saída:
count ------- 3
Execute o seguinte comando para inserir novos valores:
app=>
INSERT INTO inventory.products (id, product_name) VALUES ('lotion');Conecte-se ao banco de dados da primeira instância de banco de dados e execute a seguinte consulta:
app=>
SELECT count(*) FROM inventory.products;Se a replicação ativa-ativa for inicializada, a saída será semelhante à seguinte:
count ------- 4
Como desanexar e remover uma instância de banco de dados do grupo pgactive
É possível desanexar e remover uma instância de banco de dados do grupo pgactive
usando estas etapas:
Você pode separar a segunda instância de banco de dados da primeira instância de banco de dados usando o seguinte comando:
app=>
SELECT * FROM pgactive.pgactive_detach_nodes(ARRAY[‘node2-app
']);Remova a extensão
pgactive
da segunda instância de banco de dados usando o seguinte comando:app=>
SELECT * FROM pgactive.pgactive_remove();Para remover a extensão forçosamente:
app=>
SELECT * FROM pgactive.pgactive_remove(true);Descarte a extensão usando o seguinte comando:
app=>
DROP EXTENSION pgactive;
Lidar com conflitos na replicação ativa-ativa
A extensão pgactive
funciona por banco de dados e não por cluster. Cada instância de banco de dados que usa pgactive
é uma instância independente e pode aceitar alterações de dados de qualquer fonte. Quando uma alteração é enviada a uma instância de banco de dados, o PostgreSQL a confirma localmente e depois usa pgactive
para replicar a alteração de forma assíncrona para outras instâncias de banco de dados. Quando duas instâncias de banco de dados do PostgreSQL atualizam o mesmo registro quase ao mesmo tempo, pode ocorrer um conflito.
A extensão pgactive
fornece mecanismos para detecção de conflitos e resolução automática. Ela rastreia o carimbo de data/hora em que a transação foi confirmada em ambas as instâncias de banco de dados e aplica automaticamente a alteração com o carimbo de data/hora mais recente. A extensão pgactive
também registra em log quando ocorre um conflito na tabela pgactive.pgactive_conflict_history
.
O pgactive.pgactive_conflict_history
continuará crescendo. Talvez você queira definir uma política de limpeza. Isso pode ser feito excluindo alguns registros regularmente ou definindo um esquema de particionamento para essa relação (e depois separando, descartando e truncando as partições de interesse). Para implementar a política de limpeza regularmente, uma opção é usar a extensão pg_cron
. Veja as informações a seguir de um exemplo para a tabela de histórico pg_cron
, Agendar manutenção com a extensão pg_cron do PostgreSQL.
Lidar com sequências na replicação ativa-ativa
Uma instância de banco de dados do RDS para PostgreSQL com a extensão pgactive
usa dois mecanismos de sequência diferentes para gerar valores exclusivos.
Sequências globais
Para usar uma sequência global, crie uma sequência local com a instrução CREATE SEQUENCE
. Use pgactive.pgactive_snowflake_id_nextval(seqname)
em vez de usingnextval(seqname)
para obter o próximo valor exclusivo da sequência.
O exemplo a seguir cria uma rede global.
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');
Sequências particionadas
Em sequências divididas ou particionadas, uma sequência normal do PostgreSQL é usada em cada nó. Cada sequência é incrementada na mesma quantidade e começa com diferentes deslocamentos. Por exemplo, com a etapa 100, o nó 1 gera a sequência como 101, 201, 301 e assim por diante, e o nó 2 gera a sequência como 102, 202, 302 e assim por diante. Esse esquema funciona bem mesmo que os nós não possam se comunicar por longos períodos, mas exige que o designer especifique um número máximo de nós ao estabelecer o esquema e requer configuração por nó. Erros podem facilmente levar à sobreposição de sequências.
É relativamente simples configurar essa abordagem com pgactive
criando a sequência desejada em um nó da seguinte maneira:
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');
Em seguida, chame setval
em cada nó para fornecer um valor inicial de deslocamento diferente da forma a seguir.
postgres=>
-- On node 1 SELECT setval('some_seq', 1); -- On node 2 SELECT setval('some_seq', 2);
Referência de parâmetros da extensão pgactive
É possível usar a consulta a seguir para visualizar todos os parâmetros associados à extensão pgactive
.
postgres=>
SELECT * FROM pg_settings WHERE name LIKE 'pgactive.%';
Medir o atraso de replicação entre membros pgactive
Você pode usar a consulta a seguir para visualizar o atraso de replicação entre os membros de pgactive
. Execute essa consulta em cada nó de pgactive
para ter a imagem completa.
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
Limitações da extensão pgactive
Todas as tabelas exigem uma chave primária; do contrário, atualizações e exclusões não são permitidas. Os valores na coluna Chave primária não devem ser atualizados.
As sequências podem ter lacunas e, às vezes, podem não seguir uma ordem. As sequências não são replicadas. Para ter mais informações, consulte Lidar com sequências na replicação ativa-ativa.
O DDL e os objetos grandes não são replicados.
Índices secundários exclusivos podem causar divergência de dados.
O agrupamento precisa ser idêntico em todos os nós do grupo.
O balanceamento de carga entre os nós é um antipadrão.
Transações grandes podem causar atraso na replicação.