Lock:tuple
Lock:tuple
이벤트는 백엔드 프로세스가 튜플에 대한 잠금 획득을 대기 중일 때 발생합니다.
지원되는 엔진 버전
이 대기 이벤트 정보는 모든 Aurora PostgreSQL 버전에서 지원됩니다.
컨텍스트
이벤트 Lock:tuple
은 다른 백엔드가 동일한 튜플에서 충돌하는 잠금을 보유하는 동안 백엔드가 튜플에 대한 잠금을 얻기 위해 대기 중임을 나타냅니다. 다음 테이블에서는 세션이 Lock:tuple
이벤트를 생성하는 시나리오를 가정합니다.
Time |
세션 1 |
세션 2 |
세션 3 |
---|---|---|---|
t1 |
트랜잭션을 시작합니다. |
||
t2 |
1행을 업데이트합니다. |
||
t3 |
1행을 업데이트합니다. 세션은 튜플에 대한 배타적 잠금을 획득한 다음 세션 1이 커밋하거나 롤백하여 잠금을 해제할 때까지 기다립니다. |
||
t4 |
1행을 업데이트합니다. 세션은 세션 2가 튜플에서 배타적 잠금을 해제할 때까지 기다립니다. |
또는 벤치마킹 도구 pgbench
를 사용하여 이 대기 이벤트를 시뮬레이션할 수 있습니다. 테이블의 동일한 행을 사용자 정의 SQL 파일로 업데이트하도록 많은 수의 동시 세션을 구성합니다.
충돌하는 잠금 모드에 대한 자세한 내용은 PostgreSQL 설명서의 명시적 잠금pgbench
에 관한 더 자세한 내용은 PostgreSQL 설명서의 pgbench
대기 증가의 가능한 원인
이 이벤트가 정상보다 많이 발생해 성능 문제를 일으킬 수 있는 경우 일반적인 원인은 다음과 같습니다.
-
많은 수의 동시 세션이
UPDATE
또는DELETE
문을 실행하여 동일한 튜플에 대해 충돌하는 잠금을 얻으려고 시도합니다. -
높은 동시 세션이
FOR UPDATE
또는FOR NO KEY UPDATE
잠금 모드를 통해SELECT
문을 실행하고 있습니다. -
다양한 요인으로 인해 애플리케이션이나 연결 풀이 더 많은 세션을 열어 동일한 작업을 실행할 수 있습니다. 새 세션이 동일한 행을 수정하려고 하면 DB 로드가 급증할 수 있으며,
Lock:tuple
이 표시될 수 있습니다.
자세한 내용은 PostgreSQL 설명서의 행 수준 잠금
작업
대기 이벤트의 원인에 따라 다른 작업을 권장합니다.
애플리케이션 로직 조사
차단 세션이 오랜 시간 동안 idle in
transaction
상태인지 확인하세요. 그렇다면 차단 세션을 단기 솔루션으로 종료하는 것이 좋습니다. pg_terminate_backend
함수를 사용할 수 있습니다. 이 함수에 대한 자세한 내용은 PostgreSQL 설명서의 서버 신호 전송 함수
장기 솔루션의 경우 다음을 수행합니다.
-
애플리케이션 로직을 조정합니다.
-
idle_in_transaction_session_timeout
파라미터를 사용합니다. 이 파라미터는 지정된 시간보다 오랫동안 유휴 상태인 열린 트랜잭션으로 세션을 종료합니다. 자세한 내용은 PostgreSQL 설명서의 클라이언트 인증을 참조하세요. -
autocommit을 최대한 많이 사용합니다. 자세한 내용은 PostgreSQL 설명서의 AUTOCOMMIT 설정
을 참조하세요.
차단 세션 찾기
Lock:tuple
대기 이벤트가 발생하는 동안 어떤 잠금이 서로 의존하는지 파악하여 차단 및 차단된 세션을 식별합니다. 자세한 내용은 PostgreSQL 위키의 잠금 종속성 정보Lock:tuple
이벤트를 분석하려면, Aurora 함수 aurora_stat_backend_waits
를 사용하세요.
다음 예에서는 tuple
필터링과 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
높은 동시성 저감
Lock:tuple
이벤트는 지속적으로 발생할 수 있으며, 특히 작업 부하가 많은 시간에 발생할 수 있습니다. 이 경우 매우 바쁜 행에 대해 높은 동시성을 줄이는 것이 좋습니다. 종종 몇 개의 행만 대기열이나 불리언 로직을 제어하므로 이러한 행을 매우 바쁘게 만듭니다.
비즈니스 요구 사항, 애플리케이션 로직 및 워크로드 유형에 따라 다양한 접근 방식을 사용하여 동시성을 줄일 수 있습니다. 예를 들면, 다음을 수행할 수 있습니다.
-
테이블 및 데이터 로직을 재설계하여 높은 동시성을 줄입니다.
-
행 수준에서 높은 동시성을 줄이기 위해 애플리케이션 로직을 변경합니다.
-
행 수준 잠금으로 쿼리를 활용하고 재설계합니다.
-
NOWAIT
절을 사용해 연산을 재시도합니다. -
낙관적 및 하이브리드 잠금 로직 동시성 제어를 사용하는 것이 좋습니다.
-
데이터베이스 격리 수준을 변경하는 것이 좋습니다.
병목 현상 해결
Lock:tuple
은 CPU 부족 또는 Amazon EBS 대역폭의 최대 사용량과 같은 병목 현상이 발생시킬 수 있습니다. 병목 현상을 줄이려면 다음 방법을 고려하세요.
-
인스턴스 클래스 유형을 확장하세요.
-
리소스 집약적인 쿼리를 최적화하세요.
-
애플리케이션 로직을 변경하세요.
-
거의 액세스하지 않는 데이터를 아카이브하세요.