반응형

[2025-07-05] 비파티션 테이블을 파티션 테이블로 온라인 전환 (12cR2 New features) (12cR2에서 테스트)

 

[실습 환경]
OS : Oracle Linux Server 7.9 (Linux 5.4.17-2102.201.3.el7uek.x86_64)
DB : Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
     (Database Jan 2022 Release Update : 12.2.0.1.220118 (33587128))
RAC1 : rdb01p(192.168.0.11) : PRDB1
RAC2 : rdb02p(192.168.0.12) : PRDB2

 

이것은 오라클 12.2 릴리스의 새로운 기능 중 하나임
비 파티션 테이블을 애플리케이션 다운타임 없이 온라인으로 파티션 테이블로 변환할 수 있으며, 이는 DML 활동에 영향을 미치지 않음
지금까지 이 활동에서는 DBMS_REDEFINITION 패키지를 사용했었음

하지만 Oracle 12.2 버전에서는 이 작업이 훨씬 간소화됨

 

1. 테스트 테이블 생성 (비파티션 테이블 생성)

 

DROP TABLE TUNER.TB_ORD_NON_PART PURGE;
CREATE TABLE TUNER.TB_ORD_NON_PART
(
  CUST_NO VARCHAR2(10) NOT NULL
, ORD_DT VARCHAR2(14) NOT NULL
, ORD_TOT_AMT NUMBER(15, 2) NOT NULL
, ORD_STS_CD VARCHAR2(6) NOT NULL
, INPUT_ID VARCHAR2(20) NOT NULL
, INPUT_DT VARCHAR2(14) NOT NULL
, UPDT_ID VARCHAR2(20)
, UPDT_DT VARCHAR2(14)
)
TABLESPACE TUNER_DATA1
;

 

ALTER TABLE TUNER.TB_ORD_NON_PART NOLOGGING;

 

INSERT INTO TUNER.TB_ORD_NON_PART SELECT * FROM TUNER.TB_ORD;
COMMIT;

 

ALTER TABLE TUNER.TB_ORD_NON_PART LOGGING;


CREATE UNIQUE INDEX TUNER.PK_TB_ORD_NON_PART
ON TUNER.TB_ORD_NON_PART (CUST_NO,ORD_DT)
TABLESPACE TUNER_IDX1;

 

ALTER TABLE TUNER.TB_ORD_NON_PART
ADD CONSTRAINT PK_TB_ORD_NON_PART PRIMARY KEY (CUST_NO,ORD_DT);


BEGIN
  DBMS_STATS.GATHER_TABLE_STATS
  (
       OWNNAME          => 'TUNER'
     , TABNAME          => 'TB_ORD_NON_PART'
     , ESTIMATE_PERCENT => DBMS_STATS.AUTO_SAMPLE_SIZE
     , GRANULARITY      => 'ALL' --'ALL' - Gathers all (subpartition, partition, and global) statistics
     , CASCADE          => TRUE
     , METHOD_OPT       => 'FOR ALL COLUMNS SIZE 1'
  , DEGREE           => 1
  , NO_INVALIDATE    => TRUE --TRUE: Dependent cursors are not invalidated, FALSE: Dependent cursors are marked for immediate invalidation
  );
END;
/

TB_ORD_NON_PART
---------------
Rows=10,000,000                         Blocks=100,877
Empty_Blocks=0                          Avg_Space=0
Chain_Count=0                           Avg_Row_Length=67
Avg_Space_Freelist_Blocks=0             Freelist_Blocks=0
Sample_Size=10,000,000                  Last_Analyzed='2025/07/06 00:33:26'
Partitioned='NO'                        Tablespace='TUNER_DATA1'


  Column Name                      Nullable Column Type           Distinct    Buckets
  -------------------------------- -------- ------------------- ---------- ----------
  CUST_NO                          NOT NULL VARCHAR2(10)           995,520          1
  ORD_DT                           NOT NULL VARCHAR2(14)         9,878,528          1
  ORD_TOT_AMT                      NOT NULL NUMBER(15,2)               447          1
  ORD_STS_CD                       NOT NULL VARCHAR2(6)                  4          1
  INPUT_ID                         NOT NULL VARCHAR2(20)        10,000,000          1
  INPUT_DT                         NOT NULL VARCHAR2(14)                 1          1
  UPDT_ID                                   VARCHAR2(20)                 0          0
  UPDT_DT                                   VARCHAR2(14)                 0          0

  INDEX
  -----------------------------------------------------------------------------
  PK_TB_ORD_NON_PART : CUST_NO,ORD_DT
    Type='NORMAL', Uniq='YES', Distinct=10,300,810, Rows=10,300,810, Last_Analyzed='2025/07/06 00:33:29'

 

2. ONLINE으로 비파티션 테이블을 파티션 테이블로 전환

 

