728x90

# HSODBC 설정 방법

 

1. ODBC 설정

 오라클이 설치된 NT 장비에서 [제어판 [관리도구 [데이터원본(ODBC)] 메뉴 선택

 . ODBC 데이터 원본 관리자 창에서 [시스템 DSN] 탭메뉴 선택 후 추가 버튼 클릭

 새 데이터 원본 만들기 창에서 [SQL Server] 드라이버 선택

 . SQL Server에 새로운 데이터 원본 만들기 창의 이름 항목에 ‘hsodbctest설명 항목은 생략
     
서버 항목에 임시장비2 IP 입력

 . Microsoft SQL Server DSN 구성 창에서 ‘사용자가 입력한 로그인 ID 및 암호를 사용하는 SQL Server 
     
인증 사용’에 체크 하고,
 하단의 ‘추가 구성 옵션의 기본 설정을 얻기 위해 SQL Server에 연결’에도 체크 후 
     ID 
및 암호 항목에 임시장비2에 설치된 
MSSQL DB의 계정 정보를 입력

 그 이후 단계는 디폴트로 진행

 

 

2. 오라클 HSODBC 설정

 . $oracle_home\network\admin\tnsnames.ora 파일 수정 (붉은색 부분 추가)


hsodbc =

      (DESCRIPTION=

        (ADDRESS=(PROTOCOL=tcp)

        (HOST=127.0.0.1)

        (PORT=1521))

        (CONNECT_DATA=(SID=hsodbc))

        (HS=OK)

      )

 

 . $oracle_home\network\admin\listener.ora 파일 수정 (기존 리스너 환경에 붉은색 부분만 추가)


SID_LIST_LISTENER =

  (SID_LIST =

    (SID_DESC =

      (SID_NAME = PLSExtProc)

      (ORACLE_HOME = C:\oracle\product\10.2.0\db_1)

      (PROGRAM = extproc)

    )

    (SID_DESC=

      (SID_NAME=hsodbc)

      (ORACLE_HOME=C:\oracle\product\10.2.0\db_1)

      (PROGRAM=hsodbc)

    )

  )

 

 . $oracle_home\hs\admin\inithsodbc.ora 파일 수정 (기존 parameter 항목에 붉은색 부분 반영)


HS_FDS_CONNECT_INFO = 
hsodbctest

HS_FDS_TRACE_LEVEL = off

 

 오라클 리스너 restart

  - cmd 창에서 lsnrctl 입력 후 stop -> start 명령어 입력

 

 

3. 오라클 DB Link 생성

 . cmd 창 또는 SQLPLUS 프로그램을 통해 오라클 DB 접속 (DBA 권한이 있는 계정으로 접속)

 다음과 같은 쿼리문으로 DB Link 생성 (ID/PW는 오라클 DB가 아닌 MSSQL DB의 계정의 ID/PW )


CREATE PUBLIC DATABASE LINK 
hsodbc

CONNECT TO <MSSQL-ID> IDENTIFIED BY <MSSQL-PW> USING 'hsodbc';

 

 

4. 검증

 오라클 DB 접속

 . DB Link를 통해 MSSQL DB 내 특정 객체(테이블/조회


select count(*) from 
테이블
@hsodbc;




<참고 자료> 
- How to setup generic connectivity (HSODBC) for 32 bit Windows (Windows NT, Windows 2000, Windows XP, Windows 2003)
728x90

'Oracle > oracle' 카테고리의 다른 글

Optimizing GROUP and ORDER BY  (0) 2011.04.13
오라클 캐릭터셋 확인  (0) 2011.03.08
Oracle 11g - ADRCI : IPS  (0) 2010.05.20
NOT IN과 NOT EXISTS의 차이점  (0) 2010.05.03
NOT IN, NOT EXISTS, MINUS의 효과적인 튜닝방법  (0) 2010.04.01
728x90

Oracle 11g에서 많은 새로운 기능들이 생겼습니다.

그러나 oracle 11g를 설치하면 제일 먼저 눈에 띄는게 OFA 구조가 바뀐거죠. 

(설치 후 alert log를 한참동안 찾아 헤메였다는.. ^^;)


전통적으로 oracle alert log file과 trace file들은 $ORACLE_BASE/admin/$ORACLE_SID/bdump 에 쌓였었죠. 

(아마 8.0 때부터였던가.. 그랬었을 겁니다. 아마 ㅋ)

가끔 bug이나 resource 문제로 $ORACLE_HOME/rdbms/log에 생기기도 했고요. 


Oracle 11g에서는 이 구조가 좀 바뀌었습니다. $ORACLE_BASE 밑에 diag란 directory 밑에 쪼르륵 달려있습니다. 


$ORACLE_BASE/diag/rdbms/'DATABASE NAME'/$ORACLE_SID/trace


이렇게 구조가 달라진 이유는 아마 metalink.oracle.com에서 support.oracle.com으로의 변화와 OCM (oracle configuration management) 때문이지 않을까 싶습니다. 즉, database의 특정 환경, event 들을 OCM을 통해 support.oracle.com에서 지원하려는 .. 뭐 그런 이유 이지 않을까 싶습니다. 


암튼 단순히 trace file과 alert log의 위치만 변경된 것은 아니죠. adrci라는 diag file 관리 tool이 만들어 졌습니다. 

이 tool을 이용해 현재 발생한 problem, incident 등을 쉽게 파악할 수 있으며, 기간이 오래된 trace file 등을 한방에 정리도 할 수 있습니다.

이러한 기능은 EM에서도 가능하고요. 


oracle 내에서 어떤 문제가 생겨 SR을 open해 분석을 진행할때 가장 귀찮은 게 관련 trace, log file을 취합해서 upload하는 겁니다. (저는 그래요.. ㅋ) adrci에서는 관련 trace, log file을 한꺼번에 취합해 주는 기능이 있는데, 이것이 IPS (incident packaging service) 입니다. 


구조가 바뀌고 "PROBLEM"과 "INCIDENT"라는 단어들이 나오는데, Problem은 특정한 문제 전체를, Incident는 문제의 발생 자체를 말합니다. 즉, ORA-1555가 10번 발생했다면 ORA-1555 1개의 문제에 10번의 incident가 발생한게 됩니다.


다음은 ADRCI에서 incident를 packaging 하는 방법입니다. 

그냥 보시면 아실만한 내용이라 별도의 설명은 생략하겠습니다. 


$ adrci


ADRCI: Release 11.1.0.7.0 - Production on Mon Mar 8 16:35:56 2010


Copyright (c) 1982, 2007, Oracle.  All rights reserved.


ADR base = "/oracle"

adrci> 

adrci> show incident


ADR Home = /oracle/diag/rdbms/test/TEST01:

*************************************************************************

INCIDENT_ID          PROBLEM_KEY                                                 CREATE_TIME                              

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

656910               ORA 600 [critical problem임]                                2010-01-29 11:31:45.635899 +09:00       

656909               ORA 600 [critical problem임]                                2010-01-29 11:19:30.662164 +09:00       

656478               ORA 7445 [critical problem임]                               2010-01-25 13:21:00.086171 +09:00       

656477               ORA 7445 [critical problem임]                               2010-01-25 13:16:54.434050 +09:00       

               ...

20 rows fetched


ADR Home = /oracle/diag/clients/user_oracle/host_2085451943_11:

*************************************************************************

INCIDENT_ID          PROBLEM_KEY                                                 CREATE_TIME                              

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

25                   oci 24550 [3]                                               2009-08-19 17:01:14.504278 +09:00       

17                   oci 24550 [3]                                               2009-08-19 16:59:56.250301 +09:00       

9                    oci 24550 [3]                                               2009-06-18 08:09:28.329766 +09:00       

1                    oci 24550 [3]                                               2009-06-18 08:07:58.791738 +09:00       

4 rows fetched


adrci> show homepath

ADR Homes: 

diag/rdbms/test/TEST01

diag/clients/user_oracle/host_2085451943_11

diag/clients/user_precise/host_2085451943_11

diag/clients/user_norad/host_2085451943_11

diag/tnslsnr/TEST01/test_TEST01

diag/tnslsnr/TEST01/listener_TEST01

diag/tnslsnr/TEST01/listener_TEST01

diag/tnslsnr/TEST01/listener

adrci> set homepath diag/rdbms/test/TEST01

adrci> ips create package incident 656910

Created package 1 based on incident id 656910, correlation level typical

adrci>

adrci> IPS GENERATE PACKAGE 1 in /oracle/diag

Generated package 1 in file /oracle/diag/ORA600critical problem임_20100308163713_COM_1.zip, mode complete

adrci> exit

$ls -altr

total 12744

-rw-r--r--   1 oracle     dba        6456404 Mar  8 16:39 ORA600critical problem임_20100308163713_COM_1.zip


참고: 

Note.738732.1 ADR How to Package Diagnostic Information in 11g

728x90
728x90

이번달 퀴즈는 두가지 부정형 조인 NOT IN, NOT EXISTS 의 차이점을 설명하는것입니다.

문제를 명확히 하기 위해서 아래와 같은 상황을 고려하겠습니다.

테이블 : TEST1

     NO

Name

1

Lee

2

Kim

Park

<NULL>

Jang

<NULL>

<NULL>

 

테이블 : TEST2

NO 

 

Name

 

1

Lee

2

Kim

Park

<NULL>

Jang

* <NULL>은 데이터가 NULL값인 경우입니다.

 

테스트 쿼리

1) NOT IN 의 경우

SELECT *
   FROM TEST1 A
  WHERE A.NO NOT IN (SELECT NO FROM TEST2)

2) NOT EXISTS 의 경우

SELECT *
   FROM TEST1 A
  WHERE NOT EXISTS (SELECT 1 FROM TEST2 B WHERE A.NO = B.NO)

위와 같은 상황에서 두 개의 테스트 쿼리를 실행하여 그 결과에 대해 왜 그렇게 나왔는지 설명하세요.

 

 

답안)

