본문

151227P(일)

ORACLE - Chpter 9

 

트랜잭션(transaction)

DB 응용에서 하나의 논리적인 단위를 수행하는 DB 연산들의 모임

데이터 객체(튜플, 릴레이션)들을 접근하고 갱신도 하는 프로그램 수행의 단위

 

UPDATE CUSTOMER

SET BALANCE = BALANCE - 100000

WHERE CUST_NAME = '정미림';

 

UPDATE CUSTOMER

SET BALANCE = BALANCE + 100000

WHERE CUST_NAME = '안명석';

 

이 두개의 UPDATE문은 둘 다 완전하게 수행되거나 한 UPDATE문도 수행되서는 안되도록

하나의 트랜잭션 단위로 처리해야 한다.

 

트랜잭션의 특성(ACID 특성)

원자성(Atomicity)

한 트랜잭션 내의 모든 연산들이 완전히 수행되거나 전혀 수행되지 않음(all or nothing)을 의미

 

일관성(Consistency)

한 트랜잭션을 정확하게 수행하고 나면 DB가 하나의 일관된 상태에서 다른 일관된 상태로 바뀐다.

일관된 상태의 DB -> 수행도중 DB가 일시적으로 불일치 상태 -> 새로운 일관적 상태의 DB

 

고립성(Isolation)

한 트랜잭션이 데이터를 갱신하는 동안 이 트랜잭션이 완료되기 전에는 갱신 중인 데이터를 다른 트랜잭션들이 접근하지 못하도록 해야한다.

다수의 트랜잭션 수행한 결과 = 순서에 따라 하나씩 수행한 결과

요구 사항에 따라 다양한 고립수준(isolation level)이 존재

 

지속성(Durability)

일단 트랜잭션이 완료되면 이 트랜잭션이 갱신한 것은 그 후에 시스템에 고장이 발생하더라도 손실되지 않는다.

회복모듈이 트랜잭션의 지속성을 보장한다.

 

COMMIT(commit)

트랜잭션의 성공적인 끝맺음

새로운 일관된 상태

트랜잭션의 수행을 DB에 갱신해야 함

 

ROLLBACK(abort)

트랜잭션의 일부를 끝내지 못함

불일치 상태

DB에 일부 반영되었다면 취소해야 함

 

동시성 제어(concurrency control)

다수의 사용자들이 동시에 데이터 베이스에 대해 갱신 연산들을 수행해도 데이터 베이스의 일관성이 유지

동시에 수행되는 트랜잭션들의 간섭 및 상호작용을 제어

트랜잭션들이 동시에 수행되었어도 각 트랜잭션이 고립적으로 수행된 것과 같은 결과를 내야함

 

비직렬 스케쥴의 직렬가능(serializable)

직렬스케줄(serial schedule) = 비직렬 스케쥴(non-serial schedule)

 

동시성 제어없는 트랜잭션 동시수행

갱신손실(lost update)

갱신한 내용을 다른 트랜잭션이 덮어 씀.

갱신무효

 

오손 데이터 읽기(dirty read)

완료되지 않은 트랜잭션이 갱신한 데이터

 

반복할 수 없는 읽기(unrepeatable read)

한 트랜잭션이 다른 데이터를 두 번 읽을 때 서로 다른값을 읽는 것

 

로킹(locking)

동시성 제어를 위해 가장 널리 사용되는 기법

 

lock

동시접근을 위해 사용

DB내의 각 데이터 항목과 연결된 하나의 변수

DB의 모든 데이터 항목마다 하나의 lock 존재

DB 항목을 접근 할 때마다 요청한 lock정보는 lock table에 유지

 

독점 로크(X-lock, eXclusive lock)

트랜잭션에서 갱신을 목적으로 데이터 항목을 접근할 때 사용

 

공유 로크(S-lock, shared lock)

트랜잭션에서 읽을 목적으로 데이터 항목을 접근할 때 사용

 

S-lock 상태에서 다른 트랜잭션이 S-lock 요청(O)

S-lock 상태에서 다른 트랜잭션이 X-lock 요청(X)

X-lock 상태에서 다른 트랜잭션이 S-lock or X-lock 요청(X)

 

접근 종료후 unlock 해야 한다.

 

2단계 로킹 프로토콜(2-phase locking protocol)

