프린트 하기

내맘대로긍정이 알려주는

Oracle 23ai 신기능
무료 세미나 발표자료

다운로드 trending_flat

OS환경 : Oracle Linux 6.8 (64bit)

 

DB 환경 : Oracle Database 11.2.0.4

 

방법 : scn을 빠르게 증가시키는 방법(scn 헤드룸 테스트)

scn headroom bump up 이슈를 재현해보기 위해 scn을 빠르게 증가시키는 테스트

SCN의 최댓값은 매우 큰값임

호환성이 12.2로 설정된 12.2.0.1의 경우 최댓값은 2^63이고 버전이 12.2.0.1 미만인 경우 2^48(약 281조)임
일반적인 경우에는 scn을 최댓값까지 사용하기 어렵지만 scn headroom bump up 이슈가 발생한다면 scn이 빠르게 증가함

 

 

테스트 1. v$database 의 current_scn 컬럼 반복 조회

imsi.sql 이라는 파일을 만들고 아래 내용을 반복해서 넣음

select current_scn from v$database;

위 쿼리 조회시 scn이 1씩 증가함

imsi.sql을 복사해 imsi2.sql 이라는 파일을 만들고 

imsi.sql >> imsi2.sql 로 반복 실행 후

imsi2.sql >> imsi.sql 작업을 반복 실행

하게되면 imsi.sql 파일 안에 위 쿼리가 꽤 많이 들어가게됨

 

 

loop.sh 쉘파일 생성

1
2
3
4
5
6
$ vi loop.sh
for ((i=1; i<=100; i++))
do
nohup sqlplus / as sysdba @imsi.sql &
done
wait

 

 

실행

1
$ sh loop.sh

100개의 세션에서 @imsi.sql 을 실행함

 

 

테스트 1 결과 : 여러개를 띄워도 1초에 3000~4000 정도만 증가함

이 방법으론 280조까지 올리기는 어려움

 

 

테스트 2. sga에 저장된 scn 정보를 덤프하여 해당 값 변경

*테스트2를 하기전에 db를 cold 백업해놓고 작업하는것을 권장함

 

 

현재 프로세스로 디버그

1
2
SQL> oradebug setmypid
Statement processed.

 

 

현재 scn 값 조회

1
2
3
4
5
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
       A4A02E    10788910

현재 scn 값은 10,788,910(천만칠십~)이고 16진수로 바꿨을때의 값은 A4A02E임

 

 

10,788,910을 20,788,910 로 변경 할 예정

ko.calcuworld.com/%EC%88%98%ED%95%99/16%EC%A7%84%EB%B2%95-%EA%B3%84%EC%82%B0%EA%B8%B0/

위 사이트에서 scn 값(20788910)을 넣어서 16진수로 변환(13d36ae)

 

 

메모리에서 scn 값 주소 확인

1
2
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00A4A02E 00000000 00000000 00000000 000003B6 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

빨간색이 scn 의 주소이고 보라색이 현재 scn 값의 16진수임

 

 

scn 값 변경(20788910 의 16진수 값인 13d36ae 입력(0x13d36ae))

1
2
3
SQL> ORADEBUG POKE 0x06001AE70 4 0x13d36ae
BEFORE: [06001AE70, 06001AE74) = 00A4A241
AFTER:    [06001AE70, 06001AE74) = 013D36AE

ORADEBUG POKE 명령 설명

ORADEBUG POKE <address> <length> <value>를 사용하면 주어진 메모리 영역을 수정할 수 있음

(메모리 길이는 스칼라 C 유형의 크기로 제한됨(구글번역기 사용))
(원문 : length of memory is limited to size of scalar C types )

 

 

현재 scn 값 조회

1
2
3
4
5
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
     13D3749    20789065

scn 값이 10788910에서 20789065으로 변경됨

실제 변경시도한 값은 20788910 이지만 내부적으로 돌아가는 쿼리때문에 조금 더 올라간듯함

 

 

메모리에서 scn 값 주소 확인

1
2
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 013D3749 00000000 00000000 00000000 00000571 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

메모리에서도 정상적으로 변경됨

