

# Lock:Relation
<a name="wait-event.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](#wait-event.lockrelation.context.supported)
+ [Contexto](#wait-event.lockrelation.context)
+ [Possíveis causas do maior número de esperas](#wait-event.lockrelation.causes)
+ [Ações](#wait-event.lockrelation.actions)

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

Essas informações de eventos de espera são compatíveis com todas as versões do RDS para PostgreSQL.

## Contexto
<a name="wait-event.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 RDS para 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="wait-event.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 `ANALYSE` 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="wait-event.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](#wait-event.lockrelation.actions.reduce-blocks)
+ [Minimizar o efeito de operações de manutenção](#wait-event.lockrelation.actions.maintenance)

### Reduzir o impacto do bloqueio de instruções SQL
<a name="wait-event.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 adquirido 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="wait-event.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*.