인덱스 액세스 방법은 지원 여부를 선택할 수 있습니다 여러 프로세스에 의한 인덱스의 동시 업데이트. 만약 행동 양식PG_AM.amconcurrent플래그는 참입니다.PostgreSQL시스템 획득accesssharelock인덱스 스캔 및rowexclusivelock언제 인덱스 업데이트. 이러한 잠금 유형은 충돌하지 않기 때문에 액세스 방법은 세분화 된 처리를 담당합니다 잠금이 필요할 수 있습니다. 인덱스 전체에 대한 독점 잠금 토토 베이 생성, 파괴 또는 중에 만 취해집니다.Reindex. 언제amconcurrent거짓,postgresql여전히 획득accesssharelock인덱스 스캔 중에는accessexclusivelock업데이트 중. 이를 통해 업데이트가 인덱스를 사용하도록합니다. 주목하십시오 이것은 암시 적으로 인덱스 스캔이 읽기 전용이라고 가정합니다. 액세스 스캔 중에 인덱스를 수정할 수있는 방법은 여전히 동시 스캔의 경우를 처리하기 위해 자체 토토 베이 장치를 수행합니다.
백엔드 자체 자물쇠가 절대 충돌하지 않는다는 것을 상기하십시오. 그러므로, 비 일치한 인덱스 유형조차도 백엔드가 인덱스에 항목을 삽입하거나 삭제하는 경우 그 자체로 스캔하고 있습니다. (물론 이것은 필요합니다 지원 A업데이트인덱스를 사용합니다 업데이트 할 행을 찾으십시오.)
동시 업데이트를 지원하는 인덱스 유형 구축 일반적으로 필요한 것을 광범위하고 미묘한 분석이 필요합니다 행동. B- 트리 및 해시 인덱스 유형의 경우 읽을 수 있습니다. 관련된 디자인 결정src/backend/access/nbtree/readmeandsrc/backend/access/hash/readme.
지수 자체 내부 일관성 요구 사항을 제외하고, 동시 업데이트는 부모 테이블 (힙) 및 인덱스. 왜냐하면postgresql분리 인덱스의 힙에 대한 액세스 및 업데이트 인덱스가 힙과 일치하지 않는 창입니다. 우리는 다음 규칙 으로이 문제를 처리합니다.
인덱스 항목을 작성하기 전에 새 힙 항목이 만들어집니다. (따라서 동시 인덱스 스캔이 보지 못할 가능성이 높습니다. 힙 입구. 인덱스 리더가 원하기 때문에 괜찮습니다 어쨌든 커밋되지 않은 줄에 관심이 없습니다. 하지만 참조토토 핫 : 문서 : 8.1 : 색인 토토 핫 확인.)
힙 입력을 삭제할 때 (진공), 모든 인덱스 항목을 제거해야합니다 첫 번째.
동시 인덱스 유형의 경우 인덱스 스캔이
인덱스 페이지에서 핀이 마지막으로 반환 한 항목을 고정하는amgettuple
및Ambulkdelete
항목을 삭제할 수 없습니다
다른 백엔드에 의해 고정 된 페이지. 이것에 대한 필요성
규칙은 아래에 설명되어 있습니다.
인덱스가 동시에 있으면 인덱스가 가능합니다.
reader index index index index index index index index index진공그리고 다음에 도착합니다
그 후 해당 힙 입력이에 의해 제거되었습니다.진공. (비 전류 지수를 사용하면 그렇지 않습니다
상충되는 인덱스 레벨 잠금으로 인해 가능합니다
꺼내십시오.) 해당 항목이라면 심각한 문제가 발생하지 않습니다.
독자가 도달 할 때 번호는 여전히 사용하지 않습니다.
항목 슬롯은에 의해 무시됩니다.heap_fetch ()
. 그러나 세 번째 백엔드가 있다면 어떨까요?
이미 다른 것에 대한 항목 슬롯을 재사용 했습니까? AN을 사용할 때
MVCC 호환 스냅 샷, 새로운 것이기 때문에 아무런 문제가 없습니다
슬롯의 탑승자는
스냅 샷 테스트. 그러나 비 MVCC 호환 스냅 샷 (예 :
처럼SnapshotNow) 가능합니다
실제로 스캔과 일치하지 않는 행을 수락하고 반환합니다.
열쇠. 스캔을 요구 하여이 시나리오로부터 방어 할 수 있습니다.
모든 경우에 힙으로 다시 확인해야하지만
너무 비싸다. 대신, 우리는 인덱스 페이지의 핀을
독자가 여전히있을 수 있음을 나타내는 프록시"비행 중"인덱스 항목에서 일치까지
힙 입력. 만들기Ambulkdelete
그러한 핀의 블록진공독자가 완료되기 전에 힙 항목을 삭제할 수 없습니다.
이 솔루션은 런타임이 거의 들지 않으며 차단을 추가합니다.
실제로있는 드문 경우에만 오버 헤드
갈등.
이 솔루션은 인덱스 스캔이 필요합니다"동기": 각 힙 튜플을 가져와야합니다 해당 인덱스 항목을 스캔 한 직후. 이것은 여러 가지 이유로 비싸다."비동기"많은 TID를 수집하는 스캔 지수에서, 나중에 힙 튜플 만 방문하십시오. 인덱스 토토 베이 오버 헤드가 훨씬 적고 더 많은 것을 허용 할 수 있습니다. 효율적인 힙 액세스 패턴. 위의 분석에 따라 우리는해야합니다 비 MVCC 호환 스냅 샷에 동기식 접근 방식을 사용하십시오. 그러나 비동기 스캔은 MVCC를 사용하여 쿼리를 위해 작동합니다. 스냅 사진.
inAmgetmulti
인덱스 스캔, the
액세스 방법은
반환 된 튜플. (더 많은 것을 고정하는 것은 비현실적 일 것입니다
어쨌든 마지막.) 그러므로 그러한 스캔을 사용하는 것은 안전합니다.
MVCC 호환 스냅 샷으로.