[오라클 DB관리]23.09.22

망구씨·2023년 9월 22일
0

오라클DB관리

목록 보기
13/19
post-thumbnail

복습

✍🏻 undo는 작업한것을 취소하는 것, redo는 다시 작업하는 것 !

언두 정보 저장

💡 undo tablespace안에 undo segment가 있다. undo segment에 update나 delete를 수행했을 때의 수정되기 전 data가 저장되어 있습니다.
💡 undo segment에 저장된 데이터는 commit을 했어도 기본 15분은 덮어쓰지 않고 보관하고 있다. 왜냐하면 flashback을 가능하게 해주려고 보관하는 것입니다. undo_retention

언두 정보는 언두 세그먼트에 저장되며 언두 세그먼트는 하나의 언두 테이블스페이스에 저장됩니다. 언두 테이블스페이스의 특징은 다음과 같습니다.

➡️ 언두 세그먼트에만 사용됩니다.
➡️ Recovery 시 특별한 고려 사항이 있습니다.
➡️ 단일 instance와만 연관됩니다.
➡️ 여러 언두 테이블스페이스 중 하나만 주어진 시간에 주어진 instance에 대해 현재 쓰기가 가능해야 합니다.

SCOTT @ orcl > set autot on
SCOTT @ orcl > select * from dept;


✅ consistent gets -> cr buffer

실습1. 내 db의 undo_tablespace가 무엇인지 확인합니다.
❗ RAC에서는 여러개가 나오는데, 싱글 인스턴스는 1개가 나온다.

SQL> show parameter undo_tablespace

실습2. 지금 undo tablespace에 활성화된 undo segment를 확인하세요

SQL> select * 
       from v$rollname;
      
       USN NAME
---------- ------------------------------
         0 SYSTEM
         1 _SYSSMU1_592353410$
         2 _SYSSMU2_967517682$
         3 _SYSSMU3_1204390606$
         4 _SYSSMU4_1003442803$
         5 _SYSSMU5_538557934$
         6 _SYSSMU6_2897970769$
         7 _SYSSMU7_3517345427$
         8 _SYSSMU8_3901294357$
         9 _SYSSMU9_1735643689$
        10 _SYSSMU10_4131489474$              
SQL> show parameter undo 

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO

✅ 활성화 되는 undo segment를 오라클이 알아서 늘리고 줄이고 한다는 것이다. update나 delete작업이 많으면 이 갯수를 늘리고, 적다면 이 갯수를 줄인다.

실습3. 현재 undo segment들의 상태와 이 세그먼트들이 어느 테이블스페이스에 있는지 확인핫오

select segment_name, status, tablespace_name
  from dba_rollback_segs;

실습4. UNDOTBS3 이라는 undo tavlespace를 사이즈 50m로 생성해보기

create undo tablespace undotbs3
  datafile '/home/oracle/undotbs3.dbf' size 50m;
Tablespace created.

실습5. undotbs3이 현재 database의 undo tablespace가 되게 하시오 (지금은 UNDOTBS1)

show parameter undo 

SQL> @para.sql
Enter value for name: undo

NAME                           ISSYS_MOD
------------------------------ ---------
undo_tablespace                IMMEDIATE

* immediate면 scope=both, scope=memory 
* false면 scope=spfile만 된다. 
alter system set undo_tablespace=undotbs3;

SYS @ orcl > show parameter undo
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     900
undo_tablespace                      string      UNDOTBS3

실습6. undotbs3에 존재하는 undosegment들을 확인하기

SYS> select segment_name, status, tablespace_name
  from dba_rollback_segs;

💡 dba, db 엔지니어, data 엔지니어를 위한 팁

지금 대량의 insert 작업이 db 서버에서 이루어질 텐데 대량의 insert 작업을 하기 전에 꼭 확인해야 하는 것이 두가지가 있다.
1. undo tablespace 공간이 넉넉한지
2. temp tablespace 공간이 넉넉한지

