Oracle 12c RMAN의 new feature 중 하나인 table recovery 

아래 table recovery 방법을 보니 AUXILIARY Database를 만들어 거기서 dump datafile을 뽑아내는 모양새. 


과거에 삭제된 table 복구를 위해 수행되었던 복구 절차를 명령어 한줄로 만들어 놓았네요. ㅎ


Recover the tables EMP and DEPT using the following clauses in the RECOVER command: DATAPUMP DESTINATION, DUMP FILE, REMAP TABLE, and NOTABLEIMPORT.


The following RECOVER command recovers the EMP and DEPT tables.


RECOVER TABLE SCOTT.EMP, SCOTT.DEPT

    UNTIL TIME 'SYSDATE-1'

    AUXILIARY DESTINATION '/tmp/oracle/recover'

    DATAPUMP DESTINATION '/tmp/recover/dumpfiles'

    DUMP FILE 'emp_dept_exp_dump.dat'

    NOTABLEIMPORT;


참고 : http://docs.oracle.com/cd/E16655_01/backup.121/e17630/rcmresind.htm#BRADV703



oracle blog(?)에 oracle 11g로 upgrade해야할 이유 6개가 나왔네요. 

오라클 support 기간 종료, security 문제에 대한 fix, 그리고 new feature의 이점들.. 
뭐 훌륭한 feature 들이 많은건 일단 인정.. 
그래도 가장 큰 이유는 support 기간 종료가 아닐까.. 싶네요. 

#1: Oracle support period will end soon or has ended.

#2: The application provider is pushing you to uprgade.

#3: CPU or PSUs - security fixes.

#4: Potential cost savings part 1.

#5: Potential cost savings part 2.

#6: Faster access to LOB data - move to Secure Files.


출처 : Why upgrade?


블로그 구경다니다가 11g에서 쓸만한 hint 하나 확인해서 공유합니다. 
구구절절한 설명 보다 아래의 예를 보는게 가장 이해하기 쉽겠네요. 


However, Oracle11g allows us to use the IGNORE_ROW_ON_DUPKEY_INDEX hint, which will silently deal with the unique constraint violation errors by simply ignoring and not inserting any row in which the unique values already exist in the table.



SQL> insert into radiohead select rownum, 'OK COMPUTER' from dual connect by level <= 12;
insert into radiohead select rownum, 'OK COMPUTER' from dual connect by level <= 12
*
ERROR at line 1:
ORA-00001: unique constraint (BOWIE.RADIOHEAD_PK_I) violated

SQL> insert /*+ ignore_row_on_dupkey_index(radiohead,radiohead_pk_i) */ into radiohead select rownum, 
'OK COMPUTER' from dual connect by level <= 12;
2 rows created.

SQL> commit;
Commit complete.

위의 예를 보면 알겠지만 unique key 값이 없는 row에 대해서만 insert가 발생합니다. 에러는 생략되고요.. 
즉 새로 입력되는 값이 기존의 unique 값과 constraint violation이 발생한다면 무시되는 거죠.. 

이 hint는 update에는 사용할 수 없습니다. 또 parallel DML과 APPEND mode일 경우에는 무시됩니다. 
몇몇 요구사항에 맞지 않는다면 ORA-38912, ORA-38915, ORA-38913이 발생합니다. 

자세한 내용은 아래 메뉴얼에서...

interval partition을 drop할 때 ORA-14758 에러가 발생하는 군요. 
메세지로만 봐서는 마지막 partition은 drop될 수 없다라는데...
분명 마지막 range의 partition도 아니고.

아래 노트를 보면 명확히 설명되어 있네요. 
마지막 partition이라는 게 처음 table을 생성할 때 만들어진 마지막 partition이며 
이후 DB에서 자동으로 interval partition을 만들때 이 partition을 참조하기 때문에 삭제하면 안된답니다. 

그럼 처음 interval partition을 만들때 마지막 partition은 안지워지니까 
주기적인 데이터 삭제용도로 사용하시려면 마지막 partition의 range에 대해 고려를 좀 해보셔야 겠죠? 

ORA-14758: Last Partition In The Range Section Cannot Be Dropped (Doc ID 882681.1)

Symptoms

You drop a partition and receive the following error:
ORA-14758: Last partition in the range section cannot be dropped

Cause

In case of interval partitioning the partitions which are created automatically depends on the last partition created as a reference while creating a table. So the last partition can not be dropped.

Example:

create table test.orders
(order_id number(12),
order_date date
)
partition by range(order_date)
interval(numtoyminterval(1, 'month'))
(partition p1 values less than (to_date('2000-01-01', 'YYYY-MM-DD')),
partition p2 values less than (to_date('2000-04-01', 'YYYY-MM-DD')),
partition p3 values less than (to_date('2000-07-01', 'YYYY-MM-DD')));

insert into test.orders values(1, to_date('2000-02-15', 'YYYY-MM-DD')) ;
insert into test.orders values(1, to_date('2000-03-15', 'YYYY-MM-DD')) ;
insert into test.orders values(1, to_date('2000-05-15', 'YYYY-MM-DD')) ;
insert into test.orders values(1, to_date('2000-06-15', 'YYYY-MM-DD')) ;
insert into test.orders values(1, to_date('2000-08-15', 'YYYY-MM-DD')) ;
insert into test.orders values(1, to_date('2000-09-15', 'YYYY-MM-DD')) ;

commit;

SQL> select table_name,partition_name,high_value from dba_tab_partitions where table_name='ORDERS';

