본문 바로가기

카테고리 없음

ORACLE 11g SEQUENCE v1.0

ORACLE 11g SEQUENCE v1.0

 

Date

Ver

Etc.

13.04.17

1.0

 

 

 

 

 

 

 

 

 

1.    SEQUENCE

시퀀스는 순서대로 증가하는 혹은 감소하는 숫자이다.

보통 유니크한 값으로 사용하며 특수한 경우 (CYCLE 옵션) 를 제외하고 이 값이 중복 될 일은 없다.

 

2.    SEQUENCE OPTIONS

11g 기준으로 ‘create sequence’ 에 다음과 같은 옵션을 사용할 수 있다.

 

MINVALUE | NOMINVALUE ( 1, default)

CYCLE | NOCYCLE (default)

CACHE (20, default) | NOCACHE

ORDER | NOORDER (default)

 

[NO]MINVALUE 값은 값의 최저하한을 두는 옵션인데 실상 START WITH 를 사용하는 것과 차이가 느껴지지 않는다.

차이가 발생하는 부분은 CYCLE 을 사용하여 값이 상한을 찍고 최저값으로 돌아가는 상황이다.

 

CYCLE MAXVALUE 와 함께 사용하는 옵션으로 시퀀스를 최대값까지 다 사용하면 최저값으로 돌아간다.

이 값은 NOMINVALUE 1 이다. MAXVALUE 5 CYCLE 옵션을 사용하는 시퀀스라면 … 3,4,5,1 … 이 된다.

 

ORDER 는 시퀀스를 요청한 순서가 빠르면 빠른 시퀀스를 얻는걸 보장한다는 것이다. ORDER 와 연관된 이슈는 RAC 환경의

CACHED SEQUENCE 에서 기인한다.

 

3.    TEST

<MINVALUE>

 

MINVALUE <= START WITH < MAXVALUE 를 만족해야 한다.

 

위에 대한 확인은 다음과 같이 할 수 있다.

 

SYS|[TMALL1] OMDBTEST1  >create sequence sys.test start with 10 minvalue 15 increment by 1;

create sequence sys.test start with 10 minvalue 15 increment by 1

*

ERROR at line 1:

ORA-04006: START WITH cannot be less than MINVALUE

 

SYS|[TMALL1] OMDBTEST1  >create sequence sys.test start with 1 minvalue 10 increment by 1 maxvalue 5;

create sequence sys.test start with 1 minvalue 10 increment by 1 maxvalue 5

*

ERROR at line 1:

ORA-04004: MINVALUE must be less than MAXVALUE

 

앞서 이야기 했듯이 MINVALUE CYCLE 을 사용하는 케이스가 아니면 사용할 일이 없다.

Default NOMINVALUE 1 값을 가지기 때문에 MINVALUE 지정을 안 한 상태에서 CYCLE 을 사용하는

시퀀스가 MAXVALUE 까지 사용하면 그 다음 값이 1로 돌아간다.

 

<CYCLE>

 

NOCYCLE 의 경우 값을 MAXVALUE 까지 사용하면 끝이다.

만약 호출하는 경우 다음과 같이 에러가 발생한다.

 

SYS|[TMALL1] OMDBTEST1  >/

select test.nextval from dual

*

ERROR at line 1:

ORA-08004: sequence TEST.NEXTVAL exceeds MAXVALUE and cannot be instantiated

 

반면 CYCLE 을 이용하는 경우 MAXVALUE 이후 MINVALUE (지정한 경우) 1 (MINVALUE 지정하지 않은 경우) 값으로

돌아간다.

 

<RAC:CACHE>

 

SEQUENCE Default CACHE 옵션을 사용하며 그 값은 20 이다.

CACHE 는 사용할 값을 메모리에 가져다 놓는 걸 말하는데 이로인해 RAC 환경에서는 다음과 같은 현상이 일어난다.

 

l  CACHE 5인 시퀀스 생성 ( 1부터 시작)

l  NODE1 에서 NEXTVAL

l  NODE2 에서 NEXTVAL

 

위 결과는 NODE1 -> 1, NODE2 -> 6 이다.

NODE1 에서 최초 호출한 순간 CACHE SIZE 5 만큼 가져가고 (1~5),

NODE2 에서 다시 호출한 순간 마찬가지로 CACHE SIZE 5만큼 가져간다 (6~10)

 

