새로 도입하는 시스템이 MS-SQL을 사용한다고 해서 기존에 사용하던 Oracle에서 일부 Data는 초기에 한번, 일부 Data는 주기적으로 동기화를 맞춰주는 작업을 해야합니다. 초기에 한번 이전해 주는 작업은 MS-SQL의 SSIS라는 기능을 이용해서 넘겨주기로 했고, 기능 테스트도 이미 했죠. 문제는 주기적으로 Data의 동기화를 맞춰주는 작업인데요. DB 복제 솔루션을 이용하거나 ETL을 이용하면 쉽게 해결되겠지만, 예산이 없어서 보류하고요. 다른 방법을 찾아보기로 결정했었죠. 그래서 알아본게 다음의 두가지입니다.

1. Oracle Gateway를 이용한 이기종 DBMS간 Data 공유
2. MS-SQL의 Open Query를 이용한 이기종 DBMS간 Data 공유


 Oracle DB에 원천 Data가 있으니 변경된 내용이 생길때 바로바로 적용하기 위해서는 Oracle Gateway를 이용하는게 좋을것 같긴 한데요. 문제는 이건 제가 한번도 해보질 않아서 프로젝트 일정에 맞출수가 없을 것 같더군요. 그래서 MS-SQL에서 구현하기로 했습니다. Open query는 예전에도 써본적이 있거든요.
자꾸 이러면 실력이 늘지 않을텐데 큰일입니다. ^^;  자~ 이제 MS-SQL의 Open query를 이용해서 주기적으로 Data 동기화를 맞춰주는 기능을 구현해보도록 하겠습니다.

 제일 먼저 할 일은 MS-SQL 서버에 Oracle client를 설치하는 일입니다. 설치가 완료되면 Data를 가져올 Oracle server의 정보를 tnsnames.ora에 설정해주면 됩니다. 이제 Linked server를 설정해줄 차례입니다.

 Open Query를 사용하기 위해서 우선 Oracle과 Link를 걸어야 합니다. SQL Server Management Studio에서 [연결된 서버]라는 항목에 추가를 해주면 됩니다. 이때 [Oracle provider for OLEDB]를 선택해서 사용하시는게 좋습니다. MS에서 제공하는 OLEDB provider를 사용할 수도 있는데, 이건 뭔가 문제가 있어보이더군요. Open query에서는 테스트해보지 않았지만, SSIS에서 Oracle의 Data를 가져올때 데이터형을 좀 잘못 가져오는것 같더군요. tnsnames.ora에 설정된 이름과 사용할 Oracle의 계정 정보 등을 입력해서 linked server를 생성하시면 됩니다.

 이제 Open query에 대해서 얘기해볼까합니다. Open query를 이용하면 MS-SQL에서 Oracle DB에 insert, select, update, delete를 실행 할 수 있습니다.

USE TESTDB
GO

SELECT * FROM OPENQUERY(LINK_NAME, `SELECT * FROM 테이블이름`);


UPDATE OPENQUERY(LINK_NAME, `SELECT A FROM 테이블이름 WHERE 조건1`)
SET A='AA' WHERE 조건2;

DELETE OPENQUERY(LINK_NAME, `SELECT A FROM 테이블이름 WHERE 조건1`)
 위의 query문을 보시면 update문을 실행시키는데 select문을 실행시키고 set을 해주는 부분이 보일겁니다. 그리고 조건이 2개 붙은 부분이 보일겁니다. [조건2]가 붙는 이유는 [조건1]에 ms-sql의 프로시져에서 사용하는 변수를 적용할 수 없기 때문입니다. 변수로 처리하지 않고 문자열로 넣어서 처리할 수 있는 부분은 [조건1]에 다 넣어주고, 변수로 받아서 넣어줘야할 내용은 [조건2]에 넣어주면 됩니다. 아래에 프로시져 코드를 보시면 바로 이해하실 겁니다.

이제 배치작업을 위해서 해당 기능을 프로시져로 만듭니다. 제가 작성한 간단한 샘플 코드를 보여드리겠습니다.

