Describe 롤백세그먼트관리 here {{{ ====================== 롤백 세그먼트 관리하기 ====================== 이미 블록, 익스텐트, 세그먼트라는 부분에서 롤백세그먼트에 대해서 다뤄 봤었습니다.. 여기서는 좀더 개념적이고...깊이 하도록 하겠습니다... 롤백세그먼트가 일련의 작업단위인 트랜잭션과 너무나도 깊은 관련이 있기 때문입니다.. 오라클의 롤백세그먼트가 멀까요??? 오라클 구조에 대한 부분을 아신다면 당연히 롤백세그먼트가 먼지 아시리라 생각합니다.. 만약 갱신을 하는 문장을 사용자가 던진다면... 오라클은 After Image와 Before Image를 메모리에 만들게 됩니다.. 이것을 여기서 변경전의 이미지 즉, Before Image를 롤백세그먼트에 기록하게됩니다.. 롤백세그먼트는 물리적인 파일을 말합니다.. 메모리에는 DB_Block_Buffer를 말하지여... 변경전의 이미지와 변경후의 이미지를 관리한다는 의미는 트랜잭션을 관리한다는 의미입니다... 이것을 또한 트랜잭션간에 '일기 일관성'을 유지하도록 하는 것입니다... 데이타베이스 관리 시스템에서 아주 중요한 부분이지여... 중요한 부분이기 때문에 롤백세그먼트는 항상 관심을 대상이어야 합니다.. 롤백세그먼트는 데이타베이스가 트랜잭션을 처리하는 능력을 제어하기 때문에 그것들은 데이타베이스의 성능에 있어 중요한 역할을 합니다... 그럼 롤백세그먼트는 항상 오라클이 사용하는 것일까??? 아니다...롤백세그먼트는 SQL명령인 update, insert, delete 트랜잭션들에 대해서 사용할 수 있고, alter table과 같은 객체들에 대한 변경작업에는 사용되지 않습니다....사용되지 않는게 아니라.. 사용할 필요가 없는 메카니즘을 가지고 있는 것입니다... 위에서 롤백세그먼트는 물리적인 파일에 저장된다고 했습니다... 논리적으로 볼때 물리적인 파일(데이타 파일)은 테이블스페이스에 관련되어 있지여... 즉, 롤백세그먼트는 테이블스페이스에 저장된다는 소리입니다.... 오라클 데이타베이스에서 처음 생성되는...꼭 필요한 롤백세그먼트는 system 테이블스페이스에 생성되는 시스템 롤백세그먼트입니다... 일반적으로 이 시스템 테이블스페이스에는 다른 롤백세그먼트를 생성하지 않습니다... 이유는 당연히 시스템 테이블스페이스에는 오라클의 동작할때 꼭 필요한 정보가 저장되어 있기 때문에 중요하고, 또한 입/출력이 많기 때문에 같은 시스템 테이블스페이스에 시스템 테이블스페이스를 위한 롤백세그먼트를 제외하고는 다른 롤백세그먼트를 저장않는게 좋습니다.. 롤백세그먼트는 테이블스페이스에 속한 데이타 파일의 크기에 의존하게 됩니다.. 그러므로 시스템 테이블스페이스에 생성한 롤백세그먼트의 크기를 결정하는 일은 상당히 중요합니다.. 테이블 스페이스에 생성한 롤백세그먼트의 크기를 너무 작게 잡아논다면...오라클이 어느정도 한계에 도달하면 동작하지 않습니다...주의해야죠... 롤백세그먼트가 이해가 가시나요??? 아차차차...빼먹은게 있군여.... 롤백세그먼트가 하는 역할은 또한 복구를 위한 것입니다...만약 오라클 인스턴스가 비정상적인 종료를 했을때에 대비한 것이지여... 즉, 데이타파일에는 변경이미지가 저장이 되어 있으나 제어파일등의 오라클이 제대로 동작하기 위한 요소에 아직은 SCN정보가 적용이 되지않을 수 있습니다.. 그렇기 때문에...오라클은 리두로그 파일을 읽어서 롤백세그먼트에 저장된 이전이미지를 사용하여...SCN 정보를 맞추고 복구하는 짓을 하지여... 그렇다면 질문하나를 해보겠습니다.... <질문> 오라클의 롤백세그먼트는 무엇을 저장하나요?? 그 무엇을 저장하는 이유는 멀까요? 네...모두 아시리라 믿습니다.. 롤백세그먼트는 트랜잭션에 의해 수정된 행들을 포함하는 Before Image를 담고 있습니다... 즉, 트랜잭션의 롤백에 의해서 이전 상태로 돌아가기 위함과...또한 읽기 일관성을 위한 것이죠... 읽기 일관성이란 말이 좀 어렵게 느끼실지도 몰겠슴다.. 읽기 일관성은 여러 사용자가 데이타베이스에 접속해서 저장된 데이타를 보는 시간이 포함된 관점입니다.. 시간이 변하거나 해도 사용자가 보는 시점에서는 언제나 같아야 한다는 뜻입니다.. 하나의 롤백세그먼트는 여러개의 이전이미지를 가질 수 있습니다.. 롤백세그먼트의 개수는 성능상에서도 중요한 요소가 됩니다.. 즉, 트랜잭션이 발생했을 때 롤백세그먼트를 사용하지 못한다면 더이상 사용자는 작업을 할 수 없는 것이지여.. 오라클은 라운드 로빈 방식이라는 방식으로 트랜잭션에 대한 롤백세그먼트를 할당합니다.. 이것은 사용자의 직접적인 개입이 필요치 않습니다... 물론 사용자가 트랜잭션에 대해서 롤백세그먼트의 할당을 명시할 수도 있습니다.. 이부분은 조금 있다가 다시 살펴보구여... 앞에서 나온 라운드 로빈방식은 실행되고 있는 트랜잭션 부하량을 분산시키도록 설계된 것입니다... 하나의 롤백세그먼트는 여러개의 트랜잭션들을 지원할 수 있습니다... 일반적으로 하나의 블록에 하나의 트랜잭션을 설정하는 하는 것입니다.. 그렇다면 롤백세그먼트의 크기가 문제가 되기도합니다.. 크기가 큰 적은 수의 롤백세그먼트를 사용하고 있다면 관리상의 잇점은 있지만...디스크 공간을 낭비할 수도 있고... 또한 디스크경합을 유발해서 성능을 저하시키는 잠재적인 문제가 있을 수 있습니다.. 그렇다고 너무 작게 많은 수의 롤백세그먼트를 사용한다면 만약 크기가 큰 트랜잭션이 진행되면서 동적으로 롤백세그먼트의 크기가 확장되서 또한 성능상의 문제를 일으킬수 있습니다... 그러므로 이러한 두가지 상황을 적절하게 잘 판단해서 적절한 크기의 롤백세그먼트를 생성해야 합니다.. 이 부분은 조금 있다가 또다시 자세히 알아보겠습니다.. =============================== 롤백 세그먼트의 활성화/비활성화 =============================== 오라클을 처음 셋업하면 오라클은 시스템테이블 스페이스 시스템 롤백세그먼트를 생성합니다... 그리고 데이타베이스를 생성할때 두번째 롤백세그먼트를 만듭니다... 두번째 만드는 롤백세그먼틑 데이타베이스 생성을 위해서 만드는 것입니다.. 분명히 오라클 관리자는 오라클 데이타베이스 생성을 마친뒤에 다른 테이블스페이스에 롤백 세그먼트를 생성할 것입니다.. 이때 시스템 테이블스페이스에는 2개의 롤백세그먼트가 존재하게 되고, 다른 테이블 스페이스에 롤백세그먼트가 더 있게 될 것입니다... 이때 관리자는 시스템 테이블스페이스에 생성된 두번째 롤백세그먼트를 비활성화 시키는 것이 좋습니다.. 왜냐하면 시스템 가동중에 트랜잭션이 시스템 테이블스페이스의 두번째 롤백세그먼트를 사용할 수 있기 때문입니다.. 만약 큰 트랜잭션이 진행하다보면 시스템 테이블스페이스의 공간이 없어져 오라클이 가동되지 못하는 불상사가 일어날 수 있기 때문입니다.. 그렇다면 시스템 테이블스페이스에 있는 시스템 롤백세그먼트는 어떨때 쓰일까요? 이 롤백세그먼트는 데이타베이스 수준의 트랜잭션을 위해서 사용합니다..즉, 머...사용자 권한이라든지... 데이타 사전의 수정등에 쓰이는 것입니다.. 한기지 또 의문이 생길지도 몰겠습니다.. 시스템 테이블스페이스의 두번째 시스템 롤백세그먼트를 기냥 드롭시켜버리지....비활성화 시키느냐... 그러면 공간을 차지하고 있지 않느냐...하는 물음표를 머리 양옆에 달지도 모릅니다... ?ㅡㅡ? 이유는 비상용으로 놔두는 것입니다... 다른 롤백세그먼트를 위한 테이블스페이스에 문제가 생겼을 경우 비상용으로 사용하기 위한 것이지여... 24시간...365일 가용성이라고 하나여?? 암튼...그런 문제지여...헐헐~ 오라클8i버전에는 이런 파라미터가 없을 것입니다... 파라미터를 변경시켜줍니다... ########################################### # 시스템 관리 실행 취소 및 롤백 세그먼트 ########################################### undo_management = MANUAL ---------> 오라클9i에서는 이런 파라미터가 존재한다...auto/manual이 값으로 올수 있다... undo_tablespace = (UNDOTBS, RBS) ---------> 롤백세그먼트에 쓰일 테이블스페이스...기본적으로 UNDOTBS라는 테이블스페이스를 쓴다.. SQL> create tablespace RBS 2 datafile 'k:\oracle_tablespace\RBS01.dbf' size 70M 3 default storage (initial 8k next 8k pctincrease 0) ------------> pctincrease는 반드시 0으로 설정되어야 합니다.. 4 extent management dictionary; ------------> extent managemet local autoallocate로 설정되면 롤백세그먼트를 생성하지 못합니다.. 테이블 영역이 생성되었습니다. SQL> create rollback segment rbs1 2 tablespace RBS 3 storage (initial 8K next 8K optimal 5M); 롤백 세그멘트가 생성되었습니다. SQL> create rollback segment rbs2 2 tablespace RBS 3 storage (initial 8K next 8K optimal 5M); 롤백 세그멘트가 생성되었습니다. SQL> create rollback segment rbs3 2 tablespace RBS 3 storage (initial 8K next 8K optimal 5M); 롤백 세그멘트가 생성되었습니다. SQL> create rollback segment rbs4 2 tablespace RBS 3 storage (initial 8K next 8K optimal 5M); 롤백 세그멘트가 생성되었습니다. SQL> create rollback segment rbs5 2 tablespace RBS 3 storage (initial 8K next 8K optimal 5M); 롤백 세그멘트가 생성되었습니다. SQL> create rollback segment rbs6 2 tablespace RBS 3 storage (initial 8K next 8K optimal 5M); 롤백 세그멘트가 생성되었습니다. SQL> select segment_name, tablespace_name, status 2 from dba_rollback_segs; SEGMENT_NAME TABLESPACE_NAME STATUS ------------------------------ ------------------------------ ---------------- SYSTEM SYSTEM ONLINE ------------> 시스템 롤백세그먼트말고는 모두 오프라인입니다... _SYSSMU1$ UNDOTBS OFFLINE _SYSSMU2$ UNDOTBS OFFLINE _SYSSMU3$ UNDOTBS OFFLINE _SYSSMU4$ UNDOTBS OFFLINE _SYSSMU5$ UNDOTBS OFFLINE _SYSSMU6$ UNDOTBS OFFLINE _SYSSMU7$ UNDOTBS OFFLINE _SYSSMU8$ UNDOTBS OFFLINE _SYSSMU9$ UNDOTBS OFFLINE _SYSSMU10$ UNDOTBS OFFLINE RBS1 RBS OFFLINE RBS2 RBS OFFLINE RBS3 RBS OFFLINE RBS4 RBS OFFLINE RBS5 RBS OFFLINE RBS6 RBS OFFLINE 17 개의 행이 선택되었습니다. 앞에서 생성해준 롤백세그먼트를 오라클을 시작할때 온라인으로 설정하기 위해서 파라미터파일에 다음과 같이 명시해준후... 오라클을 재시작합니다.. ########################################### # 시스템 관리 실행 취소 및 롤백 세그먼트 ########################################### undo_management = MANUAL undo_tablespace = (UNDOTBS, RBS) rollback_segments = (RBS1, RBS2, RBS3, RBS4, RBS5, RBS6) ------------> 추가시켜준다... SQL> startup pfile = E:\oracle\admin\ORCL9i\pfile\init.ora ORACLE 인스턴스가 시작되었습니다. Total System Global Area 118255568 bytes Fixed Size 282576 bytes Variable Size 83886080 bytes Database Buffers 33554432 bytes Redo Buffers 532480 bytes 데이터베이스가 마운트되었습니다. 데이터베이스가 열렸습니다. SQL> select segment_name, tablespace_name, status 2 from dba_rollback_segs; SEGMENT_NAME TABLESPACE_NAME STATUS ------------------------------ ------------------------------ ---------------- SYSTEM SYSTEM ONLINE _SYSSMU1$ UNDOTBS OFFLINE _SYSSMU2$ UNDOTBS OFFLINE _SYSSMU3$ UNDOTBS OFFLINE _SYSSMU4$ UNDOTBS OFFLINE _SYSSMU5$ UNDOTBS OFFLINE _SYSSMU6$ UNDOTBS OFFLINE _SYSSMU7$ UNDOTBS OFFLINE _SYSSMU8$ UNDOTBS OFFLINE _SYSSMU9$ UNDOTBS OFFLINE _SYSSMU10$ UNDOTBS OFFLINE RBS1 RBS ONLINE ------------> 파라미터파일에 명시한 데로 롤백세그먼트가 활성화 된것이 보입니다.. RBS2 RBS ONLINE RBS3 RBS ONLINE RBS4 RBS ONLINE RBS5 RBS ONLINE RBS6 RBS ONLINE 17 개의 행이 선택되었습니다. 그럼...파라미터 파일에서 온라인 시키는 것 말구..직접 비활성화 활성화 시켜보겠습니다.. SQL> alter rollback segment RBS5 offline; 롤백 세그멘트가 변경되었습니다. SQL> select segment_name, tablespace_name, status 2 from dba_rollback_segs 3 where segment_name = 'RBS5'; SEGMENT_NAME TABLESPACE_NAME STATUS ------------------------------ ------------------------------ ---------------- RBS5 RBS OFFLINE ----------------> 오프라인 되었습니다.. SQL> alter rollback segment RBS5 online; 롤백 세그멘트가 변경되었습니다. SQL> select segment_name, tablespace_name, status 2 from dba_rollback_segs 3 where segment_name = 'RBS5'; SEGMENT_NAME TABLESPACE_NAME STATUS ------------------------------ ------------------------------ ---------------- RBS5 RBS ONLINE -----------> 온라인 되었습니다.. 롤백세그먼트는 시스템 롤백세그먼트와 시스템 롤백세그먼트를 제외한 것들이 있습니다... 만약 관리자가 시스템 롤백세그먼트를 오프라인 시켜려고 한다면 오라클은 에러를 리턴합니다.. 또한 파라미터 파일에 명시해서도 안됍니다... 파라미터 파일에 명시한 것은 관리자를 제외한 사용자들이 데이타베이스에 접속해서 사용하는데 사용되는 것을 명시해주는 것인데.. 거기에 시스템 롤백세그먼트를 명시하는 것은 앞뒤가 안맞는 것이지여.. SQL> alter rollback segment system offline; alter rollback segment system offline * 1행에 오류: ORA-01597: 시스템 롤백 세그먼트를 온라인 혹은 오프라인시킬 수 없습니다. ========================================= 특정 트랜잭션에 롤백 세그먼트의 사용 명시 ========================================= 아까도 언급했었지여... 만약 큰 트랜잭션(여기서 말하는 큰 트랜잭션은 크기가 큰 데이타를 변경하는 작업, 또는 대규모 트랜잭션)을 진행 시킨다면... 특별히 롤백세그먼트를 생성해주는 것이 좋습니다... 왜냐하면 롤백세그먼트가 확장하다가 크기가 모질라면 Before Image를 모두 저장할 수 없게 될 수 있기 때문입니다... 크기가 좀 큰 롤백세그먼트를 하나 만들어 보겠습니다... 그리고 set transcation문을 써서 특정 트랜잭션에 특정 롤백 세그먼트를 사용하도록 해보겠습니다.. SQL> create tablespace LARGE_RBS 2 datafile 'k:\oracle_tablespace\LARGE_RBS01.dbf' size 70M 3 default storage (initial 8k next 8k pctincrease 0) 4 extent management dictionary; 테이블 영역이 생성되었습니다. SQL> create rollback segment large_rbs 2 tablespace RBS 3 storage (initial 8K next 8K optimal 20M); 롤백 세그멘트가 생성되었습니다. SQL> alter rollback segment large_rbs online; 롤백 세그멘트가 변경되었습니다. SQL> create user yasi identified by yasi ----------------> yasi사용자 생성 2 default tablespace users 3 temporary tablespace temp; 사용자가 생성되었습니다. SQL> grant connect, resource to yasi; 권한이 부여되었습니다. SQL> connect yasi/yasi 연결되었습니다. SQL> CREATE TABLE EMP 2 (EMPNO NUMBER(4) CONSTRAINT PK_EMP PRIMARY KEY, 3 ENAME VARCHAR2(10), 4 JOB VARCHAR2(9), 5 MGR NUMBER(4), 6 HIREDATE DATE, 7 SAL NUMBER(7,2), 8 COMM NUMBER(7,2), 9 DEPTNO NUMBER(2) ); 테이블이 생성되었습니다. SQL> connect scott/tiger 연결되었습니다. SQL> grant select on emp to yasi; -----------------> scott사용자의 emp 테이블의 읽기 권한을 yasi 사용자에게 줬다.. 권한이 부여되었습니다. SQL> connect yasi/yasi 연결되었습니다. SQL> set transaction use rollback segment large_rbs; ---------> large_rbs 롤백 세그먼트를 다음에 오는 트랜잭션에 사용하라고 명시 트랜잭션이 설정되었습니다. SQL> insert into emp 2 select * from scott.emp; 14 개의 행이 만들어졌습니다. SQL> select count(*) from emp; COUNT(*) ---------- 14 SQL> commit; --------------------------------> 커밋을 하게 되면 이제 일반적인 동작을 한다... 커밋이 완료되었습니다. ================================================== ORA-1555 snapshot too old (rollback segment small) ================================================== 아주 유명한 오류이지여...미리 알아두실 것은 이 오류가 안나타나게 할 방법은 없다는 것입니다... 오라클 자체의 구조상의 문제로 이 오류가 나타날 확률은 줄일 수가 있지.... 완전히 해결할 방법은 없습니다.. 이 오류가 나타나는 원인과 롤백세그먼트의 관계를 알아보구...이 오류가 나타날 확률을 줄이는 방법을 알아보도록 하겠습니다.. 자...그러면 ORA_1555 에러가 왜 일어나는지 알아봅시다.. 원인을 알면 그에 대한 대처 방법은 자연히 나오겠죠? 헐헐~ 오라클에 여러 사용자가 접속을 하게 됩니다... 각 사용자는 각각 트랜잭션을 발생시키겠지여...그러면 롤백세그먼트에는 각각의 트랜잭션에 대한 Before Image를 저장하겠지여...그럼 롤백 세그먼트는 계속 확장하게 됩니다.. 롤백세그먼트는 순환적인 세그먼트입니다... 트랜잭션이 확장 영역 안에서 더 이상 공간을 얻을 수 없을때 롤백 세그먼트는 롤백 세그먼트 엔트리를 계속써나갈 또 다른 확장영역을 차지하게 된다는 소리지여... 그런데 롤백세그먼트는 순환적이라고 했습니다... 무한히 확장한다는 것은 문제가 있습니다...일단 커밋이 되면 롤백세그먼트의 이전 이미지는 없어지는 것이지여.. 물론 순환적이라고 해서 아직 커밋이 되지않은 트랜재션이 쓰고있는 롤백세그먼트의 확장영역을 건드리지는 않습니다.. 만약 확장영역을 쓰는 한 트랜잭션이 지금 마지막 확장영역고 첫번째 확장영역의 트랜잭션이 커밋되지 않았다면 첫번째 확장영역으로 돌아가 그 첫번째 확장영역을 쓰지 않고 다른 확장영역을 새로 만들어 가지게 됩니다.. 계속 확장한다는 뜻이지여...즉, 동적으로 자신의 확장시키게 됩니다.. 만약 과도하게 확장한 영역이 있으면 오라클은 optimal 옵션에서 설명했듯이 명시한 확장영역 빼고는 나머지는 shink 시킵니다... 그렇다면 이러한 속성을 가지고 있는 롤백 세그먼트의 ORA_1555에러는 언제 일어나는가 알아봅시다.. 하나의 긴 트랜잭션이 있다고 가정해봅니다... 이 트랜잭션(시간이 오래걸리는 질의)이 진행중인데.....다른 사용자가 갱신을 했다고 가정해봅니다... 즉, 긴 질의를 하는데 쓰고 있는 롤백세그먼트의 영역을 다른 트랜잭션이 먹어버려서 쿼리가 실패하는 경우입니다... 이것을 ORA-1555 snapshot too old 에러라고 합니다.... 확장영역 크기 |------------------|----------------------------------------------------->|확장영역의 끝 | | | | | | | | | 이 시점에서 긴 트랜잭션(질의)이 시작|------------------------------->| 트랜잭션 진행중 | | 다른 트랜잭션시작|--------------------->| 다른 트랜잭션이 쓰고 있는 확장영역을 먹어버렸다 ----> 긴 쿼리 실패!!!! 이런 그림이 연상되겠씁니다... 해결방법은 괄호 안에 있습니다... 롤백 세그먼트 안에 있는 기존 엔트리들이 덮어쓰여지지 않게 하려면 더 많은 공간을 추가하여 첫번째 확장영역으로 다시 되돌아오는데 시간을 벌 수 있게 하는 것입니다.. 또 다른 방법은 크기가 큰 롤백세그먼트를 생성해서 큰 롤백세그먼트를 요구하는 작업시 사용하는 것입니다... 앞에서 한번 해봤습니다...특정 롤백세그먼트를 특정 트랜잭션이 사용하게 하는 것이죠... 첫번째 방법은 좀 꾸진듯 해보이구여...두번째 방법은 웬지 잘 일어나지도 않는 질의를 위해서 저장공간을 잡고 있다는게 좀 걸립니다... 어쩔 수 없지여머... 저 위 두개의 방법 말고....대규모 트랜잭션은 온라인 트랜잭션 프로세싱이 최소한 줄었을때 오랫동안 질의들이 가끔씩 실행되도록 스케줄을 잡는 것이 좋습니다.. ================ 저장 공간의 할당 ================ 이 부분은 앞에서 설명한 ORA-1555 snapshot too old 에러의 대처방법중 4번째를 설명하려고 하는 것입니다.. 4번재 대처 방법은 롤백세그먼트 생성시 사용되는 optimal 파라미터의 값을 결정하는 것입니다.. 이 파라미터는 롤백 세그먼트 생성시 명시한 만큼 가장 오래된 확장 영역이 드롭되고, 그 롤백 세그먼트는 미리 정의된 만큼의 크기로 줄어듭니다... 이러한 방법은 트랜잭션이 완료되면 롤백 세그먼트는 그것을 optimal 크기 값을 검사하는데, 만약 그 값이 optimal의 크기를 넘어선다면 롤백세그먼트는 가장 오래된 확장 영역을 삭제하게 됩니다.. 이것은 optimal의 크기를 잘 유지하면서 또한 질의들을 잘 지원하도록 합니다.. 즉, optimal의 크기를 적당한 선에서 작게 설정해줌으로써 ORA-1555 snapshot too old 에러가 나지 않게 최대한 배려하는 것이 되는 거지여.. 그러나 롤백 세그먼트를 축소시키면 현재 트랜잭션들에 대해 사용할 수 있는 비활성화된 롤백 데이타의 양이 줄어들게 된다는 부작용도 있습니다.. ================================ 롤백 세그먼트 공간 할당 모니터링 ================================ SQL> select segment_name, tablespace_name, header_file, bytes, blockS 2 from dba_segments 3 where segment_type = 'ROLLBACK'; SEGMENT_NAME TABLESPACE_NAME HEADER_FILE BYTES BLOCKS --------------------------------------------------------------------------------- ------------------ SYSTEM SYSTEM 1 430080 105 RBS1 RBS 10 32768 8 RBS2 RBS 10 32768 8 RBS3 RBS 10 32768 8 RBS4 RBS 10 32768 8 RBS5 RBS 10 32768 8 RBS6 RBS 10 65536 16 LARGE_RBS RBS 10 32768 8 8 개의 행이 선택되었습니다. SQL> select segment_name, extents, initial_extent, next_extent, min_extents, max_extents 2 from dba_segments 3 where segment_type = 'ROLLBACK'; SEGMENT_NAME EXTENTS INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS --------------------------------------------------------------------------------- ---------- ------- SYSTEM 7 53248 53248 2 249 RBS1 2 8192 16384 2 249 RBS2 2 8192 16384 2 249 RBS3 2 8192 16384 2 249 RBS4 2 8192 16384 2 249 RBS5 2 8192 16384 2 249 RBS6 4 8192 16384 2 249 LARGE_RBS 2 8192 16384 2 249 8 개의 행이 선택되었습니다. 컬럼들의 중에 좀 모르겠는 것은 header_file일 것입니다...이것은 롤백 세그먼트의 첫번째 확장영역이 저장되어 있는 파일을 말합니다... optimal의 값을 모니터링을 하는 방법은 다음과 같습니다.. 만약 optimal의 크기가 명시되지 않았다면 그 값은 널값일 것입니다.. SQL> select n.name, s.optsize 2 from v$rollname n, v$rollstat s 3 where n.usn=s.usn; NAME OPTSIZE ------------------------------ ---------- SYSTEM RBS1 5242880 RBS2 5242880 RBS3 5242880 RBS4 5242880 RBS5 5242880 RBS6 5242880 LARGE_RBS 20971520 8 개의 행이 선택되었습니다. =================== 롤백세그먼트의 축소 =================== SQL> alter rollback segment large_rbs shrink to 20M; 롤백 세그멘트가 변경되었습니다. SQL> alter rollback segment large_rbs shrink; ---------------> 오라클이 알아서 롤백 세그먼트 축소를 시켜줍니다... 롤백 세그멘트가 변경되었습니다. ===================== 현재상태 모니터링하기 ===================== SQL> select segment_name, status, instance_num 2 from dba_rollback_segs; SEGMENT_NAME STATUS INSTANCE_NUM ------------------------------------------------------------ -------------------------------- ------ SYSTEM ONLINE _SYSSMU1$ OFFLINE _SYSSMU2$ OFFLINE _SYSSMU3$ OFFLINE _SYSSMU4$ OFFLINE _SYSSMU5$ OFFLINE _SYSSMU6$ OFFLINE _SYSSMU7$ OFFLINE _SYSSMU8$ OFFLINE _SYSSMU9$ OFFLINE _SYSSMU10$ OFFLINE RBS1 ONLINE RBS2 ONLINE RBS3 ONLINE RBS4 ONLINE RBS5 ONLINE RBS6 ONLINE LARGE_RBS OFFLINE 18 개의 행이 선택되었습니다. 여기서 instance_num은 롤백세그먼트가 속해있는 인스턴스, 한개 인스턴스를 갖는 시스템의 경우는 null값입니다.. 롤백세그먼트의 상태(status)값은 online, offline두가지 밖에 나오질 않았는데.. 이외에도 여러가지가 있습니다.. 다음은 그 상태값입니다... in use(online) : 온라인 available : 롤백세그먼트가 생성되었으나 아직 온라인 상태가 아니다. offline : 오프라인 pending offline : 롤백세그먼트가 온라인으로 가고 있는 중이다. invalid : 롤백세그먼트가 드롭되었다. 드롭된 롤백 세그먼트들은 이 상태로 데이타 딕셔너리 안에 계속 나타나게 된다. needs recovery : 롤백 세그먼트가 롤백될 수 없는 데이타를 포함하거나 손상되었다. partly available : 롤백세그먼트가 분산 데이타베이스에 걸쳐 있는 미결된 트랜잭션의 데이타를 포함하고 있다. ================================= 롤백세그먼트가 성능에 미치는 영향 ================================= 데이타베이스 관리자는 롤백세그먼트를 생성할때 optimal옵션을 줄 것입니다... 롤백세그먼트는 동적으로 확장/축소를 하게됩니다... 이러한 확장/축소 과정은 확장/축소하는 과정이 없을 때를 생각한다면 쓰잘때기 없는 짓이지여... 만약 대규모 트랜잭션이 진행되어서 optimal설정값을 넘어서 롤백세그먼트가 확장된다면 오라클은 다음과 같은 절차를 가지고 처리하게됩니다... - 트랜잭션을 처리한다. - 새로운 트랜잭션 엔트리에 대해 롤백 세그먼트 헤더 안에서 하나의 엔트리가 생성된다. - 트랜잭션 엔트리는 롤백 세그먼트의 확장 영역 안에서 블럭들을 얻는다. - 엔트리는 두번째 확장 영역 안으로 래핑을 시도한다. 이때 사용할 수 있는 확장영역이 없기 때문에 롤백세그먼트는 확장되어야 한다. - 롤백세그먼트는 확장된다. - 공간 관리에 대한 데이타 딕셔너리 테이블들이 업데이트된다. - 트랜잭션이 완료된다. - 롤백 세그먼트는 자기 optimal 값을 초과했는가를 검사한다. 검사 결과 현재 롤백 세그먼트는 자기의 optimal 값을 초과했다. - 롤백 세그먼트는 그것의 가장 오래된 비활성화된 상태의 확장 영역을 선택한다. - 가장 오래된 비활성화된 상태의 확장 영역이 삭제된다. 만약 그 엔트리가 하나의 확장영역안에 들어가도록 롤백 세그먼트의 크기가 설정되었다면 그런 처리 이벤트들의 순서는 다음과 같다. - 트랜잭션 시작 - 새로운 트랜잭션 엔트리에 대해 롤백세그먼트 헤더 안에서 하나의 엔트리가 생성된다. - 트랜잭션 엔트리는 롤백세그먼트의 확장영역 안에서 블럭을 얻는다. - 트랜재션이 완료된다. 첫번째 경우와 두번째 경우를 비교해 보시기 바랍니다... 첫번째는 10단계를 거치고...두번째는 4단계만을 거치면 됩니다... 확연하게 드러나는 작업절차입니다...즉, 엔트리가 하나의 확장영역 안으로 들어가도록 롤백세그먼트의 크기를 설정해야 한다는 것입니다... 불필요한 작업을 오라클에게 최대한 시키지 말아야 한다는 뜻이지여.. ========================= 롤백세그먼트 모니터링하기 ========================= 이러한 성능 모니터링은 v$rollstat 동적 성능뷰를 통해 볼 수 있습니다.. SQL> select * from v$rollstat; USN EXTENTS RSSIZE WRITES XACTS GETS WAITS OPTSIZE HWMSIZE SHRINKS CURBLK ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------- ------- 0 7 425984 4140 0 1908 0 425984 0 9 11 3 45056 64626 0 2565 0 5242880 45056 0 3 12 3 45056 62552 0 2561 0 5242880 45056 0 0 13 3 45056 62710 0 2561 0 5242880 45056 0 2 14 4 61440 60170 0 2539 0 5242880 61440 0 2 15 4 61440 59948 0 2537 0 5242880 61440 0 0 16 4 61440 60546 0 8095 0 5242880 61440 0 3 7 개의 행이 선택되었습니다. 오라클에는 UTLBSTAT.SQL과 UTLESTAT.SQL이란 스크립트가 있습니다.. 틀린글자 B --> BEGIN, E --> END 를 의미합니다.. 즉, 시작과 끝이 있다는 뜻입니다.... 이것이 의미하는 것은 어떤 특정 시점과 시점의 간격동안의 롤백세그먼트를 모니터링 할 수 있다는 뜻입니다.. 해봅시다... 1. @E:\oracle\ora90\rdbms\admin\utlbstat.sql 2. drop table stats$begin_roll; 3. create table stats$begin_roll as select * from v$rollstat where 0=1; --------> 테이블의 구조만 복사하려고..즉, 아무런 데이타가 없이 테이블의 구조만 복사하기 위한 것 4. drop table stats$end_roll; 5. create table stats$end_roll as select * from stats begin_roll; 6. insert into stats$begin_roll select * from v$rollstat; 7. @E:\oracle\ora90\rdbms\admin\utlestat.sql --> 이 스크립트가 실행되면 이 스크립트는 그 당시의 현재 값들에 대해 v$rollstat 테이블을 질의할으로써 stats$end_roll 테이블에 데이타를 채워넣게 됩니다.. 그런 다음 stats$roll이란 테이블이 생성됩니다. 8. insert into stats$end_roll select * from v$rollstat; 9. create table stats$roll as select e.usn uno_segment, e.gets-b.gets trans_tbl_gets, e.waits-b.waits trans_tbl_waits, e.writes-b.writes undo_bytes_written, e.rssize segment_size_bytes, e.xacts-b.xacts xacts, e.shrinks-b.shrinks shrinks, e.wraps-b.wraps wraps from stats$begin_roll b, stats$end_roll e where e.usn = b.usn; 마지막 9번의 결과는 stats$roll 테이블 안에 있는 데이타는 utlbstat와 utlestat를 실행시킨 사이의 간격 동안 축적된 각각의 롤백 세그먼트와 통계치들을 나타냅니다.. 다음은 stats$roll에서 사용가능한 컬럼들을 나열한 것입니다.. trans_tbl_gets : 롤배세그먼트 헤더 요청들의 개수 trans_tbl_waits : 대기 상태가 된 롤백 세그먼트 헤더 요청들의 개수 undo_bytes_written : 롤백세그먼트에게 기록된 바아트들의 수 segment_size_bytes : 롤백세그먼트 크기: 종료값만 고려 xacts : 활성화된 트랜잭션의 개수 shrinks : 롤백세그먼트가 optimal의 크기로 남아 있기 위해 실행해야 하는 shrink의 개수 wraps : 롤백세그먼트가 엔트리가 하나의 확장 영역으로부터 다른 확장 영역으로 래핑된 횟수 다음은 롤백세그먼트 하나당 트랜잭션들을 나타냅니다.. SQL> select r.name rr, nvl(s.username, 'no transaction') us, s.osuser os, s.terminal te 2 from v$lock l, v$session s, v$rollname r 3 where l.sid = s.sid(+) 4 and trunc(l.id1/65536) = r.usn 5 and l.type = 'TX' 6 and l.lmode =6 7 order by r.name; 선택된 레코드가 없습니다. 다음은 v$rollstat테이블로부터 writes 값을 선택하는 예입니다.. 여기서 말하는 writes의 값은 데이타베이스가 마지막으로 시작된 이후로 각 롤백세그먼트에게 기록된 바이트의 수를 기록하는 값입니다... SQL> select n.name, s.writes 2 from v$rollname n, v$rollstat s 3 where n.usn = s.usn; NAME WRITES ------------------------------------------------------------ ---------- SYSTEM 4140 RBS1 64820 RBS2 62940 RBS3 63098 RBS4 60364 RBS5 60142 RBS6 60740 7 개의 행이 선택되었습니다. 롤백세그먼트를 관리하는데 관리자가 파악해야 하는 제일 중요한 것은 비활성화 상태의 사용되고 있는(IIU, incacitve, in-use)엔트리들입니다.. 이것들은 커밋되거나 롤백되었지만 그 데이타는 개별적인 프로세스(오랫동안 실행되는 질의)들에 의해 사용되고 있습니다.. 즉, IIU의 양을 최소화하는 것입니다.. 이것을 알아내는 방법은 없습니다....결론적으로 ORA-1555 에러를 보고 받았을때서야 비로소 그런 롤백세그먼트가 있다는 것을 알 수 있습니다... IIU 데이타양을 최소화 하려면 오랫동안 지속되는 질의들이 언제 실행되는지 알아서 질의들을 고립시키는 것이 엔트리 양을 최소화하고 동시에 질의와 트랜잭션들간에 발생할 수 있는 잠재적인 I/O 경합을 막는데도 도움이 됩니다... 하나의 트랜잭션이 조작하고 있는 테이블을 또 다른 트랜잭션이 참조하는 경우와 같이 동시 발생적인 트랜잭션들이 발생하게 되면 IIU 데이타의 양이 많게 됩니다.. 만약 그런 상황을 최소화 할 수 있다면 그 결과로서 롤백 세그먼트 데이타 요구사항들이 고르게 분산되고 알맞은 시스템이 만들어 질 것입니다.. 여기까지해서 롤백세그먼트를 마치겠습니다... 다른 모자란 부분은 여러분들이 책을 찾아보시고...해보시고..해서 익히시기 바랍니다... 롤백세그먼트 관리 마칩니다... }}}