Amazon Redshift는 2025년 11월 1일부터 새 Python UDF 생성을 더 이상 지원하지 않습니다. Python UDF를 사용하려면 이 날짜 이전에 UDF를 생성하세요. 기존 Python UDF는 정상적으로 계속 작동합니다. 자세한 내용은 블로그 게시물
직렬화 가능한 격리 오류 문제 해결
ERROR:1023 DETAIL: Redshift의 테이블에서 직렬화 가능한 격리 위반
Amazon Redshift에서 직렬화 가능 격리 오류를 감지하면 다음과 같은 오류 메시지가 표시됩니다.
ERROR:1023 DETAIL: Serializable isolation violation on table in Redshift
직렬화 가능 격리 오류를 해결하기 위해 다음과 같은 방법을 시도할 수 있습니다.
-
취소된 트랜잭션을 재시도합니다.
Amazon Redshift에서 동시 워크로드를 직렬화할 수 없음을 감지했습니다. 이는 일반적으로 오류가 발생한 트랜잭션을 재시도하여 해결할 수 있는 애플리케이션 논리의 차이를 나타냅니다. 문제가 지속되면 다른 방법 중 하나를 시도하세요.
-
동일한 원자성 트랜잭션에 있을 필요가 없는 모든 작업을 트랜잭션 외부로 이동합니다.
이 방법은 두 개의 트랜잭션 내에 있는 개별 작업이 다른 트랜잭션의 결과에 영향을 미칠 수 있는 방식으로 상호 참조하는 경우에 사용할 수 있습니다. 예를 들어 다음 두 세션은 각자 트랜잭션을 시작합니다.
Session1_Redshift=# begin;Session2_Redshift=# begin;각 트랜잭션에 있는 SELECT 문의 결과는 다른 트랜잭션에 있는 INSERT 문에 영향을 받을 수 있습니다. 다시 말해 다음과 같은 문을 어떤 순서로든 직렬 방식으로 실행한다고 가정합시다. 어떤 경우에도 트랜잭션이 동시에 실행된 경우보다 한 행을 더 반환하는 SELECT 문 중 하나를 얻게 됩니다. 작업을 직렬로 실행하여 동시에 실행할 때와 동일한 결과를 산출할 수 있는 순서는 없습니다. 따라서 마지막으로 실행되는 작업으로 인해 직렬화 가능 격리 오류가 발생합니다.
Session1_Redshift=# select * from tab1; Session1_Redshift=# insert into tab2 values (1);Session2_Redshift=# insert into tab1 values (1); Session2_Redshift=# select * from tab2;많은 경우 SELECT 문의 결과는 중요하지 않습니다. 다시 말해 트랜잭션 내 작업의 원자성은 중요하지 않습니다. 이러한 경우에는 다음 예와 같이 SELECT 문을 트랜잭션 외부로 이동합니다.
Session1_Redshift=# begin; Session1_Redshift=# insert into tab1 values (1) Session1_Redshift=# end; Session1_Redshift=# select * from tab2;Session2_Redshift # select * from tab1; Session2_Redshift=# begin; Session2_Redshift=# insert into tab2 values (1) Session2_Redshift=# end;이 예의 경우 트랜잭션 내 교차 참조는 없습니다. 두 가지 INSERT 문은 서로에게 영향을 미치지 않습니다. 이 예의 경우 트랜잭션이 직렬로 실행되어 동시에 실행될 때와 동일한 결과를 산출하는 순서가 최소 한 개 있습니다. 이는 트랜잭션을 직렬화할 수 있음을 뜻합니다.
-
각 세션에서 모든 테이블을 잠가 직렬화를 강제 실행하세요.
LOCK 명령은 직렬화 가능 격리 오류를 발생시킬 수 있는 작업을 차단합니다. LOCK 명령 사용 시 다음을 반드시 수행하세요.
-
트랜잭션 내 읽기 전용 SELECT 문의 영향을 받는 테이블을 포함해 트랜잭션의 영향을 받는 모든 테이블을 잠급니다.
-
작업이 수행되는 순서에 상관없이 테이블을 동일한 순서로 잠급니다.
-
작업을 수행하기 전에 트랜잭션을 시작하는 시점에 모든 테이블을 잠급니다.
-
동시 트랜잭션에는 스냅샷 격리를 사용하세요.
ALTER DATABASE 명령을 스냅샷 격리와 함께 사용하세요. ALTER DATABASE의 SNAPSHOT 파라미터에 대한 자세한 내용은 파라미터 섹션을 참조하세요.
ERROR:1018 DETAIL: 관계가 존재하지 않음
여러 세션에서 동시 Amazon Redshift 작업을 실행하면 다음과 같은 오류 메시지가 표시됩니다.
ERROR: 1018 DETAIL: Relation does not exist.
Amazon Redshift의 트랜잭션은 스냅샷 격리를 따릅니다. 트랜잭션이 시작된 후 Amazon Redshift는 데이터베이스의 스냅샷을 만듭니다. 트랜잭션의 전체 수명 주기 동안 트랜잭션은 스냅샷에 반영된 데이터베이스 상태에서 작동합니다. 트랜잭션이 스냅샷에 존재하지 않는 테이블에서 읽는 경우 이전에 표시된 1018 오류 메시지가 나타납니다. 트랜잭션이 스냅샷을 만든 후 다른 동시 트랜잭션이 테이블을 생성하더라도 트랜잭션은 새로 생성된 테이블에서 읽을 수 없습니다.
이 직렬화 격리 오류를 해결하기 위해 테이블이 존재함을 알고 있는 시점으로 트랜잭션 시작을 이동하려고 할 수 있습니다.
테이블이 다른 트랜잭션에 의해 생성된 경우 이 시점은 적어도 해당 트랜잭션이 커밋된 이후입니다. 또한 테이블을 삭제했을 수 있는 동시 트랜잭션이 커밋되지 않았는지 확인합니다.
session1 = # BEGIN;
session1 = # DROP TABLE A;
session1 = # COMMIT;
session2 = # BEGIN;
session3 = # BEGIN;
session3 = # CREATE TABLE A (id INT);
session3 = # COMMIT;
session2 = # SELECT * FROM A;
session2에 의해 읽기 작업으로 실행되는 마지막 작업이 직렬화 가능한 격리 오류를 발생시킵니다. 이 오류는 session2가 스냅샷을 만들고 테이블이 커밋된 session1에 의해 이미 삭제된 경우 발생합니다. 즉, 동시 session3이 테이블을 생성하더라도 session2는 테이블이 스냅샷에 없기 때문에 테이블을 볼 수 없습니다.
이 오류를 해결하기 위해 다음과 같이 세션을 재정렬할 수 있습니다.
session1 = # BEGIN;
session1 = # DROP TABLE A;
session1 = # COMMIT;
session3 = # BEGIN; session3 = # CREATE TABLE A (id INT); session3 = # COMMIT;
session2 = # BEGIN;
session2 = # SELECT * FROM A;
이제 session2가 스냅샷을 만들 때 session3은 이미 커밋되었으며 테이블은 데이터베이스에 있습니다. Session2는 오류 없이 테이블에서 읽을 수 있습니다.