본문 바로가기
프로그래밍/오라클

오라클 시퀀스 동기화

by TcTT 2017. 3. 28.
반응형

오라클 시퀀스 동기화

오라클 시퀀스는 PK를 만들기 아주좋은 데이터로 요긴하게 사용되는데...

주 운영서버 <-> 백업서버 간에 데이터를 동기화하고

주 운영서버가 죽으면 백업서버에서 작업을 진행하기위해선

데이터 동기화를 주기적으로하고, 시퀀스를 사용한다면 시퀀스도 동기화 시켜줘야한다.


시퀀스동기화에대해 이것저것 조사하다가 정석, 편법 두가지를 찾았다.


기본개념 

  정석 : 기존 시퀀스를 삭제하고 시퀀스를 새로만든다. 새로만드는 시퀀스의 시작값을 동기화하는 서버와 맞춘다

  편법 : 기존 시퀀스의 다음값을 동기화하려는 서버의 시퀀스로 맞춘뒤 NEXTVAL 을 통해 동기화한다.



정석방법은 기존 시퀀스를 삭제하기때문에 약간 위험할 수 있다?? 

모로가든 도로가든 시퀀스만 맞추면되기 때문에 편법을 사용해 시퀀스를 동기화한다.

난 PL/SQL 에서 프로시저 형태로 시퀀스 동기화를 진행했다.




CREATE OR REPLACE PROCEDURE P_SKIP_SEQNO IS   --프로시저 생성


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

-- 변수 선언

 V_TEST_SEQ VARCHAR2(30);   --동기화 맞출 시퀀스 이름을 저장하기위한 변수


 I_TEST_SEQ INTEGER;  --시퀀스값을 임시 저장하기위한 변수

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


BEGIN


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

-- 변수 초기화

 V_TEST_SEQ := 'SKIP_SEQNO'; --동기화 맞출 시퀀스  (백업 서버의 시퀀스)

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


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

--TEST_SEQ를 1로 초기화  (백업서버의 시퀀스를 1로 초기화 한다.)

-- 1로 초기화하는 이유는 TEST_SEQ가 TEST_SEQBASE보다 크면 TEST_SEQ의 값이 동기화 불가능

 EXECUTE IMMEDIATE 'ALTER SEQUENCE ' ||V_TEST_SEQ|| ' MINVALUE 0';

 EXECUTE IMMEDIATE 'SELECT ' ||V_TEST_SEQ||'.NEXTVAL FROM DUAL' INTO I_TEST_SEQ;

 EXECUTE IMMEDIATE 'ALTER SEQUENCE ' ||V_TEST_SEQ|| ' INCREMENT BY -'||I_TEST_SEQ;

 EXECUTE IMMEDIATE 'SELECT ' ||V_TEST_SEQ|| '.NEXTVAL FROM DUAL' INTO I_TEST_SEQ;

 EXECUTE IMMEDIATE 'ALTER SEQUENCE ' ||V_TEST_SEQ|| ' INCREMENT BY 1';

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


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

--TEST_SEQBASE의 마지막 시퀀스를 가져와 I_TEST_SEQ에 담는다.

--TEST_SEQBASE 는 실운영서버에있는 시퀀스값을 담을 변수이다.

--백업서버는 DB LINK를동해 실운영서버의 시퀀스 값을 가져온다.

--DB LINK의 이름은 DL_TEST_LINK 이다


  SELECT LAST_NUMBER

  INTO I_TEST_SEQ

  FROM USER_SEQUENCES@DL_TEST_LINK

 WHERE SEQUENCE_NAME = 'SKIP_SEQNO';



--  DBMS_OUTPUT.PUT_LINE('V_TEST_SEQBASE : '||I_TEST_SEQ);  --시퀀스값을 확인하기위해 사용했음


  I_TEST_SEQ:= I_TEST_SEQ-1; --NEXTVAL 시 SEQ값이 +1되는걸 미리 1감소시킴.


--   DBMS_OUTPUT.PUT_LINE('V_TEST_SEQBASE -1 : '||I_TEST_SEQ); --시퀀스값을 확인하기위해 사용했음


  --TEST_SEQ의 증가값을 TEST_SEQBASE에서 가져온 값으로 바꾼다.

  --시퀀스 증가값을 동기화 기준의 마지막 시퀀스로바꿔준다.

  --동기화해줄 시퀀스는 1로 초기화된 상태라서 1보다는 무조건 크기때문에 현재 시컨스값이

  --동기화 기준의 시컨스로 맞춰진다.

 EXECUTE IMMEDIATE 'ALTER SEQUENCE ' ||V_TEST_SEQ|| ' INCREMENT BY '||I_TEST_SEQ;

 SELECT SKIP_SEQNO.NEXTVAL INTO I_TEST_SEQ  FROM DUAL;


  --DBMS_OUTPUT.PUT_LINE('V_TEST_SEQBASE : '||I_TEST_SEQ);  --시퀀스값을 확인하기위해 사용했음


  --시퀀스 증가값을 다시 1로 바꿔준다.

  EXECUTE IMMEDIATE 'ALTER SEQUENCE ' ||V_TEST_SEQ|| ' INCREMENT BY 1';


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


  EXCEPTION

  WHEN OTHERS THEN

    DBMS_OUTPUT.PUT_LINE('SKIP_SEQNO SYNC Error...' || SQLERRM);

END;



반응형