이번달 퀴즈의 문제는 NOT IN과 NOT EXISTS의 차이점이 무엇인가입니다.

 

1번, 2번의 경우에서 NO의 값 1,2,3은 모두 결과에 나오지 않습니다. 즉, TEST2에 속하지 않는것을 찾는것이므로 결과에 나오지 않게됩니다. 차이점은 NULL 값이 결과에 나오는가 아닌가에 있습니다.

 

NOT IN(1번)의 경우

where절의 조건이 맞는지 틀리는지를 찾는것입니다. 그런데 NULL은 조인에 참여하지 않기때문에 결과에서 빠집니다. 여기서 TEST1의 NULL값이 나오지 않은 이유는 IN 서브쿼리의 결과에 NULL유무에 영향을 받지 않습니다. 즉, TEST2의 NO컬럼에 NULL값이 없어도 TEST1의 NO컬럼의 NULL값은 결과에 나오지 않습니다.

 

NOT EXISTS(2번)의 경우

EXISTS는 서브쿼리가 TRUE인지 FALSE인지 체크하는 것이므로  NOT EXISTS는 서브쿼리가 FALSE이면 전체적으로 TRUE가 됩니다. 서브쿼리에서 TEST1과 TEST2의 조인시 NULL은 결과에서 빠지게 됩니다. 이것은 서브쿼리를 FALSE로 만들게 되고 전체적으로 TRUE가 되어 TEST1의 NULL값이 결과에 나오게 됩니다.

 

이번 퀴즈는 매우 쉬운것 같으나 자칫 잘못 생각할 수 있는 내용이기 때문에 퀴즈로 다루었습니다. 일반적으로 대용량을 처리할 때 성능상의 이유로 Hash Anti-Join, Merge Anti-Join으로 유도하기 위해 NOT EXISTS를 NOT IN으로 바꿔서 처리하기도 합니다. 이때 두 부정형 조인의 결과가 같다는 전제 조건이 있어야 합니다. 그러나 위에서와 같이 연결고리가 되는 컬럼의 값 중 NULL이 포함된 경우 결과가 다르다는것을 주의해야 합니다.

 

 

=========================================================================================================================
=========================================================================================================================

 

 

not in 과 not exists 차이점 / 부정형을 긍정으로 변경할때

 

 

일반적으로 대용량을 처리할때 성능상의 이유로 Not Exists로 되어 있는 것을


Not In으로 바꿔서 Hash나 Merge Anti Join으로 유도하는 경우가 있는데


이는 Not Exists와 Not In의 관계가 "="이 성립한다는 전제 조건에서 이루어 진다.

 

하지만 모든경우 Not Exists와 Not In의 관계가 "=" 성립하는지에 대한 의문에서


아래와 같이 테스트를 해보았습니다.

 

<결론>
   Not In 과 Not Exists는 다르다.
    + Not IN과 Not Exists의 차이점은 연결고리가 되는 컬럼의 
      값중 null값을 처리하는 부분에서 차이가 난다.


<이유>
    + Not In 은 where 절의 조건이 만족하더라도 
      연결고리 컬럼이 Null값을 가진 다면 결과에서 무조건 제외 된다.


    + Not Exists는 Not In과 달리 Null값을 가진 row들도 결과에 포함된다.

 

    + 간단히 생각해보면 in은 조건에 만족하는 row를 찾는 것이고
      exists는 exists이하 절이 true인지 아닌지를 체크하는 것이기 때문에
      연결고리 컬럼의 값이 null값을 가질때 null은 조인에 참여하지 못하기 때문에
      in은 조건에 만족하는 것을 찾을 수 없는 것이고
      exists는 false의 값을 return한다.
      
      따라서 연결고리 값이 null값을 가질때
      Not in은 조인 연산을 하지 않기 때문에 결과에서 제외되며
      Not Exists는 exists이하의 절이 false를 리턴하고 거기에 대한 Not이기 때문에
      결과적으로 true가 되어 결과에 포함된다.

 

