2015년 10월 7일 수요일

Oracle Transportable Tablespace 로컬에서 수행하기

Local  TTS 이관 간단시나리오 

  • 사전체크 
    •  TTS가능여부
    •  소스/타겟 동일 Block Size와 Character Set을 가져야함.
  • 소스DB 
    • 테이블스페이스 Read Only변경
    • TTS 메타데이터, 오브젝트 DDL (이관대상 스키마의 테이블,인덱스 제외) 익스포트
  • 타겟DB
    • TTS 메타데이터, 오브젝트 DDL 임포트
    • 테이블스페이스 Read Write변경
    • 후속작업
  • 참고문서 
    • 트랜스포터블 테이블스페이스 (TTS) 제약사항, 제한: 세부사항, 참조, 그리고 적용 가능한 버젼 (문서 ID 1541838.1) 
    • RMAN으로 Transportable Tablespaces을 엔디안 값이 다른 플랫폼으로 이전하는 방법 (문서 ID 1608593.1)

사전작업 - Source DB 스크립트 추출작업

0. Source DB -  TTS 가능여부 체크 

Icon
  • TTS이관이 가능한지 보기위한 패키지 수행 
    • 이관하려는 테이블스페이스(테이블,인덱스)가 아닌, 다른 영역의 테이블스페이스에 세그먼트가 저장되었는지를 확인하는 것 (Self-Contained확인)
  • deferred_segment_creation=true 로 설정된 경우(현재 다음카카오 11g버전) 
    • 데이터가 0건인 테이블은  segment뷰에서 보이지 않고  table/index의 메타정보만 tablespace가 기입될 수 있으므로 주의한다. 
  • 해당 패키지를 실행하면, 오류정보가 temporary table에 저장되고, 이것(sys.transport_set_violation)을 조회하여 해당 내용을 보고 조치한다. no rows를 확인해야한다.

purge dba_recyclebin;
 
set lines 400
 