단순히 로킹 기법을 사용한다고 동시성 문제가 완전히 해결되지는 않는다.

-> 트랜잭션에 lock과 unlock을 각각 따로 걸게되어 중간에 다른 트랜잭션이 끼어들면 일관성이 깨지게 된다.

 

1단계 - 로크 확장 단계

트랜잭션이 데이터 항목에 대하여 새로운 로크 요청 가능

보유중인 로크는 하나라도 해제 불가능

 

2단계 - 로크 수축 단계

보유중인 로크를 해제 가능하지만 새로운 로크는 요청 불가

단계별로 해제하는 방법과 한꺼번에 해제하는 방법 존재

 

로크포인트(lock point)

필요한 모든 로크를 걸어놓은 시점

 

데드록(deadlock)

두개 이상의 트랜잭션들이 서로 상대방이 보유하고 있는 로크를 요청하면서 기다리는 상태

1. T1이 X에 대해서 독점로크를 요청하여 허가받음

2. T2가 Y에 대해서 독점로크를 요청하여 허가받음

3. T1이 Y에 대해서 로크를 요청하여 대기

4. T2가 X에 대해서 로크를 요청하여 대기

 

다중 로크 단위(multiple granularity)

트랜잭션이 접근하는 투플 수에 따라서 lock를 하는 데이터 항목의 단위를 구분

한 트랜잭션에 lock할 수 있는 데이터 항목이 두가지 이상이면 다중로크 단위

DBMS가 자동적으로 로크 단위를 조정한다.

 

DB, 릴레이션, 디스크 블록, 투플 등 단위

레코드(투플) < 디스크 블록(페이지) < 릴레이션 < 데이터베이스

단위가 적을수록 오버헤드 증가(lock table에 정보등록 -> lock table에 정보 삭제) 

그러나 동시성 정도 증가

 

ex)

적은 수의 투플들을 접근하는 트랜잭션 -> 투플이 로크단위

많은 수의 투플들을 접근하는 트랜잭션 -> 릴레이션이 로크단위

 

팬텀 문제(phantom problem)

 

시간2에 T2가 삽입할 투플의 존재를 미리 알 수 없으므로 공유로크 사용 불가

DNO = 1;에 대한 투플에 걸어놓은 lock는 T2 투플과 겹치지 않으므로 삽입 되어진다.

∴T1의 시간1 결과 != T1의 시간 3 결과

2단계 로킹 프로토콜도 막을순 없으셈.

 

팬텀 문제 해결법

5. Phantom Read

- 한 트랜잭션 안에서 일정 범위의 레코드를 2번 읽을때, 그사이 다른 트랜잭션이 범위 사이에 값을 입력하면, 첫번째 트랜잭션에서 값을 다시 읽을때 없던 데이터가 나타나는 현상
- 트랜잭션 도중 새로운 로가 입력될 수 있도록 허용할경우 발생
- 고립수준을 3으로 올리면 해결이 되나, 나머지 트랜잭션은 트랜잭션이 끝날때 까지 대기해야함
- 보통 Phantom Read는 업무상으로 서로 이해하에서 허용하도록 함으로써 문제를 피해가는것이 정석이다.

 

2. 트랜잭션 고립화 수준 (Transaction Isolation Level)

A. Level 0 : (Read Uncommitted)
- 트랜잭션에서 처리중인 데이터 즉, 아직 커밋되지 않은 데이터를 읽도록 허용하는것
- Dirty Read, Non-Repeatable, Phantom Read 현상 발생
- 사실상 트랜잭션에 대한 의미가 거의 없는 수준이 됨

B.  Level 1 : (Read Committed)
- Dirty Read 방지, 트랜잭션이 커밋된 데이터만을 읽어 들임
- 대부분의 DB에서 기본적으로 설정되어 있는 레벨
- Non-Repeatable Read, Phantom Read 현상은 여전히 발생

C. Level 2 : (Repeatable Read)
- 선행 트랜잭션이 읽은 데이터를 타 트랜잭션에서 읽는 것은 가능하나, 수정이나, 삭제는 불가능 하도록 하는것,
- 선행 트랜잭션이 끝이나면, 다음 트랜잭션에서는 이를 수정이나 삭제 가능
- 보통 오라클에서는 select ~ for update 구문을 이용하여 읽고, Row Lock을 걸어서 해당 로를 보호한다.
- 기타 DB에서는 고립화 수준을 Level 2로 변경해야지만 적용 가능
- Phantom read현상은 여전히 발생