<참고사항>


  1) 부정형을 긍정으로 변경할 때


    + Not In일 때는 상관 없지만 Not Exists일때는 
      논리적으로 부정형을 긍정으로 변경 한 후 연결고리가 되는 컬럼이 null값 가질 경우에 
      대해서 반드시 True가 되도록 처리해 줘야 된다.
    + 즉 null 값을 가지는 컬럼에 대해서도 결과에 포함 되도록 해야 된다.

 

  ex)
      SELECT :current_il,
             A.SNG_NO,
             A.SNG_SEQ,
             A.JI_HANDO,
             A.JI_HAN_BAL,
       FROM IRMS_SNG_MAS A
      WHERE A.WONJ_ST2 = '1'
        AND A.GAGIGONG_GB IN('2','3')
        AND NOT EXISTS(SELECT 'X'
                         FROM IRMS_SNG_MAS G
                        WHERE G.WONJ_ST2 = '1'
                          AND G.GAGIGONG_GB IN('2','3')
                          AND (G.MANGI_IL < :current_il AND NVL(G.SIL_BAL,0) = 0)
                          AND G.SNG_NO = A.SNG_NO
                          AND G.SNG_SEQ = A.SNG_SEQ)

 

   <부정형을 긍정형으로 변경>


     + MANGI_IL이 NULL값을 가질때 반드시 참이 되도록 해야 됨.
     
      SELECT :current_il,
             A.SNG_NO,
             A.SNG_SEQ,
             A.JI_HANDO,
             A.JI_HAN_BAL,
        FROM IRMS_SNG_MAS A
       WHERE A.WONJ_ST2 = '1'
         AND A.GAGIGONG_GB IN('2','3')
         AND NOT (NVL(A.MANGI_IL,'99991231') < :CURRENT_IL AND NVL(A.SIL_BAL,0) = 0)

 

<테스트 테이브>
TEST_AJ01
TEST_AJ02

 

<데이타>

TEST_AJ01
========================
NO        MARRY_DT
-------------------
1        20030405
2        20030405
3        20030405
<null>   <null>
<null>   20030408


TEST_AJ02
========================
NO        MARRY_DT
-------------------
1        20030405
2        20030405
3        20030405
<null>   20030408

# NULL값을 가진 컬럼의 값은 <null>이라고 표현하였음


<테스트 SQL문>
1)
    SELECT *
      FROM TEST_AJ01 A
     WHERE A.NO NOT IN (SELECT NO FROM TEST_AJ02)
   
   ==결과==  -- 0건
   No rows returned

2)
    SELECT *
      FROM TEST_AJ01 A
     WHERE NOT EXISTS (SELECT 'X' FROM TEST_AJ02 B WHERE A.NO = B.NO)

   ==결과==  -- 2건
   <null>    <null>
   <null>    20030408

 

 

==========================================================================================================================
==========================================================================================================================

TEST1 테이블의 데이터 중 TEST2에 속하지 않는 데이터만 가져오기 ( NOT IN, NOT EXISTS, JOIN, UNION 으로 해결 )

중복되지 않는 데이터만 가져와서 INSERT 하거나

중복되는 데이터만 가져와서 UPDATE 할 때 사용할 수도 있다.

 

CREATE TABLE TEST1 (
 IDX INTEGER, 
 NAME VARCHAR(100)
)

CREATE TABLE TEST2 (
 IDX INTEGER, 
 NAME VARCHAR(100)
)


INSERT INTO TEST1 VALUES (1, 'A')
INSERT INTO TEST1 VALUES (2, 'B')
INSERT INTO TEST1 VALUES (3, 'C')
INSERT INTO TEST1 VALUES (4, 'D')
INSERT INTO TEST1 VALUES (5, 'E')


INSERT INTO TEST2 VALUES (3, 'C')
INSERT INTO TEST2 VALUES (4, 'D')
INSERT INTO TEST2 VALUES (5, 'E')
INSERT INTO TEST2 VALUES (6, 'F')
INSERT INTO TEST2 VALUES (7, 'G')


SELECT * FROM TEST1
SELECT * FROM TEST2

 

-- NOT IN

SELECT *
  FROM TEST1
 WHERE IDX NOT IN (
SELECT IDX
  FROM TEST2 )

 

-- NOT EXISTS

SELECT *
  FROM TEST1 A
 WHERE NOT EXISTS (
SELECT *
  FROM TEST2 B
 WHERE A.IDX = B.IDX )

 

-- SYBASE JOIN
SELECT *
  FROM (
 SELECT A.*
   , B.IDX B_IDX
   FROM TEST1 A
      , TEST2 B
  WHERE A.IDX *= B.IDX
    ) A
   WHERE B_IDX IS NULL
 

-- ANSI JOIN

SELECT *
  FROM TEST1 A
  LEFT JOIN TEST2 B
    on A.IDX = B.IDX
 WHERE B.IDX IS NULL
 

-- UNION ALL
SELECT A.IDX, A.NAME
  FROM (
  SELECT NAME
    , COUNT(*) CNT
    , COUNT(CASE WHEN GBN = 'A' THEN 1 END) A_CNT
    , IDX
    FROM (
    SELECT 'A' AS GBN
      , A.*
      FROM TEST1 A
    UNION ALL
    SELECT 'B'
      , B.*
      FROM TEST2 B
     ) A
   GROUP BY IDX, NAME
  ) A
 WHERE A.CNT < 2
   AND A_CNT = 1

728x90
728x90

BEST안은 적게 불러와서 적게 계산하는 것입니다. 
그 이외에도 여러가지 사항들이 많으나 몇가지만 적습니다.

- 검색조건과 무관한 인덱스 순서에 따른 문제 -> 검색 조건 우선순위에 따른 인덱스 컬럼 순서 재조정해서 재생성
- 데이터 제한 조건은 인덱스를 사용하도록
- 데이터 불러오는 양을 적게
- 사용자 ORACLE FUNCTION은 자제 (각 ROW단위로 연산이 일어나므로 매우 많은 CPU부하를 줌)
- 무조건 FULLTABLESCAN(이하 FTS)이 나쁜것은 아님
- NOT IN보다는 IN사용
- NOT EXISTS 보다는 EXISTS사용
- UNION보다는 UNION ALL사용

기본적으로는 CPU부담과 DISK I/O 를 적게 사용하는것이지만 서버의 CPU는 여유롭지만 DISK I/O가 많다면 DISK I/O를 줄여주는 방법이 좋겠고요 반대인 경우는 CPU사용을 줄여주는(연산작업) 방법이 좋은 튜닝 방법일것입니다.

위 세가지를 비교해 달라는 질문으로 알고 설명드립니다. 막상 질문사항만 놓고보자면 테이블크기, 데이터분포, 인덱스 컬럼 구성여부에 따라 상당히 다를 것입니다.

질문의 의도가 정확하게 나와 있지는 않으나 FTS를 한다는 것은 비교값이 인덱스컬럼에 적절히 설정되지 않았을 것 같은데요. 검색시 WHERE절에 들어가는 항목이 인덱스의 몇번째 컬럼인지 또한 그 분포도는 어떤지에 따라 FTS이 빠를 수도 있습니다.

우선은 해당 검색조건이 많은 데이터가 걸러지는 것인지 확인하여 인덱스를 추가/교체 구성할 필요가 있고 아니라면검색하고자 하는 조건이 인덱스 컬럼에 적정하게 설정되어 있다는 전제하에,

