데이터를 쓸때는 LGWR, DBWR이 관여하고, 불러올때는 서버프로세스가 관여
COMMIT명령이 들어오면 LGWR이 먼저 리두로그버퍼캐시에 있는 데이터를 리두로그파일에 기록
그리고 해당 DB BUFFER CACHE는 PINNED상태에서 DIRTY상태로 바뀜.
그다음 DBWR이 DB버퍼캐시에 변경된 블록 데이터를 데이터파일에 저장.
🌱 Clean (깨끗한) 버퍼: 이 상태의 버퍼는 디스크와 일치하며 변경되지 않은 상태입니다. 따라서 디스크에 대한 추가 작업 없이 버퍼 캐시에서 읽을 수 있습니다.
🌱3 : dirty buffer : 비어있지 않은 버퍼 (데이터가 변경되어서 디스크의 데이터와 서로 일지하지 않는 데이터) - 동기화가 되지 않은 상태라서 동기화가 되면 프리버퍼로 바뀜
예 : select ename, sal from sal where ename = 'SCOTT';
1 : 버퍼캐시에 위의 데이터가 있는지 확인
2 : 없으면 디스크에서 찾아서 버퍼 캐시에 복사본을 올림
3 : 서버프로세서 → 유저 프로세서에게 결과 전달
1 : 버퍼 개시에서 SCOTT의 데이터를 찾습니다.
2 : 메모리에 있으면 바로 업데이트를 수행합니다. (pinned buffer → dirty buffer)
3 : 그러면 그 버퍼는 dirty buffer가 됩니다. (메모리와 디스크 간의 싱크가 서로 맞지 않게 됨)
디스크가 아닌 메모리에서 변경하는 이유 : 빨리 변경하려고
디스크를 통하는 과정은 상대적으로 무거움.
DBWR라는 백그라운드 프로세서가 변경된 버퍼를 디스크로 내려서 똑같이 바꿔써줌.
오라클에서 데이터가 변경 혹은 추가 된 이후 commit 명령을 내리면 LGWR이 Redo Log 파일에 저장한다. 그리고 해당 버퍼의 Pinned 상태에서 Dirty 상태로 변경된다. DB 버퍼 캐시에 변경된 데이터를 저장하는 역할은 DBWR이 한다.
버퍼 캐시에 Dirty 캐시가 있고, DBWR이 작동할 때 DB버퍼 캐시에 있는 해당 블록을 통째로 가져다 DB 파일에 저장하게 된다. SELECT의 경우도 DB파일에 있는 필요한 블록을 DB버퍼 캐시에 통째로 복사한다.
DBWR이 DB 버퍼 캐시 내 블록을 변경하고 저장이 필요한 블록을 찾아서 디스크의 데이터 파일로 저장하는 경우는 다양하다. 그 중 일부는 다음과 같다
Checkpoint 신호가 발생했을 때
Direct Path Read/Write가 진행될 때
DROP TABLE 또는 TRUNCATE TABLE 명령이 실행될 때
commit 이후에 LGWR이 Redo Log Buffer에 기록된 데이터를 Redo Log 파일에 저장한 다음 DBWR에 알려주지 않으면 나중에 DBWR의 작업량이 늘어날 수가 있다. 그래서 Checkpoint 신호가 DBWR에게 저장 가능한 버퍼를 저장하도록 신호를 준다.
오라클은 대부분의 데이터를 DB 버퍼 캐시에 불러와 처리한다. 하지만 대용량 데이터를 처리할 경우 DB 버퍼 캐시를 경유하면 부하가 발생할 수 있다. 이럴 때 사용되는 것이 Read/Write다.
테이블 데이터를 DELETE명령으로 삭제할 경우에는 롤백 명령이 내려질 수도 있으므로 이에 대비해야 하지만, DROP TABLE이나 TRUNCATE TABLE같은 DDL문장은 따로 COMMIT이나 롤백을 하지 않으므로 DB 버퍼 캐시는 바로 기록 후 처리한다.
대부분의
시스템에서는 하나의 데이터베이스 기록자 프로세스(DBW0)만 사용하면 되지만, 시스템에서
데이터를 많이 수정하는 경우에는 기록 성능을 개선하기 위해 추가 프로세스(DBW1~DBW9
및 DBWa~DBWz)를 구성할 수 있습니다.
데이터베이스 버퍼 캐시의 버퍼는 수정되면 더티로 표시되며 SCN 순서로 보관되는 상위
체크포인트 큐에 추가됩니다. 그러므로 이 SCN 순서는 이들 변경된 버퍼에 대해 리두 로그에
기록되는 리두 순서와 일치합니다.
프로세스가 사용 가능한 버퍼를 얻기가 어려운 범위)까지 떨어지면 DBWn은 프로세스가
필요할 때 버퍼를 바꿀 수 있도록 LRU List의 아래쪽에 있는 데이터 파일에 대해 자주
사용되지 않는 버퍼를 기록합니다.
SGA에는 Instance Failure의 경우 Recovery가 시작되어야 하는 리두 스트림 위치의 RBA(리두
바이트 주소)를 포함하는 메모리 구조가 들어 있습니다. 이 구조는 리두에 대한 포인터 역할을
하며, 3초에 한 번씩 CKPT 프로세스에 의해 콘트롤 파일에 기록됩니다. DBWn은 더티 버퍼를
SCN 순서로 기록하며 리두는 SCN 순서로 되어 있으므로 DBWn이 LRUW list에서 더티
버퍼를 기록할 때마다 SGA 메모리 구조에 포함된 포인터도 전진하여 해당 Instance Recovery
(필요한 경우)가 정확한 위치에서부터 리두 읽기를 시작하고 불필요한 I/O를 읽지 않도록 합니다.
이를 Incremental 체크포인트라고 합니다.
• 서버 프로세스가 버퍼를 임계값 수만큼 스캔한 후에 재사용 가능한 클린 버퍼를 찾지
못하면 DBWn에 기록을 수행하라는 신호를 보냅니다. 그러면 DBWn은 다른 처리를
수행하면서 더티 버퍼를 디스크에 비동기 방식으로 기록합니다.
• DBWn은 버퍼를 기록하여 Instance Recovery가 시작되는 리두 스레드(로그)의 위치인
체크포인트를 전진시킵니다. 이 로그 위치는 버퍼 캐시의 가장 오래된 더티 버퍼에
의해 결정됩니다.
Dirty 버퍼 관리: 버퍼 캐시에는 변경된 데이터 블록이 존재하는데, 이러한 블록을 "dirty" 상태라고 합니다. 즉, 버퍼에 있는 데이터가 디스크와 일치하지 않는 상태입니다. 이런 데이터 블록들은 언젠가 디스크에 반영되어야 합니다.
LRU List 관리: LRU (Least Recently Used) List는 버퍼 캐시 내의 데이터 블록들의 사용 패턴을 추적하는데 사용됩니다. 버퍼 캐시에서 데이터 블록을 읽거나 쓸 때, 사용된 블록은 LRU List의 상단에 위치하게 되고, 오랫동안 사용되지 않은 블록은 하단에 위치합니다. DBWn은 주로 LRU List 하단에 있는, 오랫동안 사용되지 않은 dirty 데이터 블록들을 디스크에 기록합니다. 이렇게 하면 덜 중요한 데이터가 디스크로 기록되고, 캐시 공간을 새로운 데이터로 확보할 수 있습니다.
임계값 및 성능 조절: 내부 임계값을 설정하여 시스템 성능을 조절하고, 버퍼 캐시의 크기와 디스크 I/O를 관리합니다. 내부 임계값을 넘어서면 DBWn은 더 많은 데이터 블록을 디스크로 기록하여 캐시 공간을 확보하려고 노력합니다.
디스크에 변경사항 반영: 마지막으로, DBWn은 디스크에 있는 데이터 파일을 업데이트하거나 새로운 데이터를 기록합니다. 이렇게 함으로써 데이터의 영속성을 보장하고 데이터베이스의 일관성을 유지합니다.
요약하면, DBWn은 데이터베이스의 일관성과 지속성을 유지하기 위해 버퍼 캐시의 변경된 데이터 블록을 디스크에 기록하는 역할을 합니다. 기록된 데이터는 디스크와 버퍼 캐시의 내용을 일치시키며, 오랫동안 사용되지 않은 데이터 블록을 디스크로 밀어내어 캐시 공간을 확보합니다.
여기서 SCN(시스템 변경 번호)이 중요한 역할을 합니다. SCN은 데이터베이스 내의 모든 변경 작업에 고유한 번호를 할당하는 시스템적인 값입니다. 이 SCN 값은 리두 로그와 관련이 깊습니다.
데이터베이스에서 버퍼가 수정되면, 해당 버퍼는 더티로 표시됩니다. 그리고 이 변경된 버퍼에 대한 SCN이 할당됩니다. 이후에 이러한 더티 버퍼는 SCN 순서대로 상위 체크포인트 큐에 추가됩니다. 이 큐는 변경된 버퍼들을 일정한 순서로 관리하며, 이들을 디스크에 기록하는 역할을 합니다.
리두 로그는 데이터베이스 변경 작업에 대한 로그로, 데이터베이스의 변경 내용을 추적하는 중요한 메커니즘입니다. 리두 로그에는 변경 작업과 해당 변경이 발생한 SCN이 포함됩니다. 그리고 SCN은 데이터베이스의 일관성과 복구를 보장하기 위한 핵심 요소 중 하나입니다.
따라서 데이터베이스에서 변경된 버퍼들이 SCN 순서로 상위 체크포인트 큐에 추가되면, 이 순서는 리두 로그에 기록되는 변경 작업과 일치합니다. 이것은 데이터베이스의 변경 내용을 추적하고, 필요한 경우 데이터베이스를 이전 상태로 복구하는 데 사용됩니다. 이런 방식으로 데이터베이스의 일관성과 내구성을 유지할 수 있게 됩니다.
dbwr은 백그라운드 프로세스중 하나인데 데이터베이스 기록자 프로세스 라고 해.
데이터베이스 버퍼 캐시에서 변경 완료 후에 저장되어야 하는 블록을 데이터 파일로 저장하는 역할을 하고 기본적으로 DBW0 하나가 작동하지만 i/o가 많이 추가로 더 필요하면 DBW1 ~ DBW9를 동시에 사용하여 성능을 향상시킬 수 있지만, 단일 프로세서의 시스템에서는 안돼.
일단 버퍼의 종류에 대해 먼저 설명하자면
🌱 1 : free buffer : 비어있는 버퍼
🌱2 : pinned buffer : 비어있지 않은 버퍼 (지금 막 데이터가 올라갔으나 변경되진 않는 버퍼) - commit되지 않음
🌱3 : dirty buffer : 비어있지 않은 버퍼 (데이터가 변경되어서 디스크의 데이터와 서로 일지하지 않는 데이터) - 동기화가 되지 않은 상태라서 동기화가 되면 프리버퍼로 바뀜
이야.
우리가 sql을 날리면
1. 버퍼 캐시에서 스캇의 데이터를 찾고
2. 메모리에 있다면 바로 업데이트를 수행해. 여기서 버퍼는 핀드에서 더티로 바뀌어.
3. 바뀐 더티 버퍼는 디스크와 싱크가 서로 맞지 않게 되므로, DBWR가 변경된 버퍼를 디스크로 내려서 똑같이 맞추어줘(변경시켜줌)
이외에 DBWR이 DB 버퍼 캐시 내 블록을 변경하고 저장이 필요한 블록을 찾아서 디스크의 데이터 파일로 저장하는 경우는 다양하다. 그 중 일부는 다음과 같다.
commit 이후에 LGWR이 Redo Log Buffer에 기록된 데이터를 Redo Log 파일에 저장한 다음 DBWR에 알려주지 않으면 나중에 DBWR의 작업량이 늘어날 수가 있다. 그래서 Checkpoint 신호가 DBWR에게 저장 가능한 버퍼를 저장하도록 신호를 준다.
LGWR, 체크포인트 정리