

# Usar pgactive para comportar a replicação ativa-ativa
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive"></a>

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 17.0 e todas as versões posteriores
+ 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 obter mais informações, consulte . [Lidar com conflitos na replicação ativa-ativa](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)

**Topics**
+ [Limitações da extensão pgactive](#Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations)
+ [Inicializar o recurso de extensão pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md)
+ [Configurar a replicação ativa-ativa para as instâncias de banco de dados do RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication.md)
+ [Medir o atraso de replicação entre membros pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag.md)
+ [Configurar as definições de parâmetro para a extensão pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.md)
+ [Noções básicas sobre conflitos ativos-ativos](Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication.md)
+ [Noções básicas sobre o esquema da pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.md)
+ [Referência de funções da pgactive](pgactive-functions-reference.md)
+ [Lidar com conflitos na replicação ativa-ativa](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts.md)
+ [Lidar com sequências na replicação ativa-ativa](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md)

## Limitações da extensão pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.requirements-limitations"></a>
+ 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 obter mais informações, consulte [Lidar com sequências na replicação ativa-ativa](Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences.md).
+ 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.

# Inicializar o recurso de extensão pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup"></a>

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 Console de gerenciamento da AWS 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](USER_WorkingWithParamGroups.md).

## Console
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CON"></a>

**Como inicializar o recurso de extensão pgactive**

1. Faça login no Console de gerenciamento da AWS e abra o console do Amazon RDS em [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. No painel de navegação, escolha a instância de banco de dados do RDS para PostgreSQL.

1. 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**. 

1. Clique no link para abrir os parâmetros personalizados associados à instância de banco de dados do RDS para PostgreSQL. 

1. Encontre o parâmetro `rds.enable_pgactive` e configure-o como `1` para inicializar o recurso `pgactive`.

1. Escolha **Salvar alterações**.

1. No painel de navegação do console do Amazon RDS, escolha **Bancos de dados**.

1. Selecione a instância de banco de dados do RDS para PostgreSQL e escolha **Reinicializar** no menu **Ações**.

1. Confirme a reinicialização da instância de banco de dados para que as alterações tenham efeito. 

1. 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=postgres --password=PASSWORD --dbname=postgres
   ```

1. 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 em `shared_preload_libraries`, o comando anterior retornará o seguinte:

   ```
   ?column? 
   ----------
    t
   ```

## AWS CLI
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.CLI"></a>

**Como inicializar o recurso de extensão pgactive**

Para inicializar `pgactive` usando a AWS CLI, execute a operação [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) para modificar determinados parâmetros no grupo parâmetros personalizado, conforme mostrado no procedimento a seguir.

1. Use o comando AWS CLI a seguir para definir `rds.enable_pgactive` como `1` para inicializar o recurso `pgactive` da instância de banco de dados do RDS para PostgreSQL.

   ```
   postgres=>aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. 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 \
       --region aws-region
   ```

1. 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=PASSWORD --dbname=postgres
   ```

1. 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 em `shared_preload_libraries`, o comando anterior retornará o seguinte:

   ```
   ?column? 
   ----------
    t
   ```

# Configurar a replicação ativa-ativa para as instâncias de banco de dados do RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.setup-replication"></a>

O procedimento a seguir mostra como iniciar a replicação ativa-ativa entre dois clusters de banco de dados do duas instâncias de banco de dados do RDS para PostgreSQL em que `pgactive` está disponível. 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](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html).

**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 habilitada com a extensão `pgactive`. Para obter mais informações, consulte [Inicializar o recurso de extensão pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md). 

**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.

1. 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=postgres --password=PASSWORD --dbname=postgres
   ```

1. Crie um banco de dados na instância do RDS para PostgreSQL usando o seguinte comando:

   ```
   postgres=> CREATE DATABASE app;
   ```

1. Alterne a conexão para o novo banco de dados usando o seguinte comando:

   ```
   \c app
   ```

1. Crie e preencha uma tabela de exemplo usando a seguinte instrução SQL:

   1. 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);
      ```

   1. 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');
      ```

   1. Verifique se os dados existem na tabela usando a declaração SQL a seguir.

      ```
       app=>SELECT count(*) FROM inventory.products;
      
       count
      -------
       3
      ```

1. Crie uma extensão `pgactive` no banco de dados existente.

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. Para criar e inicializar com segurança o grupo da pgactive, use os seguintes comandos:

   ```
   app=>
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
         -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   Agora você pode inicializar o grupo de replicações e adicionar esta primeira instância:

   ```
   SELECT pgactive.pgactive_create_group(
       node_name := 'endpoint1-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   
   );
   ```

   Use os seguintes comandos como um método alternativo, mas menos seguro, para criar e inicializar o grupo da pgactive:

   ```
   app=> SELECT pgactive.pgactive_create_group(
       node_name := 'node1-app',
       node_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres 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 como `1`.

1. 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 obter mais informações, consulte [Inicializar o recurso de extensão pgactive](Appendix.PostgreSQL.CommonDBATasks.pgactive.basic-setup.md). 

1. 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=postgres --password=PASSWORD --dbname=postgres
   ```

1. Crie um banco de dados na segunda instância de banco de dados do RDS para PostgreSQL usando o seguinte comando:

   ```
   postgres=> CREATE DATABASE app;
   ```

1. Alterne a conexão para o novo banco de dados usando o seguinte comando:

   ```
   \c app
   ```

1. Crie a extensão `pgactive` no banco de dados existente.

   ```
   app=> CREATE EXTENSION pgactive;
   ```

1. Junte a segunda instância de banco de dados do RDS para PostgreSQL ao grupo do `pgactive` de uma forma mais segura usando os seguintes comandos:

   ```
   -- connection info for endpoint1
   CREATE SERVER pgactive_server_endpoint1
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint1>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint1
       OPTIONS (user 'postgres', password '<password>');
   
   -- connection info for endpoint2
   CREATE SERVER pgactive_server_endpoint2
       FOREIGN DATA WRAPPER pgactive_fdw
       OPTIONS (host '<endpoint2>', dbname 'app');
   CREATE USER MAPPING FOR postgres
       SERVER pgactive_server_endpoint2
       OPTIONS (user 'postgres', password '<password>');
   ```

   ```
   SELECT pgactive.pgactive_join_group(
       node_name := 'endpoint2-app',
       node_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint2',
       join_using_dsn := 'user_mapping=postgres pgactive_foreign_server=pgactive_server_endpoint1'
   );
   ```

   Use os comandos a seguir como um método alternativo, mas menos seguro, para juntar a segunda instância de banco de dados do RDS for PostgreSQL ao grupo da `pgactive`:

   ```
   app=> SELECT pgactive.pgactive_join_group(
   node_name := 'node2-app',
   node_dsn := 'dbname=app host=secondinstance.111122223333.aws-region.rds.amazonaws.com user=postgres 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`.

1. 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.

