by-nc-sa     개발자, DBA가 함께 만들어가는 구루비 지식창고!

14. SECUREFILE




Overview

데이터의 양이 많아지고 그 형태가 다양해지면서 정형(Structured) 텍스트 혹은 숫자형 데이터 뿐만 아니라
이미지, 오디오, 비디오, PDF, Word 문서 등의 비정형(Unstructured) 데이터의 비중이 커지고 있음.
이런 비정형 데이터는 성능상 그리고 관리상의 편의성 때문에 일반적으로 파일 시스템에 저장해왔음.

하지만 이렇게 정형 데이터와 비정형 데이터에 대해 서로 다른 스토리지 메커니즘을 유지하는 구조는,
파일이나 비정형 데이터에 대한 오라클의 보안성, 확장성, 읽기 일관성, 고가용성등의 효과를 절감 시키며, 보안/감사 혹은 백업/복구 모델의 양분화를 초래함.
그리고 궁극적으로는 ROI를 낮추는 결과를 가져오게 됨.

오라클은 11g에서 SecureFile이라는 기능을 선보임.

  • SecureFile은 비정형 데이터 관리에도 오라클 데이터베이스의 기능들을 적용하면서 동시에 성능면에서도 기존의 파일 시스템에 떨어지지 않도록 고안된 기능임.
  • SecureFile을 통해서 기업들은 모든 관계형 데이터뿐만 아니라 관련 파일들까지 모두 오라클 내에서 관리하면서 일관된 보안/감사 및 백업/복구 모델을 을 적용할 수 있게 되었음.

SecureFile은 이전 버전에서 오라클이 비정형 데이터 관리를 위해 지원했던 LOB데이터 타입에 대한 보완형이 아닌 완전히 새로 개발된 데이터 형식임.

  • 디스크 저장 구조, 네트워크 전송 프로토콜, 스페이스 관리, Redo 및 Undo 저장 형식, 버퍼 캐싱 관리와 I/O 시스템 연동 등의 측면에서 완전히 새로운 방식을 도입
  • 성능 및 확장성을 향상시키고 스토리지 관리 측면에서의 효율성과 관리 용이성을 제공

이번 장에서는 SecureFile의 특징과 사용법에 대해 소개하도록 하겠음.

  • 앞으로 10g에서 제공했던 LOB는 'Basic File'이라고 명명함

Write-Gather Cache (WGC)

SecureFile은 Write 작업 시, 캐쉬를 이용함.

  • 스토리지 단에 데이터를 내려쓰거나 커밋하기 전에 최대 4MB 까지 데이터를 캐쉬에 버퍼링한다.
  • 이렇게 버퍼링했다가 내려씀으로써 한번에 연속된 디스크 공간을 할당하고 디스크 I/O 단위를 크게 해서, 쓰기 작업 시 디스크 seek 작업에 소모되는 시간을 줄여, 쓰기 작업 성능을 크게 향상 시킬 수 있음.
  • WGC는 버퍼 캐쉬에서 할당되며 트랜잭션 별로 할당/관리 됨.
  • 최대 크기인 4MB가 다 차기 전에 디스크에 내려쓰는 시점은 오라클이 자동으로 결정하며 물론 유저가 Commit 명령어를 내리면 WGC 버퍼의 내용을 디스크에 바로 내려씀
Note

WGC 버퍼 사이즈는 직접 설정할 수 있는 파라미터가 아님.

Space Management

SecureFile의 스토리지 관리 방식은 오라클 데이터베이스 내에 파일 데이터를 저장하는데 최적화되도록 설계되었음.
오라클의 스토리지 관리자가 연속된 큰 디스크 블록들을 빠르게 할당해주며, 해제된 스페이스를 자동으로 재사용함으로써 효율적인 삭제 작업을 수행함.
이전 작업들의 공간 수요 정보를 이용해서 스페이스를 미리 할당해두는 방식으로 동작함.

SecureFile은 새롭게 도입된 통계 정보들을 이용해서 효율적으로 메모리 및 공간할당 작업을 하도록 디자인 되었음.

  • SecureFile 세그먼트들은 ASSM(Automatic Segment Space Management)방식으로 관리되는 테이블스페이스에 생성되어야 함.

Reduced Fragmentation

BasicFile과는 달리 SecureFile이용 시에는 Chunk 사이즈가 동적으로 설정됨.
이를 통해 디스크 상에 연속된 공간 할당을 극대화하고 단편화(Fragmentation) 현상을 줄일 수 있음.
오라클은 사용자가 설정한 Chunk 사이즈와 SecureFile의 세그먼트 내의 남은 공간 등 다양한 요소들을 고려해서 최적의 Chunk 사이즈를 결정함.