+alert log에는 별다른 에러메세지가 발생하지 않음

+sqlplus 를 나갔다가 들어와도 scn이 이전값으로 돌아가지 않음

 

 

테스트 3. 테트트 2 방법으로 280조에 근접하는 값으로 변경

현재 scn 값 조회

1
2
3
4
5
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
      13D37A2    20789154

 

 

scn 최댓값은 281,474,976,710,656 (약 281조, 2^48) 이라고함

 

281,474,976,710,656보다 조금 작은 값 281,474,976,710,000 로 변경 할 예정

ko.calcuworld.com/%EC%88%98%ED%95%99/16%EC%A7%84%EB%B2%95-%EA%B3%84%EC%82%B0%EA%B8%B0/

위 사이트에서 scn 값(281474976710000)을 넣어서 16진수로 변환(fffffffffd70)

 

 

현재 프로세스로 디버그

1
2
SQL> oradebug setmypid
Statement processed.

 

 

메모리에서 scn 값 주소 확인

1
2
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 013D381C 00000000 00000000 00000000 00000634 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

빨간색이 scn 의 주소이고 보라색이 현재 scn 값의 16진수임

 

 

scn 값 변경(281474976710000 의 16진수 값인 fffffffffd70 입력(0xfffffffffd70))

1
2
3
SQL> ORADEBUG POKE 0x06001AE70 4 0xfffffffffd70
BEFORE: [06001AE70, 06001AE74) = 013D386F
AFTER:    [06001AE70, 06001AE74) = FFFFFD70

 

 

현재 scn 값 조회

1
2
3
4
5
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
     FFFFFD7A 4294966650

scn 값이 원하는 값으로 변경되지 않음

아마도 ORADEBUG POKE 명령의 length 값 때문인듯함

 

 

ORADEBUG POKE 의 length 값을 4가 아닌 8로 변경 후 실행

1
2
3
SQL> ORADEBUG POKE 0x06001AE70 8 0xfffffffffd70
BEFORE: [06001AE70, 06001AE78) = FFFFFDA4 00000000
AFTER:    [06001AE70, 06001AE78) = FFFFFD70 0000FFFF

 

 

현재 scn 값 조회

1
2
3
4
5
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [2251], [65535], [4294966641], [], [], [], [], [], [], [], [], []

쿼리 실행시 ORA-00600 [2251] 이 발생하고 alert log 에도 많은 에러메세지가 발생함

이후 db가 down 되었고 db를 다시 기동함

 

 

scn 과 메모리 주소 확인

1
2
3
4
5
6
7
8
9
10
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
    100004C6C 4294986860
 
SQL> oradebug setmypid
Statement processed.
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00004C6C 00000001 00000000 00000000 0000006A 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

16진수 scn 값의 뒤 4자리가 메모리값 주소의 첫번째 8자리에 나타나고 

16진수 scn 값의 앞 5자리가 메모리값 주소의 두번째 8자리에 나타나는듯함

 

 

ORADEBUG POKE length를 16으로 변경해봤지만 1,2,4,8 값만 입력가능하다고 나옴

1
2
SQL> ORADEBUG POKE 0x06001AE70 16 0xfffffffffd70
ORA-00082: memory size of 16 is not in valid set of [1], [2], [4], [8]

 

 

현재 scn(4294986860)의 16진수 값인 100004c6c 를 첫번쨰 자리만 2로 변경해서(200004c6c) 다시 실행

 

scn 변경

1
2
3
4
5
6
7
8
SQL> ORADEBUG POKE 0x06001AE70 4 0x200004c6c
BEFORE: [06001AE70, 06001AE74) = 00009BD5
AFTER:    [06001AE70, 06001AE74) = 00004C6C
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [ktcsna: min-act-scn > env-scn], [], [], [], [], [], [], [], [], [], [], []

기존 값인 00009BD5 보다 작은 값인 00004C6C 만 들어가서 (20000(앞자리)이 안들어감)

ORA-00600 [ktcsna: min-act-scn > env-scn] 이 발생함

 

 

이후 db가 안올라와서 cold 백업본으로 기동 후 다시 아래 단계까지 옴