✅ 기존의 undo를 막 늘리지 말고, 임시로 큰 undo tablespace 만들어서 작업하고, 끝나면 drop 하기!

문제 undotbs3 tablespace를 드롭하기 !

SYS @ orcl > drop tablespace undotbs3;
drop tablespace undotbs3
*
ERROR at line 1:
ORA-30013: undo tablespace 'UNDOTBS3' is currently in use

alter system set undo_tablespace=undotbs1;
drop tablespace undotbs3 including contents and datafiles;
Tablespace dropped.

언두 데이터와 리두 데이터 비교

💡 언두는 취소를 위한 data, 리두는 복구를 위한 data

instance recovery(정전 발생)
: 서버가 셧다운 되었다 하더라도 DB startup 시 commit;한 데이터는 모두 복구 가능. commit;안한것은 모두 rollback;
commit한 데이터를 복구해주는것이 롤포워드

실습1. undo 데이터가 저장되는 undo datafile이 무엇인지 확인하세요

select tablespace_name, file_name
  from dba_data_files
  where tablespace_name like 'UNDO%';
  
TABLESPACE_NAME
------------------------------
FILE_NAME
--------------------------------------------------------------------------------
UNDOTBS1
+DATA/orcl/datafile/undotbs1.258.796857625
  

실습2. 언두 테이블스페이스 사용량을 확인하기

$ sh dba.sh -- 1번
TABLESPACE_NAME                 USEDSPACE
------------------------------ ----------
SYSAUX                         91.4583333
UNDOTBS1                          16.1875 --이거
USERS                                   5
TS300                                   1
SYSTEM                         42.6679688
EXAMPLE                            39.875
TS206                                  10
TS500                                   2
TS5000                                 10

실습3. 리두로그의 파일 위치와 사용량 조회하기

col member for a45
SYS> select group#, status, sequence#
       from v$log;
SYS> save log.sql  
SYS> select group#, member
       from v$logfile
       order by group# asc;
SYS> save logfile.sql   
-- @log.sql / @logfile.sql 로 조회!

undo 관리 (p.10-8)

✅ undo와 관련해서 발생하는 오라클의 아주 유명한 에러
ORA-01555 snap shot too old
이 에러는 왜 발생할까?

       scott A session                  scott B session
SQL>  select * from emp;               SQL> update emp set sal = 0 where ename='MILLER'; 
                                       SQL> commit;
             ↓
장기 실행 쿼리라서 아직 miller의 데이터를 안본상태    
곧 select가 완료되면 밀러의 월급을 볼텐데 
보게돠면 변경전의 1300을 봐야할까 변경후인 0를 봐야할까?
A세션이 B보다 먼저 select를 해야한다. 

💡 A session이 select 하기 직전의 commit된 데이터는 1300이므로 1300이 봐야한다. 근데 1300이 다른 DML문으로 인해서 cr buffer가 덮어씌어졌다면 -> ORA-01555 snap shot too old 발생. 언두파일이 15분 지나서 다른 데이터로 덮어씌어질 수 있는데 그걸 못하게 해야한다.

undo_management가 auto로 되어져있고 undo tavlespace의 공간이 넉넉하고, undo_retention의 초가 넉넉하다면 snap shot too old에러를 현저히 줄일 수 있다.

우리 회사에서 이 에러가 자주 발생하는 쿼리들 중 제일 길게 돌아가는 쿼리문의 시간이 2시간이다 라고 하면, undo_retention을 2시간 이상으로 맞춰주면 snap shot too old에러 발생을 줄일 수 있다. 그만큼 undo tavlespace의 공간도 넉넉해야 이 시간을 보장해줄 수 있다.

실습1. 우리 회사에서 snap shot too old 에러가 자주 발생하는 쿼리문이 있다. 이 쿼리문의 수행 시간은 2시간이다. snap shot too old 에러가 발생하지 않도록 undo_retention을 조정하세요!
1. 파라미터 변경시 확인할 것. IMMEDIATE 니까 scope=both

