Lock:Relation
Lock:Relation
이벤트는 쿼리가 현재 다른 트랜잭션에 의해 잠긴 테이블 또는 뷰(관계식)에 대한 잠금을 얻기 위해 대기 중일 때 발생합니다.
지원되는 엔진 버전
이 대기 이벤트 정보는 모든 Aurora PostgreSQL 버전에서 지원됩니다.
컨텍스트
대부분의 PostgreSQL 명령은 암시적으로 잠금을 사용하여 테이블의 데이터에 대한 동시 액세스를 제어합니다. 애플리리케이션 코드에서 LOCK
명령과 함께 이러한 잠금을 명시적으로 사용할 수도 있습니다. 많은 잠금 모드는 서로 호환되지 않으며 동일한 객체에 액세스하려고 할 때 트랜잭션을 차단할 수 있습니다. 이 경우 Aurora 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 설명서의 명시적 잠금
쿼리 및 트랜잭션 차단은 일반적으로 다음 중 한 가지 방법으로 잠금 해제합니다.
쿼리 차단 - 애플리케이션이 쿼리를 취소하거나 사용자가 프로세스를 종료할 수 있습니다. 세션의 명령문 시간 초과 또는 교착 상태 감지 메커니즘으로 인해 엔진이 쿼리를 강제로 종료할 수도 있습니다.
트랜잭션 차단 - 트랜잭션이
ROLLBACK
이나COMMIT
문을 실행할 때 차단을 중지합니다. 롤백은 클라이언트 또는 네트워크 문제로 세션의 연결이 끊어지거나 종료된 경우에도 자동으로 수행됩니다. 세션은 데이터베이스 엔진이 종료될 때, 시스템의 메모리가 부족할 때 종료될 수 있습니다.
대기 증가의 가능한 원인
Lock:Relation
이벤트가 평소보다 더 자주 발생하면 성능 문제를 나타낼 수 있습니다. 일반적인 원인은 다음과 같습니다.
- 테이블 잠금 충돌로 인한 동시 세션 증가
-
잠금 모드가 충돌하는 동일한 테이블을 하거나 잠그는 쿼리의 동시 세션 수가 증가할 수 있습니다.
- 유지 관리 작업
-
VACUUM
과ANALYZE
같은 상태 유지 관리 작업은 충돌하는 잠금 수를 크게 늘릴 수 있습니다.VACUUM FULL
은 하나의ACCESS EXCLUSIVE
잠금을,ANALYZE
는 하나의SHARE UPDATE EXCLUSIVE
잠금을 획득합니다. 두 가지 유형의 잠금은 모두Lock:Relation
대기 이벤트를 발생시킬 수 있습니다. 구체화된 뷰 새로 고침과 같은 애플리케이션 데이터 유지 관리 작업은 차단된 질의 및 트랜잭션을 증가시킬 수도 있습니다. - 리더 인스턴스 잠금
-
라이터와 리더가 보유한 관계 잠금 간에 충돌이 있을 수 있습니다. 현재
ACCESS EXCLUSIVE
관계 잠금만 리더 인스턴스에 복제됩니다. 그러나ACCESS EXCLUSIVE
관계 잠금은 리더가 보유한 모든ACCESS SHARE
관계 잠금과 충돌합니다. 이로 인해 리더에서 잠금 관계 대기 이벤트가 증가할 수 있습니다.
작업
대기 이벤트의 원인에 따라 다른 작업을 권장합니다.
SQL 문 차단의 영향 감소
SQL 문 차단의 영향을 줄이려면 가능한 경우 애플리케이션 코드를 수정하세요. 다음은 블록을 줄이기 위한 두 가지 일반적인 기술입니다.
NOWAIT
옵션 사용 -SELECT
나LOCK
문 같은 일부 SQL 명령은 이 옵션을 지원합니다.NOWAIT
지시어는 잠금을 즉시 획득할 수 없는 경우 잠금 요청 쿼리를 취소합니다. 이 기술은 차단 세션이 그 뒤에 차단된 세션이 쌓이지 않게 하는 데 도움이 될 수 있습니다.예: 트랜잭션 A가 트랜잭션 B가 보유한 잠금을 기다리고 있다고 가정합니다. 이제 B가 트랜잭션 C에 의해 잠긴 테이블에 대한 잠금을 요청하면 트랜잭션 C가 완료될 때까지 트랜잭션 A가 차단될 수 있습니다. 그러나 트랜잭션 B가
NOWAIT
를 사용하는 경우 C에서 잠금을 요청하면 빠르게 실패하고 트랜잭션 A가 계속해서 기다릴 필요가 없도록 할 수 있습니다.SET lock_timeout
사용 - SQL 문이 관계식 잠금을 획득하기 위해 대기하는 시간을 제한하는lock_timeout
값을 설정하세요. 지정된 제한 시간 내에 잠금을 획득하지 않으면 잠금을 요청하는 트랜잭션이 취소됩니다. 세션 수준에서 이 값을 설정합니다.
유지 보수 작업의 영향 최소화
VACUUM
과 ANALYZE
같은 유지 관리 작업이 중요합니다. 이러한 유지 관리 작업과 관련된 Lock:Relation
대기 이벤트를 찾을 수 있으므로 끄지 않는 것이 좋습니다. 다음 방법을 사용하면 이러한 작업의 효과를 최소화할 수 있습니다.
사용량이 적은 시간대에 수동으로 유지 관리 작업을 실행합니다.
Autovacuum 작업으로 인한
Lock:Relation
대기를 줄이려면 필요한 autovacuum 튜닝을 수행하세요. Autovacuum 튜닝에 대한 자세한 내용은 Amazon RDS 사용 설명서의 Amazon RDS에서 PostgreSQL Autovacuum 사용을 참조하세요.
리더 잠금 확인
라이터 및 리더의 동시 세션이 서로를 차단하는 잠금을 유지하는 방법을 확인할 수 있습니다. 이를 수행하는 한 가지 방법은 잠금 유형 및 관계를 반환하는 쿼리를 실행하는 것입니다. 테이블에서 두 개의 동시 세션, 즉 라이터 세션과 리더 세션에 대한 쿼리 시퀀스를 찾을 수 있습니다.
재생 프로세스는 리더 쿼리를 취소하기 전에 max_standby_streaming_delay
의 기간 동안 기다립니다. 예에서 볼 수 있듯이 100ms의 잠금 시간 제한은 기본값 max_standby_streaming_delay
인 30초보다 훨씬 낮습니다. 문제가 발생하기 전에 잠금 시간이 초과됩니다.
시퀀스 이벤트 | 세션 | 명령 또는 출력 |
---|---|---|
지정된 값을 사용하여 READER라는 환경 변수를 설정하고 이 엔드포인트를 사용하여 DB 인스턴스에 연결을 시도합니다. |
리더 세션 |
CLI 명령:
출력: psql (15devel, server 10.14) Type "help" for help. |
WRITER라는 환경 변수를 설정하고 이 엔드포인트 를 사용하여 DB 인스턴스에 연결을 시도합니다. |
라이터 세션 |
CLI 명령:
출력: psql (15devel, server 10.14) Type "help" for help. |
라이터 세션은 라이터 인스턴스에서 table t1을 생성합니다. |
라이터 세션 |
PostgreSQL 쿼리:
|
라이터에 충돌하는 쿼리가 없는 경우 라이터에서 ACCESS EXCLUSIVE 잠금을 즉시 획득합니다. |
라이터 세션 |
|
리더 세션은 잠금 시간 초과 간격을 100밀리초로 설정합니다. |
리더 세션 |
PostgreSQL 쿼리:
|
리더 세션이 리더 인스턴스의 table t1에서 데이터를 읽으려고 시도합니다. |
리더 세션 |
PostgreSQL 쿼리:
샘플 출력: b --- (0 rows) |
라이터 세션이 t1을 삭제합니다. |
라이터 세션 |
PostgreSQL 쿼리:
|
쿼리 시간이 초과되고 리더에서 취소됩니다. |
리더 세션 |
PostgreSQL 쿼리:
샘플 출력: ERROR: canceling statement due to lock timeout LINE 1: SELECT * FROM t1; ^ |
리더 세션이 |
리더 세션 |
PostgreSQL 쿼리:
|
결과는 |
리더 세션 |
쿼리 결과:
|