

# Tarefas comuns de DBA do Amazon RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks"></a>

Os administradores de banco de dados (DBAs) executam várias tarefas ao administrar uma instância de banco de dados Amazon RDS para PostgreSQL. Se você já é um DBA familiarizado com o PostgreSQL, esteja ciente sobre algumas das diferenças importantes entre a execução do PostgreSQL em seu hardware e do RDS para PostgreSQL. Por exemplo, por ser um serviço gerenciado, o Amazon RDS não permite acesso ao shell às suas instâncias de banco de dados. Isso significa que você não tem acesso direto a `pg_hba.conf` e a outros arquivos de configuração. Para o RDS para PostgreSQL, as alterações que normalmente são feitas no arquivo de configuração do PostgreSQL de uma instância on-premises são feitas em um grupo de parâmetros de banco de dados personalizado associado à instância de banco de dados do RDS para PostgreSQL. Para ter mais informações, consulte [Grupos de parâmetros para Amazon RDS](USER_WorkingWithParamGroups.md).

Você também não pode acessar arquivos de log da mesma forma que faz com uma instância do PostgreSQL on-premises. Para saber mais sobre registro em log, consulte [Arquivos de log do banco de dados RDS para PostgreSQL](USER_LogAccess.Concepts.PostgreSQL.md).

Como outro exemplo, não é possível ter acesso à conta `superuser` do PostgreSQL. No RDS para PostgreSQL, o perfil `rds_superuser` é o perfil mais privilegiado, e é concedido ao `postgres` ao configurar. Se você estiver familiarizado com o uso do PostgreSQL on-premises ou for completamente novo no RDS para PostgreSQL, recomendamos que você entenda o perfil `rds_superuser` e como trabalhar com perfis, usuários, grupos e permissões. Para ter mais informações, consulte[Noções básicas de perfis e permissões do PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Roles.md)

Veja a seguir algumas tarefas comuns do DBA para o RDS para PostgreSQL.