Chunk 사이즈가 일정하게 고정되어 있다면, 그 값이 너무 크게 설정된 경우에는 단편화를 발생시키고 너무 작게 설정된 경우에는 쓰기 성능 저하를 야기시킴.
SecurFile은 Chunk 사이즈를 동적으로 설정함으로써 한번에 큰 디스크 공간을 할당하고 해제할 수 있게 해주어 작업 성능을 향상시키고 스토리지를 좀 더 효율적으로 사용할 수 있게 함.

Intelligent Pre-fetching

SecureFile은, 네트워크를 통해서 데이터 전송 시, 데이터를 디스크에서 pre-fetching함으로서 읽기 성능을 향상시켰음.
SecureFile은 이전의 데이터 접근 패턴을 참조해서 자동으로 데이터를 pre-fetching 해둠.
Prefetching 기능은 읽기 작업 시 네트워크 RoundTrip 시간 동안에 미리 데이터를 pre-fetching해둠으로써 읽기 작업 시간을 단축시킴.

New Network Layer

SecureFile은 클라이언트와 서버간의 빠른 데이터 전송을 위해서 새로운 네크워크 계층(layer)를 도입함.
새로운 프로토콜은 기타 다른 단계를 거치지 않고 네트워크 소켓 계층에서 바로 데이터를 읽거나 쓸 수 있게 함으로서 읽기/쓰기 성능을 향상 시킴

No LOB Index Contention

기존은 LOB는 논리적인 offset과 물리적인 디스크 블록을 매핑하는 데이터 구조인 inode를 관리하기 위해서, global B+ tree 인덱스를 세그먼트마다 관리했음.
하지만 이 방식은 데이터 접근 시에도 그리고 할당되었던 스페이스를 해제하는 삭제 시에도 같은 인덱스에 접근해야 하기 때문에, 경합 발생으로 인한 성능저하를 야기시켰음.

SecureFile은 메타데이터 관리를 위해

  • 인덱스를 사용하는 대신 LOB 세그먼트 내에 데이터 블록들과 함께 위치하는 private 메타데이터 블록을 사용하기 때문에, BasicFile의 성능저하를 일으켰던 LOB 인덱스 경합 문제를 해결함,
  • 특히 delete/insert 작업이 잦은 환경에서의 성능 향상을 가져왔음

Easier Manageability

SecureFile은 메모리 및 스페이스 관리 알고리즘을 통해서 자동 튜닝되므로 사용자 정의 파라미터의 종류가 줄어들었음.
FREEPOOLS, REELISTS, FREELIST GROUP, PCRTVERSION 등의 기존 파라미터들은 SecureFile 환경에서는 더 이상 사용되지 않음.
이런 파라미터들은 workload를 예측하기 힘든 환경에서 설정하기도 어려울 뿐더러, 동적 변경도 허용되지 않았었음.
ScureFile은 내부적으로 수집된 통계치들을 이용해서 workload를 분석하여 스페이스 관리 알고리즘을 자동 튜닝 함으로써 다양한 workload 환경에서도 성능과 확장성을 보장함.

Advanced Features

SecureFile을 이용하면 De-duplication, Compression과 Encryption 등 BasicFile에서는 사용 불가능한 데이터베이스 기능들을 이용할 수 있음.

De-duplication

자동으로 SecureFile의 동일한 데이터가 중복 저장되어 있는 것을 감지하고, 중복 복사본을 삭제해서 스토리지를 절약하는 기능임.
SecureFile은 중복 복사본을 제거할 때, 제거되는 복사본에 대한 참조까지 자동으로 관리해줌.
de-duplication은 애플리케이션에 투명하게 진행되므로 애플리케이션에 전혀 영향을 미치지않고, 스토리지 관리를 간단하게 해주며, 성능 향상을 가져옴.

SecureFile의 중복 저장 감지는 하나의 LOB 세그먼트 내에서만 진행됨.
lob_storage_clause 파라미터를 통해서 파티셔닝된 SecureFile 칼럼을 다른 파티션이나 하위 파티션은 제외하고 특정 파티션만 deduplication하도록 파티션-레벨 de-duplication을 설정할 수 있음.

SecureFile de-duplication은 Advanced Compression Option에 포함된 기능임.

Compression

