

# Lock:Relation
<a name="wait-event.lockrelation"></a>

`Lock:Relation` 이벤트는 쿼리가 현재 다른 트랜잭션에 의해 잠긴 테이블 또는 뷰(관계식)에 대한 잠금을 얻기 위해 대기 중일 때 발생합니다.

**Topics**
+ [지원되는 엔진 버전](#wait-event.lockrelation.context.supported)
+ [컨텍스트](#wait-event.lockrelation.context)
+ [대기 증가의 가능한 원인](#wait-event.lockrelation.causes)
+ [작업](#wait-event.lockrelation.actions)

## 지원되는 엔진 버전
<a name="wait-event.lockrelation.context.supported"></a>

이 대기 이벤트 정보는 모든 RDS for PostgreSQL 버전에서 지원됩니다.

## 컨텍스트
<a name="wait-event.lockrelation.context"></a>

대부분의 PostgreSQL 명령은 암시적으로 잠금을 사용하여 테이블의 데이터에 대한 동시 액세스를 제어합니다. 애플리리케이션 코드에서 `LOCK` 명령과 함께 이러한 잠금을 명시적으로 사용할 수도 있습니다. 많은 잠금 모드는 서로 호환되지 않으며 동일한 객체에 액세스하려고 할 때 트랜잭션을 차단할 수 있습니다. 이 경우 RDS for PostgreSQL은 `Lock:Relation` 이벤트를 생성합니다. 다음은 몇 가지 일반적인 예입니다.
+ `ACCESS EXCLUSIVE`와 같은 독점 잠금은 모든 동시 액세스를 차단할 수 있습니다. 데이터 정의 언어(DDL) 작업(예: `DROP TABLE`,`TRUNCATE`,`VACUUM FULL`, 및`CLUSTER`)은 명시적으로 `ACCESS EXCLUSIVE` 잠금을 획득합니다. 또한 `ACCESS EXCLUSIVE`는 모드를 명시적으로 식별하지 않는 `LOCK TABLE` 문을 위한 기본 잠금 모드입니다.
+ 데이터 조작 언어(DML) 명령문 `UPDATE`,`DELETE`, 및 `INSERT`와 충돌하는 테이블에 `ROW EXCLUSIVE` 잠금을 획득하는 `CREATE INDEX (without CONCURRENT)`를 사용하세요.

테이블 수준 잠금 및 충돌하는 잠금 모드에 대한 자세한 내용은 PostgreSQL 설명서의 [명시적 잠금](https://www.postgresql.org/docs/13/explicit-locking.html)을 참조하세요.

쿼리 및 트랜잭션 차단은 일반적으로 다음 중 한 가지 방법으로 잠금 해제합니다.
+ 쿼리 차단 - 애플리케이션이 쿼리를 취소하거나 사용자가 프로세스를 종료할 수 있습니다. 세션의 명령문 시간 초과 또는 교착 상태 감지 메커니즘으로 인해 엔진이 쿼리를 강제로 종료할 수도 있습니다.
+ 트랜잭션 차단 - 트랜잭션이 `ROLLBACK`이나 `COMMIT` 문을 실행할 때 차단을 중지합니다. 롤백은 클라이언트 또는 네트워크 문제로 세션의 연결이 끊어지거나 종료된 경우에도 자동으로 수행됩니다. 세션은 데이터베이스 엔진이 종료될 때, 시스템의 메모리가 부족할 때 종료될 수 있습니다.

## 대기 증가의 가능한 원인
<a name="wait-event.lockrelation.causes"></a>

`Lock:Relation` 이벤트가 평소보다 더 자주 발생하면 성능 문제를 나타낼 수 있습니다. 일반적인 원인은 다음과 같습니다.

**테이블 잠금 충돌로 인한 동시 세션 증가**  
잠금 모드가 충돌하는 동일한 테이블을 하거나 잠그는 쿼리의 동시 세션 수가 증가할 수 있습니다.

**유지 관리 작업**  
`VACUUM`과 `ANALYZE` 같은 상태 유지 관리 작업은 충돌하는 잠금 수를 크게 늘릴 수 있습니다. `VACUUM FULL`은 하나의 `ACCESS EXCLUSIVE` 잠금을, `ANALYSE`는 하나의 `SHARE UPDATE EXCLUSIVE` 잠금을 획득합니다. 두 가지 유형의 잠금은 모두 `Lock:Relation` 대기 이벤트를 발생시킬 수 있습니다. 구체화된 뷰 새로 고침과 같은 애플리케이션 데이터 유지 관리 작업은 차단된 질의 및 트랜잭션을 증가시킬 수도 있습니다.

**리더 인스턴스 잠금**  
라이터와 리더가 보유한 관계 잠금 간에 충돌이 있을 수 있습니다. 현재 `ACCESS EXCLUSIVE` 관계 잠금만 리더 인스턴스에 복제됩니다. 그러나 `ACCESS EXCLUSIVE` 관계 잠금은 리더가 보유한 모든 `ACCESS SHARE` 관계 잠금과 충돌합니다. 이로 인해 리더에서 잠금 관계 대기 이벤트가 증가할 수 있습니다.

## 작업
<a name="wait-event.lockrelation.actions"></a>

대기 이벤트의 원인에 따라 다른 작업을 권장합니다.

**Topics**
+ [SQL 문 차단의 영향 감소](#wait-event.lockrelation.actions.reduce-blocks)
+ [유지 보수 작업의 영향 최소화](#wait-event.lockrelation.actions.maintenance)

### SQL 문 차단의 영향 감소
<a name="wait-event.lockrelation.actions.reduce-blocks"></a>

SQL 문 차단의 영향을 줄이려면 가능한 경우 애플리케이션 코드를 수정하세요. 다음은 블록을 줄이기 위한 두 가지 일반적인 기술입니다.
+ `NOWAIT` 옵션 사용 - `SELECT`나 `LOCK` 문 같은 일부 SQL 명령은 이 옵션을 지원합니다. `NOWAIT` 지시어는 잠금을 즉시 획득할 수 없는 경우 잠금 요청 쿼리를 취소합니다. 이 기술은 차단 세션이 그 뒤에 차단된 세션이 쌓이지 않게 하는 데 도움이 될 수 있습니다.

  예: 트랜잭션 A가 트랜잭션 B가 보유한 잠금을 기다리고 있다고 가정합니다. 이제 B가 트랜잭션 C에 의해 잠긴 테이블에 대한 잠금을 요청하면 트랜잭션 C가 완료될 때까지 트랜잭션 A가 차단될 수 있습니다. 그러나 트랜잭션 B가 `NOWAIT`를 사용하는 경우 C에서 잠금을 요청하면 빠르게 실패하고 트랜잭션 A가 계속해서 기다릴 필요가 없도록 할 수 있습니다.
+ `SET lock_timeout` 사용 - SQL 문이 관계식 잠금을 획득하기 위해 대기하는 시간을 제한하는 `lock_timeout` 값을 설정하세요. 지정된 제한 시간 내에 잠금을 획득하지 않으면 잠금을 요청하는 트랜잭션이 취소됩니다. 세션 수준에서 이 값을 설정합니다.

### 유지 보수 작업의 영향 최소화
<a name="wait-event.lockrelation.actions.maintenance"></a>

`VACUUM`과 `ANALYZE` 같은 유지 관리 작업이 중요합니다. 이러한 유지 관리 작업과 관련된 `Lock:Relation` 대기 이벤트를 찾을 수 있으므로 끄지 않는 것이 좋습니다. 다음 방법을 사용하면 이러한 작업의 효과를 최소화할 수 있습니다.
+ 사용량이 적은 시간대에 수동으로 유지 관리 작업을 실행합니다.
+ Autovacuum 작업으로 인한 `Lock:Relation` 대기를 줄이려면 필요한 autovacuum 튜닝을 수행하세요. Autovacuum 튜닝에 대한 자세한 내용은 [Amazon RDS 사용 설명서](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.PostgreSQL.CommonDBATasks.Autovacuum.html)의 *Amazon RDS에서 PostgreSQL Autovacuum 사용*을 참조하세요.