이런 기능이 있다는 것은 오래 전부터 알고 있었는데,

이해도 안되고 사용할 일도 없을 같아서 잊고 지내다가,

최근에 읽고 있는 책을 통해 필요성을 인식하게 되었습니다.

 

읽고 있는 책이 Oracle9i 기준으로 책이라

original export/import utility 사용한 방법에 대해서 설명되어 있는데,

여기서는 Oracle10g부터 제공되기 시작한 pump export/import utility 사용한 방법도

같이 소개해 보고자 합니다.

 

Oracle10g이상을 사용하고 있음에도 불구하고,

여전히 original export/import utility 단지 익숙하다는 이유로 사용하고 계신 분이 많을텐데,

최근에 등장한 Oracle11gR2에도 original export/import utility 지원되지만,

언젠가는(3,4 정도 같습니다) original utility

pump utility 의해 완전히 대체될 예정이므로,

하루라도 빨리 pump export/import utility 익혀두는 편이 좋습니다.

 

우선 transportable tablespace기능의 장단점에 대해 간단히 소개하고자 합니다.

 

일반적으로 tablespace전체를 <A> database에서 <B> database 복사하는 경우,

<A> 해당 tablespace안에 담겨있는 schemas export ,

<B> datasbase import하는 방식을 사용합니다.

다들 아시다시피 import export 비해 훨씬 많은 시간(5배정도) 걸립니다.

만약 tablespace 20~30GB정도 되는 대용량 tablespace 경우,

import 많은 시간이 걸리게 것입니다.

 

transportable tablespace기능을 사용하게 되면,

tablespace 들어있는 data 넣다/뺐다(export/import) 필요가 없고,

오직 필요한 것은 meta data만을 export/import하면 되기 때문에,

훨씬 시간을 절약할 있습니다.

 

대신, export/import 수행할 경우, data 깨끗하게 들어가게 되므로,

tablespace내에서 발생하고 있던 기존의 fragmentation 해소시킬 있지만,

transportable tablespace기능을 사용할 경우, fragmentation 그대로 남아 있게 됩니다.

 

이제 구체적인 작업을 설명하겠습니다.

 

1.  이동시키고자 하는 tablespace(target database) transportable한지

     체크합니다.

 

SQL> exec dbms_tts.transport_set_check('USERS', true);

PL/SQL procedure successfully completed.

 

SQL> select * from transport_set_violations;

no rows selected

 

     만약 다른 tablespace 참조하는 objects 있거나 하는 경우에는

     (예를 들어 table 여기 있지만 index 다른 tablespace 있거나 하는 경우) ,

     위의 select문의 결과로 표시되게 됩니다.

     operation상의 실수로 인해, 일부 table 다른 tablespace 있거나 하는 경우,

     "alter table <table_name> move tablespace <tablespace_name>" 통해서

     간단히 table 속한 tablespace 변경할 있습니다.

     ( 경우, index invalid상태가 되기 때문에 rebuild해줄 필요가 있음)

 

2.  target database read only mode 변경시킵니다.

 

     read only mode 변경하지 않는 경우,

     "ORA-29335: tablespace 'USERS' is not read only"

     와 같은 error 발생하게 됩니다.

SQL> alter tablespace users read only;

Tablespace altered.

 

 

3.  <A> database상에서 target tablespace meta data만을 export합니다.

 

     (1)  original export 사용하는 경우

 

           ⇒ exp system/**** transport_tablespace=y tablespaces=users file=users.dmp ...

 

     (2)  pump export 사용하는 경우

 

           ⇒ expdp system/**** transport_tablespaces=users dumpfile=users.dmp ...

 

       original export 경우에는 current directory dump file 생성되지만, pump export

          경우에는 지정한 directory object 가리키는 directory 생성됩니다.

          그러므로 directory object 실행 전에 생성해 놓아야 합니다. 위의 경우에는

          directory object 지정하지 않았는데, 그런 경우에는 "data_pump_dir"이라는

          directory object default 사용됩니다.

 

4.  target tablespace 해당하는 datafile <A> host에서 <B> host

     복사합니다.

 

     저의 경우, <B> host상에서 "wget" command 사용해서 ftp protocol 사용해서 파일을

     전송받았는데, tablespace datafile 크기가 23GB 되는 관계로 1915초라는 시간이

     걸렸습니다. 참고로, Windows 경우, "ocopy" 사용하도록 합니다.

$ wget ftp://<A_Host>//usr/local/oracle/.../datafile/users.dbf

--15:24:47--  ftp://…//usr/local/oracle/…/datafile/users.dbf

           => `users.dbf'

Connecting to 192.168.10.11:21... connected.

Logging in as oracle ... Logged in!

==> SYST ... done.    ==> PWD ... done.

100%[========================>] 23,065,534,464 54.8M/s   in 19m 15s

 

 

5.  <B> host로의 전송이 끝났다면, 앞에서 read only mode로 변경한

     tablespace를 <A> database상에서 read write mode로 되돌려 놓습니다.

 

SQL> alter tablespace users read write;

Tablespace altered.

 

 

 

6. <B> database상에 target tablespace 속한 schemas 해당 schemas

    관련된 user-defined roles생성합니다.

 

    불행히도 original utility 사용해도 pump utility 사용해도

    schemas user-defined roles import시에 자동으로 생성해 주지 않습니다.

    왜냐하면 정보들은 target tablespace 종속된 정보가 아니기 때문입니다.

 

    (1)  original export 사용하는 경우

 

          <A> database상에서 dba_users select하여, default_tablespace target database

          된 schemas 파악하고, 해당 schema 접속하여 session_privs session_roles

          select 하여, <B> database상에 생성해 준다.

          schemas 생성하기 전에 target tablespace 존재하지 않으면 default tablespace

          설정할 없기 때문에 임시로 taget tablespace 생성한다.

SQL> connect system/***@<A_DB>

Connected.

 

SQL> select username from dba_users where default_tablespace = 'USERS';

USERNAME

HR

SH

OE

 

SQL> connect hr/***@<A_DB>

Connected.

 

/* target tablespace에 속한 user가 가지는 privileges를 체크한다 */