표준 압축 알고리즘을 이용해서 SecureFile 데이터를 압축할 수 있음.
압축을 이용하면 스토리지를 절약할 수 있을 뿐 아니라 I/O, 버퍼 캐쉬 사용량, redo 생성량, 암호화 오버헤드 등이 모두 줄어들기 때문에 성능향상도 가져옴.

압축 작업 시 다음과 같은 Compression 레벨을 설정할 수 있으며, Compression 레벨이 높으면 스토리지를 많이 절약할 수 있는 반면 대기시간이 길어질 수 있음.

  • MEDIUM (default)
  • HIGH

SecureFile 압축은 Advanced Compression Option에 포함된 기능임.

Encryption

Transparent Data Encryption(TDE)을 이용하여 SecureFile을 암호화할 수 있음.
테이블 내의 모든 SecureFile 칼럼에 대해 오라클이 키를 관리해주고 투명하게 암호화/복호화 해줌.

SecureFile에 적용할 수 있는 암호화 알고리즘은 다음과 같음.

  • 3DES168: Triple Data Encryption Standard with a 168-bit key size
  • AES128: Advanced Encryption Standard with a 128 bit key size
  • AES192: Advanced Encryption Standard with a 192-bit key size (default)
  • AES256: Advanced Encryption Standard with a 256-bit key size

SecureFile 암호화는 Advanced Security Option에 포함된 기능이다.

세가지 기능은 각자 따로 설정 가능하며, 다른 기능들과 함께 사용할 수도 있음.
세가지 기능이 모두 설정되는 경우에는 De-duplication -> Compression -> Encryption의 순서로 진행됨.

성능 테스트

Oracle Database 11g: SecureFiles Performance 링크 참조 http://www.oracle.com/technetwork/database/perf-087187.html

Using SecureFile

Compatibility

11g부터 소개된 SecureFile과 기존의 LOB를 구별하기 위해 다음 두 가지 파라미터가 도입되었음.
기존의 LOB 방식은 'BASICFILE'을 SecureFile 사용을 위해서는 'SECUREFILE'을 명시하면 됨.

 
<LOB_storage_clause> ::=
LOB
{ (LOB_item [, LOB_item ]...)
    STORE AS [ SECUREFILE | BASICFILE ] (LOB_storage_parameters)
| (LOB_item)
    STORE AS [ SECUREFILE | BASICFILE ]
      { LOB_segname (LOB_storage_parameters)
      | LOB_segname
      | (LOB_storage_parameters)
      }
}

db_securefile parameter

init.ora 파일에 SecureFile 사용 정책을 설정할 수 있도록 db_securefile이 라는 초기화 파라미터가 도입되었음.
이 파라미터는 'ALTER SYSTEM' 명령어를 통해 동적으로 설정가능함.

설정 가능 값들과 그 내용은 다음과 같음.

  • PERMITTED : SecureFile 생성 허용 (디폴트)
  • FORCE : BasicFile 키워드를 무시하고 모든 LOB를 항상 SecureFile로 생성. ASSM 테이블스페이스가 아닌 경우, LOB 생성시 에러 발생.
  • ALWAYS : BasicFile 키워드를 무시하고 모든 LOB를 항상 SecureFile로 생성. 하지만 ASSM 테이블 스페이스가 아닌 경우에는 BasicFile로 생성됨.
  • IGNORE : 명시된 SecureFile 키워드와 옵션 설정 내용 모두 무시
  • NEVER : 새로운 SecureFile 생성 불허. SecureFile LOB 생성 명령 시에도 BasicFile로 생성됨.

Advanced Features

De-duplication, Compression과 Encryption 기능은 기존의 BasicFile에서는 지원되지 않다가 SecureFile에서부터 지원되기 시작한 기능들임.
세가지 기능은 따로 설정 가능하며 다른 기능들과 같이 설정도 가능함.
세가지 기능이 모두 설정되는 경우에는 De-duplication -> Compression -> Encryption의 순서로 진행됨.

De-duplication

테이블 생성 시, SecureFile에 LOB-레벨 de-duplication을 설정하는 방법은 다음과 같음.

 
CREATE TABLE t1 ( a CLOB)
    LOB(a) STORE AS SECUREFILE (
        DEDUPLICATE
        CACHE
    );

특정 파티션의 LOB 칼럼에만 de-duplication을 설정할 수도 있음.

  • 다음의 예는 p1 파티션의 LOB 칼럼에만 deduplication을 설정하는 방법을 보여줌.
     
    CREATE TABLE t1 ( REGION VARCHAR2(20), a BLOB)
         LOB(a) STORE AS SECUREFILE (
               CACHE
    )
    PARTITION BY LIST (REGION) (
         PARTITION p1 VALUES ('x', 'y')
              LOB(a) STORE AS SECUREFILE (
                    DEDUPLICATE
              ),
         PARTITION p2 VALUES (DEFAULT)
    );
    