**Topics**
+ [

# Agrupamentos permitidos no RDS para PostgreSQL.
](PostgreSQL-Collations.md)
+ [

# Noções básicas de perfis e permissões do PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Roles.md)
+ [

# Tratamento de conexões inativas no PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.md)
+ [

# Trabalhar com o autovacuum do PostgreSQL no Amazon RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md)
+ [

# Gerenciar contagens altas de objeto no Amazon RDS para PostgreSQL
](PostgreSQL.HighObjectCount.md)
+ [

# Gerenciar a contenção de TOAST OID no Amazon RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.md)
+ [

## Trabalhar com os mecanismos de registro em log compatíveis com o RDS para PostgreSQL
](#Appendix.PostgreSQL.CommonDBATasks.Auditing)
+ [

# Gerenciar arquivos temporários com o PostgreSQL
](PostgreSQL.ManagingTempFiles.md)
+ [

## Uso de pgBadger para análise de logs com o PostgreSQL
](#Appendix.PostgreSQL.CommonDBATasks.Badger)
+ [

## Usar o PGSnapper para monitorar o PostgreSQL
](#Appendix.PostgreSQL.CommonDBATasks.Snapper)
+ [

# Gerenciar conversões personalizadas no RDS para PostgreSQL
](PostgreSQL.CustomCasts.md)
+ [

# Práticas recomendadas para consultas paralelas no RDS para PostgreSQL
](PostgreSQL.ParallelQueries.md)
+ [

# Trabalhar com parâmetros na instância de banco de dados do RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Parameters.md)

# Agrupamentos permitidos no RDS para PostgreSQL.
<a name="PostgreSQL-Collations"></a>

Agrupamentos são conjuntos de regras que determinam como as strings de caracteres armazenadas no banco de dados são classificadas e comparadas. Eles desempenham um papel fundamental no sistema de computador e são incluídos como parte do sistema operacional. Os agrupamentos mudam com o tempo quando novos caracteres são adicionados aos idiomas ou quando ocorrem alterações nas regras de ordenação.

As bibliotecas de agrupamentos definem regras e algoritmos específicos para um agrupamento. As bibliotecas de agrupamentos mais populares usadas no PostgreSQL são GNU C (glibc) e Componentes Internacionais para Unicode (ICU). Por padrão, o RDS para PostgreSQL usa o agrupamento glibc que inclui ordens de classificação de caracteres Unicode para sequências de caracteres de vários bytes.

Quando você cria uma instância de banco de dados no RDS para PostgreSQL, ele verifica o agrupamento disponível no sistema operacional. Os parâmetros do PostgreSQL `LC_COLLATE` e `LC_CTYPE` do comando `CREATE DATABASE` são usados para especificar um agrupamento, que representa o agrupamento padrão nesse banco de dados. Como alternativa, você também pode usar o parâmetro `LOCALE` em `CREATE DATABASE` para definir esses parâmetros. Isso determina o agrupamento padrão para strings de caracteres no banco de dados e as regras para classificar caracteres como letras, números ou símbolos. Você também pode escolher um agrupamento para usar em uma coluna, um índice ou uma consulta.

O RDS para PostgreSQL depende da biblioteca glibc no sistema operacional para oferecer suporte a agrupamentos. A instância do RDS para PostgreSQL é atualizada periodicamente com as versões mais recentes do sistema operacional. Essas atualizações às vezes incluem uma versão mais recente da biblioteca glibc. Em situações raras, as versões mais recentes da glibc alteram a ordem de classificação ou o agrupamento de alguns caracteres, o que pode fazer com que os dados sejam classificados de forma diferente ou produzam entradas de índice inválidas. Se você descobrir problemas na ordem de classificação para agrupamento durante uma atualização, poderá ser necessário recompilar os índices.

Para reduzir os possíveis impactos das atualizações da glibc, o RDS para PostgreSQL agora inclui uma biblioteca de agrupamentos padrão independente. Essa biblioteca de agrupamentos está disponível no RDS para PostgreSQL 14.6, 13.9, 12.13, 11.18, 10.23 e versões secundárias mais recentes. É compatível com glibc 2.26-59.amzn2 e oferece estabilidade da ordem de classificação para evitar resultados de consulta incorretos.

# Noções básicas de perfis e permissões do PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles"></a>

Ao criar uma instância de banco de dados do RDS para PostgreSQL usando o Console de gerenciamento da AWS, uma conta de administrador é criada ao mesmo tempo. Por padrão, o nome é `postgres`, conforme mostrado na captura de tela a seguir:

![\[A identidade de login padrão para credenciais na página Create database (Criar banco de dados) é postgres.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/default-login-identity-apg-rpg.png)


É possível escolher outro nome em vez de aceitar esse padrão (`postgres`). Se você fizer isso, o nome escolhido deverá começar com uma letra e ter 1 a 16 caracteres alfanuméricos. Para simplificar, nós nos referimos a essa conta de usuário principal pelo seu valor padrão (`postgres`) ao longo deste guia.

Ao usar `create-db-instance` na AWS CLI em vez de usar o Console de gerenciamento da AWS, você cria o nome ao passá-lo com o parâmetro `master-username` no comando. Para obter mais informações, consulte [Criar uma instância de banco de dados do Amazon RDS](USER_CreateDBInstance.md). 

Se você usar o Console de gerenciamento da AWS, a AWS CLI ou a API do Amazon RDS e se usar o nome `postgres` padrão ou escolher um nome diferente, essa primeira conta de usuário do banco de dados será membro do grupo `rds_superuser` e terá privilégios de `rds_superuser`.

**Topics**
+ [

# Noções básicas sobre o perfil rds\$1superuser
](Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser.md)
+ [

# Controlar o acesso de usuários ao banco de dados PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Access.md)
+ [

# Delegar e controlar o gerenciamento de senhas de usuários
](Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt.md)
+ [

# Usar criptografia de senha SCRAM para PostgreSQL
](PostgreSQL_Password_Encryption_configuration.md)

# Noções básicas sobre o perfil rds\$1superuser
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.rds_superuser"></a>

No PostgreSQL, um *perfil* pode definir um usuário, um grupo ou um conjunto de permissões específicas concedidas a um grupo ou usuário a vários objetos no banco de dados. Os comandos do PostgreSQL para `CREATE USER` e `CREATE GROUP` foram substituídos pelo comando mais geral `CREATE ROLE` com propriedades específicas para distinguir usuários de banco de dados. Um usuário de banco de dados pode ser considerado um perfil com o privilégio LOGIN. 

**nota**  
Os comandos `CREATE USER` e `CREATE GROUP` ainda podem ser usados. Para obter mais informações, consulte [Database Roles](https://www.postgresql.org/docs/current/user-manag.html) (Perfis de banco de dados) na documentação do PostgreSQL.

O usuário `postgres` é o usuário de banco de dados mais privilegiado na instância de banco de dados do RDS para PostgreSQL. Ele tem as características definidas pela seguinte instrução `CREATE ROLE`. 

```
CREATE ROLE postgres WITH LOGIN NOSUPERUSER INHERIT CREATEDB CREATEROLE NOREPLICATION VALID UNTIL 'infinity'
```

As propriedades `NOSUPERUSER`, `NOREPLICATION`, `INHERIT` e `VALID UNTIL 'infinity'` são as opções padrão da instrução CREATE ROLE, a menos que especificado de outra forma. 

Por padrão, `postgres` tem privilégios concedidos à função `rds_superuser` e permissões para criar funções e bancos de dados. O perfil `rds_superuser` permite que o usuário `postgres` faça o seguinte: 
+ Adicione as extensões que estão disponíveis para uso com o Amazon RDS. Para obter mais informações, consulte [Trabalhar com recursos do PostgreSQL compatíveis com o Amazon RDS para PostgreSQL](PostgreSQL.Concepts.General.FeatureSupport.md) 
+ Crie funções para usuários e conceda privilégios aos usuários. Para obter mais informações, consulte [CREATE ROLE](https://www.postgresql.org/docs/current/sql-createrole.html) e [GRANT](https://www.postgresql.org/docs/14/sql-grant.html) na documentação do PostgreSQL. 
+ Crie bancos de dados. Para obter mais informações, consulte [CREATE DATABASE](https://www.postgresql.org/docs/14/sql-createdatabase.html) na documentação do PostgreSQL.
+ Conceda privilégios de `rds_superuser` a outras funções de usuário que não têm esses privilégios e revogue esses privilégios conforme necessário. Recomendamos que você conceda esse perfil somente aos usuários que executam tarefas de superusuário. Em outras palavras, você pode conceder esse perfil a administradores de banco de dados (DBAs) ou administradores de sistema.
+ Conceda (e revogue) o perfil `rds_replication` a usuários de banco de dados que não têm o perfil `rds_superuser`. 
+ Conceda (e revogue) o perfil `rds_password` a usuários de banco de dados que não têm o perfil `rds_superuser`. 
+ Obtenha informações de status sobre todas as conexões de banco de dados usando a visualização `pg_stat_activity`. Quando necessário, `rds_superuser` pode interromper qualquer conexão usando `pg_terminate_backend` ou `pg_cancel_backend`. 

Na instrução `CREATE ROLE postgres...`, é possível ver que o perfil do usuário `postgres` não autoriza especificamente as permissões de `superuser` do PostgreSQL. O RDS para PostgreSQL é um serviço gerenciado, portanto, você não pode acessar o sistema operacional host nem se conectar usando a conta `superuser` do PostgreSQL. Muitas das tarefas que exigem o acesso de `superuser` em um PostgreSQL autônomo são gerenciadas automaticamente pelo Amazon RDS. 

Para obter mais informações sobre como conceder privilégios, consulte [GRANT](http://www.postgresql.org/docs/current/sql-grant.html) na documentação do PostgreSQL.

O perfil `rds_superuser` é um dos vários perfis *predefinidos* em um Instância de banco de dados do RDS para PostgreSQL. 

**nota**  
No PostgreSQL 13 e em versões anteriores, os perfis *predefinidos* são conhecidos como perfis *padrão*.

Na lista a seguir, você encontra alguns dos outros perfis predefinidos que são criados automaticamente para um novo Instância de banco de dados do RDS para PostgreSQL. Os perfis predefinidos e seus privilégios não podem ser alterados. Não é possível descartar, renomear ou modificar os privilégios desses perfis predefinidos. Qualquer tentativa de fazer isso gerará um erro. 
+ **rds\$1password**: um perfil que pode alterar senhas e configurar restrições de senha para usuários de bancos de dados. O perfil `rds_superuser` recebe esse perfil por padrão e pode concedê-lo aos usuários do banco de dados. Para obter mais informações, consulte [Controlar o acesso de usuários ao banco de dados PostgreSQLControlar o acesso de usuários ao PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Access.md).
  + Para versões do RDS para PostgreSQL anteriores à 14, o perfil `rds_password` pode alterar senhas e configurar restrições de senha para usuários de bancos de dados e usuários com o perfil `rds_superuser`. Para versões do RDS para PostgreSQL 14 e posteriores, o perfil `rds_password` pode alterar senhas e configurar restrições de senha somente para usuários de banco de dados. Somente usuários com o perfil `rds_superuser` podem realizar essas ações em outros usuários com o perfil `rds_superuser`. 
+ **rdsadmin**: um perfil criado para lidar com muitas das tarefas de gerenciamento que o administrador com privilégios de `superuser` executaria em um banco de dados PostgreSQL autônomo. Esse perfil é usado internamente pelo RDS para PostgreSQL para várias tarefas de gerenciamento. 
+ **rdstopmgr**: um perfil usado internamente pelo Amazon RDS para comportar implantações multi-AZ. 
+ **rds\$1reserved**: função usada internamente pelo Amazon RDS para reservar conexões de banco de dados. 

# Visualizar perfis e os respectivos privilégios
<a name="Appendix.PostgreSQL.CommonDBATasks.Roles.View"></a>

Você pode visualizar perfis predefinidos e os respectivos privilégios na instância de banco de dados do RDS para PostgreSQL usando comandos diferentes, dependendo da versão do PostgreSQL. Para ver todos os perfis predefinidos, você pode se conectar à sua instância de banco de dados do RDS para PostgreSQL e executar os comandos a seguir usando o `psql`.

**Para o `psql` 15 e versões anteriores**

Conecte-se à instância de banco de dados do RDS para PostgreSQL e use o comando `\du` no psql:

```
postgres=> \du
                                                               List of roles
    Role name    |                         Attributes                         |                          Member of
-----------------+------------------------------------------------------------+------------------------------------------------------
 postgres        | Create role, Create DB                                    +| {rds_superuser}
                 | Password valid until infinity                              |
 rds_ad          | Cannot login                                               | {}
 rds_iam         | Cannot login                                               | {}
 rds_password    | Cannot login                                               | {}
 rds_replication | Cannot login                                               | {}
 rds_superuser   | Cannot login                                               | {pg_monitor,pg_signal_backend,rds_password,rds_replication}
 rdsadmin        | Superuser, Create role, Create DB, Replication, Bypass RLS+| {}
                 | Password valid until infinity                              |
```

**Para o `psql` 16 e versões posteriores**

```
postgres=> \drg+
                             List of role grants
   Role name   |          Member of          |       Options       | Grantor
---------------+-----------------------------+---------------------+----------
 postgres      | rds_superuser               | INHERIT, SET        | rdsadmin
 rds_superuser | pg_checkpoint               | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_monitor                  | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_signal_backend           | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | pg_use_reserved_connections | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_password                | ADMIN, INHERIT, SET | rdsadmin
 rds_superuser | rds_replication             | ADMIN, INHERIT, SET | rdsadmin
```

Para verificar a associação sem dependência de versão, você pode usar a seguinte consulta SQL:

```
SELECT m.rolname AS "Role name", r.rolname AS "Member of"
FROM pg_catalog.pg_roles m
JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)
LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)
LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)
WHERE m.rolname !~ '^pg_'
ORDER BY 1, 2;
```

Na saída, é possível ver que `rds_superuser` não é um perfil de usuário de banco de dados (não pode fazer login), mas tem os privilégios de muitos outros perfis. Também é possível ver que esse usuário do banco de dados `postgres` é membro do perfil `rds_superuser`. Como mencionado anteriormente, `postgres` é o valor padrão na página **Create database** (Criar banco de dados) do console do Amazon RDS. Se você escolheu outro nome, esse nome será mostrado na lista de perfis. 

# Controlar o acesso de usuários ao banco de dados PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Access"></a>

Os novos bancos de dados no PostgreSQL são sempre criados com um conjunto padrão de privilégios no esquema `public` do banco de dados que permite que todos os usuários e perfis do banco de dados criem objetos. Esses privilégios permitem que os usuários do banco de dados se conectem ao banco de dados, por exemplo, e criem tabelas temporárias durante a conexão.

Para controlar melhor o acesso dos usuários às instâncias de bancos de dados que você cria na instância de banco de dados do RDS para PostgreSQL, recomendamos que você revogue esses privilégios de `public` padrão. Depois disso, conceda privilégios específicos aos usuários do banco de dados de forma mais granular, conforme mostrado no procedimento a seguir. 

**Como configurar perfis e privilégios para uma nova instância de banco de dados**

Suponha que você esteja configurando um banco de dados em uma instância de banco de dados do RDS para PostgreSQL recém-criada para uso por vários pesquisadores que precisam de acesso de leitura-gravação ao banco de dados. 

1. Use o `psql` (ou o pgAdmin) para se conectar à na instância de banco de dados do RDS para PostgreSQL:

   ```
   psql --host=your-db-instance.666666666666.aws-region.rds.amazonaws.com --port=5432 --username=postgres --password
   ```

   Insira sua senha quando for solicitado. O cliente `psql` conecta-se e exibe o banco de dados de conexão administrativa padrão, `postgres=>`, como o prompt.

1. Para evitar que os usuários do banco de dados criem objetos no esquema `public`, faça o seguinte:

   ```
   postgres=> REVOKE CREATE ON SCHEMA public FROM PUBLIC;
   REVOKE
   ```

1. Em seguida, crie uma nova instância de banco de dados:

   ```
   postgres=> CREATE DATABASE lab_db;
   CREATE DATABASE
   ```

1. Revogue todos os privilégios do esquema `PUBLIC` nesse novo banco de dados.

   ```
   postgres=> REVOKE ALL ON DATABASE lab_db FROM public;
   REVOKE
   ```

1. Crie um perfil para os usuários do banco de dados.

   ```
   postgres=> CREATE ROLE lab_tech;
   CREATE ROLE
   ```

1. Permita que os usuários do banco de dados que têm esse perfil conectem-se ao banco de dados.

   ```
   postgres=> GRANT CONNECT ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. Conceda a todos os usuários com o perfil `lab_tech` todos os privilégios nesse banco de dados.

   ```
   postgres=> GRANT ALL PRIVILEGES ON DATABASE lab_db TO lab_tech;
   GRANT
   ```

1. Crie os usuários do banco de dados, da seguinte forma:

   ```
   postgres=> CREATE ROLE lab_user1 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   postgres=> CREATE ROLE lab_user2 LOGIN PASSWORD 'change_me';
   CREATE ROLE
   ```

1. Conceda a esses dois usuários os privilégios associados ao perfil lab\$1tech:

   ```
   postgres=> GRANT lab_tech TO lab_user1;
   GRANT ROLE
   postgres=> GRANT lab_tech TO lab_user2;
   GRANT ROLE
   ```

Neste ponto, o `lab_user1` e o `lab_user2` podem conectar-se ao banco de dados `lab_db`. Este exemplo não segue as práticas recomendadas para uso corporativo, o que pode incluir a criação de várias instâncias de banco de dados, esquemas diferentes e concessão de permissões limitadas. Para obter informações mais completas e cenários adicionais, consulte [Managing PostgreSQL Users and Roles](https://aws.amazon.com/blogs//database/managing-postgresql-users-and-roles/) (Gerenciar usuários e perfis do PostgreSQL). 

Para obter mais informações sobre privilégios nos bancos de dados PostgreSQL, consulte o comando [GRANT](https://www.postgresql.org/docs/current/static/sql-grant.html) na documentação do PostgreSQL.

# Delegar e controlar o gerenciamento de senhas de usuários
<a name="Appendix.PostgreSQL.CommonDBATasks.RestrictPasswordMgmt"></a>

Como DBA, talvez você queira delegar o gerenciamento de senhas de usuários. Ou talvez você queira impedir que os usuários do banco de dados alterem senhas ou reconfigurem restrições de senha, como o tempo de vida da senha. Para garantir que somente os usuários do banco de dados escolhidos possam alterar as configurações de senha, é possível ativar o recurso de gerenciamento restrito de senhas. Quando você ativa esse recurso, somente os usuários do banco de dados que receberam o perfil `rds_password` podem gerenciar senhas. 

**nota**  
Para usar o gerenciamento restrito de senhas, a instância de banco de dados do RDS para PostgreSQL deve estar executando o Amazon Aurora PostgreSQL 10.6 ou superior.

Por padrão, esse recurso está `off`, conforme mostrado a seguir:

```
postgres=> SHOW rds.restrict_password_commands;
  rds.restrict_password_commands
--------------------------------
 off
(1 row)
```

Para ativar esse recurso, use um grupo de parâmetros personalizado e altere a configuração de `rds.restrict_password_commands` para 1. Reinicialize a instância de banco de dados do RDS para PostgreSQL para que a configuração entre em vigor. 

Com esse recurso ativo, os privilégios de `rds_password` são necessários para os seguintes comandos SQL:

```
CREATE ROLE myrole WITH PASSWORD 'mypassword';
CREATE ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword' VALID UNTIL '2023-01-01';
ALTER ROLE myrole WITH PASSWORD 'mypassword';
ALTER ROLE myrole VALID UNTIL '2023-01-01';
ALTER ROLE myrole RENAME TO myrole2;
```

A renomeação de um perfil (`ALTER ROLE myrole RENAME TO newname`) também será restrita se a senha usar o algoritmo de hash MD5. 

Com esse recurso ativo, qualquer tentativa de executar um desses comandos SQL sem as permissões do perfil `rds_password` gerará o seguinte erro: 

```
ERROR: must be a member of rds_password to alter passwords
```

Recomendamos conceder a `rds_password` a apenas alguns perfis usados exclusivamente para o gerenciamento de senhas. Se você conceder privilégios de `rds_password` a usuários de banco de dados que não têm privilégios de `rds_superuser`, também precisará conceder o atributo `CREATEROLE` a eles.

Verifique os requisitos de senha, como expiração e complexidade necessária, no lado do cliente. Se você usar seu próprio utilitário do lado do cliente para alterações relacionadas a senhas, o utilitário precisará ser membro de `rds_password` e ter privilégios de `CREATE ROLE`. 

# Usar criptografia de senha SCRAM para PostgreSQL
<a name="PostgreSQL_Password_Encryption_configuration"></a>

O *Salted Challenge Response Authentication Mechanism (SCRAM)* é uma alternativa ao algoritmo de resumo de mensagens padrão (MD5) do PostgreSQL para senhas de criptografia. O mecanismo de autenticação SCRAM é considerado mais seguro que o MD5. Para saber mais sobre essas duas abordagens diferentes para proteger senhas, consulte [Autorização com senha](https://www.postgresql.org/docs/14/auth-password.html) na documentação do PostgreSQL.

Recomendamos que você use o SCRAM em vez de o MD5 como o esquema de criptografia de senha para seu Instância de banco de dados do RDS para PostgreSQL. É um mecanismo criptográfico de resposta a desafios que usa o algoritmo scram-sha-256 para autenticação e criptografia de senha. 

Convém atualizar as bibliotecas das aplicações cliente para oferecer compatibilidade com o SCRAM. Por exemplo, versões do JDBC anteriores à 42.2.0 não são compatíveis com o SCRAM. Para obter mais informações, consulte [Driver JDBC do PostgreSQL](https://jdbc.postgresql.org/changelogs/2018-01-17-42.2.0-release/) na documentação do driver JDBC do PostgreSQL. Para obter uma lista de outros drivers do PostgreSQL e compatibilidade com o SCRAM, consulte [Lista de drivers](https://wiki.postgresql.org/wiki/List_of_drivers) na documentação do PostgreSQL.

A versão 13.1 do RDS para PostgreSQL e versões posteriores são compatíveis com scram-sha-256. Essas versões também permitem configurar sua instância de banco de dados para exigir o SCRAM, conforme abordado nos procedimentos a seguir.

## Configurar a instância de banco de dados do RDS para PostgreSQL para exigir o SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.preliminary"></a>

 você pode exigir que a instância de banco de dados do RDS para PostgreSQL aceite apenas senhas que usem o algoritmo scram-sha-256.

**Importante**  
Para proxies RDS existentes com bancos de dados PostgreSQL, se você modificar a autenticação do banco de dados para usar somente `SCRAM`, o proxy ficará indisponível por até 60 segundos. Para evitar o problema, faça o seguinte:  
O banco de dados deve permitir tanto a autenticação `SCRAM` quanto a `MD5`.
Para usar somente a autenticação `SCRAM`, crie um proxy, migre o tráfego da aplicação para o novo proxy e exclua o proxy anteriormente associado ao banco de dados.

Antes de fazer alterações em seu sistema, entenda o processo completo da seguinte forma:
+ Obtenha informações sobre todos os perfis e criptografia de senha para todos os usuários do banco de dados. 
+ Confira novamente as configurações dos parâmetros da instância de banco de dados do RDS para PostgreSQL para verificar os parâmetros que controlam a criptografia de senha.
+ Se a instância de banco de dados do RDS para PostgreSQL usar um grupo de parâmetros padrão, será necessário criar um grupo de parâmetros de banco de dados personalizado e aplicá-lo à instância de banco de dados do RDS para PostgreSQL para poder modificar parâmetros quando necessário. Se sua instância de banco de dados do RDS para PostgreSQL usa um grupo de parâmetros personalizado, você poderá modificar os parâmetros necessários posteriormente no processo, conforme necessário. 
+ Altere o parâmetro `password_encryption` para `scram-sha-256`.
+ Avise a todos os usuários do banco de dados que eles precisam atualizar as senhas. Faça o mesmo para a conta `postgres`. As novas senhas são criptografadas e armazenadas usando o algoritmo scram-sha-256.
+ Verifique se todas as senhas são criptografadas usando o tipo de criptografia. 
+ Se todas as senhas utilizarem scram-sha-256, você poderá alterar o parâmetro de `rds.accepted_password_auth_method` para `md5+scram`. 

**Atenção**  
Depois de alterar `rds.accepted_password_auth_method` para scram-sha-256, os usuários (perfis) com senhas criptografadas com `md5` não conseguirão se conectar. 

### Preparar-se para exigir o SCRAM para sua instância de banco de dados do RDS para PostgreSQL
<a name="PostgreSQL_Password_Encryption_configuration.getting-ready"></a>

Antes de fazer qualquer alteração em sua instância de banco de dados do RDS para PostgreSQL, confira todas as contas de usuário do banco de dados existentes. Além disso, verifique o tipo de criptografia usada para senhas. Você pode realizar essas tarefas usando a extensão `rds_tools`. Consulte quais versões do PostgreSQL são compatíveis com `rds_tools` em [Extension versions for Amazon RDS for PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/PostgreSQLReleaseNotes/postgresql-extensions.html).

**Como obter uma lista de usuários (perfis) de banco de dados e métodos de criptografia de senha**

1. Use o `psql` para conectar-se à instância de banco de dados do RDS para PostgreSQL conforme mostrado a seguir.

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

1. Instale a extensão `rds_tools`.

   ```
   postgres=> CREATE EXTENSION rds_tools;
   CREATE EXTENSION
   ```

1. Obtenha uma lista de perfis e criptografias.

   ```
   postgres=> SELECT * FROM 
         rds_tools.role_password_encryption_type();
   ```

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

   ```
          rolname        | encryption_type
   ----------------------+-----------------
    pg_monitor           |
    pg_read_all_settings |
    pg_read_all_stats    |
    pg_stat_scan_tables  |
    pg_signal_backend    |
    lab_tester           | md5
    user_465             | md5
    postgres             | md5
   (8 rows)
   ```

### Criar um grupo de parâmetros de banco de dados personalizado
<a name="PostgreSQL_Password_Encryption_configuration.custom-parameter-group"></a>

**nota**  
Se sua instância de banco de dados do RDS para PostgreSQL já usa um grupo de parâmetros personalizado, não é necessário criar outro. 

Para obter uma visão geral dos grupos de parâmetros do Amazon RDS, consulte [Trabalhar com parâmetros na instância de banco de dados do RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Parameters.md). 

O tipo de criptografia de senha usada para senhas é definido em um parâmetro, `password_encryption`. A criptografia permitida pela instância de banco de dados do RDS para PostgreSQL é definida em outro parâmetro, `rds.accepted_password_auth_method`. Alterar qualquer um desses valores padrão exige que você crie um grupo de parâmetros de banco de dados personalizado e aplique-o à sua instância. 

Você também pode usar o Console de gerenciamento da AWS ou a API do RDS para criar um grupo de parâmetros de banco de dados personalizado. Consulte mais informações em 

Associe o grupo de parâmetros personalizado à sua instância de banco de dados. 

**Como criar um grupo de parâmetros de banco de dados personalizado**

1. Use o comando `[create-db-parameter-group](https://docs.aws.amazon.com/cli/latest/reference/rds/create-db-parameter-group.html) ` da CLI para criar o grupo de parâmetros de banco de dados personalizado. Este exemplo usa `postgres13` como a origem desse grupo de parâmetros personalizado. 

   Para Linux, macOS ou Unix:

   ```
   aws rds create-db-parameter-group --db-parameter-group-name 'docs-lab-scram-passwords' \
     --db-parameter-group-family postgres13  --description 'Custom parameter group for SCRAM'
   ```

   Para Windows:

   ```
   aws rds create-db-parameter-group --db-parameter-group-name "docs-lab-scram-passwords" ^
     --db-parameter-group-family postgres13  --description "Custom DB parameter group for SCRAM"
   ```

1. Use o comando `[modify-db-instance](https://docs.aws.amazon.com/cli/latest/reference/rds/modify-db-instance.html)` da CLI para aplicar esse grupo de parâmetros personalizado ao seu cluster de banco de dados do RDS para PostgreSQL.

   Para Linux, macOS ou Unix:

   ```
   aws rds modify-db-instance --db-instance-identifier 'your-instance-name' \
           --db-parameter-group-name "docs-lab-scram-passwords
   ```

   Para Windows:

   ```
   aws rds modify-db-instance --db-instance-identifier "your-instance-name" ^
           --db-parameter-group-name "docs-lab-scram-passwords
   ```

   Para sincronizar novamente sua instância de banco de dados do RDS para PostgreSQL com seu grupo de parâmetros de cluster de banco de dados personalizado, você precisa reiniciar a instância primária e todas as outras instâncias do cluster. Programe para que isso ocorra durante sua janela de manutenção regular a fim de minimizar o impacto para os usuários.

### Configurar a criptografia de senha para usar o SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.configure-password-encryption"></a>

O mecanismo de criptografia de senha usado por uma instância de banco de dados do RDS para PostgreSQL é definido no grupo de parâmetros de banco de dados no parâmetro `password_encryption`. Os valores permitidos não estão definidos, `md5` ou `scram-sha-256`. O valor padrão depende da versão do RDS para PostgreSQL da seguinte forma:
+ RDS para PostgreSQL 14 e superior: o padrão é `scram-sha-256`
+ RDS para PostgreSQL 13: o padrão é `md5`

Com um grupo de parâmetros de banco de dados personalizado anexado à instância de banco de dados do RDS para PostgreSQL, é possível modificar valores do parâmetro de criptografia de senha.

![\[A seguir, o console do RDS mostra os valores padrão para os parâmetros password_encryption do RDS para PostgreSQL.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/rpg-pwd-encryption-md5-scram-1.png)


**Como alterar a configuração de criptografia de senha para scram-sha-256**
+ Altere o valor da criptografia de senha para scram-sha-256, conforme mostrado a seguir. A alteração pode ser aplicada imediatamente porque o parâmetro é dinâmico, portanto, não é necessário reiniciar para que a alteração seja implementada. 

  Para Linux, macOS ou Unix:

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name \
    'docs-lab-scram-passwords' --parameters 'ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate'
  ```

  Para Windows:

  ```
  aws rds modify-db-parameter-group --db-parameter-group-name ^
    "docs-lab-scram-passwords" --parameters "ParameterName=password_encryption,ParameterValue=scram-sha-256,ApplyMethod=immediate"
  ```

### Migrar senhas para funções de usuário para o SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.migrating-users"></a>

Você pode migrar senhas de perfis de usuário para o SCRAM conforme descrito a seguir.

**Como migrar senhas de usuário (função) do banco de dados do MD5 para o SCRAM**

1. Faça login como usuário administrador (nome de usuário padrão, `postgres`) conforme mostrado a seguir.

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

1. Confira a configuração do parâmetro `password_encryption` em sua instância de banco de dados do RDS para PostgreSQL usando o comando a seguir.

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    md5
    (1 row)
   ```

1. Altere o valor desse parâmetro para scram-sha-256. Para obter mais informações, consulte [Configurar a criptografia de senha para usar o SCRAM](#PostgreSQL_Password_Encryption_configuration.configure-password-encryption). 

1.  Confira o valor novamente para garantir que agora ele esteja definido como `scram-sha-256` da seguinte forma. 

   ```
   postgres=> SHOW password_encryption;
    password_encryption
   ---------------------
    scram-sha-256
    (1 row)
   ```

1. Avise a todos os usuários do banco de dados para alterar senhas. Altere também sua própria senha para a conta `postgres` (o usuário do banco de dados com privilégios de `rds_superuser`). 

   ```
   labdb=> ALTER ROLE postgres WITH LOGIN PASSWORD 'change_me';
   ALTER ROLE
   ```

1. Repita o processo para todos os bancos de dados no Instância de banco de dados do RDS para PostgreSQL. 

### Alterar o parâmetro para exigir o SCRAM
<a name="PostgreSQL_Password_Encryption_configuration.require-scram"></a>

Esta é a etapa final do processo. Depois de fazer a alteração no procedimento a seguir, as contas de usuário (perfis) que ainda usam a criptografia `md5` para senhas não poderão fazer login no Instância de banco de dados do RDS para PostgreSQL. 

O `rds.accepted_password_auth_method` especifica o método de criptografia que a instância de banco de dados do RDS para PostgreSQL aceita para uma senha de usuário durante o processo de login. O valor padrão é `md5+scram`, o que significa que qualquer método é aceito. Na imagem a seguir, você pode encontrar a configuração padrão para esse parâmetro.

![\[O console do RDS mostrando os valores padrão e permitidos para os parâmetros rds.accepted_password_auth_method.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/pwd-encryption-md5-scram-2.png)


Os valores permitidos para esse parâmetro são `md5+scram` ou `scram`. Alterar esse valor de parâmetro para `scram` torna isso um requisito. 

**Como alterar o valor do parâmetro para exigir autenticação SCRAM para senhas**

1. Verifique se todas as senhas de usuários para todos os bancos de dados na instância de banco de dados do RDS para PostgreSQL usam `scram-sha-256` para criptografia de senha. Para fazer isso, consulte `rds_tools` para obter o perfil (usuário) e o tipo de criptografia, da seguinte forma. 

   ```
   postgres=> SELECT * FROM rds_tools.role_password_encryption_type();
     rolname        | encryption_type
     ----------------------+-----------------
     pg_monitor           |
     pg_read_all_settings |
     pg_read_all_stats    |
     pg_stat_scan_tables  |
     pg_signal_backend    |
     lab_tester           | scram-sha-256
     user_465             | scram-sha-256
     postgres             | scram-sha-256
     ( rows)
   ```

1. Repita a consulta para todas as instâncias de banco de dados em seu Instância de banco de dados do RDS para PostgreSQL. 

   Se todas as senhas usam scram-sha-256, você pode prosseguir. 

1. Altere o valor da autenticação de senha aceita para scram-sha-256 da seguinte forma.

   Para Linux, macOS ou Unix:

   ```
   aws rds modify-db-parameter-group --db-parameter-group-name 'docs-lab-scram-passwords' \
     --parameters 'ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate'
   ```

   Para Windows:

   ```
   aws rds modify-db-parameter-group --db-parameter-group-name "docs-lab-scram-passwords" ^
     --parameters "ParameterName=rds.accepted_password_auth_method,ParameterValue=scram,ApplyMethod=immediate"
   ```

# Tratamento de conexões inativas no PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling"></a>

Conexões inativas ocorrem quando uma sessão de banco de dados permanece ativa no servidor mesmo que a aplicação cliente tenha sido abandonada ou encerrada de forma anormal. Essa situação geralmente ocorre quando os processos do cliente falham ou são encerrados inesperadamente sem fechar adequadamente as respectivas conexões de banco de dados ou cancelar solicitações em andamento.

O PostgreSQL identifica e limpa com eficiência as conexões inativas quando os processos do servidor estão ociosos ou tentam enviar dados aos clientes. No entanto, a detecção é um desafio para sessões que estão ociosas, aguardando a entrada do cliente ou executando consultas ativamente. Para lidar com esses cenários, o PostgreSQL oferece os parâmetros `tcp_keepalives_*`, `tcp_user_timeout` e `client_connection_check_interval`.

**Topics**
+ [

## Conceitos básicos sobre keepalive de TCP
](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Understanding)
+ [

## Principais parâmetros de keepalive de TCP no RDS para PostgreSQL
](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Parameters)
+ [

## Casos de uso para configurações de keepalive de TCP
](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases)
+ [

## Práticas recomendadas
](#Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.BestPractices)

## Conceitos básicos sobre keepalive de TCP
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Understanding"></a>

O keepalive de TCP é um mecanismo em nível de protocolo que ajuda a manter e verificar a integridade da conexão. Cada conexão TCP mantém configurações em nível de kernel que controlam o comportamento de keepalive. Quando o temporizador de keepalive expira, o sistema realiza o seguinte:
+ Envia um pacote de sondagem sem dados e com o sinalizador ACK definido.
+ Espera uma resposta do endpoint remoto de acordo com as especificações de TCP/IP.
+ Gerencia o estado da conexão com base na resposta ou na falta dela.

## Principais parâmetros de keepalive de TCP no RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.Parameters"></a>


| Parameter | Descrição | Valores padrão | 
| --- |--- |--- |
| tcp\$1keepalives\$1idle | Specifies number of seconds of inactivity before sending keepalive message. | 300 | 
| tcp\$1keepalives\$1interval | Specifies number of seconds between retransmissions of unacknowledged keepalive messages. | 30 | 
| tcp\$1keepalives\$1count | Maximum lost keepalive messages before declaring connection dead | 2 | 
| tcp\$1user\$1timeout | Specifies how long (in Milliseconds) unacknowledged data can remain before forcibly closing the connection. | 0 | 
| client\$1connection\$1check\$1interval | Sets the interval (in Milliseconds) for checking client connection status during long-running queries. This ensures quicker detection of closed connections. | 0 | 

## Casos de uso para configurações de keepalive de TCP
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases"></a>

### Manter as sessões ociosas ativas
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases.KeepingAlive"></a>

Para evitar que conexões ociosas sejam encerradas por firewalls ou roteadores devido a inatividade:
+ Configure `tcp_keepalives_idle` para enviar pacotes de keepalive em intervalos regulares.

### Detectar conexões inativas
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.UseCases.DetectingDead"></a>

Para detectar conexões inativas imediatamente:
+ Ajuste `tcp_keepalives_idle`, `tcp_keepalives_interval` e `tcp_keepalives_count`. Por exemplo, com os padrões do Aurora PostgreSQL, a detecção de uma conexão inativa leva cerca de 1 minuto (2 sondagens × 30 segundos). Reduzir esses valores pode acelerar a detecção.
+ Use `tcp_user_timeout` para especificar o tempo máximo de espera para uma confirmação.

As configurações de keepalive de TCP ajudam o kernel a detectar conexões inativas, mas talvez o PostgreSQL não aja enquanto o soquete não for usado. Se uma sessão estiver executando uma consulta longa, as conexões inativas só poderão ser detectadas após a conclusão da consulta. No PostgreSQL 14 e versões posteriores, `client_connection_check_interval` pode acelerar a detecção de conexões inativas pesquisando periodicamente o soquete durante a execução da consulta.

## Práticas recomendadas
<a name="Appendix.PostgreSQL.CommonDBATasks.DeadConnectionHandling.BestPractices"></a>
+ **Defina intervalos razoáveis de keepalive:** ajuste `tcp_user_timeout`, `tcp_keepalives_idle`, `tcp_keepalives_count` e `tcp_keepalives_interval` para contrabalançar a velocidade de detecção e o uso de recursos.
+ **Otimize para melhorar seu ambiente:** alinhe as configurações ao comportamento da rede, às políticas de firewall e às necessidades da sessão.
+ **Aproveite os recursos do PostgreSQL**: use `client_connection_check_interval` no PostgreSQL 14 e versões posteriores para realizar verificações de conexão eficientes.

# Trabalhar com o autovacuum do PostgreSQL no Amazon RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum"></a>

É altamente recomendável que você use o recurso de autovacuum para bancos de dados PostgreSQL a fim de manter a integridade de sua instância de banco de dados PostgreSQL. O autovacuum automatiza a execução dos comandos VACUUM e ANALYZE. Ele verifica as tabelas com um grande número de tuplas inseridas, atualizadas ou excluídas. Após essa verificação, ele recupera o armazenamento removendo dados obsoletos ou tuplas do banco de dados PostgreSQL.

Por padrão, o autovacuum é ativado nas instâncias de banco de dados do RDS para PostgreSQL que você cria usando qualquer um dos grupos de parâmetros de banco de dados padrão do PostgreSQL. Outros parâmetros de configuração associados ao recurso autovacuum também são definidos por padrão. Como esses padrões são genéricos, você pode se beneficiar do ajuste de alguns dos parâmetros associados ao recurso autovacuum para seu workload específico. 

A seguir, você pode encontrar mais informações sobre o autovacuum e como ajustar alguns dos respectivos parâmetros em sua instância de banco de dados do RDS para PostgreSQL. Para ter informações gerais, consulte [Práticas recomendadas para trabalhar com PostgreSQL](CHAP_BestPractices.md#CHAP_BestPractices.PostgreSQL).

**Topics**
+ [

## Alocar memória para autovacuum
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory)
+ [

## Reduzir a probabilidade de conclusão de IDs de transação
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming)
+ [

# Determinar se as tabelas no seu banco de dados precisam de vacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming.md)
+ [

# Determinar quais tabelas são atualmente elegíveis para autovacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables.md)
+ [

# Determinar se o autovacuum está em execução e por quanto tempo
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning.md)
+ [

# Realização de um congelamento manual de vacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md)
+ [

# Reindexação de uma tabela quando o autovacuum está em execução
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing.md)
+ [

# Gerenciar o autovacuum com grandes índices
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md)
+ [

# Outros parâmetros que afetam o autovacuum
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms.md)
+ [

# Definir parâmetros de autovacuum em nível de tabela
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters.md)
+ [

# Registrar atividades do autovacuum e do vacuum em log
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging.md)
+ [

# Noções básicas sobre o comportamento do autovacuum com bancos de dados inválidos
](appendix.postgresql.commondbatasks.autovacuumbehavior.md)
+ [

# Identificar e resolver bloqueadores de limpeza agressivos no RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.md)

## Alocar memória para autovacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.WorkMemory"></a>

Um dos parâmetros mais importantes que influenciam a performance do autovacuum é o [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM). No RDS para PostgreSQL versões 14 e anteriores, o parâmetro `autovacuum_work_mem` é definido como -1, indicando que a configuração de `maintenance_work_mem` é usada em vez disso. Para todas as outras versões, `autovacuum_work_mem` é determinado por GREATEST(\$1DBInstanceClassMemory/32768\$1, 65536).

As operações vacuum manuais sempre usam a configuração `maintenance_work_mem`, com uma configuração padrão de GREATEST(\$1DBInstanceClassMemory/63963136\$11024\$1, 65536), e também é possível fazer o ajuste no nível da sessão usando o comando `SET` para operações `VACUUM` manuais mais específicas.

O `autovacuum_work_mem` determina a memória do autovacuum para armazenar identificadores de tuplas mortas (`pg_stat_all_tables.n_dead_tup`) para índices de vacuum.

Ao executar cálculos para determinar o valor do parâmetro `autovacuum_work_mem`, esteja ciente do seguinte:
+ Se você definir o parâmetro com um valor muito baixo, o processo de vacuum talvez precise verificar a tabela várias vezes para concluir o trabalho. Essas várias verificações podem ter um impacto negativo sobre a performance. Para instâncias maiores, a configuração de `maintenance_work_mem` ou `autovacuum_work_mem` para pelo menos 1 GB pode melhorar o desempenho de vaccum nas tabelas com um grande número de tuplas mortas. No entanto, no PostgreSQL versões 16 e anteriores, o uso de memória do vacuum é limitado a 1 GB, o que é suficiente para processar aproximadamente 179 milhões de tuplas mortas em uma única passagem. Se uma tabela tiver mais tuplas mortas do que isso, o vacuum precisará fazer várias passagens pelos índices da tabela, aumentando significativamente o tempo necessário. A partir da versão 17 do PostgreSQL, não há um limite de 1 GB, e o autovacuum pode processar mais de 179 milhões de tuplas usando árvores radix.

  Um identificador de tupla tem 6 bytes de tamanho. Para estimar a memória necessária para limpar um índice de uma tabela, consulte `pg_stat_all_tables.n_dead_tup` para encontrar o número de tuplas mortas e multiplique esse número por seis para determinar a memória necessária para realizar vacuum do índice em uma única passagem. Você pode usar a seguinte consulta:

  ```
  SELECT
      relname AS table_name,
      n_dead_tup,
      pg_size_pretty(n_dead_tup * 6) AS estimated_memory
  FROM
      pg_stat_all_tables
  WHERE
      relname = 'name_of_the_table';
  ```
+ O parâmetro `autovacuum_work_mem` funciona em conjunto com o parâmetro `autovacuum_max_workers`. Cada operador entre `autovacuum_max_workers` pode usar a memória que você alocar. Se você tiver muitas tabelas pequenas, aloque mais `autovacuum_max_workers` e menos `autovacuum_work_mem`. Se você tiver tabelas grandes (com mais de 100 GB), aloque mais memória e menos processos de operadores. Você precisa ter memória suficiente alocada para ter sucesso na sua maior tabela. Portanto, garanta que a combinação de processos de operadores e memória seja igual à memória total que deseja alocar.

## Reduzir a probabilidade de conclusão de IDs de transação
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming"></a>

Em alguns casos, as configurações de grupos de parâmetros relacionadas ao autovacuum podem não ser agressivas o suficiente para evitar a conclusão de IDs de transação. Para resolver isso, o RDS para PostgreSQL oferece um mecanismo que adapta automaticamente os valores dos parâmetros de autovacuum. O *autovacuum adaptável* é um recurso do RDS para PostgreSQL. Uma explicação detalhada da [conclusão de TransactionID](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND) encontra-se na documentação do PostgreSQL. 

O autovacuum adaptável está ativado por padrão para instâncias do RDS para PostgreSQL com o parâmetro dinâmico `rds.adaptive_autovacuum` definido como ATIVADO. É altamente recomendável manter esse recurso ativado. No entanto, para desabilitar esse recurso, defina o parâmetro `rds.adaptive_autovacuum` como 0 ou OFF (desativado). 

O wraparound de ID de transação ainda é possível mesmo quando o Amazon RDS ajusta os parâmetros de autovacuum. Nós encorajamos que você implemente um alarme do Amazon CloudWatch para a conclusão de IDs de transação. Para ter mais informações, consulte a postagem [Implement an early warning system for transaction ID wraparound in RDS for PostgreSQL](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/) (Implementar um sistema de alertas antecipados para conclusão de IDs de transação no RDS for PostgreSQL) no Blog de banco de dados da AWS.

Com o ajuste de parâmetros de autovacuum adaptável ativado, o Amazon RDS começa a ajustar parâmetros de autovacuum quando a métrica do CloudWatch `MaximumUsedTransactionIDs` atingir o valor do parâmetro `autovacuum_freeze_max_age` ou 500.000.000, o que for maior. 

O Amazon RDS continuará a ajustar os parâmetros para o autovacuum se uma tabela continuar a tendência para a conclusão de IDs de transação. Cada um desses ajustes dedica mais recursos ao autovacuum para evitar o envolvimento. O Amazon RDS atualiza os seguintes parâmetros relacionados ao autovacuum: 
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)
+  [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-AUTOVACUUM-WORK-MEM) 
+  [autovacuum\$1naptime](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-NAPTIME) 

O RDS modificará esses parâmetros somente se o novo valor tornar o autovacuum mais agressivo. Os parâmetros são modificados na memória na instância de banco de dados. Os valores no grupo de parâmetros não são alterados. Para visualizar as configurações atuais na memória, use o comando SQL [SHOW](https://www.postgresql.org/docs/current/sql-show.html) PostgreSQL. 

Quando o Amazon RDS modifica qualquer um desses parâmetros de autovacuum, ele gera um evento para a instância de banco de dados afetada. Esse evento é visível no Console de gerenciamento da AWS e por meio da API do Amazon RDS. Depois que a métrica `MaximumUsedTransactionIDs` do CloudWatch volta a ficar abaixo do limite, o Amazon RDS redefine os parâmetros relacionados a autovacuum na memória de volta aos valores especificados no grupo de parâmetros. Em seguida, ele gera outro evento correspondente a essa alteração.

# Determinar se as tabelas no seu banco de dados precisam de vacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.NeedVacuuming"></a>

Você pode usar a consulta a seguir para mostrar o número de transações sem restrições em um banco de dados. A coluna `datfrozenxid` de uma linha `pg_database` do banco de dados é um limite inferior nos IDs de transação normais que aparecem nesse banco de dados. Essa coluna é o mínimo dos valores de `relfrozenxid` por tabela no banco de dados. 

```
SELECT datname, age(datfrozenxid) FROM pg_database ORDER BY age(datfrozenxid) desc limit 20;
```

Por exemplo, os resultados da execução da consulta anterior podem ser os seguintes.

```
datname    | age
mydb       | 1771757888
template0  | 1721757888
template1  | 1721757888
rdsadmin   | 1694008527
postgres   | 1693881061
(5 rows)
```

Quando a idade de um banco de dados atingir 2 bilhões de IDs de transação, ocorrerá a conclusão de IDs de transação (XID), e o banco de dados se tornará somente leitura. Use essa consulta para produzir uma métrica e execute-a algumas vezes por dia. Por padrão, o autovacuum é definido para manter a idade das transações como um máximo de 200,000,000 ([https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)).

Uma estratégia de monitoramento de exemplo pode ser assim:
+ Defina o valor `autovacuum_freeze_max_age` como 200 milhões de transações.
+ Se uma tabela atingir 500 milhões de transações sem restrições, um alarme de baixa gravidade será disparado. Este não é um valor não razoável, mas pode indicar que o autovacuum não está dando conta.
+ Se uma tabela chegar a 1 bilhão, ela deverá ser tratada como um alarme que requer medidas. Em geral, convém manter as idades mais próximas de `autovacuum_freeze_max_age` por motivos de performance. Recomendamos que você investigue usando as recomendações a seguir.
+ Se uma tabela atingir 1,5 bilhões de transações sem vacuum, um alarme de alta gravidade será disparado. Dependendo da rapidez com que seu banco de dados usa IDs de transação, esse alarme pode indicar que o sistema está ficando sem tempo para executar o autovacuum. Nesse caso, recomendamos que você resolva isso imediatamente.

Se uma tabela estiver ultrapassando constantemente esses limiares, modifique ainda mais seus parâmetros de autovacuum. Por padrão, usar VACUUM manualmente (que tem atrasos baseados em custos desabilitados) é mais agressivo do que usar o autovacuum padrão, mas também é mais intrusivo para o sistema como um todo.

Recomendamos o seguinte:
+ Esteja ciente e ative um mecanismo de monitoramento para que você tenha conhecimento da idade das transações mais antigas.

  Para obter informações sobre como criar um processo que avisa sobre a conclusão de IDs de transação, consulte a publicação do blog de banco de dados da AWS [Implement an early warning system for transaction ID wraparound no Amazon RDS for PostgreSQL](https://aws.amazon.com/blogs/database/implement-an-early-warning-system-for-transaction-id-wraparound-in-amazon-rds-for-postgresql/) (Implementar um sistema de alerta antecipado para conclusão de IDs de transação no Amazon RDS for PostgreSQL).
+ Para tabelas mais ocupadas, execute um congelamento de vacuum manual regularmente durante uma janela de manutenção além de depender do autovacuum. Para obter informações sobre a realização de um congelamento manual de vacuum, consulte [Realização de um congelamento manual de vacuum](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md).

# Determinar quais tabelas são atualmente elegíveis para autovacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.EligibleTables"></a>

Muitas vezes, uma ou duas tabelas precisam de vacuum. Tabelas cujo valor de `relfrozenxid` é maior que o número de transações em `autovacuum_freeze_max_age` são sempre visadas pelo autovacuum. Caso contrário, se o número de tuplas obsoletas desde o último VACUUM exceder o limite de vacuum, um vacuum será realizado na tabela.

O [limite de autovacuum](https://www.postgresql.org/docs/current/static/routine-vacuuming.html#AUTOVACUUM) é definido como:

```
Vacuum-threshold = vacuum-base-threshold + vacuum-scale-factor * number-of-tuples
```

em que o `vacuum base threshold` é `autovacuum_vacuum_threshold`, o `vacuum scale factor` é `autovacuum_vacuum_scale_factor` e o `number of tuples` é `pg_class.reltuples`.

Enquanto você estiver conectado ao seu banco de dados, execute a consulta a seguir para ver uma lista de tabelas que o autovacuum considera elegíveis para o vacuum.

```
WITH vbt AS (SELECT setting AS autovacuum_vacuum_threshold FROM 
pg_settings WHERE name = 'autovacuum_vacuum_threshold'),
vsf AS (SELECT setting AS autovacuum_vacuum_scale_factor FROM 
pg_settings WHERE name = 'autovacuum_vacuum_scale_factor'), 
fma AS (SELECT setting AS autovacuum_freeze_max_age FROM pg_settings WHERE name = 'autovacuum_freeze_max_age'),
sto AS (select opt_oid, split_part(setting, '=', 1) as param,
split_part(setting, '=', 2) as value from (select oid opt_oid, unnest(reloptions) setting from pg_class) opt)
SELECT '"'||ns.nspname||'"."'||c.relname||'"' as relation,
pg_size_pretty(pg_table_size(c.oid)) as table_size,
age(relfrozenxid) as xid_age,
coalesce(cfma.value::float, autovacuum_freeze_max_age::float) autovacuum_freeze_max_age,
(coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) +
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * c.reltuples)
AS autovacuum_vacuum_tuples, n_dead_tup as dead_tuples FROM
pg_class c join pg_namespace ns on ns.oid = c.relnamespace 
join pg_stat_all_tables stat on stat.relid = c.oid join vbt on (1=1) join vsf on (1=1) join fma on (1=1)
left join sto cvbt on cvbt.param = 'autovacuum_vacuum_threshold' and c.oid = cvbt.opt_oid 
left join sto cvsf on cvsf.param = 'autovacuum_vacuum_scale_factor' and c.oid = cvsf.opt_oid
left join sto cfma on cfma.param = 'autovacuum_freeze_max_age' and c.oid = cfma.opt_oid
WHERE c.relkind = 'r' and nspname <> 'pg_catalog'
AND (age(relfrozenxid) >= coalesce(cfma.value::float, autovacuum_freeze_max_age::float)
OR coalesce(cvbt.value::float, autovacuum_vacuum_threshold::float) + 
coalesce(cvsf.value::float,autovacuum_vacuum_scale_factor::float) * 
c.reltuples <= n_dead_tup)
ORDER BY age(relfrozenxid) DESC LIMIT 50;
```

# Determinar se o autovacuum está em execução e por quanto tempo
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AutovacuumRunning"></a>

Se você precisa realizar vacuum em uma tabela manualmente, determine se o autovacuum está sendo executado. Se estiver, talvez seja necessário ajustar parâmetros para fazê-lo funcionar mais eficientemente ou desativar o autovacuum temporariamente para poder executar VACUUM manualmente.

Use a seguinte consulta para determinar se o autovacuum está sendo executado e por quanto tempo, e se ele está esperando por outra sessão. 

```
SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query
FROM pg_stat_activity 
WHERE upper(query) LIKE '%VACUUM%' 
ORDER BY xact_start;
```

Depois de executar a consulta, você deverá ver uma saída semelhante à seguinte:

```
 datname | usename  |  pid  | state  | wait_event |      xact_runtime       | query  
 --------+----------+-------+--------+------------+-------------------------+--------------------------------------------------------------------------------------------------------
 mydb    | rdsadmin | 16473 | active |            | 33 days 16:32:11.600656 | autovacuum: VACUUM ANALYZE public.mytable1 (to prevent wraparound)
 mydb    | rdsadmin | 22553 | active |            | 14 days 09:15:34.073141 | autovacuum: VACUUM ANALYZE public.mytable2 (to prevent wraparound)
 mydb    | rdsadmin | 41909 | active |            | 3 days 02:43:54.203349  | autovacuum: VACUUM ANALYZE public.mytable3
 mydb    | rdsadmin |   618 | active |            | 00:00:00                | SELECT datname, usename, pid, state, wait_event, current_timestamp - xact_start AS xact_runtime, query+
         |          |       |        |            |                         | FROM pg_stat_activity                                                                                 +
         |          |       |        |            |                         | WHERE query like '%VACUUM%'                                                                           +
         |          |       |        |            |                         | ORDER BY xact_start;                                                                                  +
```

Vários problemas podem causar uma sessão de autovacuum de longa execução (ou seja, vários dias de duração). O problema mais comum é que o valor do seu parâmetro [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) está muito baixo para o tamanho da tabela ou a taxa de atualizações. 

Recomendamos o uso da fórmula a seguir para definir o valor do parâmetro `maintenance_work_mem`.

```
GREATEST({DBInstanceClassMemory/63963136*1024},65536)
```

Sessões de autovacuum em execução por pouco tempo também podem indicar problemas:
+ Isso pode indicar que não há `autovacuum_max_workers` suficientes para sua workload. Neste caso, você precisa indicar o número de operadores.
+ Pode indicar que existe uma corrupção de índice (o autovacuum trava e reinicia na mesma relação, mas não faz nenhum progresso). Nesse caso, execute um `vacuum freeze verbose table` manual para ver a causa exata. 

# Realização de um congelamento manual de vacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze"></a>

Você pode querer realizar um vacuum manual em uma tabela que tenha um processo de vacuum já em execução. Isso é útil se você identificou uma tabela com uma idade XID próxima de 2 bilhões de transações (ou acima de qualquer limite que você esteja monitorando).

As etapas a seguir são uma orientação com diversas variações no processo. Por exemplo, durante testes, suponha que você perceba que o valor do parâmetro [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) está muito baixo e que precisa tomar medidas imediatas em uma tabela. No entanto, talvez você não queira devolver a instância no momento. Usando as consultas nas seções anteriores, você determina qual tabela é o problema e observa uma sessão de autovacuum de longa execução. Você sabe que precisa alterar a configuração do parâmetro `maintenance_work_mem`, mas também precisa tomar medidas imediatas e evacuar a tabela em questão. O procedimento a seguir mostra o que fazer nessa situação.

**Para executar manualmente um congelamento de vacuum**

1. Abra duas sessões no banco de dados que contém a tabela em que você deseja realizar vacuum. Para a segunda sessão, use "screen" ou outro utilitário que mantenha a sessão se a conexão for encerrada.

1. Na sessão um, obtenha o “Process ID” (PID – ID de processo) da sessão de autovacuum em execução na tabela. 

   Execute a seguinte consulta para obter o PID da sessão de autovacuum.

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) LIKE '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. Na sessão dois, calcule a quantidade de memória necessária para essa operação. Neste exemplo, determinamos que podemos usar até 2 GB de memória para essa operação e, portanto, definimos [https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM) da sessão atual como 2 GB.

   ```
   SET maintenance_work_mem='2 GB';
   SET
   ```

1. Na sessão dois, emita um comando `vacuum freeze verbose` para a tabela. A configuração detalhada é útil porque, embora não haja um relatório de andamento para isso no PostgreSQL, você pode ver as atividades.

   ```
   \timing on
   Timing is on.
   vacuum freeze verbose pgbench_branches;
   ```

   ```
   INFO:  vacuuming "public.pgbench_branches"
   INFO:  index "pgbench_branches_pkey" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  index "pgbench_branches_test_index" now contains 50 row versions in 2 pages
   DETAIL:  0 index row versions were removed.
   0 index pages have been deleted, 0 are currently reusable.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   INFO:  "pgbench_branches": found 0 removable, 50 nonremovable row versions 
        in 43 out of 43 pages
   DETAIL:  0 dead row versions cannot be removed yet.
   There were 9347 unused item pointers.
   0 pages are entirely empty.
   CPU 0.00s/0.00u sec elapsed 0.00 sec.
   VACUUM
   Time: 2.765 ms
   ```

1. Na sessão um, se o autovacuum estava bloqueando a sessão de vacuum, `pg_stat_activity` mostrará que a espera é `T` para a sessão de vacuum. Nesse caso, encerre o processo de autovacuum da maneira a seguir.

   ```
   SELECT pg_terminate_backend('the_pid'); 
   ```
**nota**  
Algumas versões anteriores do Amazon RDS não podem encerrar um processo de autovacuum usando o comando anterior e falham com o seguinte erro: `ERROR: 42501: must be a superuser to terminate superuser process LOCATION: pg_terminate_backend, signalfuncs.c:227`. 

   Nesse ponto, sua sessão começa. O autovacuum é reiniciado imediatamente, pois essa tabela é provavelmente a mais alta em sua lista de trabalho. 

1. Inicie seu comando `vacuum freeze verbose` na sessão dois e depois termine o processo de autovacuum na sessão um.

# Reindexação de uma tabela quando o autovacuum está em execução
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Reindexing"></a>

Se um índice se tornar corrompido, o autovacuum continuará processando a tabela e falhará. Se você tentar um vacuum manual nessa situação, receberá uma mensagem de erro semelhante à mostrada a seguir.

```
postgres=>  vacuum freeze pgbench_branches;
ERROR: index "pgbench_branches_test_index" contains unexpected 
   zero page at block 30521
HINT: Please REINDEX it.
```

Quando o índice está corrompido e o autovacuum está tentando ser executado na tabela, você lutará com uma sessão de autovacuum já em execução. Ao emitir um comando [REINDEX](https://www.postgresql.org/docs/current/static/sql-reindex.html), você remove um bloqueio exclusivo na tabela. As operações de gravação são bloqueadas, bem como as operações de leitura que usam esse índice específico.

**Para reindexar uma tabela quando o autovacuum está em execução nela**

1. Abra duas sessões no banco de dados que contém a tabela em que você deseja realizar vacuum. Para a segunda sessão, use "screen" ou outro utilitário que mantenha a sessão se a conexão for encerrada.

1. Na sessão um, obtenha o PID da sessão de autovacuum em execução na tabela.

   Execute a seguinte consulta para obter o PID da sessão de autovacuum.

   ```
   SELECT datname, usename, pid, current_timestamp - xact_start 
   AS xact_runtime, query
   FROM pg_stat_activity WHERE upper(query) like '%VACUUM%' ORDER BY 
   xact_start;
   ```

1. Na segunda sessão, emita o comando reindex.

   ```
   \timing on
   Timing is on.
   reindex index pgbench_branches_test_index;
   REINDEX
     Time: 9.966 ms
   ```

1. Na sessão um, se o autovacuum estava bloqueando o processo, você verá em `pg_stat_activity` que a espera é "T" para a sua sessão de vacuum. Nesse caso, você encerra o processo de autovacuum. 

   ```
   SELECT pg_terminate_backend('the_pid');
   ```

   Nesse ponto, sua sessão começa. É importante observar que o autovacuum é reiniciado imediatamente, pois essa tabela é provavelmente a mais alta em sua lista de trabalho. 

1. Inicie seu comando na sessão dois e depois termine o processo de autovacuum na sessão um.

# Gerenciar o autovacuum com grandes índices
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes"></a>

Como parte de sua operação, o *autovacuum* executa várias [fases de aspiração](https://www.postgresql.org/docs/current/progress-reporting.html#VACUUM-PHASES) ao trabalhar em uma tabela. Antes de a tabela ser limpa, todos os seus índices são aspirados primeiro. Ao remover vários índices grandes, essa fase consome uma quantidade significativa de tempo e recursos. Portanto, como prática recomendada, controle o número de índices em uma tabela e elimine os índices não usados.

Para esse processo, primeiro confira o tamanho geral do índice. Depois, determine se há índices possivelmente não usados que podem ser removidos conforme mostrado nos exemplos a seguir.

**Como conferir o tamanho da tabela e os respectivos índices**

```
postgres=> select pg_size_pretty(pg_relation_size('pgbench_accounts'));
pg_size_pretty
6404 MB
(1 row)
```

```
postgres=> select pg_size_pretty(pg_indexes_size('pgbench_accounts'));
pg_size_pretty
11 GB
(1 row)
```

Neste exemplo, o tamanho dos índices é maior do que a tabela. Essa diferença pode causar problemas de performance, pois os índices estão sobrecarregados ou não são usados, o que afeta as operações de autovacuum e de inserção.

**Como conferir índices não usados**

Usando a visualização [https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ALL-INDEXES-VIEW), você pode conferir com que frequência um índice é usado com a coluna `idx_scan`. No exemplo a seguir, os índices não usados têm o valor `idx_scan` de `0`.

```
postgres=> select * from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
relid  | indexrelid | schemaname | relname          | indexrelname          | idx_scan | idx_tup_read | idx_tup_fetch
-------+------------+------------+------------------+-----------------------+----------+--------------+---------------
16433  | 16454      | public     | pgbench_accounts | index_f               | 6        | 6            | 0
16433  | 16450      | public     | pgbench_accounts | index_b               | 3        | 199999       | 0
16433  | 16447      | public     | pgbench_accounts | pgbench_accounts_pkey | 0        | 0            | 0
16433  | 16452      | public     | pgbench_accounts | index_d               | 0        | 0            | 0
16433  | 16453      | public     | pgbench_accounts | index_e               | 0        | 0            | 0
16433  | 16451      | public     | pgbench_accounts | index_c               | 0        | 0            | 0
16433  | 16449      | public     | pgbench_accounts | index_a               | 0        | 0            | 0
(7 rows)
```

```
postgres=> select schemaname, relname, indexrelname, idx_scan from pg_stat_user_indexes where relname = 'pgbench_accounts' order by idx_scan desc;
    
schemaname  | relname          | indexrelname          | idx_scan
------------+------------------+-----------------------+----------
public      | pgbench_accounts | index_f               | 6
public      | pgbench_accounts | index_b               | 3
public      | pgbench_accounts | pgbench_accounts_pkey | 0
public      | pgbench_accounts | index_d               | 0
public      | pgbench_accounts | index_e               | 0
public      | pgbench_accounts | index_c               | 0
public      | pgbench_accounts | index_a               | 0
(7 rows)
```

**nota**  
Essas estatísticas são incrementais a partir do momento em que as estatísticas são redefinidas. Suponha que você tenha um índice usado apenas no final de um trimestre comercial ou apenas para um relatório específico. É possível que esse índice não tenha sido usado desde que as estatísticas foram redefinidas. Para ter mais informações, consulte [Funções de estatística](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-STATS-FUNCTIONS). Os índices usados para impor a exclusividade não terão verificações realizadas e não devem ser identificados como índices não usados. Para identificar os índices não usados, você deve ter um conhecimento profundo da aplicação e das respectivas consultas.

Para conferir quando as estatísticas foram redefinidas pela última vez em um banco de dados, use [ https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW]( https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW)

```
postgres=> select datname, stats_reset from pg_stat_database where datname = 'postgres';
    
datname   | stats_reset
----------+-------------------------------
postgres  | 2022-11-17 08:58:11.427224+00
(1 row)
```

## Aspirar uma tabela o mais rápido possível
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.Executing"></a>

**RDS para PostgreSQL 12 e posterior**

Se você tiver muitos índices em uma tabela grande, a instância de banco de dados poderá estar se aproximando do encapsulamento de ID (XID), que é quando o contador XID chega a zero. Se não for conferida, essa situação poderá ocasionar perda de dados. No entanto, você pode aspirar rapidamente a tabela sem limpar os índices. No RDS para PostgreSQL 12 e posterior, você pode usar VACUUM com a cláusula [https://www.postgresql.org/docs/current/sql-vacuum.html](https://www.postgresql.org/docs/current/sql-vacuum.html).

```
postgres=> VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) pgbench_accounts;
        
INFO: vacuuming "public.pgbench_accounts"
INFO: table "pgbench_accounts": found 0 removable, 8 nonremovable row versions in 1 out of 819673 pages
DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 7517
Skipped 0 pages due to buffer pins, 0 frozen pages.
CPU: user: 0.01 s, system: 0.00 s, elapsed: 0.01 s.
```

Se uma sessão de autovacuum já estiver em execução, você deverá encerrá-la para iniciar a aspiração manual. Para ter informações sobre a realização de um congelamento manual de aspiração, consulte [Realização de um congelamento manual de vacuum](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.VacuumFreeze.md).

**nota**  
Ignorar a limpeza do índice regularmente causa sobrecarga no índice, o que diminui a performance geral da verificação. O índice retém as linhas inativas e a tabela retém os ponteiros das linhas inativas. Consequentemente, `pg_stat_all_tables.n_dead_tup` aumenta até que o autovacuum ou um VACUUM manual com limpeza de índice seja executado. Como prática recomendada, use esse procedimento somente para evitar o encapsulamento de ID.

**RDS para PostgreSQL 11 e versões mais antigas**

No entanto, no RDS para PostgreSQL 11 e versões anteriores, a única maneira de permitir que a aspiração seja concluída mais rapidamente é reduzir o número de índices em uma tabela. A eliminação de um índice pode afetar os planos de consulta. Recomendamos que você elimine primeiro os índices não usados e, depois, descarte os índices quando o encapsulamento XID estiver muito próximo. Depois que o processo de aspiração for concluído, você poderá recriar esses índices.

# Outros parâmetros que afetam o autovacuum
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.OtherParms"></a>

A consulta a seguir mostra os valores de alguns dos parâmetros que afetam diretamente o autovacuum e seu comportamento. Os [parâmetros de autovacuum](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html) são descritos inteiramente na documentação do PostgreSQL.

```
SELECT name, setting, unit, short_desc
FROM pg_settings
WHERE name IN (
'autovacuum_max_workers',
'autovacuum_analyze_scale_factor',
'autovacuum_naptime',
'autovacuum_analyze_threshold',
'autovacuum_analyze_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_scale_factor',
'autovacuum_vacuum_threshold',
'autovacuum_vacuum_cost_delay',
'autovacuum_vacuum_cost_limit',
'vacuum_cost_limit',
'autovacuum_freeze_max_age',
'maintenance_work_mem',
'vacuum_freeze_min_age');
```

Enquanto todos estes afetem o autovacuum, alguns dos mais importantes são:
+ [maintenance\$1work\$1mem](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#GUC-MAINTENANCE_WORK_MEM)
+ [autovacuum\$1freeze\$1max\$1age](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-FREEZE-MAX-AGE)
+ [autovacuum\$1max\$1workers](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-WORKERS)
+ [autovacuum\$1vacuum\$1cost\$1delay](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-DELAY)
+ [ autovacuum\$1vacuum\$1cost\$1limit](https://www.postgresql.org/docs/current/static/runtime-config-autovacuum.html#GUC-AUTOVACUUM-VACUUM-COST-LIMIT)

# Definir parâmetros de autovacuum em nível de tabela
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.TableParameters"></a>

Você pode definir [parâmetros de armazenamento](https://www.postgresql.org/docs/current/static/sql-createtable.html#SQL-CREATETABLE-STORAGE-PARAMETERS) relacionados ao autovacuum em nível de tabela, o que pode ser melhor do que alterar o comportamento do banco de dados inteiro. Para tabelas grandes, talvez você precise definir configurações agressivas e talvez você não queira que o autovacuum se comporte dessa maneira para todas as tabelas.

A consulta a seguir mostra quais tabelas atualmente têm opções em nível de tabela.

```
SELECT relname, reloptions
FROM pg_class
WHERE reloptions IS NOT null;
```

Um exemplo em que isso pode ser útil é em tabelas que são muito maiores do que o resto das suas tabelas. Suponha que você tenha uma tabela de 300 GB e outras 30 tabelas com menos de 1 GB. Nesse caso, você pode definir alguns parâmetros específicos para a sua tabela grande, para não alterar o comportamento de todo o sistema.

```
ALTER TABLE mytable set (autovacuum_vacuum_cost_delay=0);
```

Fazer isso desativará o atraso de autovacuum baseado em custos para essa tabela, mas aumentará o uso de recursos no seu sistema. Normalmente, o autovacuum faz uma pausa durante `autovacuum_vacuum_cost_delay` sempre que `autovacuum_cost_limit` é alcançado. Para obtert mais detalhes, consulte a documentação do PostgreSQL sobre [vacuum baseado no custo](https://www.postgresql.org/docs/current/static/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-VACUUM-COST).

# Registrar atividades do autovacuum e do vacuum em log
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging"></a>

Informações sobre atividades de autovacuum são enviadas para `postgresql.log` com base no nível especificado no parâmetro `rds.force_autovacuum_logging_level`. A seguir estão os valores permitidos para esse parâmetro e as versões do PostgreSQL para as quais esse valor é a configuração padrão:
+ `disabled` (PostgreSQL 10, PostgreSQL 9.6)
+ `debug5`, `debug4`, `debug3`, `debug2`, `debug1`
+ `info` (PostgreSQL 12, PostgreSQL 11)
+ `notice`
+ `warning` (PostgreSQL 13 e superior)
+ `error`, log, `fatal`, `panic`

A configuração `rds.force_autovacuum_logging_level` funciona com o parâmetro `log_autovacuum_min_duration`. O valor do parâmetro `log_autovacuum_min_duration` é o limite (em milissegundos) acima do qual as ações autovacuum são registradas em log. Uma configuração `-1` não registra nada em log, enquanto uma configuração 0 registra todas as ações em log. Como ocorre com `rds.force_autovacuum_logging_level`, os valores padrão de `log_autovacuum_min_duration` são dependentes da versão, da seguinte maneira: 
+ `10000 ms`: PostgreSQL 14, PostgreSQL 13, PostgreSQL 12 e PostgreSQL 11 
+ `(empty)`: nenhum valor padrão para PostgreSQL 10 e PostgreSQL 9.6

Recomendamos que você defina `rds.force_autovacuum_logging_level` como `WARNING`. Também recomendamos definir `log_autovacuum_min_duration` para um valor entre 1000 e 5000. Uma configuração 5000 registra em log a atividade que leva mais de 5.000 milissegundos. Qualquer configuração diferente de -1 também registrará mensagens se a ação autovacuum for ignorada devido a um bloqueio conflitante ou relações descartadas simultaneamente. Para ter mais informações, consulte [Automatic Vacuuming](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html) (Aplicação automática do vacuum) na documentação do PostgreSQL. 

Para solucionar problemas, você pode alterar o parâmetro `rds.force_autovacuum_logging_level` para um dos níveis de depuração, de `debug1` a `debug5`, para obter informações mais detalhadas. Recomendamos que você use as configurações de depuração por curtos períodos e apenas para fins de solução de problemas. Para saber mais, consulte [When to log](https://www.postgresql.org/docs/current/static/runtime-config-logging.html#RUNTIME-CONFIG-LOGGING-WHEN) (Quando registrar em log) na documentação do PostgreSQL. 

**nota**  
O PostgreSQL permite que a conta `rds_superuser` visualize sessões de autovacuum em `pg_stat_activity`. Por exemplo, você pode identificar e encerrar uma sessão de autovacuum que esteja bloqueando a execução de um comando, ou executando de forma mais lenta do que um comando de vacuum emitido manualmente.

# Noções básicas sobre o comportamento do autovacuum com bancos de dados inválidos
<a name="appendix.postgresql.commondbatasks.autovacuumbehavior"></a>

 Um novo valor `-2` é introduzido na coluna `datconnlimit` do catálogo `pg_database` para indicar bancos de dados que foram interrompidos no meio da operação DROP DATABASE como inválidos. 

 Esse novo valor está disponível nas seguintes versões do RDS para PostgreSQL: 
+ 15.4 e todas as versões posteriores
+ 14.9 e versões posteriores
+ 13.12 e versões posteriores
+ 12.16 e versões posteriores
+ 11.21 e versões posteriores

Bancos de dados inválidos não afetam a capacidade do autovacuum de congelar a funcionalidade de bancos de dados válidos. O Autovacuum ignora bancos de dados inválidos. Consequentemente, as operações regulares de limpeza continuarão funcionando de forma adequada e eficiente em todos os bancos de dados válidos no ambiente do PostgreSQL.

**Topics**
+ [

## ID da transação de monitoramento
](#appendix.postgresql.commondbatasks.autovacuum.monitorxid)
+ [

## Ajustar a consulta de monitoramento
](#appendix.postgresql.commondbatasks.autovacuum.monitoradjust)
+ [

## Resolver o problema de banco de dados inválido
](#appendix.postgresql.commondbatasks.autovacuum.connissue)

## ID da transação de monitoramento
<a name="appendix.postgresql.commondbatasks.autovacuum.monitorxid"></a>

 A função `age(datfrozenxid)` geralmente é usada para monitorar a idade do ID de transação (XID) dos bancos de dados para evitar o encapsulamento de IDs de transação. 

 Como bancos de dados inválidos são excluídos do autovacuum, seu contador de ID de transação (XID) pode atingir o valor máximo de `2 billion`, ser encapsulado em `- 2 billion` e continuar esse ciclo indefinidamente. Uma consulta típica para monitorar o encapsulamento de IDs de transação pode ser: 

```
SELECT max(age(datfrozenxid)) FROM pg_database;
```

No entanto, com a introdução do valor -2 para `datconnlimit`, bancos de dados inválidos podem distorcer os resultados dessa consulta. Como esses bancos de dados não são válidos e não devem fazer parte das verificações de manutenção regulares, eles podem causar falsos positivos, levando você a acreditar que o `age(datfrozenxid)` é maior do que realmente é.

## Ajustar a consulta de monitoramento
<a name="appendix.postgresql.commondbatasks.autovacuum.monitoradjust"></a>

 Para garantir um monitoramento preciso, você deve ajustar sua consulta de monitoramento para excluir bancos de dados inválidos. Siga esta consulta recomendada: 

```
SELECT
    max(age(datfrozenxid))
FROM
    pg_database
WHERE
    datconnlimit <> -2;
```

Essa consulta garante que somente bancos de dados válidos sejam considerados no cálculo `age(datfrozenxid)`, fornecendo um reflexo real da idade do ID da transação no ambiente do PostgreSQL.

## Resolver o problema de banco de dados inválido
<a name="appendix.postgresql.commondbatasks.autovacuum.connissue"></a>

 Ao tentar se conectar a um banco de dados inválido, talvez seja exibida uma mensagem de erro semelhante à seguinte: 

```
postgres=> \c db1
connection to server at "mydb.xxxxxxxxxx.us-west-2.rds.amazonaws.com" (xx.xx.xx.xxx), port xxxx failed: FATAL:  cannot connect to invalid database "db1"
HINT:  Use DROP DATABASE to drop invalid databases.
Previous connection kept
```

 Além disso, se o parâmetro `log_min_messages` estiver definido como `DEBUG2` ou posterior, você poderá observar as seguintes entradas de log indicando que o processo de autovacuum está ignorando o banco de dados inválido: 

```
       
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db6"
2024-07-30 05:59:00 UTC::@:[32000]:DEBUG:  autovacuum: skipping invalid database "db1"
```

Para resolver o problema, siga a `HINT` fornecida durante a tentativa de conexão. Conecte-se a qualquer banco de dados válido usando sua conta principal do RDS ou uma conta de banco de dados com o perfil `rds_superuser` e elimine bancos de dados inválidos.

```
SELECT
    'DROP DATABASE ' || quote_ident(datname) || ';'
FROM
    pg_database
WHERE
    datconnlimit = -2 \gexec
```

# Identificar e resolver bloqueadores de limpeza agressivos no RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring"></a>

No PostgreSQL, a limpeza é vital para garantir a integridade do banco de dados, pois recupera o armazenamento e evita problemas de [conclusão do ID da transação.](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND) No entanto, há momentos em que a limpeza pode ser impedida de operar conforme desejado, o que pode resultar em degradação do desempenho e sobrecarga do armazenamento e até mesmo afetar a disponibilidade da instância de banco de dados pelo wraparound de ID de transação. Portanto, identificar e resolver esses problemas é essencial para o desempenho e a disponibilidade ideais do banco de dados. Leia [Understanding autovacuum in Amazon RDS for PostgreSQL environments](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/) para saber mais sobre o autovacuum.

A função `postgres_get_av_diag()` ajuda a identificar problemas que impedem ou atrasam o progresso da limpeza agressiva. São fornecidas sugestões, que podem incluir comandos para resolver o problema onde ele é identificável ou orientações para diagnósticos adicionais quando o problema não é identificável. Bloqueadores de limpeza agressiva são relatados quando a idade excede o limite de [autovacuum adaptativo](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming) do RDS de 500 milhões de IDs de transação.

**Qual é a idade do ID da transação?**

A função `age()` para IDs de transação calcula o número de transações que ocorreram desde o ID de transação não congelado mais antigo de um banco de dados (`pg_database.datfrozenxid`) ou tabela (`pg_class.relfrozenxid`). Esse valor indica a atividade do banco de dados desde a última operação de limpeza agressiva e destaca a provável workload para os próximos processos de VACUUM. 

**O que é uma limpeza agressiva?**

Uma operação VACUUM agressiva conduz uma varredura abrangente de todas as páginas em uma tabela, incluindo aquelas normalmente ignoradas durante operações VACUUM regulares. Essa verificação completa visa "congelar" os IDs de transação que se aproximam de sua idade máxima, evitando efetivamente uma situação conhecida como [conclusão de ID de transação](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND).

Para que `postgres_get_av_diag()` reporte bloqueadores, o bloqueador deve ter pelo menos 500 milhões de transações de idade.

**Topics**
+ [

# Instalar ferramentas de monitoramento e diagnóstico de autovacuum no RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md)
+ [

# Funções de postgres\$1get\$1av\$1diag() no RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions.md)
+ [

# Solucionar bloqueadores de limpeza identificáveis no RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md)
+ [

# Solucionar bloqueadores de limpeza não identificáveis no RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers.md)
+ [

# Resolver problemas de desempenho de limpeza no RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md)
+ [

# Explicação das mensagens de AVISO no RDS para PostgreSQL
](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)

# Instalar ferramentas de monitoramento e diagnóstico de autovacuum no RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation"></a>

No momento, a função `postgres_get_av_diag()` está disponível nas seguintes versões do RDS para PostgreSQL:
+ 17.2 e versões 17 posteriores
+ 16.7 e versões 16 posteriores
+ 15.11 e versões 15 posteriores
+ 14.16 e versões 14 posteriores
+ 13.19 e versões 13 posteriores

 Para usar `postgres_get_av_diag()`, crie a extensão `rds_tools`.

```
postgres=> CREATE EXTENSION rds_tools ;
CREATE EXTENSION
```

Para verificar se a extensão está instalada.

```
postgres=> \dx rds_tools
             List of installed extensions
   Name    | Version |  Schema   |                    Description
 ----------+---------+-----------+----------------------------------------------------------
 rds_tools |   1.8   | rds_tools | miscellaneous administrative functions for RDS PostgreSQL
 1 row
```

Verifique se a função foi criada.

```
postgres=> SELECT
    proname function_name,
    pronamespace::regnamespace function_schema,
    proowner::regrole function_owner
FROM
    pg_proc
WHERE
    proname = 'postgres_get_av_diag';
    function_name     | function_schema | function_owner
----------------------+-----------------+----------------
 postgres_get_av_diag | rds_tools       | rds_superuser
(1 row)
```

# Funções de postgres\$1get\$1av\$1diag() no RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions"></a>

A função `postgres_get_av_diag()` recupera informações de diagnóstico sobre processos de autovacuum que estão bloqueando ou atrasando em um banco de dados do RDS para PostgreSQL. A consulta precisa ser executada no banco de dados com o ID de transação mais antigo para obter resultados precisos. Para obter mais informações sobre como usar o banco de dados com o ID de transação mais antigo, consulte [Não conectado ao banco de dados com o ID de transação mais antigo](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md)

```
SELECT
    blocker,
    DATABASE,
    blocker_identifier,
    wait_event,
    TO_CHAR(autovacuum_lagging_by, 'FM9,999,999,999') AS autovacuum_lagging_by,
    suggestion,
    suggested_action
FROM (
    SELECT
        *
    FROM
        rds_tools.postgres_get_av_diag ()
    ORDER BY
        autovacuum_lagging_by DESC) q;
```

A função `postgres_get_av_diag()` retorna uma tabela com as informações a seguir:

**blocker**  
Especifica a categoria da atividade do banco de dados que está bloqueando o vacuum.  
+ [Instrução ativa](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [Ocioso na transação](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [Transação preparada](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [Slot de replicação lógica](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [Réplica de leitura com slot de replicação física](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [Réplica de leitura com replicação de streaming](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [Tabelas temporárias](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

**banco de dados**  
Especifica o nome do banco de dados, quando aplicável e suportado. Este é o banco de dados no qual a atividade está em andamento e bloqueia ou bloqueará o autovacuum. Este é o banco de dados ao qual você precisa se conectar e tomar ação.

**blocker\$1identifier**  
Especifica o identificador da atividade que está bloqueando ou bloqueará o autovacuum. O identificador pode ser um ID de processo junto com uma instrução SQL, uma transação preparada, um endereço IP de uma réplica de leitura e o nome do slot de replicação, seja lógico ou físico.

**wait\$1event**  
Especifica o [evento de espera](PostgreSQL.Tuning.md) da sessão de bloqueio e é aplicável para os seguintes bloqueadores:  
+ Instrução ativa
+ Ocioso na transação

**autovacuum\$1lagging\$1by**  
Especifica o número de transações que o autovacuum está atrasado no trabalho pendente por categoria.

**suggestion**  
Especifica sugestões para resolver o bloqueador. Essas instruções incluem o nome do banco de dados no qual a atividade existe, quando aplicável, o ID do processo (PID) da sessão, quando aplicável, e a ação a ser tomada.

**suggested\$1action**  
Sugere a ação que precisa ser tomada para resolver o bloqueador.

# Solucionar bloqueadores de limpeza identificáveis no RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Identifiableblockers"></a>

O Autovacuum realiza limpezas agressivas e reduz a idade dos IDs de transação para abaixo do limite especificado pelo parâmetro `autovacuum_freeze_max_age` de sua instância do RDS. É possível rastrear essa idade usando a métrica `MaximumUsedTransactionIDs` do Amazon CloudWatch.

Para encontrar a configuração de `autovacuum_freeze_max_age` (que tem um padrão de 200 milhões de IDs de transação) da sua instância do Amazon RDS, use a seguinte consulta:

```
SELECT
    TO_CHAR(setting::bigint, 'FM9,999,999,999') autovacuum_freeze_max_age
FROM
    pg_settings
WHERE
    name = 'autovacuum_freeze_max_age';
```

Observe que `postgres_get_av_diag()` só verifica se há bloqueadores de limpeza agressiva quando a idade excede o limite de 500 milhões de IDs de transação do [autovacuum adaptativo](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.AdaptiveAutoVacuuming) do Amazon RDS. Para que `postgres_get_av_diag()` detecte bloqueadores, o bloqueador deve ter pelo menos 500 milhões de transações de idade.

A função `postgres_get_av_diag()` identifica os seguintes tipos de bloqueadores:

**Topics**
+ [

## Instrução ativa
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement)
+ [

## Ocioso na transação
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction)
+ [

## Transação preparada
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction)
+ [

## Slot de replicação lógica
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot)
+ [

## Réplicas de leitura
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas)
+ [

## Tabelas temporárias
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables)

## Instrução ativa
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Active_statement"></a>

No PostgreSQL, uma instrução ativa é uma instrução SQL que está sendo executada atualmente pelo banco de dados. Isso inclui consultas, transações ou quaisquer operações em andamento. Ao monitorar por meio do `pg_stat_activity`, a coluna de estado indica que o processo com o PID correspondente está ativo.

A função `postgres_get_av_diag()` exibe uma saída semelhante à saída a seguir quando identifica uma instrução que é uma instrução ativa.

```
blocker               | Active statement
database              | my_database
blocker_identifier    | SELECT pg_sleep(20000);
wait_event            | Timeout:PgSleep
autovacuum_lagging_by | 568,600,871
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (29621);"}
```

**Ação sugerida**

Seguindo as orientações na coluna `suggestion`, o usuário pode se conectar ao banco de dados em que a instrução ativa está presente e, conforme especificado na coluna `suggested_action`, é recomendável analisar cuidadosamente a opção de encerrar a sessão. Se o encerramento for seguro, use a função `pg_terminate_backend()` para encerrar a sessão. Essa ação pode ser executada por um administrador (como a conta mestra do RDS) ou por um usuário com o privilégio `pg_terminate_backend()` necessário.

**Atenção**  
Uma sessão encerrada reverterá (`ROLLBACK`) as alterações feitas. Dependendo de seus requisitos, pode ser necessário executar a instrução novamente. No entanto, é recomendável fazer isso somente após o processo do autovacuum terminar a operação de limpeza agressiva.

## Ocioso na transação
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Idle_in_transaction"></a>

Uma instrução ociosa na transação se refere a qualquer sessão que abriu uma transação explícita (como emitir uma instrução `BEGIN`), realizou algum trabalho e agora está esperando que o cliente passe mais trabalho ou sinalize o final da transação emitindo um `COMMIT`, `ROLLBACK` ou `END` (o que resultaria em um `COMMIT` implícito).

A função `postgres_get_av_diag()` exibe uma saída semelhante à saída a seguir quando identifica uma instrução `idle in transaction` como um bloqueador.

```
blocker               | idle in transaction
database              | my_database
blocker_identifier    | INSERT INTO tt SELECT * FROM tt;
wait_event            | Client:ClientRead
autovacuum_lagging_by | 1,237,201,759
suggestion            | Connect to database "my_database", review carefully and you may consider terminating the process using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_terminate_backend (28438);"}
```

**Ação sugerida**

Conforme indicado na coluna `suggestion`, conecte-se ao banco de dados em que a sessão ociosa na transação está presente e encerre a sessão usando a função `pg_terminate_backend()`. O usuário pode ser seu usuário administrador (conta mestra do RDS) ou um usuário com o privilégio `pg_terminate_backend()`.

**Atenção**  
Uma sessão encerrada reverterá (`ROLLBACK`) as alterações feitas. Dependendo de seus requisitos, pode ser necessário executar a instrução novamente. No entanto, é recomendável fazer isso somente após o processo do autovacuum terminar a operação de limpeza agressiva.

## Transação preparada
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Prepared_transaction"></a>

O PostgreSQL permite transações que fazem parte de uma estratégia de confirmação bifásica chamada [transações preparadas](https://www.postgresql.org/docs/current/sql-prepare-transaction.html). Elas são habilitadas ao definir o parâmetro `max_prepared_transactions` como um valor diferente de zero. As transações preparadas são projetadas para garantir que uma transação seja durável e permaneça disponível mesmo após falhas no banco de dados, reinicializações ou desconexões do cliente. Como as transações regulares, elas recebem um ID de transação e podem afetar o autovacuum. Se deixado em um estado preparado, o autovacuum não realiza o congelamento e isso pode levar à conclusão do ID da transação.

Quando as transações são deixadas no estado de preparação indefinidamente, sem serem resolvidas por um gerenciador de transações, elas se tornam transações preparadas órfãs. A única maneira de corrigir isso é confirmar ou reverter a transação usando os comandos `COMMIT PREPARED` ou `ROLLBACK PREPARED`, respectivamente.

**nota**  
Esteja ciente de que um backup feito durante uma transação preparada ainda conterá essa transação após a restauração. Consulte as informações a seguir sobre como localizar e fechar essas transações.

A função `postgres_get_av_diag()` exibe a saída a seguir quando identifica um bloqueador que é uma transação preparada.

```
blocker               | Prepared transaction
database              | my_database
blocker_identifier    | myptx
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database" and consider either COMMIT or ROLLBACK the prepared transaction using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"COMMIT PREPARED 'myptx';",[OR],"ROLLBACK PREPARED 'myptx';"}
```

**Ação sugerida**

Conforme mencionado na coluna de sugestões, conecte-se ao banco de dados em que a transação preparada está localizada. Com base na coluna `suggested_action`, analise cuidadosamente se deseja executar `COMMIT` ou `ROLLBACK`, e então execute a ação apropriada.

Para monitorar transações preparadas em geral, o PostgreSQL oferece uma visualização de catálogo chamada `pg_prepared_xacts`. Use a consulta a seguir para encontrar transações preparadas.

```
SELECT
    gid,
    prepared,
    owner,
    database,
    transaction AS oldest_xmin
FROM
    pg_prepared_xacts
ORDER BY
    age(transaction) DESC;
```

## Slot de replicação lógica
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Logical_replication_slot"></a>

O objetivo de um slot de replicação é manter as alterações não consumidas até que elas sejam replicadas em um servidor de destino. Consulte a página sobre [replicação lógica](https://www.postgresql.org/docs/current/logical-replication.html) do PostgreSQL para obter mais informações.

Existem dois tipos de slots de replicação lógica.

**Slots de replicação lógica inativa**

Quando a replicação é encerrada, os logs de transações não consumidos não podem ser removidos e o slot de replicação fica inativo. Embora um slot de replicação lógica inativo não seja usado atualmente por um assinante, ele permanece no servidor, levando à retenção de arquivos WAL e impedindo a remoção de logs de transações antigos. Isso pode aumentar o uso do disco e, especificamente, impedir que o autovacuum limpe as tabelas internas do catálogo, pois o sistema deve evitar que as informações do LSN sejam sobrescritas. Se não for resolvido, esse problema pode resultar em inchaço do catálogo, degradação do desempenho e aumento do risco de conclusão da limpeza, potencialmente causando tempo de inatividade das transações.

**Slots de replicação lógica ativos, mas lentos**

Às vezes, a remoção de tuplas inativas do catálogo é adiada devido à degradação do desempenho da replicação lógica. Esse atraso na replicação retarda a atualização do `catalog_xmin` e pode causar inchaço do catálogo e conclusão da limpeza.

A função `postgres_get_av_diag()` exibe uma saída semelhante à saída a seguir quando encontra um slot de replicação lógica como um bloqueador.

```
blocker               | Logical replication slot
database              | my_database
blocker_identifier    | slot1
wait_event            | Not applicable
autovacuum_lagging_by | 1,940,103,068
suggestion            | Ensure replication is active and resolve any lag for the slot if active. If inactive, consider dropping it using the command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"SELECT pg_drop_replication_slot('slot1') FROM pg_replication_slots WHERE active = 'f';"}
```

**Ação sugerida**

Para resolver esse problema, verifique se há problemas com o esquema ou os dados de destino na configuração de replicação que possam estar encerrando o processo de aplicação. Os motivos mais comuns são: 
+ Colunas ausentes
+ Tipos de dados incompatíveis
+ Incompatibilidade de dados
+ Tabela ausente

Se o problema estiver relacionado a questões de infraestrutura:
+ Problemas de rede: [Como resolver problemas com um banco de dados do Amazon RDS que está em um estado de rede incompatível?](https://repost.aws/knowledge-center/rds-incompatible-network).
+ O banco de dados ou a instância de banco de dados não está disponível devido aos seguintes motivos:
  + A instância da réplica está sem armazenamento: consulte [Como resolver problemas que ocorrem quando as instâncias de banco de dados do Amazon RDS ficam sem armazenamento?](https://repost.aws/knowledge-center/rds-out-of-storage) para obter informações sobre como adicionar armazenamento.
  + Parâmetros incompatíveis: consulte [Como corrijo uma instância de banco de dados do Amazon RDS que está presa no status de parâmetros incompatíveis?](https://repost.aws/knowledge-center/rds-incompatible-parameters) para obter mais informações sobre como resolver o problema.

Se sua instância estiver fora da rede da AWS ou no AWS EC2, consulte seu administrador sobre como resolver os problemas de disponibilidade ou problemas relacionados à infraestrutura.

**Descartar o slot inativo**

**Atenção**  
Cuidado: antes de descartar um slot de replicação, verifique cuidadosamente se ele não tem nenhuma replicação em andamento, está inativo e está em um estado irrecuperável. Descartar um slot prematuramente pode interromper a replicação ou causar perda de dados.

Depois de confirmar que o slot de replicação não é mais necessário, descarte-o para permitir que o autovacuum continue. A condição `active = 'f'` garante que somente um slot inativo seja descartado.

```
SELECT pg_drop_replication_slot('slot1') WHERE active ='f'
```

## Réplicas de leitura
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Read_replicas"></a>

Quando a configuração `hot_standby_feedback` está habilitada para [réplicas de leitura do Amazon RDS](USER_PostgreSQL.Replication.ReadReplicas.md), ela impede que o autovacuum no banco de dados primário remova linhas inativas que ainda podem ser necessárias para consultas executadas na réplica de leitura. Isso afeta todos os tipos de réplicas de leitura físicas, incluindo as que são gerenciadas com ou sem slots de replicação. Esse comportamento é necessário porque as consultas executadas na réplica em espera exigem que essas linhas permaneçam disponíveis no primário, evitando [conflitos de consultas](https://www.postgresql.org/docs/current/hot-standby.html#HOT-STANDBY-CONFLICT) e cancelamentos.

**Réplica de leitura com slot de replicação física**  
As réplicas de leitura com slots de replicação física aumentam significativamente a confiabilidade e a estabilidade da replicação no RDS para PostgreSQL. Esses slots garantem que o banco de dados primário retenha os arquivos essenciais do log de gravação antecipada até que a réplica os processe, mantendo a consistência de dados mesmo durante interrupções na rede.

A partir do RDS para PostgreSQL versão 14, todas as réplicas utilizam slots de replicação. Nas versões anteriores, somente réplicas entre regiões usavam slots de replicação.

A função `postgres_get_av_diag()` exibe uma saída semelhante à saída a seguir quando encontra uma réplica de leitura com slot de replicação física como um bloqueador.

```
blocker               | Read replica with physical replication slot
database              |
blocker_identifier    | rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxxx
wait_event            | Not applicable
autovacuum_lagging_by | 554,080,689
suggestion            | Run the following query on the replica "rds_us_west_2_db_xxxxxxxxxxxxxxxxxxxx" to find the long running query:                           
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;                                                       
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                 +                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 757989377;","                                                                                 +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                   +
                      | [OR]                                                                                                                                                                                                 +
                      | ","Delete the read replica if not needed"}
```

**Réplica de leitura com replicação de streaming**  
O Amazon RDS permite configurar réplicas de leitura sem um slot de replicação física em versões mais antigas, até a versão 13. Essa abordagem reduz a sobrecarga ao permitir que o primário recicle arquivos WAL de forma mais agressiva, o que é vantajoso em ambientes com espaço em disco limitado e que podem tolerar ReplicaLag ocasional. No entanto, sem um slot, o standby deve permanecer sincronizado para evitar a perda de arquivos WAL. O Amazon RDS usa arquivos WAL arquivados para ajudar a réplica a se recuperar caso ela fique atrasada, mas esse processo exige monitoramento cuidadoso e pode ser lento.

A função `postgres_get_av_diag()` exibe uma saída semelhante à saída a seguir quando encontra uma réplica de leitura de streaming como um bloqueador.

```
blocker               | Read replica with streaming replication slot
database              | Not applicable
blocker_identifier    | xx.x.x.xxx/xx
wait_event            | Not applicable
autovacuum_lagging_by | 610,146,760
suggestion            | Run the following query on the replica "xx.x.x.xxx" to find the long running query:                                                                                                                                                         +
                      | SELECT * FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;                                                                                                                                                     +
                      | Review carefully and you may consdier terminating the query on read replica using suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.                                       +
                      |
suggested_action      | {"SELECT pg_terminate_backend(pid) FROM pg_catalog.pg_stat_activity WHERE backend_xmin::text::bigint = 348319343;","                                                                                                                        +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Disable hot_standby_feedback","                                                                                                                                                                                                          +
                      | [OR]                                                                                                                                                                                                                                        +
                      | ","Delete the read replica if not needed"}
```

**Ação sugerida**

Conforme recomendado na coluna `suggested_action`, analise cuidadosamente essas opções para desbloquear o autovacuum.
+ **Encerrar a consulta**: seguindo as orientações na coluna de sugestões, é possível se conectar à réplica de leitura, conforme especificado na coluna suggested\$1action. É recomendável analisar cuidadosamente a opção de encerrar a sessão. Se o encerramento for considerado seguro, use a função `pg_terminate_backend()` para encerrar a sessão. Essa ação pode ser executada por um administrador (como a conta mestra do RDS) ou por um usuário com o privilégio pg\$1terminate\$1backend() necessário.

  Execute o comando SQL a seguir na réplica de leitura para encerrar a consulta que está impedindo a limpeza das linhas antigas no primário. O valor de `backend_xmin` é reportado na saída da função:

  ```
  SELECT
      pg_terminate_backend(pid)
  FROM
      pg_catalog.pg_stat_activity
  WHERE
      backend_xmin::text::bigint = backend_xmin;
  ```
+ **Desabilitar o feedback de standby a quente**: considere desabilitar o parâmetro `hot_standby_feedback` se ele estiver causando atrasos significativos na limpeza.

  O parâmetro `hot_standby_feedback` permite que uma réplica de leitura informe o primário sobre sua atividade de consulta, impedindo que o primário faça a limpeza de tabelas ou linhas que estão em uso no standby. Embora isso garanta a estabilidade da consulta no standby, pode atrasar significativamente a limpeza no primário. Desabilitar esse recurso permite que o primário prossiga com a limpeza sem esperar que o standby se atualize. No entanto, isso pode levar a cancelamentos de consultas ou falhas no standby se ele tentar acessar linhas que foram removidas pela limpeza no primário.
+ **Excluir a réplica de leitura se não for necessária**: se a réplica de leitura não for mais necessária, você poderá exclui-la. Isso removerá a sobrecarga de replicação associada e permitirá que o primário recicle os logs de transações sem ser retido pela réplica.

## Tabelas temporárias
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Temporary_tables"></a>

[Tabelas temporárias](https://www.postgresql.org/docs/current/sql-createtable.html), criadas usando a palavra-chave `TEMPORARY`, residem no esquema temporário, por exemplo pg\$1temp\$1xxx, e só podem ser acessadas pela sessão que as criou. As tabelas temporárias são removidas quando a sessão termina. No entanto, essas tabelas são invisíveis para o processo de autovacuum do PostgreSQL e devem ser limpas manualmente pela sessão que as criou. Tentar limpar a tabela temporária de outra sessão não tem efeito.

Em circunstâncias incomuns, uma tabela temporária pode existir sem uma sessão ativa que a possua. Se a sessão proprietária terminar inesperadamente devido a uma falha fatal, problemas de rede ou eventos do tipo, a tabela temporária pode não ser limpa, deixando-a como uma tabela "órfã". Quando o processo de autovacuum do PostgreSQL detecta uma tabela temporária órfã, ele registra em log a seguinte mensagem:

```
LOG: autovacuum: found orphan temp table \"%s\".\"%s\" in database \"%s\"
```

A função `postgres_get_av_diag()` exibe uma saída semelhante à saída a seguir quando identifica uma tabela temporária como um bloqueador. Para que a função exiba corretamente a saída relacionada às tabelas temporárias, ela precisa ser executada no mesmo banco de dados em que essas tabelas existem.

```
blocker               | Temporary table
database              | my_database
blocker_identifier    | pg_temp_14.ttemp
wait_event            | Not applicable
autovacuum_lagging_by | 1,805,802,632
suggestion            | Connect to database "my_database". Review carefully, you may consider dropping temporary table using command in suggested_action. For more information, see Working with PostgreSQL autovacuum in the Amazon RDS User Guide.
suggested_action      | {"DROP TABLE ttemp;"}
```

**Ação sugerida**

Siga as instruções fornecidas na coluna `suggestion` da saída para identificar e remover a tabela temporária que está impedindo a execução do autovacuum. Use o comando a seguir para eliminar a tabela temporária reportada por `postgres_get_av_diag()`. Substitua o nome da tabela com base na saída fornecida pela função `postgres_get_av_diag()`.

```
DROP TABLE my_temp_schema.my_temp_table;
```

A seguinte consulta pode ser usada para identificar tabelas temporárias:

```
SELECT
    oid,
    relname,
    relnamespace::regnamespace,
    age(relfrozenxid)
FROM
    pg_class
WHERE
relpersistence = 't'
ORDER BY
    age(relfrozenxid) DESC;
```

# Solucionar bloqueadores de limpeza não identificáveis no RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Unidentifiable_blockers"></a>

Esta seção explora razões adicionais que podem impedir o progresso da limpeza. Esses problemas atualmente não são diretamente identificáveis pela função `postgres_get_av_diag()`. 

**Topics**
+ [

## Páginas inválidas
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages)
+ [

## Inconsistência do índice
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency)
+ [

## Taxa de transação excepcionalmente alta
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate)

## Páginas inválidas
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages"></a>

Um erro de página inválida ocorre quando o PostgreSQL detecta uma incompatibilidade na soma de verificação de uma página ao acessá-la. O conteúdo é ilegível, impedindo que o autovacuum congele as tuplas. Isso efetivamente interrompe o processo de limpeza. O seguinte erro é registrado no log do PostgreSQL:

```
WARNING:  page verification failed, calculated checksum YYYYY but expected XXXX
ERROR:  invalid page in block ZZZZZ of relation base/XXXXX/XXXXX
CONTEXT:  automatic vacuum of table myschema.mytable
```

**Determinar o tipo de objeto**

```
ERROR: invalid page in block 4305910 of relation base/16403/186752608 
WARNING: page verification failed, calculated checksum 50065 but expected 60033
```

A partir da mensagem de erro, o caminho `base/16403/186752608` fornece as seguintes informações:
+ "base" é o nome do diretório sob o diretório de dados do PostgreSQL.
+ "16403" é o OID do banco de dados, que você pode consultar no catálogo do sistema `pg_database`.
+ "186752608" é o `relfilenode`, que você pode usar para pesquisar o esquema e o nome do objeto no catálogo do sistema `pg_class`.

Ao verificar a saída da consulta a seguir no banco de dados afetado, será possível determinar o tipo de objeto. A consulta a seguir recupera informações do objeto para oid: 186752608. Substitua o OID pelo relevante para o erro que você encontrou.

```
SELECT
    relname AS object_name,
    relkind AS object_type,
    nspname AS schema_name
FROM
    pg_class c
    JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE
    c.oid = 186752608;
```

Para obter mais informações, consulte a documentação do PostgreSQL [https://www.postgresql.org/docs/current/catalog-pg-class.html](https://www.postgresql.org/docs/current/catalog-pg-class.html) para ver todos os tipos de objetos compatíveis, indicados pela coluna `relkind` em `pg_class`.

**Orientação**

A solução mais eficaz para esse problema depende da configuração da instância específica do Amazon RDS e do tipo de dados afetados pela página inconsistente.

**Se o tipo de objeto for um índice:**

É recomendável reconstruir o índice.
+ **Usar a opção `CONCURRENTLY`**: antes da versão 12 do PostgreSQL, a reconstrução de um índice exigia um bloqueio de tabela exclusivo, restringindo o acesso à tabela. Com a versão 12 e posteriores do PostgreSQL, a opção `CONCURRENTLY` permite o bloqueio em nível de linha, melhorando significativamente a disponibilidade da tabela. Este é o comando:

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  Embora `CONCURRENTLY` seja menos disruptivo, pode ser mais lento em tabelas acessadas com frequência. Considere construir o índice durante períodos de baixo tráfego, se possível.

  Para obter mais informações, consulte a documentação [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html) do PostgreSQL.
+ **Usar a opção `INDEX_CLEANUP FALSE`**: se os índices forem grandes e, segundo sua avaliação, exigirem muito tempo para serem concluídos, é possível desbloquear o autovacuum executando um `VACUUM FREEZE` manual ao excluir os índices. Essa funcionalidade está disponível na versão 12 e versões posteriores do PostgreSQL. 

  Ignorar os índices permitirá que você pule o processo de limpeza do índice inconsistente e mitigue o problema de conclusão. No entanto, isso não resolverá o problema subjacente da página inválida. Para abordar e resolver totalmente o problema da página inválida, ainda será necessário reconstruir o índice.

**Se o tipo de objeto for uma visão materializada:**

Se ocorrer um erro de página inválida em uma visão materializada, faça login no banco de dados afetado e atualize-a para resolver a página inválida:

Atualize a visão materializada.

```
REFRESH MATERIALIZED VIEW schema_name.materialized_view_name;
```

Se a atualização falhar, tente recriar:

```
DROP MATERIALIZED VIEW schema_name.materialized_view_name;
CREATE MATERIALIZED VIEW schema_name.materialized_view_name AS query;
```

Atualizar ou recriar a visão materializada a restaura sem afetar os dados da tabela subjacente.

**Para todos os outros tipos de objetos:**

Para todos os outros tipos de objetos, entre em contato com o AWS Support.

## Inconsistência do índice
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Index_inconsistency"></a>

Um índice logicamente inconsistente pode impedir que o autovacuum progrida. Os seguintes erros ou erros semelhantes são registrados em log durante a fase de limpeza do índice ou quando o índice é acessado por instruções SQL.

```
ERROR: right sibling's left-link doesn't match:block 5 links to 10 instead of expected 2 in index ix_name
```

```
ERROR: failed to re-find parent key in index "XXXXXXXXXX" for deletion target page XXX
CONTEXT:  while vacuuming index index_name of relation schema.table
```

**Orientação**

Reconstrua o índice ou pule índices usando `INDEX_CLEANUP` no manual `VACUUM FREEZE`. Para obter informações sobre como reconstruir o índice, consulte [Se o tipo de objeto for um índice](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Invalid_pages).
+ **Usar a opção CONCURRENTLY**: antes da versão 12 do PostgreSQL, a reconstrução de um índice exigia um bloqueio de tabela exclusivo, restringindo o acesso à tabela. Com a versão 12 e posteriores do PostgreSQL, a opção CONCURRENTLY permite o bloqueio em nível de linha, melhorando significativamente a disponibilidade da tabela. Este é o comando:

  ```
  REINDEX INDEX ix_name CONCURRENTLY;
  ```

  Embora CONCURRENTLY seja menos disruptivo, pode ser mais lento em tabelas acessadas com frequência. Considere construir o índice durante períodos de baixo tráfego, se possível. Para ter mais informações, consulte a documentação [REINDEX](https://www.postgresql.org/docs/current/sql-reindex.html) do *PostgreSQL*.
+ **Usar a opção INDEX\$1CLEANUP FALSE**: se os índices forem grandes e, segundo sua avaliação, exigirem muito tempo para serem concluídos, é possível desbloquear o autovacuum executando um VACUUM FREEZE manual ao excluir os índices. Essa funcionalidade está disponível na versão 12 e versões posteriores do PostgreSQL.

  Ignorar os índices permitirá que você pule o processo de limpeza do índice inconsistente e mitigue o problema de conclusão. No entanto, isso não resolverá o problema subjacente da página inválida. Para abordar e resolver totalmente o problema da página inválida, ainda será necessário reconstruir o índice.

## Taxa de transação excepcionalmente alta
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.High_transaction_rate"></a>

No PostgreSQL, altas taxas de transação podem afetar significativamente o desempenho do autovacuum, levando a uma limpeza mais lenta das tuplas inativas e ao aumento do risco de conclusão do ID da transação. É possível monitorar a taxa de transação medindo a diferença em `max(age(datfrozenxid))` entre dois períodos, normalmente por segundo. Além disso, é possível usar as métricas de contador do Insights de Performance do RDS a seguir para medir a taxa de transação (a soma de xact\$1commit e xact\$1rollback), que é o número total de transações.


|  Contador  |  Type  |  Unidade  |  Métrica  | 
| --- | --- | --- | --- | 
|  xact\$1commit  |  Transações  |  Confirmações por segundo  |  db.Transactions.xact\$1commit  | 
|  xact\$1rollback  |  Transações  |  Reversões por segundo  |  db.Transactions.xact\$1rollback  | 

Um aumento rápido indica uma alta carga de transações, que pode sobrecarregar o autovacuum, causando sobrecarga, contenção de bloqueios e possíveis problemas de desempenho. Isso pode impactar negativamente o processo de autovacuum de duas maneiras:
+ **Atividade da tabela:** a tabela específica que está sendo limpa pode estar passando por um alto volume de transações, causando atrasos.
+ **Recursos do sistema:** o sistema geral pode estar sobrecarregado, dificultando que o autovacuum acesse os recursos necessários para funcionar com eficiência.

Considere as seguintes estratégias para permitir que o autovacuum opere com mais eficiência e acompanhe suas tarefas:

1. Reduza a taxa de transação, se possível. Considere agrupar transações semelhantes sempre que possível.

1. Defina tabelas atualizadas com frequência com a operação `VACUUM FREEZE` manual noturna, semanal ou quinzenal durante horários de baixo movimento. 

1. Considere aumentar a escala verticalmente da classe de instância para alocar mais recursos do sistema para lidar com o alto volume de transações e o autovacuum.

# Resolver problemas de desempenho de limpeza no RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance"></a>

Esta seção discute os fatores que geralmente contribuem para um desempenho mais lento de limpeza e como resolvê-los.

**Topics**
+ [

## Limpeza em índices grandes
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes)
+ [

## Muitas tabelas ou bancos de dados para limpar
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables)
+ [

## A limpeza agressiva (para evitar conclusão) está em execução
](#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)

## Limpeza em índices grandes
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Large_indexes"></a>

O VACUUM opera em fases sequenciais: inicialização, verificação do heap, índice e limpeza do heap, limpeza de índices, truncamento de heap e limpeza final. Durante a verificação do heap, o processo remove, desfragmenta e congela páginas. Depois que o heap é verificado, o VACUUM limpa os índices, devolve páginas vazias ao sistema operacional e realiza tarefas finais de limpeza, como limpar o mapa de espaço livre e atualizar as estatísticas.

A limpeza de índice pode exigir várias passagens quando `maintenance_work_mem` (ou `autovacuum_work_mem`) é insuficiente para processar o índice. No PostgreSQL 16 e anterior, um limite de memória de 1 GB para armazenar IDs de tuplas mortas geralmente forçava várias passagens em índices grandes. O PostgreSQL 17 introduz o `TidStore`, que aloca memória dinamicamente em vez de usar uma matriz de alocação única. Isso remove a restrição de 1 GB, usa a memória com maior eficiência e reduz a necessidade de várias verificações para cada índice.

Índices grandes ainda podem exigir várias passagens no PostgreSQL 17 se a memória disponível não for suficiente para o processamento completo do índice de uma só vez. Normalmente, os índices maiores contêm mais tuplas mortas que exigem várias passagens.

**Detectar operações de limpeza lentas**

A função `postgres_get_av_diag()` pode detectar quando a execução de operações de limpeza está lenta devido a memória insuficiente. Para ter mais informações sobre essa função, consulte [Instalar ferramentas de monitoramento e diagnóstico de autovacuum no RDS para PostgreSQL](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Installation.md).

A função `postgres_get_av_diag()` emite os avisos a seguir quando a memória disponível não é suficiente para concluir a limpeza do índice em uma única passagem.

**`rds_tools` 1.8**

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_work_mem is "XXX" and might not be sufficient. Consider increasing the setting, and if necessary, scaling up the Amazon RDS instance class for more memory. 
        Additionally, review the possibility of manual vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;).
```

**`rds_tools` 1.9**

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_work_mem is XX might not be sufficient. Consider increasing the setting to XXX, and if necessary, scaling up the RDS instance class for more 
        memory. The suggested value is an estimate based on the current number of dead tuples for the table being vacuumed, which might not fully reflect the latest state. Additionally, review the possibility of manual 
        vacuum with exclusion of indexes using (VACUUM (INDEX_CLEANUP FALSE, VERBOSE TRUE) table_name;). For more information, see 
        [Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)
        .
```

**nota**  
A função `postgres_get_av_diag()` depende do `pg_stat_all_tables.n_dead_tup` para estimar a quantidade de memória necessária para a limpeza do índice.

Quando a função `postgres_get_av_diag()` identificar uma operação de limpeza lenta que requer várias verificações do índice devido a `autovacuum_work_mem` insuficiente, ela gerará a seguinte mensagem:

```
NOTICE: Your vacuum is performing multiple index scans due to insufficient autovacuum_work_mem:XXX for index vacuuming. 
        For more information, see [Working with PostgreSQL autovacuum in the Amazon Amazon RDS User Guide](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html).
```

**Orientação**

Você pode aplicar as soluções alternativas a seguir usando o `VACUUM FREEZE` manual para acelerar o congelamento da tabela.

**Aumentar a memória para limpeza**

Conforme sugerido pela função `postgres_get_av_diag()`, é recomendável aumentar o parâmetro `autovacuum_work_mem` para lidar com possíveis restrições de memória no nível da instância. Embora `autovacuum_work_mem` seja um parâmetro dinâmico, é importante observar que, para que a nova configuração de memória entre em vigor, o daemon autovacuum precisa reiniciar seus processos. Para fazer isso:

1. Confirme se a nova configuração está em vigor.

1. Encerre os processos que estão executando o autovacuum.

Essa abordagem garante que a alocação de memória ajustada seja aplicada às novas operações do autovacuum.

Para obter resultados mais imediatos, considere realizar manualmente uma operação `VACUUM FREEZE` com uma configuração `maintenance_work_mem` maior em sua sessão:

```
SET maintenance_work_mem TO '1GB';
VACUUM FREEZE VERBOSE table_name;
```

Se você estiver usando o Amazon RDS e notar que precisa de memória adicional para oferecer suporte a valores mais altos para `maintenance_work_mem` ou `autovacuum_work_mem`, considere fazer upgrade para uma classe de instância com mais memória. Isso pode fornecer os recursos necessários para aprimorar as operações de limpeza manuais e automáticas, levando a um melhor desempenho geral da limpeza e do banco de dados.

**Desativar INDEX\$1CLEANUP**

O `VACUUM` manual no PostgreSQL versão 12 e posteriores permite pular a fase de limpeza do índice, enquanto o autovacuum de emergência no PostgreSQL versão 14 e posteriores faz isso automaticamente com base no parâmetro [https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-VACUUM-FAILSAFE-AGE).

**Atenção**  
Pular a etapa de limpeza do índice pode causar inchaço no índice e afetar negativamente o desempenho da consulta. Para mitigar isso, considere reindexar ou fazer limpeza nos índices afetados durante uma janela de manutenção.

Para obter orientação adicional sobre como lidar com índices grandes, consulte a documentação em [Gerenciar o autovacuum com grandes índices](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.md).

**Limpeza paralelo de índices**

Desde o PostgreSQL 13, os índices podem ser limpos em paralelo por padrão usando o `VACUUM` manual, com um processo de operação de limpeza atribuído a cada índice. No entanto, para que o PostgreSQL determine se uma operação de limpeza se qualifica para execução paralela, critérios específicos devem ser atendidos:
+ Deve haver pelo menos dois índices.
+ O parâmetro `max_parallel_maintenance_workers` deve ser definido como no mínimo 2.
+ O tamanho do índice deve exceder o limite `min_parallel_index_scan_size`, que por padrão é 512 KB.

É possível ajustar a configuração `max_parallel_maintenance_workers` com base no número de vCPUs disponíveis na sua instância do Amazon RDS e no número de índices na tabela para otimizar o tempo de resposta da limpeza.

Para obter mais informações, consulte [Parallel vacuuming in Amazon RDS for PostgreSQL and Amazon Aurora PostgreSQL](https://aws.amazon.com/blogs/database/parallel-vacuuming-in-amazon-rds-for-postgresql-and-amazon-aurora-postgresql/).

## Muitas tabelas ou bancos de dados para limpar
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Multiple_tables"></a>

Conforme mencionado na documentação [The Autovacuum Daemon](https://www.postgresql.org/docs/current/routine-vacuuming.html#AUTOVACUUM') do PostgreSQL, o daemon autovacuum é executado por meio de vários processos. Isso inclui um inicializador persistente de autovacuum, responsável por iniciar os processos de trabalho de autovacuum para cada banco de dados do sistema. O inicializador programa esses trabalhadores para iniciarem aproximadamente a cada `autovacuum_naptime` segundos por banco de dados.

Com 'N' bancos de dados, um novo trabalhador começa aproximadamente a cada [`autovacuum_naptime`/N segundos]. No entanto, o número total de trabalhadores simultâneos é limitado pela configuração `autovacuum_max_workers`. Se o número de bancos de dados ou tabelas que precisam ser limpos exceder esse limite, o próximo banco de dados ou tabela será processado assim que um trabalhador estiver disponível.

Quando muitas tabelas ou bancos de dados grandes precisam ser limpos simultaneamente, todos os trabalhadores de autovacuum disponíveis podem ficar ocupados por um longo período, atrasando a manutenção em outras tabelas e bancos de dados. Em ambientes com altas taxas de transação, esse gargalo pode aumentar rapidamente e potencialmente levar a problemas de conclusão de limpeza em sua instância do Amazon RDS.

Quando o `postgres_get_av_diag()` detecta um grande número de tabelas ou bancos de dados, ele fornece a seguinte recomendação:

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound and it might be slow.
```

```
NOTICE: The current setting of autovacuum_max_workers:3 might not be sufficient. Consider increasing the setting and, if necessary, consider scaling up the Amazon RDS instance class for more workers.
```

**Orientação**

**Aumentar autovacuum\$1max\$1workers**

Para agilizar a limpeza, recomendamos ajustar o parâmetro `autovacuum_max_workers` para permitir mais trabalhadores simultâneos de autovacuum. Se os gargalos de desempenho persistirem, considere aumentar a escala verticalmente de sua instância do Amazon RDS para uma classe com mais vCPUs, o que pode melhorar ainda mais as capacidades de processamento paralelo.

## A limpeza agressiva (para evitar conclusão) está em execução
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum"></a>

A idade do banco de dados (MaximumUsedTransactionIDs) no PostgreSQL só diminui quando uma limpeza agressiva (para evitar conclusão) é concluída com sucesso. Até que essa limpeza termine, a idade continuará aumentando dependendo da taxa de transação.

A função `postgres_get_av_diag()` gera o seguinte `NOTICE` quando detecta uma limpeza agressiva. No entanto, ela só aciona essa saída depois que a limpeza estiver ativa por pelo menos dois minutos.

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```

Consulte [When an aggressive vacuum is already running](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE.md) para obter mais informações sobre a limpeza agressiva.

Use a seguinte consulta para verificar se uma limpeza agressiva está em andamento:

```
SELECT
    a.xact_start AS start_time,
    v.datname "database",
    a.query,
    a.wait_event,
    v.pid,
    v.phase,
    v.relid::regclass,
    pg_size_pretty(pg_relation_size(v.relid)) AS heap_size,
    (
        SELECT
            string_agg(pg_size_pretty(pg_relation_size(i.indexrelid)) || ':' || i.indexrelid::regclass || chr(10), ', ')
        FROM
            pg_index i
        WHERE
            i.indrelid = v.relid
    ) AS index_sizes,
    trunc(v.heap_blks_scanned * 100 / NULLIF(v.heap_blks_total, 0)) AS step1_scan_pct,
    v.index_vacuum_count || '/' || (
        SELECT
            count(*)
        FROM
            pg_index i
        WHERE
            i.indrelid = v.relid
    ) AS step2_vacuum_indexes,
    trunc(v.heap_blks_vacuumed * 100 / NULLIF(v.heap_blks_total, 0)) AS step3_vacuum_pct,
    age(CURRENT_TIMESTAMP, a.xact_start) AS total_time_spent_sofar
FROM
    pg_stat_activity a
    INNER JOIN pg_stat_progress_vacuum v ON v.pid = a.pid;
```

É possível determinar se é uma limpeza agressiva (para evitar conclusão) verificando a coluna de consulta na saída. A frase "para evitar conclusão" indica que se trata de uma limpeza agressiva.

```
query                  | autovacuum: VACUUM public.t3 (to prevent wraparound)
```

Por exemplo, suponha que você tenha um bloqueador com idade de transação de 1 bilhão e uma tabela exigindo uma limpeza agressiva para evitar conclusão na mesma idade da transação. Além disso, há outro bloqueador com idade de transação de 750 milhões. Depois de eliminar o bloqueador com idade de transação de 1 bilhão, a idade de transação não cairá imediatamente para 750 milhões. Ela permanecerá alta até que a tabela que precise da limpeza agressiva ou qualquer transação com idade superior a 750 milhões seja concluída. Durante esse período, a idade das transações do cluster do PostgreSQL continuará aumentando. Quando o processo de limpeza for concluído, a idade da transação cairá para 750 milhões, mas começará a aumentar novamente até que a limpeza adicional seja concluída. Esse ciclo continuará enquanto essas condições persistirem, até que a idade da transação caia para o nível configurado na instância do Amazon RDS, especificado por `autovacuum_freeze_max_age`.

# Explicação das mensagens de AVISO no RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.NOTICE"></a>

 A função `postgres_get_av_diag()` fornece as seguintes mensagens de AVISO:

**Quando a idade ainda não atingiu o limite de monitoramento**  
O limite de monitoramento de `postgres_get_av_diag()` para identificar bloqueadores é de 500 milhões de transações por padrão. Se `postgres_get_av_diag()` gerar o seguinte AVISO, isso indica que a idade da transação ainda não atingiu esse limite.  

```
NOTICE: postgres_get_av_diag() checks for blockers that prevent aggressive vacuums only, it does so only after exceeding dvb_threshold which is 500,000,000 and age of this PostgreSQL cluster is currently at 2.
```

**Não conectado ao banco de dados com o ID de transação mais antigo**  
A função `postgres_get_av_diag()` fornece a saída mais precisa quando conectada ao banco de dados com a idade de ID de transação mais antiga. O banco de dados com a idade de ID de transação mais antiga informada por `postgres_get_av_diag()` será diferente de “my\$1database” no seu caso. Se você não estiver conectado ao banco de dados correto, o seguinte AVISO será gerado:  

```
NOTICE: You are not connected to the database with the age of oldest transaction ID. Connect to my_database database and run postgres_get_av_diag() for accurate reporting.
```
Conectar-se ao banco de dados com a idade de transação mais antiga é importante pelos seguintes motivos:  
+ **Identificação de bloqueadores de tabelas temporárias:** como os metadados das tabelas temporárias são específicos de cada banco de dados, eles geralmente são encontrados no banco de dados em que foram criados. No entanto, se uma tabela temporária for o principal bloqueador e residir no banco de dados com a transação mais antiga, isso pode ser enganoso. A conexão com o banco de dados correto garante a identificação precisa do bloqueador de tabelas temporárias.
+ **Diagnóstico de vacuums lentos:** os metadados do índice e as informações de contagem de tabelas são específicos do banco de dados e necessários para diagnosticar problemas de vacuum lento.

**O banco de dados com a transação mais antiga por idade está em um banco de dados rdsadmin ou template0**  
Em alguns casos, os bancos de dados `rdsadmin` ou `template0` podem ser identificados como o banco de dados com a idade de ID de transação mais antiga. Se isso acontecer, `postgres_get_av_diag()` emitirá o seguinte AVISO:  

```
NOTICE: The database with the age of oldest transaction ID is rdsadmin or template0, reach out to support if the reported blocker is in rdsadmin or template0.
```
Verifique se o bloqueador listado não é originário de nenhum desses dois bancos de dados. Se for relatado que o bloqueador está presente em `rdsadmin` ou `template0`, entre em contato com o suporte, pois esses bancos de dados não são acessíveis ao usuário e exigem intervenção.  
É altamente improvável que o banco de dados `rdsadmin` ou `template0` contenha um bloqueador principal.

**Quando um vacuum agressivo já está em execução**  
A função `postgres_get_av_diag()` foi projetada para relatar quando um processo de vacuum agressivo está em execução, mas ela só vai acionar essa saída depois que o vacuum estiver ativo por pelo menos 1 minuto. Esse atraso intencional ajuda a reduzir as chances de falsos positivos. Ao esperar, a função garante que somente vacuums efetivos e significativos sejam relatados, levando a um monitoramento mais preciso e confiável da atividade do vacuum.  
A função `postgres_get_av_diag()` gera o seguinte AVISO quando detecta um ou mais vacuums agressivos em andamento.   

```
NOTICE: Your database is currently running aggressive vacuum to prevent wraparound, monitor autovacuum performance.
```
Conforme indicado no AVISO, continue monitorando o desempenho do vacuum. Para obter mais informações sobre o vacuum agressivo, consulte [A limpeza agressiva (para evitar conclusão) está em execução](Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Resolving_Performance.md#Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Aggressive_vacuum)

**Quando o autovacuum está desativado**  
A função `postgres_get_av_diag()` vai gerar o seguinte AVISO se o autovacuum estiver desativado na instância de banco de dados:  

```
NOTICE: Autovacuum is OFF, we strongly recommend to enable it, no restart is necessary.
```
O autovacuum é um recurso essencial da instância de banco de dados do RDS para PostgreSQL que garante uma operação tranquila do banco de dados. Ele remove automaticamente as versões antigas das linhas, recupera espaço de armazenamento e evita o inchaço das tabelas, ajudando a manter as tabelas e os índices eficientes para um desempenho ideal. Além disso, ele protege contra o wraparound de ID de transação, que pode interromper transações na instância do Amazon RDS. A desativação do autovacuum pode levar a quedas de longo prazo no desempenho e na estabilidade do banco de dados. Sugerimos que você o mantenha ativado sempre. Para ter mais informações, consulte [Understanding autovacuum in RDS for PostgreSQL environments](https://aws.amazon.com/blogs/database/understanding-autovacuum-in-amazon-rds-for-postgresql-environments/).  
O desligamento do autovacuum não impede os vacuums agressivos. Estes ainda ocorrerão quando as tabelas atingirem o limite de `autovacuum_freeze_max_age`. 

**O número de transações restantes é criticamente baixo**  
A função `postgres_get_av_diag()` gera o seguinte AVISO quando um vacuum wraparound é iminente. Este AVISO é emitido quando a instância do Amazon RDS está a 100 milhões de transações de possivelmente rejeitar novas transações.  

```
WARNING: Number of transactions remaining is critically low, resolve issues with autovacuum or perform manual VACUUM FREEZE before your instance stops accepting transactions.
```
Sua ação imediata é necessária para evitar tempo de inatividade do banco de dados. Você deve monitorar de perto suas operações de vacuum e considerar iniciar manualmente um `VACUUM FREEZE` no banco de dados afetado para evitar falhas nas transações.

# Gerenciar contagens altas de objeto no Amazon RDS para PostgreSQL
<a name="PostgreSQL.HighObjectCount"></a>

Embora as limitações do PostgreSQL sejam teóricas, ter contagens de objetos extremamente altas em um banco de dados causará um impacto perceptível no desempenho de várias operações. Esta documentação aborda vários tipos comuns de objeto que podem causar vários impactos possíveis quando a contagem total é alta.

A seguinte tabela apresenta um resumo dos tipos de objeto e dos possíveis impactos.


**Tipos de objeto e possíveis impactos**  

| Tipo de objeto | Autovacuum | Replicação lógica | Atualização de versão principal | pg\$1dump/pg\$1restore | Desempenho geral | Reinicialização da instância | 
| --- | --- | --- | --- | --- | --- | --- | 
| [Relações](#PostgreSQL.HighObjectCount.Relations) | x |  | x | x | x |  | 
| [Tabelas temporárias](#PostgreSQL.HighObjectCount.TempTables) | x |  |  |  | x |  | 
| [Tabelas não registradas](#PostgreSQL.HighObjectCount.UnloggedTables) |  | x |  |  |  | x | 
| [Partições](#PostgreSQL.HighObjectCount.Partitions) |  |  |  |  | x |  | 
| [Arquivos temporários](#PostgreSQL.HighObjectCount.TempFiles) |  |  |  |  | x |  | 
| [Sequências](#PostgreSQL.HighObjectCount.Sequences) |  | x |  |  |  |  | 
| [Objetos grandes](#PostgreSQL.HighObjectCount.LargeObjects) |  | x | x |  |  |  | 

## Relações
<a name="PostgreSQL.HighObjectCount.Relations"></a>

Não há um limite rígido específico em relação ao número de tabelas em um banco de dados PostgreSQL. O limite teórico é extremamente alto, mas há outros limites práticos que precisam ser considerados na fase de design do banco de dados.

**Impacto: atraso do autovacuum**  
O autovacuum pode ter dificuldade de acompanhar o aumento de IDs de transação ou o inchaço de tabela devido à falta de operadores em comparação à quantidade de trabalho.  
**Ação recomendada:** há vários fatores que permitem ajustar o autovacuum para acompanhar adequadamente determinado número de tabelas e determinada workload. Consulte [Práticas recomendadas para trabalhar com o autovacuum do PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html) para ver sugestões sobre como determinar as configurações apropriadas do autovacuum. Use o [utilitário postgres\$1get\$1av\$1diag utility](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum_Monitoring.Functions.html) para monitorar problemas de aumento de IDs de transação.

**Impacto: atualização da versão principal/pg\$1dump e pg\$1restore**  
O Amazon RDS usa a opção “--link” durante a execução do pg\$1upgrade para evitar a necessidade de fazer cópias dos arquivos de dados. Os metadados do esquema ainda assim precisam ser restaurados na nova versão do banco de dados. Mesmo com o pg\$1restore paralelo, se houver um número significativo de relações, isso aumentará o tempo de inatividade.

**Impacto: degradação geral do desempenho**  
Degradação geral do desempenho devido ao tamanho do catálogo. Cada tabela e as colunas correspondentes aumentarão as tabelas `pg_attribute`, `pg_class` e `pg_depend` que são frequentemente usadas em operações normais de banco de dados. Não haverá um evento de espera específico visível, mas a eficiência do buffer compartilhado será afetada.  
**Ação recomendada:** verifique regularmente o inchaço dessas tabelas específicas e, ocasionalmente, execute `VACUUM FULL` nessas tabelas. Lembre-se de que `VACUUM FULL` nas tabelas de catálogo exigem um bloqueio `ACCESS EXCLUSIVE`, o que significa que nenhuma outra consulta poderá acessá-las enquanto a operação não for concluída.

**Impacto: esgotamento do descritor de arquivo**  
Error: “out of file descriptors: Too many open files in system; release and retry”. O parâmetro `max_files_per_process` do PostgreSQL determina quantos arquivos cada processo pode abrir. Se houver um grande número de conexões unindo um grande número de tabelas, esse limite provavelmente será atingido.  
**Ação recomendada:**  
+ Reduzir o valor do parâmetro `max_files_per_process` pode ajudar a mitigar esse erro. Cada processo e subprocesso (por exemplo, consulta paralela) pode abrir essa quantidade de arquivos e, se as consultas estiverem unindo várias tabelas, esse limite provavelmente se esgotará.
+ Reduza o número de conexões e use um agrupador de conexões, como o [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) ou outras soluções, como o PgBouncer. Para saber mais, consulte o site do [PgBouncer](https://www.pgbouncer.org/).

**Impacto: esgotamento de inodes**  
Error: “No space left on device”. Se isso for observado quando houver bastante espaço livre de armazenamento, a causa é a falta de inodes. O [Monitoramento aprimorado do Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.OS.html) oferece visibilidade sobre os inodes em uso e o número máximo disponível para o host.

**Limite aproximado:** [milhões](#PostgreSQL.HighObjectCount.Note).

## Tabelas temporárias
<a name="PostgreSQL.HighObjectCount.TempTables"></a>

O uso de tabelas temporárias, que é útil para dados de teste ou resultados intermediários, é um padrão comum visto em muitos mecanismos de banco de dados. É necessário entender as implicações do uso intenso no PostgreSQL para evitar algumas das armadilhas. Cada tabela temporária criada e descartada adicionará linhas às tabelas de catálogo do sistema, o que causará problemas gerais de desempenho quando essas tabelas ficarem inchadas.

**Impacto: atraso do autovacuum**  
As tabelas temporárias não são limpas pelo autovacuum. Elas ficarão atreladas aos IDs de transação enquanto existirem e poderão provocar wraparound se não forem removidas.  
**Ação recomendada:** manter as tabelas temporárias durante a sessão que as criou ou eliminá-las manualmente. Evitar transações de longa duração com tabelas temporárias é uma prática recomendada que impedirá que essas tabelas contribuam para o aumento máximo de IDs de transação usados.

**Impacto: degradação geral do desempenho**  
Degradação geral do desempenho devido ao tamanho do catálogo. Quando as sessões criam e eliminam continuamente tabelas temporárias, elas aumentam as tabelas `pg_attribute`, `pg_class` e `pg_depend` tabelas que são frequentemente usadas em operações normais de banco de dados. Não haverá um evento de espera específico visível, mas a eficiência do buffer compartilhado será afetada.  
**Ação recomendada:**  
+ Verifique regularmente o inchaço dessas tabelas específicas e, ocasionalmente, execute `VACUUM FULL` nessas tabelas. Lembre-se de que `VACUUM FULL` nas tabelas de catálogo exigem um bloqueio `ACCESS EXCLUSIVE`, o que significa que nenhuma outra consulta poderá acessá-las enquanto a operação não for concluída.
+ Se forem usadas muitas tabelas temporárias, é altamente recomendável executar `VACUUM FULL` nessas tabelas de catálogo específicas antes de uma atualização de versão principal para reduzir o tempo de inatividade.

**Práticas recomendadas gerais:**
+ Reduza o uso de tabelas temporárias utilizando expressões de tabela comuns para produzir resultados intermediários. Às vezes, isso pode complicar as consultas necessárias, mas eliminará os impactos listados acima.
+ Reutilize as tabelas temporárias usando o comando `TRUNCATE` para limpar o conteúdo em vez de executar as etapas de descartar/criar. Isso também eliminará o problema de aumento de IDs de transação provocado por tabelas temporárias.

**Limite aproximado:** [dezenas de milhares](#PostgreSQL.HighObjectCount.Note).

## Tabelas não registradas
<a name="PostgreSQL.HighObjectCount.UnloggedTables"></a>

Tabelas não registradas em log podem oferecer ganhos de desempenho, pois não geram nenhuma informação de registro em log com gravação antecipada (WAL). Visto que elas não oferecerão durabilidade durante a recuperação de falhas no banco de dados porque estarão truncadas, é necessário usá-las com cautela. Essa é uma operação cara no PostgreSQL, pois cada tabela não registrada e log é truncada em série. Embora essa operação seja rápida para um pequeno número de tabelas não registradas em log, quando o número atinge a casa de milhares, isso pode começar a causar um atraso notável durante a inicialização.

**Impacto: replicação lógica**  
As tabelas não registradas em log geralmente não são incluídas na replicação lógica, inclusive em [implantações azuis/verde](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html), porque a replicação lógica depende do WAL para capturar e transferir alterações. 

  


**Impacto: tempo de inatividade prolongado durante a recuperação**  
Durante qualquer estado do banco de dados que envolva recuperação de falhas no banco de dados, como reinicialização multi-AZ com failover, recuperação para um ponto no tempo do Amazon RDS e atualização da versão principal do Amazon RDS, ocorrerá a operação serializada de truncamento das tabelas não registradas em log. Isso pode levar a uma experiência de tempo de inatividade bem maior do que o esperado.  
**Ação recomendada:**  
+ Minimize o uso de tabelas não registradas em log somente para dados que possam ser perdidos durante as operações de recuperação de falhas no banco de dados.
+ Minimize o uso de tabelas não registradas em log, pois o comportamento atual de truncamento em série pode aumentar significativamente o tempo de inicialização de um banco de dados.

**Práticas recomendadas gerais:**
+ As tabelas não registradas em log não são à prova de falhas. Iniciar uma recuperação para um ponto no tempo, o que envolve recuperação de falhas, leva um tempo significativo no PostgreSQL porque esse é um processo em série que trunca cada tabela.

**Limite aproximado:** [milhares](#PostgreSQL.HighObjectCount.Note).

## Partições
<a name="PostgreSQL.HighObjectCount.Partitions"></a>

O particionamento pode aumentar o desempenho da consulta e oferecer uma organização lógica dos dados. Em cenários ideais, o particionamento é organizado para que a remoção de partições possa ser usada durante o planejamento e a execução da consulta. Usar muitas partições pode provocar impactos negativos no desempenho das consultas e na manutenção do banco de dados. A escolha de como particionar uma tabela deve ser feita com cuidado, pois o desempenho do planejamento e da execução da consulta pode ser afetado negativamente por um design ineficiente. Consulte a [documentação do PostgreSQL](https://www.postgresql.org/docs/current/ddl-partitioning.html) para obter detalhes sobre particionamento.

**Impacto: degradação geral do desempenho**  
Algumas vezes os custos indiretos do tempo de planejamento aumentarão e a explicação dos planos referentes às consultas se tornarão mais complexa, dificultando a identificação de oportunidades de ajuste. Em versões do PostgreSQL anteriores à 18, muitas partições com alta workload podem provocar esperas `LWLock:LockManager`.  
**Ação recomendada:** determine um número mínimo de partições que permita concluir a organização dos dados e, ao mesmo tempo, oferecer uma execução de consulta eficiente.

**Impacto: manutenção complexa**  
Um número muito alto de partições provocará dificuldades de manutenção, como predefinição e remoção. O autovacuum tratará as partições como relações normais e deverá realizar uma limpeza regular, exigindo, portanto, operadores suficientes para concluir a tarefa.  
**Ação recomendada:**  
+ Predefina as partições para que a workload não seja bloqueada quando uma nova partição for necessária (por exemplo, partições mensais) e partições antigas forem removidas.
+ Garanta que haja operadores de autovacuum suficientes para realizar a manutenção de limpeza normal de todas as partições.

**Limite aproximado:**: [centenas](#PostgreSQL.HighObjectCount.Note).

## Arquivos temporários
<a name="PostgreSQL.HighObjectCount.TempFiles"></a>

Diferentemente das tabelas temporárias mencionadas acima, o PostgreSQL cria arquivos temporários na eventualidade de uma consulta complexa executar várias operações de classificação ou de hash simultaneamente e de cada uma dessas operações utilizar a memória da instância para armazenar resultados até o valor especificado no parâmetro `work_mem`. Quando a memória da instância não é suficiente, arquivos temporários são criados para armazenar os resultados. Consulte [Gerenciar arquivos temporários](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.ManagingTempFiles.html) para obter mais detalhes sobre arquivos temporários. Se a workload gerar um grande número desses arquivos, poderá haver vários impactos.

  


**Impacto: esgotamento do descritor de arquivo**  
Error: “out of file descriptors: Too many open files in system; release and retry”. O parâmetro `max_files_per_process` do PostgreSQL determina quantos arquivos cada processo pode abrir. Se houver um grande número de conexões unindo um grande número de tabelas, esse limite provavelmente será atingido.  
**Ação recomendada:**  
+ Reduzir o valor do parâmetro `max_files_per_process` pode ajudar a mitigar esse erro. Cada processo e subprocesso (por exemplo, consulta paralela) pode abrir essa quantidade de arquivos e, se as consultas estiverem unindo várias tabelas, esse limite provavelmente se esgotará.
+ Reduza o número de conexões e use um agrupador de conexões, como o [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html), ou outras soluções, como o PgBouncer. Para saber mais, consulte o site do [PgBouncer](https://www.pgbouncer.org/).

**Impacto: esgotamento de inodes**  
Error: “No space left on device”. Se isso for observado quando houver bastante espaço livre de armazenamento, a causa é a falta de inodes. O [Monitoramento aprimorado do Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Monitoring.OS.html) oferece visibilidade sobre os inodes em uso e o número máximo disponível para o host.

**Práticas recomendadas gerais:**
+ Monitore o uso de arquivos temporários com o [Insights de Performance](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_PerfInsights.html).
+ Ajuste as consultas que estão gerando arquivos temporários significativos para ver se é possível reduzir o número total de arquivos temporários.

**Limite aproximado:** [milhares](#PostgreSQL.HighObjectCount.Note).

## Sequências
<a name="PostgreSQL.HighObjectCount.Sequences"></a>

As sequências são o objeto subjacente usado para acrescentar colunas automaticamente no PostgreSQL e oferecem exclusividade e uma chave para os dados. Elas podem ser usadas em tabelas individuais sem problemas durante operações normais, exceto na replicação lógica.

No momento, no PostgreSQL, a replicação lógica não replica o valor atual de uma sequência para nenhum assinante. Para saber mais, consulte a página [Restrictions na documentação do PostgreSQL](https://www.postgresql.org/docs/current/logical-replication-restrictions.html).

**Impacto: tempo de transição estendido**  
Se você planeja usar [implantações azuis/verdes do Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html) para qualquer tipo de alteração ou atualização de configuração, é importante entender o impacto de ter um grande número de sequências na transição. Uma das fases finais da transição sincronizará o valor atual das sequências e, se houver vários milhares, isso aumentará o tempo geral de transição.  
**Ação recomendada:** se a workload do banco de dados permitir o uso de um UUID compartilhado em vez de uma abordagem de sequência por tabela, isso poderá reduzir a etapa de sincronização durante a transição.

**Limite aproximado:** [milhares](#PostgreSQL.HighObjectCount.Note).

## Objetos grandes
<a name="PostgreSQL.HighObjectCount.LargeObjects"></a>

Objetos grandes são armazenados em uma única tabela do sistema chamada pg\$1largeobject. Cada objeto grande também tem uma entrada na tabela do sistema pg\$1largeobject\$1metadata. O processo de criação, modificação e limpeza desses objetos é bem diferente do utilizado nas relações padrão. Os objetos grandes não são processados pelo autovacuum e devem ser limpos periodicamente por meio de um processo separado, chamado vacuumlo. Consulte “Gerenciar objetos grandes com o módulo lo” para ver exemplos sobre como gerenciar objetos grandes.

**Impacto: replicação lógica**  
No momento, não é possível replicar objetos grandes no PostgreSQL durante a replicação lógica. Para saber mais, consulte a página [Restrictions na documentação do PostgreSQL](https://www.postgresql.org/docs/current/logical-replication-restrictions.html). Em uma configuração [azul/verde](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/blue-green-deployments.html), isso significa que objetos grandes no ambiente azul não são replicados no ambiente verde.

**Impacto: atualização de versão principal**  
Uma atualização poderá ficar sem memória e falhar se houver milhões de objetos grandes, e a instância não puder manipulá-los durante uma atualização. O processo de atualização da versão principal do PostgreSQL compreende duas fases amplas: despejar o esquema via pg\$1dump e restaurá-lo por meio de pg\$1restore. Se seu banco de dados tiver milhões de objetos grandes, você precisará garantir que sua instância tenha memória suficiente para lidar com o pg\$1dump e o pg\$1restore durante uma atualização e escalá-la para um tipo de instância maior.

**Práticas recomendadas gerais:**
+ Use regularmente o utilitário vacuumlo para remover qualquer objeto grande órfão que você possa ter.
+ Considere a possibilidade de usar o tipo de dados BYTEA para armazenar objetos grandes no banco de dados.

**Limite aproximado:** [milhões](#PostgreSQL.HighObjectCount.Note).

## Limites aproximados
<a name="PostgreSQL.HighObjectCount.Note"></a>

Os limites aproximados mencionados neste tópico são usados somente para oferecer uma estimativa de até que ponto determinado recurso pode ser escalado. Eles representam o âmbito geral em que os impactos descritos se tornam mais prováveis, mas o comportamento real depende de fatores específicos, como workload, tamanho da instância e configuração. Embora seja possível exceder essas estimativas, é necessário seguir as operações de cuidado e manutenção para evitar os impactos listados.

# Gerenciar a contenção de TOAST OID no Amazon RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID"></a>

TOAST (The Oversized-Attribute Storage Technique) é um recurso do PostgreSQL projetado para lidar com grandes valores de dados que excedem o tamanho normal de blocos de banco de dados de 8 KB. O PostgreSQL não permite que linhas físicas abranjam vários blocos. O tamanho do bloco atua como um limite superior no tamanho da linha. O TOAST supera essa restrição dividindo grandes valores de campo em partes menores. Ele os armazena separadamente em uma tabela TOAST dedicada vinculada à tabela principal. Para acessar mais informações, consulte a [documentação de implementação e mecanismo de armazenamento TOAST do PostgreSQL](https://www.postgresql.org/docs/current/storage-toast.html).

**Topics**
+ [

## Noções básicas sobre operações TOAST
](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.HowWorks)
+ [

## Identificar problemas de performance
](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceChallenges)
+ [

## Recomendações
](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Recommendations)
+ [

## Monitoramento
](#Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Monitoring)

## Noções básicas sobre operações TOAST
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.HowWorks"></a>

O TOAST executa a compactação e armazena grandes valores de campo fora da linha. O recurso atribui um OID (Identificador de Objeto) exclusivo a cada bloco de dados superdimensionados armazenado na tabela TOAST. A tabela principal armazena o ID do valor TOAST e o ID da relação na página para fazer referência à linha correspondente na tabela TOAST. Isso permite que o PostgreSQL localize e gerencie com eficiência esses fragmentos do TOAST. No entanto, à medida que a tabela TOAST cresce, o sistema corre o risco de esgotar os OIDs disponíveis, causando a degradação da performance e um possível tempo de inatividade devido ao esgotamento do OID.

### Identificadores de objetos no TOAST
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.ObjectIdentifiers"></a>

Identificador de Objeto (OID) é um identificador exclusivo em todo o sistema usado pelo PostgreSQL para fazer referência a objetos de banco de dados, como tabelas, índices e funções. Esses identificadores desempenham um papel essencial nas operações internas do PostgreSQL, permitindo que o banco de dados localize e gerencie objetos com eficiência.

Para tabelas com conjuntos de dados elegíveis para toasting, o PostgreSQL atribui OIDs para identificar exclusivamente cada fragmento de dado excedente armazenado na tabela TOAST associada. O sistema associa cada fragmento a um `chunk_id`, o que ajuda o PostgreSQL a organizar e localizar esses fragmentos de forma eficiente na tabela TOAST.

## Identificar problemas de performance
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceChallenges"></a>

O gerenciamento de OID do PostgreSQL depende de um contador global de 32 bits para que ele funcione depois de gerar 4 bilhões de valores exclusivos. Embora o cluster de banco de dados compartilhe esse contador, a alocação de OID envolve duas etapas durante as operações TOAST:
+ **Contador global para alocação**: o contador global atribui um novo OID em todo o cluster.
+ **Pesquisa local de conflitos**: a tabela TOAST garante que o novo OID não entre em conflito com os OIDs existentes já usados nessa tabela específica.

A degradação da performance pode ocorrer quando:
+ A tabela TOAST tem alta fragmentação ou uso denso de OID, causando atrasos na atribuição do OID.
+ O sistema frequentemente aloca e reutiliza OIDs em ambientes com alta rotatividade de dados ou tabelas amplas que usam o TOAST extensivamente.

Para acessar mais informações, consulte a [documentação de alocação de OID e limites de tamanho de tabelas TOAST do PostgreSQL](https://wiki.postgresql.org/wiki/TOAST#Total_table_size_limit):

Um contador global gera os OIDs e envolve cada 4 bilhões de valores, para que, periodicamente, o sistema gere novamente um valor já usado. O PostgreSQL detecta isso e tenta novamente com o próximo OID. Um INSERT lento poderá ocorrer se houver uma série muito longa de valores de OID usados sem lacunas na tabela TOAST. Esses desafios se tornam mais pronunciados à medida que o espaço do OID é preenchido, causando inserções e atualizações mais lentas.

### Identificar o problema
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.IdentifyingProblem"></a>
+ Declarações `INSERT` simples demoram muito mais do que o normal de maneira inconsistente e aleatória.
+ Atrasos ocorrem somente para declarações `INSERT` e `UPDATE` envolvendo operações TOAST.
+ As seguintes entradas de log aparecem nos logs do PostgreSQL quando o sistema tem dificuldade para encontrar OIDs disponíveis nas tabelas TOAST:

  ```
  LOG: still searching for an unused OID in relation "pg_toast_20815"
  DETAIL: OID candidates have been checked 1000000 times, but no unused OID has been found yet.
  ```
+ O Insights de Performance indica um alto número médio de sessões ativas (AAS) associadas a eventos de espera `LWLock:buffer_io` e `LWLock:OidGenLock`.

  Você pode executar a seguinte consulta SQL para identificar transações INSERT de longa duração com eventos de espera:

  ```
  SELECT
      datname AS database_name,
      usename AS database_user,
      pid,
      now() - pg_stat_activity.xact_start AS transaction_duration,
      concat(wait_event_type, ':', wait_event) AS wait_event,
      substr(query, 1, 30) AS TRANSACTION,
      state
  FROM
      pg_stat_activity
  WHERE (now() - pg_stat_activity.xact_start) > INTERVAL '60 seconds'
      AND state IN ('active', 'idle in transaction', 'idle in transaction (aborted)', 'fastpath function call', 'disabled')
      AND pid <> pg_backend_pid()
  AND lower(query) LIKE '%insert%'
  ORDER BY
      transaction_duration DESC;
  ```

  Exemplos de resultado de consulta exibindo operações INSERT com tempos de espera estendidos:

  ```
   database_name |  database_user  |  pid  | transaction_duration |     wait_event      |          transaction           | state
  ---------------+-----------------+-------+----------------------+---------------------+--------------------------------+--------
   postgres       | db_admin_user| 70965 | 00:10:19.484061      | LWLock:buffer_io    | INSERT INTO "products" (......... | active
   postgres       | db_admin_user| 69878 | 00:06:14.976037      | LWLock:buffer_io    | INSERT INTO "products" (......... | active
   postgres       | db_admin_user| 68937 | 00:05:13.942847      | :                   | INSERT INTO "products" (......... | active
  ```

### Isolar o problema
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.IsolatingProblem"></a>
+ **Testar a inserção pequena**: insira um registro menor que o limite `toast_tuple_target`. Lembre-se de que a compactação é aplicada antes do armazenamento TOAST. Se isso funcionar sem problemas de performance, o problema está relacionado às operações TOAST.
+ **Testar nova tabela**: crie uma tabela com a mesma estrutura e insira um registro maior que `toast_tuple_target`. Se isso funcionar sem problemas, o problema estará localizado na alocação de OID da tabela original.

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

As abordagens a seguir podem ajudar a resolver problemas de contenção do TOAST OID.
+ **Limpeza e arquivamento de dados**: analise e exclua quaisquer dados obsoletos ou desnecessários para liberar OIDs para uso futuro ou arquivar os dados. Considere as seguintes limitações:
  + Escalabilidade limitada, pois a limpeza futura nem sempre é possível.
  + Possível operação VACUUM de longa duração para remover as tuplas inativas resultantes.
+ **Gravar em uma nova tabela**: crie uma tabela para futuras inserções e use uma visualização `UNION ALL` para combinar dados antigos e novos para consultas. Essa visualização apresenta os dados combinados das tabelas antigas e novas, permitindo que as consultas os acessem como uma única tabela. Considere as seguintes limitações:
  + As atualizações na tabela antiga ainda podem causar o esgotamento de OIDs.
+ **Partição ou fragmento**: particione a tabela ou fragmente os dados para ter melhor escalabilidade e performance. Considere as seguintes limitações:
  + Maior complexidade na lógica de consulta e na manutenção, possível necessidade de alterações na aplicação para lidar corretamente com dados particionados.

## Monitoramento
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.Monitoring"></a>

### Usar tabelas do sistema
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.SystemTables"></a>

Você pode usar as tabelas do sistema do PostgreSQL para monitorar o crescimento do uso de OIDs.

**Atenção**  
Dependendo do número de OIDs na tabela TOAST, pode levar algum tempo para ser concluído. Recomendamos que você agende o monitoramento fora do horário comercial para minimizar o impacto.

O bloco anônimo a seguir conta o número de OIDs distintos usados em cada tabela TOAST e exibe as informações da tabela principal:

```
DO $$
DECLARE
    r record;
    o bigint;
    parent_table text;
    parent_schema text;
BEGIN
    SET LOCAL client_min_messages TO notice;
    FOR r IN
    SELECT
        c.oid,
        c.oid::regclass AS toast_table
    FROM
        pg_class c
    WHERE
        c.relkind = 't'
        AND c.relowner != 10 LOOP
            -- Fetch the number of distinct used OIDs (chunk IDs) from the TOAST table
            EXECUTE 'SELECT COUNT(DISTINCT chunk_id) FROM ' || r.toast_table INTO o;
            -- If there are used OIDs, find the associated parent table and its schema
            IF o <> 0 THEN
                SELECT
                    n.nspname,
                    c.relname INTO parent_schema,
                    parent_table
                FROM
                    pg_class c
                    JOIN pg_namespace n ON c.relnamespace = n.oid
                WHERE
                    c.reltoastrelid = r.oid;
                -- Raise a concise NOTICE message
                RAISE NOTICE 'Parent schema: % | Parent table: % | Toast table: % | Number of used OIDs: %', parent_schema, parent_table, r.toast_table, TO_CHAR(o, 'FM9,999,999,999,999');
            END IF;
        END LOOP;
END
$$;
```

Exemplo de saída exibindo estatísticas de uso de OIDs pela tabela TOAST:

```
NOTICE:  Parent schema: public | Parent table: my_table | Toast table: pg_toast.pg_toast_16559 | Number of used OIDs: 45,623,317
NOTICE:  Parent schema: public | Parent table: my_table1 | Toast table: pg_toast.pg_toast_45639925 | Number of used OIDs: 10,000
NOTICE:  Parent schema: public | Parent table: my_table2 | Toast table: pg_toast.pg_toast_45649931 | Number of used OIDs: 1,000,000
DO
```

O bloco anônimo a seguir recupera o OID máximo atribuído para cada tabela TOAST não vazia:

```
DO $$
DECLARE
    r record;
    o bigint;
    parent_table text;
    parent_schema text;
BEGIN
    SET LOCAL client_min_messages TO notice;
    FOR r IN
    SELECT
        c.oid,
        c.oid::regclass AS toast_table
    FROM
        pg_class c
    WHERE
        c.relkind = 't'
        AND c.relowner != 10 LOOP
            -- Fetch the max(chunk_id) from the TOAST table
            EXECUTE 'SELECT max(chunk_id) FROM ' || r.toast_table INTO o;
            -- If there's at least one TOASTed chunk, find the associated parent table and its schema
            IF o IS NOT NULL THEN
                SELECT
                    n.nspname,
                    c.relname INTO parent_schema,
                    parent_table
                FROM
                    pg_class c
                    JOIN pg_namespace n ON c.relnamespace = n.oid
                WHERE
                    c.reltoastrelid = r.oid;
                -- Raise a concise NOTICE message
                RAISE NOTICE 'Parent schema: % | Parent table: % | Toast table: % | Max chunk_id: %', parent_schema, parent_table, r.toast_table, TO_CHAR(o, 'FM9,999,999,999,999');
            END IF;
        END LOOP;
END
$$;
```

Exemplo de saída exibindo o máximo de IDs de blocos para tabelas TOAST:

```
NOTICE:  Parent schema: public | Parent table: my_table | Toast table: pg_toast.pg_toast_16559 | Max chunk_id: 45,639,907
NOTICE:  Parent schema: public | Parent table: my_table1 | Toast table: pg_toast.pg_toast_45639925 | Max chunk_id: 45,649,929
NOTICE:  Parent schema: public | Parent table: my_table2 | Toast table: pg_toast.pg_toast_45649931 | Max chunk_id: 46,649,935
DO
```

### Usar o Performance Insights
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.PerformanceInsights"></a>

Os eventos de espera `LWLock:buffer_io` e `LWLock:OidGenLock` aparecem no Insights de Performance durante operações que exigem a atribuição de novos identificadores de objetos (OIDs). As sessões ativas de alta média (AAS) para esses eventos geralmente apontam para contenção durante a atribuição de OIDs e o gerenciamento de recursos. Isso é particularmente comum em ambientes com alta rotatividade de dados, uso extensivo de grandes volumes de dados ou criação frequente de objetos.

#### LWLock:buffer\$1io
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.LWLockBufferIO"></a>

`LWLock:buffer_io` é um evento de espera que ocorre quando uma sessão do PostgreSQL aguarda a conclusão das operações de E/S em um buffer compartilhado. Isso geralmente acontece quando o banco de dados lê dados do disco para a memória ou grava páginas modificadas da memória para o disco. O evento de espera `BufferIO` garante a consistência ao impedir que vários processos acessem ou modifiquem o mesmo buffer enquanto as operações de E/S estão em andamento. Altas ocorrências desse evento de espera podem indicar gargalos no disco ou atividade excessiva de E/S na workload do banco de dados.

Durante as operações TOAST:
+ O PostgreSQL aloca OIDs para objetos grandes e garante sua exclusividade examinando o índice da tabela TOAST.
+ Índices TOAST grandes podem exigir o acesso a várias páginas para verificar a exclusividade do OID. Isso gera aumento de E/S de disco, principalmente quando o grupo de buffers não consegue armazenar em cache todas as páginas necessárias.

O tamanho do índice afeta diretamente o número de páginas de buffer que precisam ser acessadas durante essas operações. Mesmo que o índice não esteja inchado, seu tamanho pode aumentar a E/S do buffer, principalmente em ambientes de alta simultaneidade ou alta rotatividade. Para acessar mais informações, consulte o [Guia de solução de problemas com o evento de espera LWLock:BufferIO](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/apg-waits.lwlockbufferio.html).

#### LWLock:OidGenLock
<a name="Appendix.PostgreSQL.CommonDBATasks.TOAST_OID.LWLockOidGenLock"></a>

`OidGenLock` é um evento de espera que ocorre quando uma sessão do PostgreSQL está aguardando para alocar um novo identificador de objeto (OID). Esse bloqueio garante que os OIDs sejam gerados sequencialmente e com segurança, permitindo que somente um processo gere OIDs por vez.

Durante as operações TOAST:
+ **Alocação de OID para blocos na tabela TOAST**: o PostgreSQL atribui OIDs a blocos nas tabelas TOAST ao gerenciar grandes registros de dados. Cada OID deve ser exclusivo para evitar conflitos no catálogo do sistema.
+ **Alta simultaneidade**: como o acesso ao gerador de OIDs é sequencial, quando várias sessões estão criando simultaneamente objetos que exigem OIDs, pode ocorrer contenção para `OidGenLock`. Isso aumenta a probabilidade de sessões esperando a conclusão da alocação de OIDs.
+ **Dependência do acesso ao catálogo do sistema**: a alocação de OIDs requer atualizações nas tabelas compartilhadas do catálogo do sistema, como `pg_class` e `pg_type`. Se essas tabelas apresentarem muita atividade (devido às operações frequentes de DDL), isso poderá aumentar a contenção de bloqueio para `OidGenLock`.
+ **Alta demanda de alocação de OIDs**: workloads intensas envolvendo TOAST com grandes registros de dados exigem alocação constante de OIDs, aumentando a contenção.

Fatores adicionais que aumentam a contenção de OIDs:
+ **Criação frequente de objetos**: workloads trabalho que frequentemente criam e descartam objetos, como tabelas temporárias, amplificam a contenção no contador global de OIDs.
+ **Bloqueio global do contador**: o contador global de OIDs é acessado em série para garantir a exclusividade, criando um único ponto de contenção em ambientes de alta simultaneidade.

## Trabalhar com os mecanismos de registro em log compatíveis com o RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Auditing"></a>

Existem vários parâmetros, extensões e outros itens configuráveis que você pode definir para registrar em log as atividades que ocorrem na sua instância de banco de dados PostgreSQL. Incluindo o seguinte:
+ O parâmetro `log_statement` pode ser usado para registrar as atividades dos usuários no seu banco de dados PostgreSQL. Para saber mais sobre o registro em log do RDS para PostgreSQL e como monitorar os logs, consulte [Arquivos de log do banco de dados RDS para PostgreSQL](USER_LogAccess.Concepts.PostgreSQL.md).
+ O parâmetro `rds.force_admin_logging_level` registra na instância de banco de dados as ações do usuário interno do Amazon RDS (rdsadmin) nos bancos de dados. Ele grava a saída no log de erros do PostgreSQL. Os valores permitidos são `disabled`, `debug5`, `debug4`, `debug3`, `debug2`, `debug1`, `info`, `notice`, `warning`, `error`, log,`fatal` e `panic`. O valor padrão é `disabled`.
+ O parâmetro `rds.force_autovacuum_logging_level` pode ser definido para capturar várias operações de autovacuum no log de erros do PostgreSQL. Para ter mais informações, consulte[Registrar atividades do autovacuum e do vacuum em log](Appendix.PostgreSQL.CommonDBATasks.Autovacuum.Logging.md) 
+ A extensão do PostgreSQL Audit (pgAudit) pode ser instalada e configurada para capturar atividades no nível da sessão ou no nível do objeto. Para ter mais informações, consulte[Usar pgAudit para registrar a atividade do banco de dados](Appendix.PostgreSQL.CommonDBATasks.pgaudit.md)
+ A extensão `log_fdw` possibilita que você acesse o log do mecanismo de banco de dados usando SQL. Para ter mais informações, consulte [Usar a extensão log\$1fdw para acessar o log de banco de dados usando SQL](CHAP_PostgreSQL.Extensions.log_fdw.md).
+ A biblioteca `pg_stat_statements` é especificada como padrão para o parâmetro `shared_preload_libraries` no RDS para PostgreSQL versão 10 e posteriores. É essa biblioteca que você pode usar para analisar consultas em execução. Certifique-se de que `pg_stat_statements` esteja definido no grupo de parâmetros de banco de dados. Para ter mais informações sobre o monitoramento da instância de banco de dados do RDS para PostgreSQL usando as informações fornecidas por essa biblioteca, consulte [Estatísticas SQL do RDS PostgreSQL](USER_PerfInsights.UsingDashboard.AnalyzeDBLoad.AdditionalMetrics.PostgreSQL.md).
+ O parâmetro `log_hostname` captura no log o nome do host de cada conexão do cliente. Para RDS para PostgreSQL versão 12 e versões superiores, esse parâmetro é definido como `off` por padrão. Se você ativá-lo, monitore os tempos de conexão da sessão. Quando ativado, o serviço usa a solicitação de pesquisa reversa do sistema de Nomes de Domínio (DNS) para obter o nome do host do cliente que está fazendo a conexão e adicioná-lo ao log do PostgreSQL. Isso tem um impacto perceptível durante a conexão da sessão. Recomendamos que você ative esse parâmetro apenas para solução de problemas. 

Em termos gerais, o objetivo do registro em log é possibilitar que o DBA monitore, ajuste a performance e solucione problemas. Muitos dos logs são carregados automaticamente no Amazon CloudWatch ou no Performance Insights. Aqui, eles são classificados e agrupados para fornecer métricas completas para sua instância de banco de dados. Para saber mais sobre o monitoramento e as métricas do Amazon RDS, consulte [Métricas de monitoramento em uma instância do Amazon RDS](CHAP_Monitoring.md). 

# Gerenciar arquivos temporários com o PostgreSQL
<a name="PostgreSQL.ManagingTempFiles"></a>

No PostgreSQL, uma consulta complexa pode executar algumas operações de classificação ou de hash simultaneamente, com cada uma utilizando a memória da instância para armazenar resultados até o valor especificado no parâmetro [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM). Quando a memória da instância não é suficiente, arquivos temporários são criados para armazenar os resultados. Eles são gravados em disco para concluir a execução da consulta. Posteriormente, esses arquivos são removidos automaticamente após a conclusão da consulta. No RDS para PostgreSQL, esses arquivos são armazenados no Amazon EBS no volume de dados. Para obter mais informações, consulte Armazenamento de instâncias de banco de dados do Amazon RDS. Você pode monitorar a métrica `FreeStorageSpace` publicada no CloudWatch para garantir que a instância de banco de dados tenha espaço de armazenamento livre suficiente. Para obter mais informações, consulte [https://repost.aws/knowledge-center/storage-full-rds-cloudwatch-alarm](https://repost.aws/knowledge-center/storage-full-rds-cloudwatch-alarm)

Recomendamos o uso de instâncias do Amazon RDS com otimização de memória para workloads com várias consultas simultâneas que aumentam o uso de arquivos temporários. Essas instâncias usam o armazenamento ao nível do bloco de unidade de estado sólido (SSD) local baseado em memória expressa não volátil (NVMe) para guardar os arquivos temporários. Para obter mais informações, consulte [Melhorar a performance das consultas para o RDS para PostgreSQL com leituras otimizadas pelo Amazon RDS](USER_PostgreSQL.optimizedreads.md).

Você pode usar os parâmetros e as funções a seguir para gerenciar os arquivos temporários em sua instância.
+ **[https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK](https://www.postgresql.org/docs/current/runtime-config-resource.html#RUNTIME-CONFIG-RESOURCE-DISK)** – esse parâmetro cancela qualquer consulta que exceda o tamanho de temp\$1files em KB. Esse limite impede que qualquer consulta seja executada indefinidamente e consuma espaço em disco com arquivos temporários. Você pode estimar o valor utilizando os resultados do parâmetro `log_temp_files`. Como prática recomendada, examine o comportamento da workload e defina o limite de acordo com a estimativa. O exemplo a seguir mostra como uma consulta é cancelada quando ela excede o limite.

  ```
  postgres=>select * from pgbench_accounts, pg_class, big_table;
  ```

  ```
  ERROR: temporary file size exceeds temp_file_limit (64kB)
  ```
+ **[https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-TEMP-FILES](https://www.postgresql.org/docs/current/runtime-config-logging.html#GUC-LOG-TEMP-FILES)** – esse parâmetro envia mensagens ao postgresql.log quando os arquivos temporários de uma sessão são removidos. Esse parâmetro produz logs após a conclusão bem-sucedida de uma consulta. Portanto, isso pode não ajudar na solução de problemas de consultas ativas e de longa duração. 

  O exemplo a seguir mostra que, quando a consulta é concluída com êxito, as entradas são registradas no arquivo postgresql.log enquanto os arquivos temporários são limpos.

  ```
                      
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp31236.5", size 140353536
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:STATEMENT:  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid limit 10;
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:LOG:  temporary file: path "base/pgsql_tmp/pgsql_tmp31236.4", size 180428800
  2023-02-06 23:48:35 UTC:205.251.233.182(12456):adminuser@postgres:[31236]:STATEMENT:  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid limit 10;
  ```
+ **[https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADMIN-GENFILE](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADMIN-GENFILE)** – essa função que está disponível no RDS para PostgreSQL 13 e versões posteriores oferece visibilidade sobre o uso atual de arquivos temporários. A consulta concluída não aparece nos resultados da função. No exemplo a seguir, você pode visualizar os resultados dessa função.

  ```
  postgres=>select * from pg_ls_tmpdir();
  ```

  ```
        name       |    size    |      modification
  -----------------+------------+------------------------
   pgsql_tmp8355.1 | 1072250880 | 2023-02-06 22:54:56+00
   pgsql_tmp8351.0 | 1072250880 | 2023-02-06 22:54:43+00
   pgsql_tmp8327.0 | 1072250880 | 2023-02-06 22:54:56+00
   pgsql_tmp8351.1 |  703168512 | 2023-02-06 22:54:56+00
   pgsql_tmp8355.0 | 1072250880 | 2023-02-06 22:54:00+00
   pgsql_tmp8328.1 |  835031040 | 2023-02-06 22:54:56+00
   pgsql_tmp8328.0 | 1072250880 | 2023-02-06 22:54:40+00
  (7 rows)
  ```

  ```
  postgres=>select query from pg_stat_activity where pid = 8355;
                  
  query
  ----------------------------------------------------------------------------------------
  select a.aid from pgbench_accounts a, pgbench_accounts b where a.bid=b.bid order by a.bid
  (1 row)
  ```

  O nome do arquivo inclui o ID de processamento (PID) da sessão que gerou o arquivo temporário. Uma consulta mais avançada, como no exemplo a seguir, executa uma soma dos arquivos temporários para cada PID.

  ```
  postgres=>select replace(left(name, strpos(name, '.')-1),'pgsql_tmp','') as pid, count(*), sum(size) from pg_ls_tmpdir() group by pid;
  ```

  ```
   pid  | count |   sum
  ------+-------------------
   8355 |     2 | 2144501760
   8351 |     2 | 2090770432
   8327 |     1 | 1072250880
   8328 |     2 | 2144501760
  (4 rows)
  ```
+ **`[ pg\$1stat\$1statements](https://www.postgresql.org/docs/current/pgstatstatements.html)`** – se você ativar o parâmetro pg\$1stat\$1statements, poderá visualizar o uso médio de arquivos temporários por chamada. Você pode identificar o query\$1id da consulta e usá-lo para examinar o uso do arquivo temporário, conforme mostrado no exemplo a seguir.

  ```
  postgres=>select queryid from pg_stat_statements where query like 'select a.aid from pgbench%';
  ```

  ```
         queryid
  ----------------------
   -7170349228837045701
  (1 row)
  ```

  ```
  postgres=>select queryid, substr(query,1,25), calls, temp_blks_read/calls temp_blks_read_per_call, temp_blks_written/calls temp_blks_written_per_call from pg_stat_statements where queryid = -7170349228837045701;
  ```

  ```
         queryid        |          substr           | calls | temp_blks_read_per_call | temp_blks_written_per_call
  ----------------------+---------------------------+-------+-------------------------+----------------------------
   -7170349228837045701 | select a.aid from pgbench |    50 |                  239226 |                     388678
  (1 row)
  ```
+ **`[Performance Insights](https://aws.amazon.com/rds/performance-insights/)`**: no painel do Performance Insights, você pode visualizar o uso temporário de arquivos ativando as métricas **temp\$1bytes** e **temp\$1files**. Depois, você pode ver a média dessas duas métricas e como elas correspondem à workload da consulta. A exibição no Performance Insights não mostra especificamente as consultas que estão gerando os arquivos temporários. No entanto, ao combinar o Performance Insights com a consulta mostrada para `pg_ls_tmpdir`, você pode solucionar problemas, analisar e determinar as alterações em sua workload de consulta. 

  Para ter mais informações sobre como analisar as métricas e as consultas com o Insights de Performance, consulte [Análise de métricas usando o painel do Performance Insights](USER_PerfInsights.UsingDashboard.md).

  Para ver um exemplo de como visualizar o uso de arquivos temporários com o Insights de Performance, consulte [Visualizar o uso de arquivos temporários com o Insights de Performance](PostgreSQL.ManagingTempFiles.Example.md).

# Visualizar o uso de arquivos temporários com o Insights de Performance
<a name="PostgreSQL.ManagingTempFiles.Example"></a>

É possível usar o Insights de Performance para visualizar o uso de arquivos temporários ativando as métricas **temp\$1bytes** e **temp\$1files**. A visualização no Insights de Performance não mostra as consultas específicas que geram arquivos temporários, no entanto, ao combinar o Insights de Performance com a consulta mostrada para `pg_ls_tmpdir`, é possível solucionar problemas, analisar e determinar as alterações na workload de consulta.

1. No painel do Performance Insights, selecione **Gerenciar métricas**.

1. Escolha **Métricas de banco de dados** e selecione as métricas **temp\$1bytes** e **temp\$1files** como mostrado na imagem a seguir.  
![\[Métricas serão exibidos no grafo.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/rpg_mantempfiles_metrics.png)

1. Na guia **Top SQL**, selecione o ícone **Preferências**.

1. Na janela **Preferências**, ative as estatísticas a seguir para serem exibidas na guia **Top SQL** e selecione **Continuar**.
   + Gravações temporárias/segundo
   + Leituras de temperatura/segundo
   + Gravação/chamada em bloco temporário
   + Leitura/chamada em bloco temporário

1. O arquivo temporário é dividido quando combinado com a consulta mostrada para `pg_ls_tmpdir`, conforme exibido no exemplo a seguir.  
![\[Consulta que exibe o uso de arquivos temporários.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/rpg_mantempfiles_query.png)

Os eventos `IO:BufFileRead` e `IO:BufFileWrite` ocorrem porque as principais consultas na workload geralmente criam arquivos temporários. Você pode usar o Insights de Performance para identificar as principais consultas que aguardam `IO:BufFileRead` e `IO:BufFileWrite` revisando “Média de sessões ativas (AAS)” nas seções “Carga do banco de dados” e “SQL principal”. 

![\[IO:BufFileRead e IO:BufFileWrite no grafo.\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/images/perfinsights_IOBufFile.png)


Para obter mais informações sobre como usar o Insights de Performance para analisar as principais consultas e a carga por eventos de espera, consulte [Visão geral da guia Top SQL (SQL principal)](USER_PerfInsights.UsingDashboard.AnalyzeDBLoad.AdditionalMetrics.md#USER_PerfInsights.UsingDashboard.Components.AvgActiveSessions.TopLoadItemsTable.TopSQL) Você deve identificar e ajustar as consultas que aumentam o uso de arquivos temporários e os eventos de espera correspondentes. Para ter mais informações sobre esses eventos de espera e a correção, consulte, [IO:BufFileRead e IO:BufFileWrite](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/wait-event.iobuffile.html).

**nota**  
O parâmetro [https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM) controla quando a operação de classificação fica sem memória e os resultados são gravados em arquivos temporários. Recomendamos que você não altere a configuração desse parâmetro acima do valor padrão, pois isso permitiria que cada sessão do banco de dados consumisse mais memória. Além disso, uma única sessão que executa junções e classificações complexas pode realizar operações paralelas nas quais cada operação consome memória.   
Como prática recomendada, quando você tem um relatório grande com várias junções e classificações, defina esse parâmetro no nível da sessão usando o comando `SET work_mem`. Depois, a alteração é aplicada somente à sessão atual e não altera o valor globalmente.

## Uso de pgBadger para análise de logs com o PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Badger"></a>

Você pode usar um analisador de log, como o [pgBadger](http://dalibo.github.io/pgbadger/), para analisar logs do PostgreSQL. A documentação do pgBadger indica que o padrão %l (linha de log da sessão ou do processo) deve ser uma parte do prefixo. Contudo, se você fornecer o `log_line_prefix` atual do RDS como um parâmetro para pgBadger, isso ainda produzirá um relatório.

Por exemplo, o comando a seguir formata corretamente um arquivo de log do Amazon RDS para PostgreSQL com data de 04/02/2014 usando pgBadger.

```
./pgbadger -f stderr -p '%t:%r:%u@%d:[%p]:' postgresql.log.2014-02-04-00 
```

## Usar o PGSnapper para monitorar o PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Snapper"></a>

Você pode usar o PGSnapper para auxiliar na coleta periódica de estatísticas e métricas relacionadas à performance do Amazon RDS para PostgreSQL. Para ter mais informações, consulte [Monitorar a performance do Amazon RDS para PostgreSQL usando o PGSnapper](https://aws.amazon.com/blogs/database/monitor-amazon-rds-for-postgresql-and-amazon-aurora-postgresql-performance-using-pgsnapper/).

# Gerenciar conversões personalizadas no RDS para PostgreSQL
<a name="PostgreSQL.CustomCasts"></a>

No PostgreSQL, a **conversão de tipo** refere-se ao processo de conversão de um valor de um tipo de dados em outro. O PostgreSQL oferece conversões integradas para várias conversões comuns, mas também é possível criar conversões personalizadas para definir como as conversões de tipos específicos devem se comportar.

Um conversão especifica como realizar uma conversão de um tipo de dados em outro. Por exemplo, converter texto `'123'` em número inteiro `123` ou numérico `45.67` em texto `'45.67'`.

Para ter informações abrangentes sobre os conceitos e a sintaxe de conversão do PostgreSQL, consulte [CREATE CAST na documentação do PostgreSQL](https://www.postgresql.org/docs/current/sql-createcast.html).

A partir das versões do RDS para PostgreSQL 13.23, 14.20, 15.15, 16.11, 17.7 e 18.1, é possível usar a extensão rds\$1casts para instalar outras conversões para tipos integrados e, ao mesmo tempo, criar conversões próprias para tipos personalizados

**Topics**
+ [

## Instalar e usar a extensão rds\$1casts
](#PostgreSQL.CustomCasts.Installing)
+ [

## Conversões compatíveis
](#PostgreSQL.CustomCasts.Supported)
+ [

## Criar ou eliminar conversões
](#PostgreSQL.CustomCasts.Creating)
+ [

## Criar conversões personalizadas com a estratégia de contexto adequada
](#PostgreSQL.CustomCasts.BestPractices)

## Instalar e usar a extensão rds\$1casts
<a name="PostgreSQL.CustomCasts.Installing"></a>

Para criar a extensão `rds_casts`, conecte-se à sua instância de banco de dados do RDS para PostgreSQL como um `rds_superuser` e execute o seguinte comando:

```
CREATE EXTENSION IF NOT EXISTS rds_casts;
```

## Conversões compatíveis
<a name="PostgreSQL.CustomCasts.Supported"></a>

Crie a extensão em cada banco de dados em que você deseja usar conversões personalizadas. Depois de criar a extensão, use o seguinte comando para visualizar todas as conversões disponíveis:

```
SELECT * FROM rds_casts.list_supported_casts();
```

Essa função lista as combinações de conversão disponíveis (tipo de origem, tipo de destino, contexto de coerção e função de conversão). Por exemplo, se você quiser criar uma conversão de `text` em `numeric` como uma conversão `implicit`. É possível usar a seguinte consulta para descobrir se a conversão está disponível para criação:

```
SELECT * FROM rds_casts.list_supported_casts()
WHERE source_type = 'text' AND target_type = 'numeric';
 id | source_type | target_type |          qualified_function          | coercion_context
----+-------------+-------------+--------------------------------------+------------------
 10 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | implicit
 11 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | assignment
 13 | text        | numeric     | rds_casts.rds_text_to_numeric_custom | explicit
 20 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | implicit
 21 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | assignment
 23 | text        | numeric     | rds_casts.rds_text_to_numeric_inout  | explicit
```

A extensão rds\$1casts oferece dois tipos de função de conversão para cada conversão:
+ *\$1inout functions*: usam o mecanismo de conversão de E/S padrão do PostgreSQL, comportando-se de forma idêntica às conversões criadas com o método INOUT.
+ *\$1custom functions*: oferecem lógica de conversão aprimorada que lida com casos extremos, como converter strings vazias em valores NULL para evitar erros de conversão

As funções `inout` replicam o comportamento de conversão nativo do PostgreSQL, enquanto as funções `custom` estendem essa funcionalidade, lidando com cenários que as conversões INOUT padrão não conseguem atender, como converter strings vazias em números inteiros.

## Criar ou eliminar conversões
<a name="PostgreSQL.CustomCasts.Creating"></a>

É possível criar e eliminar conversões compatíveis usando dois métodos:

### Criação de conversão
<a name="PostgreSQL.CustomCasts.Creating.Methods"></a>

**Método 1: usar o comando nativo CREATE CAST**

```
CREATE CAST (text AS numeric)
WITH FUNCTION rds_casts.rds_text_to_numeric_custom
AS IMPLICIT;
```

**Método 2: usar a função rds\$1casts.create\$1cast**

```
SELECT rds_casts.create_cast(10);
```

A função `create_cast` obtém o ID da saída `list_supported_casts()`. Esse método é mais simples e garante o uso da combinação correta de função e contexto. Esse ID com certeza permanecerá o mesmo em diferentes versões do Postgres.

Para verificar se a conversão foi criada com êxito, consulte o catálogo de sistema pg\$1cast:

```
SELECT oid, castsource::regtype, casttarget::regtype, castfunc::regproc, castcontext, castmethod
FROM pg_cast
WHERE castsource = 'text'::regtype AND casttarget = 'numeric'::regtype;
  oid   | castsource | casttarget |               castfunc               | castcontext | castmethod
--------+------------+------------+--------------------------------------+-------------+------------
 356372 | text       | numeric    | rds_casts.rds_text_to_numeric_custom | i           | f
```

A coluna `castcontext` mostra: `e` para EXPLICIT, `a` para ASSIGNMENT ou `i` para IMPLICIT.

### Eliminar conversões
<a name="PostgreSQL.CustomCasts.Dropping"></a>

**Método 1: usar o comando DROP CAST**

```
DROP CAST IF EXISTS (text AS numeric);
```

**Método 2: usar a função rds\$1casts.drop\$1cast**

```
SELECT rds_casts.drop_cast(10);
```

A função `drop_cast` usa o mesmo ID usado ao criar a conversão. Esse método garante a eliminação da conversão exata que foi criada com o ID correspondente.

## Criar conversões personalizadas com a estratégia de contexto adequada
<a name="PostgreSQL.CustomCasts.BestPractices"></a>

Ao criar várias conversões para tipos inteiros, erros de ambiguidade de operador poderão ocorrer se todas as conversões forem criadas como IMPLICIT. O seguinte exemplo demonstra esse problema criando duas conversões implícitas de texto em números inteiros com largura diferente:

```
-- Creating multiple IMPLICIT casts causes ambiguity
postgres=> CREATE CAST (text AS int4) WITH FUNCTION rds_casts.rds_text_to_int4_custom(text) AS IMPLICIT;
CREATE CAST
postgres=> CREATE CAST (text AS int8) WITH FUNCTION rds_casts.rds_text_to_int8_custom(text) AS IMPLICIT;
CREATE CAST

postgres=> CREATE TABLE test_cast(col int);
CREATE TABLE
postgres=> INSERT INTO test_cast VALUES ('123'::text);
INSERT 0 1
postgres=> SELECT * FROM test_cast WHERE col='123'::text;
ERROR:  operator is not unique: integer = text
LINE 1: SELECT * FROM test_cast WHERE col='123'::text;
                                         ^
HINT:  Could not choose a best candidate operator. You might need to add explicit type casts.
```

O erro ocorre porque o PostgreSQL não consegue determinar qual conversão implícita usar ao comparar uma coluna de inteiros com um valor de texto. As conversões implícitas int4 e int8 são ambas candidatas válidas, o que cria ambiguidade.

Para evitar essa ambiguidade de operador, use o contexto ASSIGNMENT para inteiros com largura menor e o contexto IMPLICIT para inteiros com largura maior:

```
-- Use ASSIGNMENT for smaller integer widths
CREATE CAST (text AS int2)
WITH FUNCTION rds_casts.rds_text_to_int2_custom(text)
AS ASSIGNMENT;

CREATE CAST (text AS int4)
WITH FUNCTION rds_casts.rds_text_to_int4_custom(text)
AS ASSIGNMENT;

-- Use IMPLICIT for larger integer widths
CREATE CAST (text AS int8)
WITH FUNCTION rds_casts.rds_text_to_int8_custom(text)
AS IMPLICIT;

postgres=> INSERT INTO test_cast VALUES ('123'::text);
INSERT 0 1
postgres=> SELECT * FROM test_cast WHERE col='123'::text;
 col
-----
 123
(1 row)
```

Com essa estratégia, somente a conversão int8 é implícita, possibilitando que o PostgreSQL determine de forma inequívoca qual conversão usar.

# Práticas recomendadas para consultas paralelas no RDS para PostgreSQL
<a name="PostgreSQL.ParallelQueries"></a>

A execução de consultas paralelas é um recurso do PostgreSQL que permite que uma única consulta SQL seja dividida em tarefas menores que são realizadas simultaneamente por vários processos de operador em segundo plano. Em vez de executar uma consulta inteiramente em um único processo de backend, o PostgreSQL pode distribuir partes da consulta, como verificações, junções, agregações ou classificações, em vários núcleos de CPU. O *processo líder* coordena essa execução e reúne os resultados dos *operadores paralelos*.

No entanto, para a maioria das workloads de produção, especialmente sistemas de processamento de transações on-line (OLTP) com alta simultaneidade, recomendamos desabilitar a execução automática de consultas paralelas. Embora o paralelismo possa acelerar as consultas em grandes conjuntos de dados em workloads de analytics ou geração de relatórios, ele apresenta riscos significativos que geralmente superam os benefícios em ambientes de produção movimentados.

A execução paralela também gera custos indiretos significativos. Cada operador paralelo é um processo completo de backend no PostgreSQL, que requer bifurcação (cópia de estruturas de memória e inicialização do estado do processo) e autenticação de processos (consumo de slots de conexão do limite de `max_connections`). Cada operador também consome sua própria memória, inclusive `work_mem` para operações de classificação e hash. Quando há vários operadores por consulta, o uso da memória se multiplica rapidamente (p. ex., 4 operadores × 64 MB de `work_mem` = 256 MB por consulta). Por isso, as consultas paralelas podem consumir consideravelmente mais recursos do sistema do que as consultas de processo único. Se elas não forem ajustadas adequadamente, poderá haver saturação da CPU (vários operadores consomem a capacidade de processamento disponível), aumento da troca de contexto (o sistema operacional alterna frequentemente entre vários processos de operador, aumentando os custos indiretos e reduzindo o throughput) ou exaustão da conexão (visto que cada operador paralelo consome um slot de conexão, uma única consulta com quatro operadores usa cinco conexões no total, uma líder \$1 quatro operadores, o que pode esgotar rapidamente o grupo de conexões quando há alta simultaneidade, impedindo novas conexões de cliente e causando falhas na aplicação). Esses problemas são particularmente graves em workloads com alta simultaneidade, nas quais várias consultas podem tentar a execução paralela simultaneamente.

O PostgreSQL decide se deve usar o paralelismo com base em estimativas de custo. Em alguns casos, o planejador pode mudar automaticamente para um plano paralelo se isso parecer mais barato, mesmo quando não for o ideal na prática. Isso pode ocorrer se as estatísticas do índice estiverem desatualizadas ou se o inchaço fizer com que as verificações sequenciais pareçam mais atrativas do que as pesquisas de índice. Devido a esse comportamento, os planos paralelos automáticos às vezes podem provocar regressões no desempenho da consulta ou na estabilidade do sistema.

Para extrair o máximo benefício das consultas paralelas no RDS para PostgreSQL, é importante testá-las e ajustá-las com base na workload, monitorar o impacto sobre o sistema e desabilitar a seleção automática de planos paralelos em favor do controle em nível de consulta.

## Parâmetros de configuração
<a name="PostgreSQL.ParallelQueries.ConfigurationParameters"></a>

O PostgreSQL usa vários parâmetros para controlar o comportamento e a disponibilidade de consultas paralelas. Compreendê-los e ajustá-los é fundamental para alcançar um desempenho previsível:


| Parâmetro | Descrição | Padrão | 
| --- | --- | --- | 
| max\$1parallel\$1workers | Número máximo de processos de operador em segundo plano que podem ser executados no total. | GREATEST(\$1DBInstanceVCPU/2,8) | 
| max\$1parallel\$1workers\$1per\$1gather | Número máximo de operadores por nó do plano de consulta (p. ex., por Gather). | 2 | 
| parallel\$1setup\$1cost | Custo adicional do planejador para iniciar a infraestrutura de consulta paralela. | 1.000 | 
| parallel\$1tuple\$1cost | Custo por tupla processada em modo paralelo (afeta a decisão do planejador). | 0,1 | 
| force\$1parallel\$1mode | Força o planejador a testar planos paralelos (off, on, regress). | off | 

### Considerações importantes
<a name="PostgreSQL.ParallelQueries.ConfigurationParameters.KeyConsiderations"></a>
+ `max_parallel_workers` controla o conjunto total de operadores paralelos. Se definido com um valor muito baixo, algumas consultas podem voltar à execução em série.
+ `max_parallel_workers_per_gather` determina quantos operadores uma única consulta pode usar. Um valor maior aumenta a simultaneidade, mas também o uso de recursos.
+ `parallel_setup_cost` e `parallel_tuple_cost` afetam o modelo de custo do planejador. Reduzi-los pode aumentar a probabilidade de os planos paralelos serem escolhidos.
+ `force_parallel_mode` é útil para testes, mas não deve ser usado na produção, a menos que necessário.

**nota**  
O valor padrão do `max_parallel_workers` parâmetro é calculado dinamicamente com base no tamanho da instância usando a fórmula`GREATEST($DBInstanceVCPU/2, 8)`. Isso significa que quando você escalar a computação de uma instância de banco de dados para um tamanho maior com mais vCPUs, o número máximo de operadores paralelos disponíveis aumentará automaticamente. Por isso, consultas que antes eram executadas em série ou com paralelismo limitado podem utilizar mais operadores paralelos de maneira repentina após uma operação de aumento da escala vertical e possivelmente provocar aumentos inesperados no uso da conexão, na utilização da CPU e no consumo de memória. É importante monitorar o comportamento da consulta paralela após qualquer evento de ajuste de escala da computação e, se necessário, ajustar `max_parallel_workers_per_gather` para manter o uso previsível dos recursos.

## Identificar o uso de consultas paralelas
<a name="PostgreSQL.ParallelQueries.IdentifyUsage"></a>

As consultas podem mudar para planos paralelos com base na distribuição de dados ou nas estatísticas. Por exemplo:

```
SELECT count(*) FROM customers WHERE last_login < now() - interval '6 months';
```

Essa consulta pode usar um índice para dados recentes, mas mudar para uma verificação sequencial paralela de dados históricos.

É possível registrar em log os planos de execução de consultas carregando o módulo `auto_explain`. Para saber mais, consulte [Como registrar em log planos de execução de consultas](https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-tune-query-performance/#) no Centro de Conhecimento da AWS.



É possível monitorar eventos de espera no [CloudWatch Database Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Database-Insights-Database-Instance-Dashboard.html) relacionados à consulta paralela. Para saber mais sobre eventos de espera relacionados à consulta paralela, consulte [IPC: eventos de espera paralelos](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/apg-ipc-parallel.html).

A partir da versão 18 do PostgreSQL, é possível monitorar a atividade de operadores paralelos usando novas colunas em [https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW) e [https://www.postgresql.org/docs/current/pgstatstatements.html](https://www.postgresql.org/docs/current/pgstatstatements.html):
+ `parallel_workers_to_launch`: número de operadores paralelos que se pretende iniciar.
+ `parallel_workers_launched`: número de operadores paralelos realmente iniciados.

Essas métricas ajudam a identificar discrepâncias entre o paralelismo planejado e real, o que pode indicar restrições de recursos ou problemas de configuração. Use as seguintes consultas para monitorar a execução paralela:

Para métricas de operadores paralelos em nível de banco de dados:

```
SELECT datname, parallel_workers_to_launch, parallel_workers_launched
FROM pg_stat_database
WHERE datname = current_database();
```

Para métricas de operadores paralelos em nível de consulta:

```
SELECT query, parallel_workers_to_launch, parallel_workers_launched
FROM pg_stat_statements
ORDER BY parallel_workers_launched;
```

## Como controlar o paralelismo
<a name="PostgreSQL.ParallelQueries.ControlParallelism"></a>

Há várias maneiras de controlar o paralelismo de consultas, cada uma projetada para diferentes cenários e requisitos.

Para desabilitar o paralelismo automático globalmente, [modifique seu grupo de parâmetros](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithParamGroups.Modifying.html) para definir:

```
max_parallel_workers_per_gather = 0;
```

Para configurações persistentes e específicas do usuário, o comando ALTER ROLE oferece uma maneira para definir parâmetros que se aplicarão a todas as sessões futuras de determinado usuário.

Por exemplo:

`ALTER ROLE username SET max_parallel_workers_per_gather = 4;` garante que, toda vez que esse usuário se conectar ao banco de dados, as respectivas sessões usarão essa configuração de operador paralelo quando necessário.

O controle em nível de sessão pode ser obtido usando o comando SET, que modifica os parâmetros durante a sessão atual do banco de dados. Isso é particularmente útil quando é necessário ajustar temporariamente as configurações sem afetar outros usuários ou sessões futuras. Depois de definidos, esses parâmetros permanecem em vigor até serem redefinidos explicitamente ou até que a sessão termine. Os comandos são simples:

```
SET max_parallel_workers_per_gather = 4;
-- Run your queries
RESET max_parallel_workers_per_gather;
```

Para ter um controle ainda mais granular, o SET LOCAL permite modificar os parâmetros de uma única transação. Isso é ideal quando é necessário ajustar as configurações de um conjunto específico de consultas em uma transação e, após isso, reverter automaticamente as configurações para os valores anteriores. Essa abordagem ajuda a evitar efeitos indesejados em outras operações na mesma sessão.

## Diagnosticar o comportamento das consultas paralelas
<a name="PostgreSQL.ParallelQueries.Diagnosing"></a>

Use `EXPLAIN (ANALYZE, VERBOSE)` para confirmar se uma consulta usou execução paralela:
+ Procure nós como `Gather`, `Gather Merge` ou `Parallel Seq Scan`.
+ Compare os planos com e sem paralelismo.

Para desabilitar temporariamente o paralelismo para comparação:

```
SET max_parallel_workers_per_gather = 0;
EXPLAIN ANALYZE <your_query>;
RESET max_parallel_workers_per_gather;
```

# Trabalhar com parâmetros na instância de banco de dados do RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Parameters"></a>

Em alguns casos, você pode criar uma instância de banco de dados do RDS para PostgreSQL sem especificar um grupo de parâmetros personalizado. Se for o caso, sua instância de banco de dados será criada usando o grupo de parâmetros padrão para a versão do PostgreSQL que você escolher. Por exemplo, suponha que você crie uma instância de banco de dados do RDS para PostgreSQL usando o PostgreSQL 13.3. Nesse caso, a instância de banco de dados é criada usando os valores no grupo de parâmetros para versões do PostgreSQL 13, `default.postgres13`. 

Você também pode criar seus próprios grupos de parâmetros de banco de dados personalizados. Você precisará fazer isso se quiser modificar qualquer configuração da instância de banco de dados do RDS para PostgreSQL de seus valores padrão. Para saber como, consulte [Grupos de parâmetros para Amazon RDS](USER_WorkingWithParamGroups.md). 

Você pode rastrear as configurações em sua instância de banco de dados do RDS para PostgreSQL de várias maneiras diferentes. Você pode usar o Console de gerenciamento da AWS, a AWS CLI ou a API do Amazon RDS. Você também pode consultar os valores `pg_settings` da tabela PostgreSQL da instância, conforme mostrado a seguir. 

```
SELECT name, setting, boot_val, reset_val, unit
 FROM pg_settings
 ORDER BY name;
```

Para saber mais sobre os valores retornados dessa consulta, consulte [https://www.postgresql.org/docs/current/view-pg-settings.html](https://www.postgresql.org/docs/current/view-pg-settings.html) na documentação do PostgreSQL.

Tenha cuidado especial ao alterar as configurações para `max_connections` e `shared_buffers` em sua instância de banco de dados do RDS para PostgreSQL. Por exemplo, suponha que você modifique as configurações de `max_connections` ou `shared_buffers` e use valores muito altos para sua workload real. Nesse caso, sua instância de banco de dados do RDS para PostgreSQL não será iniciada. Se isso acontecer, você verá o erro a seguir no `postgres.log`.

```
2018-09-18 21:13:15 UTC::@:[8097]:FATAL:  could not map anonymous shared memory: Cannot allocate memory
2018-09-18 21:13:15 UTC::@:[8097]:HINT:  This error usually means that PostgreSQL's request for a shared memory segment
exceeded available memory or swap space. To reduce the request size (currently 3514134274048 bytes), reduce 
PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
```

No entanto, não é possível alterar nenhum valor das configurações contidas nos grupos de parâmetros de banco de dados padrão do RDS para PostgreSQL. Para alterar as configurações de qualquer parâmetro, primeiro crie um grupo de parâmetros de banco de dados personalizado. Em seguida, altere as configurações nesse grupo personalizado e, em seguida, aplique o grupo de parâmetros personalizado à sua instância de banco de dados do RDS para PostgreSQL. Para saber mais, consulte [Grupos de parâmetros para Amazon RDS](USER_WorkingWithParamGroups.md). 

Existem dois tipos de parâmetro no RDS para PostgreSQL.
+ **Parâmetros estáticos** – Os parâmetros estáticos exigem que a instância de banco de dados do RDS para PostgreSQL seja reinicializada após uma alteração para que o novo valor possa entrar em vigor.
+ **Parâmetros dinâmicos** – Parâmetros dinâmicos não exigem uma reinicialização após alterar suas configurações.

**nota**  
Se sua instância de banco de dados do RDS para PostgreSQL estiver usando seu próprio grupo de parâmetros de banco de dados personalizado, você poderá alterar os valores de parâmetros dinâmicos na instância de banco de dados em execução. Isso pode ser feito usando o Console de gerenciamento da AWS, a AWS CLI ou a API do Amazon RDS. 

Você também poderá alterar valores de parâmetros se tiver os privilégios de segurança necessários para isso usando os comandos `ALTER DATABASE`, `ALTER ROLE` e `SET`. 

## Lista de parâmetros de instância de banco de dados do RDS para PostgreSQL
<a name="Appendix.PostgreSQL.CommonDBATasks.Parameters.parameters-list"></a>

A tabela a seguir lista alguns dos parâmetros (mas nem todos) disponíveis em uma instância de banco de dados do RDS para PostgreSQL. Para visualizar todos os parâmetros disponíveis, use o comando [describe-db-parameters](https://docs.aws.amazon.com/cli/latest/reference/rds/describe-db-parameters.html) da AWS CLI. Por exemplo, para obter a lista de todos os parâmetros disponíveis no grupo de parâmetros padrão do RDS para PostgreSQL versão 13, execute o seguinte.

```
aws rds describe-db-parameters --db-parameter-group-name default.postgres13
```

Você também pode usar o console. Selecione **Parameter groups** (Grupos de parâmetros) no menu do Amazon RDS e depois selecione o grupo de parâmetros dentre os disponíveis em sua Região da AWS.


|  Nome do parâmetro  |  Apply\$1Type  |  Descrição  | 
| --- | --- | --- | 
|  `application_name`  | Dinâmico | Define o nome da aplicação a ser informada em estatísticas e logs. | 
|  `archive_command`  | Dinâmico | Define o comando shell que será chamado para arquivar um arquivo WAL. | 
|  `array_nulls`  | Dinâmico | Permite entrada de elementos NULL em arrays. | 
|  `authentication_timeout`  | Dinâmico | Define o tempo máximo permitido para concluir a autenticação de cliente. | 
|  `autovacuum`  | Dinâmico | Inicia o subprocesso de autovacuum. | 
|  `autovacuum_analyze_scale_factor`  | Dinâmico | Número de inserções, atualizações ou exclusões de tuplas anteriores à análise, como uma fração de reltuplas. | 
|  `autovacuum_analyze_threshold`  | Dinâmico | Número mínimo de inserções, atualizações ou exclusões de tuplas antes da análise. | 
|  `autovacuum_freeze_max_age`  | Estático | Idade na qual o autovacuum de uma tabela deve ocorrer para evitar a conclusão do ID de transação.  | 
|  `autovacuum_naptime`  | Dinâmico | Tempo de suspensão entre execuções de autovacuum. | 
|  `autovacuum_max_workers`  | Estático | Define o número máximo de processos de trabalho de autovacuum em execução simultaneamente. | 
|  `autovacuum_vacuum_cost_delay`  | Dinâmico | Atraso de custo de vacuum, em milissegundos, para autovacuum. | 
|  `autovacuum_vacuum_cost_limit`  | Dinâmico | Valor do custo de vacuum disponível antes da suspensão, para autovacuum. | 
|  `autovacuum_vacuum_scale_factor`  | Dinâmico | Número de atualizações ou exclusões de tuplas antes de vacuum, como uma fração de reltuplas. | 
|  `autovacuum_vacuum_threshold`  | Dinâmico | Número mínimo de atualizações ou exclusões de tuplas antes de vacuum. | 
|  `backslash_quote`  | Dinâmico | Define-se uma barra invertida (\$1) é permitida em literais de string. | 
|  `bgwriter_delay`  | Dinâmico | Tempo de suspensão do gravador em segundo plano entre rodadas. | 
|  `bgwriter_lru_maxpages`  | Dinâmico | Número máximo do gravador em segundo plano de páginas LRU para descarregamento por rodada. | 
|  `bgwriter_lru_multiplier`  | Dinâmico | Múltiplo do uso médio do buffer para liberação por rodada. | 
|  `bytea_output`  | Dinâmico | Define o formato da saída para bytes. | 
|  `check_function_bodies`  | Dinâmico | Verifica corpos de funções durante CREATE FUNCTION. | 
|  `checkpoint_completion_target`  | Dinâmico | Tempo gasto descarregando buffers sujos durante verificações, como uma fração do intervalo de verificação. | 
|  `checkpoint_segments`  | Dinâmico | Define a distância máxima em segmentos de log entre verificações pontos de verificação WAL (write-ahead log)de log WAL automáticos. | 
|  `checkpoint_timeout`  | Dinâmico | Define o tempo máximo entre verificações WAL automáticas. | 
|  `checkpoint_warning`  | Dinâmico | Permite avisos se segmentos de verificação forem preenchidos mais frequentemente do que isso. | 
|  `client_connection_check_interval`  | Dinâmico |  Define o intervalo de tempo entre as verificações de desconexão durante a execução de consultas. | 
|  `client_encoding`  | Dinâmico | Define a codificação do conjunto de caracteres do cliente. | 
|  `client_min_messages`  | Dinâmico | Define os níveis de mensagem enviados ao cliente. | 
|  `commit_delay`  | Dinâmico | Define o atraso em microssegundos entre a confirmação da transação e a liberação do WAL no disco. | 
|  `commit_siblings`  | Dinâmico | Define o mínimo de transações simultâneas abertas antes de realizar commit\$1delay. | 
|  `constraint_exclusion`  | Dinâmico | Permite que o planejador use restrições para otimizar consultas. | 
|  `cpu_index_tuple_cost`  | Dinâmico | Define a estimativa do planejador sobre o custo do processamento de cada entrada de índice durante uma verificação de índice. | 
|  `cpu_operator_cost`  | Dinâmico | Define a estimativa do planejador sobre o custo do processamento de cada operador ou chamada de função. | 
|  `cpu_tuple_cost`  | Dinâmico | Define a estimativa do planejador sobre o custo do processamento de cada tupla (linha). | 
|  `cursor_tuple_fraction`  | Dinâmico | Define a estimativa do planejador sobre a fração de linhas de um cursor que serão recuperadas. | 
|  `datestyle`  | Dinâmico | Define o formato de exibição de valores de data e hora. | 
|  `deadlock_timeout`  | Dinâmico | Define o tempo de espera em um bloqueio antes de verificar a existência de um deadlock. | 
|  `debug_pretty_print`  | Dinâmico | Recua exibições de árvores de análise e plano. | 
|  `debug_print_parse`  | Dinâmico | Registra a árvore de análise de cada consulta. | 
|  `debug_print_plan`  | Dinâmico | Registra o plano de execução de cada consulta. | 
|  `debug_print_rewritten`  | Dinâmico | Registra a árvore de análise regravada de cada consulta. | 
|  `default_statistics_target`  | Dinâmico | Define o destino de estatísticas padrão. | 
|  `default_tablespace`  | Dinâmico | Define o espaço de tabela padrão no qual criar tabelas e índices. | 
|  `default_transaction_deferrable`  | Dinâmico | Define o status padrão postergável de novas transações. | 
|  `default_transaction_isolation`  | Dinâmico | Define o nível de isolamento de transação de cada nova transação. | 
|  `default_transaction_read_only`  | Dinâmico | Define o status padrão somente leitura de novas transações. | 
|  `default_with_oids`  | Dinâmico | Cria tabelas com “Object IDs” (OIDs – IDs de objetos) por padrão. | 
|  `effective_cache_size`  | Dinâmico | Define a pressuposição do planejador sobre o tamanho do cache de disco. | 
|  `effective_io_concurrency`  | Dinâmico | Número de solicitações simultâneas que podem ser manipuladas de forma eficiente pelo subsistema de disco. | 
|  `enable_bitmapscan`  | Dinâmico | Permite o uso do planejador de planos de verificação de bitmap. | 
|  `enable_hashagg`  | Dinâmico | Permite o uso do planejador de planos de agregação em hash. | 
|  `enable_hashjoin`  | Dinâmico | Permite o uso do planejador de planos de junção hash. | 
|  `enable_indexscan`  | Dinâmico | Permite o uso do planejador de planos de verificação de índice. | 
|  `enable_material`  | Dinâmico | Permite o uso do planejador da materialização. | 
|  `enable_mergejoin`  | Dinâmico | Permite o uso do planejador de planos de junção de mesclagem. | 
|  `enable_nestloop`  | Dinâmico | Permite o uso do planejador de planos de junção de loop aninhado. | 
|  `enable_seqscan`  | Dinâmico | Permite o uso do planejador de planos de verificação sequencial. | 
|  `enable_sort`  | Dinâmico | Permite o uso do planejador de etapas de classificação explícitas. | 
|  `enable_tidscan`  | Dinâmico | Permite o uso do planejador de planos de verificação TID. | 
|  `escape_string_warning`  | Dinâmico | Avisa sobre escapes de barra invertida (\$1) em literais de string comuns. | 
|  `extra_float_digits`  | Dinâmico | Define o número de dígitos exibidos para valores de ponto flutuante. | 
|  `from_collapse_limit`  | Dinâmico | Define o tamanho da lista FROM além do qual subconsultas não são recolhidas. | 
|  `fsync`  | Dinâmico | Força a sincronização de atualizações no disco. | 
|  `full_page_writes`  | Dinâmico | Grava páginas cheias no WAL ao serem modificadas pela primeira vez após uma verificação. | 
|  `geqo`  | Dinâmico | Permite a otimização de consultas genéticas. | 
|  `geqo_effort`  | Dinâmico | GEQO: esforço é usado para definir o padrão para outros parâmetros GEQO. | 
|  `geqo_generations`  | Dinâmico | GEQO: número de iterações do algoritmo. | 
|  `geqo_pool_size`  | Dinâmico | GEQO: número de indivíduos na população. | 
|  `geqo_seed`  | Dinâmico | GEQO: propagação para seleção de caminho aleatório. | 
|  `geqo_selection_bias`  | Dinâmico | GEQO: pressão seletiva dentro da população. | 
|  `geqo_threshold`  | Dinâmico | Define o limite de itens FROM além do qual o GEQO é usado. | 
|  `gin_fuzzy_search_limit`  | Dinâmico | Define o resultado máximo permitido para pesquisa exata por GIN. | 
|  `hot_standby_feedback`  | Dinâmico | Determina se um standby a quente envia mensagens de comentários ao standby principal ou upstream. | 
|  `intervalstyle`  | Dinâmico | Define o formato de exibição para valores de intervalo. | 
|  `join_collapse_limit`  | Dinâmico | Define o tamanho da lista FROM além do qual constructos JOIN não são nivelados. | 
|  `lc_messages`  | Dinâmico | Define o idioma em que as mensagens são exibidas. | 
|  `lc_monetary`  | Dinâmico | Define a localidade para a formatação de valores monetários. | 
|  `lc_numeric`  | Dinâmico | Define a localidade para a formatação de números. | 
|  `lc_time`  | Dinâmico | Define a localidade para a formatação de valores de data e hora. | 
|  `log_autovacuum_min_duration`  | Dinâmico | Define o tempo de execução mínimo acima do qual as ações de autovacuum serão registradas em log. | 
|  `log_checkpoints`  | Dinâmico | Registra cada verificação. | 
|  `log_connections`  | Dinâmico | Registra cada conexão bem-sucedida. | 
|  `log_disconnections`  | Dinâmico | Registra o fim de uma sessão, incluindo a duração. | 
|  `log_duration`  | Dinâmico | Registra a duração de cada instrução SQL concluída. | 
|  `log_error_verbosity`  | Dinâmico | Define a verbosidade das mensagens registradas. | 
|  `log_executor_stats`  | Dinâmico | Grava estatísticas de performance do executor no log do servidor. | 
|  `log_filename`  | Dinâmico | Define o padrão de nome de arquivo para arquivos de log. | 
|  `log_file_mode`  | Dinâmico | Define as permissões de arquivos de log. O valor padrão é 0644. | 
|  `log_hostname`  | Dinâmico | Registra o nome do host nos logs de conexão. A partir do PostgreSQL 12 e versões posteriores, esse parâmetro está “desativado” por padrão. Quando ativada, a conexão usa a pesquisa reversa de DNS para obter o nome do host que é capturado nos logs de conexão. Se você ativar esse parâmetro, deverá monitorar o impacto que ele tem no tempo necessário para estabelecer conexões.  | 
|  `log_line_prefix `  | Dinâmico | Controla informações prefixadas para cada linha de log. | 
|  `log_lock_waits`  | Dinâmico | Registra esperas de bloqueio longas. | 
|  `log_min_duration_statement`  | Dinâmico | Define o tempo de execução mínimo acima do qual as instruções serão registradas em log. | 
|  `log_min_error_statement`  | Dinâmico | Faz com que todas as instruções que geram um erro igual ou acima desse nível sejam registradas. | 
|  `log_min_messages`  | Dinâmico | Define os níveis de mensagem registrados. | 
|  `log_parser_stats`  | Dinâmico | Grava estatísticas de performance do analisador no log do servidor. | 
|  `log_planner_stats`  | Dinâmico | Grava estatísticas de performance do planejador no log do servidor. | 
|  `log_rotation_age`  | Dinâmico | A rotação automática de arquivos de log ocorrerá depois de N minutos. | 
|  `log_rotation_size`  | Dinâmico | A rotação automática de arquivos de log ocorrerá depois de N kilobytes. | 
|  `log_statement`  | Dinâmico | Define o tipo de instruções registradas. | 
|  `log_statement_stats`  | Dinâmico | Grava estatísticas de performance cumulativas no log do servidor. | 
|  `log_temp_files`  | Dinâmico | Registra o uso de arquivos temporários maiores do que esse número de kilobytes. | 
|  `log_timezone`  | Dinâmico | Define o fuso horário a ser usado em mensagens de log. | 
|  `log_truncate_on_rotation`  | Dinâmico | Trunca os arquivos de log existentes com o mesmo nome durante a alternância do log. | 
|  `logging_collector`  | Estático | Inicia um subprocesso para capturar a saída stderr e/ou csvlogs em arquivos de log. | 
|  `maintenance_work_mem`  | Dinâmico | Define a memória máxima a ser usada para operações de manutenção. | 
|  `max_connections`  | Estático | Define o número máximo de conexões simultâneas. | 
|  `max_files_per_process`  | Estático | Define o número máximo de arquivos abertos simultaneamente para cada processo do servidor. | 
|  `max_locks_per_transaction`  | Estático | Define o número máximo de bloqueios por transação. | 
|  `max_pred_locks_per_transaction`  | Estático | Define o número máximo de bloqueios de predicado por transação. | 
|  `max_prepared_transactions`  | Estático | Define o número máximo de transações simultaneamente preparadas. | 
|  `max_stack_depth`  | Dinâmico | Define a profundidade máxima da pilha, em kilobytes. | 
|  `max_standby_archive_delay`  | Dinâmico | Define o atraso máximo antes de cancelar consultas quando um servidor em standby a quente está processando dados WAL arquivados. | 
|  `max_standby_streaming_delay`  | Dinâmico | Define o atraso máximo antes de cancelar consultas quando um servidor em standby a quente está processando dados do WAL em stream. | 
| max\$1wal\$1size | Dinâmico | Define o tamanho do WAL (MB) que aciona o ponto de verificação. [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Parameters.html) Use o seguinte comando na instância de banco de dados do Amazon RDS para PostgreSQL para ver o valor atual: <pre>SHOW max_wal_size;</pre>  | 
| min\$1wal\$1size | Dinâmico | Define o tamanho mínimo até o qual diminuir o WAL. Para o PostgreSQL versão 9.6 e anterior, min\$1wal\$1size está em unidades de 16 MB. Para o PostgreSQL versão 10 e posterior, min\$1wal\$1size está em unidades de 1 MB.  | 
|  `quote_all_identifiers`  | Dinâmico | Adiciona aspas (") a todos os identificadores ao gerar fragmentos SQL. | 
|  `random_page_cost`  | Dinâmico | Define a estimativa do planejador sobre o custo de uma página de disco não sequencialmente buscada. Esse parâmetro não tem valor, a menos que o gerenciamento do plano de consulta (QPM) esteja ativado. Quando o QPM está ativado, o valor padrão desse parâmetro é 4.  | 
| rds.adaptive\$1autovacuum | Dinâmico | Ajusta automaticamente os parâmetros de autovacuum sempre que os limites de ID de transação são excedidos. | 
| rds.force\$1ssl | Dinâmico | Requer o uso de conexões SSL. O valor padrão é definido como 1 (ligado) para o RDS para PostgreSQL versão 15. Todas as outras versões principais do RDS para PostgreSQL 14 e anteriores têm o valor padrão definido como 0 (desativado). | 
|  `rds.local_volume_spill_enabled`  | Estático | Permite gravar arquivos de despejo lógico no volume local. | 
|  `rds.log_retention_period`  | Dinâmico | Define a retenção de logs para que o Amazon RDS exclua os logs do PostgreSQL com mais de n minutos. | 
| rds.rds\$1superuser\$1reserved\$1connections | Estático | Define o número de slots de conexão reservados para rds\$1superusers. Esse parâmetro só está disponível nas versões 15 e posterior. Para ter mais informações, consulte [reserved\$1connections](https://www.postgresql.org/docs/current/runtime-config-connection.html#GUC-RESERVED-CONNECTIONS) na documentação do PostgreSQL. | 
| `rds.replica_identity_full` | Dinâmico | Quando você define esse parâmetro como `on`, ele substitui a configuração de identidade da réplica por `FULL` em todas as tabelas do banco de dados. Isso significa que todos os valores das colunas são gravados no log de gravação antecipada (WAL), independentemente das configurações de `REPLICA IDENTITY FULL`.  A ativação desse parâmetro pode aumentar as IOPS da instância de banco de dados devido ao registro em log adicional com gravação antecipada (WAL).   | 
| rds.restrict\$1password\$1commands | Estático | Restringe quem gerencia senhas para usuários com a função rds\$1password. Defina esse parâmetro como 1 para habilitar a restrição de senha. O padrão é 0. | 
|  `search_path`  | Dinâmico | Define a ordem de pesquisa do esquema de nomes que não são qualificados para esquema. | 
|  `seq_page_cost`  | Dinâmico | Define a estimativa do planejador sobre o custo de uma página de disco sequencialmente buscada. | 
|  `session_replication_role`  | Dinâmico | Define o comportamento de sessões para disparadores e regras de regravação. | 
|  `shared_buffers`  | Estático | Define o número de buffers de memória compartilhada usados pelo servidor. | 
|  `shared_preload_libraries `  | Estático | Lista as bibliotecas compartilhadas a serem pré-carregadas na instância de banco de dados do RDS para PostgreSQL. Os valores compatíveis incluem auto\$1explain, orafce, pgaudit, pglogical, pg\$1bigm, pg\$1cron, pg\$1hint\$1plan, pg\$1prewarm, pg\$1similarity, pg\$1stat\$1statements, pg\$1tle, pg\$1transport, plprofiler e plrust. | 
|  `ssl`  | Dinâmico | Habilita conexões SSL. | 
|  `sql_inheritance`  | Dinâmico | Faz com que subtabelas sejam incluídas por padrão em vários comandos. | 
|  `ssl_renegotiation_limit`  | Dinâmico | Define a quantidade de tráfego para envio e recebimento antes da renegociação das chaves de criptografia. | 
|  `standard_conforming_strings`  | Dinâmico | Faz com que strings ... tratem barras invertidas literalmente. | 
|  `statement_timeout`  | Dinâmico | Define a duração máxima permitida de qualquer instrução. | 
|  `synchronize_seqscans`  | Dinâmico | Permite varreduras sequenciais sincronizadas. | 
|  `synchronous_commit`  | Dinâmico | Define o nível de sincronização de transações atual. | 
|  `tcp_keepalives_count`  | Dinâmico | Número máximo de retransmissões de keepalives TCP. | 
|  `tcp_keepalives_idle`  | Dinâmico | Tempo entre a emissão de keepalives TCP. | 
|  `tcp_keepalives_interval`  | Dinâmico | Tempo entre retransmissões de keepalives TCP. | 
|  `temp_buffers`  | Dinâmico | Define o número máximo de buffers temporários usado por cada sessão. | 
| temp\$1file\$1limit | Dinâmico | Define o tamanho máximo em KB até o qual os arquivos temporários podem aumentar. | 
|  `temp_tablespaces`  | Dinâmico | Define os espaços de tabela a serem usados para tabelas temporárias e arquivos de classificação. | 
|  `timezone`  | Dinâmico | Define o fuso horário para exibir e interpretar carimbos de data/hora. A Internet Assigned Numbers Authority (IANA) publica novos fusos horários várias vezes por ano em [https://www.iana.org/time-zones](https://www.iana.org/time-zones). Toda vez que o RDS lança uma nova versão de manutenção secundária do PostgreSQL, ela vem com os dados de fuso horário mais recentes no momento do lançamento. Quando você usa as versões mais recentes do RDS para PostgreSQL, você tem dados de fuso horário recentes do RDS. Para garantir que sua instância de banco de dados tenha dados de fuso horário recentes, recomendamos atualizar para uma versão superior do mecanismo de banco de dados. Não é possível modificar manualmente as tabelas de fuso horário nas instâncias de banco de dados PostgreSQL. O RDS não modifica nem redefine os dados de fuso horário das instâncias de banco de dados em execução. Os novos dados de fuso horário são instalados somente quando você executa uma atualização da versão do mecanismo de banco de dados. | 
|  `track_activities`  | Dinâmico | Coleta informações sobre a execução de comandos. | 
|  `track_activity_query_size`  | Estático | Define o tamanho reservado para pg\$1stat\$1activity.current\$1query, em bytes. | 
|  `track_counts`  | Dinâmico | Coleta estatísticas sobre a atividade do banco de dados. | 
|  `track_functions`  | Dinâmico | Coleta estatísticas em nível de função sobre a atividade do banco de dados. | 
|  `track_io_timing`  | Dinâmico | Coleta estatísticas de tempo sobre atividades de E/S do banco de dados. | 
|  `transaction_deferrable`  | Dinâmico | Indica se uma transação serializável somente de leitura deve ser adiada até que ela possa ser iniciada sem falhas de serialização possíveis. | 
|  `transaction_isolation`  | Dinâmico | Define o nível atual de isolamento de transações. | 
|  `transaction_read_only`  | Dinâmico | Define o status somente leitura das transações atuais. | 
|  `transform_null_equals`  | Dinâmico | Trata expr=NULL como expr IS NULL. | 
|  `update_process_title`  | Dinâmico | Atualiza o título do processo para mostrar o comando SQL ativo. | 
|  `vacuum_cost_delay`  | Dinâmico | Atraso de custo de vacuum, em milissegundos. | 
|  `vacuum_cost_limit`  | Dinâmico | Valor do custo de vacuum disponível antes da suspensão. | 
|  `vacuum_cost_page_dirty`  | Dinâmico | Custo de vacuum para uma página suja por vacuum. | 
|  `vacuum_cost_page_hit`  | Dinâmico | Custo de vacuum para uma página encontrada no cache do buffer. | 
|  `vacuum_cost_page_miss`  | Dinâmico | Custo de vacuum para uma página não encontrada no cache do buffer. | 
|  `vacuum_defer_cleanup_age`  | Dinâmico | Número de transações pelas quais a limpeza vacuum e hot deve ser adiada, se houver. | 
|  `vacuum_freeze_min_age`  | Dinâmico | Idade mínima na qual o vacuum deve congelar uma linha de tabela. | 
|  `vacuum_freeze_table_age`  | Dinâmico | Idade na qual o vacuum deve varrer uma tabela inteira para congelar tuplas. | 
|  `wal_buffers`  | Estático | Define o número de buffers da página de disco na memória compartilhada para WAL. | 
|  `wal_writer_delay`  | Dinâmico | Tempo de suspensão do gravador WAL entre liberações do WAL. | 
|  `work_mem`  | Dinâmico | Define o máximo de memória a ser usado para espaços de trabalho de consulta. | 
|  `xmlbinary`  | Dinâmico | Define como valores binários devem ser codificados em XML. | 
|  `xmloption`  | Dinâmico | Define se dados XML em operações de análise e serialização implícitas são considerados documentos ou fragmentos de conteúdo. | 

O Amazon RDS usa as unidades padrão do PostgreSQL para todos os parâmetros. A tabela a seguir mostra a unidade padrão de cada parâmetro do PostgreSQL.


|  Nome do parâmetro  |  Unidade  | 
| --- | --- | 
| `archive_timeout` | s | 
| `authentication_timeout` | s | 
| `autovacuum_naptime` | s | 
| `autovacuum_vacuum_cost_delay` | ms | 
| `bgwriter_delay` | ms | 
| `checkpoint_timeout` | s | 
| `checkpoint_warning` | s | 
| `deadlock_timeout` | ms | 
| `effective_cache_size` | 8 KB | 
| `lock_timeout` | ms | 
| `log_autovacuum_min_duration` | ms | 
| `log_min_duration_statement` | ms | 
| `log_rotation_age` | minutos | 
| `log_rotation_size` | KB | 
| `log_temp_files` | KB | 
| `maintenance_work_mem` | KB | 
| `max_stack_depth` | KB | 
| `max_standby_archive_delay` | ms | 
| `max_standby_streaming_delay` | ms | 
| `post_auth_delay` | s | 
| `pre_auth_delay` | s | 
| `segment_size` | 8 KB | 
| `shared_buffers` | 8 KB | 
| `statement_timeout` | ms | 
| `ssl_renegotiation_limit` | KB | 
| `tcp_keepalives_idle` | s | 
| `tcp_keepalives_interval` | s | 
| `temp_file_limit` | KB | 
| `work_mem` | KB | 
| `temp_buffers` | 8 KB | 
| `vacuum_cost_delay` | ms | 
| `wal_buffers` | 8 KB | 
| `wal_receiver_timeout` | ms | 
| `wal_segment_size` | B | 
| `wal_sender_timeout` | ms | 
| `wal_writer_delay` | ms | 
| `wal_receiver_status_interval` | s | 