위 상황에서 NODE2 가 시퀀스 캐시를 다 소모하고 11을 호출하면 (11~15) 값을 가져가고,

NODE1 에서 (1~5) 를 다 소모하고 다음 호출을 하면 16 을 반환한다.

 

위와 같이 각 노드가 자신이 사용할 시퀀스를 캐시사이즈 만큼 배타적으로 가져가기 때문에

다음과 같은 결과를 얻을 수 있다.

 

l  Insert 이후 바로 commit

l  1 > 2 > 1 노드 에 대해 Insert + commit

l  ID1 값은 시퀀스.NEXTVAL

l  ID2 값은 시분초 값임

 

ID1 ID2

---------- ------------------------------

         1 152145

         6 152310

         2 152506

 

1 > 2 > 1 INSERT 를 했기 때문에 사용자는 1,2,3 으로 정렬된 시퀀스를 가져가기 원할 수 있다.

이러한 요구가 있기 때문에 NOCACHE ORDER 를 사용하게 된다.

 

<RAC:NOCACHE>

 

NOCACHE 는 문자 그대로 메모리에 시퀀스를 캐싱하지 않겠다는 이야기다.

미래에 사용할 시퀀스를 미리 캐시하지 않기에 사용 요청을 받을때마다 하나씩 반환한다.

 

그래서 앞서 살펴 본 먼저 들어온 요청이 더 늦게 들어온 요청의 시퀀스보다 뒤쳐지는 현상을 회피할 수 있다.

그러나 위와 같이 순서를 보장하겠다고 호출이 빈번한 시퀀스를 NOCACHE 로 사용하게 되면 row cache lock 경합이 발생한다.

 

위 경합이 바람직하지 않다는 것은 SEQUENCE 생성 시 default CACHE 20 인 것을 생각해봐도 나온다.

 

<RAC:ORDER + CACHE>

 

ORDER 는 앞서 살펴 본 CACHE 에서의 문제, 먼저 호출된 시퀀스가 앞서는 번호를 가져가길 원하는 경우 (즉 정렬된 값) 사용한다.

이 부분까지만 보면 NOCACHE 와 동일하지만 시퀀스를 미리 캐싱해 둔다는게 특징이다.

 

RAC:CACHE 동일 환경으로 1 > 2 > 1 노드에 대해 INSERT 하는 경우 다음과 같은 결과를 얻는다.

 

ID1 ID2

---------- ------------------------------

         1 153744

         2 153923

         3 154046

 

ID1 = 2 인 값은 NODE2 에서 수행된 값이며 본디 CACHE 만 사용한 경우 값이 6이 들어와야 한다.

하지만 ORDER 옵션을 써서 사용자가 원하는 정렬된 값을 얻었다. (NOCACHE 와 동일한 효과)

 

다만 NOCACHE 경우보다는 낫다고는 하나 타 노드에서 캐싱되어 있는 시퀀스 값을 메모리를 뒤져 가져가야 하는 부하가 있기에

빈번한 호출에는 사용해서는 안 된다.

 

<RAC:ALTER CACHE SIZE>

 

Sequence 를 사용하는 와중에 CACHE SIZE 를 변경하는 경우를 가정한다.

 

(cache 2) > 1 > 2 > (cache 4) > 1 > 2

 

CACHE2 로 생성하여 node1 에서 NEXTVAL, 마찬가지로 NODE2

이후 CACHE 4로 변경해서 NODE1, NODE2 에서 순차적으로 NEXTVAL 을 수행해 보았다.

 

위와 같이 cache 2 상태에서 1,2 노드에서 nextval 을 호출하면 1번노드에서는 1, 2번 노드에서는 3을 보게 된다.

이 상태에서 cache size 4로 변경하고 다시 1, 2를 호출하면 나오는 값은 5, 9 이 된다.

 

이는 기존의 cached 값이 버려졌기 때문이다.

기존에 1번 노드에서 캐싱한 값이 (1,2), 2번 노드에서 캐싱한 값이 (3,4) 인 상태에서 alter 후 시퀀스 호출했을 때 5가 나왔다는 건

2,4 값이 버려졌다는 것을 의미한다.

 

캐시사이즈가 4로 변경되었기에 1번 노드는 (5,6,7,8) 을 가지게 되고 2번 노드는 (9,10,11,12) 를 가지게 된다.

 

4.    REFERENCES

A.     CREATE SEQUENCE | B28286-06