테이블 생성 시, de-duplication을 비활성화 시키는 방법은 다음과 같음.

 
CREATE TABLE t1 ( a CLOB)
   LOB(a) STORE AS SECUREFILE (
        KEEP_DUPLICATES
        CACHE
   );

특정 파티션에 포함된 LOB 칼럼만은 제외하고 나머지 LOB 칼럼들에는 모두 de-duplication이 활성화되도록 설정할 수도 있음.

  • 아래 예는 de-duplication 설정 시 p2 파티션에 포함된 LOB를 제외하고 나머지 칼럼들에만 de-duplication을 화성화 시키는 방법임.
     
    CREATE TABLE t1 ( REGION VARCHAR2(20), ID NUMBER, a BLOB)
         LOB(a) STORE AS SECUREFILE (
               DEDUPLICATE
               CACHE
    )
    PARTITION BY RANGE (REGION)
          SUBPARTITION BY HASH(ID) SUBPARTITIONS 2 (
             PARTITION p1 VALUES LESS THAN (51)
                lob(a) STORE AS a_t2_p1
                 (SUBPARTITION t2_p1_s1 lob(a) STORE AS a_t2_p1_s1,
                  SUBPARTITION t2_p1_s2 lob(a) STORE AS a_t2_p1_s2),
             PARTITION p2 VALUES LESS THAN (MAXVALUE)
                lob(a) STORE AS a_t2_p2 ( KEEP_DUPLICATES )
                 (SUBPARTITION t2_p2_s1 lob(a) STORE AS a_t2_p2_s1,
                  SUBPARTITION t2_p2_s2 lob(a) STORE AS a_t2_p2_s2)
           );
    

Compression

SecureFile Compression은 테이블이나 인덱스 Compression까지를 의미하는 것은 아님.
다음과 같이 SecureFile로 테이블 생성 시, COMPRESS라고 명시하면 LOB 칼럼이 Compress 됨.
디폴트 Compression 레벨은 MIDIUM임.

 
CREATE TABLE t1 ( a CLOB)
   LOB(a) STORE AS SECUREFILE (
        COMPRESS
        CACHE
   );

다음과 같이 Compression 레벨을 명시할 수 있음.

 
CREATE TABLE t1 ( a CLOB)
   LOB(a) STORE AS SECUREFILE (
        COMPRESS HIGH
        CACHE
   );

특정 파티션 내의 LOB칼럼에만 Compression을 활성화 시키는 방법은 다음과 같음.

  • P1 파티션의 LOB칼럼만이 Compression됨.
     
    CREATE TABLE t1 ( REGION VARCHAR2(20), a BLOB)
       LOB(a) STORE AS SECUREFILE (
          CACHE
       )
       PARTITION BY LIST (REGION) (
            PARTITION p1 VALUES ('x', 'y')
                 LOB(a) STORE AS SECUREFILE (
                     COMPRESS
                 ),
            PARTITION p2 VALUES (DEFAULT)
        );
    

테이블 생성 시, LOB Compression을 비활성화시키는 방법은 다음과 같음.

 
CREATE TABLE t1 ( a CLOB)
    LOB(a) STORE AS SECUREFILE (
         NOCOMPRESS
         CACHE
   );

Encryption

SecureFile을 이용하면 LOB칼럼도 Encryption할 수 있음.
Encryption은 블록 레벨로 이루어지며 LOB Encryption에는 칼럼 레벨 암호화에서 지원되던 NO SALT 옵션은 지원되지 않음.

테이블 생성 시, LOB칼럼을 AES128 알고리즘으로 Encryption하는 방법은 다음과 같음.

 
CREATE TABLE t1 ( a CLOB ENCRYPT USING 'AES128')
    LOB(a) STORE AS SECUREFILE (
         CACHE
    );

테이블의 모든 파티션의 LOB 칼럼을 Encryption하는 방법은 다음과 같음.

 
CREATE TABLE t1 ( REGION VARCHAR2(20), a BLOB)
LOB(a) STORE AS SECUREFILE (
ENCRYPT USING 'AES128'
NOCACHE
FILESYSTEM_LIKE_LOGGING
)
PARTITION BY LIST (REGION) (
PARTITION p1 VALUES ('x', 'y'),
PARTITION p2 VALUES (DEFAULT)
);

