카테고리 없음

ORACLE 11g SEQUENCE v1.0

Walking again 2013. 4. 18. 09:59

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