티스토리 뷰

Undo와 Redo 

Oracle Database Architecture

 

Undo란 DML 트랜잭션을 취소하여 데이터베이스를 트랜잭션 이전의 상태로 되돌리는 것으로 작업 롤백과, 읽기 일관성, 복구를 합니다. DML 트랜잭션(update, insert, delete)이 발생하게 되면, 변경 이전의 데이터(원본 데이터)인 Undo Data는 전부 Undo Segment에 저장됩니다. 이때 Undo Segment를 저장하고 있는 Tablespace가 바로 Undo Tablespace입니다.

 

Redo란 단어 그대로 "다시 하다"라는 뜻을 가지고 있습니다. 즉, DML 트랜잭션을 다시 수행한다는 의미겟죠?

Redo는 기본적으로 복구의 역할을 합니다. DML 트랜잭션을 수행하던 도중 서버에 장애가 발생하여 데이터베이스가 shutdown 되었을 때 데이터베이스를 재기동시켜 트랜잭션을 다시 수행하여 복구하도록 합니다. 이 Redo 작업은 DBMS에 의해 자동적으로 일어나게 됩니다. 

오라클 서버에 무슨 작업을 하던지 모두 Redo Log에 기록되어집니다.(Undo도 포함) 따라서, 복구에 있어 Redo Log가 가장 중요하다고 생각하시면 됩니다. 

 

위 그림에서 파란색 테두리의 영역은 디스크 영역을 의미합니다. 이 디스크 영역은 Data files, Control files, Online redo log files로 이루어져 있습니다.

  • Data files: 테이블 스페이스에 해당하는 Data File이 저장되어 있습니다.
  • Control files: 데이터베이스 구조에 대한 정보가 저장되어 있습니다.
  • Online redo log files: Redo 작업에 대한 Log file이 저장되어 있습니다.

위에서 잠깐 언급하였듯이 Undo Data들은 디스크 내부 Data files의 Undo Segment에 저장되어 있습니다. 데이터베이스가 기동 되면 디스크 영역의 Data files가 메모리 영역의 Database buffer cache로 올라가게 됩니다.

또한, Redo와 관련된 내용들은 디스크 영역의 Online redo log files에 저장되어 있습니다. 마찬가지로 데이터베이스가 기동되면 Online redo log files에 저장되어 있는 Redo Log가 메모리 영역의 Redo log buffer로 올라가게 됩니다.

 

Oracle이 일관성 있는 데이터를 제공할 수 있는 이유

DML 실행 시, 변경 이전의 내용(원본 데이터)은 Undo Tablespace에 저장됩니다. 예를 들어, A 테이블의 empno 칼럼 값을 1 → 2로 변경했다고 한다면, 변경 이전의 값인 1을 Undo Tablespace에 저장하는 것입니다. 

 

이렇게 Undo Tablespace를 통해서 이전의 값을 관리하는 이유는 DB에 접근하는 여러 사용자들에게 일관성 있는 데이터를 제공하기 위해서입니다. Kim이라는 사용자가 empno 값을 1 → 2로 변경하고 COMMIT을 하지 않은 상태라면, 다른 Park, Jung 사용자들이 empno 값을 바라볼 때 변경되지 않은 값인 1을 봐야 하기 때문입니다. 이때 Park, Jung 사용자들이 바라보는 empno의 값 1은 Undo Tablespace에 저장되어 있는 변경 이전의 값(원본 데이터)입니다.

 

MySQL이나 MariaDB와 같은 DB를 주로 사용하시던 분들이라면 방금 말씀드린 개념이 조금 어려우실 수 있습니다.

MySQL에 경우 DML 실행 후 따로 commit을 선언하지 않아도 데이터베이스에 변경사항이 반영되어 다른 사용자가 같은 데이터를 조회해도 변경된 값으로 조회됩니다. 그 이유는 Auto Commit 기능이 default로 활성화 되어 있기 때문입니다. Oracle은 Auto Commit이 기본적으로 off 상태입니다. 따라서, 트랜잭션을 실행한 이후 변경 사항을 반영하기 위해선 commit이 필요합니다.

auto commit 관련 명령어

-- 현재 auto commit 상태 확인하기
show autocommit

-- auto commit 활성화
set autocommit on;

-- auto commit 비활성화
set autocommit off;

Redo Log와 Archive Mode

Redo Log는 데이터베이스 장애 시 복구를 위해 반드시 필요합니다. DML을 실행할 때 마다 모든 변경 사항은 Redo log buffer에 쌓이게되고, commit을 하는 순간 데이터베이스의 Online redo log files 영역에 모든 변경 사항들이 반영됩니다.

 