Migration

기존의 BasicFile LOB에서 SecureFile로 마이그레이션 하려고 한다면 Online Redefinition을 이용해야 함.
Online Redefinition은

  • 테이블 레벨 및 파티션 레벨로 모두 마이그레이션 가능하며,
  • 마이그레이션 작업 시에도 테이블이나 파티션을 offline 시키지 않아도 됨.

마이그레이션 시에 redo를 생성하면 성능 상의 문제를 야기할 수 있으므로

  • 마이그레이션 시에는 마이그레이션의 대상이 되는 SecureFile의 LOB 칼럼이 NOLOGGING으로 설정되어있는지 반드시 확인하고,
  • 마이그레이션 작업이 끝난 후에 반드시 원래대로 LOGGING으로 변경함.

Online Redefinition 시에는

  • 마이그레이션하려는 기존의 테이블의 LOB 세그먼트와 동일한 크기의 스페이스가 준비되어 있어야 하며,
  • Global Index는 마이그레이션 후에 rebuild 해주어야 함.

Online Redefinition을 이용한 마이그레이션 예는 다음과 같음.

 
REM Grant privileges required for online redefinition.
GRANT EXECUTE ON DBMS_REDEFINITION TO pm;
GRANT ALTER ANY TABLE TO pm;
GRANT DROP ANY TABLE TO pm;
GRANT LOCK ANY TABLE TO pm;
GRANT CREATE ANY TABLE TO pm;
GRANT SELECT ANY TABLE TO pm;

REM Privileges required to perform cloning of dependent objects.
GRANT CREATE ANY TRIGGER TO pm;
GRANT CREATE ANY INDEX TO pm;

CONNECT pm

DROP TABLE cust;
CREATE TABLE cust(c_id NUMBER PRIMARY KEY,
c_zip NUMBER,
c_name VARCHAR(30) DEFAULT NULL,
c_lob CLOB
);

INSERT INTO cust VALUES(1, 94065, 'hhh', 'ttt');

-- Creating Interim Table
-- There is no need to specify constraints because they are
-- copied over from the original table.
CREATE TABLE cust_int(c_id NUMBER NOT NULL,
c_zip NUMBER,
c_name VARCHAR(30) DEFAULT NULL,
c_lob CLOB
) LOB(c) STORE AS SECUREFILE (NOCACHE FILESYSTEM_LIKE_LOGGING);

DECLARE
col_mapping VARCHAR2(1000);

BEGIN
-- map all the columns in the interim table to the original table
col_mapping :=
'c_id c_id , '||
'c_zip c_zip , '||
'c_name c_name, '||
'c_lob c_lob';
DBMS_REDEFINITION.START_REDEF_TABLE('pm', 'cust', 'cust_int', col_mapping);
END;
/

DECLARE
error_count pls_integer := 0;

BEGIN
DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS('pm', 'cust', 'cust_int', 1, TRUE,TRUE,TRUE,FALSE, error_count);
DBMS_OUTPUT.PUT_LINE('errors := ' || TO_CHAR(error_count));
END;
/

EXEC DBMS_REDEFINITION.FINISH_REDEF_TABLE('pm', 'cust', 'cust_int');

-- Drop the interim table
DROP TABLE cust_int;
DESC cust;

-- The following insert statement fails. This illustrates
-- that the primary key constraint on the c_id column is
-- preserved after migration.
INSERT INTO cust VALUES(1, 94065, 'hhh', 'ttt');

SELECT * FROM cust;

실습예제

BasicFile을 이용해서 LOB칼럼을 포함한 테이블을 생성하고, 그 테이블을 SecureFile로 마이그레이션하는 실습

1) 실습에 이용할 SF_DEMO 스키마를 생성하고, CONNECT, RESOURCE 및 EXECUTE ANY PROCEDURE, CREATE ANY DIRECTORY들의 필요 권한들을 부여하자.

SQL> /*== Create a database account for this OBE ==*/
SQL>
SQL> DROP USER sf_demo CASCADE
  2 /

User dropped.

SQL>
SQL> CREATE USER sf_demo IDENTIFIED BY oracle
  2  DEFAULT TABLESPACE users
  3  TEMPORARY TABLESPACE temp
  4  QUOTA UNLIMITED ON users
  5  /
  
User created.

SQL>
SQL> GRANT connect, resource TO sf_demo
  2  /

Grant succeeded.