SYS @ orcl > @para
Enter value for name: undo_retention
old   3:        where  name  like '%&name%'
new   3:        where  name  like '%undo_retention%'

NAME                           ISSYS_MOD
------------------------------ ---------
undo_retention                 IMMEDIATE

2. 바꾸기

alter system set undo_retention=7200;
SYS @ orcl > show parameter undo

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
undo_management                      string      AUTO
undo_retention                       integer     7200 --변경완료
undo_tablespace                      string      UNDOTBS1

💡 flashback table도 2시간 까지 복구할 수 있고, 장기 실행 쿼리도 2시간 안에 끝나면 ORA-01555 snap shot too old 에러를 안 볼 확률이 높다.

undo retention 구성

UNDO_RETENTION은 이미 커밋된 언두 정보를 보존해야 하는 기간을 초 단위로 지정합니다. 이 파라미터는 다음과 같은 경우에만 설정합니다.

  • 언두 테이블스페이스에서 AUTOEXTEND 옵션이 활성화된 경우
SQL> create undo tablespace undotbs3
       datafile '/home/oracle/undotbs3/dbf' size 50m
       autoextend on maxsize 100m;

✅ 갑자기 몰리는것에 대비해 100m까지 늘어나게 해주겠다 라는 뜻의 autoextend on maxsize 100m; 를 써서 테이블스페이스를 생성하는것이 좋다. 공간을 무한히 크게 쓸 수는 없으니 일단 50m로 작게 잡되 100m까지 늘어날 수 있다! 라고 여유있게 만들어주기

  • LOB에 대해 언두 retention을 설정할 경우
  • retention을 보장하려는 경우

undo retention 보장

💡 만약 undo_retention을 2시간으로 설정했다고 하더라도 무조건 2시간을 보장하는것은 아니고, 다음과 같이 2시간을 보장하겠다고 명령을 해주어야 보장된다.

SQL> ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;

undo retention 를 보장하려고 크게 만들면 다른 디엠엘 작업을 못할수가 있다.
언두 테이블 스페이스가 작으면 DML문장 막 넣으려고 계속 그래서 작업을 못할수가 있다. 실패되면 undo tbs를 크게 만들어주자.

실습1. 언두 리텐션을 2시간을 확실히 보장할 수 있도록 아래의 명령어를 실행하세요.(OCM문제)

SYS @ orcl > ALTER TABLESPACE undotbs1 RETENTION GUARANTEE;

Tablespace altered.

✔️ 잘 보장되었는지 확인하는 쿼리

select tablespace_name, retention
 from dba_tablespaces;

TABLESPACE_NAME                RETENTION
------------------------------ -----------
SYSTEM                         NOT APPLY
SYSAUX                         NOT APPLY
UNDOTBS1                       GUARANTEE -- 잘 보장되어 있다!
TEMP                           NOT APPLY
USERS                          NOT APPLY
EXAMPLE                        NOT APPLY
TS300                          NOT APPLY
TS500                          NOT APPLY
TS5000                         NOT APPLY
TS206                          NOT APPLY 

언두 테이블 스페이스를 고정 크기로 변경하기

💡 우리가 앞에서 2시간으로 설정했으면, 그 시간에 맞게 테이블 스페이스가 커야한다. 그렇지 않으면 DML문이 실패할 가능성이 높다.

✅ 이렇게 보장되면 혹시 cr buffer에 다른 데이터가 덮어씌워 지려고 하면 이게 안덮어씌워지고 다른 공간에 데이터가 저장이된다. 그래서 테이블 스페이스 사이즈가 커야한다.
근데 이거 그러면 2시간이면 사이즈를 얼마나 늘려야 하는지? -> 언두 어드바이저를 통해 알 수 있다.
em> 서버 > 자동실행 취소관리 > 일반사항 > 그래프표시

