IT기술/Oracle

성능 고도화 1 - 02 트랜잭션과 Lock

dobbby 2014. 1. 21. 17:57
반응형

DB2, SQLServer, Sybase 등은 Lock을 통해 읽기 일관성을 구현하지만, 오라클은 Undo 데이터를 이용해 읽기 일관성을 구현한다.

Undo 에 저장된 정보를 이용해 쿼리가 시작된 시점을 기준으로 일관성 있는 결과집합을 생성해낸다.

 

01 트랜잭션 동시성 제어

(1) 동시성 제어

다중 사용자 환경에서 발생할 수 있는 갖가지 동시성 문제에 대한 충분한 고려 없이 시스템 개발이 이루어지는 문제

동시성 제어란 동시에 실행되는 트랜잭션 수를 최대화하면서도 입력, 수정, 삭제 검색 시 데이터의 무결성이 유지될 수 있도록 노력하는 것

동시성 (Concurrency): 다중 사용자가 같은 데이터를 동시에 액세스

일관성 (Consistency): 자신이 발생시킨 변경 사항과 다른 트랜잭션의 변경사항을 포함해 일관성 있는 상태로 데이터를 제공

 

(2) 트랜잭션이란?

여러 개의 수정작업이 하나의 작업처럼 전부 처리되거나 아예 전부 처리가 안되도록 하는 것인데, 이러한 일의 최소단위를 트랜잭션이라 한다. (원자성)

 

(3) 트랜잭션의 특징 (ACID)

- 원자성 (Atomicity): 더이상 분해 불가능한 업무의 최소 단위

- 일관성 (Consistency): 트랜잭션이 그 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 변환한다.

- 격리성 (Isolation): 트랜잭션이 실행 중에 생성하는 중간 결과는 다른 트랜잭션이 접근할 수 없다.

- 영속성 (Durability): 실행을 성공적으로 완료하면 결과는 데이터베이스에 영속적으로 저장된다.

 

 

 

 

 

02 트랜잭션 수준 읽기 일관성

(1) 트랜잭션 수준 읽기 일관성이란?

문장수준 읽기 일관성은 쿼리가 시작된 시점을 기준으로 데이터를 일관성 있게 읽어들이는 것을 말한다.

트랜잭션 수준 읽기 일관성은 트랜잭션이 시작된 시점을 기준으로 일관성 있게 데이터를 읽어들이는 것을 말한다.

오라클은 완벽한 문장수준의 읽기 일관성을 보장하지만, 트랜잭션에 대해서는 기본적으로 보장하지 않는다.

트랜잭션 수준으로 읽기 일관성을 강화하려면 트랜잭션 고립화 수준을 높여주어야 한다.

 

(2) 트랜잭션 고립화 수준

레벨 0 (=Read Uncommitted)

- 트랜잭션에서 처리 중인, 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용

레벨 1 (=Read Committed)

- Dirty Read 방지: 트랜잭션이 커밋되어 확정된 데이터만 읽는 것을 허용

레벨 2 (=Repeatable Read)

- 선행 트랜잭션이 읽은 데이터는 트랜잭션이 종료될 때까지 후행 트랜잭션이 갱신하거나 삭제하는 것을 불허함으로써

같은 데이터를 두 번 쿼리했을 때 일관성 있는 결과를 리턴

레벨 3 (=Serializable)

- 선행 트랜잭션이 읽은 데이터를 후행 트랜잭션이 갱신하거나 삭제하지 못할 뿐만 아니라 중간에 새로운 레코드를 삽입하는 것도 막아줌

 

낮은 단계의 트랜잭션 고립화 수준을 사용할 때 발생하는 세가지 현상

- Dirty Read (=Uncommitted Dependency)

- Non-Repeatable Read (=Inconsistent Analysis)

- Phantom Read

 

(3) Dirty Read

아직 커밋되지 않은 수정 중인 데이터를 다른 트랜잭션에서 읽을 수 있도록 허용할 때 발생한다.

 

(4) Non-Repeatable Read

한 트랜잭션 내에서 같은 쿼리를 두 번 수행할 때, 그 사이에 다른 트랜잭션이 값을 수정 또는 삭제함으로써 

두 쿼리의 결과가 상이하게 나타나는 비일관성이 발생하는 것

 

(5) Phantom Read

한 트랜잭션 안에서 일정범위의 레코드들을 두 번 이상 읽을 때, 첫 번째 쿼리에서 없던 유령 레코드가 두 번째 쿼리에서 나타나는 현상

 

트랜잭션의 고립화 수준을 높이면 일관성은 향상되지만, 더 넓은 범위의 Lock을 더 오랫동안 유지하는 방식을 사용하므로 동시성은 저하된다.

하지만 오라클은 트랜잭션 고립화 수준을 높이더라도 Lock 을 사용하지 않으므로 동시성이 저하되지 않는다.

 

 

 

 

03 비관적 vs. 낙관적 동시성 제어

