Avertissement : Testez toujours les opérations que vous allez mettre en œuvre avec DBMS_REDEFINITION et ne prenez jamais comptant mes propos ! En particulier, notez que la majorité des tests de ce post ont été réalisés avec Oracle 11.1.0.6 sous Linux 32bits et que d'autres versions peuvent avoir des comportements différents.
DBMS_REDEFINITION est sans doute un des packages que j'utilise le plus, surtout depuis 10g et sa capacité à "redéfinir" (déplacer, reconstruire, transformer) une seule partition aussi facilement qu'une table avec 0 indisponibilité. Zéro ? quoique ! La faute aux utilisateurs qui ne veulent pas arrêter leur système ? Pas seulement, DBMS_REDEFINITION permet aussi de conserver plus de données en ligne en déplaçant des partitions sur autre type de stockage et sans passer le tablespace en lecture seule ni de manipuler ASM ou un Volume Manager comme Veritas.
Avant de dire de quoi parle ce post, je vous renvoie à ces 2 URLs. Notez que la première est vraiment bien faite :
- Oracle 11g Administrator's Guide : Redefining Tables Online
- Oracle 11g PL/SQL Packages and Types Reference : DBMS_REDEFINITION
- Oracle 11g Reference : DBA_REDEFINITION_ERRORS et DBA_REDEFINITION_OBJECTS
Quelles sont les questions qu'il faut se poser quand vous utilisez ce package ? C'est justement de quoi ce post parle à travers un exemple simple et un ensemble de questions.
Question n°1 : Comment ça marche ?
Le principe de "redéfinition" d'une table ou une partition est très simple. Alors que votre table est accédée par des ordres DML, vous allez :
- Etape 1 : Votre table est en ligne
- Etape 2 : Démarrer la redéfinition, c'est à dire
- Créer une table vide dite "intermédiaire" avec vos nouvelles propriétés (PCTFREE, Nouveau Tablespace, Nouvelle taille de colonne ou tout ce que vous voulez ou presque)
- Définir des règles de correspondance entre les colonnes de votre table ou partition originale et la table cible (si les noms des colonnes ou les formats sont différents par exemple)
- Démarrer la capture, les modifications sur la table originale seront conservées dans un espace dédié pendant que la table intermédiaire sera alimentée par un select correspondant au moment du démarrage de la capture
- Etape 3 : Modification et synchronisation intermédiaire. Vous pouvez dans cette étape
- Construire automatiquement (ou manuellement) l'ensemble des contraintes, index, triggers et grants que vous voulez sur votre table intermédiaire. Ils seront conservés lors de l'étape 4.
- Synchroniser les modifications capturées pour diminuer le temps d'indisponibilité associé à l'étape 4
- Etape 4 : la bascule
- La table originale est verrouillée.
- Les noms de la table intermédiaire et la table ou partition originale sont échangés
- L'ensemble des clés étrangères et des triggers vers les 2 tables sont désactivés/activés à condition qu'ils aient été migrés automatiquement à l'étape 3.
- L'activité peu reprendre