이러한 변경 사항은 Redo log buffer 뿐만 아니라 Database buffer cache에도 반영할 수 있는데, 여기서 알아야 할 것은 commit 시점에 반영되는 것은 Redo log buffer → Online redo log files만 해당합니다. Database buffer cache → Data files는 commit 시점에 반영되는 것이 아니라 비동기적으로 일어납니다.

 

그래서 장애가 났을 경우, 디스크 입장에선 Data files, Control files, Online redo log files를 가지고 복구를 해야 하는데, Database buffer cache → Data files은 위에서 언급했듯이 비동기적이기 때문에 메모리에 있던 데이터가 반영되지 않았을 수도 있습니다. 반면, Online redo log files는 COMMIT을 할 때 마다 디스크에 반영하기 때문에 비교적 최신의 데이터가 들어있습니다.

 

그래서 Data files와 Online redo log files를 SCN(System Change Number)를 통해 서로 비교합니다. Data files의 SCN이 100이고, Online redo log files의 SCN이 101이라면, Data files에 트랜잭션이 하나 반영되지 않았다는 것을 깨닫고 재기동 할 때 Online redo log files 정보를 이용해 Data files에 반영하게 됩니다.

 

결론적으로 데이터베이스 복구 시에 Redo log가 정말 중요하고, Database buffer cache → Data files는 비동기화 쓰기, Redo log buffer → Online redo log files는 동기화 쓰기를 합니다. 이 때 각각의 쓰기를 담당하는 것이 DB Writer와 Log Writer이고 이들은 Oracle 백그라운드 프로세서입니다. 

Database buffer cache → Data files에서 쓰기를 담당하는 것이 DB Writer고, Redo log buffer → Online redo log files에 쓰기를 하는 것이 Log Writer입니다.

 

Online redo log files를 Archive Mode로 운영한다고 하면, Online redo log files의 내용 그대로 Archived log files에 복제해 놓습니다. Archived log files은 Online redo log files의 연장선이 되겠습니다. 나중에 Archive Mode에 대해선 따로 다뤄보도록 하겠습니다.


Undo Tablespace, Rollback Segment

Undo Tablespace는 여러 개의 rollback segment(undo segment)로 이루어져 있습니다. 위에서도 이야기했듯이 rollback segment 내부에는 데이터가 변경되기 이전의 값이 저장되어 있습니다. 이것이 이제 DB안에 Undo Tablespace 영역에 저장되는 것입니다.

Undo Tablespace의 저장 구조

Undo Tablespace는 공간을 계속 재활용하여 사용합니다. 그래서 변경 작업이 길 경우, 많은 양의 변경 데이터가 쌓이게 될 텐데, 공간이 없을 경우 오래된 데이터부터 지우게 됩니다. 따라서 Undo Segment의 저장된 변경된 데이터에 접근하려고 할 때 과거 데이터가 날아가 있는 경우도 있습니다. 그렇게 되면 ORA-01555 "Snapshot too old" in Very Large Databases (if using Rollback Segments) 에러가 발생하게 됩니다. 이러한 에러가 발생하는 이유는 Rollback Segment의 크기가 작기 때문입니다. 따라서, 이러한 에러를 방지하기 위해 자주 commit을 해주거나, 어쩔 수 없이 변경 작업이 길어질 경우에는 Undo Tablespace의 공간을 늘려야 합니다. 


Redo log file 조회하기

Oracle에선 sysdba 계정으로 접속하면 redo log file 목록을 확인할 수 있습니다. 명령어는 다음과 같습니다.

#sysdba 계정으로 접속하여 redo log file을 조회 
SQL> conn / sysdba
Connected.
SQL> select * from v$logfile;

redo log file 조회 결과 1

SQL> col member for a50
SQL> 1
	1* select * from v$logfile
SQL> /

redo log file 조회 결과 2

 

위 결과를 확인해보면 Group이 1, 2, 3으로 조회되는 것을 볼 수 있습니다. 지금은 한 그룹에 멤버가 1개씩 구성되어 있지만, 중요한 DB 같은 경우 한 그룹에 멤버를 2개씩 구성하여 이중화합니다.

똑같은 데이터가 동시에 Disk A, Disk B에 저장되는 것이죠. 중요한 데이터베이스이기 때문에 안정성을 위해 이중화하는 것입니다.

만약, A_LOG에 대한 내용들을 나중에 복구할 때 오래된 데이터도 사용하고 싶다면 재활용하기 전, Archive Mode를 통해 Archive Log에 저장하면 됩니다.  


참고

https://www.youtube.com/watch?v=2l-LRUh-mNk&list=PLB4gJELhoLImJ3SBsmvFH8K78j1_zPNzK&index=7

https://brownbears.tistory.com/181

공지사항
최근에 올라온 글
Total
Today
Yesterday