실습2. 우리 회사에 적절한 undo tablespace 사이즈가 어떻게 되는지 undo advisor를 통해 확인해보자.

161,949분 일때 10,000mb의 사이즈를 가지면 된다고 권장하고 있다.

정리하면
1. undo_management는 반드시 auto로 쓰세요
2. undo_retention우리회사에서 가장 긴 쿼리문의 시간으로 지정
3. undo tablespace의 크기는 undo advisor의 조언으로 지정하면 된다.

undo data의 상태를 가끔 집중으로 모니터링 해야할 때가 있다.

  • 대량의 데이터를 이행할 때 (특별한날 데이터 이행도 있는데 평상시 데이터 이행도 있다.)
undo data를 가장 많이 생성하는 DML문이 무엇일까?
-> delete > update > insert
* insert시 발생하는 undo data는 insert 하는 로우의 주소를 undo segment에 저장한다. 

시스템 작업 보기

데이터 이행을 하기 전에 반드시 undo tablespace의 공간이 넉넉한지 확인하고 데이터 이행중에는 undo data상태를 실시간 모니터링을 해야한다.
점심시간문제 책에 나오는 undo data 모니터링하는 em의 페이지를 찾아보기

em> 서버 > 자동실행 취소관리 > 시스템작업 > 그래프표시

📖 감사

• DBA 권한을 가진 유저는 신뢰되어야 합니다.
– 신뢰의 남용
– Audit Trail로 신뢰된 지위 보호
• DBA 책임을 공유해야 합니다.
• 계정을 공유해서는 안됩니다.
• DBA 및 시스템 관리자는 서로 다른 사람이어야 합니다.
• 운영자와 DBA의 책임을 구분합니다.

필수 감사

누가 db에 로그온 하고 로그오프 했는지 감사

alter session set nls_date_format='RRRR/MM/DD HH24:MI:SS';

select username, timestamp, action_name, terminal
  from dba_audit_trail
  where user='SCOTT' and timestamp LIKE'2023%'
  order by timestamp;

db 감사

특정 테이블을 drop 하고 select 했을 때 감사

감사 기능을 쓰게되면 서버 프로세스가 일기를 쓰기 시작한다.
실습1. 감사 기능을 활성화 시킵니다.

SYS> show parameter audit_trail

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_trail                          string      DB -- null아니고 DB! DB감사 활성화 되어있다. 

감사 옵션 지정

1. audit table; -> 테이블을 drop하면 감사됨
2. audit select on scott.emp; -> scott의 emp 테이블을 select 할 때 마다 감사
3. audit create any trigger; -> 트리거를 생성하면 감사
💡 트리거는 계속 같은 테이블에 대해 동기화를 시켜준다. ex) emp와 emp_backup을 계속 동기화 (똑같이만들어줌) 시켜준다. 너무 좋은 기능이지만 (대충만들어서...) 문제가 생길시 크닐남
4. audit seleect any table by hr by session; -> hr 계정에 의해 특정 테이블이 select 되면 감사하겠다. (기록하겠다.)

🚨 감사 옵션을 주고 감사 기능을 활성화 할 때 주의사항 ! 🚨

감사 로드가 쌓이는 공간이 system tablespace인데 system tablespace가 금방 full 나기 때문에 full이 나지 않도록 여유공간을 확보하고 해줘야한다.

실습2. 테이블 감사를 실습합니다.

1. SYS> audit table;
2. SCOTT> drop table emp; 
2. SCOTT> drop table dept; 
3. sqldeveloper >
select username, userhost, timestamp, action_name, terminal
  from dba_audit_trail
  where user='SCOTT' and timestamp LIKE'2023%' and action_name like '%DROP%'; 


SCOTT @ orcl > flashback table dept to before drop;
Flashback complete.  



다나온다!

실습3. 특정 테이블을 검색했을 때 감사되게 하시오 (scott의 emp테이블을 검색했을 때)

SYS> audit select on scott.emp; 