1
2
3
4
5
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
     FFFFFD78 4294966648

 

 

현재 C_SCN이 FFFFFD78 인데 FFFFFFF8로 변경

1
2
3
4
5
6
7
8
SQL> ORADEBUG POKE 0x06001AE70 4 0xFFFFFFF8
BEFORE: [06001AE70, 06001AE74) = FFFFFDA5
AFTER:    [06001AE70, 06001AE74) = FFFFFFF8
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
     FFFFFFFA 4294967290

 

 

scn 조회 구문 몇회 더 실행 후 메모리 값 확인

1
2
3
4
5
6
7
8
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
    100000021 4294967329
 
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00000021 00000001 00000000 00000000 000008F5 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

C_SCN이 FFFFFFFF의 다음값인 100000000, 100000001 ~ 로 변함

메모리 값도 따라서 변함, 위에서 적은것처럼

16진수 scn 값의 뒤 4자리가 메모리값 주소의 첫번째 8자리에 나타나고 

16진수 scn 값의 앞 5자리가 메모리값 주소의 두번째 8자리에 나타남

현재 내가 실행한 ORADEBUG POKE 0x06001AE70 4 [16진수 값] 으로는 앞 8자리밖에 변경되지 않음

 

 

다시한번 length를 8로 변경하고 현재 값의 2배로 scn 값을 변경시도함(4294967329를 앞자리 8로 변경 8294967329)

8294967329의 16진수 값 1ee6b2821

1
2
3
4
5
6
7
8
SQL> ORADEBUG POKE 0x06001AE70 8 0x1ee6b2821
BEFORE: [06001AE70, 06001AE78) = 000000D6 00000001
AFTER:    [06001AE70, 06001AE78) = EE6B2821 00000001
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
    1EE6B28A3 8294967459

정상적으로 변경됨

 

 

똑같이 앞자리를 16 으로 변경 후 16진수로 변경(16294967329 -> 3cb417821)

1
2
3
4
5
6
7
8
SQL> ORADEBUG POKE 0x06001AE70 8 0x3cb417821
BEFORE: [06001AE70, 06001AE78) = EE6B28EB 00000001
AFTER:    [06001AE70, 06001AE78) = CB417821 00000003
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN             SCN
------------- ----------
    3CB417823 1.6295E+10

변경되었지만 scn이 길어서 짤려서 나옴

 

 

컬럼 길이 조절 후 다시 확인

1
2
3
4
5
6
SQL> col scn for 99999999999999999999999999
SQL> /
 
C_SCN                      SCN
------------- ---------------------------
    3CB417828              16294967336

정상적으로 변경됨

 

 

처음에 length 8 로 변경한 후 처음부터 너무 큰값을 넣어서 안되었던것 같음

(281474976710000 의 16진수 값인 fffffffffd70 입력(0xfffffffffd70))

 

 

다시 C_SCN을 기존보다 더 큰값인 FFFFFFFF8 로 변경 후 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SQL> ORADEBUG POKE 0x06001AE70 8 0xFFFFFFFF8
BEFORE: [06001AE70, 06001AE78) = CB417941 00000003
AFTER:    [06001AE70, 06001AE78) = FFFFFFF8 0000000F
SQL>  select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN                      SCN
------------- ---------------------------
    FFFFFFFFA              68719476730
.
.
SQL> /
 
C_SCN                      SCN
------------- ---------------------------
   1000000001              68719476737
 
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00000004 00000010 00000000 00000000 00000A7B 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

FFFFFFFFA에서 scn 조회 쿼리를 몇번 더 실행하면 C_SCN이 1000000001로 넘어가고

메모리 값에는 두번째가 00000001 에서 00000010 으로 변경됨

 

 

더 큰 값으로 변경 직전에 변경한 16진수 값에서 F 1개 더 추가(0xFFFFFFFFF8)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
SQL> ORADEBUG POKE 0x06001AE70 8 0xFFFFFFFFF8
BEFORE: [06001AE70, 06001AE78) = 0000005C 00000010
AFTER:    [06001AE70, 06001AE78) = FFFFFFF8 000000FF
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN                      SCN
------------- ---------------------------
   FFFFFFFFFB            1099511627771