SQL>
SQL> GRANT EXECUTE ANY PROCEDURE, CREATE ANY DIRECTORY TO sf_demo
  2  /

Grant succeeded.

2) 150MB짜리 테이블 스페이스 두개를 생성한다.
OBE_TBS1은 BasicFile 포맷으로 OBE_TBS2는 SecureFile 포맷으로 LOB을 저장하는데 사용할 것이다.
SecureFile을 사용하기 위해서는 테이블스페이스가 반드시 ASSM 방식으로 생성되어야 한다.

SQL> /*== Create tablespaces to store the LOB tables ==*/
SQL> /*== ==*/
SQL> /*== Note that SecureFile LOB storage requires ASSM.==*/
SQL> /*== The segment allocation unit is 64MB. ==*/
SQL>
SQL> DROP TABLESPACE obe_tbs1 INCLUDING CONTENTS
  2  /
DROP TABLESPACE obe_tbs1 INCLUDING CONTENTS
*
ERROR at line 1:
ORA-00959: tablespace 'OBE_TBS1' does not exist

SQL> CREATE TABLESPACE obe_tbs1
  2  DATAFILE 'obe_tbs1.dbf' SIZE 150M REUSE
  3  EXTENT MANAGEMENT LOCAL
  4  UNIFORM SIZE 64M
  5  SEGMENT SPACE MANAGEMENT AUTO
  6  /

Tablespace created.
SQL>
SQL> DROP TABLESPACE obe_tbs2 INCLUDING CONTENTS
  2 /
DROP TABLESPACE obe_tbs2 INCLUDING CONTENTS
*
ERROR at line 1:
ORA-00959: tablespace 'OBE_TBS2' does not exist

SQL>
SQL> CREATE TABLESPACE obe_tbs2
  2  DATAFILE 'obe_tbs2.dbf' SIZE 150M REUSE
  3  EXTENT MANAGEMENT LOCAL
  4  UNIFORM SIZE 64M
  5  SEGMENT SPACE MANAGEMENT AUTO
  6  /

Tablespace created.

3) SF_DEMO 스키마에 테이블을 생성한다. RESUME라는 BLOB칼럼을 가지는 RESUMES 테이블을 생성한다.
이 LOB칼럼은 BasicFile 포맷으로 저장된다.

SQL> /*== As SF_DEMO, create a table with a LOB that uses BasicFile LOB storage ==*/
SQL>
SQL> connect sf_demo/oracle
Connected.
SQL>
SQL> CREATE TABLE resumes
  2  (id NUMBER, first_name VARCHAR2(15),
  3   last_name VARCHAR2(40), resume BLOB)
  4   LOB(resume) STORE AS BASICFILE
  5  (TABLESPACE obe_tbs1)
  6  /

Table created.

4) BLOB 칼럼에 MS Word 파일을 저장하기 위해서 다음과 같이 Word 파일이 들어있는 디렉토리 패스를 DIRECTORY 객체로 생성한다.
Enter value for directory_name 프롬프트가 떨어지면 Word파일이 들어있는 디렉토리의 전체 경로를 입력한다.

SQL> /*== Create a DIRECTORY object. It is required for accessing the MS Word files ==*/
SQL> /*== to be loaded into the LOB column. Enter the full path to the files, omit ==*/
SQL> /*== the final "/" at the end. ==*/
SQL>
SQL> CREATE OR REPLACE DIRECTORY cwd AS '&directory_name';
Enter value for directory_name: /mnt/hgfs/01/files/
old 1: CREATE OR REPLACE DIRECTORY cwd AS '&directory_name'
new 1: CREATE OR REPLACE DIRECTORY cwd AS '/mnt/hgfs/01/files/'

Directory created.

5) MS Word 파일을 파일시스템에서 읽어 들이는 loadLOBFromBFILE_proc 프로시저를 생성한다.
이 프로시저는 DBMS_LOB 패키지를 이용한다.

SQL> /*== Create the procedure to read the MS Word files and load them into the LOB column ==*/
SQL>
SQL> CREATE OR REPLACE PROCEDURE loadLOBFromBFILE_proc (dest_loc IN OUT BLOB, file_name IN VARCHAR2)
  2  IS
  3    src_loc BFILE := BFILENAME('CWD', file_name);
  4    amount INTEGER := 4000;
  5  BEGIN
  6  
  7    DBMS_LOB.OPEN(src_loc, DBMS_LOB.LOB_READONLY);
  8    amount := DBMS_LOB.GETLENGTH(src_loc);
  9    DBMS_LOB.LOADFROMFILE(dest_loc, src_loc, amount);
 10    DBMS_LOB.CLOSE(src_loc);
 11  
 12  END;
 13  /