sqldeveloper >
select *
  from dba_audit_trail
  where username='SCOTT' and timestamp LIKE'2023%' and action_name like '%SESSION REC%'; 

의심스러운 작업을 어떤 SQL을 수행했는지 알아내려면 상세감사를 사용해야 한다!

상세감사 Fine-Grained Auditing(p.11-16)

FGA 정책

audit_condition=> 'department_id=10', <- 특히나 이것을 조회하면 감사
audit_column => 'SALARY,COMMISSION_PCT' <- 특히나 이 컬럼을 조회하면 감사
statement_types => 'SELECT,UPDATE') <- select, update가 되면 감사

실습1. scott의 emp테이블에서 월급이 3000 이상인 사원들의 data를 조회하는 SQL을 누군가 수행하면 감사되게 해라 !

SYS>
begin
    dbms_fga.add_policy(object_schema=>'SCOTT',
                       object_name=>'EMP',
                       policy_name=>'POL7',
                       audit_condition=>'SAL >= 3000',
                       enable=>TRUE,
                       statement_types=>'INSERT,SELECT,UPDATE',
  audit_trail=>DBMS_FGA.DB_EXTENDED);
END;
/

SCOTT>  select  ename, sal
             from  emp
             where sal = 5000;

SCOTT>  update emp
           set sal = 6000
        where ename='SCOTT';

SCOTT>  commit;

SYS> 
col timeinfo  for  a15
col  object_name  for  a10
col sql_text for  a40
col sql_bind  for  a20
 
select to_char(TIMESTAMP,'yyyy/mm/dd HH24:MI:SS')  timeinfo , userhost, os_user,
OBJECT_NAME,SCN,
  SQL_TEXT,SQL_BIND
  from dba_fga_audit_trail; 

문제 salgrade table에 losal 컬럼을 4000보다 큰 값으로 insert하거나 update하면 감사가 되게 하시오!

SYS>
begin
    dbms_fga.add_policy(object_schema=>'SCOTT',
                       object_name=>'SALGRADE',
                       policy_name=>'POL8',
                       audit_condition=>'LOSAL >= 4000',
                       enable=>TRUE,
                       statement_types=>'INSERT,UPDATE',
  audit_trail=>DBMS_FGA.DB_EXTENDED);
END;
/

SCOTT>  update salgrade 
          set losal=5000
          where losal=700;

SCOTT>  insert into salgrade values(6,4001,8000);

✅ audit_trail이 db로 되어있으면 모든 감사로그는 system tablespace에 저장된다. 그래서 system tablespace가 full나지 않도록 db말고 os라고 지정하면 감사로그가 os저장이 된다.
audit_file_dest 파라미터에 지정된 위치에 감사로그가 저장이 된다.

문제1. audit_trail를 os로 변경해보기

@para.sql
NAME                           ISSYS_MOD
------------------------------ ---------
audit_trail                    FALSE

SYS> alter system set audit_trail='os' scope=spfile;

SYS> show parameter audit_trail;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_trail                          string      OS

문제2. 감사 로그가 /home/oracle밑에 생성될 수 있도록 audit_file_dest를 /home/oracle로 지정하시오

SYS> show parameter audit_file_dest;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest                      string      /u01/app/oracle/admin/orcl/adu
                                                 mp
SYS @ orcl > @para.sql
Enter value for name: audit_file_dest
old   3:        where  name  like '%&name%'
new   3:        where  name  like '%audit_file_dest%'

NAME                           ISSYS_MOD
------------------------------ ---------
audit_file_dest                DEFERRED -- 얘는 뭐냐면 지금 세션에 적용되는것이 아니라 그다음 세션에 변경되는 것이다. =spfile

SYS> alter system set audit_file_dest='/home/oracle' scope=spfile;
shutdown immediate
startup


ls -rlt 해보면 벌써 두개가 저장되어있는것이 보인다.
DEFERRED

감사 설정시 고려사항

상세 감사 (FGA)지침