TABLE_NAME PARTITION_NAME HIGH_VALUE
------------------------------ ------------------------------ --------------------------------------------------------------------------------
ORDERS P1 TO_DATE(' 2000-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
ORDERS P2 TO_DATE(' 2000-04-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
ORDERS P3 TO_DATE(' 2000-07-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
ORDERS SYS_P115 TO_DATE(' 2000-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA
ORDERS SYS_P116 TO_DATE(' 2000-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIA

SQL> alter table test.orders drop partition SYS_P116;

Table altered.

SQL> alter table test.orders drop partition P2;

Table altered.

SQL> alter table test.orders drop partition P3;
alter table test.orders drop partition P3
*
ERROR at line 1:
ORA-14758: Last partition in the range section cannot be dropped

Solution

This is expected behaviour.
Do not drop the last partition on which the interval partitions are based.

오류에 대해 좀 찾아 보니 interval을 임시로 바꿔 지우는 방법이 나와 있습니다. 
하지만 오라클쪽 자료(metalink)에는 그런 내용은 없는 것 같습니다. 
요 방법 써도 괜찮을라나? 


10. 8. 16 작성자: April C Sims의 Oracle High Availability

New error logging facility in 11g…spool errors from a table that traps them. Table is automatically created after using the SET command in SQLPLUS.

Data stored in the sperrorlog persists between sessions and whether it is interactive or non-interactive such as a script.

Should you turn on errorlogging for SYS?  Sort of a catchall auditing for errors not ordinarily trapped? I am turning on sperrorlog for SYS in a non-production 11gR2 database to see what happens.

New 11g SQLPLUS Parameter ERRORLOGGING [ID 471066.1]


11g에서는 sqlplus에서 발생하는 에러를 logging 할 수 있다는 군요. 
(이 사람들은 새로운 버전 나올때 마다 모든 메뉴얼을 다 보는 것일까요? 존경스럽습니다.. )

위의 내용보고 따라해 봤습니다..

$ sqlplus system
SQL> set errorlogging on
SQL> select * from sperrorlog;

no rows selected

SQL> select * from scott.emp;
select * from scott.emp
                    *
ERROR at line 1:
ORA-00942: table or view does not exist

SQL> set pagesize 200
SQL> select * from sperrorlog;

USERNAME
--------------------------------------------------------------------------------
TIMESTAMP
---------------------------------------------------------------------------
SCRIPT
--------------------------------------------------------------------------------
IDENTIFIER
--------------------------------------------------------------------------------
MESSAGE
--------------------------------------------------------------------------------
STATEMENT
--------------------------------------------------------------------------------
SYSTEM
2010-09-17-13.53.55.000000


ORA-00942: table or view does not exist
select * from scott.emp

잘 되는 군요..
sqlplus를 재 접속해도 위의 에러정보는 계속 남습니다. 

그러면 purge는 어떻게 할까요? 
따로 나와있는 내용이 없는 거 같으니, 아마 delete나 truncate로 해야하는 거 같긴한데..
요건 좀 나중에 확인해 보고..

user가 table을 만들고 이걸 지정할 수 도 있답니다. 

SQL>  SET ERRORLOGGING ON TABLE enduser_sperrorlog;

위의 블로그 한번 들러 보시지요~ ^^


We promised in an earlier post to cover some of the questions from the Optimizer round table discussion at Oracle Open World. Here's our first in a series of posts that will address these questions. 

Q: When moving from 10g to 11g, should hints in existing SQL be removed? 

A: I was glad to see this question at the round table, since I think this is something people often overlook when adding hints to an application. Over time, hints can become stale. You may have added a hint to a query because of a weakness in an old version of the optimizer, but the hint might no longer be necessary to get the best plan. Even worse, the hint may force a plan which is suboptimal, for a couple of reasons:

이 질문은 오라클 데이터베이스 관계자라면 매우 자주 듣는 질문이죠. 
이전 버전의 SQL에 적용된 hint를 제거하는게 맞을까요? 아님 계속 사용하는게 맞을까요? 
물론 답은 당연히 제거하라 겠죠? 

새로운 버전에서, 그리고 변경되는 데이터 상에서 해당 hint가 적정할지,
또 hint를 사용한 사람이 선택한 plan이 과연 적정할지.. 
그 hint는 새로운 버전에서 계속 존재하는지..
이러한 판단이 가능한 사람이 있을까 모르겠네요.. 

위의 포스트는 오라클 optimizer 팀 blog의 post 입니다. open world에서 질문 나온걸 정리한다네요. 
한번 읽어 보세요 ~
baseline을 이용한 plan 고정하는 방법도 나오네요..

그나저나 _optimizer_ignore_hints parameter는 언제 생긴걸까? 
이거 쓸만할 거 같은데, 확인 좀 해 봐야겠네요~


* 여기저기서 좋다는 책 몇권 추천합니다. 고수가 되는 그날까지.. 파이팅!!



+ INVISIBLE index 생성 
SQL> create index emp_idx01 on emp(empno) invisible;

Index created.

+ 일반 세션에서 SQL 수행 
SQL> set autot on exp
SQL> 
SQL> select empno from emp where empno = 7839;

     EMPNO
----------
      7839

Execution Plan
----------------------------------------------------------
Plan hash value: 2872589290

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     4 |    12   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |     1 |     4 |    12   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("EMPNO"=7839)

+ INVISIBLE INDEX 사용 정의
SQL> alter session set optimizer_use_invisible_indexes=true;

Session altered.

SQL> select empno from emp where empno = 7839;

     EMPNO
----------
      7839


Execution Plan
----------------------------------------------------------
Plan hash value: 3956893595

------------------------------------------------------------------------------
| Id  | Operation        | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------
|   0 | SELECT STATEMENT |           |     1 |     4 |     1   (0)| 00:00:01 |
|*  1 |  INDEX RANGE SCAN| EMP_IDX01 |     1 |     4 |     1   (0)| 00:00:01 |
------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("EMPNO"=7839)

+ INVISIBLE INDEX 사용 해제
SQL> alter session set optimizer_use_invisible_indexes=false;

Session altered.

SQL> select empno from emp where empno = 7839;

     EMPNO
----------
      7839


Execution Plan
----------------------------------------------------------
Plan hash value: 2872589290

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     4 |    12   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |     1 |     4 |    12   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("EMPNO"=7839)

+ OPT_PARAM hint를 통한 INVISIBLE index 사용 권한 부여 -> 실패 ?
SQL> select /*+ opt_param('optimizer_use_invisible_indexes','true') */ empno from emp where empno = 7839;

     EMPNO
----------
      7839


Execution Plan
----------------------------------------------------------
Plan hash value: 2872589290

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |     4 |    12   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| EMP  |     1 |     4 |    12   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("EMPNO"=7839)

CROSS JOIN/ Cartesian Products

 - Cartesian product 값을 얻을때 사용 합니다. 
 - 즉 join을 통해 생성가능한 모든 row를 return 합니다. 

SQL>SELECT ename FROM emp CROSS JOIN dept;
SQL>SELECT ename FROM emp, dept;

참고: CROSS가 생략되어 INNER join으로 수행되는 경우(join condition이 없는 경우) 나 CROSS join에서 join condition이 기술된 경우 에러발생합니다. 

SQL>SELECT e.lname, d.name FROM employee e JOIN department d;
ORA-00905: missing keyword

SQL>SELECT e.lname, d.name FROM employee e CROSS JOIN department d ON e.dept_id = d.dept_id;
ORA-00933: SQL command not properly ended


INNER JOIN 

 - 일반 조인시 Table간의 ','를 생략하고 'INNER JOIN'을 추가하고 WHERE절대신 ON절을 사용해야 합니다.
 - INNER는 생략 가능합니다.

SQL>SELECT e.empno, e.ename FROM dept d INNER JOIN emp e ON d.deptno=e.deptno;
SQL>SELECT e.empno, e.ename FROM dept d , emp e WHERE d.deptno=e.deptno;

EQUI-JOIN/ NON-EQUI-JOIN 
 - Join condition에 equal operation(=)을 사용하는 JOIN 
 - Join condition에 equal operation 외의 다른 operation을 사용하는 JOIN

SQL> SELECT s.name supplier_name, p.name part_name FROM supplier s JOIN part p ON s.supplier_id = p.supplier_id;
SQL> SELECT p.name part_name, c.inv_class inv_class FROM part p JOIN inventory_class c ON p.unit_cost BETWEEN c.low_cost AND c.high_cost;

SELF JOIN
 - 동일 TABLE에 대한 JOIN

SQL> SELECT e.lname employee, m.lname manager FROM employee e JOIN employee m ON e.manager_emp_id = m.emp_id;

OUTER JOIN 

 - Join시 특정 table의 join 조건에 일치하지 않은 row를 추가할때 사용해야 합니다.
 - { LEFT | RIGHT | FULL } [OUTER]

SQL>SELECT e.empno, e.ename FROM dept d LEFT OUTER JOIN emp e ON d.deptno=e.deptno;
SQL>SELECT e.empno, e.ename FROM dept d , emp e WHERE d.deptno=e.deptno(+);

SQL>SELECT e.empno, e.ename FROM dept d RIGHT OUTER JOIN emp e ON d.deptno=e.deptno;
SQL>SELECT e.empno, e.ename FROM dept d , emp e WHERE d.deptno(+)=e.deptno;

SQL>SELECT e.empno, e.ename FROM dept d FULL OUTER JOIN emp e ON d.deptno=e.deptno;

참고: full outer join의 비밀 [Science of DataBase]


PARTITION OUTER JOIN 

 - PARTITION OUTER JOIN을 사용하여 분석 대상이 되는 디멘션의 densification을 수행할 수 있으며, 
 - 파티션이나 테이블 내부에서 OUTER JOIN을 적용할 수 있습니다.

select hiredate,d.dname,  nvl(sum_sal,0) sum_sal
from dept d
left outer join (select deptno,to_char(hiredate,'YYYY') hiredate, sum(sal) sum_sal from emp group by deptno,to_char(hiredate,'YYYY')) e
partition by (e.hiredate)
on d.deptno = e.deptno
order by 1,2
/

HIREDATE     DNAME                                         SUM_SAL
------------ ------------------------------------------ ----------
1980         ACCOUNTING                                          0
1980         OPERATIONS                                          0
1980         RESEARCH                                          800
1980         SALES                                               0
1981         ACCOUNTING                                       7450
1981         OPERATIONS                                          0
1981         RESEARCH                                         5975
1981         SALES                                            9400
1982         ACCOUNTING                                       1300
1982         OPERATIONS                                          0
1982         RESEARCH                                         3000
1982         SALES                                               0
1983         ACCOUNTING                                          0
1983         OPERATIONS                                          0
1983         RESEARCH                                         1100
1983         SALES                                               0



NATURAL JOIN 

 - Equijoin과 동일하다고 보시면 됩니다.
 - 두 테이블의 동일한 이름을 가지는 칼럼은 모두 조인이 됩니다. (oracle forum : HR유저에서 NATURAL JOIN 결과가 다릅니다 )
 - 동일한 컬럼을 내부적으로 찾게 되므로 테이블 Alias를 주면 오류가 발생 합니다. 
    (ORA-25155: column used in NATURAL join cannot have qualifier)
 - 동일한 컬럼이 두개 이상일 경우 JOIN~USING문장으로 조인되는 컬럼을 제어 할 수 있습니다.
 
SQL>SELECT empno, ename, deptno FROM emp NATURAL JOIN dept 
SQL>SELECT e.empno, e.ename, d.deptno FROM emp e, dept d WHERE e.deptno=d.deptno


JOIN ~ USING 

 - NATURAL JOIN의 단점은 동일한 이름을 가지는 칼럼은 모두 조인이 되었는데 USING 문을 사용하면 컬럼을 선택해서 조인을 할 수가 있습니다.
 - USING절 안에 포함되는 컬럼에 Alias를 지정하면 오류가 발생 합니다.
  
SQL>SELECT e.empno, e.ename, deptno FROM emp e JOIN dept d USING(deptno)


ON 구문

 - 조인 조건을 지정 할 수 있습니다. 
 - 모든 논리 연산 및 서브쿼리를 지정할 수 있습니다.

SQL>SELECT e.empno, e.ename, e.sal
       FROM emp e JOIN dept    d  ON (e.deptno=d.deptno)
                           JOIN bonus  b ON (b.ename = e.ename)
       WHERE e.sal IS NOT NULL




* 여기저기서 좋다는 책 몇권 추천합니다. 고수가 되는 그날까지.. 파이팅!!



Oracle 11gR2에 새로 추가된 기능인 SCAN에 대해 간단히 정리합니다.. (까먹기 전에 --;)

Oracle은 새로운 버전이 나올때 마다 새로운 기능들을 추가하는데, 이번에 소개드릴 기능은 SCAN (Single Client Access Name) 입니다. 말 그대로 client에서 server를 접속할 때 여러개의 RAC 노드가 있더라도 하나의 access name을 갖도록 하는 기능입니다. 이 기능은 새로운 노드가 추가되거나 삭제되는 경우에도 적용되며, 사실 이것을 염두에 두고 있습니다. 

새로운 노드의 추가와 삭제와 상관없는 single client access name 이라..
딱 클라우드 컴퓨팅ㄱ이라는 단어가 생각나지 않습니다? 

아래의 tns alias 설정은 SCAN 기능을 사용할 경우 client의 tns alias 설정 sample 입니다. 
언듯보면.. 자세히 봐도 single DB 접속하는 tns alias와 동일합니다. 

TEST.ORACLE.COM =
(DESCRIPTION=
(ADDRESS=(PROTOCOL=tcp)(HOST=SCAN-TEST.ORACLE.COM)(PORT=1521))
(CONNECT_DATA=(SERVICE_NAME=11GR2TEST.ORACLE.COM))
)

이전의 RAC에서의 tns alias는 아래와 같이 설정했었습니다. 

TEST.ORACLE.COM =
(DESCRIPTION=
(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=tcp)(HOST=TEST1-vip.ORACLE.COM)(PORT=1521))
(ADDRESS=(PROTOCOL=tcp)(HOST=TEST2-vip.ORACLE.COM)(PORT=1521))
)
(CONNECT_DATA=(SERVICE_NAME=11GR2TEST.ORACLE.COM))


그럼 어떻게 노드의 추가/삭제에도 동일한 access name을 가질 수 있을까요?
각 노드의 listener 앞에 새로운 listener를 두는 겁니다. 이 앞단의 listener들이 뒤의 RAC listener를 보게 됩니다.



11gR2 Grid Infrastructure Single Client Access Name (SCAN) Explained

SCAN Concepts

  • Single client access name (SCAN) is the virtual hostname to provide for all clients connecting to the cluster (as opposed to the vip hostnames in 10g and 11gR1).  
  • SCAN is a domain name registered to at least one and up to three IP addresses, either in the domain name service (DNS) or the Grid Naming Service (GNS).
  • By default, the name used as the SCAN is also the name of the cluster and must be globally unique throughout your enterprise. The default value for the SCAN is based on the local node name. SCAN name must be at least one character long and no more than 15 characters in length, must be alphanumeric - cannot begin with a numeral and may contain hyphens (-). If you require a SCAN that is longer than 15 characters, then select an Advanced installation.
  • For installation to succeed, the SCAN must resolve to at least one address.
  • SCAN VIP addresses must be on the same subnet as virtual IP addresses and public IP addresses.
  • Oracle strongly recommends that you do not configure SCAN VIP addresses in the hosts file. If you use the hosts file to resolve SCANs, then you will only be able to resolve to one IP address and you will have only one SCAN address - be sure to provide a hosts file entry for each SCAN address in hosts file in same order.
  • If hosts file is used to resolve SCAN hostname, you will receive Cluster Verification Utility failure at end of installation (see Note: 887471.1 for more details)
  • For high availability and scalability, Oracle recommends that you configure the SCAN to use DNS Round Robin resolution to three addresses.
  • Because the SCAN is associated with the cluster as a whole, rather than to a particular node, the SCAN makes it possible to add or remove nodes from the cluster without needing to reconfigure clients. It also adds location independence for the databases, so that client configuration does not have to depend on which nodes are running a particular database.
  • Clients can continue to access the cluster in the same way as with previous releases, but Oracle recommends that clients accessing the cluster use the SCAN. Clients using the SCAN can also access the cluster using EZCONNECT.
  • Grid Infrastructure will start local listener LISTENER on all nodes to listen on local VIP, and SCAN listener LISTENER_SCAN1 (up to three cluster wide) to listen on SCAN VIP(s); 11gR2 database by default will set local_listener to local LISTENER, and remote_listener to SCAN listener.

위의 SCAN에 대한 concept을 정리해보자면 RAC에 대한 virtual hostname 입니다. 이는 DNS에 설정되어 있고 이를 통해 DB에 접속하게 됩니다. failover나 load-balancing은 RAC 각 노드의 listener 들이 담당하게 됩니다.

이 내용은 "Note:887522.1 - 11gR2 Grid Infrastructure Single Client Access Name (SCAN) Explained" 를 참조했습니다

관련 문서와 동영상을 같이 링크 겁니다.  아직 한글로 소개된 자료는 없는 것 같네요.. 

[PDF] 

SINGLE CLIENT ACCESS NAME (SCAN)

 - [ 이 페이지 번역하기 ]
파일 형식: PDF/Adobe Acrobat - 빠른 보기
29 Mar 2010 ... Single Client Access Name (SCAN) is s a new Oracle Real Application Clusters (RAC)11g Release 2 feature that provides ...
www.oracle.com/technology/products/database/.../scan.pdf - 유사한 페이지






* 여기저기서 좋다는 책 몇권 추천합니다. 고수가 되는 그날까지.. 파이팅!!


 
오라클은 사용자 작업을 위해 많은 Package/Fuction 등 을 지원합니다. 
이런 놈들을 다 알필요는 없지만 아는 많큼 손발이 고생할 여지가 조금씩 줄어 듭니다. 그러니 기회가 있을 때마다 조금씩 알아 놓는게 좋겠죠 ^^;
얼마전 작업하다기 DBMS_SHARED_POOL.PURGE procedure를 유용하게 사용할 수 있는 기회가 있었어 간략하게 정리합니다. 
 
주말의 몇몇 table의 re-org 작업이 있었는데, 
시간 계산을 잘못해서 마지막 즈음에 기다리던 작업자를 위해 사용자 세션을 풀어 주었습니다. 주말이라 얼마나 들어오겠나 싶었죠.. 
많은 세션들이 들어오진 않았지만, 몇몇 세션들이 주로 수행되는 SQL을 이것 저것 수행하고 나갔습니다. 
 
근데 작업 전보다 성능이 않좋다고 하더군요. 
지금 re-org 작업이 있으니 조금 느릴 수도 있겠다 싶었죠. 근데, 작업 후에도 느리다고 하더군요. 
Plan이 바뀌었습니다. 통계정보도 같이 넣어 주었는데 말이죠.. 
 
import로 data를 loading 하면 마지막에 해당 segment의 통계정보를 같이 적제하게 됩니다. 근데 통계정보가 다 들어가기 전에 수행된 SQL은 통계정보가 없는 상태에서 cost를 계산해서 sql plan을 만들어 버리죠. 또 이렇게 만들어진 plan 정보는 해당 cursor가 purge 되기 전까지는 계속 사용하게 됩니다. 
 
이러한 비슷한 경우는 bind peeking 기능에 의해 일반적이지 않은 bind 값이 들어가도 발생할 수가 있습니다. 
 
이러한 경우 shared pool flush를 시켜 해당 cursor를 purge 시킬 수 도 있겠지만 11g 이후 부터는 단일 cursor 별로 purge가 가능합니다. 10.2.0.4 version에서도 사용가능한데, 이 버전의 경우 event 설정이 필요합니다. 
 
event="5614566 trace name context forever"
다음의 내용은 참조 노트의 사용 방법에 대한 간단한 예 입니다. 
 
SESSION 1 
 
sqlplus scott/tiger 
SQL> select ename from emp where empno=7900;
 
SESSION 2 
 
sqlplus / as sysdba 
 
SQL> select address, hash_value, executions, loads, version_count, invalidations, parse_calls 
     from v$sqlarea 
     where sql_text = 'select ename from emp where empno=7900';
 
ADDRESS          HASH_VALUE EXECUTIONS      LOADS VERSION_COUNT INVALIDATIONS PARSE_CALLS 
---------------- ---------- ---------- ---------- ------------- ------------- ----------- 
000000007A6CF430 1052545619          1          1             1             0           1
 
SQL> exec dbms_shared_pool.purge ('000000007A6CF430,1052545619 ','C'); 
 
SQL> select address, hash_value, executions, loads, version_count, invalidations, parse_calls 
     from v$sqlarea 
     where sql_text = 'select ename from emp where empno=7900';
 
no rows selected
 
 
이 내용은 아래의 문서를 참조했습니다. 
 
Note 457309.1 How To Flush an Object out the Library Cache 
Note 751876.1 DBMS_SHARED_POOL.PURGE Is Not Working On 10.2.0.4
 

Faster Startup


The days when dinosaurs ruled the earth and 2GB memory was considered large are gone. Now, it's not uncommon to see large buffer caches to the tune of 100GB. When the instance is started, it might take several minutes, or even hours, to initialize a buffer cache of this size.

If you look deeper into the situation, you will notice that the entire buffer cache need not be up when the database instance starts. After the instance starts, the buffer cache is empty, which gradually fills up when users select data from tables. So, there is no need to initialize the entire buffer cache when the instance starts.

In Oracle Database 10g Release 2, this behavior is accounted for in the startup logic. When you start the instance, only 10% of the buffer cache is initialized; the rest is initialized after the database is opened by the checkpoint process. This new approach reduces instance startup time significantly.

Bear in mind, however, that until the entire buffer cache is initialized, automatic buffer cache sizing is not available.

아시다 시피 SGA memory 영역은 Database가 nomount 단계에서 할당됩니다. 
이 new feature는 nomount 단계에서는 10%의 buffer pool만 할당하고 나머지는 instance가 open 된 후에 할당한다는 의미입니다.


Drop Empty Datafiles


Imagine that you just added a datafile to the wrong directory or tablespace—a fairly common error. All is not lost; the datafile doesn't contain any data yet, so you can easily drop it, right?

Unfortunately, you can't. Prior to Oracle Database 10g Release 2, your only clean option for removing a datafile is to drop the entire tablespace and then rebuild it without that particular file. If the tablespace contains data, you have to go through the time-consuming and laborious process of storing the data on a separate location and reinstating it. In addition to its inconvenience, this process makes the tablespace unavailable.

Thankfully, in Oracle Database 10g Release 2 the process has been simplified: You can just drop the datafile. For example, the following command will remove the indicated datafile from the tablespace as well as from the server.
alter tablespace users drop datafile '/tmp/users01.dbf'
 /
There are a couple restrictions, however: The datafile must be empty to be dropped. You can't drop the last datafile in a tablespace; the tablespace itself must be dropped. And the tablespace must be online and in read-write status.

10g 이전 버전에서는 데이터파일을 잘 못 붙일 경우 이거 띄어 내려면 tablespace 전체를 재구성해야 하죠. 
예전 OPS 쓸때 raw device가 아닌 filesystem에 datafile을 추가하는 등의 황당한 경우도 있었습니다.. ㅋ
drop empty datafiles new feature는 이런 유저 실수로 인한 막대한 작업을 더이상 안해도 되게 해주겠군요. 


Catch the Error and Move On: Error Logging Clause


Suppose you are trying to insert the records of the table ACCOUNTS_NY to the table ACCOUNTS. The table ACCOUNTS has a primary key on ACC_NO column. It's possible that some rows in ACCOUNTS_NY may violate that primary key. Try using a conventional insert statement:
SQL> insert into accounts
  2  select * from accounts_ny;
insert into accounts
*
ERROR at line 1:
ORA-00001: unique constraint (ARUP.PK_ACCOUNTS) violated
None of the records from the table ACCOUNTS_NY has been loaded. Now, try the same with error logging turned on. First, you need to create a table to hold the records rejected by the DML statement. Call that table ERR_ACCOUNTS.
exec dbms_errlog.CREATE_ERROR_LOG ('ACCOUNTS','ERR_ACCOUNTS')
Next, execute the earlier statement with the error-logging clause.
SQL> insert into accounts
  2  select * from accounts_ny
  3  log errors into err_accounts
  4  reject limit 200
  5  /

6 rows created.
Note that the table ACCOUNTS_NY contains 10 rows yet only six rows were inserted; the other four rows were rejected due to some error. To find out what it was, query the ERR_ACCOUNTS table.
SQL> select ORA_ERR_NUMBER$, ORA_ERR_MESG$, ACC_NO
 2  from err_accounts;

ORA_ERR_NUMBER$   ORA_ERR_MESG$                                       ACC_NO
 ---------------  --------------------------------------------------  ------
               1  ORA-00001: unique constraint (ARUP.PK_ACCOUNTS) vi  9997
               olated
               1  ORA-00001: unique constraint (ARUP.PK_ACCOUNTS)vi  9998
               olated
               1  ORA-00001: unique constraint (ARUP.PK_ACCOUNTS) vi 9999
               olated
               1  ORA-00001: unique constraint (ARUP.PK_ACCOUNTS) vi 10000
               olated
Note the columns ORA_ERR_NUMBER$, which show the Oracle error number encountered during the DML statement execution, and the ORA_ERR_MESG$, which shows the error message. In this case you can see that four records were rejected because they violated the primary key constraint PK_ACCOUNTS. The table also captures all the column of table ACCOUNTS, including the column ACC_NO. Looking at the rejected records, note that these account numbers already exist in the table; hence the records were rejected with ORA-00001 error. Without the error-logging clause, the whole statement would have failed, with no records rejected. Through this clause, only the invalid records were rejected; all others were successful.

이 기능은 sql*loader의 bad file 같은 기능입니다. 
특정 에러가 발생해도 이를 logging만 하고 나머지 데이터는 처리를 해주는 군요.  
PK constraint violation 발생하면 이거 처리하는 것도 좀 귀찮은 작업인데, 요 기능 쓰면 약간 편해지겠습니다. ^^

그나 저나 아직도 10g new feature를 모르고 있다니... 좌절이다~



* 여기저기서 좋다는 책 몇권 추천합니다. 고수가 되는 그날까지.. 파이팅!!



11g에서 나온 PIVOT 구문입니다. 
아래 sample 처럼 동일 column 값에 대해 pivot 기능이 적용되어 display 됩니다. 

SQL> select job,deptno,avg(sal) from emp  group by job,deptno;

JOB                             DEPTNO   AVG(SAL)
--------------------------- ---------- ----------
PRESIDENT                           10       5000
MANAGER                             30       2850
CLERK                               30        950
CLERK                               10       1300
MANAGER                             20       2975
ANALYST                             20     6499.5
CLERK                               20        950
SALESMAN                            30       1400
MANAGER                             10       2450


SQL> select * from (select job,deptno,sal from emp) 
pivot (avg(sal) for deptno in (10,20,30)) order by job;

JOB                                 10         20         30
--------------------------- ---------- ---------- ----------
ANALYST                                    6499.5
CLERK                             1300        950        950
MANAGER                           2450       2975       2850
PRESIDENT                         5000
SALESMAN                                                1400


PIVOT 기능은 AWR 데이터를 보기편하게 변형하는 데 유용합니다. 

* 아래 SQL은 노드별 user call 값을 출력해본 간단한 SQL 입니다. 
select * from
(
 select to_char(end_interval_time,'HH24:MI:SS') end_interval_time
       ,a.instance_number,value from dba_hist_sysstat a, dba_hist_snapshot b
 where stat_name in ('user calls')
 and a.snap_id = b.snap_id
 and a.instance_number = b.instance_number
)
pivot (avg(value) for instance_number in (1 as "Node1",2 as "Node2",3 as "Node3"))
order by 1
/

END_INTERV                Node1      Node2      Node3
---------- -------------------- ---------- ----------
00:10:31          1,432,826,125 1278172133 1281672038
00:10:34          1,254,265,411 1153949372 1154503152
00:10:39            233,495,867  223300171  222547544
00:20:01          1,255,123,846 1154019492 1154577807
00:20:02          2,260,343,067 2050291466 2048154492
00:20:08            719,183,716  664321484  663506525
00:20:13            478,942,298  446272763  444528572


* V$SYSSTAT의 특정 statistic 값을 query하는 SQL 
select *
from (select to_char(sysdate,'MMDDHH24MISS') dat, a.name,a.value
        from v$sysstat a 
        where statistic# in (146,9,67,62,72,6,446,447,0,451,5,4)
        )
pivot (sum(value) for name in ('logons cumulative','user rollbacks','user commits','user calls','session logical reads','physical reads','db block changes', 'physical writes','redo size','parse count (total)','parse count (hard)','execute count'))
order by dat
/

* PIVOT을 decode로 바꿔본 SQL (11g 이전 버전)
select to_char(sysdate,'MMDDHH24MISS') dat,
       sum(decode(name,'logons cumulative',value)) "logons cumulative",
       sum(decode(name,'user rollbacks',value)) "user rollbacks",
       sum(decode(name,'user commits',value)) "user commits",
       sum(decode(name,'user calls',value)) "user calls",
       sum(decode(name,'session logical reads',value)) "session logical reads",
       sum(decode(name,'physical reads',value)) "physical reads",
       sum(decode(name,'db block changes',value)) "db block changes",
       sum(decode(name,'physical writes',value)) "physical writes",
       sum(decode(name,'redo size',value)) "redo size",
       sum(decode(name,'parse count (total)',value)) "parse count (total)",
       sum(decode(name,'parse count (hard)',value)) "parse count (hard)",
       sum(decode(name,'execute count',value)) "execute count"
from v$sysstat
where statistic# in (146,9,67,62,72,6,446,447,0,451,5,4)
group by to_char(sysdate,'MMDDHH24MISS')
/
(왠지 좀 무지해 보이는데.. 더 좋은 방법이 있으면 알려주세요 *^^*)


* 여기저기서 좋다는 책 몇권 추천합니다. 고수가 되는 그날까지.. 파이팅!!



Oracle External table은 오라클 외부의 데이터를 내부로 loading해 table 형식으로 보여 줍니다.
Oracle 11g R2에서는 "PREPROCESSOR 절"이 생겨 이 외부 file에 대해 선처리 프로세서를 정의해 줄 수 있습니다.

대부분 외부 SAM file 형식이니 압축해제나 shell을 통한 추출 정도의 선 프로세서를 정의할 수 있겠네요.
잘만 된다면 SAM file 저장하는 공간을 줄일 수 있겠네요.

예 : compress된 데이터를 gunzip을 이용해 압축 해제 후 loading

CREATE TABLE sales_transactions_ext
     (PROD_ID NUMBER, CUST_ID NUMBER, TIME_ID DATE, CHANNEL_ID NUMBER, PROMO_ID NUMBER, QUANTITY_SOLD NUMBER,
      AMOUNT_SOLD NUMBER(10,2), UNIT_COST NUMBER(10,2), UNIT_PRICE NUMBER(10,2))
ORGANIZATION external
 (TYPE oracle_loader DEFAULT DIRECTORY data_file_dir
  ACCESS PARAMETERS
  (RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII
   PREPROCESSOR exec_file_dir:'gunzip' OPTIONS '-c'
   BADFILE log_file_dir:'sh_sales.bad_xt'
   LOGFILE log_file_dir:'sh_sales.log_xt'
   FIELDS TERMINATED BY "|"
   LDRTRIM ( PROD_ID, CUST_ID, TIME_ID DATE(10) "YYYY-MM-DD", CHANNEL_ID, PROMO_ID, QUANTITY_SOLD,
                AMOUNT_SOLD, UNIT_COST, UNIT_PRICE))
location ('sh_sales.dat.gz') )
REJECT LIMIT UNLIMITED;






Oracle INVISIBLE index는 Oracle 11g new feature 입니다.

말 그대로 보이지 않는 index 입니다. 여기서 보는 주체는 oracle optimizer가 됩니다.
즉 index는 존재하지만 optimizer는 이를 기준으로 plan을 생성하지 않습니다.
그러나 해당 index의 table에 대한 DML 변경 내역은 모두 index에 적용되게 됩니다.

이는 index 생성에 따른 혹은 index 삭제에 따른 전체 성능, 일부 성능 측정에 도움이 될 만한 feature가 아닌가 싶습니다.

Invisible index 생성
SQL> Create index invisible_index on table(column) invisible;

Invitible index 사용 정의
SQL> alter session set optimizer_use_invisible_indexes=true;

Invisible index를 visible로 변경
SQL> alter index invisible_index visible;

visible index를 invisible로 변경
SQL> alter index invisible_index invisible;





운영 중 spfile이 유실 되는 경우, 간편하게 recovery 할 수 있는 명령어가 oracle 11g에서 추가되었네요.

뭐 alert log file에 나온 parameter 정보나 show parameter 등으로도 만들 수 있지만 많이 귀찮죠.
(사실 spfile이나 init file 유실되는 건 본적은 없으나...)

create spfile from memory;
create spfile='/u01/oracle/app/oracle/product/11g/dbs/spfile_back.ora' from memory;







전통적인 Oracle 접속 방식인 "Dedicated Server"와 "Shared Server" 방식외에 Oracle 11g에서 DRCP (Database Resident Connection Pooling)라는 접속 방식이 추가 되었습니다.

Database resident connection pooling (DRCP) provides a connection pool in the database server for typical Web application usage scenarios where the application acquires a database connection, works on it for a relatively short duration, and then releases it.

메뉴얼을 보면 각각의 접속 방식에 소모되는 memory를 계산해 놓은 부분이 있는데, 요거 보면 적용할 만 하겠다 싶긴 합니다.

그러나 memory 사용량을 보면 혹할수도 있겠는데, 만약 concurrent가 5000이라고 가정 한다면,
DRCP의 경우는 100개만 접속 해 있고 나머지는 queue에 대기하고 있는 모양이겠죠?

shared server의 경우 100개만 떠있어도 100개의 shared server가 5000개의 세션을 cover 해주고 있으니,
DRCP와 dedicate/ shared server와 비교하는 것 자체가 사실 말이 안될 수 도 있습니다.

memory required for each session is 400 KB and the memory required for each server process is 4 MB. The pool size is 100 and the number of shared servers used is 100. If there are 5000 client connections, the memory used by each configuration is as follows:

 Dedicated Server
 Memory used = 5000 X (400 KB + 4 MB) = 22 GB
 Shared Server
 Memory used = 5000 X 400 KB + 100 X 4 MB = 2.5 GB
 Database Resident Connection Pooling
 Memory used = 100 X (400 KB + 4 MB) + (5000 X 35KB)= 615 MB

설정 방법도 별로 어렵지 않습니다. 서버단에서 process parameter 좀 늘려주고 다음 처럼 수행하고, client 단에서 tnsnaems.ora의 설정 부분에 SERVER를 POOLED라고만 정의하면 되네요. 

DRCP 설정 방법
SQL> exec dbms_connection_pool.configure_pool(maxsize=>10,inactivity_timeout=>60);
SQL> exec sys.dbms_connection_pool.start_pool();

Client 설정
DRCP =
  (DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = sample.com)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVER = POOLED)
      (SERVICE_NAME = orcl.sample.com)
    )
  )

딱히 테스트 해보고 올린 post가 아니니 잘못된 부분이 있으면 가차없이 알려주세요. ^^




OTN 11g new feature 자료입니다.


11g logo

Oracle Database 11g:
The Top New Features for DBAs and Developers

by Arup Nanda Oracle ACE Director

In this multipart series, learn how important new features such as Database Replay, Flashback Data Archive, and SecureFiles work via simple, actionable how-to's and sample code.

Change, although constantly present, is seldom risk-free. Even if the change is relatively minor (creating an index for example), your goal is probably to predict its precise impact as accurately as possible and then take appropriate action

Many new change assurance (or "Real Application Testing," as Oracle calls it) features in Oracle Database 11g bring that dream closer to reality. The Database Replay tool, for example, allows you to capture production database workload and replay it in a test (or even the same) database to assess the impact of change. Or consider SQL Performance Analyzer, which predicts the performance impact of changes to SQL before they are made. In my opinion, this Real Application Testing functionality alone justifies the upgrade.

Overall, Oracle Database 11g makes database infrastructure far more efficient, resilient, and manageable. For example, very compelling new features in the realm of partitioning ease the design and management of partitioned tables immensely.

In this series (as in the previous series focusing on Oracle Database 10g), you will learn how these new features work via simple, actionable how-to's and sample code.

Enjoy the series, and the release!

Download series as PDF (4.35MB zip)

Subscribe to this series via

Database Replay

Explore Database Replay, the new tool that captures SQL statements and lets you replay them at will.

Partitioning

Learn about Referential, Internal, and Virtual Column partitioning; new sub-partitioning options; and more.

Transaction Management

Get an introduction to Flashback Data Archive and explore Enterprise Manager's LogMiner interface.

Schema Management

Add columns with a default value easily and explore invisible indexes, virtual columns, and read only tables.

SQL Plan Management

Use bind variables that pick the right plan every time and ensure a new execution plan is perfect before it's used.

SQL Performance Analyzer

Accurately assess the impact of rewriting of SQL statements and get suggested improvements.

SQL Access Advisor

Get advice about optimal table design based on actual use of the table, not just data.

PL/SQL: Efficient Coding

Triggers that fire several times at different events and ability to force triggers of the same type to follow a sequence are some new gems.

RMAN

Explore Data Recovery Advisor, do parallel backup of the same file, and create and manage virtual catalogs.

Security

Learn about Tablespace Encryption, case-sensitive passwords, data masking, and other features.

Automatic Storage Management

Learn about new SYSASM role, variable extent sizes, and other ASM improvements.

Manageability

Explore automatic memory management, multicolumn statistics, online patching, and more features.

Caching and Pooling

Explore SQL Result Cache, PL/SQL Function Cache, and Database Resident Connection Pooling.

SQL Operations: Pivot and Unpivot

Present information in a spreadsheet-type crosstab report from any relational table using simple SQL, and store any data from a crosstab table to a relational table.

SecureFiles

Explore next-generation LOBs: LOB encryption, compression, deduplication, and asynchronicity.

Resiliency

Explore Automatic Health Monitor, Automatic Diagnostic Repository, and other new resiliency features.

Data Guard

Query the physical standby database in real time without shutting down recovery, just for starters.

PL/SQL Performance

Explore in-lining of code, "real" native compilation, PLS timer, use of simple integer, and more.

Data Warehousing and OLAP

Get a tour of new features in these areas, including Cube Organized MVs.

And Don't Forget...

COPY command, Export/Imports, Data Pump improvements, and more.




+ Recent posts