USE [testdb]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [tdb].[user_sync]
AS

    DECLARE ora_cursor CURSOR FOR
    SELECT TRG_FLAG, USER_ID, USER_NAME, TEL, CEL, EMAIL, ZIP_CD, ADDR1, ADDR2
       FROM OPENQUERY(VOCA2, 'SELECT B.TRG_FLAG, B.USER_ID, A.USER_NAME, A.TEL, A.CEL, 
                                                               A.EMAIL, A.ZIP_CD, A.ADDR1, A.ADDR2
                                                     FROM USER_TEST A, USER_TRG B
                                                    WHERE B.USER_ID = A.USER_ID(+)  AND B.MIG_DATE IS NULL');

    OPEN ora_cursor

    DECLARE @TRG_FLAG        VARCHAR(1)
    DECLARE @USER_ID            VARCHAR(30)
    DECLARE @USER_NAME            VARCHAR(50)
    DECLARE @TEL            VARCHAR(50)
    DECLARE @CEL            VARCHAR(50)
    DECLARE @EMAIL        VARCHAR(100)
    DECLARE @ZIP_CD            VARCHAR(7)
    DECLARE @ADDR1        VARCHAR(100)
    DECLARE @ADDR2        VARCHAR(100)

    FETCH NEXT FROM ora_cursor INTO @TRG_FLAG, @ USER_ID , @USER_NAME, @USER_TEL, @USER_CEL, @USER_EMAIL, @ZIP_CD, @USER_ADDR1, @USER_ADDR2

    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF (@TRG_FLAG = 'I')
            BEGIN
                INSERT INTO USER_TEST  ( USER_ID , USER_NAME, USER_TEL, USER_CEL, USER_EMAIL, ZIP_CD, USER_ADDR1, USER_ADDR2)
                VALUES(@USER_ID, @USER_NAME, @USER_TEL, @USER_CEL, @USER_EMAIL, @ZIP_CD, @USER_ADDR1, @USER_ADDR2);

                UPDATE OPENQUERY(VOCA2, 'SELECT MIG_FLAG, MIG_DATE, USER_ID FROM  USER_TRG  WHERE TRG_FLAG=''I'' AND MIG_FLAG=''N''')
                    SET MIG_FLAG='Y', MIG_DATE=GETDATE()
                    WHERE USER_ID=@USER_ID;
            END;
        ELSE IF (@TRG_FLAG = 'U')
            BEGIN
                UPDATE  USER_TEST    SET USER_NAME=@USER_NAME, USER_TEL=@USER_TEL, USER_CEL=@USER_CEL, USER_EMAIL=@USER_EMAIL, ZIP_CD=@ZIP_CD,
                                           USER_ADDR1=@USER_ADDR1, USER_ADDR2=@USER_ADDR2
                WHERE USER_ID=@USER_ID;

                UPDATE OPENQUERY(VOCA2, 'SELECT MIG_FLAG, MIG_DATE, USER_ID FROM  USER_TRG   WHERE TRG_FLAG=''U'' AND MIG_FLAG=''N''')
                    SET MIG_FLAG='Y', MIG_DATE=GETDATE()
                    WHERE USER_ID=@USER_ID;
            END;
        ELSE IF (@TRG_FLAG = 'D')
            BEGIN
                DELETE FROM  USER_TEST    WHERE USER_ID=@USER_ID;

                UPDATE OPENQUERY(VOCA2, 'SELECT MIG_FLAG, MIG_DATE, USER_ID FROM  USER_TRG   WHERE TRG_FLAG=''D'' AND MIG_FLAG=''N''')
                    SET MIG_FLAG='Y', MIG_DATE=GETDATE()
                    WHERE USER_ID=@USER_ID;
            END;

        INSERT INTO dbo.USER_TEST_LOG(REG_DATE, USER_ID, TRG_FLAG) VALUES(GETDATE(), @USER_ID, @TRG_FLAG);
        
    FETCH NEXT FROM ora_cursor INTO @TRG_FLAG, @USER_ID, @USER_NAME, @USER_TEL, @USER_CEL, @USER_EMAIL, @ZIP_CD, @USER_ADDR1, @USER_ADDR2 
    END;

    CLOSE ora_cursor                                        -- 커서 클로즈

    DEALLOCATE ora_cursor                              -- 커서 메모리 반환
GO




자 이제 배치작업으로 주기적으로 실행시키는 일만 남았네요.


 현재 재직중인 직장에서 TmaxData의 Tibero4로 DBMS를 migration 및 신규 서비스 구축을 한다는 말씀을 드렸었나요? 음... 암튼 지금 그런 일이 진행되고 있습니다. 나름 대규모 작업이 진행중인데요.
국내 기업이다보니 버그나 기능 개선이 요구되면 그때그때 패치가 되고 있습니다. 이건 뭐 긍정적이라고 생각합니다. 아직 개선할 점이 많은게 문제이긴하지만 대응이 빠른 편이라고 생각합니다. 좋게좋게 생각해야죠.

 이번에 말씀드리려는건 현재 패치가 진행중이라고 알고있는데요. PSM(Oracle의 PL/SQL에 해당함)을 이용해서 함수(Function)를 만들어서 쓸때 생기는 문제입니다.

문제점 : select문장에서 만들어 놓은 함수를 실행시켰는데, 널(null) 값이 반환된다.

원인 : 함수안에서 실행되는 Query 문장이 인덱스를 타게되면 널(null) 값이 반환된다.

해결책 : 현재 패치 진행중이라고 한다. 일단 Full table scan하도록 힌트를 주면 됨.

 뭐... 패치 중이니까요... 곧 해결되겠죠.
 Tibero를 지원하는 Orange for Tibero 2009는 Tibero ODBC Driver가 설치되어 있어야 사용 가능하다.
문제는 티맥스 테크넷이나 홈페이지에서 관련 정보를 찾을 수 없었다는 점이고...

Orange for Tibero 2009를 제작한 웨어벨리 홈페이지에서 Tibero ODC Driver를 설치하는 방법을 찾았다.

1. 윈도우용 티베로가 설치된 디렉토리에서 client/lib 디렉토리에 있는 dll 파일 세개를 windows 디렉토리의 system32 디렉토리에 복사한다.
  libtbcli.dll, libtbertl.dll, libtscli.dll 이상의 세개 파일이다.

2. 윈도우의 컴맨드 창에서 티베로가 설치된 디렉토리의 client/bin 디렉토리도 이동하여
   odbc_driver_install.exe -i 를 입력한다.

D:\temp\tibero3\client\bin>odbc_driver_install.exe -i
Tibero ODBC Driver is being installed to [ C:\WINDOWS\system32 ]
<Caution!!> If you changed the driver path, you should remove all Tibero DSN's and add them again.

Success to INSTALL Tibero ODBC driver

이렇게 하고 Orange for Tibero 2009를 실행시키면 된다.
 요즘 들어서 IBM이 Linux, UNIX, Windows 플랫폼에서의 DB2 설치 및 운영에 관한 정보를 많이 뿌린다는 느낌을 받습니다. DB2용 Orange도 무료로 다운로드 받을 수 있게 해놓았네요.

 예전부터 DB2에 관심이 있긴했지만, 자료가 별로 없어서 힘들었다는 얘기를 하고 했었는데, 이제는 좀 환경이 좋아졌네요. 이참에 한번 설치 해볼까 합니다. ^^

IBM - Break free with DB2!
DB2 Solution information center
Korea DB2 User Group
한국 DeveloperWorks - Information Management

 위의 웹 사이트에 가보면 DB2 관련 자료를 꽤 많이 찾을 수 있습니다.
Break free wirh DB2 사이트에 가보시면 Orange for DB2를 받으실 수 있고요.
Korea DB2 User Group 사이트에는 Oracle 사용자를 위한 DB2 메뉴얼이 있더군요.

 [Power*Architect Data Modeling & Profiling Tool]라는 툴을 아십니까? 흔히들 알고 있는 ERWin과 비슷한 모델링 툴이죠. 큐브리드 홈페이지에 Power*Architect에서 큐브리드를 사용하는 법이 소개된 글이 있어서 링크를 겁니다.

 원문보러가기 : Power*Architect 에서 CUBRID 사용하기

.소개: 본 문서는 보다 편리하게 CUBRID를 사용할 수 있도록 사용자 중심의 편의성 및 기능을 제공하기 위한 데이터 모델링 도구인Power*ArchitectJDBC를 이용하여 연결하는 방법을 소개합니다.

- 예전에 한번 사용해보려다가 모델링과 모델링 툴에 대한 이해 부족과 영문 메뉴얼에 좌절해서 접었던 적이 있었는데, 이렇게 문서도 올라오고 하니... 다시한번 사용해볼까 합니다. ^^;
 예전에는 MS-SQL을 사용하던 중소 규모의 업체에서 회사 규모 확장에 따라서 Oracle을 구매하여 Migration을 하는 경우가 많았었다.  예전에 몸 담았었던 H 모사에서도 그랬고 대용량 DB를 운영하는 사이트에서는 Oracle을 많이 사용하는 추세였죠.
 최근들어 Windows 계열 서버의 사용이 많아지고, MS-SQL Server의 기능이 향상됨에 따라서 MS-SQL Server의 사용이 많아지고 있습니다. 그래서 역으로 Oracle에서 MS-SQL로 이전하는 경우도 생기고 있습니다. 물론 일반적인 경우는 아니라고 생각합니다. 아직은... 성능이든 엔지니어든 여러모로 부족한게 사실이니까요. 설치 및 관리의 편리함은 MS-SQL에 대한 접근성을 낮춰주었고 수많은 MS-SQL 사이트들이 존재하며 그 영역을 넓혀가고 있는데요. 기존 Oracle에서 MS-SQL로 이전하는 사용자를 위한 이전 툴이 MS에서 나왔습니다. 당연한 얘기겠죠. 후발 주자이니 이런 툴에 대한 지원을 잘해야겠죠.

이름하여 SQL Server Migration Assistant(SSMA for Oracle)!!

홈페이지에 있는 정보를 보니 세번째 버전인것 같은데, 그동안 까마득히 모르고 있었네요. 사실 이런식으로 Migration 작업을 한 적이 없었는데, 이번에 Migration 작업을 하시는 분이 있어서 대신 자료를 찾다가 발견하게 되었습니다. 이런 툴들이 존재하는걸 보니 이제는 DB 시장도 치열한 경쟁 구도로 바뀌어가는것 같습니다.

 DB Server migration 작업의 네번째 이야기입니다.
이번에 할 얘기는 장비 설치입니다. 설치는 S/W가 아니라 H/W의 설치를 뜻합니다. 제 경우처럼 대형 장비가 들어올 경우에 여러 업체에서 다양한 엔지니어들이 들어와서 설치를 하게됩니다. 일정 조정은 지난번에 말씀드렸으니 이번엔 설치하던 날에 대해서 얘기해보죠.

 우선 토요일 오후에 시작해서 일요일 오전에 끝나도록 일정이 잡혔고, 시간대별로 각 업체의 엔지니어분들이 들어왔습니다. 이번 작업을 하면서 서비스를 내리게되자 다른 서버의 펌웨어 업그레이드와 패치 등의 작업도 함께하게 되었습니다. 서비스를 자주 중지할 수 없는, 그리고 중지하더라도 넉넉하게 작업 시간을 확보할 수 없는 환경에서 이런 대형 공사가 있게되면 다른 작업도 함께 하게 되죠. 저희의 경우엔 기존 IBM P-595의 펌웨어 및 관리콘솔의 펌웨어 업그레이드도 함께 하게 되었습니다.

 1. 스토리지 증설
 스토리지에 새로 들어온 장비를 위한 디스크를 장착하고 포멧을 했죠.


2. 펌웨어 업그레이드
 이건 새로 들어온 장비와 상관없이 기존 장비 유지보수를 위한 작업이었죠. 이렇게 10시간 이상 다운타임이 생기면 정말 감사할 따름이죠. ^^


3. 서버 설치
 서버가 꽤 무거운 관계로 서버 납품 업체에서 네분 정도가 지원을 나오셨더군요.
너는 뭘 했냐고 물어보시면... 음... 저는 "갑"은 아니지만 작업 진행 상황을 체크하는 입장이라서 바쁘게 돌아다니기만 했습니다. ^^; 그리고 대형 서버 장비의 경우에는 납품 업체에서 모든걸 처리합니다. 혹시나 도와준다고 했다가 문제 생기면 그쪽에서 책임을 지지 않죠. IBM, HP, SUN 등등 대부분의 대형 서버 밴더들은 그렇습니다.
 서버 장착하는데도 커다란 공구가 필요하더군요. 저는 공구만 옮겨드렸었습니다.


4. SAN 및 기타 넷트웍 케이블 연결
 스토리지, 인터넷 서비스 등을 위한 SAN 케이블을 연결하고 잘 인식하는지 확인합니다. 3번과 4번 사이에는 아주 많은 시간 차이가 있습니다. 엔지니어분들이 고생하셨죠. 수고하셨습니다.~~


 그후.
설치후에 기본적인 설정을 하게됩니다. 그 이야기는 다음에 하도록 하겠습니다. 점심시간이 끝나가네요.

 보통 새 장비가 들어오면 - 그 장비가 몇백만원 단위의 저가가 아니라 대형 장비라면 - 그 장비를 설치하는 일은 납품 업체에서하고, OS 설치까지도 알아서 해주죠. 저희는 서버, 스토리지, SAN Switch까지 들어오기때문에 여러 업체가 작업을 하게 되었습니다. 그래서 중간에 조정자가 필요합니다. 저희도 "을"의 입장이지만, 납품 업체들의 일정을 모아서 "갑"에게 알려주고 "갑"의 의사결정에 따라서 일정을 확정하는거죠.

0. 상면, 전력 등을 미리 신청하여 확보하였는가?
1. 기존의 서버스와 상관없이 미리 할 수 있는 작업은 무엇인가?
2. 여러 업체가 동시간대에 할 수 있는 작업은 무엇인가?
3. 다른 작업보다 먼저 해야할 작업은 무엇인가?
4. 기존의 서비스를 중지해야한다면 최소, 최대 몇시간이 걸리는가?
5. Migration하게 될 장비의 사양에 맞게 소프트웨어 라이센스도 확보되었는가?



음... 이 정도가 중요하게 고려되어야할 문제인것 같습니다. 마지막에 라이센스 문제가 적혀있는데, 이번에 저희 프로젝트에서 문제가 되었던 점입니다. 이건 초기에 계약이 어떻게 되었는지와도 상관이 있는 문제라서 좀... 난감한 문제이죠.
 DB 서버 이전을 하는 첫 단계로 기본 정보 수집 단계입니다.

 이 단계에서 우선 기본적으로 DB에 Datafile이 몇개나 되는지 용량은 얼마나 되는지 어떤 디렉토리 구조로 나뉘어서 저장되어 있는지 목록을 만듭니다. 그리고 각 계정별로 어떤 테이블이 있는지, 그리고 데이터의 양은 얼마나 되는지를 마찬가지로 목록으로 만듭니다.

 목록으로 만드는 이유는 이전 과정에서 앞으로는 없어도 되는, 현재 사용중이지 않은 테이블 혹은 계정을 가려내어 빼기 위함입니다. 한번쯤은 정리해주는게 필요하죠. ^^ 그래야 새 서버로 옮겼을때에 성능 향상이 눈에 뛰겠죠. ㅋㅋ 음... 그리고 좀더 자세한 내용은 나중에 적어보겠습니다. 사무실에 올라가야 겠네요.

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

내용 추가

1. 데이터 파일 목록

2. 유저별 Object 목록
 : system, sys 및 기타 DBMS 설치시 생성되거나 툴을 설치할때 생성되는 계정의 Object를 제외한 목록 정리

3. 각 유저별 디스크 사용량 정리
 이번에 새 장비가 들어와서 서버 이전을 해야합니다. 이기종 DBMS간의 이전은 아니라서 참 다행스럽긴한데, 그래도 고민해야할것들이 참 많네요. 그래서 Oracle이라는 DBMS의 관점을 포함해서 일반적인 DBMS Server의 이전이라고 가정하고 서버 이전을 할때 고려해야할 점들을 정리해보고자합니다.

 (1) 서버 이전을 시작하며

 서버 이전을 하기전에 우선 새 장비 도입과 관련된 업체 사람들이 모여서 회의를 하죠.
서버 납품 일정, 스토리지 장비 납품일정, 넷트웍 관련 장비 납품 일정, 전원 및 상면 예약 등등의  협의 사항을 얘기했습니다. 장비가 들어오는 시간 순서부터, 연결하는 순서. 동시에 작업 가능한 일들... 열거하려니 참 힘드네요.

그리고 결정적으로 Migration시에 발생하는 라이센스 변동 내용. 이건... 계약 내용에 없는건데, 갑이 억지를 부리네요. CPU갯수가 두배이상 늘어나는데, 어플리케이션 라이센스도 알아서 처리하라는...(음... CPU갯수가 틀리니까 경고메세지가 뜨는데 그게 보기 싫으시다는) 우리 "갑"님.

 그 외에는 걱정거리는 없네요.
더 많은 CPU 갯수, 더 빠른 CPU, 더 빠르고 용량이 늘어난 스토리지 도입. 뭐 걱정보단 DB 파일 저장 구조를 어떻게 꾸밀지만 고민하면 됩니다. 이것도 중요한거지요.

자세한 고민은 다음회부터 하겠습니다. 그럼 빨리 사무실에 들어가봐야 겠어요. 벌써 15분 가량이 지났네요.

+ Recent posts