➡️ 모든 행을 감사(Audit)하려면 null 감사(Audit) 조건을 사용합니다.
➡️ 모든 열을 감사(Audit)하려면 null 감사(Audit) 열을 사용합니다.
➡️ 정책 이름은 고유해야 합니다.
➡️ 정책 생성 시에는 감사(Audit)되는 테이블 또는 뷰가 존재해야 합니다.
➡️ 감사(Audit) 조건 구문이 유효하지 않은 경우 감사(Audit)되는 객체에 액세스하면 ORA-28112 오류가 발생합니다.
➡️ 테이블에 감사(Audit)된 열이 없으면 어떠한 행도 감사(Audit) 되지 않습니다.
➡️ 이벤트 처리기가 없는 경우 오류가 반환되지 않고 감사(Audit) 레코드가 생성됩니다.

위 글은 아래 대한 설명
SYS>
begin
    dbms_fga.add_policy(object_schema=>'SCOTT',
                       object_name=>'SALGRADE',
                       policy_name=>'POL8',
                       audit_condition=>'LOSAL >= 4000',
                       enable=>TRUE,
                       statement_types=>'INSERT,UPDATE',
  audit_trail=>DBMS_FGA.DB_EXTENDED);
END;
/

실습1. 데이터베이스에 생성된 상세 감사가 어떤것이 있는지 조회하기

select * from dictionary where table_name like'%FGA%';  

select distinct policy_name from dba_fga_audit_trail;

실습2. db에 만든 상세감사 정책(위에꺼)을 모두 삭제하기(drop)

SYS>
begin
    dbms_fga.drop_policy(object_schema=>'SCOTT',
                       object_name=>'SALGRADE',
                       policy_name=>'POL8'
                       );
END;
/

begin
    dbms_fga.drop_policy(object_schema=>'SCOTT',
                       object_name=>'EMP',
                       policy_name=>'POL7'
                       );
END;
/

developr> select distinct policy_name from dba_fga_audit_trail;

실습3. 방금 설정한 AUDIT 기능을 끄기

SYS> noaudit table;
SYS> noaudit select any table;

SYSDBA 감사


✅ 만약 sysdba권한을 가진 유저를 감사하려면
1. audit_trail = os
2. audit_file_dest = os의 위치
3. audit_sys_operations 를 true로 설정하면

show parameter audit_sys;

------------------------------------ ----------- ------------------------------
audit_sys_operations                 boolean     FALSE
audit_syslog_level                   string

실습1. audit_sys_operations를 True로 켜기

SYS> alter system set audit_sys_operations=true scope=spfile;
SYS> shutdown immediate
SYS> startup

SYS @ orcl > show parameter audit_sys;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_sys_operations                 boolean     TRUE
audit_syslog_level                   string

-- 이제 syssdba로 접속했을 때 언제 접속했는지 감사를 할 수 있다. 

-- 누가 디비에 접속했는지 확인(이거수행안했음)
alter session set nls_date_format='RRRR/MM/DD HH24:MI:SS';

select username, timestamp, action_name, terminal
  from dba_audit_trail
  where user='SYS' and timestamp LIKE'2023%'
  order by timestamp;
  
----
-rw-r----- 1 oracle dba           1193  9월 22 16:15 orcl_ora_27931_1.aud
[orcl:~]$ vi orcl_ora_27931_1.aud
  

Audit trail 유지 관리

oracle audit valut 기능

SQL> select ename, sal
  from emp;

✅ 원래는 위와같은 sql날리면 14명이 모두 조회되어야 하는데 vault 기능을 이용하면 특정 행을 감출 수 있다. 감추고 13명만 조회된다던지, 월급이 3000이상인 사원들은 조회 안되도록 설정도 가능하다. 우리가 위에서 배운것들은 모두 사전대책이지만 지금 이것은 사후대책이다. 그러니까 다른 사람들은 3000 이상인 사원들은 애초에 있는지 없는지도 볼 수가 없다.
실제로는 db에 저장되어있지만, 조회는 안된다 !