.
.
SQL> /
 
C_SCN                      SCN
------------- ---------------------------
  10000000003            1099511627779
 
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00000007 00000100 00000000 00000000 00000AD5 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

정상적으로 변경됨

 

 

더 큰 값으로 변경 F 1개 추가(0xFFFFFFFFFF8)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00004EF1 00000100 00000000 00000000 00000053 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000
SQL> ORADEBUG POKE 0x06001AE70 8 0xFFFFFFFFFF8
BEFORE: [06001AE70, 06001AE78) = 00004F01 00000100
AFTER:    [06001AE70, 06001AE78) = FFFFFFF8 00000FFF
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN                   SCN
------------- --------------------
  FFFFFFFFFFA        17592186044410
.
.
SQL> /
 
C_SCN                   SCN
------------- --------------------
 100000000002        17592186044418
 
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 0000000A 00001000 00000000 00000000 0000006C 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

정상적으로 변경됨

현재 17조(17,592,186,044,418)가 됨

 

 

scn 99조(99999999999990 -> 16진수 5af3107a3ff6)
scn 82조(82407813955574 -> 16진수 4af3107a3ff6)
scn 50조(50592186044421 -> 16진수 2e0369471005) 로 변경 모두 실패

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
SQL> ORADEBUG POKE 0x06001AE70 8 0x5af3107a3ff6
BEFORE: [06001AE70, 06001AE78) = D083BED8 0000165D
AFTER:    [06001AE70, 06001AE78) = 107A3FF6 00005AF3
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database
                                                                       *
ERROR at line 1:
ORA-00600: internal error code, arguments: [2252], [23283], [276447224], [9545], [2305851392], [], [], [], [], [], [], []
 
SQL> ORADEBUG POKE 0x06001AE70 8 0x4af3107a3ff6
BEFORE: [06001AE70, 06001AE78) = D0845C05 0000165D
AFTER:    [06001AE70, 06001AE78) = 107A3FF6 00004AF3
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [2252], [19187], [276447224], [9545], [2321776640], [], [], [], [], [], [], []
 
SQL> ORADEBUG POKE 0x06001AE70 8 0x2e0369471005
BEFORE: [06001AE70, 06001AE78) = D084AAA9 0000165D
AFTER:    [06001AE70, 06001AE78) = 69471005 00002E03
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database
                                                                       *
ERROR at line 1:
ORA-00600: internal error code, arguments: [2252], [11779], [1766264841], [9545], [2329346048], [], [], [], [], [], [], []

 

 

scn 33조(33000000000005 -> 16진수 1e0369471005)로 변경

1
2
3
4
5
6
7
8
9
10
11
SQL> ORADEBUG POKE 0x06001AE70 8 0x1e0369471005
BEFORE: [06001AE70, 06001AE78) = D084FC40 0000165D
AFTER:    [06001AE70, 06001AE78) = 69471005 00001E03
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN                   SCN
------------- --------------------
 1E0369471007        33000000000007
 
SQL> oradebug DUMPvar SGA kcsgscn
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 6947104E 00001E03 00000000 00000000 000002C7 00000000 00000000 00000000 00000000 00000000 6001AB50 00000000

정상적으로 변경됨

 

 

테스트를 하다 SCN 헤드 룸을 조회하는 쿼리를 찾음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
SQL> 
set serveroutput on;
declare
 v_rsl number;
 v_headroom_in_scn number;
 v_headroom_in_sec number;
 v_cur_scn_compat number;
 v_max_scn_compat number;
begin
 dbms_scn.getcurrentscnparams(v_rsl, v_headroom_in_scn, v_headroom_in_sec, v_cur_scn_compat, v_max_scn_compat);
 dbms_output.put_line('reasonable scn limit (soft limit)     : ' || to_char(v_rsl,'999,999,999,999,999,999'));
 dbms_output.put_line('headroom in scn                             : ' || to_char(v_headroom_in_scn,'999,999,999,999,999,999'));
 dbms_output.put_line('headroom in seconds                     : ' || v_headroom_in_sec);
 dbms_output.put_line('headroom in days                            : ' || round(v_headroom_in_sec/3600/24));
 dbms_output.put_line('current scn compatibility scheme  : ' || v_cur_scn_compat);
 dbms_output.put_line('max scn compatibility scheme       : ' || v_max_scn_compat);