1. NOT IN은 각각의 데이터 자체를 비교하므로 CPU를 상대적으로 많이 사용하게 되며, 
2. NOT EXISTS는 KEY값(인덱스컬럼)만을 비교하므로 NOT IN에 비해여 자원을 덜 사용하게 될 것입니다.
    (하지만 때에 따라서는 NOT IN이 떠 빨리 결과를 내 줄수도 있습니다.)
3. 이와 달리 MINUS는 내부적으로 메모리내 SORT작업을 추가적으로 거치게 되고 일반적으로 서버자원을 좀 더 사용하므로 보통의 경우 많이 사용하지 않습니다.

결론적으로 말씀드리면 일반적인 SQL PLAN결과에 의한 튜닝기대효과는 NOT EXISTS > NOT IN > MINUS라고 볼수 있습니다. 하지만 테이블이 작은 경우라면 MINUS가 오히려 제일 빠른 결과를 내 줄 수도 있습니다.

부가적으로, FUNCTION BASED INDEX는 데이터 변경이 자주/많이 일어나는 경우,평상시 부하를 증가 시키므로 오히려 역효과가 날 수 있습니다. (해당 테이블을 사용하는 다른 SQL에 영향을 줄 수도 있고요...)
또한 정확한 조건MATCH가 일어나는 경우에만 인덱스를 사용하므로 해당 조건 추가시 효과에 대해 검토를 하여야 합니다.

※ 어느정도 개선되어 있는 상황이라면  tkprof를 사용하여 CPU자원을 많이 사용하는 것인지, DISK I/O를 많이 사용하는 것인지 판단하여 시간이 많이 걸리는/부하가 많이 걸리는 부분에 대한 개선을 하는것을 권장합니다.

질문의 의도를 정확히 판단하지 못하여 엉뚱한 답변이 되었을 수 있습니다. 양해바랍니다.



3. 실제로 NOT IN, NOT EXISTS, MINUS 부분은 인덱스를 타지 못하고 FTS(Full Table Scan)을 사용합니다.

오라클 교육을 받다보면, 아래와 같은 경우는 인덱스를 사용할수 없다고 나옵니다.

ⓛ NOT 연산자 사용
② IS NULL, IS NOT NULL 사용
③ 옵티마이저의 취사 선택
④ 외부적인 변형(External Suppressing)
⑤ 내부적인 변형(Internal Suppressing)

간단하게 정리를 해보았습니다.  참고하시길.
1. 연산자를 변경하여 처리하는 방법이 있습니다.
==> 경우에 따라서는 연산자 변경이 안될수도 있습니다. 특히 not 조건이라면 인덱스로 포함하려는 범위가 넓을것입니다. 

2. FTS와 인덱스 스캔 및 CBO vs RBO
 1) FTS로 수행한다고 무조건 느린것은 아닙니다.
  
  - 수행하실 테이블이 크지 않거나 칼럼 분포도가 좋지 않을경우는 오히려 FTS가 낫습니다. 
 2) Oracle 10g이상사용시 
   - 실제로 CBO를 사용하면, 비용개념으로 처리를 하기때문에 인덱스를 안타는 경우도 발생합니다. 
   - RBO를 사용하실 경우에는 실제로 계획된 대로 처리가 됩니다.
==> 10g 이상이라면,  Explain Plan을 해보시면 아실수 있을것입니다.
그리고,  테이블의 구조 및 상태에 따라 유동적이므로, 최적의 방법을 찾는것이 좋습니다. 

3. Not in 조건 사용시 
 1) 이 부분은 인덱스를 탈수 있는 연산자 변경을 하시면 가능합니다. 단 in 조건을 이용하셔서 그 값을 모두 뽑아도 된다면, 하나의 방법이 되겠지만, in에 조건값이 많아지면 그 성능은 그리 뛰어나다고 할수 없습니다.

종합적으로 보았을때, SQL 정보 및 시스템 상황을 고려해야할 경우라면 , 아래 두가지 정도입니다.
1) 성능상으로 크게 문제가 되지 않고, 해당 인덱스가 적용될 칼럼의 분포도 및 DML문(:insert ,update, delete)이 자주 발생하는 경우라면, CBO를 사용하여 비용단위로 추출된 쿼리로 FTS를 사용해도 괜찮을것입니다.(쿼리 실행 횟수도 체크가 필요할것입니다.)

2) 그러나, 해당 테이블이 대용량이고 select성으로 사용되는 테이블이고 ,해당 쿼리로 인하여 DB서버 및 AP에 부하가 우려되는 경우라면 말씀하신데로 연산자 변경이나 Function Based index를 사용하시는것이 좋을것입니다.

728x90
728x90

SELECT 문장에서 DISTINCT를 사용하는 이유는 중복된 행을 제거 하기 위해서 입니다. 이를 위해 오라클은 SORT를 수행 하며 당연히 소트를 위한 시간, 메모리 또는 디스크 공간이 필요 할 수도 있습니다. 그러니깐 가급적이면 사용 안 하는 것이 좋습니다. 추출되는 데이터가 순서에 의해 출력되지 않아도 된다면 아래의 경우처럼 EXISTS를 사용하는 것이 훨씬 효율적 입니다. 예제를 통해 이해 하도록 하겠습니다. 실제 비용(COST)의 경우도 1/10 정도로 줄게 됩니다.


SQL> set autotrace on
SQL> select distinct c.name
  2  from s_customer c, s_ord o
  3  where c.id = o.customer_id;

NAME
--------------------------------------------------
Beisbol Si!
Big John's Sports Emporium
Delhi Sports
Futbol Sonora
Hamada Sport
Kam's Sporting Goods
Kuhn's Sports
Muench Sports
OJ Atheletics
Ojibway Retail
Sportique

NAME
--------------------------------------------------
Unisports
Womansport

13 개의 행이 선택되었습니다.

경   과: 00:00:00.03

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   SORT (UNIQUE)
   2    1     NESTED LOOPS
   3    2       TABLE ACCESS (FULL) OF 'S_ORD'
   4    2       TABLE ACCESS (BY INDEX ROWID) OF 'S_CUSTOMER'
   5    4         INDEX (UNIQUE SCAN) OF 'S_CUSTOMER_ID_PK' (UNIQUE)

이 경우엔 S_ORD 테이블을 전체 스캔 한 데이터와 S_CUSTOMER 테이블의 데이터를 UNIQUE 인덱스를 이용하여 가져온 후 ROWIDD로 찾은 데이터와 비교하여 같은 아이디의 데이터가 있으면 추출하고 아니면 반복하는 구조를 가집니다. 그런 다음 c.name으로 SORT를 하게 되는 거죠…


Statistics
----------------------------------------------------------
         80  recursive calls
          0  db block gets
         57  consistent gets
          0  physical reads
          0  redo size
        651  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         13  rows processed

이번엔 EXISTS를 이용하는 예 입니다.

SQL> select c.name
  2  from s_customer c
  3  where exists (select 1 from s_ord o
  4                where o.customer_id = c.id);

NAME
--------------------------------------------------
Unisports
OJ Atheletics
Delhi Sports
Womansport
Kam's Sporting Goods
Sportique
Muench Sports
Beisbol Si!
Futbol Sonora
Kuhn's Sports
Hamada Sport

