티스토리 뷰

[한빛아카데미] 오라클로 배우는 데이터베이스 개론과 실습 책으로 학습한 내용을 정리한 것입니다.

 

* 트랜잭션(Transaction)

- DBMS가 데이터베이스를 다룰 때 사용하는 작업(프로그램)의 단위

- 데이터베이스의 무결성을 유지하기 위해 원자성, 일관성, 고립성, 지속성의 성질을 가짐

- 트랜잭션은 장애 시 데이터를 복구하는 작업의 단위

- 데이터베이스에서 여러 작업이 동시에 같은 데이터를 다룰 때, 이 작업을 서로 분리하는 단위가 됨

- 트랜잭션은 전체가 수행되거나 또는 전혀 수행되지 않아야 함(All or nothing)

 

* 트랜잭션 수행 과정

출처 : https://mangkyu.tistory.com/30

 

[예시]

1) A계좌(박지성)의 값을 하드디스크(데이터베이스)에서 주기억장치 버퍼로 읽어옴

2) B계좌(김연아)의 값을 하드디스크(데이터베이스)에서 주기억장치 버퍼로 읽어옴

3) A계좌(박지성)에서 10,000원을 인출한 값을 저장함

4) B계좌(김연아)에 10,000원을 입금한 값을 저장함

5) A계좌(박지성)의 값을 주기억장치 버퍼에서 하드디스크(데이터베이스)에 기록함

6) B계좌(김연아)의 값을 주기억장치 버퍼에서 하드디스크(데이터베이스)에 기록함

 

* 트랜잭션의 성질 - ACID 성질

- 원자성(Atomicitiy) : 트랜잭션에 포함된 작업은 전부 수행되거나 아니면 전부 수행되지 않아야 함(All or nothing)

- 일관성(Consistency) : 트랜잭션을 수행하기 전이나 수행한 후나 데이터베이스는 항상 일관된. 상태를 유지해야 함

- 고립성(Isolation) : 수행 중인 트랜잭션에 다른 트랜잭션이 끼어들어 변경 중인 데이터 값을 훼손하는 일이 없어야 함

- 지속성(Durability) : 수행을 성공적으로 완료한 트랜잭션은 변경한 데이터를 영구히 저장해야 함

                                   저장된 데이터베이스는 저장 직후 혹은 어느 때나 발생할 수 있는 정전, 장애, 오류에 영향 받지 않음

 

[트랜잭션과 프로그램의 차이점]

구분 트랜잭션 프로그램
프로그램 구조 START TRANSACTION
...
COMMIT
main() {
     . . .
}
다루는 데이터 데이터베이스에 저장된 데이터 파일에 저장된 데이터
번역기 DBMS 컴파일러
성질 원자성, 일관성, 고립성, 지속성 -

 

[원자성 - 오라클의 트랜잭션 제어 명령어(TCL)]

명령어 문법 설명
START TRANSACTION SET TRANSACTION NAME (이름) 트랜잭션의 시작
COMMIT COMMIT 트랜잭션의 종료
ROLLBACK ROLLBACK {TO <savepoint>} 트랜잭션을 전체 혹은 savepoint까지 무효화시킴
SAVE SAVEPOINT <savepoint> savepoint를 만듦

 

* 트랜잭션과 DBMS

- DBMS는 트랜잭션이 원자성, 일관성, 고립성, 지속성을 유지할 수 있도록 지원

- 원자성을 유지하기 위해 회복(복구) 관리자 프로그램을 작동시킴

(참고) 회복 관리자 프로그램 : 데이터베이스가 변경한 내용을 로그로 기록하고 있다가 트랜잭션에 문제가 생겼을 경우 원래 상태로 되돌림

- 일관성을 유지하기 위해 무결성 제약조건을 활용하며, 동시에 같은 데이터를 접근하는 트랜잭션들이 질서 있게 접근하여 데이터베이스의 일관성을 유지하기 위해서는 동시성 제어 알고리즘을 작동시킴

- 고립성을 유지하기 위해 동시성 제어 알고리즘 작동시킴

- 지속성을 유지하기 위해 회복 관리자 프로그램을 이용하며, 데이터베이스가 변경한 내용을 로그로 기록하고 있다가 트랜잭션에 문제가 있을 경우 원래 상태로 되돌림

 

