본문 바로가기
DB & SQL/데이터베이스 개론

회복과 병행 제어

by k-mozzi 2022. 2. 24.
반응형
Preface

 

이번 장에선 트랜잭션을 사용한 회복과 병행 제어를 알아보았다.

 

딱히 이해하기 어려운 부분은 없었지만, 의문이 생기는 부분들이 있었다.

 

먼저, 데이터베이스의 회복 연산인 undo에 관한 내용이다.

 

undo 연산은 로그를 이용해 실행된 모든 변경 연산을 취소하여 데이터베이스를 원래 상태로 복구하는 작업으로, 주로 트랜잭션이 완료되기 전 장애가 발생한 경우 사용한다고 하는데,

 

트랜잭션이 완료되기 전 상태라면 rollback 연산을 사용하여 트랜잭션이 수행되기 전의 상태로 돌아가는 것이 undo 연산으로 로그 레코드를 사용하는 것보다 효율적일 것 같다는 생각을 했다.

 

다음은 즉시 갱신 회복 기법에 관한 내용이다.

 

예를 들어 T1과 T2 트랜잭션을 직렬 스케줄로 수행할 때 T2 트랜잭션 수행 도중 장애가 발생한 경우 T1 트랜잭션에도 redo 연산을 수행한다고 하는데, 굳이 그럴 필요가 있을까?

 

이 의문에 대한 다양한 가설을 생각해봤다.

 

T2 트랜잭션의 장애가 T1 트랜잭션에 영향을 미칠 수 있어서 그렇다고 가정하면 만약 장애가 발생한 경우 항상 모든 트랜잭션에 회복 연산을 실행해야 하는가?

 

아니면 묶어서 실행하는 특정(관련) 트랜잭션들만 그런 것인가?

 

그런데 이 의문은 다음 페이지의 검사 시점 회복 기법을 통해 금방 해소되었다.

 

내가 생각했던 의문점들을 로그를 이용한 회복 기법의 단점으로 소개하며 이를 해결하기 위해 검사 시점을 설정해두고 특정 범위의 트랜잭션에만 회복 기법을 적용한다고 한다.

 

마지막은 미디어 회복 기법에 관한 내용인데, 디스크 장애 발생 시 덤프를 이용해 DB를 복구한 후 필요에 따라 로그의 내용을 토대로 redo 연산을 실행한다고 한다.

 

그러나 만약 디스크 장애가 발생하면 로그 레코드에도 문제가 생기지 않을까?

 

그렇다면 로그 파일도 안정 저장장치에 별도로 저장해두어야 한다는 것인데, 왜 DB의 단점으로 많은 비용을 꼽는 것인지 조금은 알 것 같다.


 

1. 트랜잭션

 

 

- 트랜잭션: 하나의 작업을 수행하는 데 필요한 DB의 연산들을 모아놓은 것

1) DB에서 논리적인 작업의 단위

2) DB에 장애가 발생했을 때 데이터를 복구하는 작업의 단위

→ 일반적으로 INSERT 문, DELETE 문, UPDATE 문의 실행을 관리한다.

 

 

- 트랜잭션의 특성(ACID): DB의 무결성과 일관성을 보장시키기 위한 특성

1) 원자성(Atomicity): 트랜잭션을 구성하는 연산들이 모두 정상적으로 실행되거나 하나도 실행되지 않아야 한다는 특성

→ all-or-nothing

 

2) 일관성(Consostency): 트랜잭션이 성공적으로 수행된 후에도 DB가 일관된 상태를 유지해야 한다는 특성

 

3) 격리성(Isolation): 현재 수행 중인 트랜잭션이 완료될 때까지 트랜잭션이 생성한 중간 연산 결과에 다른 트랜잭션들이 접근할 수 없다는 특성

 

4) 지속성(Durability): 트랜잭션이 성공적으로 완료된 후 DB에 반영한 수행 결과는 어떤 경우에도 손실되지 않고 영구적이어야 한다는 특성

 

 

- 트랜잭션의 연산

1) commit 연산: 트랜잭션의 수행이 성공적으로 완료되었음을 선언하는 연산

→ commit 연산이 실행된 후에야 트랜잭션의 수행 결과가 DB에 반영된다.

