[데이터베이스] CH 9 트랜잭션 (2)
회복
1. 회복의 필요성
- 어떤 트랜잭션 T를 수행하는 도중에 시스템이 다운되었을 때, T의 수행 효과가 디스크의 데이터베이스 일부 반영되었을 수 있음
* 어떻게 T의 수행을 취소하여 원자성을 보장할 것인가?
- 또한 트랜잭션 T가 완료된 직후에 시스템이 다운되면 T의 모든 갱신 효과가 주기억 장치로부터 디스크에 기록되지 않았을 수 있음
* 어떻게 T의 수행 결과가 데이터베이스에 완전하게 반영되도록 하여 지속성을 보장할 것인가?
- 디스크의 헤드 등이 고장 나서 디스크의 데이터베이스를 접근할 수 없다면 어떻게 할 것인가?
2. 회복의 개요
- 여러 응용이 주기억 장치 버퍼 내의 동일한 데이터베이스 항목을 갱신한 후에 디스크에 기록함으로써 성능을 향상시키는 것이 중요함
- 버퍼의 내용을 디스크에 기록하는 것을 가능하면 최대한 줄이는 것이 일반적
* 예: 버퍼가 꽉 찼을 때 또는 트랜잭션이 완료될 때 버퍼의 내용이 디스크에 기록될 수 있음
- 트랜잭션이 버퍼에는 갱신사항을 반영했지만 버퍼의 내용이 디스크에 기록되기 전에 고장이 발생할 수 있음
- 고장이 발생하기 전에 트랜잭션이 완료 명령을 수행했다면 회복 모듈은 이 트랜잭션의 갱신 사항을 재수행(REDO) 하여 트랜잭션의 갱신이 지속성을 갖도록 해야 함
- 고장이 발생하기 전에 트랜잭션이 완료 명령을 수행하지 못했다면 원자성을 보장하기 위해서 이 트랜잭션이 데이터베이스에 반영했을 가능성이 있는 갱신 사항을 취소(UNDO) 해야함
3. 저장 장치의 유형
- 주기억 장치와 같은 휘발성 저장 장치에 들어 있는 내용은 시스템이 다운된 후에 모두 사라짐
- 디스크와 같은 비휘발 저장 장치에 들어 있는 내용은 디스크 헤드 등이 손상을 입지 않는 한 시스템이 다운된 후에도 유지됨
- 안전 저장 장치 (stable storage)는 모든 유형의 고장을 견딜 수 있는 저장 장치를 의미
- 두 개 이상의 비휘발성 저장 장치가 동시에 고장날 가능성이 매우 낮으므로 비휘발성 저장 장치에 두 개 이상의 사본을 중복해서 저장함으로써 안전 저장 장치를 구현함
4. 재해적 고장과 비재해적 고장
√ 재해적 고장
- 디스크가 손상을 입어서 데이터베이스를 읽을 수 없는 고장
- 재해적 고장으로부터의 회복은 데이터베이스를 백업해 놓은 자기 테이블을 기반으로 함
√ 비재해적 고장
- 그 이외의 고장
- 대부분의 회복 알고리즘들은 비재해적 고장에 적용됨
- 로그를 기반으로 한 즉시 갱신, 로그를 기반으로 한 지연 갱신, 그림자 페이징 (shadow paging) 등 여러 알고리즘
- 대부분의 상용 DBMS에서 로그를 기반으로 한 즉시 갱신 방식을 사용
5. 로그를 사용한 즉시 갱신
√ 즉시 갱신에서는 트랜잭션이 데이터베이스를 갱신한 사항이 주기억 장치의 버퍼에 유지되다가 트랜잭션이 완료되기 전이라도 디스크의 데이터베이스에 기록될 수 있음
√ 데이터베이스에는 완료된 트랜잭션의 수행 결과뿐만 아니라 철회된 트랜잭션의 수행 결과도 반영될 수 있음
√ 트랜잭션의 원자성과 지속성을 보장하기 위해 DBMS는 로그라고 불리는 특별한 화일을 유지함
- 데이터베이스의 항목에 영향을 미치는 모든 트랜잭션의 연산들에 대해서 로그 레코드를 기록함
- 각 로그 레코드는 로그 순서 번호 (LSN: Log Sequence Number)로 식별됨
√ 주기억 장치 내의 로그 버퍼에 로그 레코드를 기록하고 로그 버퍼가 꽉 찰 때까지 디스크에 기록함
√ 로그는 데이터베이스 회복에 필수적이므로 일반적으로 안전 저장 장치에 저장됨
- 이중 로그(dual logging): 로그를 두 개의 디스크에 중복해서 저장하는 것
√ 각 로그 레코드가 어떤 트랜잭션에 속한 것인가를 식별하기 위해서 각 로그 레코드마다 트랜잭션 ID를 포함시킴
√ 동일한 트랜잭션에 속하는 로그 레코드들은 연결 리스트로 유지됨
6. 로그 레코드의 유형
√ [Trans-ID, start]
- 한 트랜잭션이 생성될 때 기록되는 로그 레코드
√ [Trans-ID, X, old_value, new_value]
- 주어진 Trans_ID를 갖는 트랜잭션이 데이터 항목 X를 이전값(old_value)에서 새값(new_value)로 수정했음을 나타내는 로그 레코드
√ [Trans-ID, commit]
- 주어진 Trans_ID를 갖는 트랜잭션이 데이터베이스에 대한 갱신을 모두 성공적으로 완료하였음을 나타내는 로그 레코드
√ [Trans-ID, abort]
- 주어진 Trans_ID를 갖는 트랜잭션이 철회되었음을 나타내는 로그 레코드
7. 트랜잭션의 완료점 (commit point)
√ 한 트랜잭션의 데이터베이스 갱신 연산이 모두 끝나고 데이터베이스 갱신 사항이 로그에 기록되었을 때 그 트랜잭션이 완료점에 도달
√ 시스템이 다운된 후에 재기동되면, 회복과정을 거쳐야 한다
- DBMS의 회복 모듈은 로그를 검사하여 로그에 [Trans_ID, start] 로그 레코드와 [Trans-ID, commit] 로그 레코드가 모두 존재하는 트랜잭션들은 재수행
- [Trans-ID, start] 로그 레코드는 로그에 존재하지만 [Trans-ID, commit] 로그 레코드가 존재하지 않는 트랜잭션들은 취소
8. 로그 먼저 쓰기 (WAL: Write-Ahead Logging)
√ 트랜잭션이 데이터베이스를 갱신하면 주기억 장치의 데이터베이스 버퍼에 갱신 사항을 기록하고, 로그 버퍼는 이에 대응되는 로그 레코드를 기록함
√ 만일 데이터베이스 버퍼가 로그 버퍼보다 먼저 디스크에 기록되는 경우에는 로그 버퍼가 디스크에 기록되기 전에 다운될 수 있다. (로그 레코드가 없어서 이전 값을 알 수 없으므로 취소가 불가능함)
√ 따라서 데이터베이스 버퍼보다 로그 버퍼를 먼저 디스크에 기록해야 함
9. 체크 포인트 (check point)
√ 시스템이 다운된 시점으로부터 오래 전에 완료된 트랜잭션들이 데이터베이스를 갱신한 사항은 이미 디스크에 반영되었을 가능성이 큼
√ 따라서 DBMS는 회복시 재수행할 트랜잭션 수를 줄이기 위해서 주기적으로 체크 포인트를 수행함
√ 체크 포인트 시점에는 주기억 장치의 버퍼 내용이 디스크에 강제로 기록되므로, 체크포인트를 수행하면 디스크 상에서 로그와 데이터베이스 내용이 일치하게 됨
√ 체크포인트 작업이 끝나면 로그에 [checkpoint] 로그 레코드가 기록됨
√ 일반적으로 체크포인트를 10~20분마다 한 번씩 수행함
10. 체크포인트를 할 때 수행되는 작업
√ 수행 중인 트랜잭션들을 일시적으로 중지시킴. 회복 알고리즘에 따라서는 이 작업이 필요하지 않을 수 있음
√ 주기억 장치의 로그 버퍼를 디스크에 강제 출력
√ 주기억 장치의 데이터베이스 버퍼를 디스크에 강제로 출력
√ [checkpoint] 로그 레코드를 로그 버퍼에 기록한 후 디스크에 강제로 출력
√ 체크포인트 시점에 수행 중이던 트랜잭션들의 ID도 [checkpoint] 로그 레코드에 함께 기록
√ 일시적으로 중지된 트랜잭션의 수행을 재개
11. 데이터베이스 백업과 재해적 고장으로부터의 회복
- 아주 드물지만, 데이터베이스가 저장되어 있는 디스크 헤드 등이 고장나서 데이터베이스를 읽을 수 없는 경우 발생
- 이 경우 회복 방법은 주기적으로 자기 테이프에 전체 데이터베이스와 로그를 백업하고, 자기 테이프를 별도의 공간에 안전하게 보관하는 것
- 사용자들에게 데이터베이스 사용을 계속 허용하면서, 지난 번 백업 이후에 갱신된 내용만 백업을 하는 점진적인 백업이 바람직