

# Usar extensões PostgreSQL com o Amazon RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Extensions"></a>

É possível estender a funcionalidade do PostgreSQL instalando uma variedade de extensões e módulos. Por exemplo, para trabalhar com dados espaciais, você pode instalar e usar a extensão PostGIS. Para obter mais informações, consulte[Gerenciar dados espaciais com a extensão PostGIS](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md) Como outro exemplo, se você quiser melhorar a entrada de dados para tabelas muito grandes, considere particionar seus dados usando `pg_partman`. Para saber mais, consulte [Gerenciar partições do PostgreSQL com a extensão pg\$1partman](PostgreSQL_Partitions.md).

**nota**  
O RDS para PostgreSQL comporta extensões de linguagem confiáveis para PostgreSQL por meio da extensão `pg_tle`, que você pode adicionar à sua instância de banco de dados. Ao usar essa extensão, os desenvolvedores podem criar suas próprias extensões do PostgreSQL em um ambiente seguro que simplifique os requisitos de instalação e configuração. Para saber mais sobre as versões do RDS para PostgreSQL que aceitam a extensão `pg_tle` e ter mais informações, consulte [Trabalhar com Trusted Language Extensions para PostgreSQL](PostgreSQL_trusted_language_extension.md).

Em alguns casos, em vez de instalar uma extensão, você pode adicionar um módulo específico à lista de `shared_preload_libraries` no grupo de parâmetros de banco de dados personalizado da instância de banco de dados do RDS para PostgreSQL. Normalmente, o grupo de parâmetros padrão do cluster de banco de dados carrega somente as `pg_stat_statements`, mas vários outros módulos estão disponíveis para serem adicionados à lista. Por exemplo, você pode incluir a capacidade de agendamento adicionando o módulo `pg_cron`, conforme detalhado em [Agendar manutenção com a extensão pg\$1cron do PostgreSQL](PostgreSQL_pg_cron.md). Como outro exemplo, você pode registrar planos de execução de consultas carregando o módulo `auto_explain`. Para saber mais, consulte [Logging execution plans of queries](https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-tune-query-performance/#) (Registrar em log planos de execução de consultas) no Centro de Conhecimentos da AWS.

Dependendo da versão do RDS para PostgreSQL, a instalação de uma extensão pode exigir permissões de `rds_superuser`, como a seguir: 
+ Para o RDS para PostgreSQL versões 12 e versões anteriores, a instalação de extensões requer privilégios de `rds_superuser`.
+ Para o RDS para PostgreSQL versão 13 e versões superiores, os usuários (perfis) com permissões de criação em uma determinada instância de banco de dados podem instalar e usar quaisquer *extensões confiáveis*. Para obter uma lista de extensões confiáveis, consulte [Extensões confiáveis do PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.Extensions.Trusted). 

Também é possível especificar com precisão quais extensões podem ser instaladas na instância de banco de dados do RDS para PostgreSQL, listando-as no parâmetro `rds.allowed_extensions`. Para obter mais informações, consulte [Restringir a instalação de extensões do PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction).

Para saber mais a respeito do perfil de `rds_superuser`, consulte [Noções básicas de perfis e permissões do PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Roles.md).

**Topics**
+ [

# Usar funções da extensão orafce
](Appendix.PostgreSQL.CommonDBATasks.orafce.md)
+ [

# Usar a compatibilidade com extensões delegadas do Amazon RDS para PostgreSQL
](RDS_delegated_ext.md)
+ [

# Gerenciar partições do PostgreSQL com a extensão pg\$1partman
](PostgreSQL_Partitions.md)
+ [

# Usar pgAudit para registrar a atividade do banco de dados
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.md)
+ [

# Agendar manutenção com a extensão pg\$1cron do PostgreSQL
](PostgreSQL_pg_cron.md)
+ [

# Usar pglogical para sincronizar dados entre instâncias
](Appendix.PostgreSQL.CommonDBATasks.pglogical.md)
+ [

# Usar pgactive para comportar a replicação ativa-ativa
](Appendix.PostgreSQL.CommonDBATasks.pgactive.md)
+ [

# Reduzir o inchaço em tabelas e índices com a extensão pg\$1repack
](Appendix.PostgreSQL.CommonDBATasks.pg_repack.md)
+ [

# Atualizar e usar a extensão PLV8
](PostgreSQL.Concepts.General.UpgradingPLv8.md)
+ [

# Usar PL/Rust para escrever funções do PostgreSQL na linguagem Rust
](PostgreSQL.Concepts.General.Using.PL_Rust.md)
+ [

# Gerenciar dados espaciais com a extensão PostGIS
](Appendix.PostgreSQL.CommonDBATasks.PostGIS.md)

# Usar funções da extensão orafce
<a name="Appendix.PostgreSQL.CommonDBATasks.orafce"></a>

A extensão orafce fornece funções e operadores que emulam um subconjunto de funções e pacotes de um banco de dados Oracle. A extensão orafce permite fazer a portabilidade de uma aplicação Oracle para o PostgreSQL com mais facilidade. Essa extensão é compatível com o RDS para PostgreSQL versões 9.6.6 e posteriores. Para obter mais informações sobre a extensão, consulte o [orafce](https://github.com/orafce/orafce) no GitHub.

**nota**  
O RDS para PostgreSQL não é compatível com o pacote `utl_file` que faz parte da extensão orafce. Isso ocorre porque as funções do esquema `utl_file` fornecem operações de leitura e gravação em arquivos de texto do sistema operacional, o que exige que o superusuário acesse o host subjacente. Como um serviço gerenciado, o RDS para PostgreSQL não fornece acesso ao host.

**Para usar a extensão orafce**

1. Conecte-se à instância de banco de dados com o nome do usuário principal que você usou para criar a instância de banco de dados. 

   Se você quiser ativar a extensão orafce para um banco de dados diferente na mesma instância de banco de dados, use o comando `/c dbname` do psql. Usando esse comando, você muda do banco de dados primário depois de iniciar a conexão.

1. Ativar a extensão orafce com a instrução `CREATE EXTENSION`.

   ```
   CREATE EXTENSION orafce;
   ```

1. Transfira propriedade do esquema oracle para a função rds\$1superuser com a instrução `ALTER SCHEMA`.

   ```
   ALTER SCHEMA oracle OWNER TO rds_superuser;
   ```

   Caso queira ver uma lista de proprietários do esquema oracle, use o comando de psql `\dn`.

# Usar a compatibilidade com extensões delegadas do Amazon RDS para PostgreSQL
<a name="RDS_delegated_ext"></a>

Usando a compatibilidade com extensões delegadas do PostgreSQL, é possível delegar o gerenciamento de extensões a um usuário que não precise ser um `rds_superuser`. Com esse suporte de extensão delegado, um novo perfil chamado `rds_extension` é criado, e você deve atribuí-lo a um usuário para gerenciar outras extensões. Esse perfil pode criar, atualizar e eliminar extensões.

É possível especificar quais extensões podem ser instaladas na instância de banco de dados do RDS listando-as no parâmetro `rds.allowed_extensions`. Para obter mais informações, consulte [Usar extensões PostgreSQL com o Amazon RDS para PostgreSQL](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Extensions.html).

É possível restringir a lista de extensões disponíveis que podem ser gerenciadas pelo usuário com o perfil `rds_extension` usando o parâmetro `rds.allowed_delegated_extensions`.

O suporte de extensão delegado está disponível nas seguintes versões:
+ Todas as versões posteriores
+ 16.4 e versões 16 posteriores
+ 15.8 e versões 15 posteriores
+ 14.13 e versões 14 posteriores
+ 13.16 e versões 13 posteriores
+ 12.20 e versões 12 posteriores

**Topics**
+ [

## Ativar o suporte de extensão delegado a um usuário
](#RDSPostgreSQL.delegated_ext_mgmt)
+ [

## Configuração usada na compatibilidade com extensões delegadas do PostgreSQL
](#RDSPostgreSQL.delegated_ext_config)
+ [

## Desativar o suporte para a extensão delegada
](#RDSPostgreSQL.delegated_ext_disable)
+ [

## Benefícios de usar a compatibilidade com extensões delegadas do Amazon RDS
](#RDSPostgreSQL.delegated_ext_benefits)
+ [

## Limitação da compatibilidade com extensões delegadas do PostgreSQL
](#RDSPostgreSQL.delegated_ext_limit)
+ [

## Permissões necessárias para determinadas extensões
](#RDSPostgreSQL.delegated_ext_perm)
+ [

## Considerações sobre segurança
](#RDSPostgreSQL.delegated_ext_sec)
+ [

## Descartar cascata de extensão desabilitado
](#RDSPostgreSQL.delegated_ext_drop)
+ [

## Exemplos de extensões que podem ser adicionadas usando o suporte de extensão delegado
](#RDSPostgreSQL.delegated_ext_support)

## Ativar o suporte de extensão delegado a um usuário
<a name="RDSPostgreSQL.delegated_ext_mgmt"></a>

É necessário executar o seguinte para habilitar o suporte de extensão delegado a um usuário:

1. **Conceder o perfil `rds_extension` a um usuário**: conecte-se ao banco de dados `rds_superuser` e execute o seguinte comando:

   ```
   Postgres => grant rds_extension to user_name;
   ```

1. **Definir a lista de extensões disponíveis para usuários delegados gerenciarem**: o `rds.allowed_delegated_extensions` permite que você especifique um subconjunto das extensões disponíveis usando o parâmetro de cluster de banco de dados `rds.allowed_extensions`. É possível fazer isso em um dos seguintes níveis:
   + No cluster ou no grupo de parâmetros da instância, por meio do Console de gerenciamento da AWS ou da API. Para obter mais informações, consulte [Grupos de parâmetros para Amazon RDS](USER_WorkingWithParamGroups.md).
   + Use o seguinte comando em nível de banco de dados:

     ```
     alter database database_name set rds.allowed_delegated_extensions = 'extension_name_1,
                         extension_name_2,...extension_name_n';
     ```
   + Use o seguinte comando em nível de usuário:

     ```
     alter user user_name set rds.allowed_delegated_extensions = 'extension_name_1,
                         extension_name_2,...extension_name_n';
     ```
**nota**  
Não é necessário reiniciar o banco de dados depois de alterar o parâmetro dinâmico `rds.allowed_delegated_extensions`.

1. **Permitir que o usuário delegado acesse os objetos criados durante o processo de criação da extensão**: determinadas extensões criam objetos que exigem que permissões adicionais sejam concedidas para que o usuário com o perfil `rds_extension` possa acessá-los. O `rds_superuser` deve conceder ao usuário delegado acesso a esses objetos. Uma das opções é usar um gatilho de eventos para conceder permissão automaticamente ao usuário delegado.

   **Exemplo de gatilho de eventos**

   Se quiser permitir que um usuário delegado com `rds_extension` use extensões que exijam permissões de configuração nos objetos criados pela criação da extensão, você poderá personalizar o exemplo abaixo de um gatilho de eventos e adicionar somente as extensões para as quais você deseja que os usuários delegados tenham acesso à funcionalidade completa. Esse gatilho de eventos pode ser criado no modelo 1 (o modelo padrão), portanto, todo banco de dados criado a partir do modelo 1 terá esse gatilho de eventos. Quando um usuário delegado instalar a extensão, esse gatilho concederá automaticamente a propriedade dos objetos criados pela extensão.

   ```
   CREATE OR REPLACE FUNCTION create_ext()
   
     RETURNS event_trigger AS $$
   
   DECLARE
   
     schemaname TEXT;
     databaseowner TEXT;
   
     r RECORD;
   
   BEGIN
   
     IF tg_tag = 'CREATE EXTENSION' and current_user != 'rds_superuser' THEN
       RAISE NOTICE 'SECURITY INVOKER';
       RAISE NOTICE 'user: %', current_user;
       FOR r IN SELECT * FROM pg_catalog.pg_event_trigger_ddl_commands()
       LOOP
           CONTINUE WHEN r.command_tag != 'CREATE EXTENSION' OR r.object_type != 'extension';
   
           schemaname = (
               SELECT n.nspname
               FROM pg_catalog.pg_extension AS e
               INNER JOIN pg_catalog.pg_namespace AS n
               ON e.extnamespace = n.oid
               WHERE e.oid = r.objid
           );
   
           databaseowner = (
               SELECT pg_catalog.pg_get_userbyid(d.datdba)
               FROM pg_catalog.pg_database d
               WHERE d.datname = current_database()
           );
           RAISE NOTICE 'Record for event trigger %, objid: %,tag: %, current_user: %, schema: %, database_owenr: %', r.object_identity, r.objid, tg_tag, current_user, schemaname, databaseowner;
           IF r.object_identity = 'address_standardizer_data_us' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_gaz TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_lex TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.us_rules TO %I WITH GRANT OPTION;', schemaname, databaseowner);
           ELSIF r.object_identity = 'dict_int' THEN
               EXECUTE pg_catalog.format('ALTER TEXT SEARCH DICTIONARY %I.intdict OWNER TO %I;', schemaname, databaseowner);
           ELSIF r.object_identity = 'pg_partman' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.part_config_sub TO %I WITH GRANT OPTION;', schemaname, databaseowner);
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE %I.custom_time_partitions TO %I WITH GRANT OPTION;', schemaname, databaseowner);
           ELSIF r.object_identity = 'postgis_topology' THEN
               EXECUTE pg_catalog.format('GRANT SELECT, UPDATE, INSERT, DELETE ON ALL TABLES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
               EXECUTE pg_catalog.format('GRANT USAGE ON SCHEMA topology TO %I WITH GRANT OPTION;', databaseowner);
           END IF;
       END LOOP;
     END IF;
   END;
   $$ LANGUAGE plpgsql SECURITY DEFINER;
   
   CREATE EVENT TRIGGER log_create_ext ON ddl_command_end EXECUTE PROCEDURE create_ext();
   ```

## Configuração usada na compatibilidade com extensões delegadas do PostgreSQL
<a name="RDSPostgreSQL.delegated_ext_config"></a>


| Nome da configuração | Descrição | Valor padrão | Observações | Quem pode modificar ou conceder permissão | 
| --- | --- | --- | --- | --- | 
| `rds.allowed_delegated_extensions` | Esse parâmetro limita as extensões que um perfil rds\$1extension pode gerenciar em um banco de dados. Ele deve ser um subconjunto de rds.allowed\$1extensions. | string vazia | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/RDS_delegated_ext.html) Para saber mais sobre como configurar esse parâmetro, consulte [Ativar o suporte de extensão delegado a um usuário](#RDSPostgreSQL.delegated_ext_mgmt). | rds\$1superuser | 
| `rds.allowed_extensions` | Esse parâmetro permite que o cliente limite as extensões que podem ser instaladas na instância de banco de dados do RDS. Para ter mais informações, consulte [Restringir a instalação de extensões do PostgreSQL](https://docs.aws.amazon.com//AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction). | "\$1" | Por padrão, esse parâmetro é definido como “\$1”, o que significa que todas as extensões aceitas no RDS para PostgreSQL e no Aurora PostgreSQL podem ser criadas por usuários com os privilégios necessários. Vazio significa que nenhuma extensão pode ser instalada na instância de banco de dados do RDS. | administrador | 
| `rds-delegated_extension_allow_drop_cascade` | Esse parâmetro controla a capacidade do usuário com `rds_extension` de eliminar a extensão usando uma opção em cascata. | desligar | Por padrão, `rds-delegated_extension_allow_drop_cascade` é definido como `off`. Isso significa que os usuários com `rds_extension` não têm permissão para descartar uma extensão usando a opção em cascata. Para conceder essa capacidade, o parâmetro `rds.delegated_extension_allow_drop_cascade` deve ser definido como `on`. | rds\$1superuser | 

## Desativar o suporte para a extensão delegada
<a name="RDSPostgreSQL.delegated_ext_disable"></a>

**Desativar parcialmente**  
Os usuários delegados não podem criar extensões, mas ainda podem atualizar as existentes.
+ Redefina `rds.allowed_delegated_extensions` como o valor padrão no grupo de parâmetros de cluster de banco de dados.
+ Use o seguinte comando em nível de banco de dados:

  ```
  alter database database_name reset rds.allowed_delegated_extensions;
  ```
+ Use o seguinte comando em nível de usuário:

  ```
  alter user user_name reset rds.allowed_delegated_extensions;
  ```

**Desativar totalmente**  
Revogar o perfil `rds_extension` de um usuário vai restaurar as permissões padrão do usuário. O usuário não pode mais criar, atualizar nem descartar extensões. 

```
postgres => revoke rds_extension from user_name;
```

## Benefícios de usar a compatibilidade com extensões delegadas do Amazon RDS
<a name="RDSPostgreSQL.delegated_ext_benefits"></a>

Usando a compatibilidade com extensões delegadas do PostgreSQL, é possível delegar, com segurança, o gerenciamento de extensões a usuários que não têm o perfil `rds_superuser`. Esse recurso oferece os seguintes benefícios:
+ É possível delegar facilmente o gerenciamento de extensões aos usuários de sua escolha.
+ Isso não exige o perfil `rds_superuser`.
+ Oferece a capacidade de oferecer compatibilidade com um conjunto diferente de extensões para bancos de dados diferentes no mesmo cluster de banco de dados.

## Limitação da compatibilidade com extensões delegadas do PostgreSQL
<a name="RDSPostgreSQL.delegated_ext_limit"></a>
+ Objetos criados durante o processo de criação da extensão podem exigir privilégios adicionais para que a extensão funcione corretamente.
+ Algumas extensões não podem ser gerenciadas pelo usuário da extensão delegada por padrão, incluindo as seguintes: `log_fdw`, `pg_cron`, `pg_tle`, `pgactive`, `pglogical`, `postgis_raster`, `postgis_tiger_geocoder`, `postgis_topology`.

## Permissões necessárias para determinadas extensões
<a name="RDSPostgreSQL.delegated_ext_perm"></a>

Para criar, usar ou atualizar as extensões a seguir, o usuário delegado deve ter os privilégios necessários nestas funções, tabelas e esquemas.


| Extensões que precisam de propriedade ou permissões | Função | Tabelas | Schema | Dicionário de pesquisa de texto | Comment | 
| --- | --- | --- | --- | --- | --- | 
|  address\$1standardizer\$1data\$1us | nenhuma | us\$1gaz, us\$1lex, us\$1lex, I.us\$1rules | nenhuma | nenhuma | nenhuma | 
| amcheck | bt\$1index\$1check, bt\$1index\$1parent\$1check | nenhuma | nenhuma | nenhuma | nenhuma | 
| dict\$1int | nenhuma | nenhuma | nenhuma | intdict | nenhuma | 
| pg\$1partman | nenhuma | custom\$1time\$1partitions, part\$1config, part\$1config\$1sub | nenhuma | nenhuma | nenhuma | 
| pg\$1stat\$1statements | nenhuma | nenhuma | nenhuma | nenhuma | nenhuma | 
| PostGIS | st\$1tileenvelope | spatial\$1ref\$1sys | nenhuma | nenhuma | nenhuma | 
| postgis\$1raster | nenhuma | nenhuma | nenhuma | nenhuma | nenhuma | 
|  postgis\$1topology | nenhuma | topologia, camada | topologia | nenhuma | o usuário delegado deve ser o proprietário do banco de dados | 
| log\$1fdw | create\$1foreign\$1table\$1for\$1log\$1file | nenhuma | nenhuma | nenhuma | nenhuma | 
| rds\$1tools | role\$1password\$1encryption\$1type | nenhuma | nenhuma | nenhuma | nenhuma | 
|  postgis\$1tiger\$1geocoder | nenhuma | geocode\$1settings\$1default, geocode\$1settings | tiger | nenhuma | nenhuma | 
| pg\$1freespacemap | pg\$1freespace | nenhuma | nenhuma | nenhuma | nenhuma | 
| pg\$1visibility | pg\$1visibility | nenhuma | nenhuma | nenhuma | nenhuma | 

## Considerações sobre segurança
<a name="RDSPostgreSQL.delegated_ext_sec"></a>

 Lembre-se de que um usuário com o perfil `rds_extension` poderá gerenciar extensões em todos os bancos de dados nos quais tiver o privilégio de conexão. Se a intenção for fazer com que um usuário delegado gerencie a extensão em um único banco de dados, uma prática recomendada é revogar todos os privilégios públicos em cada banco de dados e, depois, conceder explicitamente o privilégio de conexão desse banco de dados específico ao usuário delegado. 

 Existem várias extensões que podem permitir que um usuário acesse informações de vários bancos de dados. Garanta que os usuários que receberem `rds_extension` tenham recursos de vários bancos de dados antes de adicionar essas extensões a `rds.allowed_delegated_extensions`. Por exemplo, `postgres_fdw` e `dblink` oferecem a capacidade de consultar vários bancos de dados na mesma instância ou em instâncias remotas. `log_fdw` lê os arquivos de log do mecanismo postgres, relacionados a todos os bancos de dados na instância, possivelmente contendo consultas lentas ou mensagens de erro de vários bancos de dados. `pg_cron` permite a execução de trabalhos agendados em segundo plano na instância de banco de dados e pode configurar trabalhos para execução em um banco de dados diferente. 

## Descartar cascata de extensão desabilitado
<a name="RDSPostgreSQL.delegated_ext_drop"></a>

 A capacidade de descartar a extensão com a opção em cascata por um usuário com o perfil `rds_extension` é controlada pelo parâmetro `rds.delegated_extension_allow_drop_cascade`. Por padrão, `rds-delegated_extension_allow_drop_cascade` é definido como `off`. Isso significa que os usuários com o perfil `rds_extension` não têm permissão para descartar uma extensão usando a opção em cascata, conforme mostrado na consulta a seguir. 

```
DROP EXTENSION CASCADE;
```

Pois isso descartará automaticamente os objetos que dependem da extensão e, por sua vez, todos os objetos que dependem desses objetos. A tentativa de usar a opção em cascata gerará um erro.

 Para conceder essa capacidade, o parâmetro `rds.delegated_extension_allow_drop_cascade` deve ser definido como `on`. 

 Alterar o parâmetro dinâmico `rds.delegated_extension_allow_drop_cascade` não requer a reinicialização do banco de dados. É possível fazer isso em um dos seguintes níveis: 
+ No cluster ou no grupo de parâmetros da instância, por meio do Console de gerenciamento da AWS ou da API.
+ Usar o seguinte comando em nível de banco de dados:

  ```
  alter database database_name set rds.delegated_extension_allow_drop_cascade = 'on';
  ```
+ Usar o seguinte comando em nível de usuário:

  ```
  alter role tenant_user set rds.delegated_extension_allow_drop_cascade = 'on';
  ```

## Exemplos de extensões que podem ser adicionadas usando o suporte de extensão delegado
<a name="RDSPostgreSQL.delegated_ext_support"></a>
+ `rds_tools`

  ```
  extension_test_db=> create extension rds_tools;
  CREATE EXTENSION
  extension_test_db=> SELECT * from rds_tools.role_password_encryption_type() where rolname = 'pg_read_server_files';
  ERROR: permission denied for function role_password_encryption_type
  ```
+ `amcheck`

  ```
  extension_test_db=> CREATE TABLE amcheck_test (id int);
  CREATE TABLE
  extension_test_db=> INSERT INTO amcheck_test VALUES (generate_series(1,100000));
  INSERT 0 100000
  extension_test_db=> CREATE INDEX amcheck_test_btree_idx ON amcheck_test USING btree (id);
  CREATE INDEX
  extension_test_db=> create extension amcheck;
  CREATE EXTENSION
  extension_test_db=> SELECT bt_index_check('amcheck_test_btree_idx'::regclass);
  ERROR: permission denied for function bt_index_check
  extension_test_db=> SELECT bt_index_parent_check('amcheck_test_btree_idx'::regclass);
  ERROR: permission denied for function bt_index_parent_check
  ```
+ `pg_freespacemap`

  ```
  extension_test_db=> create extension pg_freespacemap;
  CREATE EXTENSION
  extension_test_db=> SELECT * FROM pg_freespace('pg_authid');
  ERROR: permission denied for function pg_freespace
  extension_test_db=> SELECT * FROM pg_freespace('pg_authid',0);
  ERROR: permission denied for function pg_freespace
  ```
+ `pg_visibility`

  ```
  extension_test_db=> create extension pg_visibility;
  CREATE EXTENSION
  extension_test_db=> select * from pg_visibility('pg_database'::regclass);
  ERROR: permission denied for function pg_visibility
  ```
+ `postgres_fdw`

  ```
  extension_test_db=> create extension postgres_fdw;
  CREATE EXTENSION
  extension_test_db=> create server myserver foreign data wrapper postgres_fdw options (host 'foo', dbname 'foodb', port '5432');
  ERROR: permission denied for foreign-data wrapper postgres_fdw
  ```

# Gerenciar partições do PostgreSQL com a extensão pg\$1partman
<a name="PostgreSQL_Partitions"></a>

O particionamento de tabelas PostgreSQL fornece um framework para processamento de alta performance de entrada e relatórios de dados. Use o particionamento para bancos de dados que exigem entrada muito rápida de grandes quantidades de dados. O particionamento também fornece consultas mais rápidas de tabelas grandes. O particionamento ajuda a manter os dados sem afetar a instância do banco de dados, pois requer menos recursos de E/S.

Ao usar o particionamento, você pode dividir dados em blocos de tamanho personalizado para processamento. Por exemplo, você pode particionar dados de séries temporais para intervalos como por hora, diário, semanal, mensal, trimestral, anual, personalizado ou qualquer combinação destes. Para um exemplo de dados de séries temporais, se você particionar a tabela por hora, cada partição conterá uma hora de dados. Se você particionar a tabela de séries temporais por dia, as partições manterão dados de um dia e assim por diante. A chave de partição controla o tamanho de uma partição. 

Quando você usa um comando SQL `INSERT` ou `UPDATE` em uma tabela particionada, o mecanismo de banco de dados roteia os dados para a partição apropriada. As partições de tabela PostgreSQL que armazenam os dados são tabelas filhas da tabela principal. 

Durante as leituras de consulta de banco de dados, o otimizador PostgreSQL examina a cláusula `WHERE` da consulta e, se possível, direciona a verificação do banco de dados apenas para as partições relevantes.

A partir da versão 10, o PostgreSQL usa o particionamento declarativo para implementar o particionamento de tabela. Isso também é conhecido como particionamento nativo do PostgreSQL. Antes do PostgreSQL versão 10, você usou gatilhos para implementar partições. 

O particionamento de tabelas PostgreSQL fornece os seguintes recursos:
+ Criação de novas partições a qualquer momento.
+ Intervalos variáveis de partição.
+ Partições destacáveis e reanexáveis usando instruções DDL (Data Definition Language, linguagem de definição de dados).

  Por exemplo, partições destacáveis são úteis para remover dados históricos da partição principal, mas manter dados históricos para análise.
+ Novas partições herdam as propriedades da tabela do banco de dados pai, incluindo:
  + Índices
  + Chaves primárias, que devem incluir a coluna de chave de partição
  + Chaves externas
  + Restrições de verificação
  + Referências
+ Criação de índices para a tabela completa ou cada partição específica.

Você não pode alterar o esquema de uma partição individual. No entanto, você pode fazer uma alteração na tabela pai (adicionando uma nova coluna, por exemplo) que se propaga para as partições. 

**Topics**
+ [

## Visão geral da extensão pg\$1partman do PostgreSQL
](#PostgreSQL_Partitions.pg_partman)
+ [

## Ativar a extensão pg\$1partman
](#PostgreSQL_Partitions.enable)
+ [

## Configurar partições usando a função create\$1parent
](#PostgreSQL_Partitions.create_parent)
+ [

## Configurar a manutenção da partição usando a função run\$1maintenance\$1proc
](#PostgreSQL_Partitions.run_maintenance_proc)

## Visão geral da extensão pg\$1partman do PostgreSQL
<a name="PostgreSQL_Partitions.pg_partman"></a>

Você pode usar a extensão `pg_partman` do PostgreSQL para automatizar a criação e a manutenção de partições de tabelas. Para obter mais informações gerais, consulte [PG Partition Manager](https://github.com/pgpartman/pg_partman) na documentação `pg_partman`.

**nota**  
A extensão `pg_partman` é compatível com o RDS para PostgreSQL versões 12.5 e posteriores.

Em vez de ter que criar manualmente cada partição, você ajusta o `pg_partman` com as seguintes configurações: 
+ Tabela a ser particionada
+ Tipo de partição
+ Chave de partição
+ Granularidade de partição
+ Opções de pré-criação e gerenciamento de partições

Depois de criar uma tabela particionada do PostgreSQL, registre-a com `pg_partman` chamando a função `create_parent`. Fazer isso cria as partições necessárias com base nos parâmetros que você passa para a função.

A extensão `pg_partman` também fornece a função `run_maintenance_proc`, que você pode chamar de maneira programada para gerenciar as partições automaticamente. Para garantir que as partições adequadas sejam criadas conforme necessário, agende essa função para ser executada periodicamente (por hora, por exemplo). Você também pode garantir que as partições sejam descartadas automaticamente.

## Ativar a extensão pg\$1partman
<a name="PostgreSQL_Partitions.enable"></a>

Se você tiver vários bancos de dados dentro da mesma instância de banco de dados PostgreSQL para a qual deseja gerenciar partições, habilite a extensão `pg_partman` separadamente para cada banco de dados. Para habilitar a extensão `pg_partman` para um banco de dados específico, crie o esquema de manutenção de partição e crie a extensão `pg_partman` da maneira a seguir.

```
CREATE SCHEMA partman;
CREATE EXTENSION pg_partman WITH SCHEMA partman;
```

**nota**  
Para criar a extensão `pg_partman`, certifique-se de que você tenha privilégios `rds_superuser`. 

Se você receber um erro como o seguinte, conceda os privilégios de `rds_superuser` à conta ou use sua conta de superusuário. 

```
ERROR: permission denied to create extension "pg_partman"
HINT: Must be superuser to create this extension.
```

Para conceder privilégios de `rds_superuser`, conecte-se à sua conta de superusuário e execute o seguinte comando.

```
GRANT rds_superuser TO user-or-role;
```

Para os exemplos que mostram usando a extensão pg\$1partman, usamos a seguinte tabela de banco de dados de amostra e partição. Esse banco de dados usa uma tabela particionada com base em um carimbo de data/hora. Um esquema `data_mart` contém uma tabela chamada `events` com uma coluna chamada `created_at`. As seguintes configurações estão incluídas na tabela `events`:
+  Chaves primárias `event_id` e `created_at`, que devem ter a coluna usada para orientar a partição.
+ Uma restrição de verificação `ck_valid_operation` para impor valores para uma coluna `operation` da tabela.
+ Duas chaves estrangeiras, onde uma (`fk_orga_membership)` aponta para a tabela externa `organization` e a outra (`fk_parent_event_id`) é uma chave estrangeira autorreferenciada. 
+ Dois índices, onde um (`idx_org_id`) é para a chave estrangeira e o outro (`idx_event_type`) é para o tipo de evento.

As declarações DDL a seguir criam esses objetos, que serão incluídos automaticamente em cada partição.

```
CREATE SCHEMA data_mart;
CREATE TABLE data_mart.organization ( org_id BIGSERIAL,
        org_name TEXT,
        CONSTRAINT pk_organization PRIMARY KEY (org_id)  
    );

CREATE TABLE data_mart.events(
        event_id        BIGSERIAL, 
        operation       CHAR(1), 
        value           FLOAT(24), 
        parent_event_id BIGINT, 
        event_type      VARCHAR(25), 
        org_id          BIGSERIAL, 
        created_at      timestamp, 
        CONSTRAINT pk_data_mart_event PRIMARY KEY (event_id, created_at), 
        CONSTRAINT ck_valid_operation CHECK (operation = 'C' OR operation = 'D'), 
        CONSTRAINT fk_orga_membership 
            FOREIGN KEY(org_id) 
            REFERENCES data_mart.organization (org_id),
        CONSTRAINT fk_parent_event_id 
            FOREIGN KEY(parent_event_id, created_at) 
            REFERENCES data_mart.events (event_id,created_at)
    ) PARTITION BY RANGE (created_at);

CREATE INDEX idx_org_id     ON  data_mart.events(org_id);
CREATE INDEX idx_event_type ON  data_mart.events(event_type);
```



## Configurar partições usando a função create\$1parent
<a name="PostgreSQL_Partitions.create_parent"></a>

Depois de habilitar a extensão `pg_partman`, use a função `create_parent` para configurar partições dentro do esquema de manutenção de partição. Aqui é usado o exemplo de tabela `events` criado em [Ativar a extensão pg\$1partmanConfigurar a manutenção da partição usando a função run\$1maintenance\$1proc](#PostgreSQL_Partitions.enable). Chame a função `create_parent` da seguinte forma:

```
SELECT partman.create_parent( 
 p_parent_table => 'data_mart.events',
 p_control      => 'created_at',
 p_type         => 'range',
 p_interval     => '1 day',
 p_premake      => 30);
```

Os parâmetros são os seguintes:
+ `p_parent_table` – a tabela particionada pai. Essa tabela já deve existir e estar totalmente qualificada, incluindo o esquema. 
+ `p_control` – a coluna na qual o particionamento deve ser baseado. O tipo de dados deve ser um inteiro ou baseado em tempo.
+ `p_type`: o tipo é `'range'` ou `'list'`.
+ `p_interval` – o intervalo ou a faixa de inteiros para cada partição. Os valores de exemplo incluem `1 day`, `1 hour` e assim por diante.
+ `p_premake` – o número de partições para criar antecipadamente a fim de dar suporte a novas inserções.

Para obter uma descrição completa da função `create_parent`, consulte [Funções de criação](https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md#user-content-creation-functions) na documentação do `pg_partman`..

## Configurar a manutenção da partição usando a função run\$1maintenance\$1proc
<a name="PostgreSQL_Partitions.run_maintenance_proc"></a>

Você pode executar operações de manutenção de partição para criar automaticamente novas partições, desanexar partições ou remover partições antigas. A manutenção da partição depende da função `run_maintenance_proc` da extesão `pg_partman` e da extensão `pg_cron`, que inicia um programador interno. O agendador `pg_cron` executa automaticamente instruções SQL, funções e procedimentos definidos em seus bancos de dados. 

A seguir, será usado o exemplo de tabela `events` criado em [Ativar a extensão pg\$1partmanConfigurar a manutenção da partição usando a função run\$1maintenance\$1proc](#PostgreSQL_Partitions.enable) para definir que as operações de manutenção de partição serão executadas automaticamente. Como pré-requisito, adicione `pg_cron` ao parâmetro `shared_preload_libraries` no grupo de parâmetros da instância de banco de dados.

```
CREATE EXTENSION pg_cron;

UPDATE partman.part_config 
SET infinite_time_partitions = true,
    retention = '3 months', 
    retention_keep_table=true 
WHERE parent_table = 'data_mart.events';
SELECT cron.schedule('@hourly', $$CALL partman.run_maintenance_proc()$$);
```

A seguir, você pode encontrar uma explicação detalhada do exemplo anterior: 

1. Modifique o grupo de parâmetros associado à sua instância de banco de dados e adicione `pg_cron` ao valor do parâmetro `shared_preload_libraries`. Essa alteração exige a reinicialização da instância de banco de dados para que tenha efeito. Para obter mais informações, consulte [Modificar parâmetros em um grupo de parâmetros de banco de dados no Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

1. Execute o comando `CREATE EXTENSION pg_cron;` usando uma conta que tenha as permissões de `rds_superuser`. Isso habilita a extensão `pg_cron`. Para obter mais informações, consulte [Agendar manutenção com a extensão pg\$1cron do PostgreSQL](PostgreSQL_pg_cron.md).

1. Execute o comando `UPDATE partman.part_config` para ajustar as configurações `pg_partman` para a tabela `data_mart.events`. 

1. Execute o comando `SET` . . . para configurar a tabela `data_mart.events`, com estas cláusulas:

   1. `infinite_time_partitions = true,` – configura a tabela para poder criar novas partições automaticamente, sem qualquer limite.

   1. `retention = '3 months',` – configura a tabela para ter uma retenção máxima de três meses. 

   1. `retention_keep_table=true `– Configura a tabela para que, quando o período de retenção for devido, a tabela não seja excluída automaticamente. Em vez disso, as partições que são mais antigas do que o período de retenção são apenas separadas da tabela pai.

1. Execute o comando `SELECT cron.schedule` . . . para fazer uma chamada da função `pg_cron`. Esta chamada define com que frequência o programador executa o procedimento de manutenção `pg_partman`, `partman.run_maintenance_proc`. Para este exemplo, o procedimento é executado a cada hora. 

Para obter uma descrição completa da função `run_maintenance_proc`, consulte [Funções de manutenção](https://github.com/pgpartman/pg_partman/blob/master/doc/pg_partman.md#maintenance-functions) na documentação do `pg_partman`. 

# Usar pgAudit para registrar a atividade do banco de dados
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit"></a>

Instituições financeiras, agências governamentais e muitos setores precisam manter *registros de auditoria* para atender aos requisitos regulatórios. Ao usar a extensão do PostgreSQL Audit (pgAudit) com sua instância de banco de dados do RDS para PostgreSQL, você pode capturar os registros detalhados que normalmente são necessários aos auditores ou para atender aos requisitos regulatórios. Por exemplo, você pode configurar a extensão pgAudit para monitorar alterações feitas em tabelas e bancos de dados específicos, registrar o usuário que fez a alteração e muitos outros detalhes.

A extensão pgAudit se baseia na funcionalidade da infraestrutura de registro em log nativa do PostgreSQL, estendendo as mensagens de log com mais detalhes. Em outras palavras, é usada a mesma abordagem para visualizar o log de auditoria e quaisquer mensagens de log. Para obter mais informações sobre o registro em log do PostgreSQL, consulte [Arquivos de log do banco de dados RDS para PostgreSQL](USER_LogAccess.Concepts.PostgreSQL.md). 

A extensão pgAudit retira dados confidenciais, como senhas de texto não criptografado, dos logs. Se sua instância de banco de dados do RDS para PostgreSQL estiver configurada para registrar declarações de linguagem de manipulação de dados (DML) conforme detalhado em [Ativar o registro em log de consultas para a instância de banco de dados do RDS para PostgreSQL](USER_LogAccess.Concepts.PostgreSQL.Query_Logging.md), você poderá evitar o problema de senha de texto não criptografado usando a extensão do PostgreSQL Audit. 

Você pode configurar a auditoria em suas instâncias de banco de dados com um alto grau de especificidade. É possível auditar todos os bancos de dados e todos os usuários. Ou você pode optar por auditar somente determinados bancos de dados, usuários e outros objetos. Também é possível excluir explicitamente da auditoria determinados usuários e bancos de dados. Para obter mais informações, consulte [Excluir usuários ou bancos de dados do registro em log de auditoria](Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db.md). 

Dada a quantidade de detalhes que podem ser capturados, recomendamos que, se você usar pgAudit, monitore seu consumo de armazenamento. 

A extensão pgAudit é compatível com todas as Versões do RDS para PostgreSQL. Para obter uma lista de versões de pgAudit compatíveis com a versão do RDS para PostgreSQL, consulte [Extension versions for Amazon Aurora PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html) (Versões de extensão para o Amazon Aurora PostgreSQL) em *Amazon RDS for PostgreSQL Release Notes* (Notas de versão do Amazon RDS para PostgreSQL). 

**Topics**
+ [

# Configurar a extensão pgAudit
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.md)
+ [

# Auditar objetos de banco de dados
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.auditing.md)
+ [

# Excluir usuários ou bancos de dados do registro em log de auditoria
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db.md)
+ [

# Referência para a extensão pgAudit
](Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.md)

# Configurar a extensão pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup"></a>

Para configurar a extensão pgAudit em sua instância de banco de dados do RDS para PostgreSQL, , primeiro adicione pgAudit às bibliotecas compartilhadas no grupo de parâmetros de banco de dados personalizado para sua instância de banco de dados do RDS para PostgreSQL. Para obter informações sobre como criar um grupo de parâmetros de banco de dados, consulte [Grupos de parâmetros para Amazon RDS](USER_WorkingWithParamGroups.md). Depois, instale a extensão pgAudit. Por fim, especifique os bancos de dados e os objetos que deseja auditar. Os procedimentos nesta seção mostram o procedimento. É possível usar o Console de gerenciamento da AWS ou a AWS CLI. 

Você deve ter permissões como a função `rds_superuser` para realizar todas essas tarefas.

As etapas a seguir pressupõem que sua instância de banco de dados do RDS para PostgreSQL esteja associada a um grupo de parâmetros de banco de dados. 

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

**Como configurar a extensão pgAudit**

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, selecione sua instância de banco de dados do RDS para PostgreSQL.

1. Abra a guia **Configuration** (Configuração) para sua Instância de banco de dados do RDS para PostgreSQL. Entre os detalhes da instância, encontre o link **Parameter group** (Grupo de parâmetros). 

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

1. No campo **Parameters** (Parâmetros), digite `shared_pre` para encontrar o parâmetro `shared_preload_libraries`.

1. Selecione **Edit parameters** (Editar parâmetros) para acessar os valores das propriedades.

1. Adicione `pgaudit` à lista no campo **Values** (Valores). Use uma vírgula para separar itens na lista de valores.   
![\[Imagem do parâmetro shared_preload_libaries com pgAudit adicionada.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pgaudit.png)

1. Reinicie a instância de banco de dados do RDS para PostgreSQL para que a alteração no parâmetro `shared_preload_libraries` tenha efeito. 

1. Quando a instância estiver disponível, verifique se a pgAudit foi inicializada. Use `psql` para se conectar à instância de banco de dados do RDS para PostgreSQL e depois execute o comando a seguir.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pgaudit
   (1 row)
   ```

1. Com a pgAudit inicializada, agora você pode criar a extensão. Você precisa criar a extensão depois de inicializar a biblioteca porque a extensão `pgaudit` instala acionadores de eventos para auditar declarações de linguagem de definição de dados (DDL). 

   ```
   CREATE EXTENSION pgaudit;
   ```

1. Feche a sessão `psql`.

   ```
   labdb=> \q
   ```

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. Encontre o parâmetro `pgaudit.log` na lista e defina como o valor apropriado para o caso de uso. Por exemplo, definir o parâmetro `pgaudit.log` como `write` conforme mostrado na imagem a seguir captura inserções, atualizações, exclusões e alguns outros tipos de alterações no log.   
![\[Imagem do parâmetro pgaudit.log com a configuração.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/rpg_set_pgaudit-log-level.png)

   Você também pode selecionar um dos valores a seguir para o parâmetro `pgaudit.log`.
   + none: esse é o valor padrão. Nenhuma alteração no banco de dados é registrada. 
   + all: registra tudo (read, write, function, role, ddl, misc). 
   + ddl: registra todas as instruções de linguagem de definição de dados (DDL) não incluídas na classe `ROLE`.
   + function: registra chamadas de função e blocos de `DO`.
   + misc: registra comandos diversos, como `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` e `SET`.
   + read: registra `SELECT` e `COPY` quando a fonte é uma relação (como uma tabela) ou uma consulta.
   + role: registra declarações relacionadas a funções e privilégios, como `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` e `DROP ROLE`.
   + write: registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` e `COPY` quando o destino é uma relação (tabela).

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

1. Abra o console do Amazon RDS em [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Selecione a instância de banco de dados do RDS para PostgreSQL na lista Bancos de dados.

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

**Como configurar a pgAudit**

Para configurar a pgAudit usando a AWS CLI, chame a operação [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) para modificar os parâmetros do log de auditoria em seu grupo de parâmetros personalizado, conforme mostrado no procedimento a seguir.

1. Use o comando AWS CLI a seguir para adicionar `pgaudit` ao parâmetro `shared_preload_libraries`.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pgaudit,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 para que a biblioteca da pgaudit seja inicializada.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Quando a instância estiver disponível, verifique se a `pgaudit` foi inicializada. Use `psql` para se conectar à instância de banco de dados do RDS para PostgreSQL e, depois, execute o comando a seguir.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pgaudit
   (1 row)
   ```

   Com a pgAudit inicializada, agora você pode criar a extensão.

   ```
   CREATE EXTENSION pgaudit;
   ```

1. Feche a sessão `psql` para que você possa usar a AWS CLI.

   ```
   labdb=> \q
   ```

1. Use o comando AWS CLI a seguir para especificar as classes de declaração que devem ser registradas pelo registro em log de auditoria da sessão. O exemplo define o parâmetro `pgaudit.log` como `write`, que captura inserções, atualizações e exclusões no log.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=pgaudit.log,ParameterValue=write,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

   Você também pode selecionar um dos valores a seguir para o parâmetro `pgaudit.log`.
   + none: esse é o valor padrão. Nenhuma alteração no banco de dados é registrada. 
   + all: registra tudo (read, write, function, role, ddl, misc). 
   + ddl: registra todas as instruções de linguagem de definição de dados (DDL) não incluídas na classe `ROLE`.
   + function: registra chamadas de função e blocos de `DO`.
   + misc: registra comandos diversos, como `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` e `SET`.
   + read: registra `SELECT` e `COPY` quando a fonte é uma relação (como uma tabela) ou uma consulta.
   + role: registra declarações relacionadas a funções e privilégios, como `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` e `DROP ROLE`.
   + write: registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` e `COPY` quando o destino é uma relação (tabela).

   Reinicie a instância de banco de dados do RDS para PostgreSQL usando o comando AWS CLI a seguir.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

# Auditar objetos de banco de dados
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.auditing"></a>

Com a pgAudit configurada em sua instância e banco de dados do RDS para PostgreSQL e configurada para seus requisitos, informações mais detalhadas são capturadas no log do PostgreSQL. Por exemplo, enquanto a configuração de registro em padrão do PostgreSQL identifica a data e a hora em que uma alteração foi feita em uma tabela do banco de dados, com a extensão pgAudit, a entrada do log pode incluir o esquema, o usuário que fez a alteração e outros detalhes, dependendo de como os parâmetros da extensão estão configurados. Você pode configurar a auditoria para monitorar as alterações das maneiras a seguir.
+ Para cada sessão, por usuário. Para o nível da sessão, você pode capturar o texto do comando totalmente qualificado.
+ Para cada objeto, por usuário e por banco de dados. 

O recurso de auditoria de objetos é ativado quando você cria a função `rds_pgaudit` no sistema e depois a adiciona ao parâmetro `pgaudit.role` no grupo de parâmetros personalizado. Por padrão, o parâmetro `pgaudit.role` não está definido e o único valor permitido é `rds_pgaudit`. As etapas a seguir pressupõem que a `pgaudit` tenha sido inicializada e que você tenha criado a extensão `pgaudit` seguindo o procedimento em [Configurar a extensão pgAudit](Appendix.PostgreSQL.CommonDBATasks.pgaudit.basic-setup.md). 

![\[Imagem do arquivo de log do PostgreSQL depois de configurar a pgAudit.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/pgaudit-log-example.png)


Conforme mostrado neste exemplo, a linha “LOG: AUDIT: SESSION” fornece informações sobre a tabela e o respectivo esquema, entre outros detalhes. 

**Como configurar a auditoria de objetos**

1. Use `psql` para se conectar à instância de banco de dados do RDS para PostgreSQL.

   ```
   psql --host=your-instance-name.aws-region.rds.amazonaws.com --port=5432 --username=postgrespostgres --password --dbname=labdb
   ```

1. Crie uma função de banco de dados chamada `rds_pgaudit` usando o comando a seguir.

   ```
   labdb=> CREATE ROLE rds_pgaudit;
   CREATE ROLE
   labdb=>
   ```

1. Feche a sessão `psql`.

   ```
   labdb=> \q
   ```

   Nas próximas etapas, use a AWS CLI para modificar os parâmetros de log de auditoria no grupo de parâmetros personalizado. 

1. Use o comando AWS CLI a seguir para definir o parâmetro `pgaudit.role` como `rds_pgaudit`. Por padrão, esse parâmetro está vazio, e `rds_pgaudit` é o único valor permitido.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=pgaudit.role,ParameterValue=rds_pgaudit,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 para que as alterações nos parâmetros tenham efeito.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Execute o comando a seguir para confirmar que `pgaudit.role` está definido como `rds_pgaudit`.

   ```
   SHOW pgaudit.role;
   pgaudit.role 
   ------------------
   rds_pgaudit
   ```

Para testar o registro em log da extensão pgAudit, execute vários comandos de exemplo semelhantes ao que você deseja auditar. Por exemplo, você pode executar os seguintes comandos.

```
CREATE TABLE t1 (id int);
GRANT SELECT ON t1 TO rds_pgaudit;
SELECT * FROM t1;
id 
----
(0 rows)
```

Os logs do banco de dados devem conter uma entrada semelhante à seguinte.

```
...
2017-06-12 19:09:49 UTC:...:rds_test@postgres:[11701]:LOG: AUDIT:
OBJECT,1,1,READ,SELECT,TABLE,public.t1,select * from t1;
...
```

Para obter informações sobre como visualizar os logs, consulte [Monitorar arquivos de log do Amazon RDS](USER_LogAccess.md).

Para saber mais sobre a extensão pgAudit, consulte [pgAudit](https://github.com/pgaudit/pgaudit/blob/master/README.md) no GitHub.

# Excluir usuários ou bancos de dados do registro em log de auditoria
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.exclude-user-db"></a>

Conforme discutido em [Arquivos de log do banco de dados RDS para PostgreSQL](USER_LogAccess.Concepts.PostgreSQL.md), os logs do PostgreSQL consomem espaço de armazenamento. O uso da extensão pgAudit aumenta o volume de dados reunidos nos logs em vários graus, dependendo das alterações monitoradas. Talvez você não precise auditar todos os usuários nem bancos de dados no Instância de banco de dados do RDS para PostgreSQL.

Para minimizar os impactos no armazenamento e evitar a captura desnecessária de registros de auditoria, você pode excluir usuários e bancos de dados da auditoria. Você também pode alterar o registro em log em determinada sessão. Os exemplos a seguir mostram o procedimento. 

**nota**  
As configurações de parâmetros no nível da sessão têm precedência sobre as configurações no grupo de parâmetros de banco de dados personalizado para a instância de banco de dados do RDS para PostgreSQL. Se você não quiser que os usuários do banco de dados ignorem suas configurações de registro em log de auditoria, não se esqueça de alterar as permissões. 

Suponha que sua instância de banco de dados do RDS para PostgreSQL esteja configurada ) para auditar o mesmo nível de atividade para todos os usuários e bancos de dados. Depois, decida que não quer auditar o usuário `myuser`. Você pode desativar a auditoria para `myuser` com o comando SQL a seguir.

```
ALTER USER myuser SET pgaudit.log TO 'NONE';
```

Depois, você pode usar a consulta a seguir para conferir a coluna `user_specific_settings` para `pgaudit.log` a fim de confirmar se o parâmetro está definido como `NONE`.

```
SELECT
    usename AS user_name,
    useconfig AS user_specific_settings
FROM
    pg_user
WHERE
    usename = 'myuser';
```

Você deve ver a saída da forma a seguir.

```
 user_name | user_specific_settings
-----------+------------------------
 myuser    | {pgaudit.log=NONE}
(1 row)
```

Você pode desativar o registro em log de determinado usuário no meio da sessão com o banco de dados com o comando a seguir.

```
ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'none';
```

Use a consulta a seguir para conferir a coluna de configurações de pgaudit.log para uma combinação específica de usuário e banco de dados. 

```
SELECT
    usename AS "user_name",
    datname AS "database_name",
    pg_catalog.array_to_string(setconfig, E'\n') AS "settings"
FROM
    pg_catalog.pg_db_role_setting s
    LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase
    LEFT JOIN pg_catalog.pg_user r ON r.usesysid = setrole
WHERE
    usename = 'myuser'
    AND datname = 'mydatabase'
ORDER BY
    1,
    2;
```

Você verá uma saída semelhante à seguinte.

```
  user_name | database_name |     settings
-----------+---------------+------------------
 myuser    | mydatabase    | pgaudit.log=none
(1 row)
```

Depois de desativar a auditoria de `myuser`, você decide que não deseja monitorar as alterações em `mydatabase`. Você pode desativar a auditoria para esse banco de dados específico usando o comando a seguir.

```
ALTER DATABASE mydatabase SET pgaudit.log to 'NONE';
```

Depois, use a consulta a seguir para conferir a coluna database\$1specific\$1settings a fim de confirmar se pgaudit.log está definido como NONE.

```
SELECT
a.datname AS database_name,
b.setconfig AS database_specific_settings
FROM
pg_database a
FULL JOIN pg_db_role_setting b ON a.oid = b.setdatabase
WHERE
a.datname = 'mydatabase';
```

Você deve ver a saída da forma a seguir.

```
 database_name | database_specific_settings
---------------+----------------------------
 mydatabase    | {pgaudit.log=NONE}
(1 row)
```

Para restaurar as configurações padrão para myuser, use o seguinte comando:

```
ALTER USER myuser RESET pgaudit.log;
```

Para restaurar as configurações padrão para um banco de dados, use o comando a seguir.

```
ALTER DATABASE mydatabase RESET pgaudit.log;
```

Para restaurar as configurações padrão de usuário e banco de dados, use o comando a seguir.

```
ALTER USER myuser IN DATABASE mydatabase RESET pgaudit.log;
```

Você também pode capturar eventos específicos no log definindo `pgaudit.log` como um dos outros valores permitidos para o parâmetro `pgaudit.log`. Para ter mais informações, consulte [Lista de configurações permitidas para o parâmetro `pgaudit.log`](Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.md#Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings).

```
ALTER USER myuser SET pgaudit.log TO 'read';
ALTER DATABASE mydatabase SET pgaudit.log TO 'function';
ALTER USER myuser IN DATABASE mydatabase SET pgaudit.log TO 'read,function'
```

# Referência para a extensão pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference"></a>

Você pode especificar o nível de detalhes que deseja para o log de auditoria alterando um ou mais dos parâmetros listados nesta seção. 

## Controlar o comportamento da pgAudit
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.basic-setup.parameters"></a>

Você pode controlar o registro em log de auditoria alterando um ou mais dos parâmetros listados na tabela a seguir. 


| Parameter | Descrição | 
| --- | --- | 
| `pgaudit.log`  | Especifica as classes de declaração que serão registradas pelo registro em log de auditoria de sessão. Os valores permitidos incluem ddl, function, misc, read, role, write, none, all. Para obter mais informações, consulte [Lista de configurações permitidas para o parâmetro `pgaudit.log`](#Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings).  | 
| `pgaudit.log_catalog` | Quando ativado (definido como 1), adiciona declarações à trilha de auditoria se todas as relações em uma declaração estiverem em pg\$1catalog. | 
| `pgaudit.log_level` | Especifica o nível de log que será usado para entradas de log. Valores permitidos: debug5, debug4, debug3, debug2, debug1, info, notice, warning, log | 
| `pgaudit.log_parameter` | Quando ativado (definido como 1), os parâmetros passados com a declaração são capturados no log de auditoria. | 
| `pgaudit.log_relation` | Quando ativado (definido como 1), o log de auditoria da sessão cria uma entrada de log separada para cada relação (TABLE, VIEW etc.) referenciada em uma declaração SELECT ou DML. | 
| `pgaudit.log_statement_once` | Especifica se o registro incluirá o texto e os parâmetros da instrução com a primeira entrada de log para uma combinação de instrução/subinstrução ou com cada entrada. | 
| `pgaudit.role` | Especifica a função primária a ser usada para o registro em log de auditoria de objetos. A única entrada permitida é `rds_pgaudit`. | 

## Lista de configurações permitidas para o parâmetro `pgaudit.log`
<a name="Appendix.PostgreSQL.CommonDBATasks.pgaudit.reference.pgaudit-log-settings"></a>

 


| Valor | Descrição | 
| --- | --- | 
| nenhuma | Esse é o padrão. Nenhuma alteração no banco de dados é registrada.  | 
| todas | Registra tudo (read, write, function, role, ddl, misc).  | 
| ddl | Registra todas as declarações de linguagem de definição de dados (DDL) não incluídas na classe `ROLE`. | 
| função | Registra chamadas de função e blocos de `DO`. | 
| misc | Registra comandos diversos, como `DISCARD`, `FETCH`, `CHECKPOINT`, `VACUUM` e `SET`. | 
| leitura | Registra `SELECT` e `COPY` quando a fonte é uma relação (como uma tabela) ou uma consulta. | 
| perfil | Registra declarações relacionadas a funções e privilégios, como `GRANT`, `REVOKE`, `CREATE ROLE`, `ALTER ROLE` e `DROP ROLE`. | 
| write | Registra `INSERT`, `UPDATE`, `DELETE`, `TRUNCATE` e `COPY` quando o destino é uma relação (tabela). | 

Para registrar vários tipos de eventos com auditoria de sessões, use uma lista separada por vírgulas. Para registrar todos os tipos de eventos, defina `pgaudit.log` para `ALL`. Reinicie a instância de banco de dados para aplicar as alterações.

Com a auditoria de objetos, você pode refinar o registro em log de auditoria para trabalhar com relações específicas. Por exemplo, você pode especificar que deseja o registro em log de auditoria para operações `READ` em uma ou mais tabelas.

# Agendar manutenção com a extensão pg\$1cron do PostgreSQL
<a name="PostgreSQL_pg_cron"></a>

Você pode utilizar a extensão `pg_cron` do PostgreSQL para programar comandos de manutenção dentro de um banco de dados do PostgreSQL. Para obter mais informações sobre a extensão, consulte [O que é pg\$1cron?](https://github.com/citusdata/pg_cron) na documentação do pg\$1cron. 

A extensão `pg_cron` é compatível com o mecanismo do RDS para PostgreSQL versões 12.5 e posteriores.

Para saber mais sobre como usar `pg_cron`, consulte [Programar trabalhos com pg\$1cron em bancos de dados do RDS para PostgreSQL ou compatíveis com o Aurora PostgreSQL](https://aws.amazon.com/blogs/database/schedule-jobs-with-pg_cron-on-your-amazon-rds-for-postgresql-or-amazon-aurora-for-postgresql-databases/).

**nota**  
A versão da extensão `pg_cron` é exibida como uma versão de dois dígitos, por exemplo, 1.6, na visualização pg\$1available\$1extensions. Embora você possa ver versões de três dígitos, por exemplo, 1.6.4 ou 1.6.5, listadas em alguns contextos, você deve especificar a versão de dois dígitos ao realizar uma atualização de extensão.

**Topics**
+ [

## Configurar a extensão pg\$1cron
](#PostgreSQL_pg_cron.enable)
+ [

## Conceder permissões de banco de dados para usar pg\$1cron
](#PostgreSQL_pg_cron.permissions)
+ [

## Agendar trabalhos de pg\$1cron
](#PostgreSQL_pg_cron.examples)
+ [

## Referência para a extensão pg\$1cron
](#PostgreSQL_pg_cron.reference)

## Configurar a extensão pg\$1cron
<a name="PostgreSQL_pg_cron.enable"></a>

Configure a extensão `pg_cron` da seguinte forma:

1. Modifique o grupo de parâmetros personalizado associado à sua instância de banco de dados do PostgreSQL adicionando `pg_cron` ao valor do parâmetro `shared_preload_libraries`.
   + Se a instância de banco de dados do RDS para PostgreSQL usa o parâmetro `rds.allowed_extensions` para listar explicitamente as extensões que podem ser instaladas, você precisa adicionar a extensão `pg_cron` à lista. Somente determinadas versões do RDS para PostgreSQL oferecem suporte ao parâmetro `rds.allowed_extensions`. Por padrão, todas as extensões disponíveis são permitidas. Para obter mais informações, consulte [Restringir a instalação de extensões do PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.Extensions.md#PostgreSQL.Concepts.General.FeatureSupport.Extensions.Restriction).

   Reinicie a instância de banco de dados do PostgreSQL para que as alterações no grupo de parâmetros entrem em vigor. Para saber mais sobre como trabalhar com grupos de parâmetros, consulte [Modificar parâmetros em um grupo de parâmetros de banco de dados no Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

1. Após a reinicialização da instância de banco de dados do PostgreSQL, execute o comando a seguir usando uma conta que tenha permissões `rds_superuser`. Por exemplo, se você usou as configurações padrão ao criar a instância de banco de dados do RDS para PostgreSQL, conecte-se como o usuário `postgres` e crie a extensão. 

   ```
   CREATE EXTENSION pg_cron;
   ```

   O agendador do `pg_cron` é definido no banco de dados PostgreSQL padrão chamado `postgres`. Os objetos `pg_cron` são criados neste banco de dados `postgres` e todas as ações de agendamento são executadas neste banco de dados.

1. Você pode usar as configurações padrão ou programar trabalhos para serem executados em outros bancos de dados dentro de sua instância de banco de dados PostgreSQL. Para programar trabalhos a serem executados em outros bancos de dados em sua instância de banco de dados PostgreSQL, consulte o exemplo em [Agendar um trabalho cron para um banco de dados diferente do banco de dados padrão](#PostgreSQL_pg_cron.otherDB).

## Conceder permissões de banco de dados para usar pg\$1cron
<a name="PostgreSQL_pg_cron.permissions"></a>

A instalação da extensão `pg_cron` requer privilégios de `rds_superuser`. No entanto, as permissões para usar `pg_cron` podem ser concedidas (por um membro do grupo/perfil de `rds_superuser`) para outros usuários do banco de dados, para que eles possam programar seus próprios trabalhos. Recomendamos que você conceda permissões para o esquema `cron` somente conforme necessário se ele melhorar as operações do ambiente de produção. 

Para conceder permissão a um usuário do banco de dados no esquema `cron`, execute o seguinte comando:

```
postgres=> GRANT USAGE ON SCHEMA cron TO db-user;
```

Isso concede a *db-user* permissão para acessar o esquema `cron` para programar trabalhos cron para os objetos que o usuário tem permissão para acessar. Se o usuário do banco de dados não tiver permissões, o trabalho falhará após a publicação da mensagem de erro no arquivo `postgresql.log`, conforme mostrado a seguir:

```
2020-12-08 16:41:00 UTC::@:[30647]:ERROR: permission denied for table table-name
2020-12-08 16:41:00 UTC::@:[27071]:LOG: background worker "pg_cron" (PID 30647) exited with exit code 1
```

Em outras palavras, certifique-se de que os usuários do banco de dados que tenham permissões no esquema `cron` também tenham permissões nos objetos (tabelas, esquemas e assim por diante) que planejam programar.

Os detalhes do trabalho cron e seu sucesso ou falha também são capturados na tabela `cron.job_run_details`. Para obter mais informações, consulte [Tabelas para agendar trabalhos e capturar status](#PostgreSQL_pg_cron.tables).

## Agendar trabalhos de pg\$1cron
<a name="PostgreSQL_pg_cron.examples"></a>

As seções a seguir mostram como você pode agendar várias tarefas de gerenciamento usando trabalhos `pg_cron`.

**nota**  
Ao criar trabalhos `pg_cron`, verifique se a configuração `max_worker_processes` a configuração é maior do que o número de `cron.max_running_jobs`. Um trabalho `pg_cron` falhará se ficar sem processos de operador em segundo plano. O número padrão de trabalhos `pg_cron` é `5`. Para obter mais informações, consulte [Parâmetros para gerenciar a extensão pg\$1cron](#PostgreSQL_pg_cron.parameters).

**Topics**
+ [

### Vacuum de tabelas
](#PostgreSQL_pg_cron.vacuum)
+ [

### Limpar a tabela de histórico de pg\$1cron
](#PostgreSQL_pg_cron.job_run_details)
+ [

### Registrar em log erros somente no arquivo postgresql.log
](#PostgreSQL_pg_cron.log_run)
+ [

### Agendar um trabalho cron para um banco de dados diferente do banco de dados padrão
](#PostgreSQL_pg_cron.otherDB)

### Vacuum de tabelas
<a name="PostgreSQL_pg_cron.vacuum"></a>

O autovacuum lida com manutenção de vacuum para a maioria dos casos. No entanto, você pode agendar o vacuum de uma tabela específica quando quiser. 

Consulte também, [Trabalhar com o autovacuum do PostgreSQL no Amazon RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md). 

Veja a seguir um exemplo de uso da função `cron.schedule` para configurar um trabalho a ser usado `VACUUM FREEZE` em uma tabela específica todos os dias às 22:00 (GMT).

```
SELECT cron.schedule('manual vacuum', '0 22 * * *', 'VACUUM FREEZE pgbench_accounts');
 schedule
----------
1
(1 row)
```

Após o exemplo anterior ser executado, você pode verificar o histórico na tabela `cron.job_run_details` da seguinte forma.

```
postgres=> SELECT * FROM cron.job_run_details;
jobid  | runid | job_pid | database | username | command                        | status    | return_message | start_time                    | end_time
-------+-------+---------+----------+----------+--------------------------------+-----------+----------------+-------------------------------+-------------------------------
 1     | 1     | 3395    | postgres | adminuser| vacuum freeze pgbench_accounts | succeeded | VACUUM         | 2020-12-04 21:10:00.050386+00 | 2020-12-04 21:10:00.072028+00
(1 row)
```

A seguir está uma consulta à tabela `cron.job_run_details` para ver os trabalhos que falharam.

```
postgres=> SELECT * FROM cron.job_run_details WHERE status = 'failed';
jobid | runid | job_pid | database | username | command                       | status | return_message                                   | start_time                    | end_time
------+-------+---------+----------+----------+-------------------------------+--------+--------------------------------------------------+-------------------------------+------------------------------
 5    | 4     | 30339   | postgres | adminuser| vacuum freeze pgbench_account | failed | ERROR: relation "pgbench_account" does not exist | 2020-12-04 21:48:00.015145+00 | 2020-12-04 21:48:00.029567+00
(1 row)
```

Para obter mais informações, consulte [Tabelas para agendar trabalhos e capturar status](#PostgreSQL_pg_cron.tables).

### Limpar a tabela de histórico de pg\$1cron
<a name="PostgreSQL_pg_cron.job_run_details"></a>

A tabela `cron.job_run_details` contém um histórico de trabalhos cron que podem se tornar muito grandes ao longo do tempo. Recomendamos que você agende um trabalho que limpe essa tabela. Por exemplo, manter uma semana de registros pode ser suficiente para fins de solução de problemas. 

O exemplo a seguir usa a função [cron.schedule](#PostgreSQL_pg_cron.schedule) para agendar um trabalho que é executado todos os dias à meia-noite para limpar a tabela `cron.job_run_details`. O trabalho mantém apenas os últimos sete dias. Use sua `rds_superuser` para agendar o trabalho da seguinte forma.

```
SELECT cron.schedule('0 0 * * *', $$DELETE 
    FROM cron.job_run_details 
    WHERE end_time < now() - interval '7 days'$$);
```

Para obter mais informações, consulte [Tabelas para agendar trabalhos e capturar status](#PostgreSQL_pg_cron.tables).

### Registrar em log erros somente no arquivo postgresql.log
<a name="PostgreSQL_pg_cron.log_run"></a>

Para impedir a gravação na tabela `cron.job_run_details`, modifique o grupo de parâmetros associado à instância de banco de dados do PostgreSQL e defina o parâmetro `cron.log_run` como desativado. A extensão `pg_cron` não gravará mais na tabela e vai capturar erros somente no arquivo `postgresql.log`. Para obter mais informações, consulte [Modificar parâmetros em um grupo de parâmetros de banco de dados no Amazon RDS](USER_WorkingWithParamGroups.Modifying.md). 

Use o comando a seguir para verificar o valor do parâmetro `cron.log_run`.

```
postgres=> SHOW cron.log_run;
```

Para obter mais informações, consulte [Parâmetros para gerenciar a extensão pg\$1cron](#PostgreSQL_pg_cron.parameters).

### Agendar um trabalho cron para um banco de dados diferente do banco de dados padrão
<a name="PostgreSQL_pg_cron.otherDB"></a>

Os metadados para `pg_cron` são todos mantidos no banco de dados padrão PostgreSQL chamado `postgres`. Como os operadores em segundo plano são usados para executar os trabalhos cron de manutenção, você pode agendar um trabalho em qualquer um dos seus bancos de dados dentro da instância de banco de dados do PostgreSQL.

**nota**  
Somente usuários com o perfil `rds_superuser` ou privilégios `rds_superuser` podem listar todos os trabalhos cron no banco de dados. Outros usuários podem visualizar somente seus próprios trabalhos na tabela `cron.job`.

1. No banco de dados cron, agende o trabalho como você normalmente faria usando a [cron.schedule](#PostgreSQL_pg_cron.schedule).

   ```
   postgres=> SELECT cron.schedule('database1 manual vacuum', '29 03 * * *', 'vacuum freeze test_table');
   ```

1. Como um usuário com a função `rds_superuser`, atualize a coluna do banco de dados para o trabalho que você acabou de criar para que ele seja executado em outro banco de dados dentro de sua instância de banco de dados do PostgreSQL.

   ```
   postgres=> UPDATE cron.job SET database = 'database1' WHERE jobid = 106;
   ```

1.  Verifique consultando a tabela `cron.job`.

   ```
   postgres=> SELECT * FROM cron.job;
   jobid | schedule    | command                        | nodename  | nodeport | database | username  | active | jobname
   ------+-------------+--------------------------------+-----------+----------+----------+-----------+--------+-------------------------
   106   | 29 03 * * * | vacuum freeze test_table       | localhost | 8192     | database1| adminuser | t      | database1 manual vacuum
     1   | 59 23 * * * | vacuum freeze pgbench_accounts | localhost | 8192     | postgres | adminuser | t      | manual vacuum
   (2 rows)
   ```

**nota**  
Em algumas situações, você pode adicionar um cron job que você pretende executar em um banco de dados diferente. Nesses casos, o job pode tentar executar no banco de dados padrão (`postgres`) antes de atualizar a coluna correta do banco de dados. Se o nome de usuário tiver permissões, o trabalho será executado com êxito no banco de dados padrão.

## Referência para a extensão pg\$1cron
<a name="PostgreSQL_pg_cron.reference"></a>

Você pode usar os seguintes parâmetros, funções e tabelas com a extensão `pg_cron`. Para obter mais informações, consulte [O que é pg\$1cron?](https://github.com/citusdata/pg_cron) na documentação do pg\$1cron.

**Topics**
+ [

### Parâmetros para gerenciar a extensão pg\$1cron
](#PostgreSQL_pg_cron.parameters)
+ [

### Referência da função: cron.schedule
](#PostgreSQL_pg_cron.schedule)
+ [

### Referência da função: cron.schedule
](#PostgreSQL_pg_cron.unschedule)
+ [

### Tabelas para agendar trabalhos e capturar status
](#PostgreSQL_pg_cron.tables)

### Parâmetros para gerenciar a extensão pg\$1cron
<a name="PostgreSQL_pg_cron.parameters"></a>

Veja a seguir uma lista de parâmetros que controlam o comportamento da extensão `pg_cron`. 


| Parâmetro | Descrição | 
| --- | --- | 
| cron.database\$1name |  O banco de dados em que os metadados de `pg_cron` são mantidos.  | 
| cron.host |  O nome do host para se conectar ao PostgresSQL. Não é possível modificar esse valor.  | 
| cron.log\$1run |  Registre todos os trabalhos executados na tabela `job_run_details`. Os valores são `on` ou `off`. Para obter mais informações, consulte [Tabelas para agendar trabalhos e capturar status](#PostgreSQL_pg_cron.tables).  | 
| cron.log\$1statement |  Registre todas as instruções cron antes de executá-las. Os valores são `on` ou `off`.  | 
| cron.max\$1running\$1jobs |  O número máximo de trabalhos que podem ser executados simultaneamente.  | 
| cron.use\$1background\$1workers |  Use trabalhadores em segundo plano em vez de sessões de cliente. Não é possível modificar esse valor.  | 

Use o seguinte comando SQL para exibir esses parâmetros e seus valores.

```
postgres=> SELECT name, setting, short_desc FROM pg_settings WHERE name LIKE 'cron.%' ORDER BY name;
```

### Referência da função: cron.schedule
<a name="PostgreSQL_pg_cron.schedule"></a>

Essa função agenda um trabalho cron. Inicialmente, o trabalho é agendado no banco de dados `postgres` padrão. A função retorna um valor `bigint` que representa o identificador de trabalho. Para agendar trabalhos a serem executados em outros bancos de dados em sua instância de banco de dados PostgreSQL, consulte o exemplo em [Agendar um trabalho cron para um banco de dados diferente do banco de dados padrão](#PostgreSQL_pg_cron.otherDB).

A função tem dois formatos de sintaxe.

**Sintaxe**  

```
cron.schedule (job_name,
    schedule,
    command
);

cron.schedule (schedule,
    command
);
```

**Parâmetros**      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)

**Exemplos**  

```
postgres=> SELECT cron.schedule ('test','0 10 * * *', 'VACUUM pgbench_history');
 schedule
----------
      145
(1 row)

postgres=> SELECT cron.schedule ('0 15 * * *', 'VACUUM pgbench_accounts');
 schedule
----------
      146
(1 row)
```

### Referência da função: cron.schedule
<a name="PostgreSQL_pg_cron.unschedule"></a>

Esta função exclui um trabalho cron. Você pode especificar `job_name` ou `job_id`. Uma política garante que você seja o proprietário para remover a programação do trabalho. A função retorna um booleano indicando êxito ou falha.

A função tem os seguintes formatos de sintaxe.

**Sintaxe**  

```
cron.unschedule (job_id);

cron.unschedule (job_name);
```

**Parâmetros**      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html)

**Exemplos**  

```
postgres=> SELECT cron.unschedule(108);
 unschedule
------------
 t
(1 row)

postgres=> SELECT cron.unschedule('test');
 unschedule
------------
 t
(1 row)
```

### Tabelas para agendar trabalhos e capturar status
<a name="PostgreSQL_pg_cron.tables"></a>

As tabelas a seguir são usadas para agendar os trabalhos cron e registrar como os trabalhos foram concluídos. 


| Tabela | Descrição | 
| --- | --- | 
| cron.job |  Contém os metadados sobre cada trabalho agendado. A maioria das interações com esta tabela deve ser feita por meio das funções `cron.schedule` e `cron.unschedule`.  Não recomendamos conceder privilégios de atualização ou inserção diretamente a essa tabela. Isso permitiria que o usuário atualizasse a coluna `username` para ser executada como `rds-superuser`.   | 
| cron.job\$1run\$1details |  Contém informações históricas sobre trabalhos agendados passados que foram executados. Isso é útil para investigar o status, as mensagens de retorno e as horas de início e término do trabalho executado.  Para evitar que esta tabela cresça indefinidamente, purgue-a regularmente. Para ver um exemplo, consulte [Limpar a tabela de histórico de pg\$1cron](#PostgreSQL_pg_cron.job_run_details).   | 

# Usar pglogical para sincronizar dados entre instâncias
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical"></a>

Todas as versões do RDS para PostgreSQL atualmente disponíveis são compatíveis com a extensão `pglogical`. A extensão pglogical é anterior ao recurso de replicação lógica funcionalmente similar que foi introduzido pelo PostgreSQL na versão 10. Para obter mais informações, consulte [Executar replicação lógica para o Amazon RDS para PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.LogicalReplication.md).

A extensão `pglogical` é compatível com a replicação lógica entre dois ou mais Instâncias de banco de dados do RDS para PostgreSQL. Ela também é compatível com a replicação entre diferentes versões do PostgreSQL e entre bancos de dados executados em instâncias de banco de dados RDS para PostgreSQL e clusters de banco de dados Aurora PostgreSQL. A extensão `pglogical` usa um modelo de publicação e assinatura para replicar alterações em tabelas e outros objetos, como sequências, de um editor para um assinante. Ela depende de um slot de replicação para garantir que as alterações sejam sincronizadas de um nó do editor para um nó assinante, definido da seguinte forma. 
+ O *nó do editor* é a instância de banco de dados RDS para PostgreSQL, que é a fonte de dados a serem replicados para outros nós. O nó do editor define as tabelas a serem replicadas em um conjunto de publicações. 
+ O *nó do assinante* é a instância de banco de dados Aurora PostgreSQL que recebe atualizações WAL do editor. O assinante cria uma assinatura para se conectar ao editor e obter os dados WAL decodificados. Quando o assinante cria a assinatura, o slot de replicação é criado no nó do editor. 

Depois, você pode encontrar informações sobre a configuração da extensão `pglogical`. 

**Topics**
+ [

## Requisitos e limitações da extensão pglogical
](#Appendix.PostgreSQL.CommonDBATasks.pglogical.requirements-limitations)
+ [

# Configurar a extensão pglogical
](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md)
+ [

# Configurar a replicação lógica para a instância de banco de dados RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.pglogical.setup-replication.md)
+ [

# Restabelecer a replicação lógica após uma atualização principal
](Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.md)
+ [

# Gerenciar slots de replicação lógica para o RDS for PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md)
+ [

# Referência de parâmetros da extensão pglogical
](Appendix.PostgreSQL.CommonDBATasks.pglogical.reference.md)

## Requisitos e limitações da extensão pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.requirements-limitations"></a>

Todas as versões atualmente disponíveis do RDS para PostgreSQL são compatíveis com a extensão `pglogical`. 

Tanto o nó do editor quanto o do assinante devem estar configurados para replicação lógica.

As tabelas que você deseja replicar de um publicador para um assinante devem ter os mesmos nomes e o mesmo esquema. Essas tabelas também devem conter as mesmas colunas, e as colunas devem usar os mesmos tipos de dados. As tabelas de editores e assinantes devem ter as mesmas chaves primárias. Recomendamos que você use somente a CHAVE PRIMÁRIA como restrição exclusiva.

As tabelas no nó do assinante podem ter mais restrições permissivas do que as do nó do editor para restrições CHECK e NOT NULL. 

A extensão `pglogical` fornece recursos como replicação bidirecional que não são compatíveis com o recurso de replicação lógica incorporado ao PostgreSQL (versão 10 e superior). Para obter mais informações, consulte [PostgreSQL bi-directional replication using pglogical](https://aws.amazon.com/blogs/database/postgresql-bi-directional-replication-using-pglogical/) (Replicação bidirecional do PostgreSQL usando pglogical).

# Configurar a extensão pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup"></a>

Para configurar a extensão `pglogical` em sua instância de banco de dados RDS para PostgreSQL , adicione `pglogical` às bibliotecas compartilhadas no grupo de parâmetros de banco de dados personalizado para sua instância de banco de dados RDS para PostgreSQL. Você também precisa definir o valor do parâmetro `rds.logical_replication` como `1`, para ativar a decodificação lógica. Finalmente, você cria a extensão no banco de dados. Você pode usar o Console de gerenciamento da AWS ou a AWS CLI para essas tarefas. 

Você deve ter permissões como a função `rds_superuser` para realizar essas tarefas.

As etapas a seguir pressupõem que a instância de banco de dados do RDS para PostgreSQL está associada a um grupo de parâmetros de banco de dados. Para obter informações sobre como criar um grupo de parâmetros de banco de dados, consulte [Grupos de parâmetros para Amazon RDS](USER_WorkingWithParamGroups.md).

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

**Como configurar a extensão pglogical**

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, selecione sua instância de banco de dados do RDS para PostgreSQL.

1. Abra a guia **Configuration** (Configuração) para sua Instância de banco de dados do RDS para PostgreSQL. Entre os detalhes da instância, encontre o link **Parameter group** (Grupo de parâmetros). 

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

1. No campo **Parâmetros**, digite `shared_pre` para encontrar o parâmetro `shared_preload_libraries`.

1. Selecione **Edit parameters** (Editar parâmetros) para acessar os valores das propriedades.

1. Adicione `pglogical` à lista no campo **Values** (Valores). Use uma vírgula para separar itens na lista de valores.   
![\[Imagem do parâmetro shared_preload_libraries com pglogical adicionada.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/apg_rpg_shared_preload_pglogical.png)

1. Encontre o parâmetro `rds.logical_replication` e defina-o como `1` para ativar a replicação lógica.

1. Reinicialize a instância de banco de dados do RDS para PostgreSQL para que suas alterações tenham efeito. 

1. Quando a instância estiver disponível, você poderá usar `psql` (ou pgAdmin) para se conectar à instância de banco de dados RDS para PostgreSQL. 

   ```
   psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Para verificar se pglogical foi inicializada, execute o comando a seguir.

   ```
   SHOW shared_preload_libraries;
   shared_preload_libraries 
   --------------------------
   rdsutils,pglogical
   (1 row)
   ```

1. Verifique a configuração que permite a decodificação lógica da forma a seguir.

   ```
   SHOW wal_level;
   wal_level
   -----------
    logical
   (1 row)
   ```

1. Crie a extensão da forma a seguir.

   ```
   CREATE EXTENSION pglogical;
   EXTENSION CREATED
   ```

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

1. Abra o console do Amazon RDS em [https://console.aws.amazon.com/rds/](https://console.aws.amazon.com/rds/).

1. Selecione a instância de banco de dados do RDS para PostgreSQL na lista de bancos de dados para selecioná-la e depois selecione **Reboot** (Reinicializar) no menu Actions (Ações).

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

**Como configurar a extensão pglogical**

Para configurar a pglogical usando a AWS CLI, chame 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 em seu grupo de parâmetros personalizado, conforme mostrado no procedimento a seguir.

1. Use o comando AWS CLI a seguir para adicionar `pglogical` ao parâmetro `shared_preload_libraries`.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=pglogical,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Use o comando AWS CLI a seguir para definir `rds.logical_replication` como `1` a fim de ativar o recurso de decodificação lógica para a Instância de banco de dados do RDS para PostgreSQL.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=rds.logical_replication,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 para que a biblioteca da pglogical seja inicializada.

   ```
   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=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Crie a extensão da forma a seguir.

   ```
   CREATE EXTENSION pglogical;
   EXTENSION CREATED
   ```

1. Reinicie a instância de banco de dados do RDS para PostgreSQL usando o comando AWS CLI a seguir.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

# Configurar a replicação lógica para a instância de banco de dados RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.setup-replication"></a>

O procedimento a seguir mostra como iniciar a replicação lógica entre duas instâncias de banco de dados RDS PostgreSQL. As etapas pressupõem que tanto a fonte (editor) quanto o destino (assinante) tenham a extensão `pglogical` configurada conforme detalhado em [Configurar a extensão pglogical](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md). 

**nota**  
O `node_name` de um nó assinante não pode começar com `rds`.

**Como criar o nó do editor e definir as tabelas a serem replicadas**

Estas etapas pressupõem que a instância de banco de dados do RDS para PostgreSQL tenha um banco de dados com uma ou mais tabelas que você deseja replicar para outro nó. Você precisa recriar a estrutura da tabela do editor no assinante, então, primeiro, obtenha a estrutura da tabela, se necessário. Você pode fazer isso usando o metacomando `psql` `\d tablename` e criando a mesma tabela na instância do assinante. O procedimento a seguir cria uma tabela de exemplo no editor (fonte) para fins de demonstração.

1. Use `psql` para se conectar à instância que tem a tabela que você deseja usar como fonte para assinantes. 

   ```
   psql --host=source-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

   Se você não tiver uma tabela, crie uma tabela de exemplo da forma a seguir.

   1. Crie uma tabela de exemplo usando a declaração SQL a seguir.

      ```
      CREATE TABLE docs_lab_table (a int PRIMARY KEY);
      ```

   1. Preencha a tabela com dados gerados usando a instrução SQL a seguir.

      ```
      INSERT INTO docs_lab_table VALUES (generate_series(1,5000));
      INSERT 0 5000
      ```

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

      ```
      SELECT count(*) FROM docs_lab_table;
      ```

1. Identifique essa instância de banco de dados do RDS para PostgreSQL como o nó do editor da forma a seguir.

   ```
   SELECT pglogical.create_node(
       node_name := 'docs_lab_provider',
       dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 dbname=labdb');
    create_node
   -------------
      3410995529
   (1 row)
   ```

1. Adicione a tabela que você deseja replicar ao conjunto de replicação padrão. Para obter mais informações sobre conjuntos de replicação, consulte [Replication sets](https://github.com/2ndQuadrant/pglogical/tree/REL2_x_STABLE/docs#replication-sets) (Conjuntos de replicação) na documentação da pglogical. 

   ```
   SELECT pglogical.replication_set_add_table('default', 'docs_lab_table', 'true', NULL, NULL);
    replication_set_add_table
     ---------------------------
     t
     (1 row)
   ```

A configuração do nó do editor está concluída. Agora você pode configurar o nó de assinante para receber as atualizações do editor.

**Como configurar o nó de assinante e criar uma assinatura para receber atualizações**

Estas etapas pressupõem que instância de banco de dados do RDS para PostgreSQL tenha sido configurada com a extensão `pglogical`. Para obter mais informações, consulte [Configurar a extensão pglogical](Appendix.PostgreSQL.CommonDBATasks.pglogical.basic-setup.md). 

1. Use `psql` para se conectar à instância em que você deseja receber atualizações do editor.

   ```
   psql --host=target-instance.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1.  Na instância de banco de dados RDS para PostgreSQL do assinante, crie a mesma tabela que existe no editor. Neste exemplo, a tabela é `docs_lab_table`. Você pode criar a tabela da seguinte maneira.

   ```
   CREATE TABLE docs_lab_table (a int PRIMARY KEY);
   ```

1. Verifique se essa tabela está vazia.

   ```
   SELECT count(*) FROM docs_lab_table;
    count
   -------
     0
   (1 row)
   ```

1. Identifique essa instância de banco de dados RDS para PostgreSQL como o nó do assinante da forma a seguir.

   ```
   SELECT pglogical.create_node(
       node_name := 'docs_lab_target',
       dsn := 'host=target-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=********');
    create_node
   -------------
      2182738256
   (1 row)
   ```

1. Crie a assinatura. 

   ```
   SELECT pglogical.create_subscription(
      subscription_name := 'docs_lab_subscription',
      provider_dsn := 'host=source-instance.aws-region.rds.amazonaws.com port=5432 sslmode=require dbname=labdb user=postgres password=*******',
      replication_sets := ARRAY['default'],
      synchronize_data := true,
      forward_origins := '{}' );  
    create_subscription
   ---------------------
   1038357190
   (1 row)
   ```

   Ao concluir essa etapa, os dados da tabela no editor são criados na tabela no assinante. Se você quiser verificar se isso ocorreu, verifique a consulta SQL a seguir.

   ```
   SELECT count(*) FROM docs_lab_table;
    count
   -------
     5000
   (1 row)
   ```

Desse ponto em diante, as alterações feitas na tabela do editor são replicadas na tabela do assinante.

# Restabelecer a replicação lógica após uma atualização principal
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade"></a>

Antes de realizar uma atualização de versão principal de uma instância de banco de dados do RDS para PostgreSQL que está sendo configurada como um nó de editor para replicação lógica, você deve eliminar todos os slots de replicação, mesmo aqueles que não estão ativos. Recomendamos que você desvie temporariamente as transações do banco de dados do nó do editor, elimine os slots de replicação, atualize a instância de banco de dados do RDS para PostgreSQL e, depois, restabeleça e reinicie a replicação.

Os slots de replicação são hospedados somente no nó do editor. O nó de assinante do RDS para PostgreSQL em um cenário de replicação lógica não tem slots a serem descartados, mas não pode ser atualizado para uma versão principal enquanto estiver designado como um nó de assinante com uma assinatura do editor. Antes de atualizar o nó de assinante do RDS para PostgreSQL, elimine a assinatura e o nó. Para obter mais informações, consulte [Gerenciar slots de replicação lógica para o RDS for PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots.md).  

## Determinar se a replicação lógica foi interrompida
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.recover-replication-after-upgrade.identifying-the-issue"></a>

Você pode determinar se o processo de replicação foi interrompido consultando o nó do editor ou o nó do assinante da forma a seguir.

**Como conferir o nó do editor**
+ Use `psql` para se conectar ao nó do editor e, depois, consultar a função `pg_replication_slots`. Observe o valor na coluna ativa. Normalmente, isso retornará `t` (true) mostrando que a replicação está ativa. Se a consulta retornar `f` (false), é uma indicação de que a replicação para o assinante foi interrompida. 

  ```
  SELECT slot_name,plugin,slot_type,active FROM pg_replication_slots;
                      slot_name              |      plugin      | slot_type | active
  -------------------------------------------+------------------+-----------+--------
   pgl_labdb_docs_labcb4fa94_docs_lab3de412c | pglogical_output | logical   | f
  (1 row)
  ```

**Como conferir o nó do assinante**

No nó do assinante, você pode conferir o status da replicação de três maneiras diferentes.
+ Examine os logs do PostgreSQL no nó do assinante para encontrar mensagens de falha. O log identifica falhas com mensagens que incluem o código de saída 1, conforme mostrado a seguir.

  ```
  2022-07-06 16:17:03 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 14610) exited with exit code 1
  2022-07-06 16:19:44 UTC::@:[7361]:LOG: background worker "pglogical apply 16404:2880255011" (PID 21783) exited with exit code 1
  ```
+ Consulte a função `pg_replication_origin`. Conecte-se ao banco de dados no nó do assinante usando `psql` e consulte a função `pg_replication_origin` da forma a seguir.

  ```
  SELECT * FROM pg_replication_origin;
   roident | roname
  ---------+--------
  (0 rows)
  ```

  O conjunto de resultados vazio significa que a replicação foi interrompida. Normalmente, você deve ver a saída da forma a seguir.

  ```
     roident |                       roname
    ---------+----------------------------------------------------
           1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
    (1 row)
  ```
+ Consulte a função `pglogical.show_subscription_status` conforme exibido no exemplo a seguir.

  ```
  SELECT subscription_name,status,slot_name FROM pglogical.show_subscription_status();
       subscription_name | status |              slot_name
  ---====----------------+--------+-------------------------------------
   docs_lab_subscription | down   | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
  (1 row)
  ```

  Essa saída mostra que a replicação foi interrompida. Seu status é `down`. Normalmente, a saída mostra o status como `replicating`.

Se seu processo de replicação lógica tiver sido interrompido, você poderá restabelecer a replicação seguindo estas etapas.

**Como restabelecer a replicação lógica entre os nós do editor e do assinante**

Para restabelecer a replicação, primeiro você desconecta o assinante do nó do editor e depois restabelece a assinatura, conforme descrito nestas etapas. 

1. Conecte-se ao nó do assinante usando `psql` da forma a seguir.

   ```
   psql --host=222222222222.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password --dbname=labdb
   ```

1. Desative a assinatura usando a função `pglogical.alter_subscription_disable`.

   ```
   SELECT pglogical.alter_subscription_disable('docs_lab_subscription',true);
    alter_subscription_disable
   ----------------------------
    t
   (1 row)
   ```

1. Obtenha o identificador do nó do editor consultando a `pg_replication_origin` da forma a seguir.

   ```
   SELECT * FROM pg_replication_origin;
    roident |               roname
   ---------+-------------------------------------
          1 | pgl_labdb_docs_labcb4fa94_docs_lab3de412c
   (1 row)
   ```

1. Use a resposta da etapa anterior com o comando `pg_replication_origin_create` para atribuir o identificador que pode ser usado pela assinatura quando restabelecida. 

   ```
   SELECT pg_replication_origin_create('pgl_labdb_docs_labcb4fa94_docs_lab3de412c');
     pg_replication_origin_create
   ------------------------------
                               1
   (1 row)
   ```

1. Ative a assinatura passando seu nome com um status de `true`, conforme exibido no exemplo a seguir.

   ```
   SELECT pglogical.alter_subscription_enable('docs_lab_subscription',true);
     alter_subscription_enable
   ---------------------------
    t
   (1 row)
   ```

Consulte o status do nó. Seu status deve ser `replicating` conforme mostrado neste exemplo.

```
SELECT subscription_name,status,slot_name
  FROM pglogical.show_subscription_status();
             subscription_name |   status    |              slot_name
-------------------------------+-------------+-------------------------------------
 docs_lab_subscription         | replicating | pgl_labdb_docs_lab98f517b_docs_lab3de412c
(1 row)
```

Confira o status do slot de replicação do assinante no nó do editor. A coluna `active` do slot deve retornar `t` (true), indicando que a replicação foi restabelecida.

```
SELECT slot_name,plugin,slot_type,active
  FROM pg_replication_slots;
                    slot_name              |      plugin      | slot_type | active
-------------------------------------------+------------------+-----------+--------
 pgl_labdb_docs_lab98f517b_docs_lab3de412c | pglogical_output | logical   | t
(1 row)
```

# Gerenciar slots de replicação lógica para o RDS for PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.handle-slots"></a>

Antes de realizar uma atualização de versão principal de uma uma instância de banco de dados do RDS para PostgreSQL que está atuando como um nó de editor em um cenário de replicação lógica, você deve eliminar os slots de replicação na instância. O processo de pré-conferência da atualização da versão principal notifica você de que a atualização não pode continuar até que os slots sejam eliminados.

Para eliminar slots da sua instância de banco de dados do RDS para PostgreSQL, primeiro cancele a assinatura e depois o slot. 

Para identificar os slots de replicação que foram criados usando a extensão `pglogical`, faça login em cada banco de dados e obtenha o nome dos nós. Ao consultar o nó do assinante, você obtém os nós do editor e do assinante na saída, conforme mostrado neste exemplo. 

```
SELECT * FROM pglogical.node;
node_id   |     node_name
------------+-------------------
 2182738256 | docs_lab_target
 3410995529 | docs_lab_provider
(2 rows)
```

Você pode obter os detalhes sobre a assinatura com a consulta a seguir.

```
SELECT sub_name,sub_slot_name,sub_target
  FROM pglogical.subscription;
 sub_name |         sub_slot_name          | sub_target
----------+--------------------------------+------------
  docs_lab_subscription     | pgl_labdb_docs_labcb4fa94_docs_lab3de412c | 2182738256
(1 row)
```

Agora você pode cancelar a assinatura da forma a seguir.

```
SELECT pglogical.drop_subscription(subscription_name := 'docs_lab_subscription');
 drop_subscription
-------------------
                 1
(1 row)
```

Depois de cancelar a assinatura, você pode excluir o nó.

```
SELECT pglogical.drop_node(node_name := 'docs-lab-subscriber');
 drop_node
-----------
 t
(1 row)
```

Você pode verificar se o nó não existe mais da forma a seguir.

```
SELECT * FROM pglogical.node;
 node_id | node_name
---------+-----------
(0 rows)
```

# Referência de parâmetros da extensão pglogical
<a name="Appendix.PostgreSQL.CommonDBATasks.pglogical.reference"></a>

Na tabela, você pode encontrar parâmetros associados à extensão `pglogical`. Parâmetros como `pglogical.conflict_log_level` e `pglogical.conflict_resolution` são usados para lidar com conflitos de atualização. Podem surgir conflitos quando alterações são feitas localmente nas mesmas tabelas que estão inscritas para receber alterações do editor. Os conflitos também podem ocorrer durante vários cenários, como replicação bidirecional ou quando vários assinantes estão se replicando do mesmo editor. Para obter mais informações, consulte [PostgreSQL bi-directional replication using pglogical](https://aws.amazon.com/blogs/database/postgresql-bi-directional-replication-using-pglogical/) (Replicação bidirecional do PostgreSQL usando pglogical). 


| Parameter | Descrição | 
| --- | --- | 
| pglogical.batch\$1inserts | Inserções em lote, se possível. Não definido por padrão. Mude para “1” para ativar, “0” para desativar. | 
| pglogical.conflict\$1log\$1level | Define o nível de log a ser usado para registrar em log conflitos resolvidos. Os valores de string compatíveis são debug5, debug4, debug3, debug2, debug1, info, notice, warning, error, log, fatal, panic. | 
| pglogical.conflict\$1resolution | Define o método a ser usado para resolver conflitos quando eles podem ser resolvidos. Os valores de string compatíveis são error, apply\$1remote, keep\$1local, last\$1update\$1wins, first\$1update\$1wins. | 
| pglogical.extra\$1connection\$1options | Opções de conexão para adicionar a todas as conexões de nó de pares. | 
| pglogical.synchronous\$1commit | Valor de confirmação síncrona específica do pglogical | 
| pglogical.use\$1spi | Use a SPI (interface de programação de servidores) em vez da API de baixo nível para aplicar alterações. Defina como “1” para ativar, “0” para desativar. Para obter mais informações sobre a SPI, consulte [Server Programming Interface](https://www.postgresql.org/docs/current/spi.html) (Interface de programação de servidores) na documentação do PostgreSQL.  | 

# 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);
```

# Reduzir o inchaço em tabelas e índices com a extensão pg\$1repack
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack"></a>

É possível usar a extensão `pg_repack` para remover a sobrecarga de tabelas e índices como uma alternativa a `VACUUM FULL`. Esta extensão é compatível com o RDS para PostgreSQL versões 9.6.3 e posteriores. Para ter mais informações sobre a extensão `pg_repack` e a recriação da tabela inteira, consulte a [documentação de projetos do GitHub](https://reorg.github.io/pg_repack/).

Ao contrário de `VACUUM FULL`, a extensão `pg_repack` requer um bloqueio exclusivo (AccessExclusiveLock) somente por um curto período durante a operação de recriação da tabela nos seguintes casos:
+ Criação inicial da tabela de logs: uma tabela de logs é criada para registrar as alterações que ocorrem durante a cópia inicial dos dados, conforme mostrado no seguinte exemplo: 

  ```
  postgres=>\dt+ repack.log_*
  List of relations
  -[ RECORD 1 ]-+----------
  Schema        | repack
  Name          | log_16490
  Type          | table
  Owner         | postgres
  Persistence   | permanent
  Access method | heap
  Size          | 65 MB
  Description   |
  ```
+ Fase final de troca e descarte.

Para o restante da operação de recriação, ela só precisa de um bloqueio `ACCESS SHARE` na tabela original para copiar as linhas dela para a nova tabela. Isso ajuda as operações INSERT, UPDATE e DELETE a prosseguir normalmente.

## Recomendações
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Recommen"></a>

As recomendações a seguir se aplicam ao remover a sobrecarga das tabelas e dos índices usando a extensão `pg_repack`:
+ Realize a recriação fora do horário comercial ou durante uma janela de manutenção para minimizar o impacto na performance de outras atividades do banco de dados.
+ Monitore atentamente as sessões de bloqueio durante a atividade de recriação e garanta que não haja nenhuma atividade na tabela original que possa bloquear `pg_repack`, especificamente durante a fase final de troca e descarte, quando ela precisa de um bloqueio exclusivo na tabela original. Para ter mais informações, consulte [Como identificar o que está bloqueando uma consulta](https://repost.aws/knowledge-center/rds-aurora-postgresql-query-blocked). 

  Ao ver uma sessão de bloqueio, é possível encerrá-la usando o comando a seguir após uma análise cuidadosa. Isso ajuda na continuação da `pg_repack` para concluir a recriação:

  ```
  SELECT pg_terminate_backend(pid);
  ```
+ Ao aplicar as alterações acumuladas da tabela de logs de `pg_repack's` em sistemas com uma taxa de transação muito alta, o processo de aplicação pode não ser capaz de acompanhar a taxa de alterações. Nesses casos, `pg_repack` não conseguiria concluir o processo de aplicação. Para obter mais informações, consulte [Monitorar a nova tabela durante a recriação](#Appendix.PostgreSQL.CommonDBATasks.pg_repack.Monitoring). Se os índices estiverem muito sobrecarregados, uma solução alternativa será realizar uma recriação somente de índices. Isso também ajuda os ciclos de limpeza do índice do VACUUM a terminar mais rapidamente.

  É possível ignorar a fase de limpeza do índice usando o VACUUM manual do PostgreSQL versão 12, e ela é ignorada automaticamente durante o autovacuum de emergência do PostgreSQL versão 14. Isso ajuda o VACUUM a ser concluído mais rapidamente sem remover a sobrecarga do índice e serve apenas para situações de emergência, como evitar o VACUUM de encapsulamento. Para ter mais informações, consulte [Evitar a sobrecarga nos índices](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html#AuroraPostgreSQL.diag-table-ind-bloat.AvoidinginIndexes) no Guia do usuário do Amazon Aurora.

## Pré-requisitos
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Prereq"></a>
+ A tabela deve ter PRIMARY KEY ou a restrição UNIQUE não nula.
+ A versão da extensão deve ser a mesma para o cliente e para o servidor.
+ Garanta que a instância do RDS tenha mais `FreeStorageSpace` do que o tamanho total da tabela sem a sobrecarga. Por exemplo, pense no tamanho total da tabela, incluindo TOAST e índices, como 2 TB, e a sobrecarga total na tabela, como 1 TB. O `FreeStorageSpace` necessário deve ser maior do que o valor exibido pelo seguinte cálculo:

   `2TB (Table size)` - `1TB (Table bloat)` = `1TB`

  É possível usar a consulta a seguir para conferir o tamanho total da tabela e usar `pgstattuple` para gerar a sobrecarga. Para ter mais informações, consulte [Diagnosticar a sobrecarga na tabela e no índice](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.diag-table-ind-bloat.html) no Guia do usuário do Amazon Aurora. 

  ```
  SELECT pg_size_pretty(pg_total_relation_size('table_name')) AS total_table_size;
  ```

  Esse espaço é recuperado após a conclusão da atividade. 
+ Garanta que a instância do RDS tenha capacidade computacional e de E/S suficientes para lidar com a operação de recriação. Pense na possibilidade de aumentar a escala da classe de instância verticalmente para conseguir o equilíbrio ideal de performance. 

**Como usar a extensão `pg_repack`**

1. Instale a extensão `pg_repack` na instância de banco de dados RDS for PostgreSQL executando o comando a seguir.

   ```
   CREATE EXTENSION pg_repack;
   ```

1. Execute os comandos a seguir para conceder acesso de gravação para recriar as tabelas de logs temporárias criadas pelo `pg_repack`.

   ```
   ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT INSERT ON TABLES TO PUBLIC;
   ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT USAGE, SELECT ON SEQUENCES TO PUBLIC;
   ```

1. Conecte-se ao banco de dados usando o utilitário de cliente `pg_repack`. Use uma conta que tenha privilégios `rds_superuser`. Como exemplo, suponha que a função `rds_test` tenha os privilégios `rds_superuser`. A sintaxe a seguir realiza a `pg_repack` para tabelas completas, incluindo todos os índices da tabela no banco de dados `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test -k postgres
   ```
**nota**  
É necessário se conectar usando a opção -k. Não há suporte para a opção -a.

   A resposta do cliente `pg_repack` fornece informações sobre as tabelas recriadas na instância de banco de dados.

   ```
   INFO: repacking table "pgbench_tellers"
   INFO: repacking table "pgbench_accounts"
   INFO: repacking table "pgbench_branches"
   ```

1. A sintaxe a seguir recria uma única tabela `orders` incluindo índices no banco de dados `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders -k postgres
   ```

   A sintaxe a seguir recria somente os índices da tabela `orders` no banco de dados `postgres`.

   ```
   pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders --only-indexes -k postgres
   ```

## Monitorar a nova tabela durante a recriação
<a name="Appendix.PostgreSQL.CommonDBATasks.pg_repack.Monitoring"></a>
+ O tamanho do banco de dados é aumentado pelo tamanho total da tabela menos a sobrecarga, até a fase de troca e descarte da recriação. É possível monitorar a taxa de crescimento do tamanho do banco de dados, calcular a velocidade da recriação e estimar aproximadamente o tempo necessário para concluir a transferência inicial dos dados.

  Por exemplo, pense no tamanho total da tabela como 2 TB, o tamanho do banco de dados como 4 TB e a sobrecarga total na tabela como 1 TB. O valor do tamanho total do banco de dados exibido pelo cálculo no final da operação de recriação é o seguinte:

   `2TB (Table size)` \$1 `4 TB (Database size)` - `1TB (Table bloat)` = `5TB`

  É possível calcular aproximadamente a velocidade da operação de recriação criando uma amostra da taxa de crescimento em bytes entre dois pontos no tempo. Se a taxa de crescimento for de 1 GB por minuto, poderá levar mil minutos ou 16,6 horas aproximadamente para concluir a operação inicial de criação da tabela. Além da criação inicial da tabela, a `pg_repack` também precisa aplicar as alterações acumuladas. O tempo necessário depende da taxa de aplicação das alterações em andamento, além das alterações acumuladas.
**nota**  
É possível usar a extensão `pgstattuple` para calcular a sobrecarga na tabela. Para ter mais informações, consulte [pgstattuple](https://www.postgresql.org/docs/current/pgstattuple.html).
+ O número de linhas na tabela de logs `pg_repack's`, no esquema de recriação, representa o volume de alterações pendentes para serem aplicadas à nova tabela após o carregamento inicial.

  É possível conferir a tabela de logs `pg_repack's` em `pg_stat_all_tables` para monitorar as alterações aplicadas à nova tabela. `pg_stat_all_tables.n_live_tup` indica o número de registros pendentes a serem aplicados à nova tabela. Para ter mais informações, consulte [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW). 

  ```
  postgres=>SELECT relname,n_live_tup FROM pg_stat_all_tables WHERE schemaname = 'repack' AND relname ILIKE '%log%';
          
  -[ RECORD 1 ]---------
  relname    | log_16490
  n_live_tup | 2000000
  ```
+ É possível usar a extensão `pg_stat_statements` para descobrir o tempo gasto em cada etapa da operação de recriação. Isso é útil na preparação para aplicar a mesma operação de recriação em um ambiente de produção. É possível ajustar a cláusula `LIMIT` para estender ainda mais a saída.

  ```
  postgres=>SELECT
       SUBSTR(query, 1, 100) query,
       round((round(total_exec_time::numeric, 6) / 1000 / 60),4) total_exec_time_in_minutes
   FROM
       pg_stat_statements
   WHERE
       query ILIKE '%repack%'
   ORDER BY
       total_exec_time DESC LIMIT 5;
          
   query                                                                 | total_exec_time_in_minutes
  -----------------------------------------------------------------------+----------------------------
   CREATE UNIQUE INDEX index_16493 ON repack.table_16490 USING btree (a) |                     6.8627
   INSERT INTO repack.table_16490 SELECT a FROM ONLY public.t1           |                     6.4150
   SELECT repack.repack_apply($1, $2, $3, $4, $5, $6)                    |                     0.5395
   SELECT repack.repack_drop($1, $2)                                     |                     0.0004
   SELECT repack.repack_swap($1)                                         |                     0.0004
  (5 rows)
  ```

A recriação é uma operação extraordinária, portanto, a tabela original não é afetada e não prevemos nenhum desafio inesperado que exija a recuperação da tabela original. Se a recriação falhar inesperadamente, você deverá inspecionar a causa do erro e resolvê-lo.

Depois que o problema for resolvido, descarte e recrie a extensão `pg_repack` no banco de dados em que a tabela existe e repita a etapa `pg_repack`. Além disso, a disponibilidade de recursos computacionais e a acessibilidade simultânea da tabela desempenham um papel crucial na conclusão oportuna da operação de recriação.

# Atualizar e usar a extensão PLV8
<a name="PostgreSQL.Concepts.General.UpgradingPLv8"></a>

O PLV8 é uma extensão de linguagem Javascript confiável para o PostgreSQL. Você pode usá-lo para procedimentos armazenados, gatilhos e outros códigos processuais que podem ser chamados do SQL. Essa extensão de idioma é compatível com todas as versões atuais do PostgreSQL. 

Se você usar o [PLV8](https://plv8.github.io/) e atualizar o PostgreSQL para uma nova versão do PLV8, você poderá aproveitar imediatamente a nova extensão. Tome as medidas a seguir para sincronizar os metadados do catálogo com a nova versão do PLV8. Estas etapas são opcionais, mas recomendamos fortemente que você as conclua para evitar avisos de incompatibilidade dos metadados.

O processo de atualização elimina todas as suas funções PLV8 existentes. Portanto, recomendamos que você crie um snapshot da sua instância de banco de dados do RDS para PostgreSQL antes de atualizar. Para obter mais informações, consulte [Criar um snapshot de banco de dados para uma instância de banco de dados single-AZ para o Amazon RDS](USER_CreateSnapshot.md).

**Importante**  
A partir da versão 18 do PostgreSQL, o Amazon RDS para PostgreSQL descontinuará as extensões `plcoffee` e `plls` do PostgreSQL. Recomendamos que você pare de usar o CoffeeScript e o LiveScript em suas aplicações para garantir um caminho de atualização para futuras atualizações de versão do mecanismo.

**Para sincronizar os metadados do catálogo com uma nova versão do PLV8**

1. Verifique se você precisa atualizar. Para fazer isso, execute o comando a seguir enquanto conectado à instância.

   ```
   SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee');
   ```

   Se os resultados contiverem valores para uma versão instalada que seja um número menor que a versão padrão, continue com este procedimento para atualizar suas extensões. Por exemplo, o seguinte conjunto de resultados indica que você deve atualizar.

   ```
   name    | default_version | installed_version |                     comment
   --------+-----------------+-------------------+--------------------------------------------------
   plls    | 2.1.0           | 1.5.3             | PL/LiveScript (v8) trusted procedural language
   plcoffee| 2.1.0           | 1.5.3             | PL/CoffeeScript (v8) trusted procedural language
   plv8    | 2.1.0           | 1.5.3             | PL/JavaScript (v8) trusted procedural language
   (3 rows)
   ```

1. Crie um snapshot da sua instância de banco de dados do RDS para PostgreSQL se você ainda não tiver feito isso. Você pode continuar com as seguintes etapas enquanto o snapshot estiver sendo criado. 

1. Obtenha uma contagem do número de funções do PLV8 em sua instância de banco de dados para que você possa confirmar se todas estão implementadas depois da atualização. Por exemplo, a consulta SQL a seguir retorna o número de funções gravadas em plv8, plcoffee e plls.

   ```
   SELECT proname, nspname, lanname 
   FROM pg_proc p, pg_language l, pg_namespace n
   WHERE p.prolang = l.oid
   AND n.oid = p.pronamespace
   AND lanname IN ('plv8','plcoffee','plls');
   ```

1. Use o pg\$1dump para criar um arquivo de despejo de somente esquema. Por exemplo, crie um arquivo na máquina do cliente no diretório `/tmp`.

   ```
   ./pg_dump -Fc --schema-only -U master postgres >/tmp/test.dmp
   ```

   Esse exemplo usa as seguintes opções: 
   + `-Fc`: formato personalizado
   + --schema-only: fará o despejo apenas dos comandos necessários para criar o esquema (funções em nosso caso)
   + `-U`: o nome do usuário mestre do RDS
   + `database`: o nome do banco de dados de nossa instância de banco de dados

   Para obter mais informações sobre pg\$1dump, consulte [pg\$1dump](https://www.postgresql.org/docs/current/static/app-pgdump.html ) na documentação do PostgreSQL.

1. Extraia a declaração DDL "CREATE FUNCTION" que está presente no arquivo de despejo. O exemplo a seguir usa o comando `grep` para extrair a instrução DDL que cria as funções e as salva em um arquivo. Use isso em etapas subsequentes para recriar as funções. 

   ```
   ./pg_restore -l /tmp/test.dmp | grep FUNCTION > /tmp/function_list
   ```

   Para obter mais informações sobre pg\$1restore, consulte [pg\$1restore](https://www.postgresql.org/docs/current/static/app-pgrestore.html) na documentação do PostgreSQL. 

1. Descarte as funções e as extensões. O exemplo a seguir descarta todos os objetos baseados em PLV8. A opção de cascata garante que qualquer dependente seja descartado.

   ```
   DROP EXTENSION plv8 CASCADE;
   ```

   Se sua instância do PostgreSQL contiver objetos baseados em plcoffee ou plls, repita essa etapa para essas extensões.

1. Crie as extensões. O exemplo a seguir cria as extensões plv8, plcoffee e plls.

   ```
   CREATE EXTENSION plv8;
   CREATE EXTENSION plcoffee;
   CREATE EXTENSION plls;
   ```

1. Crie as funções usando o arquivo de despejo e o arquivo do “driver”.

   O exemplo a seguir recria as funções que você extraiu anteriormente.

   ```
   ./pg_restore -U master -d postgres -Fc -L /tmp/function_list /tmp/test.dmp
   ```

1. Verifique se todas as suas funções foram recriadas usando a seguinte consulta. 

   ```
   SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee'); 
   ```

   A versão 2 do PLV8 adiciona a seguinte linha extra ao conjunto de resultados:

   ```
       proname    |  nspname   | lanname
   ---------------+------------+----------
    plv8_version  | pg_catalog | plv8
   ```

# Usar PL/Rust para escrever funções do PostgreSQL na linguagem Rust
<a name="PostgreSQL.Concepts.General.Using.PL_Rust"></a>

O PL/Rust é uma extensão de linguagem Rust confiável para o PostgreSQL. Você pode usá-lo para procedimentos armazenados, funções e outros códigos processuais que podem ser chamados do SQL. A extensão de linguagem PL/Rust está disponível nas seguintes versões:
+ RDS para PostgreSQL 17.1 e versões 17 posteriores
+ RDS para PostgreSQL 16.1 e versões 16 posteriores
+ RDS para PostgreSQL 15.2-R2 e versões 15 posteriores
+ RDS para PostgreSQL 14.9 e versões 14 posteriores
+ RDS para PostgreSQL 13.12 e versões 13 posteriores

Para obter mais informações, consulte [PL/Rust](https://github.com/tcdi/plrust#readme) no GitHub.

**Topics**
+ [

## Configurar o PL/Rust
](#PL_Rust-setting-up)
+ [

## Criar funções com o PL/Rust
](#PL_Rust-create-function)
+ [

## Usar caixas com PL/Rust
](#PL_Rust-crates)
+ [

## Limitações do PL/Rust
](#PL_Rust-limitations)

## Configurar o PL/Rust
<a name="PL_Rust-setting-up"></a>

Para instalar a extensão plrust da instância de banco de dados, adicione o plrust ao parâmetro `shared_preload_libraries` no grupo de parâmetros de banco de dados associado à instância de banco de dados. Com a extensão plrust instalada, é possível criar funções. 

Para modificar o parâmetro `shared_preload_libraries`, a instância de banco de dados deve estar associada a um grupo de parâmetros 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).

É possível instalar a extensão plrust usando o Console de gerenciamento da AWS ou a AWS CLI.

As etapas a seguir pressupõem que a instância de banco de dados esteja associada a um grupo de parâmetros de banco de dados personalizado.

### Console
<a name="PL_Rust-setting-up.CON"></a>

**Instalar a extensão plrust no parâmetro `shared_preload_libraries`**

Conclua as etapas a seguir usando uma conta que seja membro do grupo (perfil) `rds_superuser`.

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 **Bancos de dados**.

1. Escolha o nome da instância de banco de dados para mostrar os detalhes.

1. Abra a guia **Configuração** da instância de banco de dados e 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. 

1. No campo **Parâmetros**, digite `shared_pre` para encontrar o parâmetro **`shared_preload_libraries`**.

1. Selecione **Edit parameters** (Editar parâmetros) para acessar os valores das propriedades.

1. Adicione plrust à lista no campo **Valores**. Use uma vírgula para separar itens na lista de valores.

1. Reinicialize a instância de banco de dados para que a alteração no parâmetro `shared_preload_libraries` tenha efeito. A reinicialização inicial pode exigir mais tempo para ser concluída.

1. Quando a instância estiver disponível, verifique se plrust foi inicializado. Use `psql` para se conectar à instância de banco de dados e execute o comando a seguir.

   ```
   SHOW shared_preload_libraries;
   ```

   O resultado deve ser semelhante ao seguinte:

   ```
   shared_preload_libraries 
   --------------------------
   rdsutils,plrust
   (1 row)
   ```

### AWS CLI
<a name="PL_Rust-setting-up-CLI"></a>

**Instalar a extensão plrust no parâmetro shared\$1preload\$1libraries**

Conclua as etapas a seguir usando uma conta que seja membro do grupo (perfil) `rds_superuser`.

1. Utilize o comando [modify-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-parameter-group.html) da AWS CLI para adicionar plrust ao parâmetro `shared_preload_libraries`.

   ```
   aws rds modify-db-parameter-group \
      --db-parameter-group-name custom-param-group-name \
      --parameters "ParameterName=shared_preload_libraries,ParameterValue=plrust,ApplyMethod=pending-reboot" \
      --region aws-region
   ```

1. Use o comando [reboot-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/reboot-db-instance) da AWS CLI para reinicializar a instância de banco de dados e inicializar a biblioteca plrust. A reinicialização inicial pode exigir mais tempo para ser concluída.

   ```
   aws rds reboot-db-instance \
       --db-instance-identifier your-instance \
       --region aws-region
   ```

1. Quando a instância estiver disponível, é possível verificar se plrust foi inicializado. Use `psql` para se conectar à instância de banco de dados e execute o comando a seguir.

   ```
   SHOW shared_preload_libraries;
   ```

   O resultado deve ser semelhante ao seguinte:

   ```
   shared_preload_libraries
   --------------------------
   rdsutils,plrust
   (1 row)
   ```

## Criar funções com o PL/Rust
<a name="PL_Rust-create-function"></a>

O PL/Rust compilará a função como uma biblioteca dinâmica, a carregará e a executará.

A função do Rust a seguir filtra múltiplos de uma matriz.

```
postgres=> CREATE LANGUAGE plrust;
CREATE EXTENSION
```

```
CREATE OR REPLACE FUNCTION filter_multiples(a BIGINT[], multiple BIGINT) RETURNS BIGINT[]
    IMMUTABLE STRICT
    LANGUAGE PLRUST AS
$$
    Ok(Some(a.into_iter().filter(|x| x.unwrap() % multiple != 0).collect()))
$$;
        
WITH gen_values AS (
SELECT ARRAY(SELECT * FROM generate_series(1,100)) as arr)
SELECT filter_multiples(arr, 3)
from gen_values;
```

## Usar caixas com PL/Rust
<a name="PL_Rust-crates"></a>

No RDS para PostgreSQL versões 16.3-R2 e posterior, 15.7-R2 e versões 15 posteriores, 14.12-R2 e versões 14 posteriores e 13.15-R2 e versões 13 posteriores, o PL/Rust é compatível com caixas adicionais:
+ `url` 
+ `regex` 
+ `serde` 
+ `serde_json` 

No RDS para PostgreSQL versões 15.5-R2 e posterior, 14.10-R2 e versões 14 posteriores e 13.13-R2 e versões 13 posteriores, o PL/Rust é compatível com duas caixas adicionais:
+ `croaring-rs` 
+ `num-bigint` 

A partir das versões 15.4, 14.9 e 13.12 do Amazon RDS para PostgreSQL, o PL/Rust comporta as seguintes caixas:
+ `aes` 
+ `ctr` 
+ `rand` 

Somente os recursos padrão são comportados para essas caixas. As novas versões do RDS para PostgreSQL poderão conter versões de caixa atualizadas, ao passo que as mais antigas podem deixar de ter suporte.

Siga as práticas recomendadas para realizar uma atualização de versão principal e testar se suas funções do PL/Rust são compatíveis com a nova versão principal. Para obter mais informações, consulte a publicação de blog [Práticas recomendadas para atualizar o Amazon RDS para versões principais e secundárias do PostgreSQL](https://aws.amazon.com/blogs/database/best-practices-for-upgrading-amazon-rds-to-major-and-minor-versions-of-postgresql/) e [Atualizar o mecanismo de banco de dados PostgreSQL para Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_UpgradeDBInstance.PostgreSQL.html) no “Guia do usuário do Amazon RDS”. 

Exemplos de uso de dependências ao criar uma função PL/Rust estão disponíveis em [Usar dependências](https://tcdi.github.io/plrust/use-plrust.html#use-dependencies).

## Limitações do PL/Rust
<a name="PL_Rust-limitations"></a>

Por padrão, os usuários do banco de dados não podem usar PL/Rust. Para fornecer acesso ao PL/Rust, conecte-se como usuário com o privilégio rds\$1superuser e execute o seguinte comando:

```
postgres=> GRANT USAGE ON LANGUAGE PLRUST TO user;
```

# Gerenciar dados espaciais com a extensão PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS"></a>

PostGIS é uma extensão do PostgreSQL para armazenar e gerenciar informações espaciais. Para saber mais sobre a extensão PostGIS, consulte [Postgis.net](https://postgis.net/). 

Desde a versão 10.5, o PostgreSQL é compatível com a biblioteca libprotobuf 1.3.0 usada pelo PostGIS para trabalhar com dados de blocos vetoriais do Mapbox.

A configuração da extensão PostGIS exige privilégios `rds_superuser`. Recomendamos criar um usuário (perfil) para gerenciar a extensão PostGIS e os dados espaciais. A extensão PostGIS e seus componentes relacionados adicionam milhares de funções ao PostgreSQL. Considere criar a extensão PostGIS em seu próprio esquema se isso fizer sentido para o seu caso de uso. O exemplo a seguir mostra como instalar a extensão em seu próprio banco de dados, mas isso não é necessário.

**Topics**
+ [

## Etapa 1: Criar um usuário (função) para gerenciar a extensão PostGIS
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect)
+ [

## Etapa 2: Carregar as extensões PostGIS
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions)
+ [

## Etapa 3: Transferir a propriedade dos esquemas de extensão
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership)
+ [

## Etapa 4: Transferir a propriedade dos objetos PostGIS
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects)
+ [

## Etapa 5: Testar as extensões
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test)
+ [

## Etapa 6: Atualize a extensão PostGIS
](#Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update)
+ [Versões de extensão PostGIS](#CHAP_PostgreSQL.Extensions.PostGIS)
+ [Upgrade do PostGIS 2 para o PostGIS 3](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3)

## Etapa 1: Criar um usuário (função) para gerenciar a extensão PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Connect"></a>

Primeiro, conecte-se a uma instância de banco de dados do RDS para PostgreSQL como um usuário que tem privilégios `rds_superuser`. Se você manteve o nome padrão ao configurar a instância, se conectará como `postgres`. 

```
psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
```

Crie um perfil separado (usuário) para administrar a extensão PostGIS.

```
postgres=>  CREATE ROLE gis_admin LOGIN PASSWORD 'change_me';
CREATE ROLE
```

Conceda a esse perfil privilégios `rds_superuser` para permitir que ele instale a extensão.

```
postgres=> GRANT rds_superuser TO gis_admin;
GRANT
```

Crie um banco de dados a ser usado para seus artefatos PostGIS. Esta etapa é opcional. Como alternativa, você pode criar um esquema em seu banco de dados de usuário para as extensões PostGIS, mas isso também não é necessário.

```
postgres=> CREATE DATABASE lab_gis;
CREATE DATABASE
```

Conceda a `gis_admin` todos os privilégios no banco de dados `lab_gis`.

```
postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_gis TO gis_admin;
GRANT
```

Saia da sessão e reconecte-se a uma instância de banco de dados do RDS para PostgreSQL como `gis_admin`.

```
postgres=> psql --host=111122223333.aws-region.rds.amazonaws.com --port=5432 --username=gis_admin --password --dbname=lab_gis
Password for user gis_admin:...
lab_gis=>
```

Continue a configurar a extensão conforme detalhado nas próximas etapas.

## Etapa 2: Carregar as extensões PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.LoadExtensions"></a>

A extensão PostGIS inclui várias extensões relacionadas que funcionam juntas para fornecer funcionalidade geoespacial. Dependendo do seu caso de uso, talvez você não precise de todas as extensões criadas nesta etapa. 

Use instruções `CREATE EXTENSION` para carregar as extensões PostGIS. 

```
CREATE EXTENSION postgis;
CREATE EXTENSION
CREATE EXTENSION postgis_raster;
CREATE EXTENSION
CREATE EXTENSION fuzzystrmatch;
CREATE EXTENSION
CREATE EXTENSION postgis_tiger_geocoder;
CREATE EXTENSION
CREATE EXTENSION postgis_topology;
CREATE EXTENSION
CREATE EXTENSION address_standardizer_data_us;
CREATE EXTENSION
```

É possível verificar os resultados executando a consulta SQL mostrada no exemplo a seguir, que lista as extensões e seus proprietários. 

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;
List of schemas
     Name     |   Owner
--------------+-----------
 public       | postgres
 tiger        | rdsadmin
 tiger_data   | rdsadmin
 topology     | rdsadmin
(4 rows)
```

## Etapa 3: Transferir a propriedade dos esquemas de extensão
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferOwnership"></a>

Use as instruções ALTER SCHEMA para transferir a propriedade dos esquemas à função `gis_admin`.

```
ALTER SCHEMA tiger OWNER TO gis_admin;
ALTER SCHEMA
ALTER SCHEMA tiger_data OWNER TO gis_admin; 
ALTER SCHEMA
ALTER SCHEMA topology OWNER TO gis_admin;
ALTER SCHEMA
```

Se você quiser confirmar a alteração de propriedade, realize a consulta SQL a seguir. Ou é possível usar o metacomando `\dn` na linha de comando do psql. 

```
SELECT n.nspname AS "Name",
  pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
  FROM pg_catalog.pg_namespace n
  WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
  ORDER BY 1;

       List of schemas
     Name     |     Owner
--------------+---------------
 public       | postgres
 tiger        | gis_admin
 tiger_data   | gis_admin
 topology     | gis_admin
(4 rows)
```

## Etapa 4: Transferir a propriedade dos objetos PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.TransferObjects"></a>

**nota**  
Não altere a propriedade das funções do PostGIS. A operação adequada e as futuras atualizações do PostGIS exigem que essas funções retenham a propriedade original. Para ter mais informações sobre permissões do PostGIS, consulte [Segurança do PostgreSQL](https://postgis.net/workshops/postgis-intro/security.html).

Use a seguinte função para transferir a propriedade das tabelas do PostGIS ao perfil `gis_admin`. Execute a seguinte instrução no prompt psql para criar a função.

```
CREATE FUNCTION exec(text) returns text language plpgsql volatile AS $f$ BEGIN EXECUTE $1; RETURN $1; END; $f$;
CREATE FUNCTION
```

Depois, execute a consulta a seguir para executar a função `exec` que, por sua vez, executa as instruções e altera as permissões.

```
SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' || quote_ident(s.relname) || ' OWNER TO gis_admin;')
  FROM (
    SELECT nspname, relname
    FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
    WHERE nspname in ('tiger','topology') AND
    relkind IN ('r','S','v') ORDER BY relkind = 'S')
s;
```

## Etapa 5: Testar as extensões
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Test"></a>

Para evitar a necessidade de especificar o nome do esquema, adicione o esquema `tiger` ao seu caminho de pesquisa usando o seguinte comando.

```
SET search_path=public,tiger;
SET
```

Teste o esquema `tiger` usando a seguinte instrução SELECT.

```
SELECT address, streetname, streettypeabbrev, zip
 FROM normalize_address('1 Devonshire Place, Boston, MA 02109') AS na;
address | streetname | streettypeabbrev |  zip
---------+------------+------------------+-------
       1 | Devonshire | Pl               | 02109
(1 row)
```

Para saber mais sobre essa extensão, consulte [Geocodificador Tiger](https://postgis.net/docs/Extras.html#Tiger_Geocoder) na documentação do PostGIS. 

Teste o acesso ao esquema `topology` usando a seguinte instrução `SELECT`. Isso chama a função `createtopology` para registrar um novo objeto de topologia (my\$1new\$1topo) com o identificador de referência espacial especificado (26986) e a tolerância padrão (0,5). Para saber mais, consulte [CreateTopology](https://postgis.net/docs/CreateTopology.html) na documentação do PostGIS. 

```
SELECT topology.createtopology('my_new_topo',26986,0.5);
 createtopology
----------------
              1
(1 row)
```

## Etapa 6: Atualize a extensão PostGIS
<a name="Appendix.PostgreSQL.CommonDBATasks.PostGIS.Update"></a>

Cada nova versão do PostgreSQL oferece suporte a uma ou mais versões da extensão PostGIS compatíveis com essa versão. A atualização do mecanismo PostgreSQL para uma nova versão não atualiza automaticamente a extensão PostGIS. Antes de atualizar o mecanismo PostgreSQL, faça upgrade do PostGIS para a versão mais recente disponível para a versão atual do PostgreSQL. Para obter detalhes, consulte [Versões de extensão PostGIS](#CHAP_PostgreSQL.Extensions.PostGIS). 

Após a atualização do mecanismo PostgreSQL, faça upgrade da extensão PostGIS novamente, desta vez para a versão compatível com a versão recém-atualizada do mecanismo PostgreSQL. Para obter mais informações sobre como fazer upgrade do mecanismo PostgreSQL, consulte [Como atualizar a versão principal do RDS para PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md). 

Você pode verificar as atualizações de versão da extensão PostGIS disponíveis na sua instância de banco de dados do RDS para PostgreSQL a qualquer momento. Para fazer isso, execute o comando a seguir. Esta função está disponível com PostGIS 2.5.0 e versões posteriores.

```
SELECT postGIS_extensions_upgrade();
```

Se a sua aplicação não oferecer suporte à versão mais recente do PostGIS, você poderá instalar uma versão mais antiga do PostGIS que esteja disponível na sua versão principal conforme o exposto a seguir.

```
CREATE EXTENSION postgis VERSION "2.5.5";
```

Se quiser fazer upgrade para uma versão específica do PostGIS usando uma versão mais antiga, também poderá usar o comando a seguir.

```
ALTER EXTENSION postgis UPDATE TO "2.5.5";
```

Dependendo de sua versão atual antes do upgrade, talvez você precise usar essa função novamente. O resultado da primeira execução da função determina a necessidade de uma função de atualização adicional. Por exemplo, isso acontece em caso de upgrade do PostGIS 2 para o PostGIS 3. Para obter mais informações, consulte [Upgrade do PostGIS 2 para o PostGIS 3](#PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3).

Se você atualizou essa extensão para se preparar para uma atualização da versão principal do mecanismo PostgreSQL, poderá continuar com outras tarefas preliminares. Para obter mais informações, consulte [Como atualizar a versão principal do RDS para PostgreSQL](USER_UpgradeDBInstance.PostgreSQL.MajorVersion.Process.md). 

## Versões de extensão PostGIS
<a name="CHAP_PostgreSQL.Extensions.PostGIS"></a>

Recomendamos que você instale as versões de todas as extensões, como PostGIS, conforme listado em [“Extension versions for Amazon RDS para PostgreSQL”](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html) (Versões de extensões para o Amazon RDS para PostgreSQL) nas *Notas de lançamento do Amazon RDS para PostgreSQL.* Você pode conferir quais versões estão disponíveis na sua versão usando o comando a seguir.

```
SELECT * FROM pg_available_extension_versions WHERE name='postgis';
```

Informações sobre versões estão disponíveis nas seções a seguir das *Notas de lançamento do Amazon RDS para PostgreSQL*:
+ [ Extensões do PostgreSQL versão 16 compatíveis com o Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-16x)
+ [ Extensões do PostgreSQL versão 15 compatíveis com o Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-15x)
+ [ Extensões do PostgreSQL versão 14 compatíveis com o Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-14x)
+ [ Extensões do PostgreSQL versão 13 compatíveis com o Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-13x)
+ [ Extensões do PostgreSQL versão 12 compatíveis com o Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-12x)
+ [ Extensões do PostgreSQL versão 11 compatíveis com o Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-11x)
+ [ Extensões do PostgreSQL versão 10 compatíveis com o Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-101x)
+ [ Extensões do PostgreSQL versão 9.6.x compatíveis com o Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html#postgresql-extensions-96x)

## Upgrade do PostGIS 2 para o PostGIS 3
<a name="PostgreSQL.Extensions.PostGIS.versions.upgrading.2-to-3"></a>

A partir da versão 3.0, a funcionalidade de rasterização do PostGIS é uma extensão separada, `postgis_raster`. Essa extensão tem seu próprio caminho de instalação e upgrade. Isso remove dezenas de funções, tipos de dados e outros artefatos necessários para o processamento de imagens rasterizadas da extensão `postgis` principal. Isso significa que, se o seu caso de uso não exigir processamento de rasterização, você não precisará instalar a extensão `postgis_raster`.

No exemplo de upgrade a seguir, o primeiro comando de upgrade extrai a funcionalidade de rasterização na extensão `postgis_raster`. Um segundo comando de upgrade é necessário para atualizar `postgis_raster` para a nova versão.

**Como fazer upgrade do PostGIS 2 para o PostGIS 3**

1. Identifique a versão padrão do PostGIS que está disponível para a versão do PostgreSQL em seu Instância de banco de dados do RDS para PostgreSQL. Para fazer isso, execute a consulta a seguir.

   ```
   SELECT * FROM pg_available_extensions
       WHERE default_version > installed_version;
     name   | default_version | installed_version |                          comment
   ---------+-----------------+-------------------+------------------------------------------------------------
    postgis | 3.1.4           | 2.3.7             | PostGIS geometry and geography spatial types and functions
   (1 row)
   ```

1. Identifique as versões do PostGIS instaladas em cada banco de dados na sua instância de banco de dados do RDS para PostgreSQL. Em outras palavras, consulte cada banco de dados do usuário da seguinte forma.

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
       AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
     Name   | Version | Schema |                             Description
   ---------+---------+--------+---------------------------------------------------------------------
    postgis | 2.3.7   | public | PostGIS geometry, geography, and raster spatial types and functions
   (1 row)
   ```

   Essa divergência entre a versão padrão (PostGIS 3.1.4) e a versão instalada (PostGIS 2.3.7) significa que você precisa atualizar a extensão PostGIS.

   ```
   ALTER EXTENSION postgis UPDATE;
   ALTER EXTENSION
   WARNING: unpackaging raster
   WARNING: PostGIS Raster functionality has been unpackaged
   ```

1. Execute a consulta a seguir para verificar se a funcionalidade de rasterização já está em seu próprio pacote.

   ```
   SELECT
       probin,
       count(*)
   FROM
       pg_proc
   WHERE
       probin LIKE '%postgis%'
   GROUP BY
       probin;
             probin          | count
   --------------------------+-------
    $libdir/rtpostgis-2.3    | 107
    $libdir/postgis-3        | 487
   (2 rows)
   ```

   O resultado mostra que ainda há uma diferença entre as versões. As funções do PostGIS são da versão 3 (postgis-3), enquanto as funções de rasterização (rtpostgis) são da versão 2 (rtpostgis-2.3). Para concluir a atualização, execute o comando de upgrade novamente, da seguinte forma.

   ```
   postgres=> SELECT postgis_extensions_upgrade();
   ```

   Você pode ignorar as mensagens de aviso. Execute a consulta a seguir novamente para verificar se a atualização foi concluída. A atualização é concluída quando o PostGIS e todas as extensões relacionadas deixam de estar sinalizadas como necessitando de atualização. 

   ```
   SELECT postgis_full_version();
   ```

1. Use a consulta a seguir para ver o processo de atualização concluído e as extensões empacotadas separadamente, e verifique se as versões correspondem. 

   ```
   SELECT
       e.extname AS "Name",
       e.extversion AS "Version",
       n.nspname AS "Schema",
       c.description AS "Description"
   FROM
       pg_catalog.pg_extension e
       LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace
       LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid
           AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass
   WHERE
       e.extname LIKE '%postgis%'
   ORDER BY
       1;
         Name      | Version | Schema |                             Description
   ----------------+---------+--------+---------------------------------------------------------------------
    postgis        | 3.1.5   | public | PostGIS geometry, geography, and raster spatial types and functions
    postgis_raster | 3.1.5   | public | PostGIS raster types and functions
   (2 rows)
   ```

   A saída mostra que a extensão PostGIS 2 foi atualizada para PostGIS 3, e tanto `postgis` quanto a extensão `postgis_raster` agora separada estão na versão 3.1.5.

Depois que essa atualização for concluída, se você não planejar usar a funcionalidade de rasterização, poderá descartar a extensão da seguinte forma.

```
DROP EXTENSION postgis_raster;
```