NAME
--------------------------------------------------
Big John's Sports Emporium
Ojibway Retail

13 개의 행이 선택되었습니다.

경   과: 00:00:00.03

Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=CHOOSE
   1    0   FILTER
   2    1     TABLE ACCESS (FULL) OF 'S_CUSTOMER'
   3    1     TABLE ACCESS (FULL) OF 'S_ORD'

이 경우엔 S_CUSTOMER를 전체 스캔하고 S_ORD도 전체 스캔하여 필터링(ID가 같은 데이터가 있는지) 하므로 SORT를 이용하지는 않습니다. 그러므로 앞의 쿼리와 추출되는 데이터의 개수는 같지만 순서는 달리 나오는 겁니다.


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         49  consistent gets
          0  physical reads
          0  redo size
        651  bytes sent via SQL*Net to client
        503  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
         13  rows processed



출처 : http://blog.daum.net/sadest/15853269

728x90
728x90

SQL*LOADER는 일반 text file의 data를 ORACLE table로 load하는 유틸리티로서 IBM의 DB2 load utility와 흡사하다. SQL*LOADER의 처리 mode에는 크게 direct load와 conventional load가 있다. 여기에서는 각 mode 의 차이점과, SQL*LOADER 를 실행중 index 가 direct load state로 빠지는 현상에 대해 살펴본다.  
1.CONVENTIONAL PATH LOAD  

default로 사용되는 option으로 일정한 크기의 버퍼을 memory에 할당하고 이곳에 text data를 저장 하여 버퍼가 모두 차면 SQL command인 insert를 이용하여일반 적인 insert 작업을 수행하게 된다. 이러한 방법은 ORACLE에서 제공하는 일반적인 다른 tool 들에서도 사용하는 insert 방법이다. commit은 버퍼에 저장된 row들이 전부 insert되었을때 수행되며 버퍼의 size는 bindsize라는 option으로 지정되며 만일 한 row의 길이가 너무 길어 지정된 bindsize내에 하나의 row가 수용되지 못할 정도로 크다면 SQL*LOADER는 error를 발생시킨다.  

예)bindsize=10k,rows=1,record length=15K일 경우 error발생.  

conventional mode는 direct mode에 비해 처리 과정에서 훨씬 여러 단계를 거치므로 performance는 떨어진다. 그러나 이 방법은direct mode가 안고 있는 몇 가지 제한 사항을 해결하는 장점이 있다.  

1)load하려는 table에 다른 process에서 access가 가능하다.  

즉 한쪽에서는 SQL*LOADER로 A table에 load하고 다른 쪽에서는 같은 A table에 SQL*PLUS로 update,insert가 가능하다.  

2)load시 SQL function을 사용 하려면 conventional을 사용해야 한다.  

예)load data  
infile 'test.dat'  
append  
into table dept  
(deptno position(01:02) integer external,  
dname position(03:10) char upper(:dname),  
loac position(11:15) char  
)  

3)load하려고 하는 table이 단일 table이 아닌 cluster인 경우로 cluster table은 direct path load를 사용 못함.  

4)SQL*NET을 통해 data를 load시 SQL*NET을 이용해 direct path load mode로 data를 load할 수는 없다.  

2.DIRECT PATH LOAD  

direct mode는 일반적으로 다량의 data를 table에 load시 performance를 위해 이용하는 방법이다. 이 경우에는 일반적으로 table에 index가 있으면 제거한 후 load를 하는 것이 더 좋은 performance를 얻을 수 있는데 그 이유는 direct mode에서insert시 index가 구성되는 mechanism을 살펴보면 쉽게 알 수 있다.  

1)direct path load에서의 index의 형성과정은  

memory buffer의 data를 datafile에 direct하게 저장 
load된 new data에 대해 temporary index를 생성 
old index와 temporary index를 merge하여 new index를 형성 
d)old index의 drop및 new index로 대치한다.  
2)이의 처리를 위해 direct path를 이용해 data load시 다음의 제한이 따른다.  

a)cluster에는 사용 할 수 없다.  

만일 해당 table에 active transaction이 있는 경우 error발생(commit 안된transaction 이 있는 상태에서 direct load시 ORA-54 error가 발생하는데 해당 table에 table lock을 걸다 실패하기 때문이다) 
c)SQL function을 control file에서 사용 할 수 없다.  
d)만일 index가 table에 있을 경우 direct load중에는 select를 할 수 없다.  

제약사항과 특별한 index 생성 process로 인해 direct mode에서는 실제로 data는 table에 load 되었으나 index에서 문제가 발생하여 해당index를 사용하지 못하는 상태가 발생할 수 있다. 즉 direct load중 index에 대한 space를 allocate할 수 없는 경우, sorted indexes option이 사용되었는데 data가 ordered되지 않은 경우, load도중 shutdown이 발생한 경우, index가 unique index인데 load되는 data중에 동일한 key값이 있는 경우에 해당index는 direct load state 상태가 된다. 이 상태에서는 이 테이블을 select시 index를 사용하지 못하거나, SQL*LOADER direct=y option으로 load시 ORA-1502 error 를 만나게 된다. 이 때는 해당 index를 drop후 recreate하면 쉽게 해결이 가능하다 

728x90
728x90

매우 많은 양의 데이타를 빠른 시간 내에 load하고자하는 경우 direct path load를
사용할 수 있다. 여기에서 이러한 direct path load의 자세한 개념 및 사용방법,
사용 시 고려해야 할 점 등을 설명한다.

1. conventional path load

일반적인 sql*loader를 이용한 방법은 존재하는 table에 datafile 내의 data를 
SQL의 INSERT command를 이용하여 insert시킨다. 이렇게 SQL command를 
이용하기 때문에 각각의 데이타를 위한 insert command가 생성되어 parsing되는 
과정이 필요하며, 먼저 bind array buffer (data block buffer) 내에 insert되는 
데이타를 입력시킨 후 이것을 disk에 write하게 된다.

conventional path load를 사용하여야 하는 경우는 다음과 같다.
--- load 중에 table을 index를 이용하여 access하여야 하는 경우
direct load중에는 index가 'direct load state'가 되어 사용이 불가능하다.
--- load 중에 index를 사용하지 않고 table을 update나 insert등을 수행해야 
하는 경우
direct load 중에는 table에 exclusive write(X) lock을 건다.
--- SQL*NET을 통해 load를 수행해야 하는 경우
--- clustered table에 load하여야 하는 경우
--- index가 걸려 있는 큰 table에 적은 수의 데이타를 load하고자 할 때
--- referential이나 check integrity가 정의되어 있는 큰 table에 
load하고자 할 때
--- data field에 SQL function을 사용하여 load하고자 할 때

2. direct path load의 수행 원리

Direct Path Loads는 다음과 같은 특징들로 인하여 매우 많은 양의 데이타를 
빠른 시간에 load하고자 할 때 이용하는 것이 바람직하다.