D. Level 3 : (Serializable Read)
- 선행 트랜잭션이 읽은 데이터를 타 트랜잭션이 수정, 삭제가 불가능 하며, 해당 테이블에 삽입하는것 까지 불가능 하게 함
- 완벽한 읽기 일관성을 제공
- 동시성이 매우 떨어짐
- Phantom read 가 없어짐

 

http://neokido.tistory.com/entry/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%84%A4%EA%B3%84%EC%99%80-%EC%9D%B4%EC%9A%A9-Locking-%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%BD%EA%B8%B0-%EC%9D%BC%EA%B4%80%EC%84%B1-%EB%AC%B8%EC%A0%9C-328

 

 

 

회복(recovery)

데이터베이스를 갱신하는 도중에 시스템이 고장나도 DB의 일관성이 유지되도록 하는 기법

원자성과 지속성의 보장

백업(backup), 로깅(logging), 체크포인트(checkpoint)

 

재수행(REDO)

고장이 발생하기 전에 트랜잭션이 commit을 수행했다면 회복모듈은 트랜잭션의 갱신사항을 재수행하여 지속성을 유지하도록 한다.

 

취소(UNDO)

고장이 발생하기 전에 commit을 수행하지 못했다면 원자성 보장을 위해 갱신사항을 취소해야 한다.

 

로그를 사용한 즉시 갱신

즉시 갱신에서는 트랜잭션이 완료되기 전이라도 디스크의 DB에 기록될 수 있다.

 

로그(log)

철회된 트랜잭션의 수행결과도 반영 될 수 있으므로 원자성과 지속성 보장을 위해 추가로 정보를 유지해야 하므로 log라고 부르는 특별한 파일을 유지한다.

로그 기록은 파일 끝에 순차적으로 이루어지므로 성능 저하는 없다.

DB와 로그의 동시손상 회피, 성능저하 회피를 위해 전용 디스크에 로그를 저장

 

모든 트랜잭션 연산에 대해서 로그 레코드를 기록한다.

로그 레코드는 로그 순서 번호(LSN : Log Sequence Number)로 식별

로그 레코드 마다 트랜잭션 ID를 포함한다.

동일 트랜잭션에 속하는 로그 레코드들은 연결 리스트로 유지

 

이중로그(dual log)

로그를 두 개의 디스크에 중복해서 저장

 

로그 레코드 유형

Trans-ID, start

한 트랜잭션이 생성 될 때 기록되는 로그 레코드

 

Trans-ID, X, old_value, new_value

주어진 Trans_ID를 갖는 트랜잭션이 X를 이전값에서 새값으로 수정

이전값은 트랜잭션 취소에 사용

새값은 트랜잭션 재수행에 사용

 

Trans-ID, commit

갱신 성공을 나타내는 로그 레코드

 

Trans-ID, abort

트랜잭션이 철회 되었음을 나타내는 로그 레코드

 

완료점(commit point)

한 트랜잭션의 DB 갱신 연산이 모두 끝나고 DB 갱신 사항이 로그에 기록되었을때 완료점에 도달했다고 말한다.

 

commit 레코드가 존재하면 재수행 -> 로그 기록방향으로 진행

start만 있으면 취소. -> 로그 역방향으로 진행

 

로그 먼저 쓰기(WAL : Write-Ahead Logging)

로그 버퍼와 DB 버퍼에 있는 내용을 한꺼번에 동시에 디스크에 쓰는것은 불가능 하기 때문에 로그 버퍼를 먼저 디스크에 기록하는 것

 

체크포인트(checkpoint)

로그는 주기억 장치 버퍼로부터 디스크에 기록되었는가를 구분 할 수 없으므로 재수행할 트랜잭션수가 쓸데없이 증가한다.

회복시 재수행할 트랜잭션의 수를 줄이기 위해서 주기적으로 체크포인트를 수행한다.

체크포인트 시점에서는 주기억 장치의 버퍼내용이 디스크에 강제로 기록되고 로그는 checkpoint 레코드가 기록된다.

일반적으로 10~20분마다 한번씩 checkpoint를 수행

 

checkpoint 회복 알고리즘