앞에서 한거 다 원래대로 되돌리는!! 문제
문제 audit_trail은 db로 변경하고 audit_sys_operation은 false로 변경하기

SYS> alter system set audit_trail='db' scope=spfile;
SYS> shutdown immediate
SYS> startup
SYS> show parameter audit_trail;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_trail                          string      DB


SYS> alter system set audit_sys_operations=false scope=spfile;
SYS> shutdown immediate
SYS> startup

SYS> show parameter audit_sys;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_sys_operations                 boolean     FALSE

문제 audit_file_dest의 위치도 원래 위치로 지정해주기(/u01/app/oracle/admin/orcl/adump)

SYS> alter system set audit_file_dest='/u01/app/oracle/admin/orcl/adump' scope=spfile;
SYS> shutdown immediate
SYS> startup
SYS> show parameter audit_file_dest;
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
audit_file_dest                      string      /u01/app/oracle/admin/orcl/adu
                                                 mp

오늘의 마지막 문제 ORA-01555 snap shot too old 에러를 일으켜 보세요!

session 1

✔️ 10m짜리 언두 테이블 스페이스를 생성한다.

  create undo tablespace small_undo
      datafile size 10m autoextend off;

✔️ 10m 언두 테이블 스페이스를 현재 사용중인 undo tavlespace로 변경합니다.

      alter system set undo_tablespace = small_undo;

✔️ 테이블을 생성하고 데이터를 10000건을 입력한다.

      create table t1(c1 int, c2 char(300));
      
      insert /*+ append */ into t1
      select level, 'dummy'
      from dual
      connect by level <= 10000
      ;
      
      commit;

✔️ index생성

      create index t1_n1 on t1(c1);

✔️ 사용자 정의 함수를 생성합니다.

      create or replace function fsleep(v1 int, vsleep int)
      return number
      is
      begin
      dbms_lock.sleep(vsleep);
      
      return 1;
      end;
      /

✔️ buffer cache size를 1m로 변경

      alter system set db_cache_size = 1m;

✔️ 위와 같이 환경구성을 하고 아래의 쿼리를 수행한다.

      select /*+ index(t1) */ 
      c1, substr(c2,1,10)
      from t1
      where fsleep(c1, 0.01) = 1 
      and c1 > 0
      ;

위의 쿼리가 수행되는 동안 다른 터미널 창(session2)에서 아래의 작업을 수행한다. 그러면 위의 쿼리에서 snap shot too old 에러를 발견하게됨

session2 에서 수행

✔️ 현재 활성화된 언두 세그먼트가 어떤것이 있는지 확인하기

      -- get rollback segment name

      col rollback_seg new_value v_rollback_seg
      
      select '_SYSSMU'||max(segment_id)||'$' as rollback_seg
      from dba_rollback_segs
      where segment_name <> 'SYSTEM'
      ;

✔️ 업데이트를 계속 반복!

      -- do very frequent commit on t1

      begin
      for idx in 1 .. 1000 loop
      for idx2 in 1 .. 10000 loop
      set transaction use rollback segment "&v_rollback_seg";
      update t1 set c2 = 'dummy'||idx
      where c1 = idx2;
      commit;
      end loop;
      end loop;
      end;
      /

##################### insert 문으로 테스트 ##################

-- get rollback segment name

  col rollback_seg new_value v_rollback_seg
  
  select '_SYSSMU'||max(segment_id)||'$' as rollback_seg
  from dba_rollback_segs
  where segment_name <> 'SYSTEM'
  ;
 

-- do very frequent commit on t1

  begin
  for idx in 1 .. 1000 loop
  for idx2 in 1 .. 10000 loop
  set transaction use rollback segment "&v_rollback_seg";
  insert into  t1 values( idx2, 'dummy'||idx2); 
  commit;
  end loop;
  end loop;
  end;
  /
profile
Slow and steady wins the race.

0개의 댓글