2) rollback 연산: 트랜잭션의 수행이 실패했음을 선언하는 연산

→ 트랜잭션이 지금까지 실행한 연산의 결과가 취소되고 트랜잭션 수행 이전 상태로 돌아간다.

 

 


 

2. 장애와 회복

 

 

- 회복: 장애가 발생했을 때 DB를 장애가 발생하기 전의 일관된 상태로 복구시키는 것

 

 

- 장애: 시스템이 제대로 동작하지 않는 상태

 

 

 

 

- DB는 일반적으로 비휘발성 저장 장치인 디스크에 상주하므로, 데이터를 디스크에서 메인 메모리로 가져와 이를 처리한 후 그 결과를 다시 디스크로 보내는 작업이 필요하다.

 

 

- 디스크와 메모리 간의 데이터 이동은 블록(block) 단위로 수행된다.

1) 디스크 블록: 디스크에 있는 블록

2) 버퍼 블록: 메인 메모리에 있는 블록

 

 

- 응용 프로그램에서 트랜잭션의 수행을 지시하면 메인 메모리 버퍼 블록에 있는 데이터를 프로그램의 변수로 가져오고, 데이터 처리 결과를 저장한 변수 값을 메인 메모리 버퍼 블록으로 옮기는 작업이 필요하다.

 

 

 

 

- DBMS의 회복 관리자의 역할

1) 장애 발생 탐지

2) DB 복구 기능 제공

 

 

- DB 회복의 핵심 원리는 데이터 중복이다.

 

 

- 중복 저장한 데이터를 이용해 DB를 복구하는 방법

 

 

 

- 로그: DB에 대한 변경 연산과 관련하여, 데이터를 변경하기 이전의 값과 변경한 이후의 값을 기록한 것

 

 

- 로그 파일: 로그를 저장한 파일

→ 레코드(행 / 튜플) 단위로 기록된다.

 

※ 로그 레코드도 트랜잭션의 수행과 함께 기록된다.

 

 

 

- 로그 회복 기법의 종류


1. 즉시 갱신 회복 기법: 트랜잭션 수행 중에 데이터를 변경한 연산의 결과를 DB에 즉시 반영한다.

 

- 로그를 정상적으로 사용하려면, 로그 파일에 로그 레코드를 먼저 기록한 후 DB에 변경 연산을 반영해야 한다.

 

 

- 회복을 위해 redo 연산과 undo 연산이 모두 필요한 경우, undo 연산을 먼저 실행한 후 redo 연산을 실행해야 한다.

 

 

2. 자연 갱신 회복 기법: 트랜잭션이 수행되는 동안에는 데이터 변경 연산의 결과를 DB에 즉시 반영하지 않고 로그 파일에만 기록해두었다가, 트랜잭션이 부분 완료된 후에 로그에 기록된 내용을 이용해 DB에 한 번에 반영한다.

→ undo 연산은 필요 없고 redo 연산만 필요하므로 로그 레코드에 변경 이전 값을 기록할 필요가 없다.

 


 

- 로그를 이용한 회복 기법은 로그 전체를 대상으로 회복 기법을 적용하므로 redo 연산을 수행할 필요가 없는 트랜잭션에도 redo 연산을 실행해야 하는 경우가 발생한다.

 

 

- 검사 시점 회복 기법: 로그 회복 기법과 같은 방법으로 로그 기록을 이용하되, 일정 시간 간격으로 검사 시점을 만들어둔다.

1) 장애 발생 시 가장 최근 검사 시점 이후의 트랜잭션에만 로그를 이용한 회복 작업을 수행한다.

 

 

- 미디어 회복 기법: 전체 DB의 내용을 일정 주기마다 다른 안전한 저장 장치에 복사해두는 덤프를 이용한다.

1) 장애 발생 시 가장 최근에 복사해둔 덤프를 이용해 장애 발생 이전의 일관된 DB 상태로 복구한다.

2) 이후 필요에 따라 로그의 내용을 토대로 redo 연산을 실행한다.

→ CPU가 낭비된다.

 


 

3. 병행 제어

 

 

- 병행 수행: 여러 개의 트랜잭션이 동시에 수행되는 것

→ 인터리빙 방식으로 진행된다.

 

 