SELECT
  'exec sys.dbms_tts.transport_set_check ('''
  || LTRIM (SYS_CONNECT_BY_PATH (tablespace_name, ','), ',')
  || ''', TRUE);' as tts_check_script
FROM (
  SELECT tablespace_name,
         ROW_NUMBER () OVER (ORDER BY tablespace_name) rn,
         COUNT (*) OVER () cnt
   FROM DBA_TABLESPACES
    WHERE TABLESPACE_NAME
        IN (SELECT  TABLESPACE_NAME FROM DBA_SEGMENTS 
                  WHERE OWNER IN ('SCHEMA_NAME1')
            UNION ALL
            SELECT  TABLESPACE_NAME FROM DBA_TABLES 
                  WHERE OWNER IN  ('SCHEMA_NAME1')
            UNION ALL
            SELECT  TABLESPACE_NAME FROM DBA_TAB_PARTITIONS 
                  WHERE TABLE_OWNER IN ('SCHEMA_NAME1')
            UNION ALL
            SELECT  TABLESPACE_NAME FROM DBA_TAB_SUBPARTITIONS 
                  WHERE TABLE_OWNER IN ('SCHEMA_NAME1')
      )
 )
WHERE rn=cnt
 CONNECT BY PRIOR rn = rn - 1
START WITH rn =1
UNION ALL
 SELECT
   'select * from sys.transport_set_violations;' FROM DUAL
/
 
 
SQL> exec sys.dbms_tts.transport_set_check ('TBS_1','TBS_2',TRUE);
SQL> select from sys.transport_set_violations;
       no rows selected

1. Source DB -  TTS 자동화 스크립트 수행 , 전체(일부) 메타확인 

 00.make_tts.sh   

  • 단계별로 수행할 스크립트(01~10)를 생성한다. (실제작업시 자동화 생성 쉘을 만들어서 수행하였음.)
    • 아래는 /data 를 d1 directory로 생성 후 진행한 케이스임.
      • work directory 는 작업자의 임의로 선정가능함.     
      • 00.make_tts.sh
        01.pre_meta_dump.sh
        02.cre_user_priv.sh
        03.cre_directory.sh
        04.cre_public_dblink.sh
        05.tablespace_read_only.sh
        06.expdp_tts_meta.sh
        07.expdp_schema_meta.sh
        08.impdp_tts_meta.sh
        09.impdp_schema_meta.sh
        10.tablespace_read_write.sh

01.pre_meta_dump.sh 

  • 스키마 검증을 위하여, 현 시점의 테이블스페이스 / 스키마 /디렉토리/ 디비링크 / 권한등을 추출해본다. 
  • 불필요한 스키마 (현재 라이센스 정책위배) 등에 대한 부분도 확인하여, 재 생성하지 않도록 한다. 
  • 만약 sys, system 등의 스키마에 연관된 오브젝트들을 참조하는 로직이 의심되면 전체로 한번 ddl 도 추출해본다. 
    • 참고로 서비스중  sys.write_alertlog라는 프로시저를 만들어서 사용자에게 execute 권한을 준 부분도 있었음
    • system 스키마에서 스케쥴러 등록한 경우 등도 해당

echo "####################################"
echo " start 01.pre_meta_dump.sh"
echo "####################################"
date
 
-- Meta ALL SQL (If u need)
time expdp system/systempw dumpfile=meta_all.dmp logfile=meta_all.explog \ 
 directory=d1 content=metadata_only  full=y
 
sleep 1

### Convert with SQLFILE
time impdp system/systempw dumpfile=meta_all.dmp logfile=meta_all.implog \
 full=y sqlfile=meta_all.sql directory=d1
 
echo
echo "##################################"
echo " finish  01.pre_meta_dump.sh"
echo "##################################"
date

2. Source DB - 운영중인 서버에서 사전준비 (다운타임 최소화)

  1. ORACLE_BASE : /oracle(기존)  >> /u01/app/oracle (신규)
  2. 운영중에 /oracle, /data 마운트 영역에서 /data영역 대신 /u01로 마운트한다. 
  3. 시간단축을 위해 db엔진 및 database tar본 생성
    • DB엔진(PSU 11.2.0.4.7) : /u01/app/oracle/oracle_install_$ORACLE_SID_PSU7.targ.gz
    • DataBase Files (system,undo,redo, controlfile, temp, sysaux)    ㄴ /data/oradata/$ORACLE_SID/$ORACLE_SID_SYSTEM_FILES.tar.gz
    • DB엔진만 가져온 후, PSU패치, DBCA 과정등을 진행해도된다. 
-- PSU(11.2.0.4.7)적용 DB엔진
[(oracle):/u01/app/oracle]$ oracle_install_${ORACLE_SID}_PSU7.tar.gz
[(oracle):/u01/app/oracle]$ tar xzvf oracle_install_${ORACLE_SID}.tar.gz
 
-- DBCA적용 DATABASE(system,sysaux,undo,temp,controlfile,redolog)
[(oracle):/data/oradata/ORASID]$ tar xvfz $ORACLE_SID_SYSTEM_FILES.tar.gz


   4. Database system files는 롤백시나리오를 위해 /backup01/BACKUP_SYSTEM 으로 이동(백업:move)
       할 예정이므로,소스 DB shutdown 전 스크립트 추출

-- SYSTEM DataFiles 백업 추출 쿼리 (mv_backup_source_systemfile.sh)
select
 'mv '  || name || ' /backup01/BACKUP_SYSTEM/'
 as backup_system_script
from
(
select  name  from v$controlfile
 union all
select member from v$logfile
 union all
select nvl(f.file_name,e.file_name)
  from dba_data_files f,
       dba_temp_files e,
       dba_tablespaces t
 where f.tablespace_name(+) = t.tablespace_name
   and e.tablespace_name(+) = t.tablespace_name
   and (t.contents in ('UNDO','TEMPORARY')
            or t.tablespace_name in ('SYSTEM','SYSAUX') )
 )          
 order by 1
/
  
  5. 신규 오라클 엔진에 필요한 파일들을 미리 복사/수정해 놓는다. 
  
-- 1) OS 프로파일 신규 엔진에 맞게 내용을 수정.
cp $HOME/{.bash_profile,.bashrc} /u01/app/oracle
  
-- 2) .ssh 연결인증관련 복사
cp -rf $HOME/.ssh /u01/app/oracle/
 
-- 3) 신규DB에 맞게 init$ORACLE_SID.ora파일 생성/수정 (Control file 위치 등)
cp -rf /oracle/product/11.2.0.4/dbs/*  \
  /u01/app/oracle/product/11.2.0.4/dbhome_1/dbs/
 
-- 4) network/admin폴더 : listener의 ORACLE_HOME수정, sqlnet.ora는 추후 다시 옮김
cp -rf /oracle/product/11.2.0.4/network/admin/* \
  /u01/app/oracle/product/11.2.0.4/dbhome_1/network/admin/ 

  6. /etc/passwd 파일에 신규 Oracle 계정에 대한 정보를 추가하고 주석처리(#) 해놓는다. 
  • 오라클 HOME 디렉토리는 ORACLE_BASE(/u01/app/oracle) 로 가정한다.
#oracle:x:700:700::/u01/app/oracle:/bin/bash             #신규정보
oracle:x:700:700::/oracle/product/11.2.0.4:/bin/bash     #기존정보


실제작업 - Source DB

1. Source DB - Tablespace Read-only직전, 오브젝트 체크용 테이블 생성
  • Tablespace를 Read-Only로 변경 전, 오브젝트 검증을 위한 검증용 테이블을 생성한다. .
  • Local에서 진행하기 때문에, 이관할 테이블스페이스영역에 검증용 테이블을 생성한다. 
  • 해당 테이블은  이관할 계정(이관할 테이블스페이스 저장공간)에서 생성하도록한다. 
    • CREATE TABLE SCHEMA1.SOURCE_OBJ_INFO 
      AS
      SELECT
       OWNER, OBJECT_TYPE, OBJECT_NAME,SUBOBJECT_NAME , STATUS
      FROM DBA_OBJECTS
      WHERE
         OWNER IN ('SCHEMA1','SCHEMA2','SCHEMA3','SCHEMA4')
       or (OWNER='PUBLIC' and OBJECT_TYPE='DATABASE LINK')
      ORDER BY OWNER, OBJECT_TYPE, OBJECT_NAME, SUBOBJECT_NAME;

2. Source DB - TTS를 위한 테이블스페이스 Read Only로 변경 + 오브젝트 체크 테이블 생성

05.tablespace_read_only.sh

  • TTS를 위해 테이블스페이스를 Read-Only로  Freezing한다. 
  • 사실 서버 to 서버의 TTS의 경우, tablespace read-only 이후에 파일을 복사하는 과정이 포함된다.
Icon
  1. Tablespace 를 Read Only 로 변경 전 서비스는 종료되어야한다.
  2. ADG 구성일경우 Standby DB로 서비스 전환이 먼저 완료되어야한다.
  3. 모든 서비스의 유입이 중지된 상태에서 진행하길 권고한다.

[(oracle):/data]$ cat 05.tablespace_read_only.sh

echo "####################################"
echo " start 05.tablespace_read_only.sh"
echo "####################################"
date

sqlplus / as sysdba <<EOF
 alter tablespace TBS_1 read only;
 alter tablespace TBS_2 read only; 
 select tablespace_name, contents, status from dba_tablespaces;
exit
EOF
 
echo
echo "##################################"
echo " finish  05.tablespace_read_only.sh"
echo "##################################"
date

[(oracle):/data]$ bash 05.tablespace_read_only.sh

3. SourceDB - 해당 테이블스페이스의 Meta Data Export 

06.expdp_tts_meta.sh

  • TTS로 이관할 테이블스페이스들에 대한 메타데이터를 export 한다.
  • exp(imp) / expdp(impdp) 로 모두 가능하며, 예제는 expdp를 이용한 케이스로 진행한다.  

[(oracle):/data]$ cat 06.expdp_tts_meta.sh
echo "####################################"
echo " start 06.expdp_tts_meta.sh"
echo "####################################"
date
 
time expdp system/***** DUMPFILE=tts_$ORACLE_SID_meta.dmp \
 logfile=tts_SHOPHOW_meta.explog DIRECTORY=d1 \
 TRANSPORT_TABLESPACES=TBS_1,TBS_2
 
echo
echo "##################################"
echo " finish  06.expdp_tts_meta.sh"
echo "##################################"
date

[(oracle):/data]$ bash 06.expdp_tts_meta.sh

4. SourceDB -  테이블/인덱스를 제외한 오브젝트 Export 

07.expdp_schema_meta.sh

  • 테이블스페이스 datafile에 있는 테이블,인덱스를 제외한 오브젝트(시퀀스, 뷰, 시노님, 프로시저 등)에 대한 오브젝트 export진행

[(oracle):/data]$ cat 07.expdp_schema_meta.sh
echo "####################################"
echo " start 07.expdp_schema_meta.sh"
echo "####################################"
date
 
 time expdp system/***** DUMPFILE=tts_${ORACLE_SID}_object.dmp \ 
  logfile=tts_${ORACLE_SID}_object.explog DIRECTORY=d1 EXCLUDE=TABLE,INDEX \
  SCHEMAS=SCHEMA1,SCHEMA2,SCHEMA3,SCHEMA4
 
echo
echo "##################################"
echo " finish  07.expdp_schema_meta.sh"
echo "##################################"
date

5. SourceDB -  Shutdown

  • 모든 준비가 끝나면 소스DB/ 리스너를 죵료한다. 
  • 테이블스페이스를 Read-Only하고 종료한 상태이므로, 신규DB작업시 해당 테이블스페이스를 read-write변경전까지 원복이 가능하다(롤백시나리오)
[(oracle):/oracle]$ lsnrctl stop

[hostname(oracle):/data]$ echo $ORACLE_HOME
/oracle/product/11.2.0.4/dbhome_1

[hostname(oracle):/data]$ sqlplus / as sysdba  
SQL> shutdown immediate
SQL> exit


실제작업 - Target DB 

환경변수 확인
Icon
  • Local & Remote TTS
  1. LOCAL DB
    1. 신규로 오라클 엔진 및 DBCA 가 선행되어야 한다.
    2. 기존 오라클 환경 변수를 (ex) /oracle/product/11.2.0) 현재 표준인 환경변수로 수정을한다.
    3. 즉, 신규 설치된 오라클 패스에 맞게 환경변수를 설정한다.
    4. /etc/oratab, /etc/oraInst, /etc/passwd (oracle home directory), .bash_profile 등
  2. REMOTE
    1. 표준 구성에 맞게 오라클 엔진 및 DBCA가 완료되어있어야 한다.

1. TargetDB - Startup & 시스템 Database 작업

  1. 신규 DB Open 사전작업 
    vi /etc/passwd (신규 oracle계정 활성화)
    source /u01/app/oracle/.bash_profile
    echo $ORACLE_HOME
      ㄴ /u01/app/oracle/product/11.2.0.4/dbhome_1 확인

    2. 기존 소스 데이터베이스 시스템파일들을 백업 / sqlnet.ora 파일의 최신본을 복사한다. 
  • -- 소스 데이터베이스 시스템데이터파일들 백업
    [(oracle):/data01/oradata/ORA_SID]$ ps -ef | grep ora(process 없는것 확인)
    [(oracle):/data01/oradata/ORA_SID]$ mkdir /backup01/BACKUP_SYSTEM
    [(oracle):/data01/oradata/ORA_SID]$ mv redo0* control0* temp01.dbf \ 
           system*.dbf sysaux*.dbf undotbs*.dbf /backup01/BACKUP_SYSTEM/
          
    -- SQLNET.ora 복사
    cp -rf /oracle/product/11.2.0.4/dbhome_1/network/admin/sqlnet.ora \
      /u01/app/oracle/product/11.2.0.4/dbhome_1/network/admin/
  3. 신규 system file 이동 및 datafile rename 적용 후 DB Open
  • Database File 압축본에는 /data/oradata/$ORACLE_SID 경로의 작은 용량임.
  • DB Open전 실서버 datafile위치로  신규 system files(control,system,undo,temp)을 이동한다. 
  • mount모드에서 이동한 system files rename 적용 후 신규DB Open 
  • -- 신규 spfile파라미터 파일 생성 (pfile생성 후 새로운 경로에 맞게 수정)
    SQL> create spfile from pfile;
     
    -- ControlFile / SystemFile 이동
    [(oracle):/data01/oradata/ORA_SID]$
      mv {control0*.ctl,system01.dbf,sysaux01.dbf,undo01.dbf,temp01.dbf}
    /data01/oradata/$ORACLE_SID/

    -- System Datafile Rename
    startup mount
     
    alter database rename file
     
    '/data/oradata/$ORACLE_SID/system01.dbf'  to
     '/data01/oradata/$ORACLE_SID/system01.dbf';

    alter database rename file  temp01.dbf,
    sysaux01.dbf,undotbs01.dbf도 동일rename진행

    alter database open

2. Target DB - 스키마와 권한 생성 

02.cre_user_priv.sh

  • 사전체크사항에 특이사항이 없는 경우, 사전에 임포트할 스키마를 생성한다(필수)
    • 스키마 생성 구문에  <Input Plain PWD>대신 평문 비밀번호로 변경하여 저정한다.  
    • 이슈사항 : (문서 ID 554605.1)  - 스키마 생성시 values encrypted password로 생성시, 버전이 다른 클라이언트 로그인 오류 발견 (오라클 공식적으로 values로 생성구만 보장안함)
  • 스키마 임포트시 디폴트테이블스페이스는 system 테이블스페이스로 변경되어 스크립트가 생성된다.  (TTS import이전 생성하기 때문임)
    • temporary 테이블스페이스도 다른 이름으로 사용된다면, 스크립트 변경 또는 사후작업으로 진행한다. 
    • TTS 작업완료 후, 디폴트테이블스페이스를 다시 변경해야하므로, 스키마생성구문에 주석처리로 기존 테이블스페이스를 넣어놓았음.


[(oracle):/data]$ cat 02.cre_user_priv.sh
echo "####################################"
echo " start 02.cre_user_priv.sh"
echo "####################################"
date

sqlplus / as sysdba <<EOF
-- ### 1. CREATE USER
CREATE USER SCHEMA1 IDENTIFIED BY <Input Plain PWD>
 DEFAULT TABLESPACE SYSTEM /* ORG : TBS_1 */  TEMPORARY TABLESPACE TEMP;

-- ### 2. GRANT ROLE ###
GRANT CONNECT,RESOURCE TO SCHEMA1;

-- ### 3. GRANT SYSTEM PRIVILEGES ###
GRANT UNLIMITED TABLESPACE TO DBSTAT;

[(oracle):/data]$ bash 02.cre_user_priv.sh


3. Target DB - Public Directory 생성

03.cre_directory.sh

  • 디렉토리를 사전에 생성하고, Public으로 권한 준 부분까지 생성한다. 
  • 스키마별 임포트시, Public권한은 누락될 수 있다. 
  • [(oracle):/data]$ cat 03.cre_directory.sh
    echo "####################################"
    echo " start 03.cre_directory.sh"
    echo "####################################"
    date
    sqlplus / as sysdba <<EOF
    create or replace directory D1 as '/data';
    grant READ on directory D1 to PUBLIC;
    grant WRITE on directory D1 to PUBLIC;
    exit
    EOF
    echo
    echo "##################################"
    echo " finish  03.cre_directory.sh"
    echo "##################################"
    date

4. Target DB - Public Database Link 생성

04.cre_public_dblink.sh

  • Public Database Link를 생성한다.
  • 추후 스키마별로 DDL 메타 임포트시 해당 스키마의 DB_link는 자동 생성된다
  • [(oracle):/data]$ cat 04.cre_public_dblink.sh
    echo "####################################"
    echo " start 04.cre_public_dblink.sh"
    echo "####################################"
    date
     
    sqlplus / as sysdba <<EOF
     
    CREATE PUBLIC DATABASE LINK PUBDBLINK CONNECT TO TEST
     IDENTIFIED 
    BY VALUES '0DAA0AC97C965BE2' USING 'TESTDB';
     
    exit
    EOF
    echo
    echo "##################################"
    echo " finish  04.cre_public_dblink.sh"
    echo "##################################"
    date
    [(oracle):/data]$ bash 04.cre_public_dblink.sh
     

5. TargetDB -  TTS메타 데이터 Import 

08.impdp_tts_meta.sh

  • transport_datafiles에  tts임포트할 데이터파일 목록을 지정하여 스크립트 수행 
  • 데이터파일들의 정보를 매핑시켜서 임포트하는 작업.
  • [(oracle):/data]$ cat 08.impdp_tts_meta.sh
    echo "####################################"
    echo " start 08.impdp_tts_meta.sh"
    echo "####################################"
    date
     
    time impdp system/***** DUMPFILE=tts_${ORACLE_SID}_meta.dmp \
      logfile=tts_${ORACLE_SID}_meta.implog DIRECTORY=d1 \
      transport_datafiles=/data/oradata/ORA_SID/TBS1.dbf,/data/.../TBS2.dbf
     
     
    echo
    echo "##################################"
    echo " finish  08.impdp_tts_meta.sh"
    echo "##################################"
    date

    [(oracle):/data]$ bash 08.impdp_tts_meta.sh

6. TargetDB -  테이블/인덱스를 제외한 오브젝트 Import 

09.impdp_schema_meta.sh

  • 임포트한 테이블스페이스의 사용 스키마의 오브젝트들을 생성하는 단계
  • 테이블,인덱스를 제외한 오브젝트(시퀀스, 뷰, 시노님, 프로시저 등)에 대한 오브젝트 import 스크립트 수행
  • 해당 유저의 default tablespace를 다시 재설정한다.
  • [(oracle):/data]$ cat 09.impdp_schema_meta.sh
    echo "####################################"
    echo " start 09.impdp_schema_meta.sh"
    echo "####################################"
    date
     
    time impdp system/***** DUMPFILE=tts_${ORACLE_SID}_object.dmp \
     logfile=tts_${ORACLE_SID}_object.implog DIRECTORY=d1 full=y
      
     
    echo
    echo "##################################"
    echo " finish  09.impdp_schema_meta.sh"
    echo "##################################"
    date

    [(oracle):/data]$ bash 09.impdp_schema_meta.sh

7. Object 비교 Check

  • 롤백할 수 있는 거의 마지막 단계이기 때문에, tablespace read/write 변경 전에 체크해본다. 
  • 기존 오브젝트와 개수 비교 (lob, lobindex등은 다른 이름으로 생성될 수 있다)
  • 소스에 존재했는데, 타겟에는 없는 오브젝트 체크 
  • 소스에 Invaild하지 않았는데, 타겟에서는 Invalid한 오브젝트 조회
    • @?/rdbms/admin/utlrp.sql 은  마지막단계 tablespace read write 변경 후 진행하여, 전체 오브젝트 컴파일을 진행한다. 

-- 오브젝트 개수 비교
select a.owner ,
       a.object_type ,
       source_cnt,
       target_cnt ,
       source_cnt - target_cnt as diff
  from (select owner ,
               object_type ,
               count(*) as source_cnt
          from shopcmp.SOURCE_OBJ_INFO
         where owner in ('SCHEMA1','SCHEMA2')
         group by owner,
               object_type) a,
       (select owner ,
               object_type ,
               count(*) as target_cnt
          from dba_objects
         where owner in ('SCHEMA1','SCHEMA2')
         group by owner,
               object_type
         order by owner,
               object_type) b
 where a.owner=b.owner(+)
   and a.object_type=b.object_type(+);
    
  -- 소스에 있는데 타겟에 없는 것 체크 
  select owner,
       object_type,
       object_name,
       subobject_name
   from shopcmp.SOURCE_OBJ_INFO
  where owner in ('SCHEMA1','SCHEMA2')
   minus
  select owner,
       object_type,
       object_name,
       subobject_name
  from dba_objects
  where owner in ('SCHEMA1','SCHEMA2');
   
   
  -- Invalid Object Check
select do.owner,       do.object_type,
       do.object_name,
       do.status
  from dba_objects do
 where do.status = 'INVALID'
   and do.owner in ('SCHEMA1','SCHEMA2')
   and not exists (select 1
          from shopcmp.SOURCE_OBJ_INFO
         where status = 'INVALID'
           and owner in ('SCHEMA1','SCHEMA2')
           and do.owner = owner
           and do.object_type = object_type
           and do.object_name = object_name )
 order by owner,
       object_type,
       object_name;
   


8. TargetDB -  테이블스페이스 Read-Write변경

10.tablespace_read_write.sh

  • 정상적일 경우, 해당 테이블스페이스를 read write로 변경하는 단계 ( 이 단계 이후 롤백 불가)
  • 이제 돌이킬수 없는 강을 건넜음으로, 임포트한 스키마의 default tablespace 다시 변경한다. 
    • 02.cre_user_priv.sh 스키마 생성 구문에 /* ORG : 기존 디폴트 테이블스페이스명 */ 을 확인하여 조치한다.
  • utlrp.sql 실행하여, 전체 재 컴파일을 진행한다.  (이후 7번 체크를 다시 진행해본다. 최종 확인)
  • [(oracle):/data]$ cat 10.tablespace_read_write.sh
    echo "####################################"
    echo " start 10.tablespace_read_write.sh"
    echo "####################################"
    date
     
    sqlplus / as sysdba <<EOF
     alter tablespace TBS_1 read write;
     alter tablespace TBS_2 read write;
     select tablespace_name, contents, status from dba_tablespaces;
     exit
    EOF
     
    echo
    echo "##################################"
    echo " finish  10.tablespace_read_write.sh"
    echo "##################################"
    date

    [(oracle):/data]$ bash 10.tablespace_read_write.sh 
    [(oracle):/data]$ sqlplus / as sysdba
    SQL> @?/rdbms/admin/utlrp.sql -- 재 컴파일 작업
     
    [(oracle):/data]$ lsnrctl start

작업완료 후 운영등에 필요한 작업

  1. /etc/oratab, /etc/oraInst 변경
  2. 각종 운영에 관련된 모니터링 스크립트 등

로컬TTS 수행시 장점

1. 로컬 TTS vs 원격 TTS
* 원격 서버로 datafile copy 해야 하는 시간만큼 downtime 감소된다.
  - 대용량 DB 경우 이부분에서 다운타임 감소 효과가 극대화된다.
* 기존 IP 유지가 용이하다.
* 원격 TTS 대상이 되는 신규 서버를 구성할 필요가 없다.(장비구매 비용 절감)

2. 로컬 TTS vs 일반적인 Upgrade(by DBUA)
* DBUA 이용한 upgrade 시간만큼 downtime 감속된다.
* upgrade  문제가 있어 downgrade 진행해야  경우 downgrade 작업이 용이하다.
  - 기존 DB 그대로 유지되고 있어 oracle 계정에 대한 정보 수정만으로 downgrade 가능하다.