Oracle
 sql >> Base de données >  >> RDS >> Oracle

automatiser le script de restauration oracle

DBMS_METADATA_DIFF et quelques requêtes de métadonnées peuvent automatiser ce processus.

Cet exemple illustre 6 types de modifications :1) ajouter une colonne 2) incrémenter une séquence 3) supprimer une table 4) créer une table 5) modifier une vue 6) allouer une étendue.

create table user1.add_column(id number);
create table user2.add_column(id number);
alter table user2.add_column add some_column number(5);

create sequence user1.increment_sequence nocache;
select user1.increment_sequence.nextval from dual;
select user1.increment_sequence.nextval from dual;
create sequence user2.increment_sequence nocache;
select user2.increment_sequence.nextval from dual;

create table user1.drop_table(id number);

create table user2.create_table(id number);

create view user1.change_view as select 1 a from dual;
create view user2.change_view as select 2 a from dual;

create table user1.allocate_extent(id number);
create table user2.allocate_extent(id number);
insert into user2.allocate_extent values(1);
rollback;

Vous avez raison de dire que DBMS_METADATA_DIFF ne fonctionne pas pour CREATE ou DROP . Essayer de différencier un objet qui n'existe que dans un seul schéma générera un message d'erreur comme celui-ci :

ORA-31603: object "EXTRA_TABLE" of type TABLE not found in schema "USER1"
ORA-06512: at "SYS.DBMS_METADATA", line 7944
ORA-06512: at "SYS.DBMS_METADATA_DIFF", line 712

Cependant, la suppression et l'ajout d'objets peuvent être faciles à scripter avec ce qui suit :

--Dropped objects
select 'DROP '||object_type||' USER1.'||object_name v_sql
from
(
    select object_name, object_type from dba_objects where owner = 'USER1'
    minus
    select object_name, object_type from dba_objects where owner = 'USER2'
);

V_SQL
-----
DROP TABLE USER1.DROPPED_TABLE

--Added objects
select dbms_metadata.get_ddl(object_type, object_name, 'USER2') v_sql
from
(
    select object_name, object_type from dba_objects where owner = 'USER2'
    minus
    select object_name, object_type from dba_objects where owner = 'USER1'
);

V_SQL
-----
  CREATE TABLE "USER2"."CREATED_TABLE" 
   (    "ID" NUMBER
   ) SEGMENT CREATION DEFERRED 
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 
 NOCOMPRESS LOGGING
  TABLESPACE "USERS" 

Les modifications peuvent être gérées avec une instruction SQL comme celle-ci :

select object_name, object_type, dbms_metadata_diff.compare_alter(
    object_type => object_type,
    name1 => object_name,
    name2 => object_name,
    schema1 => 'USER2',
    schema2 => 'USER1',
    network_link1 => 'MYSELF',
    network_link2 => 'MYSELF') difference
from
(
    select object_name, object_type from dba_objects where owner = 'USER1'
    intersect
    select object_name, object_type from dba_objects where owner = 'USER2'
) objects;


OBJECT_NAME         OBJECT_TYPE    DIFFERENCE
-----------         -----------    ----------
ADD_COLUMN          TABLE          ALTER TABLE "USER2"."ADD_COLUMN" DROP ("SOME_COLUMN")
ALLOCATE_EXTENT     TABLE          -- ORA-39278: Cannot alter table with segments to segment creation deferred.
CHANGE_VIEW         VIEW           -- ORA-39308: Cannot alter attribute of view: SUBQUERY
INCREMENT_SEQUENCE  SEQUENCE       ALTER SEQUENCE "USER2"."INCREMENT_SEQUENCE" RESTART START WITH 3

Quelques notes sur ces résultats :

  • ADD_COLUMN fonctionne comme prévu.
  • ALLOCATE_EXTENT est probablement un faux positif, je doute que vous vous souciez de la création de segments différés. Il est très peu probable qu'il affecte votre système.
  • CHANGE_VIEW ne fonctionne pas du tout. Mais comme pour les requêtes de métadonnées précédentes, il devrait y avoir un moyen relativement simple de créer ce script à l'aide de DBA_VIEWS.
  • INCREMENT_SEQUENCE fonctionne trop bien. La plupart du temps, une application ne se soucie pas des valeurs de séquence. Mais parfois, lorsque les choses ne sont pas synchronisées, vous devez les changer. Ce RESTART START WITH syntaxe peut être très utile. Vous n'avez pas besoin de supprimer ou de recréer les index, ni de jouer avec l'increment by plusieurs fois. Cette syntaxe n'est pas dans le manuel 12c. En fait, je ne le trouve nulle part sur Google. Il semble que ce package utilise des fonctionnalités non documentées.

Quelques autres remarques :

  • Le paquet peut parfois être très lent.
  • Si les liens réseau sur le serveur posent problème, vous devrez l'exécuter via une instance locale avec des liens vers les deux serveurs.
  • Il peut y avoir des faux positifs. Parfois, il renvoie une ligne contenant uniquement un espace.

Il est possible d'automatiser entièrement ce processus. Mais sur la base des problèmes ci-dessus et de mon expérience avec tous de tels outils automatisés, vous ne devriez pas lui faire confiance à 100 %.