end;
/
 
reasonable scn limit (soft limit)     :       40,998,051,512,320
headroom in scn                 :         7,998,051,511,494
headroom in seconds            : 81360387
headroom in days                : 942
current scn compatibility scheme  : 3
max scn compatibility scheme       : 3

위 쿼리 결과에 따르면 합리적인(소프트) scn 최댓값은 40,998,009,143,296(40조) 임

headroom in scn : 남은 scn

headroom in seconds : 남은 scn(초로 계산)

headroom in days : 남은 scn(일로 계산)

 

 

위 값에 근접하게 scn 변경 (40998009143270 -> 16진수 254997c57fe6)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SQL> ORADEBUG POKE 0x06001AE70 8 0x254997c57fe6
BEFORE: [06001AE70, 06001AE78) = 69471377 00001E03
AFTER:    [06001AE70, 06001AE78) = 97C57FE6 00002549
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
 
C_SCN                   SCN
------------- --------------------
 254997C57FE7        40998009143271
.
.
SQL> /
 
C_SCN                   SCN
------------- --------------------
 254997C58004        40998009143300

scn 변경 후 40,998,009,143,296 를 넘어서는 40,998,009,143,300 까지 갔음에도 오류가 발생하지 않음

 

 

다시 scn 헤드룸 쿼리를 조회하니 값이 변경되어있음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
SQL> 
set serveroutput on;
declare
 v_rsl number;
 v_headroom_in_scn number;
 v_headroom_in_sec number;
 v_cur_scn_compat number;
 v_max_scn_compat number;
begin
 dbms_scn.getcurrentscnparams(v_rsl, v_headroom_in_scn, v_headroom_in_sec, v_cur_scn_compat, v_max_scn_compat);
 dbms_output.put_line('reasonable scn limit (soft limit)     : ' || to_char(v_rsl,'999,999,999,999,999,999'));
 dbms_output.put_line('headroom in scn                             : ' || to_char(v_headroom_in_scn,'999,999,999,999,999,999'));
 dbms_output.put_line('headroom in seconds                     : ' || v_headroom_in_sec);
 dbms_output.put_line('headroom in days                            : ' || round(v_headroom_in_sec/3600/24));
 dbms_output.put_line('current scn compatibility scheme  : ' || v_cur_scn_compat);
 dbms_output.put_line('max scn compatibility scheme       : ' || v_max_scn_compat);
end;
/
 
reasonable scn limit (soft limit)     :       40,998,083,461,120
headroom in scn                 :            74,317,773
headroom in seconds            : 755
headroom in days                : 0
current scn compatibility scheme  : 3
max scn compatibility scheme       : 3
 
PL/SQL procedure successfully completed.

첫번 쨰 조회 시 : 40,998,051,512,320

두번 째 조회 시 : 40,998,083,461,120

근소하게 최댓값이 증가함

계속 위 쿼리를 조회해보니 1초에 약 100,000(10만)씩 최댓값이 늘어남(정확히는 98304 씩 늘어남을 확인함)

 

 

scn 헤드룸 쿼리를 확인 후 최댓값에 초당 10만을 계산해서 조금 더 많은 값으로 변경한 뒤 확인

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
SQL> ORADEBUG POKE 0x06001AE70 8 0x25499e51cd60
BEFORE: [06001AE70, 06001AE78) = 9E15AC4D 00002549
AFTER:    [06001AE70, 06001AE78) = 9E51CD60 00002549
SQL> select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database;
select to_char(current_scn,'XXXXXXXXXXXX') c_scn, current_scn scn from v$database
*
ERROR at line 1:
ORA-00600: internal error code, arguments: [2252], [9545], [2656161122], [9545], [2656010240], [], [], [], [], [], [], []
 