[트랜잭션의 성질과 DBMS의 기능]

트랜잭션의 성질 DBMS의 기능
원자성 회복
일관성 무결성 제약조건(SQL문), 동시성 제어
고립성 동시성 제어
지속성 회복

 

* 동시성 제어(Concurrency Control)

-  트랜잭션이 동시에 수행될 때, 일관성을 해치지 않도록 트랜잭션의 데이터 접근을 제어하는 DBMS의 기능

 

[트랜잭션의 읽기(read)/쓰기(write) 시나리오]

- 상황 1의 경우에는 두 트랜잭션 모두 읽기 때문에 발생하는 문제 없음

- 상황 2의 경우에는 오손 읽기, 반복불가능 읽기, 유령데이터 읽기 문제 발생할 수 있음

- 상황 3의 경우에는 무제어 병행 수행을 할 때 갱신 손실, 모순성, 연쇄 복구 문제가 발생할 수 있음

출처 : https://mangkyu.tistory.com/30

 

* 갱실손실 문제(Ost Update)

- 두 개의 트랜잭션이 한 개의 데이터를 동시에 갱신(update)할 때 발생함

- 데이터베이스에서 절대 발생하면 안되는 현상

- 갱신손실 문제를 해결하기 위해 방법(Lock) 존재함

 

[갱신손실 문제 발생 시나리오]

- T1의 100원 인출 작업을, T2의 100원 입금 작업을 동시에 수행할 경우, 주의할 점은 데이터베이스에 저장된 데이터 값은 일단 주기억장치의 버퍼로 가져와야 읽을 수 있어 갱신손실 발생할 수 있음

출처 : https://goodmilktea.tistory.com/62#google_vignette

 

* 락(Lock)

- 트랜잭션이 데이터를 읽거나 수정할 때 데이터에 표시하는 잠금 장치

- 자신이 사용할 데이터를 락으로 잠그면 다른 트랜잭션은 잠금이 풀릴 때까지 기다려야 함

 

[락을 이용한 갱신손실 문제 해결]

출처 : https://goodmilktea.tistory.com/62#google_vignette

 

* 락의 유형

- 공유락(LS, Shared Lock) : 트랜잭션이 읽기를 할 때 사용하는 락

- 배타락(LX, Exclusive Lock) : 읽고 쓰기를 할 때 사용하는 락

 

[사용 규칙]

- 데이터에 락이 걸려있지 않으면 트랜잭션은 데이터에 락을 걸 수 있음

- 트랜잭션이 데이터 X를 읽기만 하면 LS(X)를 요청하고, 읽거나 쓰기를 하면 LX(X)를 요청함

- 다른 트랜잭션이 데이터에 LS(X)을 걸어두면, LS(X)의 요청은 허용하고 LX(X)는 허용하지 않음

- 다른 트랜잭션이 데이터에 LX(X)을 걸어두면, LS(X)와 LX(X) 모두 허용하지 않음

- 트랜잭션이 락을 허용받지 못하면 대기 상태가 됨

 

[락의 허용관계에 대한 호환행렬(Compatibility Matrix)]

출처 : https://goodmilktea.tistory.com/62#google_vignette

 

* 2단계 락킹(2 Phase Locking)

- 락을 걸고 해제하는 시점에 제한을 두지 않을 경우 두 개의 트랜잭션이 동시에 실행될 때 데이터의 일관성이 깨질 수 있음

- 트랜잭션이 락을 걸고 해제하는 시점을 2단계(확장단계/수축단계)로 나눠 진행함

- 확장단계(Growing phase, Expanding phase) : 트랜잭션이 필요한 락을 획득하는 단계로, 이미 획득한 락을 해제 안함

- 수축단계(Shrinking phase) : 트랜잭션이 락을 해제하는 단계로, 새로운 락을 획득하지 않음

 

 

[2단계 락킹을 사용하지 않았을 경우] 

- 두 개의 데이터에 두 개의 트랜잭션이 접근하여 갱신하는 작업을 진행할 때 2단계 락킹 기법 적용하지 않음

- 문제 발생 원인으로는 T1이 A에 락을 걸고 작업하다가 중간에 락을 해제하여 T2가 A에 접근함