(1) SQL INSERT 문장을 generate하여 수행하지 않는다.
(2) memory 내의 bind array buffer를 이용하지 않고 database block의 
format과 같은 data 
block을 memory에 만들어 데이타를 넣은 후 그대로 disk에 write한다.
memory 내의 block buffer와 disk의 block은 그 format이 다르다.
(3) load 시작 시에 table에 lock을 걸고 load가 끝나면 release시킨다.
(4) table의 HWM (High Water Mark) 윗 부분의 block에 data를 load한다. 
HWM는 table에 data가 insert됨에 따라 계속 늘어나고 truncate 외에는 
줄어들게 하지 못한다. 
그러므로, 항상 완전히 빈 새로운 block을 할당받아 data를 입력시키게 된다.
(5) instance failure가 발생하여도 redo log file을 필요로 하지 않는다.
(6) UNDO information을 발생시키지 않는다. 
즉 rollback segment를 사용하지 않는다.
(7) OS에서 asynchronous I/O가 가능하다면, 복수개의 buffer에 의해서 동시에
data를 읽어서 buffer에 write하면서 buffer에서 disk로 write할 수 있다.
(8) parallel option을 이용하면 더욱 성능을 향상시킬 수 있다.

3. direct path load의 사용방법 및 options

direct path load를 사용하기 위한 view들은 다음 script에 포함어 있으며, 
미리 sys user로 수행되어야 한다. 단 이 script는 catalog.sql에 포함되어 있어,
db 구성 시에 이미 수행되어진다.

@$ORACLE_HOME/rdbms/admin/catldr.sql 

direct path load를 사용하기 위해서는 일반적인 sqlload 명령문에 DIRECT=TRUE를
포함시키기만 하면 된다. 다음과 같이 기술하면 된다.

sqlload username/password control=loadtest.ctl direct=true 

이 direct path load를 사용 시에 고려할 만한 추가적인 option 및 control file
내에 기술 가능한 clause들을 살펴본다.

(1) ROWS = n 
conventional path load에서 rows는 default가 64이며, rows에 지정된 갯수
만큼의 row가 load되면 commit이 발생한다. 이와 비슷하게 direct load 
path에서는 rows option을 이용하여 data save를 이루며, data save가 발생하면
data는 기존 table에 포함되어 입력된 data를 잃지 않게 된다. 
단 이 때 direct path load는 모든 data가 load된 다음에야 index가
구성되므로 data save가 발생하여도 index는 여전히 direct load state로 
사용하지 못하게 된다.
direct path load에서 이 rows의 default값은 unlimited이며, 지정된 값이
database block을 채우지 못하면 block을 완전히 채우는 값으로 올림하여, 
partial block이 생성되지 않도록 한다.

(2) PIECED clause
control file내에 column_spec datatype_spec PIECED 순으로 기술하는 
것으로서 direct path load에만 유효하다. LONG type과 같이 하나의 data가
maximum buffer size보다 큰 경우 하나의 data를 여러번에 나누어 load하는 
것이다. 이 option은 table의 맨 마지막 field 
하나에만 적용가능하며, index column인 경우에는 사용할 수 없다.
그리고 load도중 data에 문제가 있는 경우 현재 load되는 data의 잘린 부분만
bad file에 기록되게 된다. 왜냐하면 이전 조각은 이미 datafile에 기록되어 
buffer에는 남아있지 않기 때문이다.

(3) READBUFFERS = n (default is 4)
만약 매우 큰 data가 마지막 field가 아니거나 index의 한 부분인 경우 
PIECED option을 사용할 수 없다. 이러한 경우 buffer size를 증가시켜야 
하는데 이것은 readbuffers option을 이용하면 된다. default buffer갯수는 
4개이며, 만약 data load중 ORA-2374(No more slots for read buffer 
queue) message가 나타나면, buffer갯수가 부족한 것이므로 늘려주도록 한다. 
단 일반적으로는 이 option을 이용하여 값을 늘린다하더라도 system 
overhead만 증가하고 performance의 향상은 기대하기 어렵다.

4. direct path load에서의 index 처리

direct path load에서 인덱스를 생성하는 절차는 다음과 같다.

(1) data가 table에 load된다.
(2) load된 data의 key 부분이 temporary segment에 copy되어 sort된다.
(3) 기존에 존재하던 index와 (2)에 의해서 정렬된 key가 merge된다.
(4) (3)에 의해서 새로운 index가 만들어진다.
기존에 존재하던 index와 temporary segment, 그리고 새로 만들어지는 index가
merge가 완전히 끝날 때까지 모두 존재한다.
(5) old index와 temporary segment는 지워진다.

이와 같은 절차에 반해 conventional path load는 data가 insert될 때마다 한
row 씩 index에 첨가된다. 그러므로 temporary storage space는 필요하지 않지만
direct path load에 비해 index 생성 시간도 느리고, index tree의 balancing도
떨어지게 된다.

index생성 시 필요한 temporary space는 다음과 같은 공식에 의해 예측되어질 수
있다.

1.3 * key_storage
key_storage = (number_of_rows) * (10 + sum_of_column_sizes + 
number_of_columns)

여기에서 1.3은 평균적으로 sort 시에 추가적으로 필요한 space를 위한 값이며,
전체 data가 완전히 순서가 거꾸로 된 경우에는 2, 전체가 미리 정렬된 경우라면
1을 적용하면 된다.

--- SINGLEROW clause
이와 같이 direct path load에서 index 생성 시 space를 많이 차지하는 문제점
때문에 resource가 부족한 경우에는 SINGLEROW option을 사용할 수 있다.
이 option은 controlfile 내에 다음과 같은 형태로 기술하며, direct path
load에만 사용 가능하다.

into tables table_name [sorted indexes...] singlerow

이 option을 사용하면 전체 data가 load된 뒤에 index가 구성되는 것이 아니라
data가 load됨에 따라 data 각각이 바로 index에 추가된다.
이 option은 기존에 미리 index가 존재하는 경우 index를 생성하는 동안 
merge를 위해 space를 추가적으로 필요로 하는 것을 막고자 하는 것이므로 
INSERT 시에는 사용하지 않고, APPEND시에만 사용하도록 하고 있다. 
실제 새로 load할 data 보다 기존 table이 20배 이상 클 때 사용하도록 권하고
있다.

direct path load는 rollback information을 기록하지 않지만, 이 singlerow
option을 사용하면 insert되는 index에 대해 undo 정보를 rollback segment에
기록하게 된다. 
그러나, 중간에 instance failure가 발생하면 data는 data save까지는 보존
되지만 index는 여전히 direct load state로 사용할 수 없게 된다.

--- Direct Load State

만약 direct path load가 성공적으로 끝나지 않으면 index는 direct load 
state로 된다. 
이 index를 통해 조회하고자 하면 다음과 같은 오류가 발생한다.
ORA-01502 : index 'SCOTT.DEPT_PK' is in direct load state.

index가 direct load state로 되는 원인을 구체적으로 살펴보면 다음과 같다.
(1) index가 생성되는 과정에서 space가 부족한 경우
(2) SORTED INDEXES clause가 사용되었으나, 실제 data는 정렬되어 있지 않은
경우
이러한 경우 data는 모두 load가 되고, index만이 direct load state로 된다.
(3) index 생성 도중 instance failure가 발생한 경우
(4) unique index가 지정되어 있는 컬럼에 중복된 data가 load되는 경우

