

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