Aurora DSQL의 동시성 제어
동시성을 통해 여러 세션이 데이터 무결성과 일관성을 손상시키지 않고 동시에 데이터에 액세스하고 수정할 수 있습니다. Aurora DSQL은 현대적 비잠금 동시성 제어 메커니즘을 구현하면서 PostgreSQL 호환성을 제공합니다. 스냅샷 격리를 통해 완전한 ACID 규정 준수를 유지하여 데이터 일관성과 신뢰성을 보장합니다.
Aurora DSQL의 주요 이점은 일반적인 데이터베이스 성능 병목 현상을 제거하는 비잠금 아키텍처라는 점입니다. Aurora DSQL은 느린 트랜잭션이 다른 작업을 차단하는 것을 방지하고 교착 상태의 위험을 제거합니다. 이 접근 방식을 통해 Aurora DSQL은 성능과 확장성이 필수인 처리량이 많은 애플리케이션에 특히 유용합니다.
동시성 제어 응답
Aurora DSQL은 기존 잠금 기반 시스템과 다르게 작동하는 낙관적 동시성 제어(OCC)를 사용합니다. OCC는 잠금을 사용하는 대신 커밋 시 충돌을 평가합니다. 이러한 커밋 시간 충돌 평가 프로세스를 조정이라고도 합니다. Aurora DSQL은 충돌을 감지하면 SQLSTATE 코드 40001를 사용하여 PostgreSQL 직렬화 실패를 반환합니다. 응답 메시지에는 충돌 유형을 식별하는 OCC 코드가 포함되어 있습니다.
- OC000 - 데이터 충돌
-
두 트랜잭션이 동일한 행을 수정하려고 시도했습니다. 커밋 시간이 가장 빠른 트랜잭션이 성공하고 충돌하는 트랜잭션은 OC000 응답을 수신합니다.
ERROR: change conflicts with another transaction (OC000) (SQLSTATE 40001) - OC001 - 스키마 충돌
-
세션의 캐시된 스키마 카탈로그가 최신이 아닙니다. 세션이 캐시를 로드한 이후 카탈로그 버전이 변경되었음을 Aurora DSQL에서 감지하고 트랜잭션이 현재 버전으로 안전하게 리베이스할 수 없는 경우 트랜잭션은 OC001 응답을 수신합니다.
ERROR: schema has been updated by another transaction (OC001) (SQLSTATE 40001)스키마 카탈로그를 수정하는 모든 작업(
CREATE TABLE및ALTER TABLE과 같은 DDL 문,GRANT및REVOKE문 포함)은 OC001 응답을 발생시킬 수 있습니다. 자세한 내용은 Aurora DSQL의 DDL 및 분산 트랜잭션 섹션을 참조하세요.
이러한 응답을 처리하기 위해 재시도 로직을 구현하도록 애플리케이션을 설계하세요. 이상적인 설계 패턴은 멱등적이므로 가능하면 트랜잭션 재시도를 첫 번째 수단으로 사용할 수 있습니다. 권장 로직은 표준 PostgreSQL 잠금 제한 시간 또는 교착 상태의 중단 및 재시도 로직과 유사합니다. 그러나 OCC에서는 애플리케이션이 이 로직을 더 자주 실행해야 합니다.
데이터 충돌 유형
Aurora DSQL 동시성 제어 메커니즘으로 인해 SELECT ... FOR
UPDATE 및 SELECT ... FOR KEY SHARE 절은 잠금 대신 커밋 시점의 낙관적 충돌 감지를 통해 결과를 생성합니다. Aurora DSQL에서 한 트랜잭션이 행을 쓰고 다른 트랜잭션이 앞서 언급된 절 중 하나를 사용하여 해당 행을 읽는 경우, 각 트랜잭션이 사용하는 열에 따라 커밋 시점에 충돌이 발생할 수 있습니다. 다음 절들은 Aurora DSQL이 이러한 충돌을 감지하는 방식을 결정합니다.
키 열 정의
키 열은 고유하고 비부분적이며 표현식이 아닌 인덱스의 구성 요소인 열입니다. 다른 모든 열은 키가 아닌 열입니다.
SELECT ... FOR UPDATE-
Aurora DSQL은 마치 트랜잭션이 해당 행들에 쓰기 작업을 수행하는 것처럼 선택된 행들을 처리한다고 선언합니다. 다른 트랜잭션이 동일한 행에서
UPDATE,DELETE,SELECT ... FOR UPDATE또는SELECT ... FOR KEY SHARE를 실행하고 먼저 커밋하면SELECT ... FOR UPDATE를 실행한 트랜잭션이OC000응답과 함께 실패합니다. 이 절은 행에 대한 동시 쓰기 및 동시FOR UPDATE또는FOR KEY SHARE읽기와 충돌합니다. SELECT ... FOR KEY SHARE-
트랜잭션이 선택한 행의 키 열에 의존함을 선언합니다. 다른 트랜잭션이 해당 행을 삭제하거나, 키 열을 변경하거나 또는
SELECT ... FOR KEY SHARE를 먼저 실행하여 커밋할 경우OC000를 실행한 트랜잭션은SELECT ... FOR UPDATE응답과 함께 실패합니다. 키가 아닌 열에 대한 동시UPDATE는 충돌하지 않습니다.
Aurora DSQL은 NO KEY UPDATE 또는 FOR SHARE 절을 지원하지 않습니다. 그러나 DML은 암시적으로 NO KEY UPDATE 메커니즘을 사용합니다. 다음 매트릭스는 동일한 행에 액세스하는 두 개의 동시 트랜잭션이 충돌하는 경우를 요약합니다. X는 두 작업이 충돌함을 나타냅니다. 즉, 마지막으로 커밋하는 트랜잭션이 OC000 응답과 함께 실패합니다. 빈 셀은 두 트랜잭션이 모두 커밋할 수 있음을 나타냅니다.
| 연산 | INSERT, DELETE, UPDATE(키 열) 또는 SELECT ... FOR UPDATE |
UPDATE(키가 아닌 열만 해당) |
SELECT ... FOR KEY SHARE |
|---|---|---|---|
INSERT, DELETE, UPDATE(키 열) 또는 SELECT ... FOR UPDATE |
X | X | X |
UPDATE(키가 아닌 열만 해당) |
X | X | |
SELECT ... FOR KEY SHARE |
X |
트랜잭션 성능 최적화 지침
성능을 최적화하려면 단일 키 또는 작은 키 범위에서 높은 경합을 최소화합니다. 이 목표를 달성하려면 다음 지침에 따라 클러스터 키 범위에 업데이트를 분산하도록 스키마를 설계하세요.
-
테이블에 대한 임의 프라이머리 키를 선택합니다.
-
단일 키에 대한 경합을 높이는 패턴을 피합니다. 이 접근 방식은 트랜잭션 볼륨이 증가하더라도 최적의 성능을 보장합니다.