Amazon Redshift는 패치 198부터 새 Python UDF 생성을 더 이상 지원하지 않습니다. 기존 Python UDF는 2026년 6월 30일까지 계속 작동합니다. 자세한 내용은 블로그 게시물
Amazon Redshift의 격리 수준
Amazon Redshift에서 동시 쓰기 작업은 테이블에서의 쓰기 잠금 및 직렬화 가능 격리 원칙을 사용하여 보호적 방식으로 지원됩니다. 직렬화 가능 격리는 테이블에 대해 실행 중인 트랜잭션이 해당 테이블에 대해 실행 중인 유일한 트랜잭션이라는 환상을 보존합니다.
Amazon Redshift 데이터베이스는 각 작업이 트랜잭션 시작 시 데이터의 최신 커밋된 버전 또는 스냅샷을 사용하도록 하여 동시 쓰기 작업을 지원합니다. 데이터베이스 스냅샷은 대부분의 SELECT 문과 COPY, DELETE, INSERT, UPDATE, TRUNCATE 같은 DML 명령 및 다음의 DDL 명령이 처음 발생할 때 트랜잭션 내에서 생성됩니다.
ALTER TABLE(열 추가 또는 삭제)
CREATE TABLE
DROP TABLE
TRUNCATE TABLE
다른 트랜잭션은 이 스냅샷을 변경할 수 없습니다. 즉, 트랜잭션이 서로 격리됩니다. 다시 말해 동시 트랜잭션은 서로에게 보이지 않으며, 서로의 변경을 감지할 수 없습니다.
트랜잭션의 모든 동시 실행은 해당 트랜잭션의 직렬 실행과 동일한 결과를 생성해야 합니다. 동일한 결과를 생성할 수 있는 이러한 트랜잭션의 순차 실행이 없는 경우 직렬화 기능을 중단하는 문을 실행하는 트랜잭션은 중지되고 롤백됩니다.
예를 들어 사용자가 T1과 T2라는 두 개의 동시 트랜잭션을 실행하려고 한다고 가정해 보겠습니다. T1 및 T2를 실행하면 다음 시나리오 중 하나 이상과 동일한 결과가 생성되어야 합니다.
-
T1과 T2가 이 순서로 순차 실행됩니다.
-
T2와 T1이 이 순서로 순차 실행됩니다.
Amazon Redshift의 격리 수준은 다음 문제를 방지합니다.
더티 읽기 - 더티 읽기는 트랜잭션이 아직 커밋되지 않은 데이터를 읽을 때 발생합니다. 예를 들어 트랜잭션 1이 행을 업데이트한다고 가정해 보겠습니다. 트랜잭션 2는 T1이 업데이트를 커밋하기 전에 업데이트된 행을 읽습니다. T1이 변경 사항을 롤백하면 T2는 Amazon Redshift에서 이제 존재하지 않은 것으로 간주하는 커밋되지 않은 행의 읽기 데이터를 갖게 됩니다.
반복할 수 없는 읽기 - 반복할 수 없는 읽기는 단일 트랜잭션이 동일한 행을 두 번 읽지만 매번 다른 데이터를 가져올 때 발생합니다. 예를 들어 트랜잭션 1이 행을 읽는다고 가정합니다. 트랜잭션 2는 해당 행을 업데이트 또는 삭제하고 업데이트 또는 삭제를 커밋합니다. T1이 행을 다시 읽으면 다른 행 값을 검색하거나 행이 삭제되었음을 발견합니다.
팬텀 - 팬텀은 검색 기준과 일치하지만 처음에는 보이지 않는 행입니다. 예를 들어 트랜잭션 1이 검색 기준을 충족하는 행 집합을 읽었다고 가정합니다. 트랜잭션 2는 T1의 검색 기준과 일치하는 UPDATE 또는 INSERT 문에 새 행을 생성합니다. T1이 검색 문을 다시 실행하면 다른 행 집합을 가져옵니다.
SNAPSHOT 및 SERIALIZABLE 격리
SERIALIZABLE 및 SNAPSHOT 격리는 직렬화 가능한 두 가지 격리 수준으로, Amazon Redshift에서 사용할 수 있습니다.
SNAPSHOT 격리는 프로비저닝된 클러스터 및 서버리스 작업 그룹을 생성할 때의 기본 격리 수준이므로 SERIALIZABLE 격리보다 더 많은 양의 데이터를 더 짧은 시간 내에 처리할 수 있습니다.
SERIALIZABLE 격리에는 시간이 더 걸리지만 동시 트랜잭션에 대해 더 엄격한 제약 조건을 구현합니다. 이 격리 수준은 직렬화 가능한 격리 위반 오류가 있는 다른 모든 동시 트랜잭션을 취소하는 동시에 하나의 트랜잭션만 커밋하도록 허용하여 쓰기 스큐 이상과 같은 문제를 방지합니다.
다음은 SNAPSHOT 격리를 사용할 때 두 개의 동시 쓰기 작업을 처리하는 방법의 타임라인 예제입니다. 각 사용자의 UPDATE 문은 동일한 행을 업데이트하려고 해도 충돌하지 않으므로 커밋할 수 있습니다.
| 시간 | 사용자 1 작업 | 사용자 2 작업 |
|---|---|---|
| 1 | BEGIN: | |
| 2 | BEGIN: | |
| 3 | SELECT * FROM Numbers;digits ------ 0 1 |
|
| 4 | SELECT * FROM Numbers;digits ------ 0 1 |
|
| 5 | UPDATE Numbers SET digits=0 WHERE digits=1; | |
| 6 | SELECT * FROM Numbers;digits ------ 0 0 |
|
| 7 | COMMIT; | |
| 8 | Update Numbers SET digits=1 WHERE digits=0; | |
| 9 | SELECT * FROM Numbers;digits ------ 1 1 |
|
| 10 | COMMIT; | |
| 11 | SELECT * FROM Numbers;digits ------ 1 0 |
|
| 12 | SELECT * FROM Numbers;digits ------ 1 0 |
직렬화 가능 격리를 사용하여 동일한 시나리오를 실행하는 경우 Amazon Redshift 직렬화 가능 위반으로 인해 사용자 2를 종료하고 오류 1023을 반환합니다. 자세한 내용은 직렬화 가능한 격리 오류 문제 해결 섹션을 참조하세요. 이 경우 사용자 1만 성공적으로 커밋할 수 있습니다.
고려 사항
Amazon Redshift에서 격리 수준을 사용할 때는 다음 사항을 고려하세요.
STV_DB_ISOLATION_LEVEL 카탈로그 보기를 쿼리하여 데이터베이스에서 사용 중인 격리 수준을 확인합니다. 자세한 내용은 STV_DB_ISOLATION_LEVEL 섹션을 참조하세요.
PG_DATABASE_INFO 뷰를 쿼리하여 데이터베이스에 지원되는 동시 트랜잭션 수를 확인합니다. 자세한 내용은 PG_DATABASE_INFO 섹션을 참조하세요.
시스템 카탈로그 테이블(PG)과 기타 Amazon Redshift 시스템 테이블은 트랜잭션에서 잠기지 않습니다. 따라서 DDL 및 TRUNCATE 작업에서 발생하는 데이터베이스 객체의 변경 사항은 동시 트랜잭션에 대한 커밋 시 볼 수 있습니다.
예를 들어 2개의 동시 트랜잭션 T1과 T2가 시작될 때 데이터베이스에 테이블 A가 존재한다고 가정해 보세요. T2가 PG_TABLES 카탈로그 테이블에서 선택하여 테이블 목록을 반환한다고 가정합니다. 그런 다음 T1이 테이블 A를 삭제하고 커밋한 다음 T2가 테이블을 다시 나열합니다. 이제 테이블 A가 더 이상 나열되지 않습니다. T2가 삭제된 테이블을 쿼리하려고 하는 경우 Amazon Redshift는 "관계가 존재하지 않음(relation does not exist)" 오류를 반환합니다. 테이블 목록을 T2에 반환하거나 테이블 A가 존재하는지 확인하는 카탈로그 쿼리에는 사용자 테이블에서 수행되는 작업과 동일한 격리 규칙이 적용되지 않습니다.
이런 테이블의 업데이트를 위한 트랜잭션은 읽기 커밋된 격리 모드에서 실행됩니다.
PG-prefix 카탈로그 테이블은 SNAPSHOT 격리를 지원하지 않습니다.