

# Ajustar com eventos de espera do Aurora PostgreSQL
<a name="AuroraPostgreSQL.Tuning"></a>

Eventos de espera são uma ferramenta de ajuste importante para o Aurora PostgreSQL. Se você puder descobrir por que as sessões estão aguardando recursos e o que elas estão fazendo, poderá reduzir melhor os gargalos. Use as informações nesta seção para encontrar possíveis causas e ações corretivas. Antes de se aprofundar nesta seção, é altamente recomendável que você entenda os conceitos básicos do Aurora, principalmente os seguintes tópicos:
+ [Armazenamento do Amazon Aurora](Aurora.Overview.StorageReliability.md)
+ [Como gerenciar a performance e a escalabilidade de clusters de banco de dados do Aurora](Aurora.Managing.Performance.md) 

**Importante**  
Os eventos de espera nesta seção são específicos para o Aurora PostgreSQL. Utilize as informações nesta seção para ajustar somente o Amazon Aurora, e não o RDS para PostgreSQL.  
Alguns eventos de espera nesta seção não têm análogos nas versões de código aberto desses mecanismos de banco de dados. Outros eventos de espera têm os mesmos nomes que os eventos em mecanismos de código aberto, mas se comportam de maneira diferente. Por exemplo, o armazenamento do Amazon Aurora funciona de maneira diferente do armazenamento de código aberto e, portanto, eventos de espera relacionados a armazenamento indicam condições de recursos diferentes.

**Topics**
+ [Conceitos essenciais para ajuste do Aurora PostgreSQL](AuroraPostgreSQL.Tuning.concepts.md)
+ [Eventos de espera do Aurora PostgreSQL](AuroraPostgreSQL.Tuning.concepts.summary.md)
+ [Client:ClientRead](apg-waits.clientread.md)
+ [Client:ClientWrite](apg-waits.clientwrite.md)
+ [CPU](apg-waits.cpu.md)
+ [IO:BufFileRead and IO:BufFileWrite](apg-waits.iobuffile.md)
+ [IO:DataFileRead](apg-waits.iodatafileread.md)
+ [IO:XactSync](apg-waits.xactsync.md)
+ [IPC:DamRecordTxAck](apg-waits.ipcdamrecordtxac.md)
+ [IPC: eventos de espera paralelos](apg-ipc-parallel.md)
+ [IPC:ProcArrayGroupUpdate](apg-rpg-ipcprocarraygroup.md)
+ [Lock:advisory](apg-waits.lockadvisory.md)
+ [Lock:extend](apg-waits.lockextend.md)
+ [Lock:Relation](apg-waits.lockrelation.md)
+ [Lock:transactionid](apg-waits.locktransactionid.md)
+ [Lock:tuple](apg-waits.locktuple.md)
+ [LWLock:buffer\$1content (BufferContent)](apg-waits.lockbuffercontent.md)
+ [LWLock:buffer\$1mapping](apg-waits.lwl-buffer-mapping.md)
+ [LWLock:BufferIO (IPC:BufferIO)](apg-waits.lwlockbufferio.md)
+ [LWLock:lock\$1manager](apg-waits.lw-lock-manager.md)
+ [LWLock:MultiXact](apg-waits.lwlockmultixact.md)
+ [LWLock:pg\$1stat\$1statements](apg-rpg-lwlockpgstat.md)
+ [Tempo limite:PgSleep](apg-waits.timeoutpgsleep.md)

# Conceitos essenciais para ajuste do Aurora PostgreSQL
<a name="AuroraPostgreSQL.Tuning.concepts"></a>

