How to Backup Partition of Range Partitioned Table with Local Indexes

Goal
You have a range partitioned table with local indexes on it. As a part of policy or to save disk space being used by the tables, you would like to archive the data so that if needed you can restore the data back.


Note: - This document is applicable only for range partitioned table with local indexes. In case of other type of partitioning or with global indexes , the solution will differ.

 

Solution
Below procedure explains how to take a backup of range partitioned table. Also if needed, the partition can be restored back.

To explain it better, following example is being taken. Steps 1- 2 can be skipped as this is taken for creating a test table.

1)Create a range partitioned table
CREATE TABLE four_seasons
(
one DATE,
two VARCHAR2(60),
three NUMBER
)
PARTITION BY RANGE ( one)
(
PARTITION quarter_one
VALUES LESS THAN ( TO_DATE('01-aug-1998','dd-mon-yyyy')),
PARTITION quarter_two
VALUES LESS THAN ( TO_DATE('01-sep-1998','dd-mon-yyyy')),
PARTITION quarter_three
VALUES LESS THAN ( TO_DATE('01-oct-1998','dd-mon-yyyy')),
PARTITION quarter_four
VALUES LESS THAN ( TO_DATE('01-nov-1998','dd-mon-yyyy')))
TABLESPACE DIRK_DATA;
2) Create a local index


3) Verify the tables and index name by querying the user_tab_partitions and user_ind_partitions


SQL > select TABLE_NAME,PARTITION_NAME,NUM_ROWS,TABLESPACE_NAME from USER_TAB_PARTITIONS;


TABLE_NAME PARTITION_NAME NUM_ROWS TABLESPACE_NAME
------------------------------ ------------------------------ ---------- ------------------------------
FOUR_SEASONS QUARTER_ONE DIRK_DATA
FOUR_SEASONS QUARTER_TWO DIRK_DATA
FOUR_SEASONS QUARTER_THREE DIRK_DATA
FOUR_SEASONS QUARTER_FOUR DIRK_DATA


select INDEX_NAME,PARTITION_NAME,NUM_ROWS,TABLESPACE_NAME from user_ind_PARTITIONS;

INDEX_NAME PARTITION_NAME NUM_ROWS TABLESPACE_NAME
------------------------------ ------------------------------ ---------- ------------------------------
I_FOUR_SEASONS_L QUARTER_ONE 2542 DIRK_DATA
I_FOUR_SEASONS_L QUARTER_TWO 2542 DIRK_DATA
I_FOUR_SEASONS_L QUARTER_THREE 2460 DIRK_DATA
I_FOUR_SEASONS_L QUARTER_FOUR 2456 DIRK_DATA


Here in this test case, we wish to archive partition QUARTER_ONE. Now the intended operation can be performed using two ways

1) Using drop partition and then split partition
2) Using truncate partition

1) Using drop partition and then split partition

This operation can also be performed by either taking export dump of partition or using exchange partition method

A) By using exp/imp utility for relevant partition

 Here we will be exporting the partition which has to be dropped to a export file. And if needed, same file can be used to recover the partition

1)Take a export dump of partition

If you use tablename:partitionname, the specified table must be partitioned, and partitionname must be the name of one of its partitions or sub-partitions.


exp userid=abc/abc file=partition.dmp tables=four_seasons:quarter_one rows=y

 

Please make sure that the export is done successfully and there are no errors.

2)Drop the partition


SQL > alter table FOUR_SEASONS drop partition QUARTER_ONE;

Table altered.

 

3) Now in case we feel the need to restore the data, then we will have to create the partition to restore the data. The partition to be created cannot be added using add partition clause as it is lower then the range of existing partition QUARTER_FOUR.

You will receive following errors
ERROR at line 1:ORA-14074: partition bound must collate higher than that of the last partition
Therefore we will have to split the partition. The first of the resulting two new partitions includes all rows in the original partition whose partitioning key column values map lower that the specified value (which is null here). The second partition contains all rows whose partitioning key column values map greater than or equal to the specified value.


SQL > alter table four_seasons split PARTITION quarter_two at (
TO_DATE('01-aug-1998','dd-mon-yyyy')) into ( PARTITION quarter_one, PARTITION quarter_two);

Table altered.

 

4) Import the partition again with ignore=y

