REDEFINITION DE TABLE EN LIGNE

Un des challenges auquels on peut être confronté dans notre métier est de modifier la définition d’une grosse table très sollicitée dans un environnement de production 24/24 pour lequel une interruption de service n’est pas envisageable.
Oracle a introduit depuis sa version 9i le package DBMS_REDEFINITION qui permet justement de modifier la définition des tables en ligne. L’exemple qui suit montre comment changer la définition d’une table non partitionnée en table partitionnée sans aucune interruption de service.
1-/ Caractéristique de la table à partitionner

 select table_name, num_rows, partitioned from dba_tables where table_name = 'TABLE2' ;
TABLE_NAME   NUM_ROWS PAR
---------- ---------- ---
TABLE2        1000000 NO

2-/ Création d’une table intermédiaire
La table intermédiaire TABLE2_INT présentera la nouvelle définition de la table TABLE2. elle sera partitionnée par plages de valeurs sur la colonne CREATED_DATE.

CREATE TABLE JAK.TABLE2_INT (
  id            NUMBER(10),
  created_date  DATE,
  table1_id     NUMBER(10),
  data          VARCHAR2(50)
)
PARTITION BY RANGE (created_date)
(PARTITION big_table_2003 VALUES LESS THAN (TO_DATE('01/01/2004', 'DD/MM/YYYY')),
 PARTITION big_table_2004 VALUES LESS THAN (TO_DATE('01/01/2005', 'DD/MM/YYYY')),
 PARTITION big_table_2005 VALUES LESS THAN (MAXVALUE));

3-/ La table TABLE2 est elle redéfinissable
Cette étape permet de savoir si la table peut être redéfinie sans erreur grâce à la procédure can_redef_table du package dbms_redefinition.

 SQL> EXEC DBMS_REDEFINITION.can_redef_table('JAK', 'TABLE2');
PL/SQL procedure successfully completed.

Si aucune erreur n’est affichée lors de l’exécution, la table TABLE2 peut bien être redéfinie.
4-/ Début de la redéfinition de la table TABLE2
Il faut exécuter le procédure start_redef_table pour débuter le processus de redéfinition de la table. L’utilisation du parallélisme permet d’accélérer le processus.

ALTER SESSION FORCE PARALLEL DML PARALLEL 2;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 2;
BEGIN
  DBMS_REDEFINITION.start_redef_table( uname => 'JAK',orig_table => 'TABLE2',int_table  => 'TABLE2_INT');
END;
/
PL/SQL procedure successfully completed.

5-/ Synchroniser la table TABLE2_INT
Les transactions sur la table TABLE2 survenant après le début de la redéfinition sont enregistrées dans un journal de vue matérialisée (créé automatiquement par la procédure). Pour réduire au maximum la durée du verrou lors de l’étape finale, il faut synchroniser au préalable les deux tables.

BEGIN
  dbms_redefinition.sync_interim_table(uname => 'JAK', orig_table => 'TABLE2',int_table  => 'TABLE2_INT');
END;
/
PL/SQL procedure successfully completed.

6-/ Copie des objets dépendants
Les objets dépendants de la table TABLE1 doivent être copiés vers la table TABLE2_INT

SET SERVEROUTPUT ON
DECLARE
  l_errors  NUMBER;
BEGIN
  DBMS_REDEFINITION.copy_table_dependents(
    uname            => 'JAK',
    orig_table       => 'TABLE2',
    int_table        => 'TABLE2_INT',
    copy_indexes     => DBMS_REDEFINITION.cons_orig_params,
    copy_triggers    => TRUE,
    copy_constraints => TRUE,
    copy_privileges  => TRUE,
    ignore_errors    =>; FALSE,
    num_errors       => l_errors,
    copy_statistics  => FALSE,
    copy_mvlog       =>; FALSE);
  DBMS_OUTPUT.put_line('Errors=' || l_errors);
END;
/
Errors=0
PL/SQL procedure successfully completed.

7-/ Terminer la redéfinition des tables
Cette étape finalise la procédure, elle termine la synchronisation et inverse les définitions entre la TABLE2 et la TABLE2_INT dans le dictionnaire des données. La table intermédiaire devient la table réelle par la permutation de leur nom.

BEGIN
  dbms_redefinition.finish_redef_table(uname => 'JAK', orig_table =>; 'TABLE2',int_table  => 'TABLE2_INT');
END;
/
PL/SQL procedure successfully completed.

8-/ Affichage des caractéristiques de la table TABLE1

 SQL> select table_name, num_rows, partitioned from dba_tables where table_name = 'TABLE2' ;
TABLE_NAME             NUM_ROWS PAR
-------------------- ---------- ---
TABLE2                  1000000 YES

Et tout cela avec la continuité du service sur votre production ! Attention quand même au verrou exclusif qui est posé lors de l’étape finale, éviter de la réaliser au plus fort de votre activité transactionnelle.
Enfin, il n’est pas inutile de supprimer votre table intermédiaire.