Replicação bidirecional no OCI Database para PostgreSQL usando pglogical
Introdução
A replicação lógica no OCI PostgreSQL permite replicar objetos de dados e suas alterações com base na identidade de replicação de uma tabela, geralmente a chave primária. Ele usa um modelo de publicação-assinatura, em que um ou mais assinantes assinam publicações definidas em um nó do editor. Os assinantes extraem dados dessas publicações e podem, opcionalmente, republicar as alterações para permitir a replicação em cascata ou topologias mais complexas.
A replicação lógica efetua alterações no nível da linha — operações INSERT
, UPDATE
e DELETE
— decodificando o WAL (Log de Gravação Antecipada) usando a decodificação lógica. Essas alterações decodificadas são independentes do formato de armazenamento físico do OCI PostgreSQL e representam apenas as operações de dados lógicas, fornecendo maior flexibilidade para sistemas downstream.
Neste tutorial, vamos discutir como usar a extensão pglógica para replicação lógica e como ela permite a replicação bidirecional entre dois Sistemas de Banco de Dados no OCI Database para PostgreSQL.
Replicação bidirecional
A replicação bidirecional (BDR) com pglógico significa que dois ou mais Sistemas de Banco de Dados OCI PostgreSQL publicam e se inscrevem nas alterações um do outro. Em outras palavras, cada Sistema de Banco de Dados OCI PostgreSQL pode ler e gravar, e todas as alterações são replicadas em ambas as direções. Consequentemente, quaisquer modificações executadas em um dos Sistemas de Banco de Dados do OCI PostgreSQL serão espelhadas e implementadas em ambos.
A replicação bidirecional geralmente é recomendada quando você precisa de uma arquitetura de banco de dados regional ou global que ofereça acesso de leitura e gravação de baixa latência para usuários em vários locais. Ao co-localizar instâncias de leitura/gravação perto de usuários em cada região, as alterações podem ser feitas localmente e depois replicadas para outras regiões, garantindo que os dados sejam sincronizados em todos os nós.
Na prática, a maioria dos casos de uso requer apenas que um pequeno subconjunto de tabelas seja gravável em várias regiões, enquanto a maioria do banco de dados pode permanecer somente leitura ou gerenciado centralmente por meio da replicação unidirecional.
No entanto, a replicação bidirecional introduz complexidade. A manutenção da consistência de dados e o gerenciamento da topologia de replicação podem tornar-se um desafio à medida que o sistema cresce.
Se os principais objetivos do seu aplicativo forem escalabilidade de leitura e resiliência a interrupções regionais, uma abordagem mais simples e robusta será implantar uma instância do OCI Database para PostgreSQL de alta disponibilidade com várias réplicas de leitura, na mesma região ou em todas as regiões.
Como funciona o trabalho pglógico bidirecional
Em pglogical, você pode configurar várias assinaturas e publicações como esta:
-
O Sistema de Banco de Dados 1 publica alterações nas assinaturas do Sistema de Banco de Dados 2
-
Database System 2 publica alterações → Assinaturas do Database System 1
Cada nó:
-
Envia suas alterações para o outro
-
Aplica alterações do outro
-
Trata possíveis conflitos usando as configurações de resolução de conflitos da pglogical
Para saber mais sobre a replicação pglógica unidirecional entre regiões no OCI PostgreSQL, consulte este blog: pglógica unidirecional entre regiões.
Gerenciando Conflitos e Configuração
O editor (o banco de dados de origem) define uma ou mais publicações e envia dados de alteração (operações DML) ao assinante (o banco de dados de destino). Um assinante pode se conectar a vários editores e aplicar suas alterações ao banco de dados local.
A extensão pglogical fornece a resolução avançada de conflitos através do parâmetro pglogical.conflict_resolution
, que suporta os seguintes modos:
-
apply_remote
(padrão no OCI Database para PostgreSQL) -
error
-
keep_local
-
last_update_wins
-
first_update_wins
Para obter mais detalhes sobre conflict_resolution em pglógico, consulte a documentação oficial sobre o github: Opções de Configuração do 2º Quadrante.
Ao usar keep_local
, last_update_wins
ou first_update_wins
, track_commit_timestamps
deve ser ativado no editor e no assinante. Tenha em mente que habilitar essa configuração pode introduzir custos indiretos de desempenho mensuráveis, dependendo da sua carga de trabalho. É altamente recomendável avaliar o impacto no desempenho em seu ambiente de produção antes da implantação.
Configurando a replicação bidirecional no OCI PostgreSQL
Para ativar a extensão pglogical no OCI Database para PostgreSQL, consulte este tutorial: Ativar extensão pglogical no OCI PostgreSQL.
Tarefa 1: Pré-Requisitos
Depois que a extensão pglógica for criada no seu OCI Database para PostgreSQL, Conceda a seguinte permissão no sistema de banco de dados #1 e no sistema de banco de dados #2,
ALTER ROLE psql WITH REPLICATION;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_replication_origin_session_reset() TO psql;
GRANT EXECUTE ON FUNCTION pg_catalog.pg_replication_origin_session_setup TO psql;
GRANT ALL ON FUNCTION pg_catalog.pg_replication_origin_session_setup TO psql;
Observação:
psql
é uma amostra de usuário de replicação criada especificamente para fins de demonstração neste tutorial.
Tarefa 2: Configurando a Replicação Lógica Unidirecional
No Sistema de Banco de Dados 1:
Depois de concluir os pré-requisitos descritos anteriormente, crie uma tabela de teste e insira alguns registros para verificar o fluxo de trabalho pglógico.
CREATE TABLE test_table (
id serial PRIMARY KEY,
data text
);
INSERT INTO test_table
(id, data)
VALUES
(generate_series(1, 1000), 'Test');
Crie o nó do provedor:
O próximo passo é criar um nó usando a função pglógica create_node.
SELECT pglogical.create_node(
node_name := 'provider1',
dsn := 'host=primary.xxxxxxxx.postgresql.us-phoenix-1.oci.oraclecloud.com
port=5432
user=psql
password=xxxxx
dbname=postgres'
);
Veja a seguir as definições de parâmetro para a função create_node
:
node_name
: Especifique o nome do editor a ser criado no Sistema de banco de dados nº 1.host
: Informe o nome de domínio totalmente qualificado (FQDN) do Sistema de Banco de Dados nº 1.port_number
: Forneça a porta na qual o Sistema de Banco de Dados #1 está sendo executado.database_name
: Especifique o nome do banco de dados em que a replicação pglógica será configurada.
Como próxima etapa, identifique as tabelas que precisam ser incluídas na replicação. O pglogical usa conjuntos de replicação para gerenciar quais tabelas e ações (INSERT
, UPDATE
, DELETE
) são replicadas. Você pode criar um conjunto de replicação personalizado usando a função create_replication_set
ou usar o conjunto padrão predefinido, que replica todas as ações em suas tabelas designadas. Para incluir tabelas, use replication_set_add_table
para tabelas individuais ou replication_set_add_all_tables
para adicionar todas as tabelas de um esquema específico.
O seguinte comando adiciona todas as tabelas do esquema público ao conjunto de replicação padrão:
SELECT pglogical.replication_set_add_all_tables(
'default',
ARRAY['public']
);
Para saber mais sobre conjuntos de replicação, consulte Conjuntos de replicação.
No Sistema de Banco de Dados 2:
Crie uma tabela correspondente como no Sistema de Banco de Dados #1:
Crie a tabela de teste no Sistema de Banco de Dados #2 para corresponder à estrutura da tabela no Sistema de Banco de Dados #1.
CREATE TABLE test_table (
id serial PRIMARY KEY,
data text
);
Crie o nó do assinante:
Em seguida, crie um nó no Sistema de Banco de Dados #2 usando a função pglógica create_node
, assim como você fez no Sistema de Banco de Dados #1:
SELECT pglogical.create_node(
node_name := 'subscriber1',
dsn := 'host=primary.xxxxxx.postgresql.us-phoenix-1.oci.oraclecloud.com
port=5432
user=psql
password=xxxxxx
dbname=postgres'
);
Veja a seguir as definições de parâmetro para a função create_node
:
node_name
: Defina o nome do assinante no sistema de banco de dados nº 2.host
: Informe o nome de domínio totalmente qualificado (FQDN) do sistema de banco de dados nº 2.port_number
: Informe a porta na qual o sistema de banco de dados #2 está sendo executado.database_name
: Forneça o nome do banco de dados em que a assinatura será criada.
Criar Assinatura pglógica:
A próxima etapa é criar a assinatura para iniciar a replicação de dados do Sistema de Banco de Dados nº 1 usando a função create_subscription
.
O parâmetro subscription_name
pode ser qualquer nome que você escolher para a assinatura. O provider_dsn
é a string de conexão para o Sistema de Banco de Dados nº 1, e o parâmetro replication_sets
especifica quais conjuntos de replicação usar. Neste exemplo, estamos usando o conjunto de replicação padrão.
O argumento synchronize_data
informa ao pglogical se deve ou não copiar dados existentes da origem. Em nosso teste, ele é definido como true
porque queremos que todas as linhas sejam copiadas, juntamente com quaisquer alterações futuras.
O parâmetro forward_origins
é crucial para ativar a replicação bidirecional. A definição de forward_origins := '{}'
garante que somente as alterações originadas do próprio nó sejam encaminhadas e não as que já foram replicadas de outros nós. Isso impede que o processo de replicação entre em um loop infinito, onde as alterações são continuamente replicadas para frente e para trás.
SELECT pglogical.create_subscription(
subscription_name := 'subscription1',
provider_dsn := 'host=primary.xxxxxxx.postgresql.us-phoenix-1.oci.oraclecloud.com
port=5432
sslmode=require
dbname=postgres
user=psql
password=xxxxx',
replication_sets := ARRAY['default'],
synchronize_data := true,
forward_origins := '{}'
);
Verificar status da assinatura:
Verifique o status da assinatura e as informações básicas no sistema de banco de dados #2 usando o seguinte comando:
select * from pglogical.show_subscription_status();
-[ RECORD 1 ]-----+----------------------------------------------------------------------------------------------------------------------------------------------------------------
subscription_name | subscription1
status | replicating
provider_node | provider1
provider_dsn | host=primary.xxxxxxxxx.postgresql.us-phoenix-1.oci.oraclecloud.com port=5432 sslmode=require dbname=postgres user=psql password=xxxxxx
slot_name | pgl_postgres_provider1_subscription1
replication_sets | {default}
forward_origins |
Tarefa 3: Testar a replicação do Sistema de Banco de Dados #1 para o Sistema de Banco de Dados #2
Agora que a replicação está configurada entre Sistema de Banco de Dados #1 (origem) e Sistema de Banco de Dados #2 (destino), vamos testar se as alterações feitas no Sistema de Banco de Dados #1 são copiadas automaticamente para o Sistema de Banco de Dados #2.
-
Verificar dados iniciais
No Sistema de Banco de Dados #2, verifique a tabela
test_table
:postgres=> SELECT COUNT(*) FROM test_table; count ------- 1000 (1 row)
Isso confirma que a tabela já tem 1000 linhas.
-
Testar uma INSERT
Adicione uma nova linha no sistema de banco de dados nº 1:
postgres=> INSERT INTO test_table VALUES (10000, 'initial load');
-
Verifique-o no Sistema de Banco de Dados nº 1:
postgres=> SELECT * FROM test_table WHERE id = 10000; id | data -------+-------------- 10000 | initial load
-
Verifique o Sistema de Banco de Dados #2. A mesma linha aparece lá, mostrando que a replicação funciona:
postgres=> SELECT * FROM test_table WHERE id = 10000; id | data -------+-------------- 10000 | initial load
-
Testar uma instrução DELETE
Exclua a mesma linha no Sistema de Banco de Dados #1:
postgres=> DELETE FROM test_table WHERE id = 10000;
-
Verifique em ambos os sistemas – a linha se foi de ambos.
(0 rows)
-
Testar uma Atualização
Atualizar uma linha existente no Sistema de Banco de Dados #1:
postgres=> UPDATE test_table SET data = 'Initial load' WHERE id = 1;
Verifique o Sistema de Banco de Dados #1:
id | data -------+-------------- 1 | Initial load
Verifique o Sistema de Banco de Dados #2 — o valor atualizado também está lá.
Com esses testes, confirmamos que as operações INSERT
, UPDATE
e DELETE
são replicadas corretamente de Database System #1 → Database System #2.
Tarefa 4: Configurar replicação lógica bidirecional
As tarefas anteriores configuram a replicação unidirecional de Sistema de Banco de Dados Nº 1 para Sistema de Banco de Dados Nº 2. Em seguida, executaremos comandos adicionais para ativar a replicação na direção inversa também.
No Sistema de Banco de Dados 2:
Configure um conjunto de replicação da mesma forma que você fez no Sistema de Banco de Dados #1:
SELECT pglogical.replication_set_add_all_tables(
'default',
ARRAY['public']
);
No Sistema de Banco de Dados #1:
Crie uma assinatura no Sistema de Banco de Dados #1 para que ele comece a extrair as alterações do Sistema de Banco de Dados #2:
SELECT pglogical.create_subscription(
subscription_name := 'subscription2',
provider_dsn := 'host=primary.xxxxxxxx.postgresql.us-phoenix-1.oci.oraclecloud.com
port=5432
sslmode=require
dbname=postgres
user=psql
password=xxxxx',
replication_sets := ARRAY['default'],
synchronize_data := false,
forward_origins := '{}'
);
No comando anterior, o argumento synchronize_data
foi definido como false
, diferente de antes. Isso acontece porque não precisamos copiar dados existentes do Sistema de Banco de Dados #2 para o Sistema de Banco de Dados #1, pois ambas as tabelas já contêm dados idênticos.
Com este comando, a configuração de replicação bidirecional agora está concluída e todas as alterações feitas em um servidor serão replicadas para o outro. Em seguida, verifique o status da assinatura no Sistema de Banco de Dados nº 1.
Verifique o status de assinatura do Sistema de Banco de Dados nº 1:
Verifique o status da assinatura e as informações básicas no Database System #1 usando o seguinte comando:
select * from pglogical.show_subscription_status();
-[ RECORD 1 ]-----+----------------------------------------------------------------------------------------------------------------------------------------------------------------
subscription_name | subscription2
status | replicating
provider_node | subscriber1
provider_dsn | host=primary.xxxxxxxx.postgresql.us-phoenix-1.oci.oraclecloud.com port=5432 sslmode=require dbname=postgres user=psql password=xxxxx
slot_name | pgl_postgres_subscriber1_subscription2
replication_sets | {default}
forward_origins |
Tarefa 5: Testar replicação bidirecional
Vamos começar adicionando uma linha aos dois Sistemas de Banco de Dados para verificar se a replicação bidirecional está funcionando corretamente.
-
Insira uma linha no sistema de banco de dados nº 1:
Execute o seguinte comando no Sistema de Banco de Dados #1:
postgres=# INSERT INTO test_table VALUES (1001, 'Initial_load'); INSERT 0 1
-
Verifique a linha inserida no Sistema de banco de dados nº 1:
postgres=# SELECT * FROM test_table WHERE id = 1001; id | data ------+-------------- 1001 | Initial_load (1 row)
-
Verificar Replicação no Sistema de Banco de Dados #2:
Agora, verifique o Sistema de Banco de Dados #2 para confirmar se a linha foi replicada:
postgres=> SELECT * FROM test_table WHERE id = 1001; id | data ------+-------------- 1001 | Initial_load (1 row)
Isso mostra que a inserção no Sistema de Banco de Dados #1 foi replicada para o Sistema de Banco de Dados #2.
-
Insira uma linha no sistema de banco de dados nº 2:
Execute o seguinte comando no Sistema de Banco de Dados #2:
postgres=> INSERT INTO test_table VALUES (1002, 'Initial_load'); INSERT 0 1
-
Verifique a linha inserida no Sistema de banco de dados nº 2:
postgres=> SELECT * FROM test_table WHERE id = 1002; id | data ------+-------------- 1002 | Initial_load (1 row)
-
Verificar Replicação no Sistema de Banco de Dados #1:
Agora, verifique o Sistema de Banco de Dados #1 para confirmar se a linha foi replicada novamente:
postgres=# SELECT * FROM test_table WHERE id = 1002; id | data ------+-------------- 1002 | Initial_load (1 row)
Este teste confirma que as alterações de dados são replicadas com sucesso nas duas direções entre o Sistema de Banco de Dados Nº 1 e o Sistema de Banco de Dados Nº 2.
Monitorar lag de replicação lógica
Uma vez concluída a configuração pglógica, você deve monitorar o log de replicação para rastrear slots de replicação, atraso e outras métricas relevantes.
select * from pg_stat_replication;
Este comando retorna o status atual da replicação no OCI PostgreSQL.
Conclusão
Este tutorial orienta você na configuração da replicação bidirecional do PostgreSQL com pglogical. A replicação bidirecional adiciona complexidade à sua infraestrutura de banco de dados e requer esforço adicional, por isso é importante confirmar se ela se encaixa no seu caso de uso. Se o seu aplicativo exigir vários gravadores em diferentes regiões e o sharding de banco de dados não for viável, a replicação bidirecional será a solução ideal.
Confirmações
- Autor - Kaviya Selvaraj (Equipe Técnica de Membro Sênior)
Mais Recursos de Aprendizado
Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal do Oracle Learning YouTube. Além disso, acesse education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.
Para obter a documentação do produto, visite o Oracle Help Center.
Bi-directional replication in OCI Database for PostgreSQL using pglogical
G43215-01