we need to set ignore=y as the export dump will contain the table definition and while importing it will give error message.


imp userid=abc/abc file=partition.dmp tables=four_seasons:quarter_one rows=y ignore=y


This will automatically create the table partition in the same partition as the partition which is being split. Similarly  index  will be created in partition in  the same partition as the index partition which is being split.


B )Using exchange partition

ALTER TABLE EXCHANGE PARTITION can be used to convert a partition (or subpartition) into a non-partitioned table and a non-partitioned table into a partition (or subpartition) of a partitioned table by exchanging their data and index segments.

1)Create a non partitioned table


SQL > create table FOUR_SEASONS_non_part_1 as select * from four_seasons where 1=2;


Please note that the CTAS will not create the constraints (including not null) in the new table. Therefore the constraints will have to be created. This is necessary as you might get errors while exchanging partition if table structure does not match.

2)Exchange the partition data

 

SQL > Alter table FOUR_SEASONS EXCHANGE partition QUARTER_ONE with table FOUR_SEASONS_non_part_1;

Table altered.

SQL > select count(*) from FOUR_SEASONS_non_part_1;

COUNT(*)
----------
2542


3)Take the export of non-partitioned table and drop the table.

4.1.1) Drop the partition

 

SQL > alter table FOUR_SEASONS drop partition QUARTER_ONE;

Table altered.


4.1.2) Now to restore the partition again, we will split the partition QUARTER_TWO (same reasoning as above)


SQL > alter table four_seasons split PARTITION quarter_two at (
TO_DATE('01-aug-1998','dd-mon-yyyy')) into ( PARTITION quarter_one, PARTITION quarter_two);

Table altered.

 

4.1.3) Import the non-partitioned table and Insert data into FOUR_SEASON table. As all the data in FOUR_SEASONS_non_part_1 is less then '01-aug-1998' , it will be loaded into partition QUARTER_ONE


SQL > insert into FOUR_SEASONS select * from FOUR_SEASONS_non_part_1;

2542 rows created.

SQL > commit;

 


OR


You can use partition exchange method again to insert the data. Please note that once you exchange the non-partition table with partition table, then non-partition table will not have any rows.


SQL > Alter table FOUR_SEASONS EXCHANGE partition QUARTER_ONE with table FOUR_SEASONS_non_part_1;

Table altered.

 

 

OR


2) Using truncate partition

Here we are not dropping the partition and we are just truncating the partition. This will release the space occupied by the table and also avoid the creation of partition again (if we intend to reuse it). Please note that this is in continuation with point 3 above, i.e you have already taken the export of non-partitioned table.

5.1.1 )Truncate the partition


SQL > alter table FOUR_SEASONS truncate partition quarter_one;

 

5.1.2) Import the non-partitioned table again and insert data


SQL > insert into FOUR_SEASONS select * from FOUR_SEASONS_non_part_1;

2542 rows created.

SQL > commit;


OR


SQL > Alter table FOUR_SEASONS EXCHANGE partition QUARTER_ONE with table FOUR_SEASONS_non_part_1;

Table altered.

 

5.1.3) This will make the local index unusable and will require a rebuild.

You can verify the index is unusable by querying user_ind_partitions


SQL > select INDEX_NAME,PARTITION_NAME,NUM_ROWS,TABLESPACE_NAME,status from user_ind_PARTITIONS;

INDEX_NAME PARTITION_NAME NUM_ROWS TABLESPACE_NAME STATUS
------------------------------ ------------------------------ ---------- ------------------------------ --------
I_FOUR_SEASONS_L QUARTER_ONE 0 DIRK_DATA UNUSABLE
I_FOUR_SEASONS_L QUARTER_TWO 2542 DIRK_DATA USABLE
I_FOUR_SEASONS_L QUARTER_THREE 2460 DIRK_DATA USABLE
I_FOUR_SEASONS_L QUARTER_FOUR 2456 DIRK_DATA USABLE

 


SQL > Alter table FOUR_SEASONS modify partition QUARTER_ONE REBUILD UNUSABLE LOCAL INDEXES;

Table altered.

 

In case of partitioned tables with local indexes, Oracle ensures that the index is maintained
automatically when maintenance operations are performed on the underlying table.

References
NOTE:1070693.6 - How to Partition a Non-partitioned Table
http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96521/partiti.htm#20590

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章