ALTER TABLE TUNER.TB_ORD_NON_PART MODIFY PARTITION BY RANGE (ORD_DT)
(
  PARTITION P_BEF_2020 VALUES LESS THAN ('20200101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2020      VALUES LESS THAN ('20210101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2021      VALUES LESS THAN ('20220101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2022      VALUES LESS THAN ('20230101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2023      VALUES LESS THAN ('20240101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2024      VALUES LESS THAN ('20250101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2025      VALUES LESS THAN ('20260101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2026      VALUES LESS THAN ('20270101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2027      VALUES LESS THAN ('20280101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2028      VALUES LESS THAN ('20290101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2029      VALUES LESS THAN ('20300101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P2030      VALUES LESS THAN ('20310101') TABLESPACE TUNER_DATA1 NOCOMPRESS
, PARTITION P_AFT_2033 VALUES LESS THAN (MAXVALUE)   TABLESPACE TUNER_DATA1 NOCOMPRESS
)
ONLINE;
--> 해당 작업 시 인덱스 관련 옵션을 주지 않을 경우 인덱스는
--> 인덱스 구성 칼럼에 파티션 키가 속하는 경우는 LOCAL PARTITION INDEX로 만들어진다.

   (예 : 인덱스가 CUST_NO+ORD_DT인 경우 파티션 키인 ORD_DT가 인덱스 구성 칼럼에 포함되므로 LOCAL 파티션 인덱스로 생성됨)
--> 그렇지 않으면 GLOBAL NON-PARTITION INDEX로 만들어진다.

--> 인덱스 관련 옵션은 아래와 같이 주면됨 (인덱스 글로벌로 할지 LOCAL로 할지 지정가능)
UPDATE INDEXES
(
  <인덱스명> GLOBAL
, <인덱스명> LOCAL
);

 

--작업 중 새로운 세션을 열어서-------------------------------------------------------
UPDATE TUNER.TB_ORD_NON_PART SET UPDT_ID = '1' WHERE CUST_NO = 'C000001961';
DELETE TUNER.TB_ORD_NON_PART WHERE CUST_NO = 'C000001961';
--> DML작업이 가능함

ROLLBACK;
-------------------------------------------------------------------------------------

TB_ORD_NON_PART
---------------
Rows=10,000,000                         Blocks=100,877
Empty_Blocks=0                          Avg_Space=0
Chain_Count=0                           Avg_Row_Length=67
Avg_Space_Freelist_Blocks=0             Freelist_Blocks=0
Sample_Size=10,000,000                  Last_Analyzed='2025/07/06 00:33:26'
Partitioned='YES'

  Column Name                      Nullable Column Type           Distinct    Buckets
  -------------------------------- -------- ------------------- ---------- ----------
  CUST_NO                          NOT NULL VARCHAR2(10)           995,520          1
  ORD_DT                           NOT NULL VARCHAR2(14)         9,878,528          1
  ORD_TOT_AMT                      NOT NULL NUMBER(15,2)               447          1
  ORD_STS_CD                       NOT NULL VARCHAR2(6)                  4          1
  INPUT_ID                         NOT NULL VARCHAR2(20)        10,000,000          1
  INPUT_DT                         NOT NULL VARCHAR2(14)                 1          1
  UPDT_ID                                   VARCHAR2(20)                 0          0
  UPDT_DT                                   VARCHAR2(14)                 0          0

  Table Partition
  -----------------------------------------------------------------------------
  Type = Range Partition
  Keys = ORD_DT

  INDEX
  -----------------------------------------------------------------------------
  PK_TB_ORD_NON_PART : CUST_NO,ORD_DT
    Partition=LOCAL NON_PREFIXED
    Type='NORMAL', Uniq='YES', Distinct=1,005,198, Rows=10,000,000, Last_Analyzed='2025/07/06 00:40:14'

 

--테이블 메타 데이터 출력하는 법 (최종 확인 시 사용)

BEGIN
  DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'TABLESPACE',   true);
  DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE',      true);
  DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SEGMENT_ATTRIBUTES', true);
  DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'CONSTRAINTS',  true);
  DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'REF_CONSTRAINTS', false);
  DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM, 'SQLTERMINATOR', true);
  dbms_metadata.set_transform_param(dbms_metadata.session_transform, 'PRETTY', true);
END;
/

SELECT DBMS_METADATA.GET_DDL('TABLE', 'TB_ORD_NON_PART', 'TUNER') FROM DUAL;
SELECT DBMS_METADATA.GET_DDL('INDEX', INDEX_NAME, 'TUNER') FROM DBA_INDEXES WHERE TABLE_OWNER = 'TUNER' AND TABLE_NAME = 'TB_ORD_NON_PART';
SELECT DBMS_METADATA.GET_DDL('CONSTRAINT', CONSTRAINT_NAME, 'TUNER') FROM DBA_CONSTRAINTS WHERE OWNER = 'TUNER' AND TABLE_NAME = 'TB_ORD_NON_PART';

반응형

+ Recent posts