Question n°2 : Doit-on vraiment utiliser DBMS_REDEFINITION ?
Surtout pas ! Enfin, s'il y a un moyen de faire autrement bien sur ! Pourquoi ?
- Parce que DBMS_REDEFINITION nécessite de dupliquer les données dans un autre espace pendant la durée de de l'opération. Un "alter table move" aussi, me direz vous !
- Parce que c'est plus compliqué qu'un "alter table move" !
- Parce que ça génère un surplus d'activité sur la table du fait de l'activation de la capture des changements pendant la phase de transition d'une table à l'autre
- Parce que c'est plus souvent inutile qu'on pense ! Quel est l'impact d'après vous de 10 000 "chained rows" dans une table pour votre application ? Et si ça vous gène, il est sans doute possible avec DELETE puis INSERT des lignes chaînées de les supprimer. Pour les repérer, utilisez l'ordre ANALYZE TABLE ... CHAINED ROWS et faites attention aux foreign keys surtout avec ON DELETE CASCADE.
- Parce qu'il y a souvent des alternatives :
- SHRINK SPACE COMPACT est un bon exemple quand c'est utilisable.
- Vous pouvez faire des ONLINE MOVE sur une IOT !
- Vous pouvez peut-être persuader le métier d'arrêter son application
- Vous pouvez charger une valeur par défaut en batch dans une colonne que vous ajoutez
- Sûrement beaucoup d'autres cas que je n'imagine même pas
- Parce qu'il a des cas ou vous ne pouvez pas : Par exemple, si vous avez un Materialized View Log sur votre table ; remarquez qu'en 11g, ce cas n'est plus une limite d'après la documentation.
- Parce que vous n'utilisez pas la version "Enterprise Edition". Désolé les amis ; et ça m'arrive aussi !
Question n°3 : Qu'est ce que vous voulez redéfinir ?
Cette question peut vous emmener loin... En réalité, même si, vous voulez redéfinir toute votre base de données (oubliez SYS et SYSTEM), il suffit de considérer que vous allez redéfinir séparément chacune de vos tables (ou partitions) et le problème devient très simple :
- Si après vous voulez vous organiser pour tout faire en même temps, parce que, par exemple votre application doit migrer simultanément pour gérer des colonnes plus grandes, c'est un autre problème. Dans ce cas vous terminerez la "redefinition" de toutes vos tables en même temps et en quelques minutes. Pour développer vos scripts, raisonnez table par table et partition par partition, ça sera très simple
- Remarquez bien que :
- Les index et contraintes associées doivent être reconstruits avec la table. Ça peut être fait automatiquement par DBMS_REDEFINITION ou vous pouvez aussi les modifier manuellement
- Les triggers et les contraintes référentielles des autres tables vers cette table sont logés à la même enseigne que les index, sauf qu'ils seront activés lors de la dernière phase de l'opération si vous utilisez la gestion automatique des dépendances.
- Si vous modifiez la taille et/ou le contenu d'une clé primaire référencée par une clé étrangère, vos devrez modifier l'ensemble des colonnes simultanément puisqu'elles sont dépendantes
- Si vous redéfinissez une table qui contient un LOB stocké dans une table overflow, il faudra redéfinir les 2 tables simultanément
- Si vous redéfinissez une partition d'une table avec des index globaux, ils seront "UNUSABLE" après l'échange des partitions
Il y a deux manières, pour DBMS_REDEFINITION, de suivre à quelle ligne s'applique une modification sur la table/partition originale :
- Soit avec la clé primaire (La solution que vous préférerez, sauf si ce n'est pas possible)
- Soit avec ROWID. Dans ce cas, une colonne (M_ROW$$) et un index (I_SNAP$_<TABLE_NAME>) seront ajoutés sur la table intermédiaire pour stocker et rechercher le ROWID. Cette deuxième méthode est donc plus consommatrice et créée une colonne qui est marquée NOT USED automatiquement si le paramètre COMPATIBLE est supérieur ou égal à 10.2.
Question n°5 : Puis-je vraiment utiliser DBMS_REDEFINITION avec ma table ?
Le meilleur moyen de le savoir, c'est de le demander. Pour ça, vous allez utiliser la procédure CAN_REDEF_TABLE. Pour cet exemple, nous allons modifier la table SCOTT.DEPT !
exec dbms_redefinition.can_redef_table(-Dans notre exemple, DBMS_REDEFINITION.CONS_USE_PK signifie que l'on veut s'appuyer sur la clé primaire. On pourrait, s'il n'y avait pas de clé primaire, s'appuyer sur le ROWID avec DBMS_REDEFINITION.CONS_USE_ROWID. Si vous ne pouvez pas redéfinir la table une erreur est retournée avec la raison associée.
'SCOTT', -
'DEPT', -
DBMS_REDEFINITION.CONS_USE_PK)
PL/SQL procedure successfully completed.
Dans l'exemple qui suit on regarde s'il est possible de redéfinir la partition SALES.SALES_Q4_2003 du schéma exemple SH. Comme généralement les tables de fait ne sont pas de clé primaire, dans ce cas, on utilisera le ROWID. Notez que ce dernier exemple ne fonctionne qu'à partir de 10g :
exec dbms_redefinition.can_redef_table(-Question n°6 : Quelle doit être la structure de la table/partition intermédiaire que je vais créer ?
'SH', -
'SALES', -
DBMS_REDEFINITION.CONS_USE_ROWID, -
'SALES_Q4_2003')
PL/SQL procedure successfully completed.
Vaste question ! Pourquoi vous voulez utiliser DBMS_REDEFINITION déjà ? Vous pouvez changer le type, le contenu, le nom des colonnes. Vous pouvez changez le tablespace, les clauses de stockage, les index, les triggers. Tout ce que vous voulez ! Je serai donc bien malin de vous dire comment doit être votre table à la fin.
Il faut toutefois noter quelques restrictions à la manière dont vous voulez que vos tables évoluent :
- Si vous ne réorganisez qu'une partition de la table, seules les clauses de stockage peuvent changer et vous ne pouvez pas changer une colonne de type par exemple !
- La relation entre les colonnes de la table d'origine et cible doit être simple et ne peut pas mettre en oeuvre des requetes SQL par exemple (Quoique!)
- Le plus simple pour faire évoluer votre table, c'est encore de capturer le DDL d'origine avec la commande DBMS_METADATA.GET_DDL comme ci-dessous :
var output clob;Supposons donc que nous voulions créer une nouvelle table DEPT avec un PCT_FREE de 80, nous allons créer notre future "DEPT" table avec les informations que nous désirons voir modifiées et avec un nom différent (On pourra utiliser $INT pour dire qu'il s'agit d'une table intermédiaire) :
exec :output:=dbms_metadata.get_ddl('TABLE',-
'EMP',-
'SCOTT')
set pages 1000
set long 9999
print output
OUTPUT
------------------------------------------------------------------------
CREATE TABLE "SCOTT"."DEPT" (
"DEPTNO" NUMBER(2,0),
"DNAME" VARCHAR2(14),
"LOC" VARCHAR2(13),
CONSTRAINT "PK_DEPT" PRIMARY KEY ("DEPTNO")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS" ENABLE
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS"
CREATE TABLE SCOTT.DEPT$INT (Question n°7 : Comment mettre en relation les colonnes de la table d'origine et les colonnes de la table modifiée ?
DEPTNO NUMBER(2,0),
DNAME VARCHAR2(14),
LOC VARCHAR2(13),
CONSTRAINT PK_DEPT$INT PRIMARY KEY (DEPTNO)
USING INDEX TABLESPACE USERS
) PCTFREE 80
TABLESPACE USERS;
Table created.
Et bien cette étape est réalisée lors de l'initialisation de la redéfinition grâce au paramètre COL_MAPPING de la procédure START_REDEF_TABLE. Et oui, l'étape suivante une fois que vous avez créé la table intermédiaire consiste à démarrer la redéfinition avec cette procédure; Si vous voulez changer le nom des colonnes ou transformer leur contenu, il faudra utiliser ce paramètre.
le contenu du paramètre peut être NULL ce qui indique que le nom et le contenu des colonnes ne change pas. Dans ce cas, le type peut changer à condition que les données soient compatibles avec le nouveau type. Si le paramètre COL_MAPPING n'est pas NULL, il doit alors indiquer le contenu de ce que serait une clause SELECT sur la table d'origine pour alimenter la table intermédiaire.
Dans notre cas, les colonnes restent identiques, nous pourrions utiliser NULL comme valeur pour le paramètre COL_MAPPING. Juste pour le geste, voila comment démarrer la redéfinition avec le paramètre positionné malgré tout :
exec DBMS_REDEFINITION.START_REDEF_TABLE( -Cette opération, comme vous pouvez facilement le vérifier, démarre le chargement initial de la table intermédiaire :
'SCOTT', -
'DEPT', -
'DEPT$INT', -
COL_MAPPING => 'deptno, dname, loc', -
options_flag =>DBMS_REDEFINITION.CONS_USE_PK)
PL/SQL procedure successfully completed.
select count(*)Question n°8 : Comment créer les contraintes/index et autres objets dépendants ?
from scott.dept$int
COUNT(*)
--------
4
Vous pouvez copier les objets qui dépendent de votre table d'origine sur la table temporaire des maintenant ou après avoir commencé la redéfinition. A travers objets dépendants, on entend :
- Clé primaire ou secondaire (Remarquez que si vous vous appuyez sur une de ces clés, il faut qu'elle soit créées avant de commencer la redéfinition)
- Contrainte d'unicité et not null
- Check
- Clés étrangère à partir ou à destination de la table
- Index
- Triggers
- Grants
- (En 11g) Materialized View Logs
- Créer manuellement les objets dépendants et gérer leur état manuellement (e.g : disable, validated...)
- Créer manuellement les objets dépendants et les mettre en correspondance avec les objets d'origine avec DBMS_REDEFINITION.REGISTER_DEPENDENT_OBJECT
- Créer automatiquement les objets depuis la table d'origine avec la procédure DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS
Dans l'exemple qui suit nous allons utiliser la méthode 3 pour créer automatiquement la clé étrangère entre EMP et DEPT$INT. Nous utiliserons la méthode 2 pour enregistrer manuellement la clé primaire PK_DEPT$INT parmi les objets dépendants. Notez que si vous ne le faite pas, la contrainte et l'index ne seront pas renommées à la fin de la redéfinition...
var numerr number;La raison des 2 erreurs peut être facilement expliquée par le fait que nous avons créé une clé primaire et l'index associé lors de la création de la table. Pour cela, interrogeons DBA_REDEFINITION_ERRORS comme ci-dessous :
exec DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS(-
'SCOTT', -
'DEPT', -
'DEPT$INT', -
ignore_errors => true, -
num_errors => :numerr);
print numerr
NUMERR
------
2
col OBJECT_TYPE format a15Pour connaître les objets qui sont maintenant gérés par DBMS_REDEFINITION, vous pouvez interroger la vue DBA_REDEFINITION_OBJECTS :
col OBJECT_OWNER format a15
col OBJECT_NAME format a15
select OBJECT_TYPE,
OBJECT_OWNER,
OBJECT_NAME,
DDL_TXT
from dba_redefinition_errors
OBJECT_TYPE OBJECT_OWNER OBJECT_NAME
------------ --------------- ---------------
DDL_TXT
--------------------------------------------------------------------------------
INDEX SCOTT PK_DEPT
CREATE UNIQUE INDEX "SCOTT"."TMP$$_PK_DEPT0" ON "SCOTT"."DEPT$INT" ("DEPTNO")
PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS"
CONSTRAINT SCOTT PK_DEPT
ALTER TABLE "SCOTT"."DEPT$INT" ADD CONSTRAINT "TMP$$_PK_DEPT0" PRIMARY KEY ("DEP
TNO")
USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS" ENABLE NOVALIDATE
col TYPE format a10Enfin, il est possible d'ajouter la clé primaire et l'index créés avant le démarrage de la redéfinition à l'aide de DBMS_REDEFINITION.REGISTER_DEPENDENT_OBJECT comme ci-dessous :
col OWNER format a6
col NAME format a9
col IOWNER format a6
col INAME format a16
select OBJECT_TYPE TYPE,
OBJECT_OWNER OWNER,
OBJECT_NAME NAME,
INTERIM_OBJECT_OWNER IOWNER,
INTERIM_OBJECT_NAME INAME
from dba_redefinition_objects;
TYPE OWNER NAME IOWNER INAME
---------- ------ --------- ------ ----------------
TABLE SCOTT DEPT SCOTT DEPT$INT
CONSTRAINT SCOTT FK_DEPTNO SCOTT TMP$$_FK_DEPTNO0
exec dbms_redefinition.register_dependent_object( -Et nous voila fin prêt pour la suite...
'SCOTT', -
'DEPT', -
'DEPT$INT', -
DBMS_REDEFINITION.CONS_INDEX, -'SCOTT', -'PK_DEPT', -'PK_DEPT$INT');PL/SQL procedure successfully completed.
exec dbms_redefinition.register_dependent_object( -
'SCOTT', -
'DEPT', -
'DEPT$INT', -
DBMS_REDEFINITION.CONS_CONSTRAINT, -'SCOTT', -'PK_DEPT', -'PK_DEPT$INT');
PL/SQL procedure successfully completed.
select OBJECT_TYPE TYPE,
OBJECT_OWNER OWNER,
OBJECT_NAME NAME,
INTERIM_OBJECT_OWNER IOWNER,
INTERIM_OBJECT_NAME INAME
from dba_redefinition_objects;
TYPE OWNER NAME IOWNER INAME
---------- ------ --------- ------ ----------------
TABLE SCOTT DEPT SCOTT DEPT$INT
CONSTRAINT SCOTT FK_DEPTNO SCOTT TMP$$_FK_DEPTNO0
INDEX SCOTT PK_DEPT SCOTT PK_DEPT$INT
CONSTRAINT SCOTT PK_DEPT SCOTT PK_DEPT$INT
Question n°9 : Comment faire des synchronisations intermédiaires ?
Cette question peut paraître saugrenue mais dans la réalité, reconstruire l'ensemble des dépendance peut être long et beaucoup de transactions peuvent être appliquées sur la table d'origine pendant la phase précédente... Pour réduire le temps de transition, ou simplement pour améliorer vos phases de tests, faire des synchronisation intermédiaire, y compris juste avant de basculer la table intermédiaire avec la table/partition d'origine sont une bonne pratique. Pour cela, vous allez utiliser la procédure DBMS_REDEFINITION.SYNC_INTERIM_TABLE comme ci-dessous :
exec dbms_redefinition.sync_interim_table( -Il est facile de voir l'effet de cette fonction, si par exemple, vous avez inséré, modifié ou supprimé une ligne entre le début de l'utilisation de DBMS_REDEFINITION et le moment de la synchronisation intermédiaire.
'SCOTT', -
'DEPT', -
'DEPT$INT')
PL/SQL procedure successfully completed.
Question n°10 : Que se passe-t-il si on a des transactions en cours lorsque l'on finit d'utiliser DBMS_REDEFINITION ?
Pour répondre à cette question, nous allons terminer la redéfinition avec DBMS_REDEFINITION.FINISH_REDEF_TABLE, mais avant, nous allons ouvrir une nouvelle session SQL*Plus et exécuter l'ordre suivant (En veillant à laisser la session ouverte)
select *Et, comme prévu, nous allons terminer, à partir d'une autre session la redefinition
from scott.dept
where deptno=10
for update;
DEPTNO DNAME LOC
---------- -------------- -------------
10 ACCOUNTING NEW YORK
exec dbms_redefinition.finish_redef_table( -Heureusement avec SQL*Plus il est simple d'abandonner la procédure car, l'intention de poser un verrou exclusif sur la table est donnée et les nouvelles transactions sont bloquées. J'appuie vite sur
'SCOTT', -
'DEPT', -
'DEPT$INT')
*C'est pour cette raison qu'il est sans doute préférable :
ERROR at line 1:
ORA-42012: error occurred while completing the redefinition
ORA-01013: user requested cancel of current operation
ORA-06512: at "SYS.DBMS_REDEFINITION", line 78
ORA-06512: at "SYS.DBMS_REDEFINITION", line 1664
ORA-06512: at line 1
- De superviser les verrous posés depuis longtemps avant de terminer une redéfinition
- D'utiliser un LOCK TABLE ... IN EXCLUSIVE MODE WAIT 3 avant d'utiliser une commande comme celle-ci.
rollback;Puis dans la seconde session, executez DBMS_REDEFINITION.FINISH_REDEF_TABLE avec le lock exclusive wait dans le même block PL/SQL:
Rollback complete.
beginBon en l'occurence dbms_redefinition.finish_table_redef opère un ordre DDL qui libère le lock TM pose par la commande LOCK TABLE mais en général, n'hésitez pas à ajoutez la commande rollback avant la fin de votre code PL/SQL
lock table scott.dept in exclusive mode wait 3;
dbms_redefinition.finish_redef_table(
'SCOTT',
'DEPT',
'DEPT$INT');
end;
/
PL/SQL procedure successfully completed.
Question n°11 : Qu'est-ce qui peut changer après l'utilisation de DBMS_REDEFINITION et quel peut-être l'impact de ces changements ?
Je n'ai pas trouvé de documentation officielle à ce sujet mais voilà au moins ce à quoi il faut être attentif. Il se peut que j'en oublie alors soyez attentif à tout et dites moi si vous trouvez autre chose (même le plus petit détails comme un droit !)
A) Si vous faites des changements sur les objets dépendants et que vous ne gérez pas la transition via DBMS_REDEFINITION (Ce qui est toujours le cas avant 10g), il faut gérer manuellement ces objets et en particulier il faut activer (ENABLE) :
- Les triggers
- Les contraintes
- Les Materialized View Log
B) Si vous faites les changements sur les objets dépendant via DBMS_REDEFINITION.COPY_TABLE_DEPENDENTS, il faut noter que les contraintes sont "NO VALIDATED" et que, j'en ai déjà parlé, ça peut avoir un impact sur les plans d'exécution. N'hésitez pas à les valider dès que vous le pouvez (Immediatement pour NOT NULL, plus tard pour les FK...)
C) Si vous utilisez la redéfinition avec le ROWID, une colonne qui contient le rowid est ajoutée a la table. Faites y d'autant plus attention si COMPATIBLE<=10.1 puisque un "SELECT *" ne ramenera pas le même nombre de colonnes. Enfin avec COMPATIBLE >= 10.2, ce n'est plus le cas et la colonne est masquée mais elle est toujours là ! Vous pouvez toujours la supprimée après coup.
D) En 9i au moins, les statistiques et dans tous les cas bien sur les structures physiques. Il n'est pas improbable que cette opération aboutisse à des changements de plan d'exécution, souvent recherchés et parfois non
F) Les objets dépendant sont invalidés (vues, packages PL/SQL) et selon l'utilisation qui en est faite, il est possible voir probable que votre application rencontre des erreurs lors de l'appel de FINISH_TABLE_REDEF !
Question n°12 : Est-ce terminé ?
En fait, non ! N'oubliez pas de supprimer la table intermédiaire qui est en fait la table d'origine que vous n'utilisez plus ainsi que toutes ses dépendances :
drop table scott.dept$intQuestion n°13 : Comment recommencer de zéro ?
cascade constraints
purge;
Table dropped.
Si pour n'importe quelle raison, vous devez arrêter en cours de route la redéfinition de vos objets, utilisez la fonction DBMS_REDEFINITION.ABORT_REDEF_TABLE. Vous pourrez alors supprimer tous les objets intermédiaires créés et recommencer de zéro ou pas !
Question n°14 : A quoi faire attention encore ?
En arrière plan, lorsque commence une redéfinition, la table intermédiaire devient une vue matérialisée de la table d'origine et un "MV Log" est ajoutée à la table d'origine en mode "fast refresh". Vous en déduirez simplement comment suivre l'évolution des captures sur la table d'origine ! Voila et même si, comme moi, vous avez une confiance aveugle en Oracle, il est sans doute préférable de comparer l'ensemble des informations dont vous disposez avant et après les modifications et surtout de tester que votre application supporte bien de tels changements.
Voila c'est tout pour l'instant ! Si jamais j'avais oublié d'autres différences générées par DBMS_REDEFINITION (cf question 11), n'hésitez pas à commenter ce post ! A part ça, je souhaite simplement que ce post puisse vous servir d'aide mémoire pour la prochaine utilisation de ce package.
1 commentaire:
Vous avez éclairé ma lanterne quant à l'emploi du package DBMS_REDEFINITION pour faire des Reorg Online de tables.
C'est ( quand même ) une technique très importante - et utile - pour les environnements de Production avec contrainte de disponibilité ... peut-être insuffisamment documentée et "intégrée" selon moi.
Votre synthèse - qui plus est en français - mes semble complète et présente bien les enjeux et limitations de la technique.
Je vais tester par moi-même : étant un peu inquiet par d'éventuelles invalidations de vues ou packages que vous indiquez
( une gestion automatique de ces "objets dépendants" par le DBMS_REDEFINITION serait bienvenue ..." ).
Olivier
Enregistrer un commentaire