| PostgreSQL 9.1.24 문서 | ||||
|---|---|---|---|---|
| 스포츠 토토 : 문서 : 9.1 : 소개 | 스포츠 토토 결과 : 문서 : 9.1 : 동시성 제어 | 13장. 동시성 제어 | PostgreSQL : 문서 : 9.1 : 명시 적 사설 토토 사이트 | |
그SQL표준은 정의합니다 네 가지 수준의 트랜잭션 격리. 가장 엄격한 것은 단락의 표준에 의해 정의된 직렬화 가능 이는 직렬화 가능 세트의 동시 실행을 의미합니다. 트랜잭션은 실행과 동일한 효과를 생성하도록 보장됩니다. 순서대로 한 번에 하나씩. 나머지 3개 레벨은 사이의 상호 작용으로 인해 발생하는 현상으로 정의됩니다. 각 수준에서 발생해서는 안되는 동시 트랜잭션. 는 표준에서는 직렬화 가능의 정의로 인해 이러한 현상 중 일부는 해당 수준에서 가능합니다. (이건 거의 놀라운 일 - 거래의 효과가 다음과 같아야 한다면 한 번에 하나씩 실행한 것과 일치하는 것을 어떻게 알 수 있습니까? 상호작용으로 인한 현상은 없나요?)
다양한 수준에서 금지되는 현상은 다음과 같습니다:
배트맨 토토은 동시 작업에 의해 작성된 데이터를 읽습니다. 커밋되지 않은 배트맨 토토입니다.
트랜잭션은 이전에 읽은 데이터를 다시 읽고 다른 트랜잭션에 의해 데이터가 수정되었음을 발견함 (초기 읽기 이후 커밋됨).
배트맨 토토은 일련의 결과를 반환하는 쿼리를 다시 실행합니다. 검색 조건을 만족하고 해당 집합이 발견된 행 조건을 만족하는 행 중 다른 항목으로 인해 변경되었습니다. 최근에 커밋된 배트맨 토토입니다.
네 가지 배트맨 토토 격리 수준과 해당 수준 동작은에 설명되어 있습니다.표 13-1.
표 13-1. 표준SQL배트맨 토토 격리 수준
| 격리 수준 | 더티 읽기 | 반복 불배트맨 토토 읽기 | 팬텀 읽기 |
|---|---|---|---|
| 커밋되지 않은 읽기 | 가능 | 가능 | 가능 |
| 읽기 커밋 | 불가능 | 가능 | 가능 |
| 반복 읽기 | 불가능 | 불가능 | 가능 |
| 직렬화 가능 | 불가능 | 불가능 | 불가능 |
에포스트그레SQL할 수 있어요 네 가지 표준 배트맨 토토 격리 수준 중 하나를 요청합니다. 그러나 내부적으로는 세 가지 격리 수준만 있습니다. 이는 Read Committed, Repeatable Read, 그리고 직렬화 가능합니다. 커밋되지 않은 읽기 수준을 선택하면 실제로 읽기 커밋이 이루어지며 팬텀 읽기는 불가능합니다.PostgreSQL구현 반복 가능한 읽기이므로 실제 격리 수준은 더 엄격할 수 있습니다. 당신이 선택한 것보다 이는 SQL 표준에서 허용됩니다. 네 가지 격리 수준은 어떤 현상이 발생해서는 안 되는지 정의할 뿐입니다. 어떤 현상이 일어나야 하는지 정의하지 않습니다. 는 그 이유는PostgreSQL만 세 가지 격리 수준을 제공하는 것은 이것이 유일하게 합리적인 수준이라는 것입니다. 표준 격리 수준을 다중 버전에 매핑하는 방법 동시성 제어 아키텍처. 사용 가능한 동작 격리 수준은 다음 하위 섹션에 자세히 설명되어 있습니다.
트랜잭션의 배트맨 토토 격리 수준을 설정하려면 다음을 사용하십시오. 명령세트 거래.
읽기 커밋됨기본값입니다 격리 수준PostgreSQL. 트랜잭션이 이 격리 수준을 사용하는 경우, a선택쿼리(a 없음용 업데이트/공유절)은 이전에 커밋된 데이터만 봅니다. 쿼리가 시작되었습니다. 커밋되지 않은 데이터나 변경 사항을 볼 수 없습니다. 동시 트랜잭션에 의한 쿼리 실행 중에 커밋됩니다. 에서 효과, a선택쿼리가 스냅샷을 봅니다. 쿼리가 실행되기 시작하는 순간의 데이터베이스입니다. 그러나선택효과가 보입니다 자체 트랜잭션 내에서 실행된 이전 업데이트의 경우에도 아직 커밋되지는 않았지만. 또한 두 가지를 참고하세요 연속적인선택명령은 볼 수 있습니다 단일 데이터 내에 있더라도 서로 다른 데이터 배트맨 토토 중 다른 배트맨 토토이 변경 사항을 커밋하는 경우 첫 번째 실행선택.
업데이트, 삭제, 선택 대상 업데이트및공유 선택명령은 다음과 동일하게 동작합니다선택에 대상 행 검색 조건: 대상 행만 찾습니다. 명령 시작 시간을 기준으로 커밋된 행입니다. 그러나, 이러한 대상 행은 이미 업데이트되었거나 삭제되었을 수 있습니다. 또는 잠긴 경우) 다른 동시 트랜잭션에 의해 발견. 이 경우 업데이트할 예정인 업데이트 프로그램은 다음을 기다립니다. 커밋하거나 롤백하기 위해 먼저 트랜잭션을 업데이트합니다(해당되는 경우). 아직 진행 중입니다.) 첫 번째 업데이트 프로그램이 롤백되면 효과는 무효화되고 두 번째 업데이트는 계속 진행할 수 있습니다. 원래 발견된 행을 업데이트합니다. 첫 번째 업데이트인 경우 커밋하면 두 번째 업데이터는 첫 번째 업데이터가 행을 무시합니다. 업데이터가 삭제했습니다. 그렇지 않으면 적용을 시도합니다. 업데이트된 버전의 행에 대한 작업입니다. 검색 명령의 조건(어디절)을 재평가하여 업데이트된 버전이 있는지 확인합니다. 행은 여전히 검색 조건과 일치합니다. 그렇다면 두 번째 업데이터는 업데이트된 버전을 사용하여 작업을 진행합니다. 행의. 의 경우선택 대상 업데이트그리고공유 선택, 이거 이는 잠긴 행의 업데이트된 버전임을 의미하며 고객에게 반환되었습니다.
위의 규칙으로 인해 업데이트가 가능합니다. 일관되지 않은 스냅샷을 보는 명령: 효과를 볼 수 있습니다. 시도하고 있는 동일한 행에 대한 동시 업데이트 명령 수 업데이트할 수 있지만 해당 명령의 효과는 표시되지 않습니다. 데이터베이스의 다른 행. 이 동작으로 인해 읽기 커밋이 이루어집니다. 복잡한 검색이 포함된 명령에는 적합하지 않은 모드 조건; 그러나 더 간단한 경우에는 적합합니다. 에 대한 예를 들어 거래를 통해 은행 잔고를 업데이트하는 것을 고려해 보세요. 좋아요:
시작; UPDATE 계정 SET 잔액 = 잔액 + 100.00 WHERE acctnum = 12345; UPDATE 계정 SET 잔액 = 잔액 - 100.00 WHERE acctnum = 7534; 커밋;
두 개의 트랜잭션이 동시에 변경을 시도하면 계정 잔액 12345, 우리는 분명히 두 번째 잔액을 원합니다 계정의 업데이트된 버전으로 시작하는 거래 행. 각 명령은 미리 결정된 명령에만 영향을 미치기 때문에 행의 업데이트된 버전을 볼 수 있도록 하는 것은 그렇지 않습니다. 골치 아픈 불일치를 만들어냅니다.
더 복잡하게 사용하면 읽기에서 바람직하지 않은 결과가 발생할 수 있습니다. 커밋 모드. 예를 들어 다음을 고려해보세요.삭제실행 중인 데이터에 대해 작동하는 명령 다른 사람에 의해 제한 기준에 추가되거나 제거되었습니다. 명령(예: 가정웹사이트은 2열 테이블website.hits같음9그리고10:
시작; 업데이트 웹사이트 SET 조회수 = 조회수 + 1; -- 다른 세션에서 실행: DELETE FROM 웹사이트 WHERE 조회수 = 10; 커밋;
그삭제심지어 효과가 없습니다. 하지만website.hits = 10앞과 뒤의 행업데이트. 이 업데이트 전 행 값 때문에 발생함9건너뛰고, 다음 경우업데이트완료하고삭제잠금을 얻었으며 새 행 값은 no입니다. 더 이상10그러나11, 더 이상 기준과 일치하지 않습니다.
커밋 읽기 모드는 각 명령을 새로운 명령으로 시작하기 때문입니다. 해당 시점까지 커밋된 모든 배트맨 토토을 포함하는 스냅샷 즉시 동일한 배트맨 토토의 후속 명령이 표시됩니다. 커밋된 동시 배트맨 토토의 효과 사건. 위에서 문제가 되는 점은 a싱글명령은 절대적으로 데이터베이스의 일관된 보기.
Read Committed가 제공하는 부분 트랜잭션 격리 모드는 많은 응용 프로그램에 적합하며 이 모드는 빠릅니다. 사용이 간편합니다. 그러나 모든 경우에 충분하지는 않습니다. 복잡한 쿼리 및 업데이트를 수행하는 애플리케이션에는 다음이 필요할 수 있습니다. 읽기보다 데이터베이스에 대한 더 엄격하고 일관된 보기 커밋 모드가 제공됩니다.
그반복 읽기격리 수준 트랜잭션이 시작되기 전에 커밋된 데이터만 볼 수 있습니다. 그것은 결코 커밋되지 않은 데이터나 커밋된 변경 사항을 확인합니다. 동시 트랜잭션에 의한 트랜잭션 실행. (단, 쿼리는 내에서 실행된 이전 업데이트의 효과를 확인합니다. 아직 커밋되지 않은 경우에도 자체 트랜잭션입니다.) 이는 다음에서 요구하는 것보다 더 강력한 보증입니다.SQL이에 대한 표준 격리 수준이며 다음에 설명된 모든 현상을 방지합니다.테이블 13-1. 위에서 언급했듯이 이는 다음에서 특별히 허용됩니다. 만 설명하는 표준최소각 보호 격리 수준을 제공해야 합니다.
이 수준은 쿼리가 실행된다는 점에서 읽기 커밋과 다릅니다. 반복 가능한 읽기 트랜잭션에서 스냅샷은 다음과 같습니다. 의 시작거래, 처음부터 아님 트랜잭션 내의 현재 쿼리에 대한 정보입니다. 따라서 연속적인선택a 내의 명령단일거래 동일 참조 즉, 다른 트랜잭션에 의해 변경된 내용을 볼 수 없습니다. 자체 트랜잭션이 시작된 후에 커밋되었습니다.
이 수준을 사용하는 응용 프로그램은 재시도할 준비가 되어 있어야 합니다. 직렬화 실패로 인한 거래.
업데이트, 삭제, 선택 대상 업데이트및공유 선택명령은 다음과 동일하게 동작합니다SELECT에 대상 행 검색 조건: 대상 행만 찾습니다. 트랜잭션 시작 시간을 기준으로 커밋된 행입니다. 그러나 이러한 대상 행은 이미 업데이트되었을 수 있습니다(또는 삭제되거나 잠김)에 의해 다른 동시 트랜잭션에 의해 발견된 시간입니다. 이 경우 반복 가능한 읽기 트랜잭션은 첫 번째 업데이트 트랜잭션이 커밋되거나 롤될 때까지 기다립니다. 뒤로(아직 진행 중인 경우) 첫 번째 업데이터가 굴러가는 경우 되돌리면 그 효과가 무효화되고 반복 읽기가 가능해집니다. 트랜잭션은 원래 발견된 행 업데이트를 진행할 수 있습니다. 그러나 첫 번째 업데이트 프로그램이 커밋(그리고 실제로 업데이트되거나 잠긴 것이 아니라 행을 삭제한 다음) 반복 가능한 읽기 메시지와 함께 트랜잭션이 롤백됩니다.
오류: 동시 업데이트로 인해 액세스를 직렬화할 수 없습니다.
반복 가능한 읽기 트랜잭션은 수정하거나 잠글 수 없기 때문입니다. 반복 읽기 이후 다른 트랜잭션에 의해 변경된 행 거래가 시작되었습니다.
응용프로그램이 이 오류 메시지를 받으면, 현재 트랜잭션을 중단하고 전체 트랜잭션을 다시 시도합니다. 처음부터. 두 번째로 거래가 완료되었습니다. 이전에 커밋된 변경 사항이 초기 작업의 일부로 표시됩니다. 데이터베이스 보기이므로 사용 시 논리적 충돌이 없습니다. 행의 새 버전을 새 행의 시작점으로 사용 거래 업데이트.
거래 업데이트만 필요할 수 있다는 점에 유의하세요. 재시도; 읽기 전용 트랜잭션에는 직렬화가 적용되지 않습니다. 충돌.
반복 읽기 모드는 다음을 엄격하게 보장합니다. 각 트랜잭션은 데이터베이스의 완전히 안정적인 보기를 봅니다. 그러나 이러한 견해가 항상 일관되지는 않을 것이다. 일부 직렬(한 번에 하나씩) 동시 실행 같은 수준의 거래. 예를 들어, 읽기 전용이라도 이 수준의 거래는 다음과 같이 업데이트된 제어 레코드를 볼 수 있습니다. 배치가 완료되었음을 표시하지만아님상세 기록 중 하나 보기 이는 논리적으로 배치의 일부입니다. 왜냐하면 이전에 읽은 내용이기 때문입니다. 통제 기록의 개정. 사업을 강제하려는 시도 이 격리 수준에서 실행되는 트랜잭션에 의한 규칙은 명시적 잠금을 주의 깊게 사용하지 않고도 올바르게 작동할 가능성이 높습니다. 충돌하는 거래를 차단합니다.
참고:이전PostgreSQL버전 9.1, 다음 요청 제공된 직렬화 가능 배트맨 토토 격리 수준 여기에 설명된 것과 정확히 동일한 동작입니다. 유지하려면 레거시 직렬화 가능 동작, 반복 가능한 읽기는 이제 요청했습니다.
그직렬화 가능격리 수준 가장 엄격한 트랜잭션 격리를 제공합니다. 이 수준 마치 트랜잭션이 실행된 것처럼 직렬 트랜잭션 실행을 에뮬레이트합니다. 순차적으로 실행되기보다는 순차적으로 실행되었습니다. 동시에. 그러나 Repeatable Read 수준과 마찬가지로 이 수준을 사용하는 애플리케이션은 재시도할 준비가 되어 있어야 합니다. 직렬화 실패로 인한 트랜잭션. 사실, 이 격리 수준은 반복 읽기와 정확히 동일하게 작동합니다. 단, 발생할 수 있는 조건을 모니터링하는 것은 제외됩니다. 직렬화 가능한 트랜잭션의 동시 집합 실행 가능한 모든 일련의 내용과 일치하지 않는 방식으로 행동합니다(하나 한 번에) 해당 트랜잭션을 실행합니다. 이번 모니터링 현재 존재하는 것 이상의 차단을 도입하지 않습니다. 반복 읽기가 가능하지만 모니터링에 약간의 오버헤드가 있습니다. 및 다음을 유발할 수 있는 조건 감지직렬화 이상a를 트리거합니다직렬화 실패.
예를 들어 테이블을 생각해 보세요.마이탭, 처음에는 다음을 포함합니다.
클래스 | 가치
-----+-------
1 | 10
1 | 20
2 | 100
2 | 200
직렬화 가능한 트랜잭션 A가 다음을 계산한다고 가정합니다:
WHERE 클래스 = 1인 mytab에서 SUM(값) 선택;
그리고 결과(30)를 다음과 같이 삽입합니다.값다음 행에클래스 = 2. 동시에 직렬화 가능한 트랜잭션 B는 다음을 계산합니다.
SELECT SUM(값) FROM mytab WHERE 클래스 = 2;
결과 300을 얻고 새 행에 삽입합니다. 와 함께클래스 = 1. 그런 다음 두 트랜잭션 모두 커밋을 시도합니다. 둘 중 하나라면 반복 읽기 격리에서 트랜잭션이 실행 중이었습니다. 수준에서는 둘 다 커밋이 허용됩니다. 하지만 없기 때문에 다음을 사용하여 결과와 일치하는 일련의 실행 순서 직렬화 가능한 트랜잭션을 사용하면 하나의 트랜잭션을 커밋할 수 있습니다. 다음 메시지와 함께 다른 하나는 롤백됩니다.
오류: 배트맨 토토 간의 읽기/쓰기 종속성으로 인해 액세스를 직렬화할 수 없습니다.
A가 B보다 먼저 실행했다면 B는 합계를 300이 아닌 330으로 계산하고 다른 순서도 마찬가지로 계산합니다. A가 계산한 다른 합계가 발생했을 것입니다.
진정한 직렬성을 보장하기 위해PostgreSQL사용술어 잠금, 이는 다음을 유지함을 의미합니다. 쓰기가 언제 이루어졌는지 결정할 수 있는 잠금 동시 읽기의 이전 읽기 결과에 대한 영향 트랜잭션을 먼저 실행했습니다. 에서포스트그레SQL이 잠금은 어떤 문제도 일으키지 않습니다. 차단하므로 다음과 같이 할 수 있습니다.아님어떤 역할이라도 하여 교착상태. 이는 종속성을 식별하고 플래그를 지정하는 데 사용됩니다. 특정 상황에서 동시 직렬화 가능 트랜잭션 조합으로 인해 직렬화 이상이 발생할 수 있습니다. 대조적으로, 읽기 커밋 또는 반복 가능한 읽기 트랜잭션 데이터 일관성을 보장하기 위해 잠금을 해제해야 할 수도 있습니다. 전체 테이블을 사용하려는 다른 사용자를 차단할 수 있습니다. 해당 테이블 또는 다음을 사용할 수 있습니다.선택 업데이트또는공유 선택어느 다른 배트맨 토토을 차단할 수 있을 뿐만 아니라 디스크 문제를 일으킬 수 있습니다. 액세스합니다.
술어 잠금PostgreSQL, 대부분의 다른 데이터베이스와 마찬가지로 시스템은 트랜잭션을 통해 실제로 액세스되는 데이터를 기반으로 합니다. 이는 다음 항목에 표시됩니다.pg_locksa가 포함된 시스템 보기모드의SIReadLock. 동안 획득한 특정 잠금 쿼리 실행은 쿼리에서 사용하는 계획에 따라 달라집니다. 여러 개의 세분화된 잠금(예: 튜플 잠금)이 있을 수 있습니다. 더 적은 수의 성긴 잠금(예: 페이지 잠금)으로 결합 거래 과정에서 소진을 방지하기 위해 잠금을 추적하는 데 사용되는 메모리입니다. 갑읽기 만트랜잭션이 SIRead 잠금을 해제할 수 있습니다. 완료되기 전에 충돌이 여전히 발생하지 않는 것으로 감지되면 직렬화 이상 현상이 발생할 수 있습니다. 사실,읽기 전용거래는 종종 시작할 때 그 사실을 확립하고 어떤 조치도 취하지 않을 수 있습니다. 조건부 잠금. 명시적으로 요청하는 경우직렬화 가능 읽기 전용 연기 가능거래, 이 사실이 확인될 때까지 차단됩니다. (이것은만경우 직렬화 가능한 트랜잭션은 차단되지만 반복 읽기는 가능합니다. 트랜잭션은 그렇지 않습니다.) 반면에 SIRead 잠금에는 종종 다음이 필요합니다. 읽기가 겹칠 때까지 트랜잭션 커밋 이후를 유지합니다. 쓰기 트랜잭션이 완료되었습니다.
직렬화 가능한 트랜잭션을 일관되게 사용하면 단순화될 수 있습니다. 개발. 모든 동시 세트가 보장됩니다. 직렬화 가능한 트랜잭션은 마치 직렬화 가능한 트랜잭션과 동일한 효과를 갖습니다. 한 번에 하나씩 실행되었다는 것은 쓰여진 대로 단일 거래는 다음과 같은 경우 올바른 일을 할 것입니다. 자체적으로 실행되므로 해당 작업을 수행할 수 있다는 확신을 가질 수 있습니다. 직렬화 가능한 트랜잭션이 혼합되어 있는 경우에도 올바른 것입니다. 다른 거래에 대한 정보 없이 할 수도 있습니다. 이를 사용하는 환경이 중요합니다. 기술에는 직렬화를 처리하는 일반화된 방법이 있습니다. 실패(항상 SQLSTATE 값으로 반환됨) '40001'), 정확히 어느 것인지 예측하기가 매우 어렵기 때문입니다. 트랜잭션이 읽기/쓰기 종속성에 기여할 수 있습니다. 직렬화 이상 현상을 방지하려면 롤백해야 합니다. 읽기/쓰기 종속성을 모니터링하는 데에는 비용이 듭니다. 종료된 트랜잭션의 재시작 직렬화에 실패했지만 비용과 균형을 이뤘습니다. 명시적 잠금 사용과 관련된 차단 및업데이트를 위해 선택또는선택 공유용, 직렬화 가능한 트랜잭션이 최고입니다 일부 환경에 대한 성능 선택.
직렬화 가능에 의존할 때 최적의 성능을 위해 동시성 제어를 위한 트랜잭션에서는 이러한 문제를 해결해야 합니다. 고려됨:
거래를 다음으로 선언읽기 만가능하다면.
다음을 사용하여 활성 연결 수를 제어합니다. 필요한 경우 연결 풀. 이것은 항상 중요한 것입니다 성능을 고려하지만 특히 직렬화 가능을 사용하는 바쁜 시스템에서 중요 거래.
단일 거래에 필요한 것보다 더 많은 것을 투자하지 마십시오 무결성 목적.
연결을 매달아 두지 마십시오"거래 유휴"보다 길다 필요합니다.
명시적인 잠금을 제거합니다.선택 대상 업데이트및공유 선택자동 보호로 인해 더 이상 필요하지 않은 곳 직렬화 가능한 트랜잭션에 의해 제공됩니다.
시스템이 여러 페이지 수준을 강제로 결합해야 하는 경우 조건자 잠금을 단일 관계 수준 조건자 잠금으로 변경 조건자 잠금 테이블의 메모리가 부족하기 때문에 직렬화 실패율이 증가할 수 있습니다. 증가시켜 이를 방지할 수 있습니다.max_pred_locks_per_transaction.
순차 스캔에는 항상 관계 수준 조건자 잠금. 이로 인해 다음이 발생할 수 있습니다. 직렬화 실패율이 증가합니다. 도움이 될 수도 있습니다 줄여 인덱스 스캔 사용을 장려합니다.random_page_cost및/또는 증가cpu_tuple_cost. 배트맨 토토 롤백 감소와 쿼리 실행의 전반적인 변경 사항에 대해 다시 시작됩니다. 시간.