-> T1이 앞으로 B에 락을 걸 예정으로 A에 걸었던 락을 미리 해제하면 안됨(트랜잭션이 작업을 완료하기 전에 락을 해제하면 안됨)

출처 :&nbsp;https://goodmilktea.tistory.com/62#google_vignette

 

[2단계 락킹을 사용한 경우]

출처 : https://goodmilktea.tistory.com/62#google_vignette

 

* 데드락(Deadlock) (=교착상태)

- 2단계 락킹 기법을 사용하면 데이터의 일관성을 유지할 슈 있으나, 두 개 이상의 트랜잭션이 각각 자신의 데이터에 대하여 락을 획득하고 상대방 데이터에 대해 락을 요청하면 무한 대기 상태에 빠질 수 있는 현상

 

[데드락 문제 발생]

출처 : https://goodmilktea.tistory.com/62#google_vignette

 

[문제 해결]

- 데드락 발생 시 DBMS는 T1 또는 T2의 작업 중 하나를 강제로 중지시킴

- 이 때 중지시키는 트랜잭션에서 변경한 데이터는 원래 상태로 되돌려놓음

 

* 데드락 발생 조건

- 상호 배제 : 한 번에 프로세스 하나만 해당 자원을 사용할 수 있으며, 사용 중인 자원을 다른 프로세스가 사용하려면 요청한 자원이 해제될 때까지 기다려야 함

- 점유 대기 : 자원을 최소한 하나 보유하고, 다른 프로세스에 할당된 자원을 점유하기 위해 대기하는 프로세스가 존재해야 함

- 비선점 : 이미 할당된 자원을 강제로 빼앗을 수 없음

- 순환 대기 : 대기 프로세스의 집합이 순환 형태로 자원을 대기하고 있어야 함

 

* 트랜잭션 동시 실행 문제

- 오손 읽기 : 다른 트랜잭션이 COMMIT하지 않는 데이터를 읽은 후 다른 트랜잭션이 ROLLBACK하면서 발생하는 현상

- 반복불가능 읽기 : 트랜잭션 중간에 다른 트랜잭션이 변경한 데이터를 읽으면서 발생하는 현상

- 유령데이터 읽기 : 트랜잭션 중간에 다른 트랜잭션이 삽입한 데이터를 읽으면서 발생하는 현상

 

* 트랜잭션 고립 수준 명령어(Transaction isolation level instruction)

- DBMS는 트랜잭션을 동시에 실행시키면서 락보다 좀더 완화된 방법으로 문제를 해결하는 명령어를 제공

 

[트랜잭션 고립 수준 명령어와 발생 현상]

출처 : https://goodmilktea.tistory.com/62#google_vignette

 

1)  READ UNCOMMITTED(Level=0)

- 고립 수준이 가장 낮은 명령어로, 자신의 데이터에 아무런 공유 락을 걸지 않음

- 다른 트랜잭션에 공유 락과 배타락이 걸린 데이터를 대기하지 않고 읽음

- 이 명령어는 SELECT 질의의 대상이 되는 테이블에 대해 락을 설정하지 않은 것과 같음

 

2) READ COMMITTED(Level=1)

- 오손 페이지의 참조를 피하기 위해 자신의 데이터를 읽는 동안 공유락을 걸지만 트랜잭션이 끝나기 전에라도 해지 가능함

- 다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행하며, 이 옵션은 오라클의 기본 설정임

- 아무런 설정을 하지 않으면 이 방식으로 수행됨

 

3) REPEATABLE READ(Level=2)

- 자신의 데이터에 설정된 공유락과 배타락을 트랜잭션이 종료할 때까지 유지해 다른 트랜잭션이 자신의 데이터를 갱신할 수 없도록 함

- 다른 트랜잭션 데이터는 락 호환성 규칙에 따라 진행하지만, 다른 고립화 수준에 비해 데이터의 동시성이 낮아 특별한 상황이 아니라면 사용하지 않는 것이 좋음

 

 4) SERIALIZABLE(Level=3)

- 고립 수준이 가장 높은 명령어로, 실행 중인 트랜잭션은 다른 트랜잭션으로부터 완벽하게 분리됨

