신규 기능 - Partition Exchange
Partition Exchange
테스트 환경
OS : OEL release 7.2
Tibero : 6 FS05
Partition Exchange
- Partition Exchange 기능은 Partition을 Exchange 하는 기능이다. (
이런건 이제 익숙하다) - 우선, Partition이란
Partitioned Table
에서 하나의 독립된 공간을 의미하며
Exchange는 말 그대로 “맞바꿈”을 의미한다. - 또한, 여기서 “맞바꿈”의 대상이 되는 공간은
Non-Partitioned Table
이다. - 즉,
Partitioned Table
에서 하나의 독립된 공간과Non-Partitioned Table
을 “맞바꾸는” 기능이다. - 해당 기능을 통해
Partitioned Table
을Non-Partitioned Table
로 변경하거나
Non-Partitioned Table
(이하Table
)을Partitioned Table
로 변경할 수 있다.
기능 테스트
- Table을 변경하는 작업으로
ALTER TABLE
1을 기본구문으로 한다.
Partition Exchange 기본 구문
Table
과Partition
을 상호교체 시 기본적으로Partition key
에 위배되는 값이 있는지 검증하게 된다.
(WITH VALIDATION으로 동작한다.)- WITHOUT VALIDATION 옵션 적용 시 위의 검증단계가 생략된다.
(검증단계가 생략되는 만큼 빠르다.) Partitioned Table
과Table
어느 쪽이라도Index
가 있는 경우
반대쪽 Table에도 동일한Column
에Index
를 모두 생성해야 한다.- 즉, 모든
Index key Column
을 동일하게 맞춰야 한다. - 다만, 교체하게 되면 인덱스가
UNUSABLE
상태가 된다.
(위 두 가지 경우를 회피하기 위한 파라미터가 5에는Hidden
으로 존재한다.) - 따라서, 경우에 따라 삭제 후 재생성이 빠를 수 있다.
- 해당 구문은 아래와 같다.
SQL> ALTER TABLE table_name -- Partitioned Table 명시
EXCHANGE
PARTITION|SUBPARTITION partition_name -- 해당 Partition 명시
WITH TABLE table_name -- Non-Partitioned Table 명시
[WITH|WITHOUT VALIDATION] -- 검증 여부(생략시 검증 수행)
;
Test 사전 준비
Partitioned Table
생성하고 데이터를 적재한다.
SQL> /* Partitioned Table 생성(TEST_PART) */
SQL> CREATE TABLE TEST_PART
(A NUMBER,
B NUMBER,
C VARCHAR(100),
D DATE)
NOLOGGING
PARTITION BY RANGE (A)
(PARTITION PART_01 VALUES LESS THAN (1),
PARTITION PART_02 VALUES LESS THAN (2),
PARTITION PART_03 VALUES LESS THAN (3),
PARTITION PART_04 VALUES LESS THAN (4))
;
Table 'TEST_PART' created.
SQL> /* 데이터 적재 */
SQL> INSERT INTO TEST_PART
SELECT MOD(LEVEL,4) A,
LEVEL B,
DBMS_RANDOM.STRING('X',100) C,
TO_DATE(SYSDATE + LEVEL/24/60/60) D
FROM DUAL
CONNECT BY LEVEL < 1000000
;
999999 rows inserted.
SQL> COMMIT;
Commit completed.
-Local Partitioned Index
를 생성한다.
SQL> /* Local Partitioned Index 생성 */
SQL> CREATE INDEX TEST_PART_IDX ON TEST_PART (A,B) LOCAL NOLOGGING ;
Index 'TEST_PART_IDX' created.
Talbe
을 생성하고 데이터를 적재 및Index
를 생성한다.
SQL> /* Non-Partitioned Table 생성
- 교체할 PART_02 Partition의 데이터를 적재 */
SQL> CREATE TABLE TEST_NON
TABLESPACE USR2
AS
SELECT * FROM TEST_PART PARTITION(PART_02)
WHERE B < 500000
;
Table 'TEST_NON' created.
SQL> /* Index 생성 */
SQL> CREATE INDEX TEST_NON_IDX ON TEST_NON (A,B) TABLESPACE USR2 ;
Index 'TEST_NON_IDX' created.
- 생성된
Table
과Index
의 정보를 조회한다.
SQL> /* 정보 조회 */
SQL> -- SEGMENT별 Tablespace 정보
SQL> SELECT SEGMENT_NAME, PARTITION_NAME, TABLESPACE_NAME
FROM USER_SEGMENTS
ORDER BY 1, 2
;
SEGMENT_NAME PARTITION_NAME TABLESPACE_NAME
-------------------- --------------------- --------------------
TEST_NON USR2
TEST_NON_IDX USR2
TEST_PART PART_01 USR
TEST_PART PART_02 USR
TEST_PART PART_03 USR
TEST_PART PART_04 USR
TEST_PART_IDX PART_01 USR
TEST_PART_IDX PART_02 USR
TEST_PART_IDX PART_03 USR
TEST_PART_IDX PART_04 USR
10 rows selected.
SQL> -- Index 상태 조회
SQL> SELECT INDEX_NAME, STATUS
FROM USER_INDEXES
ORDER BY 1
;
INDEX_NAME STATUS
--------------------- --------
TEST_NON_IDX VALID
TEST_PART_IDX VALID
2 rows selected.
SQL> -- Index Partition 상태 조회
SQL> SELECT INDEX_NAME, PARTITION_NAME, STATUS
FROM USER_IND_PARTITIONS
ORDER BY 1, 2
;
INDEX_NAME PARTITION_NAME STATUS
--------------------- --------------------- --------
TEST_PART_IDX PART_01 USABLE
TEST_PART_IDX PART_02 USABLE
TEST_PART_IDX PART_03 USABLE
TEST_PART_IDX PART_04 USABLE
4 rows selected.
Partition Exchange 수행
ALTER TABLE
구문으로 Partition Exchange를 수행하다.- 대상
Partition
은PART_02
이다.
SQL> ALTER TABLE TEST_PART EXCHANGE PARTITION PART_02 WITH TABLE TEST_NON ;
Table 'TEST_PART' altered.
- 생성된
Index key column
에 차이가 있는 경우TBR-7280: Index key columns do not match.
에러가 발생한다.
$ tberr 7280
/*
* err: -7280
* name: ERROR_DDL_DIFFERENT_INDEX_COLUMN
* desc: Index key columns do not match.
* cause: Index key columns in the tables do not match.
* action: Unable to execute this command.;
*/
- 변경된
SEGMENT
를 정보 조회하면Tablespace
가 변경된 것을 확인할 수 있다. PART_02
와TEST_NON
의Tablespace
가 바뀌었다.
(Index
도 마찬가지)
SQL> -- SEGMENT별 Tablespace 정보
SQL> SELECT SEGMENT_NAME, PARTITION_NAME, TABLESPACE_NAME
FROM USER_SEGMENTS
ORDER BY 1, 2
;
SEGMENT_NAME PARTITION_NAME TABLESPACE_NAME
-------------------- --------------------- --------------------
TEST_NON USR
TEST_NON_IDX USR
TEST_PART PART_01 USR
TEST_PART PART_02 USR2
TEST_PART PART_03 USR
TEST_PART PART_04 USR
TEST_PART_IDX PART_01 USR
TEST_PART_IDX PART_02 USR2
TEST_PART_IDX PART_03 USR
TEST_PART_IDX PART_04 USR
10 rows selected.
Index
의 상태를 조회하면UNUSABLE
인 것을 알 수 있다.Index Partition
의 경우 교체된PART_02
만UNUSABLE
상태가 된다.- 단,
Local Partitioned Index
인 경우만 그렇고Global Partitioned Index
의 경우 모든Index Partition
이UNUSABLE
상태가 된다.
SQL> -- Index 상태 조회
SQL> SELECT INDEX_NAME, STATUS
FROM USER_INDEXES
ORDER BY 1
;
INDEX_NAME STATUS
--------------------- --------
TEST_NON_IDX UNUSABLE
TEST_PART_IDX UNUSABLE
2 rows selected.
SQL> -- Index Partition 상태 조회
SQL> SELECT INDEX_NAME, PARTITION_NAME, STATUS
FROM USER_IND_PARTITIONS
ORDER BY 1, 2
;
INDEX_NAME PARTITION_NAME STATUS
--------------------- --------------------- --------
TEST_PART_IDX PART_01 USABLE
TEST_PART_IDX PART_02 UNUSABLE
TEST_PART_IDX PART_03 USABLE
TEST_PART_IDX PART_04 USABLE
4 rows selected.
Partition Exchange 후처리
- 미리 언급했듯이
Index
가 문제가 된다. UNUSABLE
상태이므로REBUILD
가 필요하다.INDEX REBUILD
의 경우 필요한Index
에만 수행하면 된다.- 사실 특정 파티션의 인덱스를 재생성할 수 있는 기능2도 신규기능이다.
(하지만 이것도 전에 되던 거다.) Global Partitioned Index
의 경우Index
전체REBUILD
가 필요하다.
SQL> -- Index Partition의 REBUILD 수행
SQL> ALTER INDEX TEST_PART_IDX REBUILD PARTITION PART_02 ;
Index 'TEST_PART_IDX' altered.
SQL> -- Index의 REBUILD 수행
SQL> ALTER INDEX TEST_NON_IDX REBUILD ;
Index 'TEST_NON_IDX' altered.
Index
상태를 조회하면VALID
또는USABLE
인 것을 알수 있다.
SQL> -- Index 상태 조회
SQL> SELECT INDEX_NAME, STATUS
FROM USER_INDEXES
ORDER BY 1
;
INDEX_NAME STATUS
--------------------- --------
TEST_NON_IDX VALID
TEST_PART_IDX VALID
2 rows selected.
SQL> -- Index Partition 상태 조회
SQL> SELECT INDEX_NAME, PARTITION_NAME, STATUS
FROM USER_IND_PARTITIONS
ORDER BY 1, 2
;
INDEX_NAME PARTITION_NAME STATUS
--------------------- --------------------- --------
TEST_PART_IDX PART_01 USABLE
TEST_PART_IDX PART_02 USABLE
TEST_PART_IDX PART_03 USABLE
TEST_PART_IDX PART_04 USABLE
4 rows selected.
Partition Key 위배 시
- 해당 파트는
Table
에Partition Key
를 위배하는 데이터가 있는 경우
WITHOUT VALIDATION
옵션을 통해 교체 가능 한지에 대한 테스트다. - 하지만, 실제 대용량의
Table
을 교체하는 경우 해당 옵션을 사용하면 검증단계를 생략하므로 좀 더 효율적일 수 있다. TEST_NON
의 A 컬럼에는 ‘1’만 들어있다. (기존Partition key
가 ‘1’이었다)- 테스트를 위해
Table
에 ‘1’이 넘는 데이터를 넣어보자.
SQL> INSERT INTO TEST_NON
SELECT CEIL(DBMS_RANDOM.VALUE(1,10)) A,
LEVEL B,
DBMS_RANDOM.STRING('X',100) C,
TO_DATE(SYSDATE + LEVEL/24/60/60) D
FROM DUAL
CONNECT BY LEVEL <= 1000
;
1000 rows inserted.
SQL> COMMIT ;
Commit completed.`
- 데이터가 추가된 상태에서 Partition Exchange 시도하면 아래와 같은 에러가 발생한다.
SQL> ALTER TABLE TEST_PART EXCHANGE PARTITION PART_02 WITH TABLE TEST_NON ;
TBR-7287: Some rows in the table are invalid for the specified partition.
- 에러 내용은 아래와 같다.
tberr -7287
/*
* err: -7287
* name: ERROR_DDL_ROWS_DONT_QUALIFY_FOR_PARTITION
* desc: Some rows in the table are invalid for the specified partition.
* cause: Some rows cannot be inserted in the specified partition.
* action: Remove the invalid rows and try again.;
*/
- 해당 상황이 비정상적인 경우 해당 데이터를 삭제해야 한다.
- 하지만, 정상적이라고 판단되는 경우 강제로라도 교체가 이루어져야 한다.
- 따라서,
WITHOUT VALIDATION
옵션으로 Partition Exchange 수행한다고 해보자.
SQL> ALTER TABLE TEST_PART EXCHANGE PARTITION PART_02 WITH TABLE TEST_NON WITHOUT VALIDATION ;
Table 'TEST_PART' altered.
- 변경된
SEGMENT
를 정보 조회하면Tablespace
가 변경된 것을 확인할 수 있다.
SQL> -- SEGMENT별 Tablespace 정보
SQL> SELECT SEGMENT_NAME, PARTITION_NAME, TABLESPACE_NAME
FROM USER_SEGMENTS
ORDER BY 1, 2
;
SEGMENT_NAME PARTITION_NAME TABLESPACE_NAME
-------------------- --------------------- --------------------
TEST_NON USR2
TEST_NON_IDX USR2
TEST_PART PART_01 USR
TEST_PART PART_02 USR
TEST_PART PART_03 USR
TEST_PART PART_04 USR
TEST_PART_IDX PART_01 USR
TEST_PART_IDX PART_02 USR
TEST_PART_IDX PART_03 USR
TEST_PART_IDX PART_04 USR
10 rows selected.
Index
의 상태 역시UNUSABLE
인 것을 알 수 있다.
SQL> -- Index 상태 조회
SQL> SELECT INDEX_NAME, STATUS
FROM USER_INDEXES
ORDER BY 1
;
INDEX_NAME STATUS
--------------------- --------
TEST_NON_IDX UNUSABLE
TEST_PART_IDX UNUSABLE
2 rows selected.
SQL> -- Index Partition 상태 조회
SQL> SELECT INDEX_NAME, PARTITION_NAME, STATUS
FROM USER_IND_PARTITIONS
ORDER BY 1, 2
;
INDEX_NAME PARTITION_NAME STATUS
--------------------- --------------------- --------
TEST_PART_IDX PART_01 USABLE
TEST_PART_IDX PART_02 UNUSABLE
TEST_PART_IDX PART_03 USABLE
TEST_PART_IDX PART_04 USABLE
4 rows selected.
- 기존과 동일하게 후처리(
REBUILD
)를 해준다.
SQL> -- Index Partition의 REBUILD 수행
SQL> ALTER INDEX TEST_PART_IDX REBUILD PARTITION PART_02 ;
Index 'TEST_PART_IDX' altered.
SQL> -- Index의 REBUILD 수행
SQL> ALTER INDEX TEST_NON_IDX REBUILD ;
Index 'TEST_NON_IDX' altered.
- 실제 교체된
Partition
(PART_02
)의 데이터를 조회하면
Partition key
에 위배되는 데이터가 존재하는 것을 알 수 있다.
SELECT COUNT(*) FROM TEST_PART PARTITION(PART_02)
WHERE A <> 1
;
COUNT(*)
----------
1000
1 row selected.
여담
이전 테스트 때문에 Tibero6 FS05 최신 패치를 먹였다. (본 테스트와는 상관없다)
Tibero 4 이후 추가된 것으로 보인다. (4 SP1인진 정확하지 않다)
Tibero 6에서보다 오히려 Tibero 5에서는 파라미터를 먹이면 더 유용하게 쓸 수 있다.
(파라미터가 Hidden이라 문제지)
본의 아니게 두 가지 기능을 테스트했다.
'Tibero > Tibero6' 카테고리의 다른 글
신규 기능 - Recursive With (0) | 2017.05.29 |
---|---|
신규 기능 - 원격 저장소를 가진 실체화 뷰 (0) | 2017.05.22 |
신규기능 - BINARY TIP (0) | 2017.01.03 |
신규 기능 - Listener Multi-port (0) | 2016.11.10 |
신규 기능 - OFFLINE FOR DROP (0) | 2016.11.03 |
댓글