비관적 동시성 제어는 사용자들이 같은 데이터를 동시에 수정할 것이라고 가정한다.

낙관적 동시성 제어는 사용자들이 같은 데이터를 동시에 수정하지 않을 것이라고 가정한다.

 

(1) 비관적 동시성 제어

select for update

 

(2) 낙관적 동시성 제어

ora_rowscn -> bug 5270479

기존 방식대로 동시성 제어를 해야 함

 

 

 

 

04 동시성 구현 사례

(1) 일련번호 채번 동시성 높이기

Locking 을 최소화하면서 채번 테이블로부터 일련번호를 채번하고자 할 때 사용할 수 있는 사례

autonomous 트랜잭션: 메인 트랜잭션에 영향을 주지 않고 서브 트랜잭션만 따로 커밋하는 기능

 

(2) 선분이력 정합성 유지

선분이력을 추가하고 갱신할 때 발생할 수 있는 동시성 이슈를 해결한 사례

 

 

 

 

 

05 오라클 Lock

- 래치: SGA 에 공유돼 있는 갖가지 자료구조를 보호할 목적으로 사용하는 가벼운 Lock

- 버퍼 Lock: 버퍼 블록에 대한 액세스를 직렬화

 

- 라이브러리 캐시 Lock: 라이브러리 캐시 오브젝트에 대한 핸들을 보호

- 라이브러리 캐시 Pin: 라이브러리 캐시 오브젝트의 실제 내용이 담긴 힙을 보호

 

- DML 테이블 Lock: Enqueue Lock 으로 구현함

- DML 로우 Lock: 로우 단위 Lock 과 트랜잭션 Lock 을 조합해서 구현함

 

(1) Enqueue Lock

Enqueue는 공유 리소스에 대한 액세스를 관리하는 Lock 매커니즘이다.

 

(2) TX Lock (=트랜잭션 Lock)

변경 중인 레코드를 동시에 변경하려는 트랜잭션에 대해서는 액세스를 직렬화해야 하며,

그 목적으로 사용하는 Lock 메커니즘이 트랜잭션 Lock이다.

트랜잭션이 첫 번째 변경을 시작할 때 얻고, 커밋 또는 롤백할 때 해제한다.

 

(3) TX Lock ▶ 무결성 제약 위배 가능성 또는 비트맵 인덱스 엔트리 갱신

테이블에 Unique 인덱스가 정의되어 있을 때는 insert에 의한 로우 Lock 경합이 생길 수 있다.

비트맵 인덱스는 그 구조상 하나의 엔트리가 여러개의 레코드와 매핑된다.

하나의 엔트리에 Lock을 설정하면 매핑되는 레코드 전체에 Lock이 설정되므로,

비트맵 인덱스 엔트리를 두 개 이상 트랜잭션이 동시에 갱신할 때 이 이벤트가 자주 발생한다.

 

(4) TX Lock ▶ ITL 슬롯 부족

블록에 레코드를 추가/갱신/삭제하려면, ITL 슬롯을 먼저 할당받고 그 곳에 트랜잭션 ID를 먼저 기록해야 한다.

비어있는 ITL 슬롯이 없다면, ITL 슬롯을 사용 중인 트랜잭션 중 하나가 커밋 또는 롤백할 때까지 기다려야 한다.

 

(5) TX Lock ▶ 인덱스 분할

인덱스는 정렬된 상태를 유지해야 하므로 값을 입력할 위치에 빈 공간이 없으면 인덱스 분할을 실시해 새 값을 입력할 공간을 확보하게 되며,

이 과정에서 Lock 경합이 발생할 수 있다.

 

 

(6) TX Lock ▶ 기타 트랜잭션 Lock

읽기 전용 테이블 스페이스로 전환할 때

 

(7) TX Lock ▶ DML 로우 Lock

DML Lock은 다중 사용자에 의해 동시에 액세스되는 사용자 데이터의 무결성을 보호해준다.

DML 수행 중에 호환되지 않는 다른 DML 또는 DDL 오퍼레이션의 수행을 방지시켜 주는 것이다.

 

(8) TM Lock ▶ DML 테이블 Lock

오라클은 로우 Lock 획득 시, 해당 테이블에 대한 테이블 Lock도 동시에 획득한다.

현재 트랜잭션이 갱신 중인 테이블에 대한 호환되지 않는 DDL 오퍼레이션을 방지한다.

 

(9) Lock 을 푸는 열쇠, 커밋

블로킹은 Lock 경합이 발생해 특정 세션이 작업을 진행하지 못하고 멈춰 선 경우를 말하고, 이것을 해소하는 방법은 커밋(또는 롤백) 뿐이다.

교착상태(deadlock)는 두 세션이 각각 Lock을 설정한 리소스를 서로 액세스하려고 마주 보고 진행하는 상황을 말하며,

둘 중 하나가 뒤로 물러나지 않으면 영영 풀릴 수 없다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형