Antes de ajustar seu banco de dados Aurora PostgreSQL, aprenda o que são eventos de espera e por que eles ocorrem. Reveja também a arquitetura básica de memória e disco do Aurora PostgreSQL. Para obter um diagrama de arquitetura útil, consulte o wikibook [PostgreSQL](https://en.wikibooks.org/wiki/PostgreSQL/Architecture).

**Topics**
+ [Eventos de espera do Aurora PostgreSQL](#AuroraPostgreSQL.Tuning.concepts.waits)
+ [Memória do Aurora PostgreSQL](#AuroraPostgreSQL.Tuning.concepts.memory)
+ [Processos do Aurora PostgreSQL](#AuroraPostgreSQL.Tuning.concepts.processes)

## Eventos de espera do Aurora PostgreSQL
<a name="AuroraPostgreSQL.Tuning.concepts.waits"></a>

Um *evento de espera* indica um recurso pelo qual uma sessão está aguardando. Por exemplo, o evento de espera `Client:ClientRead` ocorre quando o Aurora PostgreSQL está aguardando para receber dados do cliente. Os recursos comuns que uma sessão aguarda incluem:
+ Acesso com thread único a um buffer, por exemplo, quando uma sessão está tentando modificar um buffer
+ Uma linha que está bloqueada por outra sessão
+ Uma leitura de arquivo de dados
+ Uma gravação em arquivo de log

Por exemplo, para satisfazer uma consulta, a sessão pode realizar uma varredura de tabela completa. Se esses dados ainda não estiverem na memória, a sessão aguardará a conclusão da E/S do disco. Quando os buffers são lidos na memória, talvez a sessão precise aguardar, pois outras sessões estão acessando os mesmos buffers. O banco de dados registra as esperas utilizando um evento de espera predefinido. Esses eventos estão agrupados em categorias.

Por si só, um evento de espera não mostra um problema de performance. Por exemplo, se os dados solicitados não estão na memória, é necessário ler dados do disco. Se uma sessão bloquear uma linha para uma atualização, outra sessão aguardará que essa linha seja desbloqueada para poder atualizá-la. Uma confirmação exige a conclusão da gravação em um arquivo de log. Esperas são componentes integrais do funcionamento normal de um banco de dados. 

Em geral, muitos eventos de espera indicam um problema de performance. Nesses casos, é possível utilizar os dados dos eventos de espera para determinar onde as sessões estão perdendo tempo. Por exemplo, se um relatório que é normalmente executado em minutos passou a demorar várias horas, é possível identificar os eventos de espera que mais contribuem para o tempo de espera total. Se você puder determinar as causas dos principais eventos de espera, às vezes pode aplicar alterações que melhoram a performance. Por exemplo, se a sua sessão está aguardando uma linha que foi bloqueada por outra sessão, é possível encerrar a sessão responsável pelo bloqueio. 

## Memória do Aurora PostgreSQL
<a name="AuroraPostgreSQL.Tuning.concepts.memory"></a>

A memória do Aurora PostgreSQL está dividida em compartilhada e local.

**Topics**
+ [Memória compartilhada no Aurora PostgreSQL](#AuroraPostgreSQL.Tuning.concepts.shared)
+ [Memória local no Aurora PostgreSQL](#AuroraPostgreSQL.Tuning.concepts.local)

### Memória compartilhada no Aurora PostgreSQL
<a name="AuroraPostgreSQL.Tuning.concepts.shared"></a>

O Aurora PostgreSQL aloca memória compartilhada quando a instância é iniciada. A memória compartilhada está dividida em várias subáreas. A seguir, você encontrará uma descrição das mais importantes.

**Topics**
+ [Buffers compartilhados](#AuroraPostgreSQL.Tuning.concepts.buffer-pool)
+ [Buffers de log de gravação antecipada (WAL)](#AuroraPostgreSQL.Tuning.concepts.WAL)

#### Buffers compartilhados
<a name="AuroraPostgreSQL.Tuning.concepts.buffer-pool"></a>

O *grupo de buffer compartilhado* é uma área de memória do Aurora PostgreSQL que contém todas as páginas que estão ou estavam sendo utilizadas por conexões de aplicações. Uma *página* é a versão de memória de um bloco de disco. O grupo de buffer compartilhado armazena em cache os blocos de dados lidos do disco. O grupo reduz a necessidade de reler dados do disco, fazendo com que o banco de dados opere de maneira mais eficiente.

Cada tabela e índice são armazenados como uma matriz de páginas com tamanho fixo. Cada bloco contém várias tuplas, que correspondem a linhas. Uma tupla pode ser armazenada em qualquer página.

O grupo de buffer compartilhado possui memória finita. Se uma nova solicitação exigir uma página que não esteja na memória e não houver mais memória, o Aurora PostgreSQL removerá uma página utilizada com menos frequência para acomodar essa solicitação. A política de despejo é implementada por um algoritmo de varredura de relógio.

O parâmetro `shared_buffers` determina a quantidade de memória que o servidor dedica ao armazenamento em cache de dados.

#### Buffers de log de gravação antecipada (WAL)
<a name="AuroraPostgreSQL.Tuning.concepts.WAL"></a>

Um *buffer de log de gravação antecipada (WAL)* mantém dados de transação que o Aurora PostgreSQL grava posteriormente no armazenamento persistente. Utilizando o mecanismo WAL, o Aurora PostgreSQL pode fazer o seguinte:
+ Recupere dados após uma falha
+ Reduzir a E/S de disco, evitando gravações frequentes em disco

Quando um cliente modifica dados, o Aurora PostgreSQL grava as alterações no buffer de WAL. Quando o cliente emite um `COMMIT`, o processo gravador WAL grava dados de transação no arquivo de WAL.

O parâmetro `wal_level` determina quantas informações são gravadas no WAL.

### Memória local no Aurora PostgreSQL
<a name="AuroraPostgreSQL.Tuning.concepts.local"></a>

Todo processo de backend aloca memória local para processamento de consultas.

**Topics**
+ [Área de memória de trabalho](#AuroraPostgreSQL.Tuning.concepts.local.work_mem)
+ [Área de memória de trabalho para manutenção](#AuroraPostgreSQL.Tuning.concepts.local.maintenance_work_mem)
+ [Área de buffer temporária](#AuroraPostgreSQL.Tuning.concepts.temp)

#### Área de memória de trabalho
<a name="AuroraPostgreSQL.Tuning.concepts.local.work_mem"></a>

A *área de memória de trabalho*contém dados temporários para consultas que executam classificações e hashes. Por exemplo, uma consulta com uma cláusula `ORDER BY` executa uma classificação. Consultas usam tabelas de hash em agregações e junções de hash.

O parâmetro `work_mem` é a quantidade de memória a ser utilizada por operações de classificação internas e tabelas de hash antes da gravação em arquivos de disco temporários. O valor padrão é 4 MB. Várias sessões podem ser executadas simultaneamente, e cada uma pode executar operações de manutenção em paralelo. Por esse motivo, a memória de trabalho total utilizada pode ser múltiplos da configuração `work_mem`. 

#### Área de memória de trabalho para manutenção
<a name="AuroraPostgreSQL.Tuning.concepts.local.maintenance_work_mem"></a>

A *área de memória de trabalho para manutenção* armazena dados em cache para operações de manutenção. Essas operações incluem aspiração, criação de índices e adição de chaves externas.

O parâmetro `maintenance_work_mem` especifica a quantidade máxima de memória a ser utilizada por operações de manutenção. O valor padrão é 64 MB. Uma sessão de banco de dados apenas pode executar uma operação de manutenção de cada vez.

#### Área de buffer temporária
<a name="AuroraPostgreSQL.Tuning.concepts.temp"></a>

A *área de buffer temporária* armazena tabelas temporárias em cache para cada sessão de banco de dados.

Cada sessão aloca buffers temporários conforme necessário até o limite especificado. Quando a sessão termina, o servidor limpa os buffers.

O parâmetro `temp_buffers` define o número máximo de buffers temporários utilizados por cada sessão. Antes do primeiro uso de tabelas temporárias em uma sessão, é possível alterar o valor de `temp_buffers`.

## Processos do Aurora PostgreSQL
<a name="AuroraPostgreSQL.Tuning.concepts.processes"></a>

O Aurora PostgreSQL utiliza vários processos.

**Topics**
+ [Processo Postmaster](#AuroraPostgreSQL.Tuning.concepts.postmaster)
+ [Processos de backend](#AuroraPostgreSQL.Tuning.concepts.backend)
+ [Processos em segundo plano](#AuroraPostgreSQL.Tuning.concepts.vacuum)

### Processo Postmaster
<a name="AuroraPostgreSQL.Tuning.concepts.postmaster"></a>

O *processo de postmaster* é o primeiro a ser iniciado quando você inicia o Aurora PostgreSQL. Ele tem as seguintes responsabilidades principais:
+ Bifurcar e monitorar processos em segundo plano
+ Receba solicitações de autenticação dos processos do cliente e autentique-as antes de permitir que o banco de dados atenda às solicitações

### Processos de backend
<a name="AuroraPostgreSQL.Tuning.concepts.backend"></a>

Se o postmaster autenticar uma solicitação de cliente, o postmaster bifurcará um novo processo de backend, também chamado de processo postgres. Um processo de cliente conecta-se exatamente a um processo de backend. O processo de cliente e o processo de backend se comunicam diretamente sem a intervenção do processo postmaster.

### Processos em segundo plano
<a name="AuroraPostgreSQL.Tuning.concepts.vacuum"></a>

O processo postmaster bifurca vários processos que realizam diferentes tarefas de backend. Alguns dos mais importantes incluem:
+ Gravador WAL

  O Aurora PostgreSQL grava dados no buffer de WAL (gravação antecipada) nos arquivos de log. O princípio do registro em log de gravação antecipada determina que o banco de dados não pode gravar alterações nos arquivos de dados até que o banco de dados grave registros de log descrevendo essas alterações no disco. O mecanismo WAL reduz a E/S do disco e permite que o Aurora PostgreSQL utilize os logs para recuperar o banco de dados após uma falha.
+ Gravador em segundo plano

  Esse processo grava periodicamente páginas sujas (modificadas) dos buffers de memória nos arquivos de dados. Uma página fica suja quando um processo de backend a modifica na memória.
+ Daemon autovacuum

  O daemon consiste no seguinte:
  + O launcher de autovacuum
  + Os processos de operador de autovacuum

  Quando o autovacuum está ativado, ele procura tabelas que tiveram um grande número de tuplas inseridas, atualizadas ou excluídas. Esse daemon tem as seguintes responsabilidades:
  + Recuperar ou reutilizar o espaço em disco ocupado por linhas atualizadas ou excluídas
  + Atualizar estatísticas utilizadas pelo planejador
  + Proteger contra a perda de dados antigos devido à recorrência de IDs de transação

  O recurso e autovacuum automatiza a execução de comandos `VACUUM` e `ANALYZE`. `VACUUM` tem as seguintes variantes: padrão e completo. O vacuum padrão é executado em paralelo com outras operações de banco de dados. `VACUUM FULL` requer um bloqueio exclusivo na tabela em que está trabalhando. Portanto, ele não pode ser executado em paralelo com operações que acessam a mesma tabela. `VACUUM` cria uma quantidade substancial de tráfego de E/S, podendo piorar a performance para outras sessões ativas.

# Eventos de espera do Aurora PostgreSQL
<a name="AuroraPostgreSQL.Tuning.concepts.summary"></a>

A tabela a seguir lista os eventos de espera do Aurora PostgreSQL que indicam mais comumente problemas de performance e resume as causas e medidas corretivas mais comuns. Os eventos de espera a seguir representam um subconjunto da lista em [Eventos de espera do Amazon Aurora PostgreSQL](AuroraPostgreSQL.Reference.Waitevents.md).


| Eventos de espera | Definição | 
| --- | --- | 
|  [Client:ClientRead](apg-waits.clientread.md)  |  Esse evento ocorre quando o Aurora PostgreSQL está aguardando para receber dados do cliente.  | 
|  [Client:ClientWrite](apg-waits.clientwrite.md)  |  Esse evento ocorre quando o Aurora PostgreSQL está aguardando para gravar dados no cliente.  | 
|  [CPU](apg-waits.cpu.md)  |  Ocorre quando um thread está ativo na CPU ou está aguardando a CPU.  | 
|  [IO:BufFileRead and IO:BufFileWrite](apg-waits.iobuffile.md)  |  Esses eventos ocorrem quando o Aurora PostgreSQL cria arquivos temporários.  | 
|  [IO:DataFileRead](apg-waits.iodatafileread.md)  |  Esse evento ocorre quando uma conexão aguarda em um processo de backend para ler uma página necessária do armazenamento porque essa página não está disponível na memória compartilhada.   | 
|  [IO:XactSync](apg-waits.xactsync.md)  |  Esse evento ocorre quando o banco de dados está aguardando o subsistema de armazenamento do Aurora confirmar uma transação regular ou a reversão de uma transação preparada.   | 
|  [IPC:DamRecordTxAck](apg-waits.ipcdamrecordtxac.md)  |  Esse evento ocorre quando o Aurora PostgreSQL em uma sessão que utiliza fluxos de atividades do banco de dados gera um evento de fluxo de atividades e espera que o evento se torne durável.  | 
|  [Lock:advisory](apg-waits.lockadvisory.md)  |  Esse evento ocorre quando uma aplicação PostgreSQL utiliza um bloqueio para coordenar as atividades em várias sessões.  | 
|  [Lock:extend](apg-waits.lockextend.md) |  Esse evento ocorre quando um processo de backend está aguardando para bloquear uma relação com o objetivo de a estender, enquanto outro processo tem um bloqueio nessa relação para o mesmo objetivo.  | 
|  [Lock:Relation](apg-waits.lockrelation.md)  |  Esse evento ocorre quando uma consulta está aguardando para adquirir um bloqueio em uma tabela ou visualização que está atualmente bloqueada por outra transação.  | 
|  [Lock:transactionid](apg-waits.locktransactionid.md)  | Esse evento ocorre quando uma transação está aguardando um bloqueio em nível de linha. | 
|  [Lock:tuple](apg-waits.locktuple.md)  |  Esse evento ocorre quando um processo de backend está aguardando para adquirir um bloqueio em uma tupla.  | 
|  [LWLock:buffer\$1content (BufferContent)](apg-waits.lockbuffercontent.md)  |  Esse evento ocorre quando uma sessão aguarda para ler ou gravar uma página de dados na memória enquanto outra sessão fica com a página bloqueada para gravação.  | 
|  [LWLock:buffer\$1mapping](apg-waits.lwl-buffer-mapping.md)  |  Esse evento ocorre quando uma sessão está aguardando para associar um bloco de dados a um buffer no grupo de buffer compartilhado.  | 
|  [LWLock:BufferIO (IPC:BufferIO)](apg-waits.lwlockbufferio.md)  |  Esse evento ocorre quando o Aurora PostgreSQL ou o RDS for PostgreSQL aguarda outros processos terminarem suas operações de entrada/saída (E/S) ao tentarem acessar simultaneamente uma página.  | 
|  [LWLock:lock\$1manager](apg-waits.lw-lock-manager.md)  | Esse evento ocorre quando o mecanismo Aurora PostgreSQL mantém a área de memória do bloqueio compartilhado para alocar, verificar e desalocar um bloqueio nos casos em que um bloqueio de caminho rápido não é possível. | 
| [LWLock:MultiXact](apg-waits.lwlockmultixact.md)  | Esse tipo de evento ocorre quando o Aurora PostgreSQL mantém uma sessão aberta para concluir várias transações que envolvem a mesma linha em uma tabela. O evento de espera indica qual aspecto do processamento de várias transações está gerando o evento de espera, ou seja, LWLock:MultiXactOffsetSLRU, LWLock:MultiXactOffsetBuffer, LWLock:MultiXactMemberSLRU ou LWLock:MultiXactMemberBuffer. | 
|  [Tempo limite:PgSleep](apg-waits.timeoutpgsleep.md)  |  Esse evento ocorre quando um processo do servidor chama a função `pg_sleep` e está aguardando o tempo limite de suspensão expirar.   | 

# Client:ClientRead
<a name="apg-waits.clientread"></a>

O evento `Client:ClientRead` ocorre quando o Aurora PostgreSQL está aguardando para receber dados do cliente.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.clientread.context.supported)
+ [Contexto](#apg-waits.clientread.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.clientread.causes)
+ [Ações](#apg-waits.clientread.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.clientread.context.supported"></a>

Essas informações sobre eventos de espera têm suporte para o Aurora PostgreSQL versão 10 e versões superiores.

## Contexto
<a name="apg-waits.clientread.context"></a>

Um cluster de banco de dados Aurora PostgreSQL está aguardando para receber dados do cliente. O cluster de banco de dados Aurora PostgreSQL deve receber os dados do cliente antes de poder enviar mais dados para esse cliente. O tempo de espera do cluster antes de receber dados do cliente é um evento `Client:ClientRead`.

## Possíveis causas do maior número de esperas
<a name="apg-waits.clientread.causes"></a>

Causas comuns do surgimento do evento `Client:ClientRead` nas principais esperas incluem: 

**Maior latência de rede**  
Pode haver maior latência de rede entre o cluster de banco de dados Aurora PostgreSQL e o cliente. A latência de rede mais alta aumenta o tempo necessário para o cluster de banco de dados receber dados do cliente.

**Maior carga no cliente**  
Pode haver pressão da CPU ou saturação da rede no lado do cliente. Um aumento na carga no cliente pode atrasar a transmissão de dados do cliente para o cluster de banco de dados Aurora PostgreSQL.

**Excesso de viagens de ida e volta na rede**  
Um número elevado de viagens de ida e volta na rede entre o cluster de banco de dados Aurora PostgreSQL e o cliente pode atrasar a transmissão de dados do último para o primeiro.

**Operação de cópia extensa**  
Durante uma operação de cópia, os dados são transferidos do sistema de arquivos do cliente para o cluster de banco de dados Aurora PostgreSQL. O envio de uma muitos dados para o cluster de banco de dados pode atrasar a transmissão de dados do cliente para esse cluster.

**Desconexão de um cliente inativo**  
Uma conexão com uma instância de banco de dados do Aurora PostgreSQL está inativa no estado da transação e está aguardando que um cliente envie mais dados ou emita um comando. Esse estado pode levar a um aumento em eventos `Client:ClientRead`.

**PgBouncer utilizado para agrupamento de conexões**  
PgBouncer tem uma configuração de rede de baixo nível chamada `pkt_buf` e que está definida como 4.096 por padrão. Se a workload estiver enviando pacotes de consulta maiores que 4.096 bytes por meio de PgBouncer, convém aumentar a configuração `pkt_buf` para 8.192. Se a nova configuração não diminuir o número de eventos `Client:ClientRead`, convém aumentar a configuração `pkt_buf` para valores maiores, como 16.384 ou 32.768. Se o texto da consulta for grande, a configuração maior pode ser particularmente útil.

## Ações
<a name="apg-waits.clientread.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Colocar os clientes na mesma zona de disponibilidade e sub-rede VPC que o cluster](#apg-waits.clientread.actions.az-vpc-subnet)
+ [Escalar seu cliente](#apg-waits.clientread.actions.scale-client)
+ [Utilizar instâncias da geração atual](#apg-waits.clientread.actions.db-instance-class)
+ [Aumentar a largura de banda da rede](#apg-waits.clientread.actions.increase-network-bandwidth)
+ [Monitorar máximos de performance da rede](#apg-waits.clientread.actions.monitor-network-performance)
+ [Monitorar transações no estado de “inatividade em transação”](#apg-waits.clientread.actions.check-idle-in-transaction)

### Colocar os clientes na mesma zona de disponibilidade e sub-rede VPC que o cluster
<a name="apg-waits.clientread.actions.az-vpc-subnet"></a>

Para reduzir a latência da rede e aumentar a taxa de transferência da rede, coloque clientes na mesma zona de disponibilidade e na mesma sub-rede de nuvem privada virtual (VPC) que o cluster de banco de dados Aurora PostgreSQL. Assegure-se de que os clientes estejam o mais geograficamente próximos do cluster de banco de dados quanto possível.

### Escalar seu cliente
<a name="apg-waits.clientread.actions.scale-client"></a>

Utilizando o Amazon CloudWatch ou outras métricas de host, determine se o cliente está atualmente restrito pela CPU ou pela largura de banda da rede, ou por ambas. Se o cliente estiver restrito, escale-o de acordo.

### Utilizar instâncias da geração atual
<a name="apg-waits.clientread.actions.db-instance-class"></a>

Em alguns casos, talvez você não esteja utilizando uma classe de instância de banco de dados que ofereça suporte a quadros jumbo. Se estiver executando sua aplicação no Amazon EC2, considere utilizar uma instância de geração atual para o cliente. Além disso, configure a MTU (unidade de transmissão máxima) no sistema operacional cliente. Essa técnica pode reduzir o número de idas e voltas pela rede e aumentar a taxa de transferência da rede. Consulte mais informações em [Frames jumbo (9001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) no *Guia do usuário do Amazon EC2*.

Para obter informações sobre classes de instância de banco de dados, consulte [Classes de instâncias de banco de dados do Amazon Aurora](Concepts.DBInstanceClass.md). Para determinar a classe de instância de banco de dados equivalente a um tipo de instância do Amazon EC2, coloque `db.` antes do nome do tipo de instância do Amazon EC2. Por exemplo, a instância `r5.8xlarge` do Amazon EC2 é equivalente à classe de instância de banco de dados `db.r5.8xlarge`.

### Aumentar a largura de banda da rede
<a name="apg-waits.clientread.actions.increase-network-bandwidth"></a>

Utilize as métricas `NetworkReceiveThroughput` e `NetworkTransmitThroughput` do Amazon CloudWatch para monitorar o tráfego de rede de entrada e saída no cluster de banco de dados. Essas métricas podem ajudar você a determinar se a largura de banda da rede é suficiente para a sua workload. 

Se a largura de banda da rede não suficiente, aumente-a. Se o cliente AWS ou sua instância de banco de dados estiver atingindo os limites de largura de banda da rede, a única maneira de aumentar a largura de banda será ampliar o tamanho da instância de banco de dados.

Para ter mais informações sobre métricas do CloudWatch, consulte [Métricas do Amazon CloudWatch para o Amazon Aurora](Aurora.AuroraMonitoring.Metrics.md).

### Monitorar máximos de performance da rede
<a name="apg-waits.clientread.actions.monitor-network-performance"></a>

Se você utiliza clientes do Amazon EC2, o Amazon EC2 fornece máximos para métricas de performance da rede, incluindo largura de banda de rede agregada de entrada e saída. Ele também fornece rastreamento de conexões para garantir que os pacotes sejam retornados conforme esperado e vinculem localmente o acesso para serviços como o Sistema de Nomes de Domínio (DNS). Para monitorar esses máximos, utilize um driver de rede avançado atual e monitore a performance de rede do seu cliente. 

Consulte mais informações em [Monitorar a performance de rede de sua instância do EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/monitoring-network-performance-ena.html) no *Guia do usuário do Amazon EC2*.

### Monitorar transações no estado de “inatividade em transação”
<a name="apg-waits.clientread.actions.check-idle-in-transaction"></a>

Verifique se você tem um número cada vez maior de conexões `idle in transaction`. Para isso, monitore a coluna `state` na tabela `pg_stat_activity`. Talvez seja possível identificar a origem da conexão executando uma consulta semelhante à seguinte.

```
select client_addr, state, count(1) from pg_stat_activity 
where state like 'idle in transaction%' 
group by 1,2 
order by 3 desc
```

# Client:ClientWrite
<a name="apg-waits.clientwrite"></a>

O evento `Client:ClientWrite` ocorre quando o Aurora PostgreSQL está aguardando para gravar dados no cliente.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.clientwrite.context.supported)
+ [Contexto](#apg-waits.clientwrite.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.clientwrite.causes)
+ [Ações](#apg-waits.clientwrite.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.clientwrite.context.supported"></a>

Essas informações sobre eventos de espera têm suporte para o Aurora PostgreSQL versão 10 e versões superiores.

## Contexto
<a name="apg-waits.clientwrite.context"></a>

Um processo de cliente deve ler todos os dados recebidos de um cluster de banco de dados Aurora PostgreSQL para que esse cluster possa enviar mais dados. O tempo de espera do cluster antes de enviar mais dados ao cliente é um evento `Client:ClientWrite`.

A taxa de transferência da rede reduzida entre o cluster de banco de dados Aurora PostgreSQL e o cliente pode causar esse evento. A pressão da CPU e a saturação da rede no cliente também podem causar esse evento. *Pressão da CPU* é quando a CPU está totalmente utilizada e existem tarefas aguardando o tempo da CPU. *Saturação de rede* é quando a rede entre o banco de dados e o cliente está transportando mais dados do que ela pode manipular. 

## Possíveis causas do maior número de esperas
<a name="apg-waits.clientwrite.causes"></a>

Causas comuns do surgimento do evento `Client:ClientWrite` nas principais esperas incluem: 

**Maior latência de rede**  
Pode haver maior latência de rede entre o cluster de banco de dados do Aurora PostgreSQL e o cliente. A latência de rede mais alta aumenta o tempo necessário para o cliente receber os dados.

**Maior carga no cliente**  
Pode haver pressão da CPU ou saturação da rede no lado do cliente. Um aumento na carga do cliente atrasa o recebimento de dados do cluster de banco de dados Aurora PostgreSQL.

**Grande volume de dados enviados ao cliente**  
O cluster de banco de dados Aurora PostgreSQL pode estar enviando uma grande quantidade de dados ao cliente. É possível que um cliente não consiga receber os dados tão rápido quanto o cluster os está enviando. Atividades como cópias de tabelas grandes podem resultar no aumento de eventos `Client:ClientWrite`.

## Ações
<a name="apg-waits.clientwrite.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Colocar os clientes na mesma zona de disponibilidade e sub-rede VPC que o cluster](#apg-waits.clientwrite.actions.az-vpc-subnet)
+ [Utilizar instâncias da geração atual](#apg-waits.clientwrite.actions.db-instance-class)
+ [Reduzir a quantidade de dados enviados ao cliente](#apg-waits.clientwrite.actions.reduce-data)
+ [Escalar seu cliente](#apg-waits.clientwrite.actions.scale-client)

### Colocar os clientes na mesma zona de disponibilidade e sub-rede VPC que o cluster
<a name="apg-waits.clientwrite.actions.az-vpc-subnet"></a>

Para reduzir a latência da rede e aumentar a taxa de transferência da rede, coloque clientes na mesma zona de disponibilidade e na mesma sub-rede de nuvem privada virtual (VPC) que o cluster de banco de dados do Aurora PostgreSQL.

### Utilizar instâncias da geração atual
<a name="apg-waits.clientwrite.actions.db-instance-class"></a>

Em alguns casos, talvez você não esteja utilizando uma classe de instância de banco de dados que ofereça suporte a quadros jumbo. Se estiver executando sua aplicação no Amazon EC2, considere utilizar uma instância de geração atual para o cliente. Além disso, configure a MTU (unidade de transmissão máxima) no sistema operacional cliente. Essa técnica pode reduzir o número de idas e voltas pela rede e aumentar a taxa de transferência da rede. Consulte mais informações em [Frames jumbo (9001 MTU)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/network_mtu.html#jumbo_frame_instances) no *Guia do usuário do Amazon EC2*.

Para obter informações sobre classes de instância de banco de dados, consulte [Classes de instâncias de banco de dados do Amazon Aurora](Concepts.DBInstanceClass.md). Para determinar a classe de instância de banco de dados equivalente a um tipo de instância do Amazon EC2, coloque `db.` antes do nome do tipo de instância do Amazon EC2. Por exemplo, a instância `r5.8xlarge` do Amazon EC2 é equivalente à classe de instância de banco de dados `db.r5.8xlarge`.

### Reduzir a quantidade de dados enviados ao cliente
<a name="apg-waits.clientwrite.actions.reduce-data"></a>

Quando possível, ajuste a aplicação para reduzir a quantidade de dados que o cluster de banco de dados Aurora PostgreSQL envia ao cliente. Fazer esses ajustes alivia a contenção da CPU e da rede no lado do cliente.

### Escalar seu cliente
<a name="apg-waits.clientwrite.actions.scale-client"></a>

Utilizando o Amazon CloudWatch ou outras métricas de host, determine se o cliente está atualmente restrito pela CPU ou pela largura de banda da rede, ou por ambas. Se o cliente estiver restrito, escale-o de acordo.

# CPU
<a name="apg-waits.cpu"></a>

Ocorre quando um thread está ativo na CPU ou está aguardando a CPU.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.cpu.context.supported)
+ [Contexto](#apg-waits.cpu.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.cpu.causes)
+ [Ações](#apg-waits.cpu.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.cpu.context.supported"></a>

As informações sobre eventos de espera são relevantes para o Aurora PostgreSQL versão 9.6 e versões superiores. 

## Contexto
<a name="apg-waits.cpu.context"></a>

A *unidade de processamento central (CPU)* é o componente de um computador que executa instruções. Por exemplo, instruções de CPU realizam operações aritméticas e trocam dados na memória. Se uma consulta aumentar o número de instruções que ela executa por meio do mecanismo de banco de dados, o tempo gasto na execução dessa consulta aumentará. *Programação da CPU* refere-se a alocar tempo de CPU a um processo. A programação é orquestrada pelo kernel do sistema operacional.

**Topics**
+ [Como saber quando essa espera ocorre](#apg-waits.cpu.when-it-occurs)
+ [Métrica DBLoadCPU](#apg-waits.cpu.context.dbloadcpu)
+ [Métricas os.cpuUtilization](#apg-waits.cpu.context.osmetrics)
+ [Provável causa da programação da CPU](#apg-waits.cpu.context.scheduling)

### Como saber quando essa espera ocorre
<a name="apg-waits.cpu.when-it-occurs"></a>

Esse evento de espera `CPU` indica que um processo de backend está ativo na CPU ou aguardando a CPU. É possível determinar que isso está ocorrendo quando uma consulta mostra as seguintes informações:
+ A coluna `pg_stat_activity.state` tem o valor `active`.
+ As colunas `wait_event_type` e `wait_event` em `pg_stat_activity` são ambas `null`.

Para ver os processos de backend que estão utilizando ou aguardando CPU, execute a seguinte consulta.

```
SELECT * 
FROM   pg_stat_activity
WHERE  state = 'active'
AND    wait_event_type IS NULL
AND    wait_event IS NULL;
```

### Métrica DBLoadCPU
<a name="apg-waits.cpu.context.dbloadcpu"></a>

A métrica do Performance Insights para CPU é `DBLoadCPU`. O valor de `DBLoadCPU` pode diferir do valor da métrica `CPUUtilization` do Amazon CloudWatch. A última métrica é coletada do HyperVisor para uma instância de banco de dados.

### Métricas os.cpuUtilization
<a name="apg-waits.cpu.context.osmetrics"></a>

As métricas do Performance Insights para o sistema operacional fornecem informações detalhadas sobre a utilização da CPU. Por exemplo, é possível exibir as seguintes métricas:
+ `os.cpuUtilization.nice.avg`
+ `os.cpuUtilization.total.avg`
+ `os.cpuUtilization.wait.avg`
+ `os.cpuUtilization.idle.avg`

O Performance Insights relata o uso da CPU pelo mecanismo de banco de dados como `os.cpuUtilization.nice.avg`.

### Provável causa da programação da CPU
<a name="apg-waits.cpu.context.scheduling"></a>

Do ponto de vista do sistema operacional, a CPU está ativa quando não executa o thread ocioso. A CPU está ativa enquanto faz um cálculo, mas também está ativa quando aguarda E/S de memória. Esse tipo de E/S domina uma workload típica de banco de dados.

É provável que os processos aguardem para serem programados em uma CPU quando as seguintes condições forem atendidas:
+ A métrica `CPUUtilization` do CloudWatch está próxima dos 100%.
+ A carga média é maior que o número de vCPUs, indicando uma carga pesada. Você pode encontrar a métrica `loadAverageMinute` na seção de métricas do sistema operacional do Performance Insights.

## Possíveis causas do maior número de esperas
<a name="apg-waits.cpu.causes"></a>

Quando o evento de espera de CPU ocorre mais que o normal, possivelmente indicando um problema de performance, as causas típicas incluem:

**Topics**
+ [Possíveis causas de picos súbitos](#apg-waits.cpu.causes.spikes)
+ [Possíveis causas de alta frequência a longo prazo](#apg-waits.cpu.causes.long-term)
+ [Casos excepcionais](#apg-waits.cpu.causes.corner-cases)

### Possíveis causas de picos súbitos
<a name="apg-waits.cpu.causes.spikes"></a>

As causas mais prováveis de picos súbitos são as seguintes:
+ Sua aplicação abriu muitas conexões simultâneas com o banco de dados. Esse cenário é conhecido como “tempestade de conexões”.
+ A workload da sua aplicação foi alterada de qualquer uma das seguintes maneiras:
  + Novas consultas
  + Um aumento no tamanho do conjunto de dados
  + Manutenção ou criação de índices
  + Novas funções
  + Novos operadores
  + Um aumento na execução de consultas paralelas
+ Seus planos de execução de consultas foram modificados. Em certos casos, uma alteração pode causar um aumento nos buffers. Por exemplo, a consulta agora está utilizando uma varredura sequencial quando utilizava anteriormente um índice. Nesse caso, ela precisa de mais CPU para atingir o mesmo objetivo.

### Possíveis causas de alta frequência a longo prazo
<a name="apg-waits.cpu.causes.long-term"></a>

As causas mais prováveis de eventos que se repetem por um longo período são:
+ Muitos processos de backend estão em execução simultaneamente na CPU. Esses processos podem ser operadores paralelos.
+ Consultas estão sendo executadas com performance abaixo do ideal porque precisam de um grande número de buffers.

### Casos excepcionais
<a name="apg-waits.cpu.causes.corner-cases"></a>

Se nenhuma das causas prováveis revelarem ser causas reais, as seguintes situações podem estar ocorrendo:
+ A CPU está alternando processos para dentro e para fora.
+ A alternância de contexto da CPU aumentou.
+ O código do Aurora PostgreSQL não inclui eventos de espera.

## Ações
<a name="apg-waits.cpu.actions"></a>

Se o evento de espera `CPU` domina a atividade do banco de dados, isso não indica necessariamente um problema de performance. Responda a esse evento somente quando a performance diminuir.

**Topics**
+ [Investigar se o banco de dados está causando o aumento da CPU](#apg-waits.cpu.actions.db-CPU)
+ [Determinar se o número de conexões aumentou](#apg-waits.cpu.actions.connections)
+ [Responder a alterações de workload](#apg-waits.cpu.actions.workload)

### Investigar se o banco de dados está causando o aumento da CPU
<a name="apg-waits.cpu.actions.db-CPU"></a>

Examine a métrica `os.cpuUtilization.nice.avg` no Performance Insights. Se esse valor for muito menor que o uso da CPU, processos que não são do banco de dados são os principais colaboradores para a CPU.

### Determinar se o número de conexões aumentou
<a name="apg-waits.cpu.actions.connections"></a>

Examine a métrica `DatabaseConnections` no Amazon CloudWatch. Sua ação depende se o número aumentou ou diminuiu durante o período de maior número de eventos de espera de CPU.

#### As conexões aumentaram
<a name="apg-waits.cpu.actions.connections.increased"></a>

Se o número de conexões aumentou, compare o número de processos de backend que consumem CPU com o número de vCPUs. Os cenários a seguir são possíveis:
+ O número de processos de backend que consomem CPU é menor que o número de vCPUs.

  Nesse caso, o número de conexões não é um problema. Porém, você ainda pode tentar reduzir a utilização da CPU.
+ O número de processos de backend que consomem CPU é maior que o número de vCPUs.

  Nesse caso, considere as opções a seguir:
  + Diminua o número de processos de backend conectados ao banco de dados. Por exemplo, implemente uma solução de agrupamento de conexões, como o RDS Proxy. Para saber mais, consulte [Amazon RDS Proxypara Aurora](rds-proxy.md).
  + Atualize o tamanho da sua instância para obter um número maior de vCPUs.
  + Se aplicável, redirecione algumas workloads somente leitura para nós de leitor.

#### As conexões não aumentaram
<a name="apg-waits.cpu.actions.connections.decreased"></a>

Examine as métricas `blks_hit` no Performance Insights. Procure uma correlação entre um aumento em `blks_hit` e o uso da CPU. Os cenários a seguir são possíveis:
+ O uso da CPU e `blks_hit` estão correlacionados.

  Nesse caso, encontre as principais instruções SQL vinculadas ao uso da CPU e procure modificações no plano. Você pode usar uma das seguintes técnicas:
  + Explicar os planos manualmente e compare-os com o plano de execução esperado.
  + Procurar um aumento nos acertos de bloco por segundo e nos acertos de blocos locais por segundo. Na seção **Top SQL** (SQL principal) do painel do Performance Insights, escolha **Preferences** (Preferências).
+ O uso da CPU e `blks_hit` não estão correlacionados.

  Nesse caso, determine se alguma das seguintes situações ocorre:
  + A aplicação está se conectando e se desconectando rapidamente ao/do banco de dados. 

    Diagnostique esse comportamento ativando `log_connections` e `log_disconnections` e analisando os logs do PostgreSQL. Considere utilizar o analisador de logs `pgbadger`. Para obter mais informações, consulte [https://github.com/darold/pgbadger](https://github.com/darold/pgbadger).
  + O sistema operacional está sobrecarregado.

    Nesse caso, o Performance Insights mostra que processos de backend estão consumindo CPU por mais tempo que o normal. Procure evidências nas métricas `os.cpuUtilization` do Performance Insights ou na métrica `CPUUtilization` do CloudWatch. Se o sistema operacional estiver sobrecarregado, consulte as métricas de monitoramento avançado para aprofundar o diagnóstico. Especificamente, observe a lista de processos e a porcentagem de CPU consumida por cada um.
  + As principais instruções SQL estão consumindo muita CPU.

    Examine instruções que estão vinculadas ao uso da CPU para verificar se elas podem utilizar menos CPU. Execute um comando `EXPLAIN` e concentre-se nos nós do plano que têm o maior impacto. Considere utilizar um visualizador de plano de execução do PostgreSQL. Para experimentar essa ferramenta, consulte [http://explain.dalibo.com/](http://explain.dalibo.com/).

### Responder a alterações de workload
<a name="apg-waits.cpu.actions.workload"></a>

Se a sua workload mudou, procure os seguintes tipos de alterações:

Novas consultas  
Verifique se novas consultas são esperadas. Em caso positivo, verifique se os planos de execução dessas consultas e o número de execuções por segundo são os esperados.

Um aumento no tamanho do conjunto de dados  
Determine se o particionamento, caso ainda não esteja implementado, pode ajudar. Essa estratégia é capaz de reduzir o número de páginas que uma consulta precisa recuperar.

Manutenção ou criação de índices  
Verifique se a programação de manutenção é a esperada. Uma prática recomendada é agendar atividades de manutenção fora das atividades de pico.

Novas funções  
Confirme se essas funções são executadas conforme o esperado durante o teste. Especificamente, confira se o número de execuções por segundo é o esperado.

Novos operadores  
Verifique se eles funcionam conforme o esperado durante os testes.

Um aumento na execução de consultas paralelas  
Determine se alguma das situações a seguir ocorreu:  
+ As relações ou os índices envolvidos cresceram de repente a ponto de diferirem significativamente de `min_parallel_table_scan_size` ou `min_parallel_index_scan_size`.
+ Alterações recentes foram feitas em `parallel_setup_cost` ou `parallel_tuple_cost`.
+ Alterações recentes foram feitas em `max_parallel_workers` ou `max_parallel_workers_per_gather`.

# IO:BufFileRead and IO:BufFileWrite
<a name="apg-waits.iobuffile"></a>

Os eventos `IO:BufFileRead` e `IO:BufFileWrite` ocorrem quando o Aurora PostgreSQL cria arquivos temporários. Quando as operações requerem mais memória do que os parâmetros de memória de trabalho definidos atualmente, elas gravam dados temporários no armazenamento persistente. Essa operação é chamada às vezes de *derramamento no disco*. Para obter mais informações sobre os arquivos temporários e o uso, consulte [Gerenciar arquivos temporários com o PostgreSQL](PostgreSQL.ManagingTempFiles.md).

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.iobuffile.context.supported)
+ [Contexto](#apg-waits.iobuffile.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.iobuffile.causes)
+ [Ações](#apg-waits.iobuffile.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.iobuffile.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.iobuffile.context"></a>

`IO:BufFileRead` e `IO:BufFileWrite` estão relacionados à área de memória de trabalho e a área de memória de trabalho de manutenção. Para saber mais sobre essas áreas de memória local, consulte [Área de memória de trabalho](AuroraPostgreSQL.Tuning.concepts.md#AuroraPostgreSQL.Tuning.concepts.local.work_mem) e [Área de memória de trabalho para manutenção](AuroraPostgreSQL.Tuning.concepts.md#AuroraPostgreSQL.Tuning.concepts.local.maintenance_work_mem).

O valor padrão para `work_mem` é 4 MB. Se uma sessão executar operações em paralelo, cada operador que lidar com o paralelismo usará 4 MB de memória. Por essa razão, defina `work_mem` com cautela. Se você aumentar demais esse valor, um banco de dados que execute muitas sessões poderá consumir muita memória. Se você definir um valor muito baixo, o Aurora PostgreSQL criará arquivos temporários no armazenamento local. A E/S de disco desses arquivos temporários pode reduzir a performance.

Se você observar a seguinte sequência de eventos, é possível que seu banco de dados esteja gerando arquivos temporários:

1. Redução súbita e acentuada na disponibilidade

1. Recuperação rápida para o espaço livre

Você também pode observar um padrão de “motosserra”. Esse padrão pode indicar que o banco de dados está criando arquivos pequenos constantemente.

## Possíveis causas do maior número de esperas
<a name="apg-waits.iobuffile.causes"></a>

Em geral, esses eventos de espera são causados por operações que consomem mais memória do que é alocado pelos parâmetros `work_mem` ou `maintenance_work_mem`. Para compensar isso, as operações gravam em arquivos temporários. Causas comuns dos eventos `IO:BufFileRead` e `IO:BufFileWrite` incluem:

**Consultas que necessitam de mais memória do que existe na área de memória de trabalho**  
Consultas com as seguintes características utilizam a área de memória de trabalho:  
+ Junções de hash
+ `ORDER BY`Cláusula 
+ `GROUP BY`Cláusula 
+ `DISTINCT`
+ Funções de janela
+ `CREATE TABLE AS SELECT`
+ Atualização de visualizações materializadas

**Instruções que necessitam de mais memória do que existe na área de memória do trabalho de manutenção**  
As seguintes instruções usam a área de memória do trabalho de manutenção:  
+ `CREATE INDEX`
+ `CLUSTER`

## Ações
<a name="apg-waits.iobuffile.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Identificar o problema](#apg-waits.iobuffile.actions.problem)
+ [Examinar suas consultas de junção](#apg-waits.iobuffile.actions.joins)
+ [Examinar suas consultas ORDER BY e GROUP BY](#apg-waits.iobuffile.actions.order-by)
+ [Evite utilizar a operação DISTINCT](#apg-waits.iobuffile.actions.distinct)
+ [Considere utilizar funções de janela em vez de funções GROUP BY](#apg-waits.iobuffile.actions.window)
+ [Investigar visualizações materializadas e instruções CTAS](#apg-waits.iobuffile.actions.mv-refresh)
+ [Usar pg\$1repack ao criar índices](#apg-waits.iobuffile.actions.pg_repack)
+ [Aumentar maintenance\$1work\$1mem ao agrupar tabelas](#apg-waits.iobuffile.actions.cluster)
+ [Ajustar a memória para evitar IO:BufFileRead e IO:BufFileWrite](#apg-waits.iobuffile.actions.tuning-memory)

### Identificar o problema
<a name="apg-waits.iobuffile.actions.problem"></a>

Você pode visualizar o uso de arquivos temporários diretamente no Insights de Performance. Para obter mais informações, consulte [Visualizar o uso de arquivos temporários com o Insights de Performance](PostgreSQL.ManagingTempFiles.Example.md). Quando o Insights de Performance está desabilitado, é possível observar um aumento nas operações `IO:BufFileRead` e `IO:BufFileWrite`. Para solucionar problemas, faça o seguinte:

1. Examine a métrica `FreeLocalStorage` no Amazon CloudWatch.

1. Observe se há um padrão de motosserra, ou seja, uma série de picos irregulares.

Um padrão de motosserra indica um rápido consumo e liberação de armazenamento, muitas vezes associados a arquivos temporários. Se você perceber esse padrão, ative o Performance Insights. Ao utilizar o Performance Insights, é possível identificar quando os eventos de espera ocorrem e quais consultas estão associadas a eles. A solução depende da consulta específica que está causando os eventos.

Ou defina o parâmetro `log_temp_files`. Esse parâmetro registra todas as consultas que estão gerando mais do que o limite de KB de arquivos temporários. Se o valor for `0`, o Aurora PostgreSQL registrará todos os arquivos temporários. Se o valor for `1024`, o Aurora PostgreSQL registrará todas as consultas que geram arquivos temporários maiores que 1 MB. Para obter mais informações sobre `log_temp_files`, consulte o tópico sobre [Relatórios de erros e registro em log](https://www.postgresql.org/docs/10/runtime-config-logging.html), na documentação do PostgreSQL.

### Examinar suas consultas de junção
<a name="apg-waits.iobuffile.actions.joins"></a>

Sua aplicação provavelmente utiliza junções. Por exemplo, a consulta a seguir une quatro tabelas.

```
SELECT * 
       FROM order 
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = order.customer_id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

Uma causa possível dos picos no uso temporário de arquivos é um problema na própria consulta. Por exemplo, uma cláusula quebrada talvez não esteja filtrando as junções corretamente. Considere a segunda junção interna no exemplo a seguir.

```
SELECT * 
       FROM order
 INNER JOIN order_item 
       ON (order.id = order_item.order_id)
 INNER JOIN customer 
       ON (customer.id = customer.id)
 INNER JOIN customer_address 
       ON (customer_address.customer_id = customer.id AND 
           order.customer_address_id = customer_address.id)
 WHERE customer.id = 1234567890;
```

A consulta anterior junta `customer.id` com `customer.id` por engano, gerando um produto cartesiano entre cada cliente e cada pedido. Esse tipo de junção acidental gera arquivos temporários grandes. Dependendo do tamanho das tabelas, uma consulta cartesiana pode até mesmo lotar o armazenamento. Sua aplicação pode ter junções cartesianas quando as seguintes condições são atendidas:
+ Você percebe reduções grandes e acentuadas na disponibilidade do armazenamento, seguidas de uma rápida recuperação.
+ Nenhum índice está sendo criado.
+ Nenhuma instrução `CREATE TABLE FROM SELECT` está sendo emitida.
+ Nenhuma visualização materializada está sendo atualizada.

Para verificar se as tabelas estão sendo unidas utilizando as chaves apropriadas, inspecione suas diretivas de mapeamento de consultas e objetos relacionais. Lembre-se de que certas consultas da sua aplicação não são chamadas o tempo todo e que algumas consultas são geradas dinamicamente.

### Examinar suas consultas ORDER BY e GROUP BY
<a name="apg-waits.iobuffile.actions.order-by"></a>

Em alguns casos, uma cláusula `ORDER BY` pode resultar no excesso de arquivos temporários. Considere as seguintes diretrizes:
+ Inclua somente colunas em uma cláusula `ORDER BY` quando elas precisarem ser ordenadas. Essa orientação é especialmente importante para consultas que retornam milhares de linhas e especificam muitas colunas na cláusula `ORDER BY`.
+ Considere criar índices para acelerar cláusulas `ORDER BY` quando elas correspondem a colunas que tenham a mesma ordem crescente ou decrescente. Índices parciais são preferíveis, pois são menores. Índices menores são lidos e percorridos com mais rapidez.
+ Se você criar índices para colunas que podem aceitar valores nulos, considere se deseja que esses valores nulos sejam armazenados no final ou no início dos índices.

  Se possível, reduza o número de linhas que precisam ser ordenadas, filtrando o conjunto de resultados. Se você usar instruções de cláusula `WITH` ou subconsultas, lembre-se de que uma consulta interna gera um conjunto de resultados e o transmite à consulta externa. Quanto mais linhas uma consulta puder remover, menos ordenação ela precisará fazer.
+ Se não precisar obter o conjunto completo de resultados, utilize a cláusula `LIMIT`. Por exemplo, se quiser apenas as cinco principais linhas, uma consulta utilizando a cláusula `LIMIT` não continuará gerando resultados. Dessa forma, essa consulta requer menos memória e arquivos temporários.

Uma consulta que usa uma cláusula `GROUP BY` também pode exigir arquivos temporários. Consultas `GROUP BY` resumem valores utilizando funções como as seguintes:
+ `COUNT`
+ `AVG`
+ `MIN`
+ `MAX`
+ `SUM`
+ `STDDEV`

Para ajustar consultas `GROUP BY`, siga as recomendações para consultas `ORDER BY`.

### Evite utilizar a operação DISTINCT
<a name="apg-waits.iobuffile.actions.distinct"></a>

Se possível, evite utilizar a operação `DISTINCT` para remover linhas duplicadas. Quanto mais linhas desnecessárias e duplicadas sua consulta retornar, mais cara a operação `DISTINCT` se tornará. Se possível, adicione filtros à cláusula `WHERE` mesmo que você utilize os mesmos filtros para tabelas diferentes. Filtrar a consulta e a junção corretamente melhora a performance e reduz o uso de recursos. Isso também evita relatórios e resultados incorretos.

Se precisar usar `DISTINCT` para várias linhas de uma mesma tabela, considere criar um índice composto. O agrupamento de várias colunas em um índice pode melhorar o tempo para avaliar linhas distintas. Além disso, se utilizar o Amazon Aurora PostgreSQL versão 10 ou superior, você poderá correlacionar estatísticas entre várias colunas utilizando o comando `CREATE STATISTICS`.

### Considere utilizar funções de janela em vez de funções GROUP BY
<a name="apg-waits.iobuffile.actions.window"></a>

Usando `GROUP BY`, você altera o conjunto de resultados e, em seguida, recupera o resultado agregado. Usando funções de janela, você agrega dados sem modificar o conjunto de resultados. Uma função de janela usa a cláusula `OVER` para fazer cálculos entre os conjuntos definidos pela consulta, correlacionando uma linha com outra. Você pode utilizar todas as funções `GROUP BY` em funções de janela, mas também utilizar funções como as seguintes:
+ `RANK`
+ `ARRAY_AGG`
+ `ROW_NUMBER`
+ `LAG`
+ `LEAD`

Para minimizar o número de arquivos temporários gerados por uma função de janela, remova duplicatas do mesmo conjunto de resultados quando precisar de duas agregações distintas. Considere a seguinte consulta.

```
SELECT sum(salary) OVER (PARTITION BY dept ORDER BY salary DESC) as sum_salary
     , avg(salary) OVER (PARTITION BY dept ORDER BY salary ASC) as avg_salary
  FROM empsalary;
```

Você pode reescrever essa consulta com a cláusula `WINDOW` da seguinte maneira.

```
SELECT sum(salary) OVER w as sum_salary
         , avg(salary) OVER w as_avg_salary
    FROM empsalary
  WINDOW w AS (PARTITION BY dept ORDER BY salary DESC);
```

Por padrão, o planejador de execução do Aurora PostgreSQL consolida nós semelhantes para que ele não duplique operações. No entanto, utilizando uma declaração explícita para o bloco de janelas, é possível manter a consulta com mais facilidade. Também é possível melhorar a performance ao evitar a duplicação.

### Investigar visualizações materializadas e instruções CTAS
<a name="apg-waits.iobuffile.actions.mv-refresh"></a>

Quando uma visualização materializada é atualizada, ela executa uma consulta. Essa consulta pode conter uma operação como `GROUP BY`, `ORDER BY` ou `DISTINCT`. Durante uma atualização, é possível observar um grande número de arquivos temporários e os eventos de espera `IO:BufFileWrite` e `IO:BufFileRead`. Da mesma forma, quando você cria uma tabela com base em uma instrução `SELECT`, a instrução `CREATE TABLE` executa uma consulta. Para reduzir os arquivos temporários necessários, otimize a consulta.

### Usar pg\$1repack ao criar índices
<a name="apg-waits.iobuffile.actions.pg_repack"></a>

Quando você cria um índice, o mecanismo ordena o conjunto de resultados. À medida que o tamanho das tabelas aumenta e à medida que os valores na coluna indexada se tornam mais diversificados, os arquivos temporários exigem mais espaço. Na maioria dos casos, não é possível impedir a criação de arquivos temporários para tabelas grandes sem modificar a área de memória do trabalho de manutenção. Para obter mais informações, consulte [Área de memória de trabalho para manutenção](AuroraPostgreSQL.Tuning.concepts.md#AuroraPostgreSQL.Tuning.concepts.local.maintenance_work_mem). 

Uma possível solução alternativa ao recriar um índice grande é utilizar a ferramenta pg\$1repack. Para obter mais informações, consulte o tópico sobre como [Reorganizar tabelas em bancos de dados PostgreSQL com bloqueios mínimos](https://reorg.github.io/pg_repack/), na documentação de pg\$1repack.

### Aumentar maintenance\$1work\$1mem ao agrupar tabelas
<a name="apg-waits.iobuffile.actions.cluster"></a>

O comando `CLUSTER` agrupa a tabela especificada por *table\$1name* com base em um índice existente especificado por *index\$1name*. O Aurora PostgreSQL recria fisicamente essa tabela para corresponder à ordem de um determinado índice.

Quando o armazenamento magnético era predominante, o agrupamento era comum, pois a taxa de transferência de armazenamento era limitada. Agora que o armazenamento baseado em SSD é comum, o agrupamento tornou-se menos popular. No entanto, se você agrupar tabelas, ainda poderá aumentar a performance ligeiramente, dependendo do tamanho da tabela, do índice, da consulta e assim por diante. 

Se você executar o comando `CLUSTER` e observar os eventos de espera `IO:BufFileWrite` e `IO:BufFileRead`, ajuste `maintenance_work_mem`. Aumente o tamanho da memória para uma quantidade relativamente grande. Um valor alto significa que o mecanismo pode utilizar mais memória para a operação de agrupamento.

### Ajustar a memória para evitar IO:BufFileRead e IO:BufFileWrite
<a name="apg-waits.iobuffile.actions.tuning-memory"></a>

Em uma determinada situação, você precisa ajustar a memória. A meta é equilibrar os seguintes requisitos:
+ O valor de `work_mem` (consulte [Área de memória de trabalho](AuroraPostgreSQL.Tuning.concepts.md#AuroraPostgreSQL.Tuning.concepts.local.work_mem))
+ A memória restante após descontar o valor de `shared_buffers` (consulte [Grupo de buffer](AuroraMySQL.Managing.Tuning.concepts.md#AuroraMySQL.Managing.Tuning.concepts.memory.buffer-pool))
+ As conexões máximas abertas e em uso, o que é limitado por `max_connections`

#### Aumentar o tamanho da área de memória de trabalho
<a name="apg-waits.iobuffile.actions.tuning-memory.work-mem"></a>

Em algumas situações, a única opção é aumentar a memória utilizada pela sessão. Se as consultas estiverem gravadas corretamente e utilizando as chaves corretas para junções, considere aumentar o valor de `work_mem`. Para obter mais informações, consulte [Área de memória de trabalho](AuroraPostgreSQL.Tuning.concepts.md#AuroraPostgreSQL.Tuning.concepts.local.work_mem).

Para descobrir quantos arquivos temporários são gerados por uma consulta, defina `log_temp_files` como `0`. Se você aumentar o valor de `work_mem` para o valor máximo identificado nos logs, impedirá que a consulta gere arquivos temporários. No entanto, `work_mem` define o máximo por nó de plano para cada conexão ou operador paralelo. Se o banco de dados tiver 5.000 conexões e cada uma utilizar 256 MiB de memória, o mecanismo precisará de 1,2 TiB de RAM. Portanto, sua instância pode ficar sem memória.

#### Reservar memória suficiente para o grupo de buffer compartilhado
<a name="apg-waits.iobuffile.actions.tuning-memory.shared-pool"></a>

Seu banco de dados usa áreas de memória, como o grupo de buffer compartilhado, e não apenas a área de memória de trabalho. Considere os requisitos dessas áreas de memória adicionais antes de aumentar `work_mem`. Para obter mais informações sobre o grupo de buffer, consulte [Grupo de buffer](AuroraMySQL.Managing.Tuning.concepts.md#AuroraMySQL.Managing.Tuning.concepts.memory.buffer-pool).

Por exemplo, suponha que a sua classe de instância do Aurora PostgreSQL seja db.r5.2xlarge. Essa classe tem 64 GiB de memória. Por padrão, 75% da memória são reservados para o grupo de buffer compartilhado. Depois de subtrair a quantidade alocada à área de memória compartilhada, permanecem 16.384 MB. Não aloque a memória restante exclusivamente à área de memória de trabalho, pois o sistema operacional e o mecanismo também precisam de memória.

A memória que é possível alocar a `work_mem` depende da classe da instância. Se você utilizar uma classe de instância maior, mais memória estará disponível. No entanto, no exemplo anterior, não é possível utilizar mais de 16 GiB. Caso contrário, sua instância estará indisponível quando ficar sem memória. Para recuperar a instância e retirá-la do estado indisponível, os serviços de automação do Aurora PostgreSQL são reiniciados automaticamente.

#### Gerenciar o número de conexões
<a name="apg-waits.iobuffile.actions.tuning-memory.connections"></a>

Imagine que a sua instância de banco de dados tenha 5.000 conexões simultâneas. Cada conexão usa pelo menos 4 MiB de `work_mem`. O alto consumo de memória das conexões provavelmente diminuirá a performance. Em resposta, existem as seguintes opções:
+ Faça upgrade para uma classe de instância maior.
+ Diminua o número de conexões de banco de dados simultâneas utilizando um proxy de conexão ou pooler.

Para proxies, considere o Amazon RDS Proxy, o pgBouncer ou um pooler de conexão baseado na sua aplicação. Essa solução alivia a carga da CPU. Ela também reduz o risco quando todas as conexões exigem a área de memória de trabalho. Quando há menos conexões de banco de dados, é possível aumentar o valor de `work_mem`. Dessa forma, você reduz a ocorrência dos eventos de espera `IO:BufFileRead` e `IO:BufFileWrite`. Além disso, as consultas que aguardam a área de memória de trabalho são aceleradas significativamente.

# IO:DataFileRead
<a name="apg-waits.iodatafileread"></a>

O evento `IO:DataFileRead` ocorre quando uma conexão aguarda em um processo de backend para ler uma página necessária do armazenamento porque essa página não está disponível na memória compartilhada.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.iodatafileread.context.supported)
+ [Contexto](#apg-waits.iodatafileread.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.iodatafileread.causes)
+ [Ações](#apg-waits.iodatafileread.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.iodatafileread.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.iodatafileread.context"></a>

Todas as consultas e operações de manipulação de dados (DML) acessam páginas no grupo de buffer. Instruções que podem induzir leituras incluem `SELECT`, `UPDATE` e `DELETE`. Por exemplo, um `UPDATE` pode ler páginas de tabelas ou índices. Se a página que está sendo solicitada ou atualizada não estiver no grupo de buffer compartilhado, essa leitura poderá gerar o evento `IO:DataFileRead`.

Como o grupo de buffer compartilhado é finito, ele pode ficar lotado. Nesse caso, solicitações de páginas que não estão na memória forçam o banco de dados a ler blocos do disco. Se o evento `IO:DataFileRead` ocorre com frequência, o grupo de buffer compartilhado pode ser pequeno demais para acomodar sua workload. Esse problema é grave para consultas `SELECT` que fazem a leitura de um grande número de linhas que não cabem no grupo de buffer. Para obter mais informações sobre o grupo de buffer, consulte [Grupo de buffer](AuroraMySQL.Managing.Tuning.concepts.md#AuroraMySQL.Managing.Tuning.concepts.memory.buffer-pool).

## Possíveis causas do maior número de esperas
<a name="apg-waits.iodatafileread.causes"></a>

As causas comuns do evento `IO:DataFileRead` incluem:

**Picos de conexão**  
Você pode encontrar várias conexões gerando o mesmo número de eventos de espera IO:DatafileRead. Nesse caso, pode ocorrer um pico (aumento súbito e grande) em eventos `IO:DataFileRead`. 

**Instruções SELECT e DML realizando varreduras sequenciais**  
Sua aplicação pode estar executando uma nova operação. Ou uma operação existente pode mudar por conta de um novo plano de execução. Nesses casos, procure tabelas (particularmente grandes) que tenham um valor de `seq_scan` maior. Encontre-as consultando `pg_stat_user_tables`. Para rastrear consultas que estão gerando mais operações de leitura, utilize a extensão `pg_stat_statements`.

**CTAS e CREATE INDEX para conjuntos de dados grandes**  
Um *CTAS* é uma instrução `CREATE TABLE AS SELECT`. Se você executar um CTAS utilizando um conjunto de dados grande como fonte ou criar um índice em uma tabela grande, o evento `IO:DataFileRead` poderá ocorrer. Quando você cria um índice, talvez o banco de dados precise ler o objeto inteiro utilizando uma varredura sequencial. Um CTAS gera leituras de `IO:DataFile` quando as páginas não estão na memória.

**Vários operadores de vacuum em execução ao mesmo tempo**  
Operadores de vacuum podem ser acionados manual ou automaticamente. Convém adotar uma estratégia de vacuum agressiva. No entanto, quando uma tabela possui muitas linhas atualizadas ou excluídas, as esperas de `IO:DataFileRead` aumentam. Depois que o espaço é recuperado, o tempo de vacuum gasto em `IO:DataFileRead` diminui.

**Ingestão de grandes quantidades de dados**  
Quando a aplicação ingere grandes quantidades de dados, operações `ANALYZE` podem ocorrer com mais frequência. O processo `ANALYZE` pode ser acionado por um launcher de autovacuum ou chamado manualmente.  
A operação `ANALYZE` lê um subconjunto da tabela. O número de páginas que devem ser varridas é calculado multiplicando-se 30 pelo valor de `default_statistics_target`. Para obter mais informações, consulte a [Documentação do PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET). O parâmetro `default_statistics_target` aceita valores entre 1 e 10.000, em que o padrão é 100.

**Inanição de recursos**  
Se a largura de banda ou a CPU da rede da instância forem consumidas, o evento `IO:DataFileRead` poderá ocorrer com mais frequência.

## Ações
<a name="apg-waits.iodatafileread.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Verificar filtros de predicados em busca de consultas que geram esperas](#apg-waits.iodatafileread.actions.filters)
+ [Minimizar o efeito de operações de manutenção](#apg-waits.iodatafileread.actions.maintenance)
+ [Responder a um alto número de conexões](#apg-waits.iodatafileread.actions.connections)

### Verificar filtros de predicados em busca de consultas que geram esperas
<a name="apg-waits.iodatafileread.actions.filters"></a>

Suponha que você identifique consultas específicas que estão gerando eventos de espera `IO:DataFileRead`. É possível identificá-los utilizando as seguintes técnicas:
+ Insights de Performance
+ Visualizações de catálogo, como a fornecida pela extensão `pg_stat_statements`
+ A visualização de catálogo `pg_stat_all_tables`, se ela mostrar periodicamente um número mais alto de leituras físicas
+ A visualização `pg_statio_all_tables`, se ela mostrar que os contadores de `_read` estão aumentando

Convém determinar quais filtros são utilizados no predicado (cláusula `WHERE`) dessas consultas. Siga estas diretrizes:
+ Execute o comando `EXPLAIN`. Na saída, identifique quais tipos de varreduras são utilizados. Uma varredura sequencial não indica necessariamente um problema. Consultas que utilizam varreduras sequenciais naturalmente produzem mais eventos `IO:DataFileRead` quando comparados a consultas que utilizam filtros.

  Descubra se a coluna listada na cláusula `WHERE` é indexada. Caso contrário, considere criar um índice para essa coluna. Essa abordagem evita varreduras sequenciais e reduz eventos `IO:DataFileRead`. Se uma consulta tiver filtros restritivos e ainda produzir varreduras sequenciais, avalie se os índices adequados estão sendo utilizados.
+ Descubra se a consulta está acessando uma tabela muito grande. Em alguns casos, o particionamento de uma tabela pode melhorar a performance, permitindo que a consulta leia apenas as partições necessárias.
+ Observe a cardinalidade (número total de linhas) das suas operações de junção. Observe o quão restritivos são os valores que você está transmitindo nos filtros para a sua cláusula `WHERE`. Se possível, ajuste sua consulta para reduzir o número de linhas que são transmitidas em cada etapa do plano.

### Minimizar o efeito de operações de manutenção
<a name="apg-waits.iodatafileread.actions.maintenance"></a>

Operações de manutenção, como `VACUUM` e `ANALYZE`, são importantes. Recomendamos que você não as desative ao encontrar eventos de espera `IO:DataFileRead` relacionados a essas operações de manutenção. As abordagens a seguir podem minimizar o efeito dessas operações:
+ Execute operações de manutenção manualmente fora do horário de pico. Essa técnica impede que o banco de dados atinja o limite para operações automáticas.
+ Considere particionar tabelas muito grandes. Essa técnica reduz a sobrecarga das operações de manutenção. O banco de dados somente acessa as partições que exigem manutenção.
+ Ao ingerir grandes quantidades de dados, considere desativar o recurso de análise automática.

O recurso de autovacuum é acionado automaticamente para uma tabela quando a seguinte fórmula é verdadeira.

```
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
```

A visualização `pg_stat_user_tables` e o catálogo `pg_class` têm várias linhas. Uma linha pode corresponder a uma linha na sua tabela. Essa fórmula pressupõe que os `reltuples` sejam para uma tabela específica. Os parâmetros `autovacuum_vacuum_scale_factor` (0,20 por padrão) e `autovacuum_vacuum_threshold` (50 tuplas por padrão) geralmente são definidos globalmente para toda a instância. Porém, é possível definir valores diferentes para uma tabela específica.

**Topics**
+ [Localizar tabelas que consomem espaço desnecessariamente](#apg-waits.iodatafileread.actions.maintenance.tables)
+ [Localizar índices que consomem espaço desnecessário](#apg-waits.iodatafileread.actions.maintenance.indexes)
+ [Localizar tabelas elegíveis qualificadas para receber autovacuum](#apg-waits.iodatafileread.actions.maintenance.autovacuumed)

#### Localizar tabelas que consomem espaço desnecessariamente
<a name="apg-waits.iodatafileread.actions.maintenance.tables"></a>

Para localizar tabelas que consomem mais espaço do que o necessário, execute a consulta a seguir. Quando essa consulta é executada por uma função de usuário do banco de dados que não tenha a função `rds_superuser`, ela retorna informações somente sobre as tabelas que a função de usuário tem permissão para ler. Essa consulta é compatível com o PostgreSQL versão 12 e versões posteriores. 

```
WITH report AS (
   SELECT   schemaname
           ,tblname
           ,n_dead_tup
           ,n_live_tup
           ,block_size*tblpages AS real_size
           ,(tblpages-est_tblpages)*block_size AS extra_size
           ,CASE WHEN tblpages - est_tblpages > 0
              THEN 100 * (tblpages - est_tblpages)/tblpages::float
              ELSE 0
            END AS extra_ratio, fillfactor, (tblpages-est_tblpages_ff)*block_size AS bloat_size
           ,CASE WHEN tblpages - est_tblpages_ff > 0
              THEN 100 * (tblpages - est_tblpages_ff)/tblpages::float
              ELSE 0
            END AS bloat_ratio
           ,is_na
    FROM (
           SELECT  ceil( reltuples / ( (block_size-page_hdr)/tpl_size ) ) + ceil( toasttuples / 4 ) AS est_tblpages
                  ,ceil( reltuples / ( (block_size-page_hdr)*fillfactor/(tpl_size*100) ) ) + ceil( toasttuples / 4 ) AS est_tblpages_ff
                  ,tblpages
                  ,fillfactor
                  ,block_size
                  ,tblid
                  ,schemaname
                  ,tblname
                  ,n_dead_tup
                  ,n_live_tup
                  ,heappages
                  ,toastpages
                  ,is_na
             FROM (
                    SELECT ( 4 + tpl_hdr_size + tpl_data_size + (2*ma)
                               - CASE WHEN tpl_hdr_size%ma = 0 THEN ma ELSE tpl_hdr_size%ma END
                               - CASE WHEN ceil(tpl_data_size)::int%ma = 0 THEN ma ELSE ceil(tpl_data_size)::int%ma END
                           ) AS tpl_size
                           ,block_size - page_hdr AS size_per_block
                           ,(heappages + toastpages) AS tblpages
                           ,heappages
                           ,toastpages
                           ,reltuples
                           ,toasttuples
                           ,block_size
                           ,page_hdr
                           ,tblid
                           ,schemaname
                           ,tblname
                           ,fillfactor
                           ,is_na
                           ,n_dead_tup
                           ,n_live_tup
                          FROM (
                                SELECT  tbl.oid                       AS tblid
                                       ,ns.nspname                    AS schemaname
                                       ,tbl.relname                   AS tblname
                                       ,tbl.reltuples                 AS reltuples
                                       ,tbl.relpages                  AS heappages
                                       ,coalesce(toast.relpages, 0)   AS toastpages
                                       ,coalesce(toast.reltuples, 0)  AS toasttuples
                                       ,psat.n_dead_tup               AS n_dead_tup
                                       ,psat.n_live_tup               AS n_live_tup
                                       ,24                            AS page_hdr
                                       ,current_setting('block_size')::numeric AS block_size
                                       ,coalesce(substring( array_to_string(tbl.reloptions, ' ') FROM 'fillfactor=([0-9]+)')::smallint, 100) AS fillfactor
                                       ,CASE WHEN version()~'mingw32' OR version()~'64-bit|x86_64|ppc64|ia64|amd64' THEN 8 ELSE 4 END        AS ma
                                       ,23 + CASE WHEN MAX(coalesce(null_frac,0)) > 0 THEN ( 7 + count(*) ) / 8 ELSE 0::int END              AS tpl_hdr_size
                                       ,sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024) )                                    AS tpl_data_size
                                       ,bool_or(att.atttypid = 'pg_catalog.name'::regtype) OR count(att.attname) <> count(s.attname)         AS is_na
                                  FROM  pg_attribute       AS att
                                  JOIN  pg_class           AS tbl    ON (att.attrelid = tbl.oid)
                                  JOIN  pg_stat_all_tables AS psat   ON (tbl.oid = psat.relid)
                                  JOIN  pg_namespace       AS ns     ON (ns.oid = tbl.relnamespace)
                             LEFT JOIN  pg_stats           AS s      ON (s.schemaname=ns.nspname AND s.tablename = tbl.relname AND s.inherited=false AND s.attname=att.attname)
                             LEFT JOIN  pg_class           AS toast  ON (tbl.reltoastrelid = toast.oid)
                                 WHERE  att.attnum > 0
                                   AND  NOT att.attisdropped
                                   AND  tbl.relkind = 'r'
                              GROUP BY  tbl.oid, ns.nspname, tbl.relname, tbl.reltuples, tbl.relpages, toastpages, toasttuples, fillfactor, block_size, ma, n_dead_tup, n_live_tup
                              ORDER BY  schemaname, tblname
                           ) AS s
                 ) AS s2
       ) AS s3
 ORDER BY bloat_size DESC
)
  SELECT * 
    FROM report 
   WHERE bloat_ratio != 0
 -- AND schemaname = 'public'
 -- AND tblname = 'pgbench_accounts'
;

-- WHERE NOT is_na
--   AND tblpages*((pst).free_percent + (pst).dead_tuple_percent)::float4/100 >= 1
```

É possível verificar se há sobrecarga na tabela e no índice em sua aplicação. Para obter mais informações, consulte [Diagnosticar a sobrecarga na tabela e no índice](AuroraPostgreSQL.diag-table-ind-bloat.md).

#### Localizar índices que consomem espaço desnecessário
<a name="apg-waits.iodatafileread.actions.maintenance.indexes"></a>

Para localizar índices que consomem espaço desnecessário, execute a seguinte consulta.

```
-- WARNING: run with a nonsuperuser role, the query inspects
-- only indexes on tables you have permissions to read.
-- WARNING: rows with is_na = 't' are known to have bad statistics ("name" type is not supported).
-- This query is compatible with PostgreSQL 8.2 and later.

SELECT current_database(), nspname AS schemaname, tblname, idxname, bs*(relpages)::bigint AS real_size,
  bs*(relpages-est_pages)::bigint AS extra_size,
  100 * (relpages-est_pages)::float / relpages AS extra_ratio,
  fillfactor, bs*(relpages-est_pages_ff) AS bloat_size,
  100 * (relpages-est_pages_ff)::float / relpages AS bloat_ratio,
  is_na
  -- , 100-(sub.pst).avg_leaf_density, est_pages, index_tuple_hdr_bm, 
  -- maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, sub.reltuples, sub.relpages 
  -- (DEBUG INFO)
FROM (
  SELECT coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)/(4+nulldatahdrwidth)::float)), 0 
       -- ItemIdData size + computed avg size of a tuple (nulldatahdrwidth)
    ) AS est_pages,
    coalesce(1 +
       ceil(reltuples/floor((bs-pageopqdata-pagehdr)*fillfactor/(100*(4+nulldatahdrwidth)::float))), 0
    ) AS est_pages_ff,
    bs, nspname, table_oid, tblname, idxname, relpages, fillfactor, is_na
    -- , stattuple.pgstatindex(quote_ident(nspname)||'.'||quote_ident(idxname)) AS pst, 
    -- index_tuple_hdr_bm, maxalign, pagehdr, nulldatawidth, nulldatahdrwidth, reltuples 
    -- (DEBUG INFO)
  FROM (
    SELECT maxalign, bs, nspname, tblname, idxname, reltuples, relpages, relam, table_oid, fillfactor,
      ( index_tuple_hdr_bm +
          maxalign - CASE -- Add padding to the index tuple header to align on MAXALIGN
            WHEN index_tuple_hdr_bm%maxalign = 0 THEN maxalign
            ELSE index_tuple_hdr_bm%maxalign
          END
        + nulldatawidth + maxalign - CASE -- Add padding to the data to align on MAXALIGN
            WHEN nulldatawidth = 0 THEN 0
            WHEN nulldatawidth::integer%maxalign = 0 THEN maxalign
            ELSE nulldatawidth::integer%maxalign
          END
      )::numeric AS nulldatahdrwidth, pagehdr, pageopqdata, is_na
      -- , index_tuple_hdr_bm, nulldatawidth -- (DEBUG INFO)
    FROM (
      SELECT
        i.nspname, i.tblname, i.idxname, i.reltuples, i.relpages, i.relam, a.attrelid AS table_oid,
        current_setting('block_size')::numeric AS bs, fillfactor,
        CASE -- MAXALIGN: 4 on 32bits, 8 on 64bits (and mingw32 ?)
          WHEN version() ~ 'mingw32' OR version() ~ '64-bit|x86_64|ppc64|ia64|amd64' THEN 8
          ELSE 4
        END AS maxalign,
        /* per page header, fixed size: 20 for 7.X, 24 for others */
        24 AS pagehdr,
        /* per page btree opaque data */
        16 AS pageopqdata,
        /* per tuple header: add IndexAttributeBitMapData if some cols are null-able */
        CASE WHEN max(coalesce(s.null_frac,0)) = 0
          THEN 2 -- IndexTupleData size
          ELSE 2 + (( 32 + 8 - 1 ) / 8) 
          -- IndexTupleData size + IndexAttributeBitMapData size ( max num filed per index + 8 - 1 /8)
        END AS index_tuple_hdr_bm,
        /* data len: we remove null values save space using it fractionnal part from stats */
        sum( (1-coalesce(s.null_frac, 0)) * coalesce(s.avg_width, 1024)) AS nulldatawidth,
        max( CASE WHEN a.atttypid = 'pg_catalog.name'::regtype THEN 1 ELSE 0 END ) > 0 AS is_na
      FROM pg_attribute AS a
        JOIN (
          SELECT nspname, tbl.relname AS tblname, idx.relname AS idxname, 
            idx.reltuples, idx.relpages, idx.relam,
            indrelid, indexrelid, indkey::smallint[] AS attnum,
            coalesce(substring(
              array_to_string(idx.reloptions, ' ')
               from 'fillfactor=([0-9]+)')::smallint, 90) AS fillfactor
          FROM pg_index
            JOIN pg_class idx ON idx.oid=pg_index.indexrelid
            JOIN pg_class tbl ON tbl.oid=pg_index.indrelid
            JOIN pg_namespace ON pg_namespace.oid = idx.relnamespace
          WHERE pg_index.indisvalid AND tbl.relkind = 'r' AND idx.relpages > 0
        ) AS i ON a.attrelid = i.indexrelid
        JOIN pg_stats AS s ON s.schemaname = i.nspname
          AND ((s.tablename = i.tblname AND s.attname = pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE)) 
          -- stats from tbl
          OR  (s.tablename = i.idxname AND s.attname = a.attname))
          -- stats from functionnal cols
        JOIN pg_type AS t ON a.atttypid = t.oid
      WHERE a.attnum > 0
      GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9
    ) AS s1
  ) AS s2
    JOIN pg_am am ON s2.relam = am.oid WHERE am.amname = 'btree'
) AS sub
-- WHERE NOT is_na
ORDER BY 2,3,4;
```

#### Localizar tabelas elegíveis qualificadas para receber autovacuum
<a name="apg-waits.iodatafileread.actions.maintenance.autovacuumed"></a>

Para localizar tabelas qualificadas para receber autovacuum, execute a seguinte consulta.

```
--This query shows tables that need vacuuming and are eligible candidates.
--The following query lists all tables that are due to be processed by autovacuum. 
-- During normal operation, this query should return very little.
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
    -- or 1 = 1
)
ORDER BY age(relfrozenxid) DESC;
```

### Responder a um alto número de conexões
<a name="apg-waits.iodatafileread.actions.connections"></a>

Ao monitorar o Amazon CloudWatch, você pode descobrir que a métrica `DatabaseConnections` atinge picos. Esse aumento indica um número maior de conexões com o seu banco de dados. Recomendamos a seguinte abordagem:
+ Limite o número de conexões que a aplicação pode abrir com cada instância. Se a aplicação tiver um recurso de grupo de conexões incorporado, defina um número razoável de conexões. Baseie o número no que as vCPUs na instância podem paralelizar de maneira eficiente.

  Se a aplicação não utilizar um recurso de grupo de conexões, considere utilizar o Amazon RDS Proxy ou uma alternativa. Essa abordagem permite que a aplicação abra várias conexões com o balanceador de carga. O balanceador pode então abrir um número restrito de conexões com o banco de dados. À medida que menos conexões são executadas em paralelo, sua instância de banco de dados realiza menos alternâncias de contexto no kernel. As consultas devem progredir com mais rapidez, resultando em menos eventos de espera. Para obter mais informações, consulte [Amazon RDS Proxypara Aurora](rds-proxy.md).
+ Sempre que possível, aproveite nós de leitura para o Aurora PostgreSQL e réplicas de leitura do RDS for PostgreSQL. Quando a aplicação executar uma operação somente leitura, envie essas solicitações ao endpoint somente leitura. Essa técnica dispersa as solicitações de aplicações em todos os nós de leitor, reduzindo a pressão de E/S no nó de gravador.
+ Considere aumentar a escala vertical da sua instância de banco de dados. Uma classe de instância com maior capacidade fornece mais memória, o que dá ao Aurora PostgreSQL um grupo de buffer compartilhado maior para conter páginas. O tamanho maior também dá à instância de banco de dados mais vCPUs para lidar com conexões. Mais vCPUs são particularmente úteis quando as operações que estão gerando eventos de espera `IO:DataFileRead` são gravações.

# IO:XactSync
<a name="apg-waits.xactsync"></a>

O evento `IO:XactSync` ocorre quando o banco de dados está aguardando o subsistema de armazenamento do Aurora confirmar uma transação regular ou a reversão de uma transação preparada. Uma transação preparada faz parte do suporte do PostgreSQL para uma confirmação em duas fases. Esse evento também pode ocorrer quando uma consulta está aguardando a confirmação de outra transação, principalmente nos casos em que a confirmação automática está desativada. Nesses cenários, pode parecer que as atualizações estão aguardando XactSync, mesmo que ainda não tenham sido confirmadas.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.xactsync.context.supported)
+ [Contexto](#apg-waits.xactsync.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.xactsync.causes)
+ [Ações](#apg-waits.xactsync.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.xactsync.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.xactsync.context"></a>

O evento `IO:XactSync` indica que a instância está gastando tempo à espera do subsistema de armazenamento do Aurora para confirmar que os dados da transação foram processados.

## Possíveis causas do maior número de esperas
<a name="apg-waits.xactsync.causes"></a>

Quando o evento `IO:XactSync` aparece mais que o normal, possivelmente indicando um problema de performance, as causas típicas incluem:

**Saturação da rede**  
O tráfego entre os clientes e a instância de banco de dados ou o tráfego para o subsistema de armazenamento pode ser muito pesado para a largura de banda da rede.

**Pressão da CPU**  
Uma workload pesada pode estar impedindo que o daemon de armazenamento do Aurora obtenha tempo suficiente de CPU.

## Ações
<a name="apg-waits.xactsync.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Monitorar seus recursos](#apg-waits.xactsync.actions.monitor)
+ [Aumentar a escala da CPU verticalmente](#apg-waits.xactsync.actions.scalecpu)
+ [Aumentar a largura de banda da rede](#apg-waits.xactsync.actions.scalenetwork)
+ [Reduza o número de confirmações](#apg-waits.xactsync.actions.commits)

### Monitorar seus recursos
<a name="apg-waits.xactsync.actions.monitor"></a>

Para determinar a causa do aumento de eventos `IO:XactSync`, verifique as seguintes métricas:
+ `WriteThroughput` e `CommitThroughput`: mudanças na taxa de transferência de gravação ou na taxa de transferência de confirmação podem indicar um aumento na workload.
+ `WriteLatency` e `CommitLatency`: mudanças na latência de gravação ou latência de confirmação podem indicar que o subsistema de armazenamento está sendo solicitado a trabalhar mais.
+ `CPUUtilization`: se a utilização da CPU da instância estiver acima de 90%, o daemon de armazenamento do Aurora talvez não esteja obtendo tempo suficiente na CPU. Nesse caso, a performance da E/S diminuirá.

Para obter informações sobre essas métricas, consulte [Métricas no nível da instância do Amazon Aurora](Aurora.AuroraMonitoring.Metrics.md#Aurora.AuroraMySQL.Monitoring.Metrics.instances).

### Aumentar a escala da CPU verticalmente
<a name="apg-waits.xactsync.actions.scalecpu"></a>

Para solucionar problemas de falta de CPU, considere mudar para um tipo de instância com mais capacidade de CPU. Para obter informações sobre a capacidade de CPU de uma classe de instância de banco de dados, consulte [Especificações de hardware para classes de instância de banco de dadospara o Aurora](Concepts.DBInstanceClass.Summary.md).

### Aumentar a largura de banda da rede
<a name="apg-waits.xactsync.actions.scalenetwork"></a>

Para determinar se a instância está atingindo seus limites de largura de banda de rede, verifique os seguintes eventos de espera: 
+ `IO:DataFileRead`, `IO:BufferRead`, `IO:BufferWrite` e `IO:XactWrite`: consultas que utilizam grandes quantidades de E/S podem gerar mais desses eventos de espera.
+ `Client:ClientRead` e `Client:ClientWrite`: consultas com grandes quantidades de comunicação com o cliente podem gerar mais desses eventos de espera.

Se a largura de banda da rede for um problema, considere mudar para um tipo de instância com maior largura de banda de rede. Para obter informações sobre a performance de rede de uma classe de instância de banco de dados, consulte [Especificações de hardware para classes de instância de banco de dadospara o Aurora](Concepts.DBInstanceClass.Summary.md).

### Reduza o número de confirmações
<a name="apg-waits.xactsync.actions.commits"></a>

Para reduzir o número de confirmações, combine instruções em blocos de transações.

# IPC:DamRecordTxAck
<a name="apg-waits.ipcdamrecordtxac"></a>

O evento `IPC:DamRecordTxAck` ocorre quando o Aurora PostgreSQL em uma sessão que utiliza fluxos de atividades do banco de dados gera um evento de fluxo de atividades e espera que o evento se torne durável. 

**Topics**
+ [Versões de mecanismos relevantes](#apg-waits.ipcdamrecordtxac.context.supported)
+ [Contexto](#apg-waits.ipcdamrecordtxac.context)
+ [Causas](#apg-waits.ipcdamrecordtxac.causes)
+ [Ações](#apg-waits.ipcdamrecordtxac.actions)

## Versões de mecanismos relevantes
<a name="apg-waits.ipcdamrecordtxac.context.supported"></a>

Essas informações de evento de espera são relevantes para o Aurora PostgreSQL 10.7 e todas as versões 10 superiores, a versão 11.4 e todas as versões 11 e todas as versões 12 e 13.

## Contexto
<a name="apg-waits.ipcdamrecordtxac.context"></a>

No modo síncrono, a durabilidade dos eventos de fluxos de atividades é favorecida em relação à performance do banco de dados. Ao aguardar uma gravação duradoura do evento, a sessão bloqueia outras atividades do banco de dados, causando o evento de espera `IPC:DamRecordTxAck`.

## Causas
<a name="apg-waits.ipcdamrecordtxac.causes"></a>

A causa mais comum do surgimento do evento `IPC:DamRecordTxAck` nas principais esperas é que o recurso Database Activity Streams (DAS) é uma auditoria holística. A atividade SQL mais elevada gera eventos de fluxo de atividades que precisam ser registrados.

## Ações
<a name="apg-waits.ipcdamrecordtxac.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera:
+ Reduza o número de instruções SQL ou desative fluxos de atividades de banco de dados. Fazer isso reduz o número de eventos que exigem gravações duráveis.
+ Mude para o modo assíncrono. Isso ajuda a reduzir a contenção no evento de espera `IPC:DamRecordTxAck`.

  No entanto, o recurso DAS não pode garantir a durabilidade de cada um dos eventos no modo assíncrono.

# IPC: eventos de espera paralelos
<a name="apg-ipc-parallel"></a>

Os seguintes `IPC:parallel wait events` indicam que uma sessão está aguardando a comunicação entre processos relacionada às operações de execução paralela de consultas.
+ `IPC:BgWorkerStartup`: um processo está aguardando um processo de operador concluir sua sequência de inicialização. Isso acontece ao inicializar operadores para execução paralela de consultas.
+ `IPC:BgWorkerShutdown`: um processo está aguardando um processo de operador concluir sua sequência de shutdown. Isso ocorre durante a fase de limpeza da execução paralela da consulta.
+ `IPC:ExecuteGather`: um processo está aguardando para receber dados de processos de operador paralelos durante a execução da consulta. Isso ocorre quando o processo líder precisa coletar resultados de seus operadores.
+ `IPC:ParallelFinish`: um processo está aguardando operadores paralelos terminarem sua execução e relatarem seus resultados finais. Isso acontece durante a fase de conclusão da execução paralela da consulta.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-ipc-parallel-context-supported)
+ [Contexto](#apg-ipc-parallel-context)
+ [Possíveis causas do maior número de esperas](#apg-ipc-parallel-causes)
+ [Ações](#apg-ipc-parallel-actions)

## Versões compatíveis do mecanismo
<a name="apg-ipc-parallel-context-supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-ipc-parallel-context"></a>

A execução paralela de consultas no PostgreSQL envolve vários processos trabalhando juntos para processar uma única consulta. Quando uma consulta é determinada como adequada para paralelização, um processo líder se coordena com um ou mais processos de operador paralelos com base na configuração de parâmetros `max_parallel_workers_per_gather`. O processo líder divide o trabalho entre os operadores, cada um processa sua parte dos dados de forma independente e os resultados são reunidos de volta ao processo líder.

**nota**  
Cada operador paralelo opera como um processo separado com requisitos de recursos semelhantes a uma sessão completa de usuário. Isso significa que uma consulta paralela com 4 operadores pode consumir até 5 vezes mais recursos (CPU, memória, largura de banda de E/S) em comparação com uma consulta não paralela, pois tanto o processo líder quanto cada processo de operador mantêm suas próprias alocações de recursos. Por exemplo, configurações como `work_mem` são aplicadas individualmente a cada operador, potencialmente multiplicando o uso total de memória em todos os processos.

A arquitetura de consulta paralela consiste em três componentes principais:
+ Processo líder: o processo principal que inicia a operação paralela, divide a workload e coordena com os processos de operador.
+ Processos de operador: processos em segundo plano que executam partes da consulta em paralelo.
+ Fusão Gather/Gather: operações que combinam resultados de vários processos de operador de volta ao líder

Durante a execução paralela, os processos precisam se comunicar entre si por meio de mecanismos de comunicação entre processos (IPC). Esses eventos de espera do IPC ocorrem durante diferentes fases:
+ Inicialização do operador: quando operadores paralelos estão sendo inicializados
+ Troca de dados: quando os operadores estão processando dados e enviando resultados para o líder
+ Encerramento do operador: quando a execução paralela é concluída e os operadores estão sendo encerrados
+ Pontos de sincronização: quando os processos precisam se coordenar ou esperar que outros processos concluam suas tarefas

Compreender esses eventos de espera é crucial para diagnosticar problemas de desempenho relacionados à execução paralela de consultas, especialmente em ambientes de alta concorrência, nos quais várias consultas paralelas podem ser executadas simultaneamente.

## Possíveis causas do maior número de esperas
<a name="apg-ipc-parallel-causes"></a>

Vários fatores podem contribuir para um aumento nos eventos de espera do IPC relacionados ao paralelismo:

**Alta concorrência de consultas paralelas**  
Quando muitas consultas paralelas são executadas simultaneamente, isso pode levar à contenção de recursos e ao aumento do tempo de espera para operações de IPC. Isso é particularmente comum em sistemas com altos volumes de transações ou workloads analíticas.

**Planos de consulta paralela subótimos**  
Se o planejador de consultas escolher planos paralelos ineficientes, isso poderá resultar em paralelização desnecessária ou má distribuição do trabalho entre os operadores. Isso pode levar ao aumento das esperas de IPC, especialmente para eventos IPC:ExecuteGather e IPC:ParallelFinish. Esses problemas de planejamento geralmente resultam de estatísticas desatualizadas e do inchaço da tabela/índice.

**Inicialização e encerramento frequentes de operadores paralelos**  
Consultas de curta duração que frequentemente iniciam e encerram operadores paralelos podem causar um aumento nos eventos `IPC:BgWorkerStartup` e `IPC:BgWorkerShutdown`. Isso geralmente é visto em workloads OLTP com muitas consultas pequenas e paralelizáveis.

**Restrições de recursos**  
A capacidade limitada de CPU, memória ou E/S pode causar gargalos na execução paralela, levando ao aumento do tempo de espera em todos os eventos de IPC. Por exemplo, se a CPU estiver saturada, os processos de operador podem levar mais tempo para iniciar ou processar sua parte do trabalho.

**Estruturas complexas de consulta**  
Consultas com vários níveis de paralelismo (por exemplo, junções paralelas seguidas por agregações paralelas) podem levar a padrões de IPC mais complexos e a tempos de espera potencialmente maiores, especialmente para eventos `IPC:ExecuteGather`.

**Conjuntos de resultados grandes**  
Consultas que produzem grandes conjuntos de resultados podem causar maiores tempos de espera `IPC:ExecuteGather`, pois o processo líder passa mais tempo coletando e processando resultados dos processos de operador.

Entender esses fatores pode ajudar a diagnosticar e resolver problemas de desempenho relacionados à execução paralela de consultas no Aurora PostgreSQL.

## Ações
<a name="apg-ipc-parallel-actions"></a>

Quando você vê esperas relacionadas à consulta paralela, isso normalmente significa que um processo de backend está coordenando ou aguardando processos de operador paralelos. Essas esperas são comuns durante a execução de planos paralelos. Você pode investigar e mitigar o impacto dessas esperas monitorando o uso de operadores paralelos, revisando as configurações de parâmetros e ajustando a execução da consulta e a alocação de recursos.

**Topics**
+ [Analisar planos de consulta para paralelismo ineficiente](#apg-ipc-parallel-analyze-plans)
+ [Monitorar o uso de consultas paralelas](#apg-ipc-parallel-monitor)
+ [Revisar e ajustar as configurações de consulta paralela](#apg-ipc-parallel-adjust-settings)
+ [Otimizar a alocação de recursos](#apg-ipc-parallel-optimize-resources)
+ [Investigar o gerenciamento de conexão](#apg-ipc-parallel-connection-management)
+ [Revisar e otimizar as operações de manutenção](#apg-ipc-parallel-maintenance)
+ [Utilize o gerenciamento de planos de consultas (QPM)](#apg-ipc-parallel-query-plan-management)

### Analisar planos de consulta para paralelismo ineficiente
<a name="apg-ipc-parallel-analyze-plans"></a>

A execução paralela de consultas pode frequentemente levar à instabilidade do sistema, picos de CPU e variações imprevisíveis no desempenho da consulta. É crucial analisar minuciosamente se o paralelismo realmente melhora sua workload específica. Use EXPLAIN ANALYZE para revisar os planos de execução de consultas paralelas.

Desative temporariamente o paralelismo no nível da sessão para comparar a eficiência do plano:

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

Reative o paralelismo e compare:

```
RESET max_parallel_workers_per_gather;
EXPLAIN ANALYZE <your_query>;
```

Se a desativação do paralelismo produzir resultados melhores ou mais consistentes, desative-o para consultas específicas no nível da sessão usando os comandos SET. Para um impacto mais amplo, você pode querer desabilitar o paralelismo no nível da instância ajustando os parâmetros relevantes em seu grupo de parâmetros do cluster ou instância. Para obter mais informações, consulte [Amazon Aurora PostgreSQL parameters](AuroraPostgreSQL.Reference.ParameterGroups.md).

### Monitorar o uso de consultas paralelas
<a name="apg-ipc-parallel-monitor"></a>

Use as consultas a seguir para obter visibilidade da atividade e da capacidade de consultas paralelas:

Verifique os processos de operador paralelos ativos:

```
SELECT
    COUNT(*)
FROM
    pg_stat_activity
WHERE
    backend_type = 'parallel worker';
```

Esta consulta mostra o número de processos de operador paralelos ativos. Um valor alto pode indicar que seu `max\$1parallel\$1workers` está configurado com um valor alto e você pode querer reduzi-lo.

Verifique as consultas paralelas simultâneas:

```
SELECT
    COUNT(DISTINCT leader_pid)
FROM
    pg_stat_activity
WHERE
    leader_pid IS NOT NULL;
```

Essa consulta retorna o número de processos líderes distintos que iniciaram consultas paralelas. Um número alto aqui indica que várias sessões estão executando consultas paralelas simultaneamente, o que pode aumentar a demanda de CPU e memória.

### Revisar e ajustar as configurações de consulta paralela
<a name="apg-ipc-parallel-adjust-settings"></a>

Analise os seguintes parâmetros para garantir que estejam alinhados à sua workload:
+ `max_parallel_workers`: número total de workers paralelos em todas as sessões.
+ `max_parallel_workers_per_gather`: máximo de workers por consulta.

Para workloads OLAP, aumentar esses valores pode melhorar o desempenho. Para workloads OLTP, valores mais baixos geralmente são preferidos.

```
SHOW max_parallel_workers;
SHOW max_parallel_workers_per_gather;
```

### Otimizar a alocação de recursos
<a name="apg-ipc-parallel-optimize-resources"></a>

Monitore a utilização da CPU e ajuste o número de vCPUs se for consistentemente alto e se seu aplicativo se beneficiar de consultas paralelas. Verifique se há memória adequada disponível para operações paralelas.
+ Use as métricas do Performance Insights para determinar se o sistema está limitado pela CPU.
+ Cada operador paralelo usa o seu próprio `work_mem`. Verifique se o uso total da memória está dentro dos limites da instância.

As consultas paralelas podem consumir substancialmente mais recursos do que as consultas não paralelas, porque cada processo de operador é completamente separado que tem aproximadamente o mesmo impacto no sistema que uma sessão de usuário adicional. Isso deve ser levado em consideração ao escolher um valor para essa configuração, bem como ao definir outras configurações que controlam a utilização de recursos, como `work_mem`. Para obter mais informações, consulte a [Documentação do PostgreSQL](https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM). Limites de recursos, como `work_mem`, são aplicados individualmente a cada operador, o que significa que a utilização total pode ser muito maior em todos os processos do que normalmente seria em qualquer processo único.

Aumente as vCPUs ou ajuste os parâmetros de memória se sua workload estiver altamente paralelizada.

### Investigar o gerenciamento de conexão
<a name="apg-ipc-parallel-connection-management"></a>

Se estiver experimentando esgotamento de conexões, revise as estratégias de pool de conexões do aplicativo. Implemente o pool de conexões no nível do aplicativo, se ainda não estiver em uso.

### Revisar e otimizar as operações de manutenção
<a name="apg-ipc-parallel-maintenance"></a>

Coordene a criação de índices e outras tarefas de manutenção para evitar a contenção de recursos. Agende essas operações fora do horário de pico. Evite agendar manutenções pesadas (por exemplo, construções paralelas de índices) durante períodos de alta carga de consultas do usuário. Essas operações podem consumir workers paralelos e impactar o desempenho de consultas regulares.

### Utilize o gerenciamento de planos de consultas (QPM)
<a name="apg-ipc-parallel-query-plan-management"></a>

No Aurora PostgreSQL, o atributo de gerenciamento de planos de consulta (QPM) foi projetado para garantir a adaptabilidade e a estabilidade do plano, independentemente das alterações no ambiente de banco de dados que poderiam causar a regressão do plano de consulta. Para obter mais informações, consulte [Visão geral do gerenciamento de planos de consulta do Aurora PostgreSQL](AuroraPostgreSQL.Optimize.overview.md). O QPM fornece algum controle sobre o otimizador. Revise os planos aprovados no QPM para garantir que estejam alinhados com as configurações atuais de paralelismo. Atualize ou remova planos desatualizados que possam estar forçando uma execução paralela subótima.

Você também pode corrigir os planos usando pg\$1hint\$1plan. Para obter mais informações, consulte [Corrigir planos usando pg\$1hint\$1plan](AuroraPostgreSQL.Optimize.Maintenance.md#AuroraPostgreSQL.Optimize.Maintenance.pg_hint_plan). Você pode usar a dica chamada `Parallel` para forçar a execução paralela. Para obter mais informações, consulte [Dicas para planos paralelos](https://github.com/ossc-db/pg_hint_plan/blob/master/docs/hint_table.md#hints-for-parallel-plans).

# IPC:ProcArrayGroupUpdate
<a name="apg-rpg-ipcprocarraygroup"></a>

O evento `IPC:ProcArrayGroupUpdate` ocorre quando uma sessão está aguardando o líder do grupo atualizar o status da transação ao final dessa operação. Embora o PostgreSQL geralmente associe eventos de espera do tipo IPC a operações de consulta paralela, esse evento de espera determinado não é específico de consultas paralelas.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-rpg-ipcprocarraygroup.supported)
+ [Contexto](#apg-rpg-ipcprocarraygroup.context)
+ [Possíveis causas do maior número de esperas](#apg-rpg-ipcprocarraygroup.causes)
+ [Ações](#apg-rpg-ipcprocarraygroup.actions)

## Versões compatíveis do mecanismo
<a name="apg-rpg-ipcprocarraygroup.supported"></a>

As informações sobre esse evento de espera são aceitas em todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-rpg-ipcprocarraygroup.context"></a>

**Noções básicas sobre a matriz do processo**: a matriz do processo (proc) é uma estrutura de memória compartilhada no PostgreSQL. Ela contém informações sobre todos os processos em execução, incluindo detalhes da transação. Durante a conclusão da transação (`COMMIT` ou `ROLLBACK`), o ProcArray precisa ser atualizado para refletir a alteração e limpar o ID da transação da matriz. A sessão que tenta concluir sua transação deve adquirir um bloqueio exclusivo no ProcArray. Isso impede que outros processos tenham bloqueios compartilhados ou exclusivos.

**Mecanismo de atualização de grupo**: ao executar um COMMIT ou ROLLBACK, se um processo de backend não conseguir recuperar um ProcArrayLock no modo exclusivo, ele atualizará um campo especial chamado ProcArrayGroupMember. Isso adiciona a transação à lista de sessões que pretendem terminar. Esse processo de backend então é suspenso, e o tempo de suspensão é instrumentado como o evento de espera ProcArrayGroupUpdate. O primeiro processo no ProcArray com o procArrayGroupMember, conhecido como processo líder, adquire o ProcArrayLock no modo exclusivo. Depois, ele limpa a lista de processos que aguardam a limpeza do transactionID do grupo. Quando isso é concluído, o líder libera o ProcArrayLock e, depois, ativa todos os processos dessa lista, notificando-os de que a transação foi concluída.

## Possíveis causas do maior número de esperas
<a name="apg-rpg-ipcprocarraygroup.causes"></a>

Quanto mais processos estiverem em execução, mais tempo um líder manterá um procArrayLock no modo exclusivo. Consequentemente, quanto mais transações de gravação ocorrerem, maior a chance de entrarem em um cenário de atualização em grupo, causando um possível acúmulo de processos aguardando o evento de espera `ProcArrayGroupUpdate`. Na visualização Top SQL do Database Insights, você verá que COMMIT é a declaração com a maior parte desse evento de espera. Isso é esperado, mas exigirá uma investigação mais profunda do SQL de gravação específico que está sendo executado para determinar qual ação apropriada realizar.

## Ações
<a name="apg-rpg-ipcprocarraygroup.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera. Identifique eventos `IPC:ProcArrayGroupUpdate` utilizando o Insights de Performance do Amazon RDS ou consultando a visualização `pg_stat_activity` do sistema PostgreSQL.

**Topics**
+ [Monitorar operações de confirmação e reversão de transações](#apg-rpg-ipcprocarraygroup.actions.monitor)
+ [Reduzir a simultaneidade](#apg-rpg-ipcprocarraygroup.actions.concurrency)
+ [Implementar o agrupamento de conexões](#apg-rpg-ipcprocarraygroup.actions.pooling)

### Monitorar operações de confirmação e reversão de transações
<a name="apg-rpg-ipcprocarraygroup.actions.monitor"></a>

**Monitorar confirmações e reversões**: um número maior de confirmações e reversões pode aumentar a pressão sobre o ProcArray. Por exemplo, se uma instrução SQL começar a falhar devido ao aumento das violações de chaves duplicadas, você poderá observar um aumento nas reversões, o que pode aumentar a contenção do ProcArray e o inchaço da tabela.

O Amazon RDS Database Insights fornece as métricas `xact_commit` e `xact_rollback` do PostgreSQL e relata o número de confirmações e reversões por segundo.

### Reduzir a simultaneidade
<a name="apg-rpg-ipcprocarraygroup.actions.concurrency"></a>

**Transações em lote**: sempre que possível, agrupe operações em transações únicas para reduzir as operações de confirmação/reversão.

**Limitar a simultaneidade**: reduza o número de transações ativas simultaneamente para aliviar a contenção de bloqueios no ProcArray. Embora isso exija alguns testes, reduzir o número total de conexões simultâneas pode reduzir a contenção e manter o throughput.

### Implementar o agrupamento de conexões
<a name="apg-rpg-ipcprocarraygroup.actions.pooling"></a>

**Soluções de agrupamento de conexões**: use o grupo de conexões para gerenciar conexões de banco de dados com eficiência, reduzindo o número total de backends e, portanto, a workload no ProcArray. Embora isso exija alguns testes, reduzir o número total de conexões simultâneas pode reduzir a contenção e manter o throughput.

Para acessar mais informações, consulte [Connection pooling for Aurora PostgreSQL](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.BestPractices.connection_pooling.html).

**Reduzir os surtos de conexão**: da mesma forma, um padrão de criação e encerramento frequentes de conexões causa pressão adicional no ProcArray. Ao reduzir esse padrão, a contenção geral é reduzida.

# Lock:advisory
<a name="apg-waits.lockadvisory"></a>

O evento `Lock:advisory` ocorre quando uma aplicação PostgreSQL utiliza um bloqueio para coordenar as atividades em várias sessões.

**Topics**
+ [Versões de mecanismos relevantes](#apg-waits.lockadvisory.context.supported)
+ [Contexto](#apg-waits.lockadvisory.context)
+ [Causas](#apg-waits.lockadvisory.causes)
+ [Ações](#apg-waits.lockadvisory.actions)

## Versões de mecanismos relevantes
<a name="apg-waits.lockadvisory.context.supported"></a>

As informações sobre eventos de espera são relevantes para o Aurora PostgreSQL versão 9.6 e versões superiores.

## Contexto
<a name="apg-waits.lockadvisory.context"></a>

Bloqueios consultivos do PostgreSQL são bloqueios cooperativos em nível de aplicação, feitos explicitamente e desfeitos pelo código da aplicação do usuário. Uma aplicação pode utilizar bloqueios consultivos do PostgreSQL para coordenar atividades em várias sessões. Ao contrário de bloqueios regulares, ou em nível de objeto ou linha, a aplicação tem controle total ao longo da vida útil do bloqueio. Para obter mais informações, consulte o tópico sobre [Bloqueios consultivos](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) na documentação do PostgreSQL.

Bloqueios consultivos podem ser liberados antes que uma transação termine ou podem ser mantidos por uma sessão em todas as transações. Isso não é válido para bloqueios implícitos aplicados pelo sistema, como um bloqueio exclusivo de acesso em uma tabela adquirida por uma instrução `CREATE INDEX`.

Para obter uma descrição das funções utilizadas para adquirir (bloquear) e liberar (desbloquear) bloqueios consultivos, consulte o tópico sobre [Funções de bloqueios consultivos](https://www.postgresql.org/docs/current/functions-admin.html#FUNCTIONS-ADVISORY-LOCKS), na documentação do PostgreSQL.

Bloqueios consultivos são implementados sobre o sistema de bloqueio regular do PostgreSQL e ficam visíveis na visualização do sistema `pg_locks`.

## Causas
<a name="apg-waits.lockadvisory.causes"></a>

Esse tipo de bloqueio é controlado exclusivamente por uma aplicação que o utiliza explicitamente. Bloqueios consultivos que são adquiridos para cada linha como parte de uma consulta podem causar um aumento nos bloqueios ou um acúmulo a longo prazo.

Esses efeitos acontecem quando a consulta é executada de uma maneira que adquire bloqueios em mais linhas do que as retornadas pela consulta. A aplicação deve eventualmente liberar todos os bloqueios, mas, se eles forem adquiridos em linhas que não são retornadas, a aplicação não poderá localizar todos os bloqueios.

O exemplo a seguir foi extraído do tópico [Bloqueios consultivos](https://www.postgresql.org/docs/12/explicit-locking.html#ADVISORY-LOCKS) na documentação do PostgreSQL.

```
SELECT pg_advisory_lock(id) FROM foo WHERE id > 12345 LIMIT 100;
```

Nesse exemplo, a cláusula `LIMIT` apenas pode interromper a saída da consulta depois que as linhas já foram selecionadas internamente e seus valores de ID estão bloqueados. Isso pode acontecer repentinamente quando um volume de dados crescente faz com que o planejador escolha um plano de execução diferente que não foi testado durante o desenvolvimento. O acúmulo nesse caso acontece porque a aplicação chama explicitamente `pg_advisory_unlock` para cada valor de ID bloqueado. No entanto, nesse caso, não é possível encontrar o conjunto de bloqueios adquiridos em linhas que não foram retornadas. Como os bloqueios são adquiridos em nível de sessão, eles não são liberados automaticamente no final da transação.

Outra possível causa para picos em tentativas de bloqueio bloqueadas são conflitos não intencionais. Nesses conflitos, partes não relacionadas da aplicação compartilham o mesmo espaço de ID de bloqueio por engano.

## Ações
<a name="apg-waits.lockadvisory.actions"></a>

Revise o uso da aplicação de bloqueios consultivos e detalhe onde e quando no fluxo de aplicação cada tipo de bloqueio consultivo é adquirido e liberado.

Determine se uma sessão está adquirindo muitos bloqueios ou se uma sessão de longa execução não está liberando bloqueios cedo o suficiente, resultando em um acúmulo lento de bloqueios. Você pode corrigir um acúmulo lento de bloqueios em nível de sessão encerrando a sessão com `pg_terminate_backend(pid)`. 

Um cliente que aguarda um bloqueio de consultoria aparece em `pg_stat_activity` com `wait_event_type=Lock` e `wait_event=advisory`. É possível obter valores de bloqueio específicos consultando a visualização do sistema `pg_locks` em busca do mesmo `pid`, procurando `locktype=advisory` e `granted=f`.

Em seguida, identifique a sessão de bloqueio consultando `pg_locks` em busca do mesmo bloqueio consultivo que possui `granted=t`, conforme mostrado no exemplo a seguir.

```
SELECT blocked_locks.pid AS blocked_pid,
         blocking_locks.pid AS blocking_pid,
         blocked_activity.usename AS blocked_user,
         blocking_activity.usename AS blocking_user,
         now() - blocked_activity.xact_start AS blocked_transaction_duration,
         now() - blocking_activity.xact_start AS blocking_transaction_duration,
         concat(blocked_activity.wait_event_type,':',blocked_activity.wait_event) AS blocked_wait_event,
         concat(blocking_activity.wait_event_type,':',blocking_activity.wait_event) AS blocking_wait_event,
         blocked_activity.state AS blocked_state,
         blocking_activity.state AS blocking_state,
         blocked_locks.locktype AS blocked_locktype,
         blocking_locks.locktype AS blocking_locktype,
         blocked_activity.query AS blocked_statement,
         blocking_activity.query AS blocking_statement
    FROM pg_catalog.pg_locks blocked_locks
    JOIN pg_catalog.pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
    JOIN pg_catalog.pg_locks blocking_locks
        ON blocking_locks.locktype = blocked_locks.locktype
        AND blocking_locks.DATABASE IS NOT DISTINCT FROM blocked_locks.DATABASE
        AND blocking_locks.relation IS NOT DISTINCT FROM blocked_locks.relation
        AND blocking_locks.page IS NOT DISTINCT FROM blocked_locks.page
        AND blocking_locks.tuple IS NOT DISTINCT FROM blocked_locks.tuple
        AND blocking_locks.virtualxid IS NOT DISTINCT FROM blocked_locks.virtualxid
        AND blocking_locks.transactionid IS NOT DISTINCT FROM blocked_locks.transactionid
        AND blocking_locks.classid IS NOT DISTINCT FROM blocked_locks.classid
        AND blocking_locks.objid IS NOT DISTINCT FROM blocked_locks.objid
        AND blocking_locks.objsubid IS NOT DISTINCT FROM blocked_locks.objsubid
        AND blocking_locks.pid != blocked_locks.pid
    JOIN pg_catalog.pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
    WHERE NOT blocked_locks.GRANTED;
```

Todas as funções de API de bloqueio consultivo têm dois conjuntos de argumentos, um argumento `bigint` ou dois argumentos `integer`:
+ Para as funções de API com um único argumento `bigint`, os 32 bits superiores estão em `pg_locks.classid` e os 32 bits inferiores estão em `pg_locks.objid`.
+ Para as funções da API com dois argumentos `integer`, o primeiro argumento é `pg_locks.classid` e o segundo é `pg_locks.objid`.

O valor `pg_locks.objsubid` indica qual formato de API foi utilizado: `1` significa um argumento `bigint`; `2`significa dois argumentos `integer`.

# Lock:extend
<a name="apg-waits.lockextend"></a>

O evento `Lock:extend` ocorre quando um processo de backend está aguardando para bloquear uma relação com o objetivo de a estender, enquanto outro processo tem um bloqueio nessa relação para o mesmo objetivo.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.lockextend.context.supported)
+ [Contexto](#apg-waits.lockextend.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.lockextend.causes)
+ [Ações](#apg-waits.lockextend.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.lockextend.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.lockextend.context"></a>

O evento `Lock:extend` indica que um processo de backend está aguardando para estender uma relação na qual outro processo de backend mantém um bloqueio enquanto estende essa relação. Como apenas um processo por vez pode estender uma relação, o sistema gera um evento de espera `Lock:extend`. Operações `INSERT`, `COPY` e `UPDATE` podem gerar esse evento.

## Possíveis causas do maior número de esperas
<a name="apg-waits.lockextend.causes"></a>

Quando o evento `Lock:extend` aparece mais que o normal, possivelmente indicando um problema de performance, as causas típicas incluem:

**Surto de inserções simultâneas ou atualizações na mesma tabela **  
Pode haver um aumento no número de sessões simultâneas com consultas que inserem ou atualizam a mesma tabela.

**Largura de banda da rede insuficiente**  
É possível que a largura de banda da rede na instância de banco de dados para as necessidades de comunicação de armazenamento da workload atual. Isso pode contribuir para a latência de armazenamento que causa um aumento em eventos `Lock:extend`.

## Ações
<a name="apg-waits.lockextend.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Reduzir inserções e atualizações simultâneas para a mesma relação](#apg-waits.lockextend.actions.action1)
+ [Aumentar a largura de banda da rede](#apg-waits.lockextend.actions.increase-network-bandwidth)

### Reduzir inserções e atualizações simultâneas para a mesma relação
<a name="apg-waits.lockextend.actions.action1"></a>

Primeiro, determine se há um aumento nas métricas `tup_inserted` e `tup_updated` e um aumento acompanhante nesse evento de espera. Em caso afirmativo, verifique quais relações estão em alta disputa por operações de inserção e atualização. Para determinar isso, consulte a visualização `pg_stat_all_tables` para os valores nos campos `n_tup_ins` e `n_tup_upd`. Para obter mais informações sobre a visualização `pg_stat_all_tables`, consulte [pg\$1stat\$1all\$1tables](https://www.postgresql.org/docs/13/monitoring-stats.html#MONITORING-PG-STAT-ALL-TABLES-VIEW) na documentação do PostgreSQL. 

Para obter mais informações sobre bloqueio e consultas bloqueadas, consulte `pg_stat_activity` como no exemplo a seguir:

```
SELECT
    blocked.pid,
    blocked.usename,
    blocked.query,
    blocking.pid AS blocking_id,
    blocking.query AS blocking_query,
    blocking.wait_event AS blocking_wait_event,
    blocking.wait_event_type AS blocking_wait_event_type
FROM pg_stat_activity AS blocked
JOIN pg_stat_activity AS blocking ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
where
blocked.wait_event = 'extend'
and blocked.wait_event_type = 'Lock';
 
   pid  | usename  |            query             | blocking_id |                         blocking_query                           | blocking_wait_event | blocking_wait_event_type
  ------+----------+------------------------------+-------------+------------------------------------------------------------------+---------------------+--------------------------
   7143 |  myuser  | insert into tab1 values (1); |        4600 | INSERT INTO tab1 (a) SELECT s FROM generate_series(1,1000000) s; | DataFileExtend      | IO
```

Depois de identificar relações que contribuem para o aumento dos eventos `Lock:extend`, utilize as seguintes técnicas para reduzir a contenção:
+ Descubra se é possível utilizar o particionamento para reduzir a contenção para a mesma tabela. Separar tuplas inseridas ou atualizadas em partições diferentes pode reduzir a contenção. Para obter informações sobre particionamento, consulte [Gerenciar partições do PostgreSQL com a extensão pg\$1partman](PostgreSQL_Partitions.md).
+ Se o evento de espera for principalmente devido a atividades de atualização, reduza o valor do fator de preenchimento da relação. Isso pode reduzir as solicitações de novos bloqueios durante a atualização. O fator de preenchimento é um parâmetro de armazenamento de uma tabela que determina o espaço máximo para empacotar uma página de tabela. Ele é expresso como uma porcentagem do espaço total de uma página. Para obter mais informações sobre o parâmetro de fator de preenchimento, consulte [CREATE TABLE](https://www.postgresql.org/docs/13/sql-createtable.html) na documentação do PostgreSQL. 
**Importante**  
É altamente recomendável testar seu sistema se você alterar o fator de preenchimento, pois isso pode afetar negativamente a performance dependendo da workload.

### Aumentar a largura de banda da rede
<a name="apg-waits.lockextend.actions.increase-network-bandwidth"></a>

Para ver se há um aumento na latência de gravação, verifique a métrica `WriteLatency` no CloudWatch. Se houver, use as métricas `WriteThroughput` e `ReadThroughput` do Amazon CloudWatch para monitorar o tráfego relacionado ao armazenamento no cluster de banco de dados. Essas métricas podem ajudar a determinar se a largura de banda da rede é suficiente para a atividade de armazenamento da sua workload.

Se a largura de banda da rede não suficiente, aumente-a. Se a sua instância de banco de dados estiver atingindo os limites de largura de banda da rede, a única maneira de aumentar a largura de banda será ampliar o tamanho da instância de banco de dados.

Para obter mais informações sobre métricas do CloudWatch, consulte [Métricas do Amazon CloudWatch para o Amazon Aurora](Aurora.AuroraMonitoring.Metrics.md). Para obter informações sobre a performance de rede de cada classe de instância de banco de dados, consulte [Especificações de hardware para classes de instância de banco de dadospara o Aurora](Concepts.DBInstanceClass.Summary.md).

# Lock:Relation
<a name="apg-waits.lockrelation"></a>

O evento `Lock:Relation` ocorre quando uma consulta está aguardando para adquirir um bloqueio em uma tabela ou visualização (relação) que está atualmente bloqueada por outra transação.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.lockrelation.context.supported)
+ [Contexto](#apg-waits.lockrelation.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.lockrelation.causes)
+ [Ações](#apg-waits.lockrelation.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.lockrelation.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.lockrelation.context"></a>

A maioria dos comandos PostgreSQL utiliza bloqueios implicitamente para controlar o acesso simultâneo aos dados em tabelas. Também é possível utilizar esses bloqueios explicitamente no código da aplicação com o comando `LOCK`. Vários modos de bloqueio não são compatíveis entre si e podem bloquear transações quando tentam acessar o mesmo objeto. Quando isso acontece, o Aurora PostgreSQL gera um evento `Lock:Relation`. Veja a seguir alguns exemplos comuns:
+ Bloqueios exclusivos, como `ACCESS EXCLUSIVE`, podem bloquear todo o acesso simultâneo. Operações de linguagem de definição de dados (DDL), como `DROP TABLE`, `TRUNCATE`, `VACUUM FULL` e `CLUSTER`, adquirem bloqueios `ACCESS EXCLUSIVE` implicitamente. `ACCESS EXCLUSIVE` também é o modo de bloqueio padrão para instruções `LOCK TABLE` que não especificam um modo explicitamente.
+ Usar `CREATE INDEX (without CONCURRENT)` em uma tabela gera conflito com instruções de linguagem de manipulação de dados (DML) `UPDATE`, `DELETE` e `INSERT`, que adquirem bloqueios `ROW EXCLUSIVE`.

Para obter mais informações sobre bloqueios em nível da tabela e modos de bloqueio conflitantes, consulte o tópico sobre [Bloqueio explícito](https://www.postgresql.org/docs/13/explicit-locking.html) na documentação do PostgreSQL.

Normalmente, o bloqueio de consultas e transações é liberado de uma das seguintes maneiras:
+ Consulta de bloqueio: a aplicação pode cancelar a consulta ou o usuário pode encerrar o processo. O mecanismo também pode forçar a finalização da consulta devido a um tempo limite de declaração de uma sessão ou um mecanismo de detecção de deadlock.
+ Transação de bloqueio: uma transação para de bloquear quando executa uma instrução `ROLLBACK` ou `COMMIT`. Reversões também acontecem automaticamente quando as sessões são desconectadas por um cliente ou por problemas de rede, ou quando são encerradas. As sessões podem ser encerradas quando o mecanismo de banco de dados é desligado, quando o sistema está sem memória e assim por diante.

## Possíveis causas do maior número de esperas
<a name="apg-waits.lockrelation.causes"></a>

Quando o evento `Lock:Relation` ocorre com maior frequência do que o normal, pode indicar um problema de performance. As causas típicas incluem:

**Maior número de sessões simultâneas com bloqueios de tabela conflitantes**  
Pode haver um aumento no número de sessões simultâneas com consultas que bloqueiam a mesma tabela com modos de bloqueio conflitantes.

**Operações de manutenção**  
Operações de manutenção de integridade, como `VACUUM` e `ANALYZE`, podem aumentar significativamente o número de bloqueios conflitantes. `VACUUM FULL` adquire um bloqueio `ACCESS EXCLUSIVE` e `ANALYZE` adquire um bloqueio `SHARE UPDATE EXCLUSIVE`. Ambos os tipos de bloqueios podem causar um evento de espera `Lock:Relation`. Operações de manutenção de dados de aplicações, como atualizar uma visualização materializada, também podem aumentar as consultas e transações bloqueadas.

**Bloqueios em instâncias de leitor**  
Pode haver um conflito entre os bloqueios de relação mantidos pelo gravador e os leitores. No momento, só bloqueios de relação do `ACCESS EXCLUSIVE` são replicados para instâncias do leitor. No entanto, o bloqueio de relação do `ACCESS EXCLUSIVE` entrará em conflito com qualquer bloqueio de relação do `ACCESS SHARE` mantido pelo leitor. Isso pode causar um aumento nos eventos de espera de relação de bloqueio no leitor. 

## Ações
<a name="apg-waits.lockrelation.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Reduzir o impacto do bloqueio de instruções SQL](#apg-waits.lockrelation.actions.reduce-blocks)
+ [Minimizar o efeito de operações de manutenção](#apg-waits.lockrelation.actions.maintenance)
+ [Verificar se há bloqueios de leitor](#apg-waits.lockrelation.actions.readerlocks)

### Reduzir o impacto do bloqueio de instruções SQL
<a name="apg-waits.lockrelation.actions.reduce-blocks"></a>

Para reduzir o impacto do bloqueio de instruções SQL, modifique o código da aplicação sempre que possível. Veja a seguir duas técnicas comuns para reduzir bloqueios:
+ Usar a opção `NOWAIT`: alguns comandos SQL, como instruções `SELECT` e `LOCK`, oferecem suporte a essa opção. A diretiva `NOWAIT` cancela a consulta de solicitação de bloqueio quando o bloqueio não pode ser adquirido imediatamente. Essa técnica pode evitar que uma sessão de bloqueio cause um empilhamento de sessões bloqueadas por detrás dela.

  Por exemplo: suponha que a transação A esteja aguardando um bloqueio mantido pela transação B. Se B solicitar um bloqueio em uma tabela bloqueada pela transação C, a transação A poderá ser bloqueada até a conclusão da transação C. Porém, se a transação B utilizar um `NOWAIT` quando solicitar o bloqueio em C, ela pode falhar rapidamente e garantir que a transação A não precise aguardar indefinidamente.
+ Usar `SET lock_timeout`: defina um valor de `lock_timeout` para limitar o tempo de espera de uma instrução SQL para adquirir um bloqueio em uma relação. Se o bloqueio não for obtido dentro do tempo limite definido, a transação que o está solicitando será cancelada. Defina o valor no nível da sessão.

### Minimizar o efeito de operações de manutenção
<a name="apg-waits.lockrelation.actions.maintenance"></a>

Operações de manutenção, como `VACUUM` e `ANALYZE`, são importantes. Recomendamos que você não as desative ao encontrar eventos de espera `Lock:Relation` relacionados a essas operações de manutenção. As abordagens a seguir podem minimizar o efeito dessas operações:
+ Execute operações de manutenção manualmente fora do horário de pico.
+ Para reduzir esperas `Lock:Relation` causadas por tarefas de autovacuum, realize qualquer ajuste de autovacuum necessário. Para obter mais informações sobre ajuste de autovacuum, consulte [Trabalhar com o autovacuum do PostgreSQL no Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html), no *Guia do usuário do Amazon RDS*.

### Verificar se há bloqueios de leitor
<a name="apg-waits.lockrelation.actions.readerlocks"></a>

É possível ver como as sessões simultâneas em um gravador e leitores podem estar mantendo bloqueios que são aplicáveis uns aos outros. Uma maneira de fazer isso é executando consultas que retornem o tipo de bloqueio e a relação. Na tabela, você pode encontrar uma sequência de consultas para duas dessas sessões simultâneas, uma de gravador e uma de leitor.

O processo de repetição aguarda a duração de `max_standby_streaming_delay` antes de cancelar a consulta do leitor. Como mostrado no exemplo, o tempo limite de bloqueio de 100 ms está bem abaixo do `max_standby_streaming_delay` padrão de 30 segundos. O bloqueio esgota-se antes que seja um problema. 


| Evento de sequência | Sessão | Comando ou saída | 
| --- | --- | --- | 
|  Define uma variável de ambiente chamada READER com o valor especificado e tenta se conectar à instância de banco de dados com esse endpoint.  |  Sessão de leitor  |  Comando da CLI: <pre>export READER=aurorapg2.12345678910.us-west-1.rds.amazonaws.com<br /><br />psql -h $READER</pre> Resultado: 

```
psql (15devel, server 10.14)
Type "help" for help.
```  | 
|  Define uma variável de ambiente chamada WRITER e tenta se conectar à instância de banco de dados com esse endpoint.  |  Sessão de gravador  |  Comando da CLI: <pre>export WRITER=aurorapg1.12345678910.us-west-1.rds.amazonaws.com<br />psql -h $WRITER</pre> Resultado: 

```
psql (15devel, server 10.14) 
Type "help" for help.
```  | 
|  A sessão do gravador cria a tabela t1 na instância de gravador.  |  Sessão de gravador  |  Consulta do PostgreSQL: <pre>postgres=> CREATE TABLE t1(b integer);<br />CREATE TABLE</pre>  | 
|  Se não houver consultas conflitantes no gravador, o bloqueio ACCESS EXCLUSIVE é obtido no gravador imediatamente.  |  Sessão de gravador  |  Bloqueio `ACCESS EXCLUSIVE` habilitado  | 
|  A sessão do leitor especifica um intervalo de tempo limite de bloqueio igual a 100 milissegundos.  |  Sessão de leitor  |  Consulta do PostgreSQL: <pre>postgres=> SET lock_timeout=100;<br />SET</pre>  | 
|  A sessão do leitor tenta ler dados da tabela t1 na instância de leitor.  |  Sessão de leitor  |  Consulta do PostgreSQL: <pre>postgres=> SELECT * FROM t1;</pre> Exemplo de resultado: 

```
b
---
(0 rows)
```  | 
|  A sessão do gravador descarta t1.  |  Sessão de gravador  |  Consulta do PostgreSQL: <pre>postgres=> BEGIN;<br />BEGIN<br />postgres=> DROP TABLE t1;<br />DROP TABLE<br />postgres=></pre>  | 
|  A consulta atinge o tempo limite e é cancelada no leitor.  |  Sessão de leitor  |  Consulta do PostgreSQL: <pre>postgres=> SELECT * FROM t1;</pre> Exemplo de resultado: 

```
ERROR:  canceling statement due to lock timeout
LINE 1: SELECT * FROM t1;
                      ^
```  | 
|  Para determinar a causa do erro, a sessão do leitor consulta `pg_locks` e `pg_stat_activity`  |  Sessão de leitor  |  Consulta do PostgreSQL: <pre>postgres=> SELECT locktype, relation, mode, backend_type<br />postgres=> FROM pg_locks l, pg_stat_activity t1<br />postgres=> WHERE l.pid=t1.pid AND relation = 't1'::regclass::oid;</pre>  | 
|  O resultado indica que o processo `aurora wal replay` está mantendo um bloqueio `ACCESS EXCLUSIVE` na tabela t1.  |  Sessão de leitor  |  Resultado da consulta: <pre> locktype | relation |        mode         |   backend_type<br />----------+----------+---------------------+-------------------<br /> relation | 68628525 | AccessExclusiveLock | aurora wal replay<br />(1 row)</pre>  | 

# Lock:transactionid
<a name="apg-waits.locktransactionid"></a>

O evento `Lock:transactionid` ocorre quando uma transação está aguardando um bloqueio em nível de linha.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.locktransactionid.context.supported)
+ [Contexto](#apg-waits.locktransactionid.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.locktransactionid.causes)
+ [Ações](#apg-waits.locktransactionid.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.locktransactionid.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.locktransactionid.context"></a>

O evento `Lock:transactionid` ocorre quando uma transação está tentando adquirir um bloqueio em nível de linha já concedido a uma transação que está sendo executada simultaneamente. A sessão que mostra o evento de espera `Lock:transactionid` está bloqueada devido a esse bloqueio. Depois que a transação de bloqueio terminar em uma instrução `COMMIT` ou `ROLLBACK`, a transação bloqueada pode continuar.

A semântica de controle de simultaneidade de várias versões do Aurora PostgreSQL garante que os leitores não bloqueiem gravadores e que os gravadores não bloqueiem os leitores. Para que ocorram conflitos em nível de linha, transações de bloqueio e bloqueadas devem emitir instruções conflitantes dos seguintes tipos:
+ `UPDATE`
+ `SELECT … FOR UPDATE`
+ `SELECT … FOR KEY SHARE`

A instrução `SELECT … FOR KEY SHARE` é um caso especial. O banco de dados usa a cláusula `FOR KEY SHARE` para otimizar a performance da integridade referencial. Um bloqueio em nível de linha em uma linha pode bloquear comandos `INSERT`, `UPDATE` e `DELETE` em outras tabelas que fazem referência à linha.

## Possíveis causas do maior número de esperas
<a name="apg-waits.locktransactionid.causes"></a>

Quando esse evento aparece mais do que o normal, a causa geralmente envolve instruções `UPDATE`, `SELECT … FOR UPDATE` ou `SELECT … FOR KEY SHARE` combinadas com as seguintes condições.

**Topics**
+ [Alta simultaneidade](#apg-waits.locktransactionid.concurrency)
+ [Ocioso na transação](#apg-waits.locktransactionid.idle)
+ [Transações de longa execução](#apg-waits.locktransactionid.long-running)

### Alta simultaneidade
<a name="apg-waits.locktransactionid.concurrency"></a>

O Aurora PostgreSQL pode utilizar semântica de bloqueio granular em nível de linha. A probabilidade de conflitos em nível de linha aumenta quando as condições a seguir são atendidas:
+ Uma workload altamente simultânea controla as mesmas linhas.
+ A simultaneidade aumenta.

### Ocioso na transação
<a name="apg-waits.locktransactionid.idle"></a>

Às vezes, a coluna `pg_stat_activity.state` mostra o valor `idle in transaction`. Esse valor aparece para sessões que iniciaram uma transação, mas ainda não emitiram um `COMMIT` ou `ROLLBACK`. Se o valor de `pg_stat_activity.state` não for `active`, a consulta mostrada em `pg_stat_activity` será a mais recente a terminar a execução. A sessão de bloqueio não está processando uma consulta ativamente porque uma transação aberta está mantendo um bloqueio.

Se uma transação ociosa adquiriu um bloqueio em nível de linha, talvez ela esteja impedindo que outras sessões o adquiram. Essa condição leva à ocorrência frequente do evento de espera `Lock:transactionid`. Para diagnosticar o problema, examine a saída proveniente de `pg_stat_activity` e `pg_locks`.

### Transações de longa execução
<a name="apg-waits.locktransactionid.long-running"></a>

Transações executadas por um longo tempo recebem bloqueios por um longo tempo. Esses bloqueios de longa duração podem impedir que outras transações sejam executadas.

## Ações
<a name="apg-waits.locktransactionid.actions"></a>

O bloqueio de linhas é um conflito entre instruções `UPDATE`, `SELECT … FOR UPDATE` ou `SELECT … FOR KEY SHARE`. Antes de tentar uma solução, descubra quando essas instruções estão sendo executadas na mesma linha. Use essas informações para escolher uma estratégia descrita nas seguintes seções.

**Topics**
+ [Responder a alta simultaneidade](#apg-waits.locktransactionid.actions.problem)
+ [Responder a transações ociosas](#apg-waits.locktransactionid.actions.find-blocker)
+ [Responder a transações de longa duração](#apg-waits.locktransactionid.actions.concurrency)

### Responder a alta simultaneidade
<a name="apg-waits.locktransactionid.actions.problem"></a>

Se a simultaneidade for o problema, tente uma das seguintes técnicas:
+ Reduza a simultaneidade na aplicação. Por exemplo, reduza o número de sessões ativas.
+ Implemente um pool de conexões. Para saber como agrupar conexões com o RDS Proxy, consulte [Amazon RDS Proxypara Aurora](rds-proxy.md).
+ Projete a aplicação ou o modelo de dados para evitar a contenção de instruções `UPDATE` e `SELECT … FOR UPDATE`. Também é possível diminuir o número de chaves estrangeiras acessadas por instruções `SELECT … FOR KEY SHARE`.

### Responder a transações ociosas
<a name="apg-waits.locktransactionid.actions.find-blocker"></a>

Se `pg_stat_activity.state` mostrar `idle in transaction`, utilize as seguintes estratégias:
+ Ative a confirmação automática sempre que possível. Essa abordagem impede que transações bloqueiem outras transações enquanto aguardam `COMMIT` ou `ROLLBACK`.
+ Procure caminhos de código que não contenham `COMMIT`, `ROLLBACK` ou `END`.
+ Assegure-se de que a lógica de tratamento de exceções na seu aplicação sempre tenha um caminho para um válido `end of transaction`.
+ Assegure-se de que a sua aplicação processe os resultados da consulta depois de encerrar a transação com `COMMIT` ou `ROLLBACK`.

### Responder a transações de longa duração
<a name="apg-waits.locktransactionid.actions.concurrency"></a>

Se transações de longa duração estiverem causando a ocorrência frequente de `Lock:transactionid`, tente as estratégias a seguir:
+ Mantenha os bloqueios de linha fora de transações de longa execução.
+ Limite o comprimento das consultas implementando a confirmação automática sempre que possível.

# Lock:tuple
<a name="apg-waits.locktuple"></a>

O evento `Lock:tuple` ocorre quando um processo de backend está aguardando para adquirir um bloqueio em uma tupla.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.locktuple.context.supported)
+ [Contexto](#apg-waits.locktuple.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.locktuple.causes)
+ [Ações](#apg-waits.locktuple.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.locktuple.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.locktuple.context"></a>

O evento `Lock:tuple` indica que um backend está aguardando para adquirir um bloqueio em uma tupla enquanto outro backend mantém um bloqueio conflitante na mesma tupla. A tabela a seguir ilustra um cenário em que as sessões geram o evento `Lock:tuple`.


|  Tempo  |  Sessão 1  |  Sessão 2  |  Sessão 3  | 
| --- | --- | --- | --- | 
|  t1  |  Inicia uma transação.  |    |    | 
|  t2  |  Atualiza a linha 1.  |    |    | 
|  t3  |    |  Atualiza a linha 1. A sessão adquire um bloqueio exclusivo na tupla e aguarda a sessão 1 liberar esse bloqueio via confirmação ou reversão.  |    | 
|  t4  |    |    |  Atualiza a linha 1. A sessão aguarda a sessão 2 liberar o bloqueio exclusivo na tupla.  | 

Outra alternativa é simular esse evento de espera utilizando a ferramenta de benchmarking `pgbench`. Configure um número elevado de sessões simultâneas para atualizar a mesma linha em uma tabela com um arquivo SQL personalizado.

Para saber mais sobre modos de bloqueio conflitantes, consulte o tópico sobre [Bloqueio explícito](https://www.postgresql.org/docs/current/explicit-locking.html), na documentação do PostgreSQL. Para saber mais sobre `pgbench`, consulte [pgbench](https://www.postgresql.org/docs/current/pgbench.html) na documentação do PostgreSQL.

## Possíveis causas do maior número de esperas
<a name="apg-waits.locktuple.causes"></a>

Quando esse evento aparece mais que o normal, possivelmente indicando um problema de performance, as causas típicas incluem:
+ Um número elevado de sessões simultâneas está tentando adquirir um bloqueio conflitante para a mesma tupla executando instruções `UPDATE` ou `DELETE`.
+ Sessões altamente simultâneas estão executando uma instrução `SELECT` utilizando os modos de bloqueio `FOR UPDATE` ou `FOR NO KEY UPDATE`.
+ Diversos fatores fazem com que grupos de aplicações ou conexões abram mais sessões para executar as mesmas operações. À medida que novas sessões estão tentando modificar as mesmas linhas, a carga de banco de dados pode atingir picos e `Lock:tuple` pode surgir.

Para obter mais informações, consulte o tópico sobre [Bloqueios em nível de linha](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS), na documentação do PostgreSQL.

## Ações
<a name="apg-waits.locktuple.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Investigar a lógica da sua aplicação](#apg-waits.locktuple.actions.problem)
+ [Localizar a sessão bloqueadora](#apg-waits.locktuple.actions.find-blocker)
+ [Reduzir a simultaneidade quando ela estiver elevada](#apg-waits.locktuple.actions.concurrency)
+ [Solucionar problemas de gargalos](#apg-waits.locktuple.actions.bottlenecks)

### Investigar a lógica da sua aplicação
<a name="apg-waits.locktuple.actions.problem"></a>

Descubra se uma sessão bloqueadora está no estado `idle in transaction` por muito tempo. Em caso positivo, considere encerrar a sessão bloqueadora como uma solução de curto prazo. Também é possível utilizar a função `pg_terminate_backend`. Para obter mais informações sobre essa função, consulte [Funções de sinalização de servidor](https://www.postgresql.org/docs/13/functions-admin.html#FUNCTIONS-ADMIN-SIGNAL), na documentação do PostgreSQL.

Para uma solução de longo prazo, faça o seguinte:
+ Ajuste a lógica da aplicação.
+ Use o parâmetro `idle_in_transaction_session_timeout`. Esse parâmetro encerra qualquer sessão com uma transação aberta que tenha ficado ociosa por um tempo maior que o especificado. Para obter mais informações, consulte o tópico sobre [Padrões de conexão de clientes](https://www.postgresql.org/docs/current/runtime-config-client.html#GUC-IDLE-IN-TRANSACTION-SESSION-TIMEOUT), na documentação do PostgreSQL.
+ Use a confirmação automática o máximo possível. Para obter mais informações, consulte [SET AUTOCOMMIT](https://www.postgresql.org/docs/current/ecpg-sql-set-autocommit.html), na documentação do PostgreSQL.

### Localizar a sessão bloqueadora
<a name="apg-waits.locktuple.actions.find-blocker"></a>

Enquanto o evento de espera `Lock:tuple` está ocorrendo, identifique a sessão bloqueadora e a sessão bloqueada descobrindo quais bloqueios dependem um do outro. Para obter mais informações, consulte o tópico sobre [Informações de dependências de bloqueios](https://wiki.postgresql.org/wiki/Lock_dependency_information), na wiki do PostgreSQL. Para analisar eventos `Lock:tuple` passados, utilize a função do Aurora `aurora_stat_backend_waits`. 

O exemplo a seguir consulta todas as sessões, filtrando em `tuple` e ordenando por `wait_time`.

```
--AURORA_STAT_BACKEND_WAITS
      SELECT a.pid, 
             a.usename, 
             a.app_name, 
             a.current_query,
             a.current_wait_type, 
             a.current_wait_event, 
             a.current_state, 
             wt.type_name AS wait_type, 
             we.event_name AS wait_event, 
             a.waits, 
             a.wait_time
        FROM (SELECT pid, 
                     usename, 
                     left(application_name,16) AS app_name,
                     coalesce(wait_event_type,'CPU') AS current_wait_type,
                     coalesce(wait_event,'CPU') AS current_wait_event, 
                     state AS current_state,
                     left(query,80) as current_query,
                     (aurora_stat_backend_waits(pid)).* 
                FROM pg_stat_activity 
               WHERE pid <> pg_backend_pid()
                 AND usename<>'rdsadmin') a
NATURAL JOIN aurora_stat_wait_type() wt 
NATURAL JOIN aurora_stat_wait_event() we
WHERE we.event_name = 'tuple'
    ORDER BY a.wait_time;

  pid  | usename | app_name |                 current_query                  | current_wait_type | current_wait_event | current_state | wait_type | wait_event | waits | wait_time
-------+---------+----------+------------------------------------------------+-------------------+--------------------+---------------+-----------+------------+-------+-----------
 32136 | sys     | psql     | /*session3*/ update tab set col=1 where col=1; | Lock              | tuple              | active        | Lock      | tuple      |     1 |   1000018
 11999 | sys     | psql     | /*session4*/ update tab set col=1 where col=1; | Lock              | tuple              | active        | Lock      | tuple      |     1 |   1000024
```

### Reduzir a simultaneidade quando ela estiver elevada
<a name="apg-waits.locktuple.actions.concurrency"></a>

O evento `Lock:tuple` pode ocorrer constantemente, especialmente em um tempo de workload ocupado. Nessa situação, considere reduzir a simultaneidade elevada para linhas muito ocupadas. Várias vezes, apenas algumas linhas controlam uma fila ou a lógica booleana, o que torna essas linhas muito ocupadas.

Você pode reduzir a simultaneidade utilizando diferentes abordagens com base no seu requisito de negócios, na lógica da aplicação e no tipo de workload. Por exemplo, você pode fazer o seguinte:
+ Reformule sua tabela e a lógica de dados para reduzir a simultaneidade elevada.
+ Altere a lógica da aplicação para reduzir a simultaneidade elevada no nível da linha.
+ Aproveite e reformule consultas com bloqueios em nível de linha.
+ Use a cláusula `NOWAIT` com operações de novas tentativas.
+ Considere utilizar o controle de simultaneidade lógico otimista e bloqueio híbrido.
+ Considere modificar o nível de isolamento do banco de dados.

### Solucionar problemas de gargalos
<a name="apg-waits.locktuple.actions.bottlenecks"></a>

O `Lock:tuple` pode ocorrer com gargalos, como falta de CPU ou uso máximo da largura de banda do Amazon EBS. Para diminuir gargalos, considere as seguintes abordagens:
+ Aumente a escala do seu tipo de classe de instância na vertical.
+ Otimize consultas que consomem muitos recursos.
+ Altere a lógica da aplicação.
+ Arquive dados acessados raramente.

# LWLock:buffer\$1content (BufferContent)
<a name="apg-waits.lockbuffercontent"></a>

O evento `LWLock:buffer_content` ocorre quando uma sessão aguarda para ler ou gravar uma página de dados na memória enquanto outra sessão fica com a página bloqueada para gravação. No Aurora PostgreSQL 13 e versões superiores, esse evento de espera é chamado de `BufferContent`.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.lockbuffercontent.context.supported)
+ [Contexto](#apg-waits.lockbuffercontent.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.lockbuffercontent.causes)
+ [Ações](#apg-waits.lockbuffercontent.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.lockbuffercontent.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.lockbuffercontent.context"></a>

Para ler ou manipular dados, o PostgreSQL os acessa por meio de buffers de memória compartilhada. Para ler a partir do buffer, um processo obtém um bloqueio leve (LWLock) no conteúdo do buffer no modo compartilhado. Para gravar no buffer, ele adquire esse bloqueio no modo exclusivo. Bloqueios compartilhados permitem que outros processos adquiram bloqueios compartilhados simultaneamente nesse conteúdo. Bloqueios exclusivos impedem que outros processos obtenham qualquer tipo de bloqueio nele.

O evento `LWLock:buffer_content` (`BufferContent`) indica que vários processos estão tentando obter bloqueios leves (LWLocks) no conteúdo de um buffer específico.

## Possíveis causas do maior número de esperas
<a name="apg-waits.lockbuffercontent.causes"></a>

Quando o evento `LWLock:buffer_content` (`BufferContent`) aparece mais que o normal, possivelmente indicando um problema de performance, as causas típicas incluem:

**Maior número de atualizações simultâneas para os mesmos dados**  
Pode haver um aumento no número de sessões simultâneas com consultas que atualizam o mesmo conteúdo do buffer. Essa contenção pode ser mais evidente em tabelas com vários índices.

**Os dados da workload não estão na memória**  
Quando os dados que a workload ativa está processando não estão na memória, esses eventos de espera podem aumentar. Esse efeito ocorre porque os processos que mantêm bloqueios podem fazer isso por mais tempo enquanto executam operações de E/S de disco.

**Uso excessivo de restrições de chaves externas**  
Restrições de chave externas podem aumentar o tempo durante o qual um processo mantém um bloqueio de conteúdo de buffer. Esse efeito ocorre porque operações de leitura exigem um bloqueio de conteúdo de buffer compartilhado na chave referenciada enquanto esta está sendo atualizada.

## Ações
<a name="apg-waits.lockbuffercontent.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera. Você pode identificar eventos `LWLock:buffer_content` (`BufferContent`) utilizando o Amazon RDS Performance Insights ou consultando a visualização `pg_stat_activity`.

**Topics**
+ [Melhorar a eficiência na memória](#apg-waits.lockbuffercontent.actions.in-memory)
+ [Reduzir o uso de restrições de chaves externas](#apg-waits.lockbuffercontent.actions.foreignkey)
+ [Remover índices não utilizados](#apg-waits.lockbuffercontent.actions.indexes)
+ [Remover índices duplicados](#apg-waits.lockbuffercontent.actions.duplicate-indexes)
+ [Excluir ou REINDEXAR índices inválidos](#apg-waits.lockbuffercontent.actions.invalid-indexes)
+ [Usar índices parciais](#apg-waits.lockbuffercontent.actions.partial-indexes)
+ [Remover o inchaço de tabelas e índices](#apg-waits.lockbuffercontent.actions.bloat)

### Melhorar a eficiência na memória
<a name="apg-waits.lockbuffercontent.actions.in-memory"></a>

Para aumentar as chances de que os dados da workload ativa estejam na memória, particione tabelas ou aumente a escala da sua classe de instância na vertical. Para obter informações sobre classes de instância de banco de dados, consulte [Classes de instâncias de banco de dados do Amazon Aurora](Concepts.DBInstanceClass.md).

Monitore a métrica `BufferCacheHitRatio`, que mede a porcentagem de solicitações atendidas pelo cache do buffer de uma instância de banco de dados em seu cluster de banco de dados. Essa métrica fornece insights sobre a quantidade de dados que estão sendo obtidos da memória. Uma alta taxa de acerto indica que a instância de banco de dados tem memória suficiente disponível para seu conjunto de dados de trabalho, enquanto uma taxa baixa sugere que suas consultas acessam dados do armazenamento com frequência.

O acerto de leitura do cache por tabela e o acerto de leitura do cache por índice na seção de configuração de memória do relatório do [PG Collector](https://github.com/awslabs/pg-collector) podem fornecer insights sobre a taxa de acerto do cache de tabelas e índices.

### Reduzir o uso de restrições de chaves externas
<a name="apg-waits.lockbuffercontent.actions.foreignkey"></a>

Investigue workloads com um número elevado de eventos de espera `LWLock:buffer_content` (`BufferContent`) quanto ao uso de restrições de chaves externas. Remova restrições desnecessárias de chaves externas.

### Remover índices não utilizados
<a name="apg-waits.lockbuffercontent.actions.indexes"></a>

Para workloads com um número elevado de eventos de espera `LWLock:buffer_content` (`BufferContent`), identifique índices não utilizados e remova-os.

A seção de índices não utilizados do relatório do [PG Collector](https://github.com/awslabs/pg-collector) pode fornecer insights sobre os índices não utilizados no banco de dados.

### Remover índices duplicados
<a name="apg-waits.lockbuffercontent.actions.duplicate-indexes"></a>

Identifique índices duplicados e remova-os.

A seção de índices duplicados do relatório do [PG Collector](https://github.com/awslabs/pg-collector) pode fornecer insights sobre os índices duplicados no banco de dados.

### Excluir ou REINDEXAR índices inválidos
<a name="apg-waits.lockbuffercontent.actions.invalid-indexes"></a>

Os índices inválidos geralmente se apresentam ao usar `CREATE INDEX CONCURRENTLY` ou `REINDEX CONCURRENTLY` e quando o comando falha ou é cancelado.

Embora esses índices não possam ser usados para consultas, eles serão atualizados e ocuparão espaço em disco.

A seção de índices inválidos do relatório do [PG Collector](https://github.com/awslabs/pg-collector) pode fornecer insights sobre os índices inválidos no banco de dados.

### Usar índices parciais
<a name="apg-waits.lockbuffercontent.actions.partial-indexes"></a>

Os índices parciais podem ser aproveitados para aprimorar o desempenho da consulta e reduzir o tamanho do índice. Um índice parcial é um índice criado sobre um subconjunto de uma tabela definido por uma expressão condicional. Conforme detalhado na documentação do [índice parcial](https://www.postgresql.org/docs/current/indexes-partial.html), os índices parciais podem reduzir os custos indiretos de manutenção de índices, pois o PostgreSQL não precisa atualizar o índice em todos os casos.

### Remover o inchaço de tabelas e índices
<a name="apg-waits.lockbuffercontent.actions.bloat"></a>

O inchaço de tabelas e índices pode afetar negativamente o desempenho do banco de dados. Tabelas e índices grandes demais aumentam o tamanho do conjunto de trabalho ativo, degradando a eficiência na memória. Além disso, o inchaço aumenta os custos de armazenamento e causa lentidão na execução de consultas. Para diagnosticar inchaços, consulte [Diagnosticar a sobrecarga na tabela e no índice](AuroraPostgreSQL.diag-table-ind-bloat.md). Além disso, a seção de fragmentação (inchaço) do relatório do [PG Collector](https://github.com/awslabs/pg-collector) pode fornecer insights sobre o inchaço de tabelas e índices.

Para lidar com o inchaço de tabelas e índices, há algumas opções:

**VACUUM FULL**  
`VACUUM FULL` cria uma cópia da tabela, copiando somente as tuplas ativas e, em seguida, substitui a tabela antiga pela nova enquanto mantém um bloqueio `ACCESS EXCLUSIVE`. Isso evita qualquer leitura ou gravação na tabela, o que pode causar uma interrupção. Além disso, `VACUUM FULL` levará mais tempo se a tabela for grande.

** pg\$1repack **  
O `pg_repack` é útil em situações em que `VACUUM FULL` talvez não seja adequado. Ele cria uma tabela que contém os dados da tabela inchada, monitora as alterações na tabela original e, em seguida, substitui a tabela original pela nova. Ele não bloqueia a tabela original para operações de leitura ou gravação enquanto está criando a outra tabela. Para ter mais informações sobre como usar `pg_repack`, consulte [Removing bloat with pg\$1repack](https://docs.aws.amazon.com/prescriptive-guidance/latest/postgresql-maintenance-rds-aurora/pg-repack.html) e [pg\$1repack](https://reorg.github.io/pg_repack/).

**REINDEX**  
O comando `REINDEX` pode ser usado para lidar com o inchaço do índice. `REINDEX` grava uma nova versão do índice sem as páginas inativas ou as páginas vazias ou quase vazias, reduzindo assim o consumo de espaço do índice. Para ter informações detalhadas sobre o comando [https://www.postgresql.org/docs/current/sql-reindex.html](https://www.postgresql.org/docs/current/sql-reindex.html), consulte a documentação do REINDEX.

Depois de remover o inchaço das tabelas e índices, pode ser necessário aumentar a frequência de autovacuum nessas tabelas. A implementação de configurações agressivas de autovacuum em nível de tabela pode ajudar a evitar a ocorrência de futuros inchaços. Para ter mais informações, consulte a documentação em [https://docs.aws.amazon.com/prescriptive-guidance/latest/postgresql-maintenance-rds-aurora/autovacuum.html](https://docs.aws.amazon.com/prescriptive-guidance/latest/postgresql-maintenance-rds-aurora/autovacuum.html).

# LWLock:buffer\$1mapping
<a name="apg-waits.lwl-buffer-mapping"></a>

Esse evento ocorre quando uma sessão está aguardando para associar um bloco de dados a um buffer no grupo de buffer compartilhado.

**nota**  
Esse evento aparece como `LWLock:buffer_mapping` no Aurora PostgreSQL versão 12 e inferiores e como `LWLock:BufferMapping` na versão 13 e superiores.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.lwl-buffer-mapping.context.supported)
+ [Contexto](#apg-waits.lwl-buffer-mapping.context)
+ [Causas](#apg-waits.lwl-buffer-mapping.causes)
+ [Ações](#apg-waits.lwl-buffer-mapping.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.lwl-buffer-mapping.context.supported"></a>

As informações sobre eventos de espera são relevantes para o Aurora PostgreSQL versão 9.6 e versões superiores.

## Contexto
<a name="apg-waits.lwl-buffer-mapping.context"></a>

O *grupo de buffer compartilhado* é uma área de memória do Aurora PostgreSQL que contém todas as páginas que estão ou estavam sendo utilizadas por processos. Quando um processo precisa de uma página, ele lê a página no grupo de buffer compartilhado. O parâmetro `shared_buffers` define o tamanho do buffer compartilhado e reserva uma área de memória para armazenar a tabela e as páginas de índice. Se você alterar esse parâmetro, assegure-se de reiniciar o banco de dados. Para obter mais informações, consulte [Buffers compartilhados](AuroraPostgreSQL.Tuning.concepts.md#AuroraPostgreSQL.Tuning.concepts.buffer-pool).

O evento de espera `LWLock:buffer_mapping` ocorre nos seguintes cenários:
+ Um processo pesquisa a tabela de buffer em busca de uma página e adquire um bloqueio de mapeamento de buffer compartilhado.
+ Um processo carrega uma página no grupo de buffer e adquire um bloqueio exclusivo de mapeamento de buffer.
+ Um processo remove uma página do grupo e adquire um bloqueio exclusivo de mapeamento de buffer.

## Causas
<a name="apg-waits.lwl-buffer-mapping.causes"></a>

Quando esse evento aparece mais do que o normal, possivelmente indicando um problema de performance, o banco de dados está paginando dentro e fora do grupo de buffer compartilhado. As causas típicas incluem:
+ Consultas grandes
+ Índices e tabelas inchados
+ Varreduras completas de tabelas
+ Um tamanho de grupo compartilhado menor que o conjunto de trabalho

## Ações
<a name="apg-waits.lwl-buffer-mapping.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Monitorar métricas relacionadas ao buffer](#apg-waits.lwl-buffer-mapping.actions.monitor-metrics)
+ [Avaliar sua estratégia de indexação](#apg-waits.lwl-buffer-mapping.actions.indexes)
+ [Diminuir o número de buffers que devem ser alocados rapidamente](#apg-waits.lwl-buffer-mapping.actions.buffers)

### Monitorar métricas relacionadas ao buffer
<a name="apg-waits.lwl-buffer-mapping.actions.monitor-metrics"></a>

Quando as esperas `LWLock:buffer_mapping` atingirem picos, investigue a taxa de acertos de buffer. É possível utilizar essas métricas para entender melhor o que está acontecendo no cache de buffer. Examine as métricas a seguir:

`BufferCacheHitRatio`  
Essa métrica do Amazon CloudWatch mede a porcentagem de solicitações atendidas pelo cache de buffer de uma instância de banco de dados no seu cluster de banco de dados. Você pode ver essa métrica diminuir na preparação para o evento de espera `LWLock:buffer_mapping`.

`blks_hit`  
Essa métrica de contador do Performance Insights indica o número de bloqueios que foram recuperados do grupo de buffer compartilhado. Após o surgimento do evento de espera `LWLock:buffer_mapping`, é possível observar um pico em `blks_hit`.

`blks_read`  
Essa métrica de contador do Performance Insights indica o número de bloqueios que exigiram a leitura da E/S no grupo de buffer compartilhado. Você pode observar um pico em `blks_read` em preparação para o evento de espera `LWLock:buffer_mapping`.

### Avaliar sua estratégia de indexação
<a name="apg-waits.lwl-buffer-mapping.actions.indexes"></a>

Para confirmar que sua estratégia de indexação não está diminuindo a performance, verifique o seguinte:

Inchaço de índice  
Assegure-se de que o índice e o inchaço da tabela não estejam fazendo com que páginas desnecessárias sejam lidas no buffer compartilhado. Se as suas tabelas contiverem linhas não utilizadas, considere arquivar os dados e remover as linhas das tabelas. Em seguida, você poderá reconstruir os índices para as tabelas redimensionadas.

Índices para consultas utilizadas com frequência  
Para determinar se você tem os índices ideais, monitore as métricas do mecanismo de banco de dados no Performance Insights. A métrica `tup_returned` mostra o número de linhas lidas. A métrica `tup_fetched` mostra o número de linhas retornadas ao cliente. Se `tup_returned` for significativamente maior que `tup_fetched`, talvez os dados não estejam devidamente indexados. Além disso, as estatísticas da tabela podem não estar atualizadas.

### Diminuir o número de buffers que devem ser alocados rapidamente
<a name="apg-waits.lwl-buffer-mapping.actions.buffers"></a>

Para diminuir os eventos de espera `LWLock:buffer_mapping`, tente reduzir o número de buffers que devem ser alocados rapidamente. Uma estratégia é realizar operações em lote menores. Talvez seja possível obter lotes menores particionando tabelas.

# LWLock:BufferIO (IPC:BufferIO)
<a name="apg-waits.lwlockbufferio"></a>

O evento `LWLock:BufferIO` ocorre quando o Aurora PostgreSQL ou o RDS for PostgreSQL aguarda outros processos terminarem suas operações de entrada/saída (E/S) ao tentarem acessar simultaneamente uma página. Sua finalidade é fazer com que a mesma página seja lida no buffer compartilhado.

**Topics**
+ [Versões de mecanismos relevantes](#apg-waits.lwlockbufferio.context.supported)
+ [Contexto](#apg-waits.lwlockbufferio.context)
+ [Causas](#apg-waits.lwlockbufferio.causes)
+ [Ações](#apg-waits.lwlockbufferio.actions)

## Versões de mecanismos relevantes
<a name="apg-waits.lwlockbufferio.context.supported"></a>

Essas informações de evento de espera são relevantes para todas as versões do Aurora PostgreSQL. Para o Aurora PostgreSQL 12 e versões anteriores, esse evento de espera é denominado lwlock:buffer\$1io, ao passo que, no Aurora PostgreSQL versão 13, é denominado lwlock:bufferio. A partir do Aurora PostgreSQL versão 14, o evento de espera BufferIO foi movido do tipo de evento de espera `LWLock` para `IPC` (IPC:BufferIO). 

## Contexto
<a name="apg-waits.lwlockbufferio.context"></a>

Cada buffer compartilhado tem um bloqueio de E/S associado ao evento de espera `LWLock:BufferIO`, todas as vezes que um bloqueio (ou uma página) precisa ser recuperado fora do grupo de buffer compartilhado.

Esse bloqueio é utilizado para lidar com várias sessões que requerem acesso ao mesmo bloco. Esse bloco precisa ser lido de fora do grupo de buffer compartilhado, definido pelo parâmetro `shared_buffers`.

Assim que a página for lida dentro do grupo de buffer compartilhado, o bloqueio de `LWLock:BufferIO` será liberado.

**nota**  
O evento de espera `LWLock:BufferIO` precede o evento de espera [IO:DataFileRead](apg-waits.iodatafileread.md). O evento de espera `IO:DataFileRead` ocorre enquanto os dados estão sendo lidos do armazenamento.

Para obter mais informações sobre bloqueios leves, consulte [Visão geral de bloqueios](https://github.com/postgres/postgres/blob/65dc30ced64cd17f3800ff1b73ab1d358e92efd8/src/backend/storage/lmgr/README#L20).

## Causas
<a name="apg-waits.lwlockbufferio.causes"></a>

Causas comuns do surgimento do evento `LWLock:BufferIO` nas principais esperas incluem:
+ Vários backends ou conexões tentando acessar a mesma página para a qual também há uma operação de E/S pendente
+ A proporção entre o tamanho do grupo de buffer compartilhado (definido pelo parâmetro `shared_buffers`) e o número de buffers necessários para a workload atual
+ O tamanho do grupo de buffer compartilhado não está bem equilibrado com o número de páginas que estão sendo despejadas por outras operações
+ Índices grandes ou inchados que exigem que o mecanismo leia mais páginas que o necessário no grupo de buffer compartilhado
+ Ausência índices, o que força o mecanismo de banco de dados a ler mais páginas das tabelas que o necessário
+ Picos repentinos de conexões de banco de dados tentando realizar operações na mesma página

## Ações
<a name="apg-waits.lwlockbufferio.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera:
+ Observe as métricas do Amazon CloudWatch para encontrar uma correlação entre reduções acentuadas nos eventos de espera `BufferCacheHitRatio` e `LWLock:BufferIO`. Esse efeito pode significar que existe uma pequena configuração de buffers compartilhados. Talvez seja necessário aumentá-lo ou aumentar a escala da classe de instância de banco de dados na vertical. Você pode dividir sua workload em mais nós de leitura.
+ Verifique se existem índices não utilizados e remova-os.
+ Use tabelas particionadas (que também tenham índices particionados). Fazer isso ajuda a manter a reordenação do índice baixo e reduz seu impacto.
+ Evite indexar colunas desnecessariamente.
+ Evite picos repentinos de conexão de banco de dados utilizando um grupo de conexões.
+ Restrinja o número máximo de conexões com o banco de dados como prática recomendada.

# LWLock:lock\$1manager
<a name="apg-waits.lw-lock-manager"></a>

Esse evento ocorre quando o mecanismo Aurora PostgreSQL mantém a área de memória do bloqueio compartilhado para alocar, verificar e desalocar um bloqueio nos casos em que um bloqueio de caminho rápido não é possível.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.lw-lock-manager.context.supported)
+ [Contexto](#apg-waits.lw-lock-manager.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.lw-lock-manager.causes)
+ [Ações](#apg-waits.lw-lock-manager.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.lw-lock-manager.context.supported"></a>

As informações sobre eventos de espera são relevantes para o Aurora PostgreSQL versão 9.6 e versões superiores. 

## Contexto
<a name="apg-waits.lw-lock-manager.context"></a>

Quando você emite uma instrução SQL, o Aurora PostgreSQL registra bloqueios para proteger a estrutura, os dados e a integridade do banco de dados durante operações simultâneas. O mecanismo pode atingir esse objetivo utilizando um bloqueio de caminho rápido ou um bloqueio de caminho que não é rápido. Um bloqueio de caminho que não é rápido é mais caro e gera mais sobrecarga do que um bloqueio de caminho rápido.

### Bloqueio de caminho rápido
<a name="apg-waits.lw-lock-manager.context.fast-path"></a>

Para reduzir a sobrecarga de bloqueios que são retirados e liberados com frequência, mas que raramente entram em conflito, os processos de backend podem utilizar o bloqueio de caminho rápido. O banco de dados usa esse mecanismo para bloqueios que atendem aos seguintes critérios:
+ Usam o método de bloqueio DEFAULT.
+ Representam um bloqueio em uma relação de banco de dados em vez de uma relação compartilhada.
+ São bloqueios fracos que provavelmente não entrarão em conflito.
+ O mecanismo é capaz de verificar rapidamente se nenhum bloqueio conflitante pode existir.

O mecanismo não pode utilizar o bloqueio rápido de caminho quando uma das seguintes condições é verdadeira:
+ O bloqueio não atende aos critérios anteriores.
+ Não há mais slots disponíveis para o processo de backend.

Para obter mais informações sobre o bloqueio de caminho rápido, consulte o tópico sobre [caminho rápido](https://github.com/postgres/postgres/blob/master/src/backend/storage/lmgr/README#L70-L76), no README do gerenciador de bloqueios do PostgreSQL e[pg-locks](https://www.postgresql.org/docs/15/view-pg-locks.html) na documentação do PostgreSQL. 

### Exemplo de um problema de escalabilidade para o gerenciador de bloqueios
<a name="apg-waits.lw-lock-manager.context.lock-manager"></a>

Neste exemplo, uma tabela chamada `purchases` armazena cinco anos de dados, particionados por dia. Cada partição possui dois índices. A seguinte sequência de eventos ocorre:

1. Você consulta muitos dias de dados, o que exige que o banco de dados leia várias partições.

1. O banco de dados cria uma entrada de bloqueio para cada partição. Se os índices de partição fizerem parte do caminho de acesso do otimizador, o banco de dados também criará uma entrada de bloqueio para eles.

1. Quando o número de entradas de bloqueios solicitadas para o mesmo processo de backend for maior que 16, que é o valor de `FP_LOCK_SLOTS_PER_BACKEND`, o gerenciador de bloqueio usará o método de bloqueio de caminho não rápido.

Aplicações modernas podem ter centenas de sessões. Se sessões simultâneas estiverem consultando o pai sem a devida limpeza da partição, o banco de dados poderá criar centenas ou até milhares de bloqueios de caminho não rápidos. Em geral, quando essa simultaneidade é maior que o número de vCPUs, o evento de espera `LWLock:lock_manager` é exibido.

**nota**  
O evento de espera `LWLock:lock_manager` não está relacionado ao número de partições ou índices em um esquema de banco de dados e sim ao número de bloqueios de caminho não rápidos que o banco de dados deve controlar.

## Possíveis causas do maior número de esperas
<a name="apg-waits.lw-lock-manager.causes"></a>

Quando o evento de espera `LWLock:lock_manager` ocorre mais do que o normal, possivelmente indicando um problema de performance, as causas mais prováveis de picos súbitos são:
+ Sessões ativas simultâneas estão executando consultas que não utilizam bloqueios de caminho rápido. Essas sessões também excedem a vCPU máxima.
+ Um número elevado de sessões ativas simultâneas está acessando uma tabela fortemente particionada. Cada partição possui vários índices.
+ O banco de dados está passando por uma tempestade de conexões. Por padrão, algumas aplicações e softwares de grupo de conexões criam mais conexões quando o banco de dados está lento. Essa prática piora o problema. Ajuste o software do grupo de conexões para que tempestades de conexões não ocorram.
+ Um número elevado de sessões consulta uma tabela pai sem separar partições.
+ Um comando de linguagem de definição de dados (DDL), linguagem de manipulação de dados (DML) ou manutenção bloqueia exclusivamente uma relação ocupada ou tuplas que são frequentemente acessadas ou modificadas.

## Ações
<a name="apg-waits.lw-lock-manager.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera.

**Topics**
+ [Usar a limpeza de partição](#apg-waits.lw-lock-manager.actions.pruning)
+ [Remover índices desnecessários](#apg-waits.lw-lock-manager.actions.indexes)
+ [Ajustar suas consultas para bloqueio de caminho rápido](#apg-waits.lw-lock-manager.actions.tuning)
+ [Fazer ajustes com base em eventos de espera](#apg-waits.lw-lock-manager.actions.other-waits)
+ [Reduzir gargalos de hardware](#apg-waits.lw-lock-manager.actions.hw-bottlenecks)
+ [Usar um agrupador de conexões](#apg-waits.lw-lock-manager.actions.pooler)
+ [Fazer upgrade da versão do Aurora PostgreSQL](#apg-waits.lw-lock-manager.actions.pg-version)

### Usar a limpeza de partição
<a name="apg-waits.lw-lock-manager.actions.pruning"></a>

*Limpeza de partição* é uma estratégia de otimização de consultas que exclui partições desnecessárias das varreduras de tabelas, melhorando assim a performance. Por padrão, a remoção de partição está ativada. Se ela estiver desativada, ative-a da seguinte maneira.

```
SET enable_partition_pruning = on;
```

As consultas podem tirar proveito da limpeza de partição quando suas cláusula `WHERE` contêm a coluna utilizada para o particionamento. Para obter mais informações, consulte o tópico sobre [Limpeza de partição](https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITION-PRUNING), na documentação do PostgreSQL.

### Remover índices desnecessários
<a name="apg-waits.lw-lock-manager.actions.indexes"></a>

Seu banco de dados pode conter índices não utilizados ou raramente utilizados. Se esse for o caso, considere excluí-los. Realize um dos procedimentos a seguir:
+ Saiba mais sobre como encontrar índices desnecessários lendo o tópico sobre [Índices não utilizados](https://wiki.postgresql.org/wiki/Index_Maintenance#Unused_Indexes) na wiki do PostgreSQL.
+ Execute o PG Collector. Esse script SQL reúne informações do banco de dados e as apresenta em um relatório HTML consolidado. Confira a seção “Índices não utilizados”. Para obter mais informações, consulte [pg-collector](https://github.com/awslabs/pg-collector) no Repositório AWS Labs GitHub.

### Ajustar suas consultas para bloqueio de caminho rápido
<a name="apg-waits.lw-lock-manager.actions.tuning"></a>

Para descobrir se as suas consultas usam o bloqueio de caminho rápido, consulte a coluna `fastpath` na tabela `pg_locks`. Se as suas consultas não estiverem utilizando o bloqueio de caminho rápido, tente reduzir o número de relações por consulta para menos de 16.

### Fazer ajustes com base em eventos de espera
<a name="apg-waits.lw-lock-manager.actions.other-waits"></a>

Se `LWLock:lock_manager` for o primeiro ou o segundo na lista de principais esperas, verifique se os seguintes eventos de espera também aparecem na lista:
+ `Lock:Relation`
+ `Lock:transactionid`
+ `Lock:tuple`

Se os eventos anteriores aparecerem em posição elevada na lista, considere ajustar esses eventos de espera primeiro. Esses eventos podem ser um fator impulsionador para `LWLock:lock_manager`.

### Reduzir gargalos de hardware
<a name="apg-waits.lw-lock-manager.actions.hw-bottlenecks"></a>

É possível que haja um gargalo de hardware, como falta de CPU ou uso máximo da largura de banda do Amazon EBS. Nesses casos, considere reduzir gargalos de hardware. Considere as ações a seguir:
+ Aumente a escala da sua classe de instância na vertical.
+ Otimize consultas que consomem grandes quantidades de CPU e memória.
+ Altere a lógica da aplicação.
+ Arquive os dados.

Para obter mais informações sobre CPU, memória e largura de banda da rede do EBS, consulte [Tipos de instâncias do Amazon RDS](https://aws.amazon.com/rds/instance-types/).

### Usar um agrupador de conexões
<a name="apg-waits.lw-lock-manager.actions.pooler"></a>

Se o número total de conexões ativas exceder o máximo de vCPU, mais processos do SO exigirão CPU do que o tipo de instância pode suportar. Nesse caso, considere utilizar ou ajustar um grupo de conexões. Para obter mais informações sobre as vCPUs para o seu tipo de instância, consulte o tópico sobre [Tipos de instância do Amazon RDS](https://aws.amazon.com/rds/instance-types/).

Para obter mais informações sobre agrupamento de conexões, consulte os seguintes recursos:
+ [Amazon RDS Proxypara Aurora](rds-proxy.md)
+ [pgbouncer](http://www.pgbouncer.org/usage.html)
+ [Grupos conexões e fontes de dados](https://www.postgresql.org/docs/7.4/jdbc-datasource.html), na *Documentação do PostgreSQL*

### Fazer upgrade da versão do Aurora PostgreSQL
<a name="apg-waits.lw-lock-manager.actions.pg-version"></a>

Se a versão atual do Aurora PostgreSQL for menor que 12, atualize para a versão 12 ou superior. As versões 12 e 13 do PostgreSQL possuem um mecanismo de partição aprimorado. Para obter mais informações sobre a versão 12, consulte [Notas de release do PostgreSQL 12.0]( https://www.postgresql.org/docs/release/12.0/). Para obter mais informações sobre como fazer upgrade do Aurora PostgreSQL, consulte [Atualizações do mecanismo de banco de dados do Amazon Aurora PostgreSQL](AuroraPostgreSQL.Updates.md).

# LWLock:MultiXact
<a name="apg-waits.lwlockmultixact"></a>

Os eventos de espera `LWLock:MultiXactMemberBuffer`, `LWLock:MultiXactOffsetBuffer`, `LWLock:MultiXactMemberSLRU` e `LWLock:MultiXactOffsetSLRU` indicam que uma sessão está aguardando para recuperar uma lista de transações que modificam a mesma linha em uma tabela específica. 
+ `LWLock:MultiXactMemberBuffer`: um processo está aguardando a E/S em um buffer utilizado com menos frequência (SLRU) para um membro multixact.
+ `LWLock:MultiXactMemberSLRU`: um processo está aguardando para acessar o cache utilizado com menos frequência (SLRU) para um membro multixact.
+ `LWLock:MultiXactOffsetBuffer`: um processo está aguardando a E/S em um buffer utilizado com menos frequência (SLRU) para um desvio multixact.
+ `LWLock:MultiXactOffsetSLRU`: um processo está aguardando para acessar o cache utilizado com menos frequência (SLRU) para um desvio multixact.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.xactsync.context.supported)
+ [Contexto](#apg-waits.lwlockmultixact.context)
+ [Possíveis causas do maior número de esperas](#apg-waits.lwlockmultixact.causes)
+ [Ações](#apg-waits.lwlockmultixact.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.xactsync.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Contexto
<a name="apg-waits.lwlockmultixact.context"></a>

*Multixact* é uma estrutura de dados que armazena uma lista de IDs de transação (XIDs) que modificam a mesma linha da tabela. Quando uma única transação faz referência a uma linha em uma tabela, o ID da transação é armazenado na linha de cabeçalho da tabela. Quando várias transações fazem referência à mesma linha em uma tabela, a lista de IDs de transação é armazenada na estrutura de dados multixact. Os eventos de espera multixact indicam que uma sessão está recuperando da estrutura de dados a lista de transações que se referem a uma determinada linha em uma tabela.

## Possíveis causas do maior número de esperas
<a name="apg-waits.lwlockmultixact.causes"></a>

Estas são três causas comuns para uso do multixact:
+ **Subtransações de pontos de salvamento explícitos**: a criação explícita de um ponto de salvamento nas transações gera novas transações para a mesma linha. Por exemplo, usando `SELECT FOR UPDATE`, `SAVEPOINT` e, então `UPDATE`. 

  Alguns drivers, mapeamentos de objetos relacionais (ORMs) e camadas de abstração têm opções de configuração para envolver automaticamente todas as operações com pontos de salvamento. Isso pode gerar muitos eventos de espera multiexact em algumas workloads. A opção `autosave` do driver JDBC do PostgreSQL é um exemplo disso. Para obter mais informações, consulte [pgJDBC](https://jdbc.postgresql.org/) na documentação do JDBC do PostgreSQL. Outro exemplo é o driver ODBC do PostgreSQL e sua opção `protocol`. Para obter mais informações, consulte [psqlODBC Configuration Options](https://odbc.postgresql.org/docs/config.html) (Opções de configuração do psqlODBC) na documentação do driver ODBC do PostgreSQL. 
+ **Subtransações de cláusulas EXCEPTION de PL/pgSQL**: cada cláusula `EXCEPTION` que você escreve em funções ou procedimentos de PL/pgSQL cria um `SAVEPOINT` interno.
+ **Chaves externas**: várias transações adquirem um bloqueio compartilhado no registro pai.

Quando uma determinada linha é incluída em uma operação de várias transações, o processamento da linha exige a recuperação de IDs de transação das listas `multixact`. Se as pesquisas não conseguirem obter o multixact do cache de memória, a estrutura de dados deverá ser lida da camada de armazenamento do Aurora. Essa E/S do armazenamento significa que as consultas de SQL podem demorar mais. As falhas no cache de memória podem começar a ocorrer com o uso intenso devido a um grande número de transações múltiplas. Todos esses fatores contribuem para o aumento desse evento de espera.

## Ações
<a name="apg-waits.lwlockmultixact.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera. Algumas dessas ações podem ajudar na redução imediata dos eventos de espera. Porém, outras podem precisar de investigação e correção para escalar a workload.

**Topics**
+ [Realizar a operação vacuum freeze nas tabelas com este evento de espera](#apg-waits.lwlockmultixact.actions.vacuumfreeze)
+ [Aumentar a frequência da limpeza automática das tabelas com esse evento de espera](#apg-waits.lwlockmultixact.actions.autovacuum)
+ [Aumentar os parâmetros de memória](#apg-waits.lwlockmultixact.actions.memoryparam)
+ [Reduzir transações de longa execução](#apg-waits.lwlockmultixact.actions.longtransactions)
+ [Ações de longo prazo](#apg-waits.lwlockmultixact.actions.longactions)

### Realizar a operação vacuum freeze nas tabelas com este evento de espera
<a name="apg-waits.lwlockmultixact.actions.vacuumfreeze"></a>

Se esse evento de espera aumentar repentinamente e afetar o ambiente de produção, você poderá usar qualquer um dos métodos temporários a seguir para reduzir a contagem.
+ Use *VACUUM FREEZE* na tabela ou na partição da tabela afetada para resolver o problema imediatamente. Para ter mais informações, consulte [VACUUM](https://www.postgresql.org/docs/current/sql-vacuum.html).
+ Use a cláusula VACUUM (FREEZE, INDEX\$1CLEANUP FALSE) para realizar uma limpeza rápida ignorando os índices. Para ter mais informações, consulte [Aspirar uma tabela o mais rápido possível](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.html#Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.Executing).

### Aumentar a frequência da limpeza automática das tabelas com esse evento de espera
<a name="apg-waits.lwlockmultixact.actions.autovacuum"></a>

Depois de verificar todas as tabelas em todos os bancos de dados, a operação VACUUM removerá multixacts, e os valores multixact mais antigos avançarão. Para ter mais informações, consulte [Multixacts e Wraparound](https://www.postgresql.org/docs/current/routine-vacuuming.html#VACUUM-FOR-MULTIXACT-WRAPAROUND). Para reduzir ao mínimo os eventos de espera LWLock:MultiXact, é necessário executar a operação VACUUM sempre que necessário. Para fazer isso, garanta que o VACUUM no cluster de banco de dados do Aurora PostgreSQL esteja configurado de forma ideal.

Se o uso de VACUUM FREEZE na tabela ou na partição da tabela afetada resolver o problema do evento de espera, recomendamos usar um programador, como o `pg_cron`, para realizar o VACUUM em vez de ajustar o autovacuum na instância. 

Para que o autovacuum ocorra com maior frequência, é possível reduzir o valor do parâmetro de armazenamento `autovacuum_multixact_freeze_max_age` na tabela afetada. Para ter mais informações, consulte [autovacuum\$1multixact\$1freeze\$1max\$1age](https://www.postgresql.org/docs/current/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MULTIXACT-FREEZE-MAX-AGE).

### Aumentar os parâmetros de memória
<a name="apg-waits.lwlockmultixact.actions.memoryparam"></a>

Você pode otimizar o uso da memória para caches multixact ajustando os seguintes parâmetros. Essas configurações controlam a quantidade de memória reservada para esses caches, o que pode ajudar a reduzir os eventos de espera multixact na workload. Recomendamos começar com os valores a seguir:

Para o Aurora PostgreSQL 17 e posterior:  
+ `multixact_offset_buffers` = 128
+ `multixact_member_buffers` = 256

Para o Aurora PostgreSQL 16 e posterior:  
+ `multixact_offsets_cache_size` = 128
+ `multixact_members_cache_size` = 256

**nota**  
No Aurora PostgreSQL 17, os nomes dos parâmetros foram alterados de `multixact_offsets_cache_size` para `multixact_offset_buffers` e de `multixact_members_cache_size` para `multixact_member_buffers` para se alinharem à comunidade do PostgreSQL 17.

É possível definir esses parâmetros no nível do cluster para que todas as instâncias do cluster permaneçam consistentes. Recomendamos que você teste e ajuste os valores para melhor atender aos requisitos específicos da workload e à classe de instância. É necessário reinicializar a instância do gravador para que a alteração do parâmetro tenha efeito.

Os parâmetros são expressos em termos de entradas de cache multixact. Cada entrada de cache usa `8 KB` de memória. Para calcular a memória total reservada, multiplique o valor de cada parâmetro por `8 KB`. Por exemplo, se você definir um parâmetro como 128, o total de memória reservada será `128 * 8 KB = 1 MB`.

### Reduzir transações de longa execução
<a name="apg-waits.lwlockmultixact.actions.longtransactions"></a>

Transações de longa duração fazem com que o vácuo retenha as informações até que a transação seja confirmada ou até que a transação somente leitura seja fechada. Recomendamos que você monitore e gerencie transações de longa duração de maneira proativa. Para obter mais informações, consulte [O banco de dados está inativo há muito tempo na conexão da transação](PostgreSQL.Tuning_proactive_insights.md#proactive-insights.idle-txn). Tente modificar a aplicação para evitar ou minimizar o uso de transações de longa duração.

### Ações de longo prazo
<a name="apg-waits.lwlockmultixact.actions.longactions"></a>

Examine a workload para descobrir a causa do transbordamento de multixact. É necessário corrigir o problema para escalar a workload e reduzir o evento de espera.
+ É necessário analisar a DDL (linguagem de definição de dados) usada para criar tabelas. Verifique se as estruturas e os índices das tabelas estão bem projetados.
+ Quando as tabelas afetadas tiverem chaves externas, determine se elas são necessárias ou se há outra forma de aplicar a integridade referencial.
+ Quando uma tabela tem grandes índices não utilizados, isso pode fazer com que o autovacuum não se ajuste à workload e pode impedir a execução. Para evitar isso, verifique se há índices não utilizados e remova-os completamente. Para ter mais informações, consulte [Gerenciar o autovacuum com grandes índices](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.LargeIndexes.html).
+ Reduza o uso de pontos de salvamento nas transações.

# LWLock:pg\$1stat\$1statements
<a name="apg-rpg-lwlockpgstat"></a>

O evento de espera LWLock:pg\$1stat\$1statements ocorre quando a extensão `pg_stat_statements` obtém um bloqueio exclusivo na tabela de hash que rastreia instruções SQL. Isso acontece nos seguintes cenários:
+ Quando o número de instruções rastreadas atinge o valor configurado do parâmetro `pg_stat_statements.max` e é necessário abrir espaço para mais entradas, a extensão executa uma classificação no número de chamadas, remove 5% das instruções menos executadas e preenche novamente o hash com as entradas restantes.
+ Quando `pg_stat_statements` executa uma operação `garbage collection` no arquivo `pgss_query_texts.stat` no disco e reescreve o arquivo.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-rpg-lwlockpgstat.supported)
+ [Contexto](#apg-rpg-lwlockpgstat.context)
+ [Possíveis causas do maior número de esperas](#apg-rpg-lwlockpgstat.causes)
+ [Ações](#apg-rpg-lwlockpgstat.actions)

## Versões compatíveis do mecanismo
<a name="apg-rpg-lwlockpgstat.supported"></a>

 As informações sobre esse evento de espera são aceitas em todas as versões do Aurora PostgreSQL. 

## Contexto
<a name="apg-rpg-lwlockpgstat.context"></a>

**Conceitos básicos sobre a extensão pg\$1stat\$1statements**: essa extensão rastreia as estatísticas de execução de instruções SQL em uma tabela de hash. Ela rastreia as instruções SQL até o limite definido pelo parâmetro `pg_stat_statements.max`. Esse parâmetro determina o número máximo de instruções que podem ser rastreadas, o qual corresponde ao número máximo de linhas na visualização pg\$1stat\$1statements.

**Persistência das estatísticas de instrução**: a extensão mantém as estatísticas da instrução em todas as reinicializações da instância:
+ Gravando dados em um arquivo chamado pg\$1stat\$1statements.stat.
+ Usando o parâmetro pg\$1stat\$1statements.save para controlar o comportamento de persistência.

Quando pg\$1stat\$1statements.save é definido como:
+ ativado (padrão): as estatísticas são salvas no desligamento e recarregadas na inicialização do servidor.
+ desativado: as estatísticas não são salvas no desligamento nem recarregadas na inicialização do servidor.

**Armazenamento de texto de consulta**: a extensão armazena o texto das consultas rastreadas em um arquivo chamado `pgss_query_texts.stat`. Esse arquivo pode aumentar até o dobro do tamanho médio de todas as instruções SQL rastreadas antes que a coleta de resíduos ocorra. A extensão requer um bloqueio exclusivo na tabela de hash durante as operações de limpeza e regravação do arquivo `pgss_query_texts.stat`.

**Processo de desalocação de instruções**: quando o número de instruções rastreadas atinge o limite `pg_stat_statements.max` e novas instruções precisam ser rastreadas, a extensão:
+ Obtém um bloqueio exclusivo (LWLock:pg\$1stat\$1statements) na tabela de hash.
+ Carrega os dados existentes na memória local.
+ Executa uma classificação rápida com base no número de chamadas.
+ Remove as instruções menos chamadas (5% inferiores).
+ Preenche novamente a tabela de hash com as entradas restantes.

**Monitoramento da desalocação de instruções**: no PostgreSQL 14 e versões posteriores, você pode monitorar a desalocação de instruções usando a visualização pg\$1stat\$1statements\$1info. Essa visualização inclui uma coluna de desalocação que mostra quantas vezes as instruções foram desalocadas para abrir espaço para novas.

Se a desalocação de instruções ocorrer com frequência, haverá uma coleta de resíduos mais frequente do arquivo `pgss_query_texts.stat` no disco.

## Possíveis causas do maior número de esperas
<a name="apg-rpg-lwlockpgstat.causes"></a>

As causas típicas do aumento de esperas `LWLock:pg_stat_statements` incluem:
+ Um aumento no número de consultas exclusivas usadas pela aplicação.
+ O valor do parâmetro `pg_stat_statements.max` é pequeno em comparação ao número de consultas exclusivas que estão sendo usadas.

## Ações
<a name="apg-rpg-lwlockpgstat.actions"></a>

Recomenda-se ações distintas, dependendo dos motivos do evento de espera. Você pode identificar eventos `LWLock:pg_stat_statements` utilizando o Insights de Performance do Amazon RDS ou consultando a visualização `pg_stat_activity`.

Ajuste os parâmetros `pg_stat_statements` a seguir para controlar o comportamento de rastreamento e reduzir os eventos de espera das instruções LWLock:pg\$1stat\$1.

**Topics**
+ [Desabilitar o parâmetro pg\$1stat\$1statements.track](#apg-rpg-lwlockpgstat.actions.disabletrack)
+ [Aumentar o parâmetro pg\$1stat\$1statements.max](#apg-rpg-lwlockpgstat.actions.increasemax)
+ [Desabilitar o parâmetro pg\$1stat\$1statements.track\$1utility](#apg-rpg-lwlockpgstat.actions.disableutility)

### Desabilitar o parâmetro pg\$1stat\$1statements.track
<a name="apg-rpg-lwlockpgstat.actions.disabletrack"></a>

Se o evento de espera LWLock:pg\$1stat\$1statements estiver afetando negativamente o desempenho do banco de dados e for necessária uma solução rápida antes de uma análise mais aprofundada da visualização `pg_stat_statements` para identificar a causa-raiz, o parâmetro `pg_stat_statements.track` poderá ser desabilitado configurando-o como `none`. Isso desabilitará a coleta de estatísticas de instrução.

### Aumentar o parâmetro pg\$1stat\$1statements.max
<a name="apg-rpg-lwlockpgstat.actions.increasemax"></a>

Para reduzir a desalocação e minimizar a coleta de resíduos do arquivo `pgss_query_texts.stat` no disco, aumente o valor do parâmetro `pg_stat_statements.max`. O valor padrão é `5,000`.

**nota**  
O parâmetro `pg_stat_statements.max` é estático. É necessário reinicializar a instância de banco de dados para aplicar qualquer alteração nesse parâmetro. 

### Desabilitar o parâmetro pg\$1stat\$1statements.track\$1utility
<a name="apg-rpg-lwlockpgstat.actions.disableutility"></a>

Você pode analisar a visualização pg\$1stat\$1statements para determinar quais comandos do utilitário estão consumindo mais recursos rastreados por `pg_stat_statements`.

O parâmetro `pg_stat_statements.track_utility` controla se o módulo rastreia os comandos do utilitário, que incluem todos os comandos, exceto SELECT, INSERT, UPDATE, DELETE e MERGE. Esse parâmetro é definido como por padrão `on`.

Por exemplo, quando sua aplicação usa muitas consultas de ponto de salvamento, que são inerentemente exclusivas, ela pode aumentar a desalocação de instruções. Para resolver isso, você pode desabilitar o parâmetro `pg_stat_statements.track_utility` para impedir que `pg_stat_statements` rastreie consultas de pontos de salvamento.

**nota**  
O parâmetro `pg_stat_statements.track_utility` é dinâmico. Você pode alterar o respectivo valor sem reiniciar a instância de banco de dados.

**Example Exemplo de consultas exclusivas de ponto de salvamento em pg\$1stat\$1statements**  <a name="savepoint-queries"></a>

```
                     query                       |       queryid       
-------------------------------------------------+---------------------
 SAVEPOINT JDBC_SAVEPOINT_495701                 | -7249565344517699703
 SAVEPOINT JDBC_SAVEPOINT_1320                   | -1572997038849006629
 SAVEPOINT JDBC_SAVEPOINT_26739                  |  54791337410474486
 SAVEPOINT JDBC_SAVEPOINT_1294466                |  8170064357463507593
 ROLLBACK TO SAVEPOINT JDBC_SAVEPOINT_65016      | -33608214779996400
 SAVEPOINT JDBC_SAVEPOINT_14185                  | -2175035613806809562
 SAVEPOINT JDBC_SAVEPOINT_45837                  | -6201592986750645383
 SAVEPOINT JDBC_SAVEPOINT_1324                   |  6388797791882029332
```

O PostgreSQL 17 inclui vários aprimoramentos para o rastreamento de comandos de utilitário:
+ Os nomes de ponto de salvamento agora são exibidos como constantes.
+ Os IDs de transação global (GIDs) dos comandos de confirmação em duas fases agora são exibidos como constantes.
+ Os nomes das instruções DEALLOCATE são mostrados como constantes.
+ Os parâmetros CALL agora são exibidos como constantes.

# Tempo limite:PgSleep
<a name="apg-waits.timeoutpgsleep"></a>

O evento `Timeout:PgSleep` ocorre quando um processo do servidor chama a função `pg_sleep` e está aguardando o tempo limite de suspensão expirar.

**Topics**
+ [Versões compatíveis do mecanismo](#apg-waits.timeoutpgsleep.context.supported)
+ [Possíveis causas do maior número de esperas](#apg-waits.timeoutpgsleep.causes)
+ [Ações](#apg-waits.timeoutpgsleep.actions)

## Versões compatíveis do mecanismo
<a name="apg-waits.timeoutpgsleep.context.supported"></a>

Essas informações de eventos de espera têm suporte para todas as versões do Aurora PostgreSQL.

## Possíveis causas do maior número de esperas
<a name="apg-waits.timeoutpgsleep.causes"></a>

Esse evento de espera ocorre quando uma aplicação, uma função armazenada ou um usuário emite uma instrução SQL que chama uma das seguintes funções:
+ `pg_sleep`
+ `pg_sleep_for`
+ `pg_sleep_until`

As funções anteriores atrasarão a execução até que o número especificado de segundos tenha decorrido. Por exemplo, `SELECT pg_sleep(1)` pausa por 1 segundo. Para obter mais informações, consulte [Atrasar a execução](https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-DELAY) na documentação do PostgreSQL.

## Ações
<a name="apg-waits.timeoutpgsleep.actions"></a>

Identifique a instrução que estava executando a função `pg_sleep`. Determine se o uso da função é apropriado.