SQL> select * from session_privs;

PRIVILEGE

CREATE SESSION

ALTER SESSION

CREATE TYPE

CREATE OPERATOR

CREATE INDEXTYPE

 

/* target tablespace에 속한 user가 가지는 roles를 체크한다 */

SQL> select * from session_roles;

 

ROLE

CONNECT

RESOURCE

USER_ROLE01      /* user-defined role */

USER_ROLE02      /* user-defined role */

 

SQL> connect system/***@<B_DB>

Connected.

 

/* 임시로 target tablespace와 동일한 이름의 tablespace를 생성한다 */

SQL> create tablespace users;

Tablespace created.

 

SQL> create user hr identified by **** default tablespace users

    2   quota unlimited on users;

User created.

 

/* <A> database에서 발견한 user-defined roles를 생성한다 */

SQL> create role user_role01;

Role created.

 

SQL> create role user_role02;

Role created.

 

/* 위의 session_roles를 select한 결과로 표시된 roles를 grant한다 */

SQL> grant connect, resource, user_role01, user_role02 to hr;

Grant succeeded.

 

SQL> connect hr/***@<B_DB>

Connected.

 

SQL> select * from session_privs;

PRIVILEGE

CREATE SESSION

UNLIMITED TABLESPACE

CREATE OPERATOR

CREATE INDEXTYPE

 

SQL> connect system/***@<B_DB>

Connected.

 

/* 위에서 session_privs의 결과와 비교해 부족한 privileges를 grant한다 */

SQL> grant create database link to hr;

Grant succeeded.

 

 

    (2)  pump export 사용하는 경우

 

          위와 동일한 방법을 사용해도 전혀 상관없지만, pump import의 "sqlfile"이란 option을

          사용하여 schema생성 및 privilege설정과 관련된 meta data를 SQL*Plus command 형식으로

          얻을 수 있습니다.

 

          1)   우선 위의 예와 동일한 방법으로 해당 tablespace에 종속된 schemas를 추출합니다.