- 인터리빙: 여러 트랜잭션이 차례로 번갈아 수행되는 것

 

 

- 병행 제어: 여러 개의 트랜잭션이 병행 수행되면서 같은 데이터에 접근하여 연산을 실행하더라도, 문제가 발생하지 않고 정확한 수행 결과를 얻을 수 있도록 트랜잭션의 수행을 제어하는 것

 

 

- 병행 수행의 문제

1) 갱신 분실: 하나의 트랜잭션이 수행한 데이터 변경 연산의 결과를 다른 트랜잭션이 덮어써 변경 연산이 무효화되는 것

 

2) 모순성: 하나의 트랜잭션이 여러 개의 데이터 변경 연산을 실행할 때 일관성 없는 상태의 DB에서 데이터를 가져와 연산을 실행함으로써 모순된 결과가 발생하는 것

 

3) 연쇄 복귀: 트랜잭션이 완료되기 전에 장애가 발생하여 rollback 연산을 수행하면, 이 트랜잭션이 장애 발생 전에 변경한 데이터를 가져가 변경 연산을 실행한 또 다른 트랜잭션에서도 rollback 연산을 연쇄적으로 실행해야 한다는 것

 

 

- 트랜잭션 스케줄: 트랜잭션에 포함되어 있는 연산들을 수행하는 순서


1. 직렬 스케줄: 인터리빙 방식을 이용하지 않고 각 트랜잭션별로 연산들을 순차적으로 실행시키는 것

1) 다른 트랜잭션의 방해를 받지 않고 독립적으로 수행된다.

2) 항상 모순이 없는 정확한 결과를 얻는다.

3) 어떤 직렬 스케줄을 사용하는가는 중요하지 않지만, 원하는 최종 값을 얻기 위해선 순서를 잘 설정해야 한다.

→ 일반적으로 잘 사용하지 않는다.

 

 

2. 비직렬 스케줄: 인터리빙 방식을 이용하여 트랜잭션을 병행해서 수행시키는 것

1) 최종 수행 결과의 정확성을 보장할 수 없다.

2) 어떤 비직렬 스케줄을 선택하여 트랜잭션들을 수행하느냐가 중요하다.

 

 

3. 직렬 가능 스케줄: 직렬 스케줄에 따라 수행한 것과 같이 정확한 결과를 생성하는 비직렬 스케줄

→ 간단한 작업이 아니므로, 직렬 가능성을 보장하는 병행 제어 기법을 주로 사용한다.


 

 

- 병행 제어 기법: 모든 트랜잭션이 따르면 직렬 가능성이 보장되는 나름의 규약을 정의한 것


1. 로킹 기법: 병행 수행되는 트랜잭션들이 동일한 데이터에 동시에 접근하지 못하도록 lock과 unlock 연산을 이용해 제어하는 것

1) lock: 트랜잭션이 사용할 데이터에 대한 독점권을 가지기 위해 사용

2) unlock: 트랜잭션이 데이터에 대한 독점권을 반납하기 위해 사용

 

→ 로킹 단위가 커질수록 병행성은 낮아지지만 제어가 쉽고, 로킹 단위가 작아질수록 제어가 어렵지만 병행성은 높아진다.

 

 

- 모든 트랜잭션이 기본 로킹 규약을 지키더라도 잘못된 결과를 얻을 수도 있다.

 

 

2. 2단계 로킹 규약: lock과 unlock 연산의 수행 시점에 대한 새로운 규약을 추가한 것

1) 첫 번째 unlock 연산을 실행하기 전에 필요한 모든 lock 연산을 실행해야 한다.

 

 

→ 2단계 로킹 규약을 준수하면 해당 스케줄은 직렬 가능성이 보장되지만, 교착 상태가 발생할 수도 있다.

→ 처음부터 발생하지 않도록 예방하거나, 발생했을 때 빨리 탐지하여 필요한 조치를 취하는 방법으로 해결


 

728x90
반응형

'DB & SQL > 데이터베이스 개론' 카테고리의 다른 글

데이터베이스 응용 기술  (0) 2022.03.03
보안과 권한 관리  (0) 2022.02.28
정규화  (0) 2022.02.23
데이터베이스 설계  (0) 2022.02.21
데이터베이스 언어 SQL  (0) 2022.02.17

댓글