전반적인 내용은 Real MySQL 8.0 (백은빈 이성욱 지음) 책의 내용을 기반으로 정리한 내용입니다.
모든 저작권은 해당 저자분들에게 있습니다.
개발자 입장에서 물리적 공간에 대한 메모리 할당과 해제까지 고려해야 할까?
물리적 장치 ARM, Track, Sector, Cylinder의 작업과 물리적인 I/O 오버헤드까지 고려하기에는 범주가 넓다
LOWEST LEVEL에 대한 작업들을 Disk Manager에게 맡기고
S/W를 High Level에 대해 고려하도록 만들어주자
DBMS는 DBMS Layer
Buffer Manager가 하는 일
Disk Space Manager가 하는 일
들을 계층적으로 고민해보고 이해하자
결국 이전에 우리가 공부한 Disk Space Management와 Buffer Management를 어느정도 이해했다면 내용을 이해하는데 어렵지 않을 것이다.
작업을 수행하면서 프레임 내 페이지들이 버퍼 관리자의 버퍼 교체 알고리즘에 따라서 디스크에 출력될 수 있다. 작업 도중인데, 버퍼 교체는 전적으로 버퍼의 상태에 따라서 결정되기 때문에 Consistency로 바라봤을 때 문제가 발생함. 즉, 아직 완료되지 않은 트랜잭션이 수정한 페이지들이 디스크에 출력될 수 있으므로 해당 트랜잭션이 어떤 이유든 정상적으로 종료될 수 없게 되면 트랜잭션이 변경한 페이지들은 원상 복구되어야 한다. 이러한 복구를 UNDO라고 부르는 것이다. 만약 버퍼 관리자가 트랜잭션 종료 전에는 어떤 경우에도 수정된 페이지들을 디스크에 쓰지 않는다면, UNDO 작업은 메모리 버퍼에 대해서만 이루어지면 되는 식이다. BUT : 매우 큰 크기의 메모리 버퍼가 필요하다는 문제점 때문에 채택 X
STEAL 정책
이제는 UNDO 복구의 반대 개념인 REDO 복구에 대해 알아볼 것이다.
커밋한 트랜잭션의 수정은 어떤 경우에도 유지 되어야 한다. 이미 커밋한 트랜잭션의 수정을 재반영하는 복구 작업을 REDO 복구라고 하는데, REDO 복구 역시 UNDO 복구와 마찬가지로 버퍼 관리 정책에 영향을 받음
트랜잭션이 종료되는 시점에 해당 트랜잭션이 수정한 페이지들을 디스크에도 쓸 것인가 여부로 두가지 정책이 구분
로그는 로그 레코드의 연속이며 데이터베이스의 모든갱신 작업을 기록함.
대부분 DBMS는 성능 상의 이유로 하나의 로그를 유지함.
수정 전 이미지와 수정 후 이미지를 모두 가지고 있으면서 연산이 발생할 때 적절한 조치를 취한다.
데이터베이스의 상태를 변화시키기 위해 수행하는 작업 단위라고 알려져 있다. 트랜잭션은 작업의 완전성을 보장
원자성(Atomicity) : 트랜잭션이 Database에 모두 반영되거나, 혹은 전혀 반영되지 않아야함.
All or Nothing / DBMS의 회복 모듈은 시스템이 다운되는 경우, 부분적으로 데이터베이스를 갱신한 트랜잭션의 영향을 취소함으로써 트랜잭션의 원자성을 보장
일관성(Consistency): 트랜잭션의 작업 처리 결과는 항상 일관성 있어야 한다.
트랜잭션이 수행되는 도중에 데이터베이스가 일시적으로 일관된 상태를 갖지 않을 수 있음 하지만 결과는 일관성을 가짐 ex) 전체 계좌 잔액 합계는 10,000 원
고립성(Isolation): 둘 이상의 트랜잭션이 동시에 병행 실행되고 있을 때, 어떤 트랜잭션도 다른 트랜잭션 연산에 끼어들 수 없다.
예를 들어, 현재 계좌 상태 : My 계좌 10,000, 부모님 계좌 : 0원 / 내 계좌의 10,000 금액에서 부모님 계좌로 5천원을 송금하는 트랜잭션이 수행하는 도중에 부모님 계좌로 10,000원이 입금되는 트랜잭션이 수행됐다면, 총 6000원의 금액이 존재해야 할 부모님 계좌에 여전히 0원으로 알고 있던 5천원 송금 트랜잭션때문에 5000원으로 입력된다. 따라서, 고립성이 보장되어야 함
지속성(Durability): 트랜잭션이 성공적으로 완료되었으면, 결과는 영구적으로 반영되어야 한다.
DBMS의 회복 모듈은 시스템이 다운되는 경우에도 트랜잭션의 지속성을 보장함.
하나의 트랜잭션 내에서 또는 여러 트랜잭션 간의 작업 내용을 어떻게 공유하고 차단할 것인지를 결정하는 레벨을 의미함.
트랜잭션이 안정하게 수행되기 위한 ACID는 이론적으로 완전히 보장되어야함
BUT, 성능과 동시성을 위해서 완화되는 경우들이 존재하기 때문에 Level이 존재함
단순히 암기가 아니라 Level이 왜 존재하는지 알아야 한다!
Lock과 Transaction
잠금과 트랜잭션은 비슷한 개념 같으나 Lock은 동시성을 제어하기 위한 기능이고, Transaction은
데이터의 정합성을 보장하기 위한 기능이다. 하나의 데이터를 여럴 커넥션에서 동시에 변경하려고 하는데
잠금이 없다면 하나의 데이터를 여러 커넥션에서 동시에 변경할 수 있게 된다. 결과적으로 해당 레코드
의 값은 예측할 수 없는 상태가 된다. 잠금은 여러 커넥션에서 동시에 동일한 자원을 요청할 경우
한 시점에는 하나의 커넥션만 변경할 수 있게 해주는 역할을 한다. 격리 수준이라는 것은 하나의 트랜잭션
내에서 또는 여러 트랜잭션 간의 작업 내용을 어떻게 공유하고 차단할 것인지를 결정하는 레벨을 의미함.
상태를 변화시킨다는 것 -> SQL 질의어를 통해 DB에 접근하는 것
많은 사람들이 트랜잭션에 대해 다룰 때, 은행의 입출금을 통한 예시를 둔다.
EX) 사용자 A가 사용자 B에게 만원을 송금한다. 1. 사용자 A의 계좌에서 만원을 차감한다. 출금 Update 문 2. 사용자 B의 계좌에서 만원을 추가한다. 입금 Update 문
이를 통틀어 하나의 트랜잭션이라고 하는데, 작업 단위는 출금 Update문 + 입금 Update문으로 볼 수 있다.
위 두 쿼리문 모두 성공적으로 완료되어야만 "하나의 작업(트랜잭션)"이 완료되는 것이다. Commit
작업 단위에 속하는 쿼리 중 하나라도 실패하면 모든 쿼리문을 취소하고 이전 상태로 돌아가야함. Rollback