특정 index가 direct load state인지를 확인하는 방법은 다음과 같다.

select index_name, status
from user_indexes
where table_name = TABLE_NAME';

만약 index가 direct load state로 나타나면 그 index는 drop하고 재생성
하여야만 사용할 수 있다. 단, direct load 중에는 모든 index가 direct
load state로 되었다가 load가 성공적으로 끝나면 자동으로 valid로 변경된다.

--- Pre-sorting (SORTED INDEX)

direct load 시 index구성을 위해서 정렬하는 시간을 줄이기 위해 미리 index
column에 대해서 data를 정렬하여 load시킬 수 있다. 이 때 control file 내에
SORTED INDEXES option을 다음과 같이 정의한다. 
이 option은 direct path load 시에만 유효하며, 복수 개의 index에 대해서
지정가능하다.

into table table_name SORTED INDEXES (index_names_with_blank)

만약, 기존의 index가 이미 존재한다면, 새로운 key를 일시적으로 저장할 만큼
의 temporary storage가 필요하며, 기존 index가 없는 경우였다면, 이러한
temporary space도 필요하지 않다.

이와 같이 direct path load 시에 index 구성 시에는 기존 데이타가 있는 table에
load하는 경우 space도 추가적으로 들고, load가 완전히 성공적으로 끝나지 않으면
index를 재생성하여야 하므로, 일반적으로 direct path load 전에 미리 table의
index를 제거한 후 load가 모두 끝난 후 재생성하도록 한다.

5. Recovery

direct load는 기존 segment중간에 data를 insert하는 것이 아니라 완전히 
새로운 block을 할당받아 정확히 write가 끝난 다음 해당 segment에 포함되기 
때문에 instance failure시에는 redo log정보를 필요로 하지 않는다. 그러나 
default로 direct load는 redo log에 입력되는 data를 기록하는데 이것은 media
recovery를 위한 것이다. 그러므로 archive log mode가 아니면 direct load에 
생성된 redo log 정보는 불필요하게 되므로 NOARCHIVELOG mode시에는 항상 
control file내에 UNRECOVERABLE이라는 option을 사용하여 redo log에 redo entry를 기록하지 않도록 한다. 
data가 redo log 정보 없이 instance failure시에 data save까지는 보호되는데 
반해 index는 무조건 direct load state가 되어 재생성하여야 한다. 그리고 data save이후의 load하고자 하는 table에 할당되었던 extent는 load된 data가 
user에게 보여지지는 않지만 extent가 free space로 release되지는 않는다.

6. Integrity Constraints & Triggers

direct path load중 not null, unique, primary key constraint는 enable
상태로 존재한다. not null은 insert시에 check되고 unique는 load후 index를 
구성하는 시점에 check된다.
그러나 check constraint와 referential constraint는 load가 시작되면서 
disable상태로 된다. 전체 데이타가 load되고 난 후 이렇게 disable된 
constraints를 enable시키려면 control file내에 REENABLE이라는 option을 
지정하여야 한다. 이 reenable option은 각 constraint마다 지정할 수는 없으며 
control file에 한번 지정하면 전체 integrity/check constraint에 영향을 
미치게 된다. 만약 reenable되는 과정에서 constraint를 위배하는 data가 
발견되면 해당 constraint는 enable되지 못하고 disabled status로 남게 되며, 
이렇게 위배된 data를 확인하기 위해서는 reenable clause에 exceptions option을 다음과 같이 추가하면 된다.

reenable exceptions table_name 

이 때 table_name은 $ORACLE_HOME/rdbms/admin/utlexcpt.sql을 다른 
directory로copy하여 table이름을 exceptions가 아닌 다른 이름으로 만들어 수행시키면 된다.
insert trigger도 integrity/check constraint와 같이 direct load가 시작하는
시점에 disable되며, load가 끝나면 자동으로 enable된다. 단 enable되고 나서도
load에 의해 입력된 data에 대해 trigger가 fire되지는 않는다.


http://kr.forums.oracle.com/forums/thread.jspa?threadID=470778&tstart=315

728x90
728x90

Oracle Client / Server Interoperability Support

Introduction

This note gives a summary of the support for interoperability between Oracle client and server versions. This includes support for connections over database links between Oracle versions. Note that this relates to support for investigation of defects / ability to obtain bug fixes.

Note that this is a general guide for interoperability only - certain products or utilities may impose additional restrictions on supported combinations specific to the product / utility. eg: Precompilers, Export / Import utilities etc..

For a summary of the support status of each Oracle release see Note 161818.1

General Policy

Oracles general policy is to test and support each new Oracle release for compatibility with older releases thus:

Current Interoperability Support Situation

The matrix below summarizes client and server combinations that are supported.

New interoperability problems will only be investigated if BOTH releases involved are covered by a valid support contract at the time that the issue is reported .
eg:

A 9.2.0 client to a 10.2.0 server issue requires the customer to have a valid Extended Support contract for the 9.2.0 client in order for Oracle to investigate it.

