- page 135 ROWID에 의한 테이블 액세스가 고비용 연산이라는 내용이 있는데 어떤 로직으로 액세스 하는지 궁금해서 찾아보았다.
1. rowId로 데이터를 가져오는 과정과 Cache Buffer Chains Latch
1.1 rowId 기반 데이터 검색의 주요 단계
1. rowId의 구성 정보 분석
- rowId는 다음 정보를 포함
- 데이터 오브젝트 번호: 테이블/파티션 식별.
- 데이터 블록 주소: 특정 데이터 블록 위치.
- 블록 내 로우 번호: 블록 내부의 행 위치.
데이터베이스는 이를 기반으로 데이터를 정확히 찾아감
2. 캐시 버퍼 체인 탐색 시작
데이터 블록 주소를 해싱(Hashing)하여 Cache Buffer Chains의 특정 해시 체인으로 이동.
Cache Buffer Chains Latch를 획득하여 해시 체인에 접근 권한을 확보.
3. 데이터 블록 검색
해당 해시 체인에서 데이터 블록을 검색:
버퍼 헤더(Buffer Header)를 통해 블록을 식별.
데이터 블록이 메모리(Buffer Cache)에 있으면 바로 사용.
메모리에 없으면 디스크 I/O로 데이터를 읽어와 Buffer Cache에 적재.
4. 데이터 블록 내 로우 접근
rowId의 로우 번호를 사용하여 데이터 블록 내 특정 행(Slot)을 찾아 데이터를 읽거나 수정.
5. 래치 해제 및 결과 반환
작업이 완료되면 Cache Buffer Chains Latch를 해제.
데이터를 사용자에게 반환.
1.2 Cache Buffer Chains Latch의 역할
- 여러 프로세스가 동일한 해시 체인을 탐색하지 못하도록 Cache Buffer Chains Latch를 사용해 해당 해시 체인을 잠금.
- 이 래치는 다음 상황에서 오래 대기하게 될 수 있음:
- 동일한 해시 체인을 동시에 탐색하려는 프로세스가 많을 때.
- 데이터 블록이 메모리에 없고 디스크 I/O를 통해 로드될 때 대기 시간이 길어질 경우.
2. rowId와 래치가 엮여 오래 걸리는 경우
2.1 rowId 조회 시 병목 발생 지점
1. 해시 체인 경합 (Latch Contention)
동일한 해시 체인에 여러 프로세스가 접근하려 하면, 한 프로세스만 래치를 얻고 나머지는 대기.
이로 인해 래치 획득 시간이 늘어나고 작업이 지연.
2. 디스크 I/O로 인한 추가 대기
데이터 블록이 Buffer Cache에 없으면 디스크에서 데이터를 읽어와야 하며, 이 동안 래치가 점유된 상태로 유지.
3. 버퍼 락(Buffer Lock) 경합
데이터를 수정하려는 프로세스가 이미 다른 프로세스에 의해 락이 설정된 경우, 추가 대기 발생.
읽기와 쓰기 작업이 겹칠 때도 문제가 발생.
2.2 rowId로 데이터 접근 시 래치와 락이 연쇄적으로 영향을 미치는 예
예: rowId로 동일 블록을 다수의 프로세스가 조회
- 여러 트랜잭션이 동일한 rowId(AAAAAA+BBBBBB+001)를 기반으로 데이터를 요청.
- 모든 트랜잭션이 데이터 블록 주소(BBBBBB)를 해싱하여 동일한 해시 체인으로 접근.
- Cache Buffer Chains Latch에서 첫 번째 병목 발생:
- 한 프로세스만 래치를 획득하고, 나머지는 대기.
- 래치를 획득한 프로세스가:
- 데이터 블록을 Buffer Cache에서 찾거나, 없으면 디스크에서 로드.
- 디스크 I/O 중에도 래치를 유지해 다른 프로세스의 대기가 길어짐.
- 데이터 블록이 메모리에 로드된 뒤:
- 다른 프로세스가 동일 블록에 대해 Buffer Lock을 요청.
- 읽기와 쓰기 작업이 겹치면, 락 경합으로 인해 추가 대기.
결과적으로, 래치 대기와 락 대기가 반복되면서 성능 저하가 심화.
3. 병목이 오래 걸리는 이유
3.1 Cache Buffer Chains Latch 경합
- 데이터 블록 주소를 기반으로 해시 체인에 접근할 때 래치 경쟁이 발생.
- 특히 rowId가 특정 블록으로 집중될 경우(예: 인기 데이터나 핫스팟), 병목이 더 심화.
3.2 버퍼 락과의 연쇄 대기
- 래치를 획득한 프로세스가 데이터 블록에 락을 설정하면, 이후 프로세스는 락 대기로 전환.
- 래치와 락 대기 시간이 겹치면 전체 작업 지연이 증가.
3.3 디스크 I/O와의 연관성
- 데이터 블록이 메모리에 없으면 디스크에서 읽어오는 동안 래치를 점유.
- 디스크 읽기 속도에 따라 대기 시간이 더욱 길어질 수 있음.
4. 결론
rowId로 데이터를 가져오는 과정에서 캐시 버퍼 체인 래치는 데이터 블록 검색 단계에서 발생하며, 버퍼 락은 데이터 블록 수정 또는 동시 접근 시 경합을 유발.
이 두 가지 병목은 데이터 액세스 패턴과 데이터 분산 설계에 따라 심화될 수 있으며, 이를 완화하려면 캐싱, 데이터 분산, 설계 최적화가 필수적.