티스토리 뷰
1. 특성 (ACID)
1) 원자성 (Atomicity)
- 한 트랜잭션 내 모든 연산들이 완전히 수행되거나 전혀 수행되지 않아야함 (all or nothing)
- DBMS의 회복 모듈 : 시스템 다운이 될 경우, 트랜잭션의 영향을 취소함으로써 원자성 보장
2) 일관성 (Consisitency)
- 어떤 트랜잭션이 수행되기 전에 데이터베이스가 일관된 상태를 가졌다면 트랜잭션이 수행된 후에 데이터베이스는 또 다른 새로운 일관된 상태를 가짐
- DBMS의 무결성 제약 조건, 동시성 제어 모듈
3) 고립성 (Isolation)
- 한 트랜잭션이 데이터를 갱신하는 동안 이 트랜잭션이 완료되기 전에는 갱신중인 데이터를 다른 트랜잭션들이 접근하지 못하도록 해야함
- 다수의 트랜잭션들이 동시에 수행되더라도 그 결과는 순차적으로 수행했을때랑 같아야함
- DBMS의 동시성 제어 모듈 : 고립성 보장
4) 지속성 (Durability)
- 한 트랜잭션이 완료되면 이 트랜잭션이 갱신한 것은 그 후에 시스템이 고장나도 손실되지 않음
- DBMS의 회복 모듈 : 시스템이 다운되어도 지속성 보장
2. 동시성 제어
1) 다수의 사용자들이 동시에 DBMS에 접근하고 트랜잭션을 수행할때, 서로 간섭이 생기지 않도록 해야함 (일관성과 무결성 보장해야함)
2) 동시성과 일관성은 트레이드 오프 관계 !
동시성을 높이기 위해 lock을 최소화하면 일관성을 유지하기 어려워지고,
일관성을 높이기 위해 lock을 많이 사용하면 동시성이 낮아짐
- 동시성 : 트랜잭션들이 순차적으로 실행되는 것이 아니라, 트랜잭션을 구성하는 각각의 쿼리문들이 트랜잭션의 순서에 상관없이 동시에 실행되는 것
- 일관성 : 자신이 발생시킨 변경사항과 다른 트랜잭션의 변경 사항(읽을 수 있는 버전만 허용)을 포함해 일관성 있는 상태로 데이터를 제공하는 것
3) 종류
- 직렬 스케줄 (serial schedule) : 여러 트랜잭션들의 집합을 한번에 한 트랜잭션씩 차례대로 수행
- 비직렬 스케줄 (non-serial schedule) : 여러 트랜잭션들을 동시에 수행
- 직렬 가능 (serializable) : 비직렬 스케줄의 결과가 어떤 직렬 스케줄의 수행결과와 동등함
4) 동시성 제어를 하지않았을 때 생길 문제
- 갱신 손실 (Lost Update) : 수행중인 트랜잭션이 갱신한 내용을 다른 트랜잭션이 덮어써서 무효화됨
- 오손 데이터 읽기 (Dirty Read) : 완료되지 않은 트랜잭션이 갱신한 데이터를 읽는것
- 반복 가능하지 않은 읽기 (Unrepetable Read) : 한 트랜잭션이 동일한 데이터를 두번읽을때 서로 다른값을 읽는것
5) locking
동시성 제어를 위한 방법.
- x-lock (eXclusive lock, 독점 락)
트랜잭션에서 갱신을 목적으로 데이터항목에 접근할때 요청.
현재 걸려있는 락이 x-lock일 경우, x-lock과 s-lock 요청이 오면 둘다 대기해야함
- s-lock (Shared lock, 공유 락)
트랜잭션에서 읽을 목적으로 데이터 항목에 접근할때 요청.
현재 걸려있는 락이 s-lock일 경우, s-lock 요청은 허용이지만, x-lock 요청은 대기해야함
- 2단계 락 프로토콜 (2-phase locking protocol) : 락을 요청하는 것과 해제하는 것이 2단계로 이루어짐
- 락 확장 단계 : 트랜잭션이 데이터 항목에 대하여 새로운 락을 요청할 수 있지만 가지고 있던 락을 하나라도 해제할 수 없음
- 락 수축 단계 : 가지고 있던 락을 해제할 수 잇지만 새로운 락을 요청할 수 없음. 조금씩 해제할 수도 있고 한꺼번에 모든 락을 해제할 수도 있음
- lock point : 한 트랜잭션에서 필요로 하는 모든 락을 걸어놓은 시저
- 데드락(Deadlock)
2단계 락 프로토콜에선 데드록이 발생할 수 있음.
두개 이상의 트랜잭션들이 서로 상대방이 보유하고 있는 락을 요청하면서 기다리고 있는 상태.
ex) 예시
1. T1이 X에 대해 x-lock 요청
2. T2가 Y에 대해 x-lock 요청
3. T1이 Y에 대해 s-lock이나 x-lock 요청하면 락 해제될때까지 대기
4. T2가 X에 대해 s-lock이나 x-lock 요청하면 락 해제될때까지 대기
-> 서로 무한정 대기하므로 데드락
- 팬텀 문제 (Phantom Problem) : 한 트랜잭션 내에서 동일한 쿼리를 두번 수행했을 때, 첫번째 쿼리에서 나타나지않았던 투플(Phantom)이 두번째 쿼리에서 나타나는 현상
ex) 다른 트랜잭션에서 중간에 Insert했을 경우.
3. 회복(recovery)
1) 필요성
- 트랜잭션 수행 도중이나 완료된 직후에 시스템이 다운됐을때, 원자성과 지속성을 보장하기 위해
- 고장 발생 전에 트랜잭션이 완료됐다면, 회복 모듈은 갱신 사항을 재수행(redo)하여 지속성을 보장함
- 고장 발생 전에 트랜잭션이 완료되지 못했다면, 데이터베이스에 반영했을 가능성이 있는 갱신 사항을 취소(undo)하여 원자성을 보장함
2) 로그를 사용한 즉시 갱신
- 즉시 갱신에서는 갱신 사항이 주기억 장치 버퍼에 유지되다가 완료되기 전이라도 디스크의 데이터베이스에 기록될 수 있음
- 원자성과 지속성 보장을 위해 DBMS는 로그 파일을 유지함
- 각 로그 레코드는 로그 순서번호로 식별되고 로그 레코드마다 트랜잭션 ID를 포함시킴. 동일한 트랜잭션에 속하는 로그 레코드들은 연결 리스트로 유지됨
3) 완료점(commit point)
- 한 트랜잭션의 데이터베이스 갱신 연산이 다 끝나고 로그에 기록되었을 때를 말함
- 회복 모듈은 로그에 start와 commit 로그 레코드가 모두 존재하는 트랜잭션들은 재수행(redo), start는 존재하지만 commit 로그 레코드는 없는 트랜잭션들은 취소(undo)
4) 로그 먼저 쓰기 (Write-Ahead Logging)
- 주기억 장치 데이터베이스 버퍼에 갱신 사항을 기록하고, 로그 버퍼에는 로그 레코드를 기록
- 만약 데이터베이스 버퍼가 로그 버퍼보다 먼저 디스크에 기록되는 경우 : 로그 버퍼가 기록되기 전에 시스템이 다운되면 주기억 장치는 휘발성이어서 로그 값이 남아있지 않게됨 → 트랜잭션의 취소가 불가능
- 따라서 데이터베이스 버퍼보다 로그 버퍼를 먼저 디스크에 기록해야함
5) 체크 포인트(check point)
- 시스템이 다운된 시점부터 오래전에 완료된 트랜잭션들은 이미 디스크에 반영되었을 가능성이 크지만, 로그를 사용하더라도 어떤 트랜잭션이 주기억 장치로부터 디스크에 기록되었는지 구분할 수가 없음
- 그래서 DBMS는 회복 시 재수행할 트랜잭션의 수를 줄이기 위해 주기적으로 체크포인트를 수행
- 주기억 장치의 버퍼 내용이 디스크에 강제로 기록됨 : 수행중인 트랜잭션을 잠시 멈추고 주기억 장치의 로그 버퍼를 디스크에 강제 출력 후 주기억 장치의 데이터베이스 버퍼를 디스크에 강제 출력함
- 체크포인트가 끝나면 로그에 checkpoint 로그 레코드가 기록됨
- 보통 10~20분마다 한번씩 수행
ex) 예시
트랜잭션 T0, T1, T3은 무시. T4, T5는 재수행. T2, T6은 취소
4. 고립 수준
1) Read Uncommited
- 가장 낮은 고립 수준
- s-lock을 걸지 않고 데이터를 읽기 때문에 Dirty Read 발생 가능
- Phantom Read, Unrepetable Read, Dirty Read 발생 가능
- 갱신하려는 데이터에 대해서는 x-lock을 걸고, 트랜잭션이 끝날때까지 보유함
2) Read Commited
- 기본값으로 많이 사용되는 고립수준
- 다른 트랜잭션이 커밋한 정보만 읽을 수 있음
- 읽으려는 데이터에 대해서 s-lock을 걸고, 읽기가 끝나자마자 락을 해제. 동일한 데이터를 다시 읽기위해 s-lock을 다시 걸고 데이터를 읽으면 이전에 읽은 값과 다른 값을 읽을수도 있음
- Phantom Read, Unrepetable Read 발생가능
- 갱신하려는 데이터에 대해서는 x-lock을 걸고, 트랜잭션이 끝날때까지 보유함
3) Repetable Read
- 읽으려는 데이터에 대해 s-lock을 걸고, 트랜잭션이 끝날때까지 보유함
- 한 트랜잭션 내에서 동일한 질의를 두번 이상 수행할 때 매번 같은 값을 포함한 결과를 검색하게됨
- 새로운 행을 추가하는 것을 막을 수는 없어서 Phantom Read 발생 가능
- 갱신하려는 데이터에 대해서는 x-lock을 걸고, 트랜잭션이 끝날때까지 보유함
4) Serializable
- 가장 높은 고립 수준. 가장 성능이 떨어짐
- 한 트랜잭션에서 읽고 쓰는 레코드들을 다른 트랜잭션에서 절대 접근할 수없음
- 조회되는 투플들뿐만 아니라 인덱스에 대해서도 s-lock을 걸고 트랜잭션이 끝날때까지 보유함
- 갱신하려는 데이터에 대해서는 x-lock을 걸고 트랜잭션이 끝날때까지 보유함
- 기다렸다가 순차적 진행