

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