SQL> 
set serveroutput on;
declare
 v_rsl number;
 v_headroom_in_scn number;
 v_headroom_in_sec number;
 v_cur_scn_compat number;
 v_max_scn_compat number;
begin
 dbms_scn.getcurrentscnparams(v_rsl, v_headroom_in_scn, v_headroom_in_sec, v_cur_scn_compat, v_max_scn_compat);
 dbms_output.put_line('reasonable scn limit (soft limit)     : ' || to_char(v_rsl,'999,999,999,999,999,999'));
 dbms_output.put_line('headroom in scn                             : ' || to_char(v_headroom_in_scn,'999,999,999,999,999,999'));
 dbms_output.put_line('headroom in seconds                     : ' || v_headroom_in_sec);
 dbms_output.put_line('headroom in days                            : ' || round(v_headroom_in_sec/3600/24));
 dbms_output.put_line('current scn compatibility scheme  : ' || v_cur_scn_compat);
 dbms_output.put_line('max scn compatibility scheme       : ' || v_max_scn_compat);
end;
/
 
reasonable scn limit (soft limit)     :       40,998,119,735,296
headroom in scn                 :               733,851
headroom in seconds            : 7
headroom in days                : 0
current scn compatibility scheme  : 3
max scn compatibility scheme       : 3

ORA-00600 [2252] 가 발생하지만 잠시 뒤 바로 다시 쿼리 조회가됨

최대 scn이 되었지만 자동으로 최댓값을 더 늘려서 정상적으로 사용이 가능해 진듯 함

 

 

결론

scn 최댓값2^48(약 281조) 이라곤 하지만 처음부터 최댓값이 281조가 아니라

db 기동 시간에 따라 scn 최댓값이 계속 늘어나는듯 함(초당 98304씩 scn 최댓값이 올라가는듯 함)

(현재 테스트 db는 만든지 오래되지 않아 최댓값이 약 40조임)

사용자가 위와 같은 방법으로 scn을 늘릴수는 있지만 scn 최댓값에 다다르면 ORA-00600 [2252]가 발생함

조금 기다리면 scn 최댓값이 증가해서 다시 사용가능 하지만 실제 운영 환경에서 db링크 등을 사용할 경우

scn이 빠르게 증가되는 경우 ORA-00600 [2252]가 계속 발생할듯함

db링크를 사용한다면 scn 헤드룸 권장 패치를 꼭 해줘야함

 

 

+참고용

위 작업 이후 DB에 PSU를 패치를 진행하였는데 진행 후 db 기동시 ORA-00600 [kcm_scn_headroom_warn_2] 이 발생하며 db가 기동되지 못함, cold 백업본으로 다시 기동후 패치 진행함 (positivemh.tistory.com/704)

1
2
3
4
5
6
7
8
9
10
SQL> startup
ORACLE instance started.
 
Total System Global Area 2137886720 bytes
Fixed Size            2254952 bytes
Variable Size         1442842520 bytes
Database Buffers      687865856 bytes
Redo Buffers            4923392 bytes
Database mounted.
ORA-00600: internal error code, arguments: [kcm_scn_headroom_warn_2], [], [], [], [], [], [], [], [], [], [], []

 

 

참조 : 1903000.1, 386830.1, 2712868.1

www.askmaclean.com/archives/how-to-increase-system-change-number-by-manual.html

positivemh.tistory.com/412

www.jir.io/2019/07/23/How%20to%20Increase%20SCN/

renenyffenegger.ch/notes/development/databases/Oracle/tools/oradebug/dumpvar/index

www.juliandyke.com/Diagnostics/Tools/ORADEBUG/ORADEBUG.php

www.axiominfo.co.kr/default/article/column.php?com_board_basic=read_form&com_board_idx=143&&com_board_search_code=&com_board_search_value1=&com_board_search_value2=&com_board_page=2&&com_board_id=2&&com_board_id=2

ko.calcuworld.com/%EC%88%98%ED%95%99/16%EC%A7%84%EB%B2%95-%EA%B3%84%EC%82%B0%EA%B8%B0/