1. 수행중인 트랜잭션을 일시적으로 중단시킨다.

2. 주기억장치의 로그 버퍼를 디스크에 강제로 출력한다.

3. 주기억장치의 DB 버퍼를 디스크에 강제로 출력한다.

4. checkpoint 로그 레코드를 로그 버퍼에 기록한 후 디스크에 강제로 출력한다. 수행중이던 트랜잭션 ID도 함께 기록

5. 일시적으로 중지된 트랜잭션의 수행을 재개한다.

 

점진적인 백업(incremental backup)

게임 서버와 같은 경우 24시간 운영되므로 백업을 하는동안 사용자들이 데이터베이스를 접근하지 못하도록 제한하는것이 쉽지않다. 따라서 사용자들이 DB는 계속 사용하면서 지난번 백업 이후에 갱신된 내용만 백업을 하는 방법

 

트랜잭션 관리(transaction management) 모듈 = 동시성 제어 + 회복

 

PL/SQL의 트랜잭션

암시적 끝맺음

DDL, DCL, (COMMIT, ROLLBACK 없이)Oracle SQL Developer를 정상적으로 종료

Oracle SQL Developer의 비정상적인 종료, 시스템 장애

 

명시적 끝맺음

COMMIT, ROLLBACK, SAVEPOINT, ROLLBACK TO SAVEPOINT

 

set auto on; 또는 set autocommit on;

각 데이터 조작어를 하나의 트랜잭션으로 처리

 

트랜잭션의 속성

디폴트는 읽기 + 쓰기

 

읽기전용

SET TRANSACTION READ ONLY;

 

읽기 + 쓰기

SET TRASACTION READ WRITE;

 

고립 수준(Isolation level)

한 트랜잭션이 다른 트랜잭션과 고립되어야 하는 정도

low level - 동시성은 높아지지만, 데이터의 정확성은 떨어진다.

high level - 동시성은 저하되지만, 데이터가 정확해진다.

 

READ UNCOMMITTED

가장 낮은 고립수준

읽기에 대해서 트랜잭션의 질의들이 S-lock을 걸지 않고 데이터를 읽으므로 오손 데이터를 읽을 확률이 높다.

갱신에 대해서는 X-lock을 걸고 트랜잭션이 끝날 때까지 보유

 

SET TRANSACTION READ WRITE

ISOLATION LEVEL READ UNCOMMITTED;

 

READ COMMITTED

오라클의 디폴트

읽기에 대해서 S-lock을 걸고 읽기가 끝나면 바로 lock을 해제하므로 동일 데이터를 다시 읽기위해 S-lock를 다시 걸고 데이터를 읽으면 이전 값과 다른경우가 생긴다.

갱신에 대해서는 X-lock을 걸고 트랜잭션이 끝날 때까지 보유

 

ex)

항공기 예약 트랜잭션에서 빈좌석을 찾을 수 없을때 누가 좌석을 취소했는가를 계속 검색하기 위해서 이 수준을 명시할 수 있다.

 

SET TRANSACTION READ WRITE

ISOLATION LEVEL READ COMMITTED;

 

REPEATABLE READ

읽기에 대해서 S-lock을 걸고 트랜잭션이 끝날 때 까지 보유하므로 동일한 질의를 두번 이상 수행 할 때 매번 같은 값을 검색한다.

갱신에 대해서는 X-lock을 걸고 트랜잭션이 끝날 때까지 보유

 

SET TRANSACTION READ WRITE

ISOLATION LEVEL REPEATABLE READ;

 

SERIALIZABLE

SQL2의 디폴트

가장 높은 고립 수준이며 질의에서 검색되는 투플뿐만 아니라 인덱스에 대해서도 S-lock를 걸고 트랜잭션이 끝날 때까지 보유한다.

갱신에 대해서는 X-lock을 걸고 트랜잭션이 끝날 때까지 보유

 

SET TRANSACTION READ WRITE

ISOLATION LEVEL SERIALIZABLE;

 

 

 

'낡은 서랍장 > ORACLE' 카테고리의 다른 글

160111P(월)  (0) 2016.01.11
160110P(일)  (0) 2016.01.10
160108P(금)  (0) 2016.01.08
160105P(화)  (0) 2016.01.05
151220P(일)  (0) 2016.01.02

공유

댓글