1. 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
   ```

1. Execute o seguinte comando para inserir novos valores:

   ```
   app=> INSERT INTO inventory.products (id, product_name) VALUES (4, 'lotion');
   ```

1. 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:

1. 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']);
   ```

1. 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);
   ```

1. Descarte a extensão usando o seguinte comando:

   ```
   app=> DROP EXTENSION pgactive;
   ```

# Medir o atraso de replicação entre membros pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replicationlag"></a>

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.

```
    
app=> SELECT * FROM pgactive.pgactive_get_replication_lag_info();
│-[ RECORD 1 ]--------+---------------------------------------------
│node_name            | node2-app
│node_sysid           | 7481018224801653637
│application_name     | pgactive:7481018224801653637:send
│slot_name            | pgactive_16385_7481018224801653637_0_16385__
│active               | t
│active_pid           | 783486
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/2108150
│confirmed_flush_lsn  | 0/2154690
│sent_lsn             | 0/2154690
│write_lsn            | 0/2154690
│flush_lsn            | 0/2154690
│replay_lsn           | 0/2154690
│-[ RECORD 2 ]--------+---------------------------------------------
│node_name            | node1-app
│node_sysid           | 7481018033434600853
│application_name     | pgactive:7481018033434600853:send
│slot_name            | pgactive_16385_7481018033434600853_0_16385__
│active               | t
│active_pid           | 783488
│pending_wal_decoding | 0
│pending_wal_to_apply | 0
│restart_lsn          | 0/20F5AD0
│confirmed_flush_lsn  | 0/214EF68
│sent_lsn             | 0/214EF68
│write_lsn            | 0/214EF68
│flush_lsn            | 0/214EF68
│replay_lsn           | 0/214EF68
```

Monitore, no mínimo, os seguintes diagnósticos:

active  
Configure alertas quando active for false, o que indica que o slot não está em uso no momento (a instância do assinante foi desconectada do publicador).

pending\$1wal\$1decoding  
Na replicação lógica do PostgreSQL, os arquivos WAL são armazenados em formato binário. O publicador deve decodificar essas alterações do WAL e convertê-las em alterações lógicas (como operações de inserção, atualização ou exclusão).  
A métrica pending\$1wal\$1decoding mostra o número de arquivos WAL aguardando decodificação do lado do publicador.  
Esse número pode aumentar devido a estes fatores:  
+ Quando o assinante não estiver conectado, o status active será false e pending\$1wal\$1decoding aumentará.
+ O slot está ativo, mas o publicador não consegue acompanhar o volume de alterações do WAL.

pending\$1wal\$1to\$1apply  
A métrica pending\$1wal\$1apply indica o número de arquivos WAL que ainda precisam ser aplicados do lado do assinante.  
Vários fatores podem impedir que o assinante aplique alterações e possivelmente provocar um cenário de disco cheio:  
+ Diferenças de esquema: por exemplo, quando você tem alterações no fluxo do WAL para uma tabela chamada sample e essa tabela não existe do lado do assinante.
+ Valores nas colunas da chave primária foram atualizados.
+ Índices secundários exclusivos podem causar divergência de dados.

# Configurar as definições de parâmetro para a extensão pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters"></a>

É possível usar a consulta a seguir para visualizar todos os parâmetros associados à extensão `pgactive`.

```
app=> SELECT * FROM pg_settings WHERE name LIKE 'pgactive.%';
```

Você pode configurar a extensão `pgactive` usando vários parâmetros. Esses parâmetros podem ser definidos por meio do Console de gerenciamento da AWS ou da interface da CLI AWS.

## Principais parâmetros da extensão pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.mainparams"></a>

A seguinte tabela apresenta uma referência para os principais parâmetros da extensão `pgactive`:


| Parâmetro | Unidade | Padrão | Descrição | 
| --- | --- | --- | --- | 
| pgactive.conflict\$1logging\$1include\$1tuples | `boolean` | –  | Registra em log informações completas da tupla para a extensão `pgactive`.  É necessário reinicializar o servidor para que as alterações entrem em vigor.  | 
| pgactive.log\$1conflicts\$1to\$1table | `boolean` | –  | Determina se a extensão `pgactive` registra em log os conflitos detectados na tabela `pgactive.pgactive_conflict_history`. Para ter mais informações e detalhes, consulte “Registro em log de conflitos”.  É necessário reinicializar o servidor para que as alterações entrem em vigor.  | 
| pgactive.log\$1conflicts\$1to\$1logfile | `boolean` | –  | Determina se a extensão `pgactive` registra em log os conflitos detectados no arquivo de log do PostgreSQL. Para ter mais informações e detalhes, consulte “Registro em log de conflitos”.  É necessário reinicializar o servidor para que as alterações entrem em vigor.  | 
| pgactive.synchronous\$1commit | `boolean` | desligar | Determina o comportamento de confirmação dos operadores apply da pgactive. Quando desabilitados (off), os operadores apply executam confirmações assíncronas, o que melhora o throughput do PostgreSQL durante as operações apply, mas atrasa as confirmações de reprodução para o precedente. Configurá-los como `off` é sempre seguro e não causará perda ou omissão de transações. Essa configuração afeta apenas o tempo de liberação do disco no nó subsequente e quando as confirmações são enviadas ao precedente. O sistema atrasa o envio das confirmações de liberação de reprodução até que as confirmações sejam liberadas para o disco por meio de operações não relacionadas, como pontos de verificação ou trabalho periódico. No entanto, se o precedente tiver o subsequente listado em `synchronous_standby_names`, configurá-lo como `off` fará com que as confirmações síncronas no precedente demorem mais para relatar êxito ao cliente. Nesse caso, configure o parâmetro como `on`.  Mesmo quando esse parâmetro é definido como `on` com os nós listados em `synchronous_standby_names`, conflitos de replicação ainda podem ocorrer em configurações ativas-ativas. Isso ocorre porque o sistema não tem bloqueio entre nós e gerenciamento global de snapshots, permitindo que transações simultâneas em nós diferentes modifiquem a mesma tupla. Além disso, as transações só iniciam a replicação depois de serem confirmadas no nó precedente. Habilitar a confirmação síncrona não transforma a extensão pgactive em um sistema sempre consistente.  | 
| pgactive.temp\$1dump\$1directory | `string` | – | Define o caminho de armazenamento temporário necessário para as operações de clonagem do banco de dados durante a configuração inicial. Esse diretório deve ser gravável pelo usuário do Postgres e ter espaço de armazenamento suficiente para conter um despejo completo do banco de dados. O sistema usa esse local somente durante a configuração inicial do banco de dados com operações de cópia lógica. Esse parâmetro não é usado pelo `pgactive_init_copy command`. | 
| pgactive.max\$1ddl\$1lock\$1delay | `milliseconds` | `-1` | Especifica o tempo máximo de espera para o bloqueio de DDL antes de interromper à força as transações de gravação simultâneas. O valor padrão é `-1`, que adota o valor definido em `max_standby_streaming_delay`. Esse parâmetro aceita unidades de tempo. Por exemplo, você pode configurá-lo como 10s (10 segundos). Durante esse período de espera, o sistema tenta adquirir bloqueios de DDL enquanto aguarda a confirmação ou reversão das transações de gravação em andamento. Para ter mais informações, consulte “DDL Locking”. | 
| pgactive.ddl\$1lock\$1timeout | `milliseconds` | `-1` | Especifica por quanto tempo uma tentativa de bloqueio de DDL espera para obter o bloqueio. O valor padrão é `-1`, que usa o valor especificado em lock\$1timeout. Você pode definir esse parâmetro usando unidades de tempo, como 10s (10 segundos). Esse temporizador controla apenas o período de espera para obter um bloqueio de DDL. Quando o sistema obtém o bloqueio e inicia a operação de DDL, o temporizador para. Esse parâmetro não limita a duração total em que um bloqueio de DDL pode ser mantido ou o tempo geral de operação de DDL. Para controlar a duração total da operação, use `statement_timeout` em vez disso. Para ter mais informações, consulte “DDL Locking”. | 
| pgactive.debug\$1trace\$1ddl\$1locks\$1level | `boolean` | –  | Substitui o nível de log de depuração padrão para operações de bloqueio de DDL na extensão `pgactive`. Quando configurada, essa definição faz com que mensagens relacionadas ao bloqueio de DDL sejam emitidas no nível de depuração de LOG em vez de no nível padrão. Use esse parâmetro para monitorar a atividade de bloqueio de DDL sem habilitar os níveis detalhados de log `DEBUG1` ou `DEBUG2` em todo o servidor.  Níveis de log, em ordem crescente de detalhamento: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Para ter mais informações sobre as opções de monitoramento, consulte “Monitoring global DDL locks”.  As alterações nessa configuração entram em vigor quando você a recarrega. Não é necessário reiniciar o servidor.   | 

## Parâmetros adicionais da extensão pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.addparams"></a>

A tabela a seguir apresenta as opções de configuração internas e menos frequentemente usadas disponíveis para a extensão `pgactive`.


| Parâmetro | Unidade | Padrão | Descrição | 
| --- | --- | --- | --- | 
| pgactive.debug\$1apply\$1delay | `integer` | – |  Define um atraso de apply (em milissegundos) para conexões configuradas que não têm um atraso de apply explícito na respectiva entrada `pgactive.pgactive_connections`. Esse atraso é definido durante a criação do nó ou o tempo de junção, e a pgactive não reproduzirá uma transação em nós pares enquanto pelo menos o número especificado de milissegundos não tiver decorrido desde que ela foi confirmada. Usado principalmente para simular redes de alta latência em ambientes de teste para facilitar a criação de conflitos. Por exemplo, com um atraso de 500 ms nos nós A e B, você terá pelo menos 500 ms para realizar uma inserção conflitante no nó B depois de inserir um valor no nó A.  Requer o recarregamento do servidor ou a reinicialização dos operadores apply para entrar em vigor.  | 
| pgactive.connectability\$1check\$1duration | `integer` | –  | Especifica a duração (em segundos) em que um operador de banco de dados tenta estabelecer conexões durante tentativas malsucedidas. O operador faz 1 tentativa de conexão por segundo até ter êxito ou atingir esse valor de tempo limite. Essa configuração é útil quando o mecanismo de banco de dados é iniciado antes de o operador estar pronto para estabelecer conexões. | 
| pgactive.skip\$1ddl\$1replication | `boolean` | `on` | Controla como as alterações de DDL são replicadas ou tratadas no Amazon RDS com `pgactive` habilitada. Quando definido como `on`, o nó processa as alterações de DDL como um nó não pgactive. Os seguintes requisitos se aplicam ao trabalhar com esse parâmetro: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Você pode modificar esse parâmetro de duas maneiras com privilégios de superusuário: globalmente e localmente (nível de sessão).  A alteração incorreta desse parâmetro pode desfazer suas configurações de replicação.  | 
| pgactive.do\$1not\$1replicate | `boolean` | – | Esse parâmetro é somente para uso interno. Ao definir esse parâmetro em uma transação, as alterações não são replicadas para outros nós no cluster de banco de dados.   A alteração incorreta desse parâmetro pode desfazer suas configurações de replicação.  | 
| pgactive.discard\$1mismatched\$1row\$1attributes | `boolean` | –  | Esse parâmetro destina-se somente a especialistas. Recomendamos usá-lo somente ao solucionar problemas específicos de replicação. Use esse parâmetro quando: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Essa configuração substitui a seguinte mensagem de erro e permite que surjam divergências de dados para que a replicação continue: .: `cannot right-pad mismatched attributes; attno %u is missing in local table and remote row has non-null, non-dropped value for this attribute`  A alteração incorreta desse parâmetro pode desfazer suas configurações de replicação.   | 
| pgactive.debug\$1trace\$1replay | `boolean` | – | Quando definido como `on`, ele emite uma mensagem de log para cada ação remota que os operadores apply subsequentes processam. Os logs incluem: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Os logs também capturam comandos de DDL enfileirados e exclusões de tabela.para> Por padrão, os logs não incluem o conteúdo de campos de linha. Para incluir valores de linha nos logs, você deve recompilar com os seguintes sinalizadores habilitados: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html)  A habilitação dessa configuração de registro em log pode afetar o desempenho. Recomendamos habilitá-la somente quando necessário para solucionar problemas. As alterações nessa configuração entram em vigor quando você a recarrega. Não é necessário reiniciar o servidor.   | 
| pgactive.extra\$1apply\$1connection\$1options |  | – | Você pode configurar os parâmetros de conexão para todas as conexões de nós pares com nós da pgactive. Esses parâmetros controlam configurações, como keepalives e modos SSL. Por padrão, a pgactive usa os seguintes parâmetros de conexão: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Para substituir os parâmetros padrão, use o comando semelhante abaixo: pgactive.extra\$1apply\$1connection\$1options = 'keepalives=0' As strings de conexão de nós individuais têm precedência sobre essas configurações e sobre as opções de conexão integradas da pgactive. Para ter mais informações sobre formatos de string de conexão, consulte as [strings de conexão libpq](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING). Recomendamos manter as configurações padrão de keepalive habilitadas. Só desabilite os keepalives se você tiver problemas para concluir grandes transações em redes não confiáveis.   Recomendamos manter as configurações padrão de keepalive habilitadas. Só desabilite os keepalives se você tiver problemas para concluir grandes transações em redes não confiáveis. As alterações nessa configuração entram em vigor quando você a recarrega. Não é necessário reiniciar o servidor.  | 
| pgactive.init\$1node\$1parallel\$1jobs (int) |  | – | Especifica o número de trabalhos paralelos que `pg_dump` e `pg_restore` podem usar durante junções de nós lógicos com a função `pgactive.pgactive_join_group`. As alterações nessa configuração entram em vigor quando você a recarrega. Não é necessário reiniciar o servidor. | 
| pgactive.max\$1nodes | `int` | 4 |  Especifica o número máximo de nós permitidos em um grupo da extensão pgactive. O valor padrão é quatro nós. Você deve considerar o seguinte ao definir o valor desse parâmetro: [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.pgactive.parameters.html) Você pode definir esse parâmetro de duas maneiras: no arquivo de configuração e usando o comando `ALTER SYSTEM SET`. O valor padrão para esse parâmetro é `4`; ou seja, pode haver no máximo quatro nós permitidos no grupo da extensão `pgactive` em qualquer momento específico.  A alteração entra em vigor após a reinicialização do servidor.  | 
| pgactive.permit\$1node\$1identifier\$1getter\$1function\$1creation | `boolean` | – | Esse parâmetro destina-se somente para uso interno. Quando habilitada, a extensão `pgactive` permite a criação da função getter do identificador de nó da pgactive. | 

# Noções básicas sobre conflitos ativos-ativos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.replication"></a>

Quando você usa pgactive no modo ativo-ativo, gravar nas mesmas tabelas por meio de vários nós pode criar conflitos de dados. Embora alguns sistemas de clustering usem bloqueios distribuídos para impedir o acesso simultâneo, a pgactive adota uma abordagem otimista que é mais adequada para aplicações distribuídas geograficamente.

Alguns sistemas de clustering de banco de dados impedem o acesso simultâneo aos dados por meio de bloqueios distribuídos. Embora essa abordagem funcione quando os servidores estão próximos, não é possível usá-la para aplicações distribuídas geograficamente porque, para oferecer um bom desempenho, é necessária uma latência extremamente baixa. Em vez de usar bloqueios distribuídos (uma abordagem pessimista), a extensão pgactive usa uma abordagem otimista. Isso significa que ela:
+ Ajuda a evitar conflitos quando possível.
+ Possibilita que determinados tipos de conflito ocorram.
+ Oferece resolução quando ocorrem conflitos.

Essa abordagem oferece maior flexibilidade ao criar aplicações distribuídas.

## Como os conflitos acontecem
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.howconflicts"></a>

Os conflitos entre nós surgem de sequências de eventos que não poderiam acontecer se todas as transações envolvidas ocorressem simultaneamente no mesmo nó. Como os nós só trocam alterações após a confirmação das transações, cada transação é válida individualmente no nó em que foi confirmada, mas não seria válida se executada em outro nó que tivesse feito outro trabalho nesse meio tempo. Como o apply da pgactive basicamente reproduz a transação nos outros nós, a operação de repetição pode falhar se houver um conflito entre uma transação que está sendo aplicada e uma transação que foi confirmada no nó receptor.

 O motivo pelo qual a maioria dos conflitos não pode acontecer quando todas as transações são executadas em um único nó é que o PostgreSQL tem mecanismos de comunicação entre transações para evitá-los, como:
+ Índices UNIQUE
+ SEQUENCEs
+ Bloqueio de linha e relação
+ Rastreamento de dependências SERIALIZÁVEL

Todos esses mecanismos são formas de comunicação entre transações para evitar problemas indesejáveis de simultaneidade.

A pgactive alcança baixa latência e lida bem com partições de rede porque não usa um gerenciador de transações distribuídas ou gerenciador de bloqueios. Mas isso significa que as transações em nós diferentes são executadas de maneira totalmente isolada umas das outras. Embora o isolamento normalmente melhore a consistência do banco de dados, nesse caso, você precisa reduzir o isolamento para evitar conflitos.

## Tipos de conflito
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes"></a>

Os conflitos que podem ocorrer incluem:

**Topics**
+ [Conflitos de PRIMARY KEY ou UNIQUE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1)
+ [Conflitos INSERT/INSERT](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2)
+ [INSERTs que violam várias restrições UNIQUE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3)
+ [Conflitos UPDATE/UPDATE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4)
+ [Conflitos UPDATE na CHAVE PRIMÁRIA](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5)
+ [UPDATEs que violam várias restrições UNIQUE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6)
+ [Conflitos UPDATE/DELETE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7)
+ [Conflitos INSERT/UPDATE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8)
+ [Conflitos DELETE/DELETE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9)
+ [Conflitos de restrição de chave estrangeira](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10)
+ [Conflitos de restrição de exclusão](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11)
+ [Conflitos de dados globais](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12)
+ [Conflitos de bloqueio e interrupções decorrentes de deadlock](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13)
+ [Conflitos divergentes](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14)

### Conflitos de PRIMARY KEY ou UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict1"></a>

Os conflitos de linha ocorrem quando várias operações tentam modificar a mesma chave de linha de uma maneira não possíveis em um único nó. Esses conflitos representam o tipo mais comum de conflito de dados.

A pgactive resolve conflitos detectados por meio da abordagem de última atualização prevalece ou de seu manipulador de conflitos personalizado.

Os conflitos de linha incluem:
+ INSERT versus INSERT
+ INSERT versus UPDATE
+ UPDATE versus DELETE
+ INSERT versus DELETE
+ DELETE versus DELETE
+ INSERT versus DELETE

### Conflitos INSERT/INSERT
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict2"></a>

Esse conflito mais comum ocorre quando INSERTs em dois nós diferentes criam uma tupla com os mesmos valores de PRIMARY KEY (ou valores de restrição UNIQUE idênticos quando não existe PRIMARY KEY).

O pgactivelink resolve conflitos de INSERT usando o carimbo de data/hora do host de origem para manter a tupla mais recente. Você pode substituir esse comportamento padrão com seu manipulador de conflitos personalizado. Embora esse processo não exija nenhuma ação especial do administrador, esteja ciente de que o pgactivelink descarta uma das operações INSERT em todos os nós. Nenhuma mesclagem automática de dados ocorre, a menos que seu manipulador personalizado a implemente.

O pgactivelink só pode resolver conflitos envolvendo uma única violação de restrição. Se um INSERT violar várias restrições UNIQUE, você deverá implementar estratégias adicionais de resolução de conflitos.

### INSERTs que violam várias restrições UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict3"></a>

Um conflito INSERT/INSERT pode violar várias restrições UNIQUE, incluindo a PRIMARY KEY. O pgactivelink só pode lidar com conflitos que envolvam uma única restrição UNIQUE. Quando os conflitos violarem várias restrições UNIQUE, o operador apply falhará e retornará o seguinte erro:

`multiple unique constraints violated by remotely INSERTed tuple.`

Em versões mais antigas, essa situação gerava um erro de “conflito de exclusividade divergente”. 

Para resolver esses conflitos, você deve executar uma ação manual. Use DELETE para excluir as tuplas locais conflitantes ou UPDATE para atualizá-las e remover os conflitos com a nova tupla remota. Esteja ciente de que talvez você precise resolver várias tuplas conflitantes. No momento, o pgactivelink não oferece nenhuma funcionalidade integrada para ignorar, descartar ou mesclar tuplas que violem várias restrições únicas.

**nota**  
Para ter mais informações, consulte UPDATEs que violam várias restrições UNIQUE.

### Conflitos UPDATE/UPDATE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict4"></a>

Esse conflito ocorre quando dois nós modificam simultaneamente a mesma tupla sem alterar a PRIMARY KEY. O pgactivelink resolve esses conflitos usando a lógica de última atualização prevalece ou seu manipulador de conflitos personalizado, se definido. Uma CHAVE PRIMÁRIA é essencial para correspondência de tuplas e resolução de conflitos. Para tabelas sem CHAVE PRIMÁRIA, o pgactivelink rejeita as operações UPDATE com o seguinte erro:

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

### Conflitos UPDATE na CHAVE PRIMÁRIA
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5"></a>

A pgactive tem limitações para lidar com atualizações de CHAVE PRIMÁRIA. Embora você possa realizar a operação UPDATE em uma CHAVE PRIMÁRIA, a pgactive não consegue resolver conflitos automaticamente usando a lógica de última atualização prevalece para essas operações. Você deve garantir que as atualizações da CHAVE PRIMÁRIA não entrem em conflito com os valores existentes. Se ocorrerem conflitos durante as atualizações da CHAVE PRIMÁRIA, eles se tornarão conflitos divergentes e exigirão intervenção manual. Para ter mais informações sobre como lidar com essas situações, consulte [Conflitos divergentes](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14).

### UPDATEs que violam várias restrições UNIQUE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict6"></a>

O pgactivelink não consegue aplicar a resolução de conflitos de última atualização prevalece quando um UPDATE recebido viola várias restrições UNIQUE ou valores de CHAVE PRIMÁRIA. Esse comportamento é semelhante às operações INSERT com várias violações de restrição. Essas situações criam conflitos divergentes que exigem intervenção manual. Para obter mais informações, consulte [Conflitos divergentes](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14).

### Conflitos UPDATE/DELETE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7"></a>

Esses conflitos ocorrem quando um nó executa UPDATE em uma linha e outro nó executa simultaneamente DELETE nessa linha. Nesse caso, ocorre um conflito UPDATE/DELETE na reprodução. A solução é descartar qualquer UPDATE que chegue após um DELETE, a menos que seu manipulador de conflitos personalizado especifique o contrário.

O pgactivelink requer uma CHAVE PRIMÁRIA para combinar tuplas e resolver conflitos. Para tabelas sem CHAVE PRIMÁRIA, ele rejeita operações DELETE com o seguinte erro:

`Cannot run UPDATE or DELETE on table (tablename) because it does not have a primary key.`

**nota**  
O pgactivelink não consegue distinguir entre os conflitos UPDATE/DELETE e INSERT/UPDATE. Em ambos os casos, um UPDATE afeta uma linha inexistente. Devido à replicação assíncrona e à falta de ordem de reprodução entre os nós, o pgactivelink não consegue determinar se o UPDATE é para uma nova linha (INSERT ainda não recebido) ou uma linha excluída. Em ambos os cenários, o pgactivelink descarta o UPDATE.

### Conflitos INSERT/UPDATE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict8"></a>

Esse conflito pode ocorrer em ambientes com vários nós. Isso acontece quando um nó insere uma linha, um segundo nó a atualiza e um terceiro nó recebe o UPDATE antes do INSERT original. Por padrão, o pgactivelink resolve esses conflitos descartando o UPDATE, a menos que seu acionador de conflito personalizado especifique o contrário. Esteja ciente de que esse método de resolução pode provocar inconsistências de dados entre os nós. Para ter mais informações sobre cenários semelhantes e o respectivo tratamento, consulte [Conflitos UPDATE/DELETE](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict7).

### Conflitos DELETE/DELETE
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict9"></a>

Esse conflito ocorre quando dois nós diferentes excluem simultaneamente a mesma tupla. O pgactivelink considera esses conflitos não prejudiciais porque as duas operações DELETE têm o mesmo resultado final. Nesse cenário, o pgactivelink ignora com segurança uma das operações DELETE sem afetar a consistência de dados. 

### Conflitos de restrição de chave estrangeira
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict10"></a>

As restrições de CHAVE ESTRANGEIRA podem causar conflitos ao aplicar transações remotas aos dados locais existentes. Esses conflitos geralmente ocorrem quando as transações são aplicadas em uma sequência diferente da ordem lógica nos nós de origem.

Por padrão, a pgactive aplica alterações com session\$1replication\$1role como `replica`, o que ignora as verificações de chave estrangeira durante a replicação. Em configurações ativas-ativas, isso pode provocar violações de chave estrangeira. A maioria das violações é temporária e resolvida quando a replicação é concluída. Mas pode haver chaves estrangeiras pendentes porque a pgactive não permite o bloqueio de linhas entre nós.

Esse comportamento é inerente aos sistemas ativos-ativos assíncronos com tolerância à partição. Por exemplo, o nó A pode inserir uma nova linha secundária enquanto o nó B exclui simultaneamente a linha principal. O sistema não consegue impedir esse tipo de modificação simultânea entre os nós.

Para minimizar conflitos de chave estrangeira, recomendamos o seguinte:
+ Limite as relações de chave estrangeira a entidades estreitamente relacionadas.
+ Modifique as entidades relacionadas por meio de um único nó quando possível.
+ Escolha entidades que raramente exijam modificação.
+ Implemente o controle de simultaneidade em nível de aplicação para modificações.

### Conflitos de restrição de exclusão
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict11"></a>

 O pgactivelink não permite restrições de exclusão e limita a criação de restrições.

**nota**  
Se você converter um banco de dados independente existente em um banco de dados pgactivelink, remova manualmente todas as restrições de exclusão.

Em um sistema assíncrono distribuído, não é possível garantir que nenhum conjunto de linhas viole a restrição. Isso ocorre porque todas as transações em nós diferentes são totalmente isoladas. As restrições de exclusão podem gerar deadlocks de reprodução, impedindo que a reprodução progrida de um nó para outro devido a violações da restrição de exclusão.

Se você forçar o pgactivelink a criar uma restrição de exclusão ou se não remover as existentes ao converter um banco de dados independente em pgactivelink, é provável que a replicação seja interrompida. Para restaurar o progresso da replicação, remova ou altere as tuplas locais que estão em conflito com uma tupla remota de entrada para que a transação remota possa ser aplicada.

### Conflitos de dados globais
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict12"></a>

Ao usar o pgactivelink, conflitos podem ocorrer quando os nós têm diferentes dados globais do sistema geral do PostgreSQL, como funções. Esses conflitos podem fazer com que as operações, principalmente de DDL, sejam bem-sucedidas e confirmadas em um nó, mas falhem ao serem aplicadas a outros nós.

Se um usuário existir em um nó e não em outro, podem ocorrer problemas de replicação:
+ O Node1 tem um usuário chamado `fred`, mas esse usuário não existe no Node2.
+ Quando `fred` cria uma tabela no Node1, a tabela é replicada com `fred` como proprietário.
+ Quando esse comando de DDL é aplicado ao Node2, ele falha porque o usuário `fred` não existe.
+ Essa falha gera um ERRO nos logs do PostgreSQL no Node2 e incrementa o contador `pgactive.pgactive_stats.nr_rollbacks`.

**Resolução:** crie o usuário `fred` no Node2. O usuário não precisa de permissões idênticas, mas deve existir em ambos os nós.

Se uma tabela existir em um nó e não em outro, as operações de modificação de dados vão falhar:
+ O Node1 tem uma tabela chamada `foo` que não existe no Node2.
+ Qualquer operação de DML na tabela `foo` no Node1 falhará quando replicada para o Node2.

**Resolução:** crie a tabela `foo` no Node2 com a mesma estrutura.

**nota**  
No momento, o pgactivelink não replica comandos CREATE USER ou operações de DDL. A replicação de DDL está programada para uma versão futura.

### Conflitos de bloqueio e interrupções decorrentes de deadlock
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict13"></a>

Como os processos apply da pgactive operam como sessões normais de usuário, eles seguem as regras padrão de bloqueio de linhas e tabelas. Isso pode fazer com que os processos apply do pgactivelink aguardem bloqueios mantidos por transações de usuário ou por outros processos apply.

Os seguintes tipos de bloqueio podem afetar os processos apply:
+ Bloqueio explícito em nível de tabela (LOCK TABLE…) por sessão de usuário
+ Bloqueio explícito em nível de linha (SELECT… FOR UPDATE/FOR SHARE) por sessão de usuário
+ Bloqueio de chaves estrangeiras
+ Bloqueio implícito devido operações de UPDATE, INSERT ou DELETE de linhas, seja da atividade local ou do operador apply de outros servidores

Deadlocks podem ocorrer entre:
+ Um processo apply do pgactivelink e uma transação do usuário
+ Dois processos apply

Quando ocorrem deadlocks, o detector de deadlock do PostgreSQL encerra uma das transações problemáticas. Se o processo do operador apply do pgactivelink for encerrado, ele fará uma nova tentativa automaticamente e em geral terá êxito.

**nota**  
Esses problemas são temporários e normalmente não exigem intervenção do administrador. Se um processo apply for bloqueado por um longo período devido ao bloqueio de uma sessão de usuário ociosa, você poderá encerrar a sessão do usuário para retomar a replicação. Essa situação é semelhante a quando um usuário mantém um bloqueio longo que afeta a sessão de outro usuário.
Para identificar atrasos na reprodução relacionados ao bloqueio, habilite o recurso `log_lock_waits` no PostgreSQL.

### Conflitos divergentes
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict14"></a>

Conflitos divergentes ocorrem quando dados que deveriam ser idênticos entre os nós diferem inesperadamente. Embora esses conflitos não devam acontecer, nem todos podem ser evitados de forma confiável na implementação atual.

**nota**  
 A modificação da CHAVE PRIMÁRIA de uma linha poderá causar conflitos divergentes se outro nó alterar a chave da mesma linha antes de todos os nós processarem a alteração. Evite alterar as chaves primárias ou restrinja as alterações a um nó designado. Para obter mais informações, consulte [Conflitos UPDATE na CHAVE PRIMÁRIA](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflict5).

Conflitos divergentes envolvendo dados de linha geralmente exigem intervenção do administrador. Para resolver esses conflitos, você deve ajustar manualmente os dados em um nó para corresponder a outro e, ao mesmo tempo, desabilitar temporariamente a replicação usando `pgactive.pgactive_do_not_replicate`. Esses conflitos não devem ocorrer quando você usa a pgactive conforme documentado e evita configurações ou funções marcadas como inseguras.

 Como administrador, você deve resolver esses conflitos manualmente. Dependendo do tipo de conflito, você precisará usar opções avançadas, como `pgactive.pgactive_do_not_replicate`. Use essas opções com cuidado, pois o uso indevido pode piorar a situação. Devido à variedade de possíveis conflitos, não podemos fornecer instruções gerais de resolução.

Conflitos divergentes ocorrem quando dados que deveriam ser idênticos entre diferentes nós diferem inesperadamente. Embora esses conflitos não devam acontecer, nem todos podem ser evitados de forma confiável na implementação atual.

## Evitar ou permitir conflitos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.avoidconflicts"></a>

 Na maioria dos casos, você pode usar o design de aplicação adequado para evitar conflitos ou tornar a aplicação tolerante a conflitos.

 Os conflitos só ocorrem quando acontecem operações simultâneas em vários nós. Como evitar conflitos:
+ Grave em apenas um nó.
+ Grave em subconjuntos de banco de dados independentes em cada nó (por exemplo, atribua um esquema separado a cada nó).

Quanto a conflitos INSERT versus INSERT, use sequências globais para evitar conflitos por completo.

 Se os conflitos não forem aceitáveis para seu caso de uso, considere implementar o bloqueio distribuído no nível da aplicação. Muitas vezes, a melhor abordagem é projetar a aplicação para funcionar com os mecanismos de resolução de conflitos da pgactive, em vez de tentar evitar todos os conflitos. Para obter mais informações, consulte [Tipos de conflito](#Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflicttypes). 

## Registro em log de conflitos
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.actact.conflictlogging"></a>

O pgactivelink registra incidentes de conflito na tabela `pgactive.pgactive_conflict_history` para ajudar você a diagnosticar e lidar com conflitos ativos-ativos. O registro em log de conflitos nessa tabela ocorre somente quando você define `pgactive.log_conflicts_to_table` como verdadeiro. A extensão pgactive também registra em log conflitos no arquivo de log do PostgreSQL quando log\$1min\$1messages é definido como `LOG` ou `lower`, independentemente da configuração `pgactive.log_conflicts_to_table`.

 Use a tabela do histórico de conflitos para:
+ Medir a frequência com que a aplicação cria conflitos.
+ Identificar onde os conflitos ocorrem.
+ Melhorar a aplicação para reduzir as taxas de conflito.
+ Detectar casos em que as resoluções de conflito não produzem os resultados desejados.
+ Determinar onde você precisa de acionadores de conflito definidos pelo usuário ou alterações no design da aplicação.

 Quanto a conflitos de linha, você pode, opcionalmente, registrar em log valores de linha. Isso é controlado pela configuração `pgactive.log_conflicts_to_table`. Observe que:
+ Essa opção é global para todo o banco de dados.
+ Não há controle por tabela sobre o registro em log de valores de linha.
+ Nenhum limite é aplicado a números de campo, elementos de matriz ou comprimentos de campo.
+ A habilitação desse recurso pode não ser aconselhável se você trabalha com linhas de vários megabytes que podem desencadear conflitos.

 Como a tabela do histórico de conflitos contém dados de todas as tabelas do banco de dados (cada uma com esquemas possivelmente diferentes), os valores das linhas registradas em log são armazenados como campos JSON. O JSON é criado usando `row_to_json`, de forma semelhante a chamá-lo diretamente do SQL. O PostgreSQL não oferece uma função `json_to_row`, então você precisará de um código específico de tabela (em PL/pgSQL, PL/Python, PL/Perl etc.) para reconstruir uma tupla de tipo composto por meio do JSON registrado em log.

**nota**  
O suporte a conflitos definidos pelo usuário está programado como um futuro recurso de extensão.

# Noções básicas sobre o esquema da pgactive
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema"></a>

O esquema da pgactive gerencia a replicação ativa-ativa no RDS para PostgreSQL. Esse esquema contém tabelas que armazenam informações de configuração e status da replicação.

**nota**  
O esquema da pgactive está evoluindo e está sujeito a alterações. Não modifique os dados nessas tabelas diretamente.

As tabelas principais no esquema da pgactive incluem:
+ `pgactive_nodes`: armazena informações sobre os nós no grupo de replicação ativa-ativa.
+ `pgactive_connections`: armazena detalhes da conexão para cada nó.

## pgactive\$1nodes
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.nodes"></a>

A pgactive\$1nodes armazena informações sobre os nós que participam do grupo de replicação ativa-ativa. 


| Coluna | Tipo | Collation (Agrupamento) | Anulável | Padrão | 
| --- | --- | --- | --- | --- | 
| node\$1sysid | texto | – | não nulo | – | 
| node\$1timeline | oid | – | não nulo | – | 
| node\$1dboid | oid | – | não nulo | – | 
| node\$1status | char | – | não nulo | – | 
| node\$1name | texto | – | não nulo | – | 
| node\$1dsn | texto | – | não nulo | – | 
| node\$1init\$1from\$1dsn | texto | – | não nulo | – | 
| node\$1read\$1only | booleano | – | – | false | 
| node\$1seq\$1id | smallint | – | não nulo | – | 

**node\$1sysid**  
ID exclusivo para um nó, gerado durante `pgactive_create_group` ou `pgactive_join_group`.

**node\$1status**  
Prontidão do nó:  
+ **b**: iniciando a configuração
+ **i**: inicializando
+ **c**: recuperando
+ **o**: criando slots de saída
+ **r**: pronto
+ **k**: encerrado
Essa coluna não indica se um nó está conectado ou desconectado.

**node\$1name**  
Nome de nó exclusivo fornecido pelo usuário.

**node\$1dsn**  
String de conexão ou nome de mapeamento do usuário

**node\$1init\$1from\$1dsn**  
DSN com base no qual esse nó foi criado.

## pgactive\$1connection
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.schema.connection"></a>

A pgactive\$1connections armazena detalhes da conexão para cada nó.


| Coluna | Tipo | Collation (Agrupamento) | Anulável | Padrão | 
| --- | --- | --- | --- | --- | 
| conn\$1sysid | texto | nenhuma | não nulo | nenhuma | 
| conn\$1timeline | oid | nenhuma | não nulo | nenhuma | 
| conn\$1dboid | oid | nenhuma | não nulo | nenhuma | 
| conn\$1dsn | texto | nenhuma | não nulo | nenhuma | 
| conn\$1apply\$1delay | integer | nenhuma | nenhuma | nenhuma | 
| conn\$1replication\$1sets | texto | nenhuma | nenhuma | nenhuma | 

conn\$1sysid  
Identificador do nó ao qual essa entrada se refere.

conn\$1dsn  
O mesmo que `node_dsn` de pgactive.pgactive\$1nodes.

conn\$1apply\$1delay  
Se definido, milissegundos de espera antes de aplicar cada transação por meio do nó remoto. Principalmente para depuração. Se nulo, o padrão global se aplica.

## Trabalhar com conjuntos de replicações
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.replication"></a>

Os conjuntos de replicações determinam quais tabelas incluir ou excluir das operações de replicação. Por padrão, todas as tabelas são replicadas, a menos que você especifique o contrário usando as seguintes funções:
+ `pgactive_exclude_table_replication_set()`: exclui tabelas especificadas da replicação.
+ `pgactive_include_table_replication_set()`: inclui tabelas especificadas na replicação.

**nota**  
Antes de configurar os conjuntos de replicações, considere o seguinte:  
Você pode configurar a inclusão ou exclusão da tabela somente depois de executar `pgactive_create_group()`, mas antes de `pgactive_join_group()`.
Depois de usar `pgactive_exclude_table_replication_set()`, você não pode usar `pgactive_include_table_replication_set()`.
Depois de usar `pgactive_include_table_replication_set()`, você não pode usar `pgactive_exclude_table_replication_set()`.

O sistema trata as tabelas recém-criadas de forma diferente com base na sua configuração inicial:
+ Se você excluiu tabelas: todas as outras tabelas criadas depois de `pgactive_join_group()` serão automaticamente incluídas na replicação.
+ Se você incluiu tabelas: todas as outras tabelas criadas depois de `pgactive_join_group()` serão automaticamente excluídas da replicação.

Para visualizar a configuração do conjunto de replicações de uma tabela específica, use a função `pgactive.pgactive_get_table_replication_sets()`.

# Referência de funções da pgactive
<a name="pgactive-functions-reference"></a>

Abaixo, você pode encontrar uma lista de funções da pgactive com os respectivos parâmetros, valores de retorno e observações práticas de uso para ajudar você a usá-las de forma eficaz:

## get\$1last\$1applied\$1xact\$1info
<a name="get-last-applied-xact-info"></a>

Recupera as informações da última transação aplicada para um nó especificado.

**Arguments (Argumentos)**  
+ sysid (text): OID de carimbo de data/hora
+ dboid (OID)

**Tipo de retorno**  
Ela registra o seguinte:  
+ last\$1applied\$1xact\$1id (OID)
+ last\$1applied\$1xact\$1committs (carimbo de data/hora com fuso horário)
+ last\$1applied\$1xact\$1at (carimbo de data/hora com fuso horário)

**Observações de uso**  
Use esta função para recuperar as informações da última transação aplicada para um nó especificado.

## pgactive\$1apply\$1pause
<a name="pgactive-apply-pause"></a>

Pausa o processo apply da replicação.

**Arguments (Argumentos)**  
Nenhum

**Tipo de retorno**  
boolean

**Observações de uso**  
Chame esta função para pausar o processo apply da replicação.

## pgactive\$1apply\$1resume
<a name="pgactive-apply-resume"></a>

Retoma o processo apply da replicação.

**Arguments (Argumentos)**  
Nenhum

**Tipo de retorno**  
nulo

**Observações de uso**  
Chame essa função para retomar o processo apply da replicação.

## pgactive\$1is\$1apply\$1paused
<a name="pgactive-is-apply-paused"></a>

Verifica se o processo apply da replicação está em pausa no momento.

**Arguments (Argumentos)**  
Nenhum

**Tipo de retorno**  
boolean

**Observações de uso**  
Use essa função para verificar se o processo apply da replicação está em pausa no momento.

## pgactive\$1create\$1group
<a name="pgactive-create-group"></a>

Cria um grupo da pgactive convertendo um banco de dados independente no nó inicial.



**Arguments (Argumentos)**  
+ node\$1name (text)
+ node\$1dsn (text)
+ apply\$1delay integer DEFAULT NULL::integer - replication\$1sets text[] DEFAULT ARRAY[‘default’::text]

**Tipo de retorno**  
nulo

**Observações de uso**  
Cria um grupo da pgactive convertendo um banco de dados independente no nó inicial. A função realiza verificações de integridade antes de transformar o nó em um nó pgactive. Antes de usar essa função, o cluster do PostgreSQL deve ter `max_worker_processes` suficientes para comportar operadores em segundo plano da pgactive.

## pgactive\$1detach\$1nodes
<a name="pgactive-detach-nodes"></a>

Remove os nós especificados do grupo da pgactive.

**Arguments (Argumentos)**  
+ p\$1nodes (text[])

**Tipo de retorno**  
nulo

**Observações de uso**  
Use essa função para remover os nós especificados do grupo da pgactive.

## pgactive\$1exclude\$1table\$1replication\$1set
<a name="pgactive-exclude-table-replication-set"></a>

Exclui uma tabela específica da replicação.

**Arguments (Argumentos)**  
+ p\$1relation (regclass)

**Tipo de retorno**  
nulo

**Observações de uso**  
Use essa função para excluir uma tabela específica da replicação.

## pgactive\$1get\$1replication\$1lag\$1info
<a name="pgactive-get-replication-lag-info"></a>

Recupera informações detalhadas do atraso da replicação, incluindo detalhes do nó, status do WAL e valores de LSN.

**Arguments (Argumentos)**  
Nenhum

**Tipo de retorno**  
Registro SETOF: node\$1name text, node\$1sysid text, application\$1name text, slot\$1name text, active boolean, active\$1pid integer, pending\$1wal\$1decoding bigint (tamanho aproximado do WAL em bytes a ser decodificado no nó emissor), pending\$1wal\$1to\$1apply bigint (tamanho aproximado do WAL em bytes a ser decodificado no nó receptor), restart\$1lsn pg\$1lsn, confirmed\$1flush\$1lsn pg\$1lsn, sent\$1lsn pg\$1lsn, write\$1lsn pg\$1lsn, flush\$1lsn pg\$1lsn, replay\$1lsn pg\$1lsn

**Observações de uso**  
Chame esta função para recuperar informações sobre o atraso da replicação, incluindo detalhes do nó, status do WAL e valores de LSN.

## pgactive\$1get\$1stats
<a name="pgactive-get-stats"></a>

Recupera estatísticas de replicação da pgactive.

**Arguments (Argumentos)**  
Nenhum

**Tipo de retorno**  
Registro SETOF: rep\$1node\$1id oid, rilocalid oid, riremoteid text, nr\$1commit bigint, nr\$1rollback bigint, nr\$1insert bigint, nr\$1insert\$1conflict bigint, nr\$1update bigint, nr\$1update\$1conflict bigint, nr\$1delete bigint, nr\$1delete\$1conflict bigint, nr\$1disconnect bigint

**Observações de uso**  
Use esta função para recuperar estatísticas de replicação da pgactive.

## pgactive\$1get\$1table\$1replication\$1sets
<a name="pgactive-get-table-replication-sets"></a>

Obtém a configuração do conjunto de replicações para uma relação específica.

**Arguments (Argumentos)**  
+ relation (regclass)

**Tipo de retorno**  
Registro SETOF

**Observações de uso**  
Chame esta função para obter a configuração do conjunto de replicações para uma relação específica.

## pgactive\$1include\$1table\$1replication\$1set
<a name="pgactive-include-table-replication-set"></a>

Inclui uma tabela específica na replicação.

**Arguments (Argumentos)**  
+ p\$1relation (regclass)

**Tipo de retorno**  
nulo

**Observações de uso**  
Use esta função para incluir uma tabela específica na replicação.

## pgactive\$1join\$1group
<a name="pgactive-join-group"></a>

Adiciona um nó a um grupo existente da pgactive.

**Arguments (Argumentos)**  
+ node\$1name (text)
+ node\$1dsn (text)
+ join\$1using\$1dsn (text)
+ apply\$1delay (integer, optional)
+ replication\$1sets (text[], default: ['default'])
+ bypass\$1collation\$1check (boolean, default: false)
+ bypass\$1node\$1identifier\$1creation (boolean, default: false)
+ bypass\$1user\$1tables\$1check (boolean, default: false)

**Tipo de retorno**  
nulo

**Observações de uso**  
Chame essa função para adicionar um nó a um grupo existente da pgactive. O cluster do PostgreSQL deve ter max\$1worker\$1processes suficientes para os operadores em segundo plano da pgactive.

## pgactive\$1remove
<a name="pgactive-remove"></a>

Remove todos os componentes da pgactive do nó local.

**Arguments (Argumentos)**  
+ force (boolean, default: false)

**Tipo de retorno**  
nulo

**Observações de uso**  
Chame esta função para remover todos os componentes da pgactive do nó local.

## pgactive\$1snowflake\$1id\$1nextval
<a name="pgactive-snowflake-id-nextval"></a>

Gera valores de sequência exclusivos específicos do nó.

**Arguments (Argumentos)**  
+ regclass

**Tipo de retorno**  
bigint

**Observações de uso**  
Use esta função para gerar valores de sequência exclusivos específicos do nó.

## pgactive\$1update\$1node\$1conninfo
<a name="pgactive-update-node-conninfo"></a>

Atualiza as informações de conexão de um nó da pgactive.

**Arguments (Argumentos)**  
+ node\$1name\$1to\$1update (text)
+ node\$1dsn\$1to\$1update (text)

**Tipo de retorno**  
nulo

**Observações de uso**  
Usa esta função para atualizar as informações de conexão de um nó da pgactive.

## pgactive\$1wait\$1for\$1node\$1ready
<a name="pgactive-wait-for-node-ready"></a>

Monitora o progresso das operações de criação de grupo ou junção.

**Arguments (Argumentos)**  
+ timeout (integer, default: 0)
+ progress\$1interval (integer, default: 60)

**Tipo de retorno**  
nulo

**Observações de uso**  
Chame esta função para monitorar o progresso das operações de criação de grupo ou junção.

# Lidar com conflitos na replicação ativa-ativa
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-conflicts"></a>

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\$1cron do PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html).

# Lidar com sequências na replicação ativa-ativa
<a name="Appendix.PostgreSQL.CommonDBATasks.pgactive.handle-sequences"></a>

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.

```
app=> CREATE TABLE gstest (
      id bigint primary key,
      parrot text
    );
```

```
app=>CREATE SEQUENCE gstest_id_seq OWNED BY gstest.id;
```

```
app=> 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);
```

```
app=> CREATE SEQUENCE some_seq INCREMENT 100 OWNED BY some_table.generated_value;
```

```
app=> 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.

```
app=>
-- On node 1
SELECT setval('some_seq', 1);

-- On node 2
SELECT setval('some_seq', 2);
```