Procedure created.

6) 위에서 생성한 loadLOBFromBFILE_proc 을 이용해서 RESUMES 테이블의 LOB칼럼에 insert하는 write_lob 프로시저를 생성한다.

SQL> /*== Create the procedure to insert LOBs into the table ==*/
SQL>
SQL> CREATE OR REPLACE PROCEDURE write_lob (p_file IN VARCHAR2)
  2  IS
  3    i NUMBER;
  4    fn VARCHAR2(15);
  5    ln VARCHAR2(40);
  6    b BLOB;
  7    
  8  BEGIN
  9  DBMS_OUTPUT.ENABLE;
 10  DBMS_OUTPUT.PUT_LINE('Begin inserting rows...');
 11    FOR i IN 1 .. 30 LOOP
 12      fn:=SUBSTR(p_file,1,INSTR(p_file,'.')-1);
 13      ln:=SUBSTR(p_file,INSTR(p_file,'.')+1,LENGTH(p_file)-INSTR(p_file,'.')-4);
 14      INSERT INTO resumes VALUES (i, fn, ln, EMPTY_BLOB())
 15         RETURNING resume INTO b;
 16      loadLOBFromBFILE_proc(b,p_file);
 17      DBMS_OUTPUT.PUT_LINE('Row '|| i ||' inserted.');
 18      END LOOP;
 19    COMMIT;
 20  END;
 21  /
Procedure created.
SQL>
SQL> show errors
No errors.

7) RESUMES 테이블에서 LOB 칼럼을 읽어오는 READ_LOB 프로시저를 생성한다.

SQL> /*== Create the procedure to read LOBs from the table ==*/
SQL>
SQL> CREATE OR REPLACE PROCEDURE read_lob
  2  IS
  3     lob_loc BLOB;
  4       CURSOR resumes_cur IS
  5       SELECT id, first_name, last_name, resume
  6       FROM resumes;
  7     resumes_rec resumes%ROWTYPE;
  8  BEGIN
  9  OPEN resumes_cur;
 10  LOOP
 11    FETCH resumes_cur INTO resumes_rec;
 12     lob_loc := resumes_rec.resume;
 13     DBMS_OUTPUT.PUT_LINE('The length is: '|| DBMS_LOB.GETLENGTH(lob_loc));
 14     DBMS_OUTPUT.PUT_LINE('The ID is: '|| resumes_rec.id);
 15     -- just print out the first 200 bytes of the LOB
 16     -- because DBMS_OUTPUT.PUT_LINE cannot display more than 255 bytes
 17     DBMS_OUTPUT.PUT_LINE('The blob is read: '||
 18     UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(lob_loc,200,1)));
 19    EXIT WHEN resumes_cur%NOTFOUND;
 20  END LOOP;
 21  CLOSE resumes_cur;
 22  END;
 23  /

Procedure created.

SQL> show errors
No errors.

8) 다음과 같이 RESUMES 테이블에 데이터를 insert 한다.

SQL> connect sf_demo/oracle
Connected.
SQL>
SQL> set serveroutput on
SQL> set verify on
SQL> set term on
SQL> set lines 200
SQL>
SQL> timing start load_data
SQL> exec write_lob('karl.brimmer.doc');
Begin inserting rows...
Row 1 inserted.
Row 2 inserted.
...
Row 29 inserted.
Row 30 inserted.

PL/SQL procedure successfully completed.

SQL> exec write_lob('monica.petera.doc');
Begin inserting rows...
Row 1 inserted.
Row 2 inserted.
...
Row 29 inserted.
Row 30 inserted.

PL/SQL procedure successfully completed.

SQL> exec write_lob('david.sloan.doc');
Begin inserting rows...
Row 1 inserted.
Row 2 inserted.
...
Row 29 inserted.
Row 30 inserted.

PL/SQL procedure successfully completed.

SQL> timing stop
timing for: load_data
Elapsed: 00:00:03.84

9) 다음은 위에서 생성한 RESUMES 테이블을 SecureFile 포맷을 이용하는 테이블로 Online Redefinition을 이용해서 마이그레이션하는 과정이다.
interim 테이블을 생성하고 LOB칼럼을 OBE_TBS2 테이블스페이스에 SecureFile 포맷으로 저장되도록 설정한다.
Compression 및 De-duplication도 설정해 본다.