- 데이터 집합에 범위를 지어 잠금을 설정할 수 있기 때문에 다른 사용자가 데이터를 변경하려고 할 때 트랜잭션을 완벽하게 분리할 수 있음

- 이 명령어는 네가지 고립화 수준 중 제한이 가장 심하고 데이터의 동시성도 낮음

- SELECT 질의의 대상이 되는 테이블에 미리 배타락을 설정한 것과 같은 효과를 냄

 

* 트랜잭션 고립 수준 실습

[ex1. 반복불가능 읽기 문제와 방지를 위한 명령어]

- 문제 발생 : 반복불가능 읽기

출처 :&nbsp;https://goodmilktea.tistory.com/62#google_vignette

 

- 문제 방지 : REPEATABLE READ 모드

-> 반복불가능 읽기 문제를 방치하려면 트랜잭션 T1의 고립 수준을 REPEATABLE READ로 상향하면 T1은 락을 해지하지 않아서 T2가 데이터를 UPDATE하는 것을 막을 수 있음

출처 :&nbsp;https://goodmilktea.tistory.com/62#google_vignette

 

[ex2. 유령데이터 읽기 문제와 방지를 위한 명령어]

- 문제 발생 : 유령데이터 읽기

출처 :&nbsp;https://goodmilktea.tistory.com/62#google_vignette

 

- 문제 방지 : SERIALIZABLE 모드 

-> 유령데이터 읽기 문제를 방지하려면 트랜잭션 T1의 고립 수준을 SERIALIZABLE 모드로 상향시켜 T1은 T2가 데이터를 삽입하는 것에 상관없이 새로 삽입한 데이터를 제외하고 읽음

출처 :&nbsp;https://goodmilktea.tistory.com/62#google_vignette

 

* 회복(Recovery)

- 데이터베이스에 장애가 발생했을 때 데이터베이스를 일관성 있는 상태로 되돌리는 DBMS의 기능

- 데이터베이스 시스템에서 회복에 중점을 두는 장애 유형은 시스템 충돌, 미디어 장애, 응용 소프트웨어 오류 등 있음 

- 위 장애는 장애의 내용이 무엇이든 상관없이 변경 중인 데이터를 갖고 있는 주기억장치가 손실되는 것과 데이터베이스가 저장된 하드디스크가 손실되는 것이 있음

 

* 트랜잭션과 회복

- 트랜잭션 : 데이터베이스 회복의 단위

- 데이터의 변경 내용을 한순간에 모두 데이터베이스에 기록하지 않으며, 변경한 내용(버퍼)을 로그(임시 디스크)에 기록한 후 데이터베이스에 반영함

- DBMS의 회복 관리자는 원자성과 지속성을 보장하여 장애로부터 데이터베이스를 보호함

 

[트랜잭션 수행 과정]

- 1 -> 2 -> 3 -> 4 -> COMMIT -> 5 -> 6 -> 완료(최종완료)

출처 :&nbsp;https://goodmilktea.tistory.com/62#google_vignette

 

* 로그 파일(Log file)

- DBMS는 트랜잭션이 수행 중이거나 수행이 종료된 후 발생하는 데이터베이스 손실을 방지하기 위해 트랜잭션의 데이터베이스 기록을 추적하기 위해 사용하는 파일

- 트랜잭션이 반영한 모든 데이터의 변경사항을 데이터베이스에 기록하기 전에 미리 기록해두는 별도의 데이터베이스

- 안전한 하드디스크에 저장되며 전원과 관계없이 기록이 남아있음

- 로그 파일에 저장된 로그 구조 : <트랜잭션번호, 로그의 타입, 데이터 항목 이름, 수정 전 값, 수정 후 값>

- 로그의 타입은 트랜잭션의 연산 타입으로 START, INSERT, UPDATE, DELETE, ABORT, COMMIT 등 있음

 

[트랜잭션 수행과 로그 파일]

출처 :&nbsp;https://goodmilktea.tistory.com/62#google_vignette

 

* 로그 파일을 이용한 회복

- 시스템 운영 중 장애가 발생하여 시스템이 다시 가동되었을 때 DBMS는 로그 파일을 먼저 살펴봄