Server Version
Client Version11.1.010.2.010.1.09.2.09.0.18.1.78.1.68.1.58.0.68.0.57.3.4
11.1.0YesYes #6Yes #6ES #5NoNoNo #3No #3No #3No #3No #3
10.2.0Yes #6YesYesES #5NoWasNo #3No #3No #3No #3No #3
10.1.0(#4)Yes #6YesYesESWasWas #2No #3No #3No #3No #3No #3
9.2.0ES #5ES #5ESESWasWasNoNoWasNoNo #1
9.0.1NoNoWasWasWasWasWasNoWasNoWas
8.1.7NoWasWasWasWasWasWasWasWasWasWas
8.1.6NoNoNoNoWasWasWasWasWasWasWas
8.1.5NoNoNoNoNoWasWasWasWasWasWas
8.0.6NoNoNoWasWasWasWasWasWasWasWas
8.0.5NoNoNoNoNoWasWasWasWasWasWas
7.3.4NoNoNoWasWasWasWasWasWasWasWas

Key:
YesSupported
ESSupported but fixes only possible for customers with Extended Support .
WasWas a supported combination but one of the releases is no longer covered by any of Premier Support , Primary Error Correct support , Extended Support nor Extended Maintenance Support so fixes are no longer possible.
NoHas never been Supported
Specific Notes:
  • #1 - See Note 207319.1
  • #2 - An ORA-3134 error is incorrectly reported if a 10g client tries to connect to an 8.1.7.3 or lower server. See Note 3437884.8 .
  • #3 - An ORA-3134 error is correctly reported when attempting to connect to this version.
  • #4 - There are problems connecting from a 10g client to 8i/9i where one is EBCDIC based. See Note 3564573.8
  • #5 - For connections between 10.2 (or higher) and 9.2 the 9.2 end MUST be at 9.2.0.4 or higher. Connections between 10.2 (or higher) and 9.2.0.1, 9.2.0.2 or 9.2.0.3 are not supported.
  • #6 - For connections between 11.1 (or higher) and 10.1 / 10.2 the 10g end MUST be at 10.1.0.5 / 10.2.0.2 (or higher) respectively in order to use PLSQL between those versions. See Note 4511371.8 for more details.
General Notes:
  1. For database links between different Oracle versions connections must be supported in BOTH directions in the matrix above.
    eg: As 9.2 -> 7.3.4 is not supported then database links between these version are notsupported in either direction.
  2. Unsupported combinations may appear to work but can encounter errors for particular operations. The fact that they appear to work should not be relied upon - issues on unsupported combinations will not be investigated.
  3. Since new database servers are compatible with a limited set of older OCI clients, it may not be necessary to upgrade the client software when upgrading the database. However, some new features may not work without upgrading the client software. So, for example, an Oracle 7.3.4 client is able to connect to an Oracle8i database, but is not able to take advantage of newer features such as Transparent Application Failover (introduced in v8).
  4. Oracle Applications , or other Oracle products, may have supported configurations not listed in the matrix above.
  5. The matrix above also applies between different platforms and between 32/64 bit releases of Oracle client / server except where any Oracle platform desupport notice indicates otherwise .
  6. Unix BEQUEATH (BEQ) connections are NOT supported between different releases. eg: Client 9.2.0 is not supported to make an Oracle Net connection to a 10.1.0 server using the BEQ protocol adapter regardless of the interoperability support listed above. SeeNote 364252.1 for more details.

728x90
728x90

Changing the Listener Port Number for Database Connection Requests

If you change the listener port number for database connection requests, you must ensure that all future database connection requests use the new port number. This means that connection requests such as those discussed in"Connecting Remotely with SQL Command Line" must explicitly include the port number.

For example, if you change the port number for database connection requests to 1522, subsequent SQL Command Line (SQL*Plus) connect statements must be similar to the following (assuming a connection from Oracle Database Express Edition Client):

connect system/mypassword@myhost.mydomain.com:1522

Example: Changing Listener Port Number for Database Connection Requests

Assume that your Oracle Database XE host computer is named myhost.mydomain.com and that you want to install a new software package on this computer that requires TCP port number 1521. Assume also that the port number for that software package cannot be configured, and that you must therefore resolve the port number conflict by reconfiguring Oracle Database XE. You decide to change the listener port number for database connection requests to 1522.

To change the listener port number for database connection requests to 1522:

  1. Stop the listener.

    See "Stopping and Starting the Listener" for instructions.

  2. Open the fillistener.ora with a text editor.

    Table 4-3 shows the location of this file on each platform.

    Table 4-3 Location of the listener.ora File

    PlatformLocation

    Linux

    /usr/lib/oracle/xe/app/oracle/product/10.2.0/server/network/admin/

    Windows

    c:\oraclexe\app\oracle\product\10.2.0\server\NETWORK\ADMIN\


  3. Locate the following section of the file:

    LISTENER =
      (DESCRIPTION_LIST =
        (DESCRIPTION =
          (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
          (ADDRESS = (PROTOCOL = TCP)(HOST = myhost)(PORT = 1521))
        )
      )
    

    Note that the line indicated in bold may or may not be present in the file.

  4. Change the text (PORT = 1521) to (PORT = 1522).

  5. Save the modified listener.ora file.

  6. Start the listener.

    See "Stopping and Starting the Listener" for instructions.

  7. Start SQL Command Line and connect to the database as user SYSTEM.

    See "Connecting Locally with SQL Command Line" for instructions. You must supply the SYSTEM password. You set this password upon installation (Windows) or configuration (Linux) of Oracle Database XE.

  8. Enter the following two commands:

    ALTER SYSTEM SET LOCAL_LISTENER = "(ADDRESS=(PROTOCOL=TCP)(HOST=myhost.mydomain.com)(PORT=1522))";
    ALTER SYSTEM REGISTER;
    
  9. Exit SQL Command Line and run the lsnrctl status command to verify the port number change.

    The new port number should be displayed in the Listening Endpoints Summary section of the status report, and the report should include the following lines:

    Service "XE" has 1 instance(s).  Instance "XE", status READY, has 1 handler(s) for this service...

    reference : http://download.oracle.com/docs/cd/B25329_01/doc/admin.102/b25107/network.htm#BHCCDEIH

728x90
728x90

db가 생성된 후에는,  startup upgrade후에 다음과 같은 작업을 해야합니다.

디비의 버전을 업그레이드 했지만, 이미 만들어진 객체들, 테이블, 패키지등은 아직 구버전 그대로 이기때문에,

테이블, 패키지등을 새로운 버전으로 업그레이드 하는 작업이 필요한데,  이것이  아래의 작업입니다.

 

사실은, 디비가 생성된 후에 패치 하지 마시고,  가능하면 디비 엔진만 설치 된 후에 패치하고,

그리고 디비 생성하는것이좋습니다.    그러면 아래같은 작업을 하지 않아도 됩니다.

 

아래와 같이 작업해도,  시간이 많이 걸리고, 진행이 안되고 멈추는 경우도 있었습니다. 

디비가 운영중일때는, 이런 패치작업은가능하면 안하는 것이 좋고, 

하더라도 디비 모든 내용(디비엔진, 데이터파일등 몽땅)을 다른곳에 백업을 받아놓고 하는것이 안전합니다. 

 

( 아래 내용은 패치안에 포함된 readme.html에 있는 내용을 편집한것입니다. 

  자세한 것은 readme.html을 참조하시기 바래요.)

Note:

If you do not run the catupgrd.sql script as described in this section and you start up a database for normal operation, then ORA-01092: ORACLE instance terminated. Disconnection forcederrors will occur and the error ORA-39700: database must be opened with UPGRADE optionwill be in the alert! log.

  1. Enter the following SQL*Plus commands:

    SQL> STARTUP UPGRADE
    SQL> SPOOL patch.log
    SQL> @?/rdbms/admin/catupgrd.sql  <- 이부분 실행
    SQL> SPOOL OFF
    
  2. Review the patch.log file for errors and inspect the list of components that is displayed at the end of catupgrd.sqlscript.

    This list provides the version and status of each SERVER component in the database.

  3. If necessary, rerun the catupgrd.sql script after correcting any problems.

  4. Restart the database:

    SQL> SHUTDOWN IMMEDIATE
    SQL> STARTUP
    
    1. Run the utlrp.sql script to recompile all invalid PL/SQL packages now instead of when the packages are accessed for the first time. This step is optional but recommended.
    2. SQL> @?/rdbms/admin/utlrp.sql <-이부분 실행
      
    1. Note:
    When the 10.2.0.4 patch set is applied to an Oracle Database 10g Standard Edition database, there may be 54 invalid objects after the utlrp.sql script runs. These objects belong to the unsupported components and do not affect the database operation.

    Ignore any messages indicating that the database contains invalid recycle bin objects similar to the following:

    BIN$4lzljWIt9gfgMFeM2hVSoA==$0

    1. Run the following command to check the status of all the components after the upgrade:

      SQL> select comp_name, version, status from sys.dba_registry;
      

      In the output of the preceding command, the status of all the components should be VALID for a successful upgrade.

    728x90

    + Recent posts