SQL> /*== Create the interim table for online redefinition ==*/
SQL> /*==
SQL> /*== Note that the recommended practice is to enable ==*/
SQL> /*== COMPRESSION and DEDUPLICATION at table createion ==*/
SQL> /*== time. Also, the ALTER TABLE SHRINK operation is ==*/
SQL> /*== not yet supported for SecureFiles LOBs in ==*/
SQL> /*== release 1 of Oracle Database 11g. ==*/
SQL>
SQL> CREATE TABLE sf_demo.resumes_interim
  2  (id NUMBER, first_name VARCHAR2(15),
  3   last_name VARCHAR2 (40), resume BLOB)
  4   LOB (resume) STORE AS SECUREFILE
  5  (TABLESPACE obe_tbs2
  6   COMPRESS HIGH
  7   DEDUPLICATE)
  8  /
  
Table created.

10) DBMS_REDEFINITION 패키지를 이용해서 Online Redefinition 작업을 수행한다.
이 작업 중에도 RESUMES 테이블은 Online 상태이다.

SQL> /*== Perform the online redefinition ==*/
SQL>
SQL> DECLARE
  2   error_count PLS_INTEGER := 0;
  3  BEGIN
  4  
  5  DBMS_REDEFINITION.START_REDEF_TABLE
  6  ('sf_demo', 'resumes', 'resumes_interim',
  7  'id id, first_name first_name, last_name last_name, resume resume',
  8  OPTIONS_FLAG => DBMS_REDEFINITION.CONS_USE_ROWID);
  9  
 10  DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS
 11  ('sf_demo', 'resumes', 'resumes_interim',
 12  1, true,true,true,false, error_count);
 13  
 14  DBMS_OUTPUT.PUT_LINE('Errors := ' || TO_CHAR(error_count));
 15  
 16  DBMS_REDEFINITION.FINISH_REDEF_TABLE
 17  ('sf_demo', 'resumes', 'resumes_interim');
 18  
 19  END;
 20  /

Erors := 0

PL/SQL procedure successfully completed.

11) 작업이 끝나면 interim 테이블은 삭제 가능하다.

SQL> /*== Drop the interim table ==*/
SQL>
SQL> DROP TABLE sf_demo.resumes_interim
  2  /
Table dropped.

12) 마이그레이션된 LOB 칼럼이 이제 obe_tbs2 테이블스페이스에 위치하게 된다.
DBA_SEGMENT 뷰를 이용해서 LOB 세그먼트의 서브타입이 SECUREFILE임을 확인하자.

SQL> /*== Check the segment type of the migrated LOB ==*/
SQL> /*== ==*/
SQL> /*== Note that the segment subtype for ==*/
SQL> /*== SecureFiles LOB storage is SECUREFILE ==*/
SQL>
SQL> SELECT segment_name, segment_type, segment_subtype
  2  FROM dba_segments
  3  WHERE tablespace_name = 'OBE_TBS2'
  4  AND segment_type = 'LOBSEGMENT'
  5  /
  
SEGMENT_NAME SEGMENT_TYPE SEGMENT_SU
--------------------------- ------------------ ---------------
SYS_LOB0000070998C00004$$ LOBSEGMENT SECUREFILE

13) dba_lobs 뷰를 확인하면 SecureFile LOB 세그먼트에 Compression과 De-duplication이 설정된 것을 확인할 수 있다.

SQL> /*== Check the DBA_LOBS data dictionary view for ==*/
SQL> /*== information on the SecureFiles COMPRESSION ==*/
SQL> /*== and DEDUPLICATION settings ==*/
SQL>
SQL> SELECT column_name, segment_name,
  2         compression, deduplication, securefile
  3  FROM dba_lobs
  4  WHERE owner = 'SF_DEMO' and table_name = 'RESUMES'
  5 /
  
COLUMN_NAME SEGMENT_NAME COMPRE DEDUPLICATION SEC
------------ ------------------------------ ------ --------------- ---
RESUME SYS_LOB0000070998C00004$$ HIGH LOB YES

결론

SecureFile은 정형 또는 비정형 데이터를 아우르는 모든 데이터를 관리할 수 있게 하면서도, 좋은 성능을 보장하는 Oracle 11g의 새로운 기능임.
SecureFile을 이용하면 기업내의 관계형 혹은 정형 데이터에서 그 외의 모든 비정형 데이터까지 데이터베이스 안에 저장하고 관리할 수 있으며,
일반적으로 사용되는 파일 시스템에 견줄만한 성능도 보장된다는 것을 테스트 보고를 통해 확인함.

문서정보

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.