- DBMS는 트랜잭션이 종료되었는지 혹은 중단되었는지 여부를 판단하여 종료된 트랜잭션은 종료를 확정하기 위하여 재실행(REDO)을 진행하고, 중단된 트랜잭션은 없던 일로 되돌리기 위해 취소(UNDO)를 진행함

 

* 로그 파일을 이용한 회복 방법

1) 트랜잭션의 재실행(REDO)

- 장애가 발생한 후 시스템을 다시 가동을 했을 때 로그 파일에 트랜잭션의 시작(START)이 있고 종료(COMMIT)가 있는 경우

- COMMIT 연산이 로그에 있다는 것은 트랜잭션이 모두 완료되었다는 의미

- 변경 내용이 버퍼에서 데이터베이스에 기록되지 않았을 가능성이 있어 로그를 보면서 트랜잭션이 변경한 내용을 데이터베이스에 다시 기록하는 과정

 

2) 트랜잭션의 취소(UNDO)

- 장애가 발생한 후 시스템을 다시 가동을 했을 때 로그 파일에 트랜잭션의 시작(START)만 있고 종료(COMMIT)가 없는 경우

- COMMIT 연산이 로그에 보이지 않는다는 것은 트랜잭션이 완료되지 못했다는 의미로, 한 일을 모두 취소해야 함

- 이 경우 완료하지 못했지만 버퍼의 변경 내용이 데이터베이스에 기록되어 있을 가능성이 있기 때문에 로그를 보면서 트랜잭션이 변경한 내용을 데이터베이스에서 원상복구 시키는 과정

 

* 회복을 위한 로그 기록 방법

1) 즉시 갱신(Immediate update) : '버퍼 -> 로그 파일', '버퍼 -> 데이터베이스' 작업이 부분완료 전에 동시에 진행될 수 있으며, 부분완료 전에 버퍼의 갱신 데이터는 로그에 기록이 진행된 상태이며 부분완료 전에 버퍼의 이룹 내용이 실제 데이터베이스에 반영될 수 있음

2) 지연 갱신 방법(Deferred update) : '버퍼 -> 로그 파일'이 모두 끝난 후 부분완료를 하고 이후 '버퍼 -> 데이터베이스' 작업을 진행하는 방법으로, 부분완료 전에는 갱신 내용이 실제 데이터베이스에 반영되지 않은 상태

(참고) 지연 갱신 방법은 데이터베이스에 반영하는 작업은 지연되지만, 장애 발생 시 로그에 START만 나타나는 트랜잭션은 UNDO작업을 할 필요가 없음

 

* 체크포인트(Checkpoint)

- 회복 시 많은 양의 로그를 검색하고 갱신하는 시간을 줄이기 위하여 몇 십 분 단위로 데이터베이스와 트랜잭션 로그 파일을 동기화한 후 동기화한 시점을 로그 파일에 기록해두는 방법 혹은 시점

 

* 체크포인트 시점에서 진행하는 작업

- 주기억장치의 로그 레코드를 모두 하드디스크의 로그 파일에 저장함

- 버퍼에 있는 변경된 내용을 하드디크스의 데이터베이스에 저장함

- 체크포인트를 로그 파일에 표시함

 

* 체크포인트를 위한 회복

1) 체크포인트 이전에 COMMIT 기록이 있는 트랜잭션의 경우

- 로그에 체크포인트가 나타나는 시점은 이미 변경 내용이 체크포인트에 의해 데이터베이스에 모두 기록된 후(즉시 갱신, 지연 갱신)이기 때문에 아무 작업 필요 없음

 

2) 체크포인트 이후에 COMMIT 기록이 있는 트랜잭션의 경우

- 체크포인트 이후에 변경 내용이 데이터베이스에 반영되지 않았을 가능성이 있기 떄문에 REPO(T)를 진행(즉시 갱신, 지연 갱신)

 

3) 체크포인트 이후에 COMMIT 기록이 없는 트랜잭션의 경우

- 즉시 갱신 방법을 사용했다면 버퍼의 내용이 반영됐을 수도 있어 원상복구를 시켜야 하기 때문에 UNDO(T)를 진행

- 지연 갱신 방법을 사용했다면 COMMIT 이전에는 버퍼의 내용을 데이터베이스가 반영하지 않기 때문에 아무것도 할 필요가 없음

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함