SQL> connect system/***@<A_DB>

SQL> select username from dba_users where default_tablespace = 'USERS';

USERNAME

HR

SH

...

 

 

 

          2)   <A> host상에서 pump export를 사용하여 <A> database의 전체 meta data를

                추출합니다.

$ export ORACLE_SID=<A_DB>

expdp system/**** full=y dumpfile=A_meta.dmp content=metadata_only

Export: Release 11.1.0.7.0 - 64bit Production on Wednesday, ...

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

...

Processing object type DATABASE_EXPORT/SCHEMA/PASSWORD_HISTORY
Processing object type DATABASE_EXPORT/AUDIT
Master table "SYSTEM"."SYS_EXPORT_FULL_01" successfully loaded/unloaded
*****************************************************************
Dump file set for SYSTEM.SYS_EXPORT_FULL_01 is:
  /usr/local/oracle/oradata/A_INSTANCE/backup/dpdump/A_meta.dmp
Job "SYSTEM"."SYS_EXPORT_FULL_01" successfully completed at 16:06:13

 

 

          3)   해당 dump file을 ftp등을 사용해서 <B> host에 전송합니다.

 

          4)   <B> host상에서 pump import를 사용하여 meta data를 생성하는 SQL*Plus command가

                지정한 file에 기록되도록 합니다.

$ export ORACLE_SID=B_INSTANCE

impdp system/**** schemas=hr,oe,bi,sh,pm,ix dumpfile=A_meta.dmp sqlfile=meta.sql

 

Import: Release 11.1.0.7.0 - 64bit Production on Wednesday, 09 December, ...

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

...

Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/ROLE_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
...

Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/INDEX/DOMAIN_INDEX/INDEX
Job "SYSTEM"."SYS_SQL_FILE_FULL_01" successfully completed at 17:06:05

 

                "sqlfile" option을 사용하면 meta data만 file에 기록할 뿐 data는 import되지

                    않습니다. original import의 "show" option과 비슷하다고 보면 됩니다.

 

          5)   "meta.sql" file을 열어보면, 다음과 같은 내용이 있는데, 암호화된 password와 

                tablespace를 생성하기 위한 SQL*Plus command 제외한 나머지(user생성, role생성,

                grant문, 등등)는 여기서 다 얻을 수 있습니다.

 

...

 CREATE USER HR IDENTIFIED BY VALUES 'S:922ACE90A412C'   

      DEFAULT TABLESPACE "USERS"
      TEMPORARY TABLESPACE "TEMP";

...

-- new object type path: SCHEMA_EXPORT/SYSTEM_GRANT
...

GRANT CREATE DATABASE LINK TO HR;

GRANT CREATE SEQUENCE TO HR;
GRANT CREATE VIEW TO HR;
GRANT CREATE SYNONYM TO HR;
GRANT UNLIMITED TABLESPACE TO HR;
GRANT ALTER SESSION TO HR;
GRANT CREATE SESSION TO HR;
...

-- new object type path: SCHEMA_EXPORT/DEFAULT_ROLE
...

-- new object type path: SCHEMA_EXPORT/TABLESPACE_QUOTA
...

 

 

          6)   임시로 target tablespace와 동일한 이름의 tablespace를 생성합니다.

 

          7)   "meta.sql"에서 추출한 SQL*Plus command를 <B> database상에서 실행하여,

                관련된 schemas를 생성하고 privileges and roles를 grant합니다.

 

          8)   앞의 step-6)에서 임시로 생성한 tablespace를 제거합니다.

                ⇒ drop tablespace users;

 

7.  위의 <step-3>에서 export한 dump file을 import합니다.

 

    (1)  original export 사용하는 경우

 

$ imp system/**** transport_tablespace=y file=users.dmp log=users_imp.log

datafiles='/B_DB/datafile/users.dbf'

 

Import: Release 11.1.0.7.0 - Production on Wed Dec 9 19:34:55 2009

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

 

 

 

    (2)  pump export 사용하는 경우

 

$ impdp system/orabong transport_datafiles=/B_DB/datafile/users.dbf

dumpfile=users.dmp logfile=work_dir:users_imp.log

 

Import: Release 11.1.0.7.0 - ... on Wednesday, 09 December, 2009 17:18:26

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

 

...

Processing object type TRANSPORTABLE_EXPORT/DOMAIN_INDEX/INDEX
Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
Job "SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01" completed ... at 17:19:40

 

 

     ※ 위의 시간을 보면 import에 2분이 채 안걸렸다는 것을 알 수 있습니다. 

 

8.  이동된 tablespace는 이동하기 전과 동일한 상태인 read only mode로

     있기 때문에, <B> database상에서 transport된 tablespace를

     read write mode로 변경합니다. (<step-5> 참조)

 

9.  이제 이동된 tablespace가 <B> database상에서 제대로 인식이 되는지,

     그리고 해당 tablespace에 속했던 schemas 및 속한 objects들도 제대로

     존재하는지 체크하는 일만 남았습니다.

     혹시 모르니까 "utlrp.sql"을 사용하여 전체 objects를 recompile해 주면

     좋을 것 같습니다.

 

이 작업에 소요된 전체시간을 계산하면, 30분 이하입니다.

저의 경우 아직 익숙하지 않아서 2시간 정도 걸렸지만,

schemas 전체를 export한 후 import할 때 걸리는 시간이 4시간 정도임을 감안하면,

transportable tablespace기능을 사용함으로서

훨씬 적은 시간에 data의 이동이 가능했다는 것을 알 수 있습니다.

 

중요한 내용이 하나 있는데,

<A> host와 <B> host의 O/S는 동일해야 하며,

<A> database와 <B> database의 version 및 compatibility도 동일해야 합니다.

만약 동일한 Oracle version이라고 해도, "compatible" initialization parameter에

설정된 값이 틀리면, error가 발생하게 됩니다.

 

※ Oracle9i까지는 반드시 O/S가 일치해야 했는데,

    Oracle10g부터는 O/S가 일치하지 않아도

    transportable tablespace기능을 이용할 수 있습니다.

    제가 Oracle Enterprise Linux 5.3 64bit와 Windows XP 32bit간에

    tablespace를 이동시켜보았는데 성공적으로 이루어 졌습니다.

 

저의 경우, <A> 및 <B> database가 둘다 11.1.0.7.0 이었는데,

<A>는 compatible이 11.1.0.7.0 이었고, <B>는 11.1.0.0.0 인 상태로 import를 수행했더니,

ORA-39123: Data Pump transportable tablespace job aborted
ORA-00721: changes by release 11.1.0.7.0 cannot be used by release 11.1.0.0.0

이라는 error가 발생했습니다.

 

이런 경우, <B> database의 "compatible" parameter를 변경한 후

database를 restart한 후에야 import를 할 수 있습니다.

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

[펌] exp / imp 명령어  (0) 2017.08.17
Posted by Any DB
,