partitioning a table online with dbms_redefinition

Upload: alberto-hernandez-hernandez

Post on 09-Jan-2016

216 views

Category:

Documents


0 download

DESCRIPTION

oracle

TRANSCRIPT

  • Partitioning a table online with DBMS_REDEFINITION

    If there is a requirement to change the structure of a table that is already in use productively, itmay be impossible to get a maintenance downtime for that table, because it is constantly in use.That can be the case for all kind of structural changes of a table, particulary for the change froman ordinary heap table into a partitioned table, which I am going to take here as an example,because I am ge ing asked frequently in my courses how to achieve it. In order to demonstratethat, I will create a demonstration user with a non-partitioned table with privileges andadditional dependent objects on it:

    SQL> grant dba to adam identified by adam;Grant succeeded.SQL> connect adam/adamConnected.SQL> create table original as selectrownum as id,mod(rownum,5) as channel_id,5000 as amount_sold,mod (rownum,1000) as cust_id,sysdate as time_idfrom dual connect by level create index original_id_idx on original(id) nologging;Index created.SQL> grant select on original to hr;Grant succeeded.

    The challenge is now to change this table into a partitioned one while it is used with DML &queries by end users. For this purpose, we introduced already in 9i (if I recall it right) thepackage DBMS_REDEFINITION. First step would be to ask, whether it can be used in this case:

    SQL> select * from v$version;BANNER--------------------------------------------------------------------------------Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - ProductionPL/SQL Release 11.2.0.1.0 - ProductionCORE 11.2.0.1.0 ProductionTNS for Linux: Version 11.2.0.1.0 - ProductionNLSRTL Version 11.2.0.1.0 - ProductionSQL> begindbms_redefinition.can_redef_table (uname=>'ADAM', tname=>'ORIGINAL',

    Partitioning a table online with DBMS_REDEFINITION | The Oracle ... http://uhesse.com/2010/02/15/partitioning-a-table-online-with-dbms_r...

    1 de 4 08/08/2015 11:28

  • SQL> begindbms_redefinition.can_redef_table (uname=>'ADAM', tname=>'ORIGINAL', options_flag=>DBMS_REDEFINITION.CONS_USE_ROWID);end;/PL/SQL procedure successfully completed.

    Because there is no Primary Key on the original table, I have to use CONS_USE_ROWID, else Icould use CONS_USE_PK. There are no objections against the online redenition of the tablehere else an error message would appear. Next step is to create an interim table of thestructure, desired for the original table. In my case, I create it interval partitioned (an 11g NewFeature). I could also change storage a ributes and add or remove columns during that process.

    SQL> create table interim(id number,channel_id number(1),amount_sold number(4),cust_id number(4),time_id date)partition by range (cust_id)interval (10)(partition p1 values less than (10));

    Table created.My original table has 1000 distinct cust_ids, so this will lead to 100 partitions each partion willcontain 10 distinct cust_ids. One benet of that would be the possibility of partition pruning,should there be statements, specifying the cust_id in the where-condition. These statements willbe about 100 times faster as a full table scan. The next step will basically insert all the rows fromthe orginal table into the interim table (thereby automatically generating 99 partitions), whileDML during that period is recorded:

    SQL> set timing onSQL>BEGINDBMS_REDEFINITION.START_REDEF_TABLE (uname=>'ADAM', orig_table=>'ORIGINAL', int_table=>'INTERIM', options_flag=>DBMS_REDEFINITION.CONS_USE_ROWID);end;/

    PL/SQL procedure successfully completed.Elapsed: 00:00:22.76

    If this step takes a long time to run it might be benecial to use the SYNC_INTERIM_TABLEprocedure occasionally from another session. That prevents a longer locking time for the laststep, the calling of FINISH_REDEF_TABLE. Next step is now to add the dependentobjects/privileges to the interim table:

    SQL> set timing offSQL> vari num_errors number

    Partitioning a table online with DBMS_REDEFINITION | The Oracle ... http://uhesse.com/2010/02/15/partitioning-a-table-online-with-dbms_r...

    2 de 4 08/08/2015 11:28

  • SQL> set timing offSQL> vari num_errors numberBEGINDBMS_REDEFINITION.COPY_TABLE_DEPENDENTS (uname=>'ADAM', orig_table=>'ORIGINAL', int_table=>'INTERIM', num_errors=>:num_errors);END;/PL/SQL procedure successfully completed.SQL> print num_errorsNUM_ERRORS---------- 0

    There was no problem with this step. Until now the original table is still an ordinary heap table only the interim table is partitioned:

    SQL> select table_name from user_part_tables;TABLE_NAME------------------------------INTERIM

    In the last step, the two tables change their names and the recorded DML that occured in themeantime gets used for actualization:

    SQL> begindbms_redefinition.finish_redef_table (uname=>'ADAM', orig_table=>'ORIGINAL', int_table=>'INTERIM');end;/

    PL/SQL procedure successfully completed.We will now determine that the original table is partitioned and the dependencies are still there:

    SQL> select table_name,partitioning_type from user_part_tables;TABLE_NAME PARTITION------------------------------ ---------ORIGINAL RANGESQL> select count(*) from user_tab_partitions;

    Partitioning a table online with DBMS_REDEFINITION | The Oracle ... http://uhesse.com/2010/02/15/partitioning-a-table-online-with-dbms_r...

    3 de 4 08/08/2015 11:28

  • ------------------------------ ---------ORIGINAL RANGESQL> select count(*) from user_tab_partitions; COUNT(*)---------- 100SQL> select grantee,privilege from user_tab_privs_made where table_name='ORIGINAL';GRANTEE PRIVILEGE------------------------------ ----------------------------------------HR SELECTSQL> select index_name,table_name from user_indexes;INDEX_NAME TABLE_NAME------------------------------ ------------------------------ORIGINAL_ID_IDX ORIGINALTMP$$_ORIGINAL_ID_IDX0 INTERIM

    The interim table can now be dropped. We changed the table into a partitioned table withoutany end user noticing it!

    This picture illustrates the steps you have seen above hope you nd it useful

    Conclusion: If a table structureneeds to be modied and the table is permanently accessed by end users, this can be done withsome eort using DBMS_REFDEFINITION. One common but not the only possible use caseis the modication of a non-partitioned table into a partitioned one. You have seen a simplieddemonstration about it. As always: Dont believe it, test it!

    :-)

    :-)

    Partitioning a table online with DBMS_REDEFINITION | The Oracle ... http://uhesse.com/2010/02/15/partitioning-a-table-online-with-dbms_r...

    4 de 4 08/08/2015 11:28