Oracle 11g R2 : Migrations cross plateformes avec les tablespaces transportables

Logo

Introduction

La migration d’une instance Oracle 11g R2 64 bits d’une plateforme Sun SPARC Solaris 10 64 bits vers une plateforme SunOS X86 Solaris 10 64 bits n’est pas anodine car dans ce contexte les fichiers de données Oracle doivent subir une conversion, le poids (ou endian en anglais) étant différent entre ces deux plateformes (big endian pour Sun SPARC, little endian pour SunOS x86).

La fonctionnalité des tablespaces transportables d’Oracle (transportable tablespaces) inclut de façon très simple et efficace depuis la version 10g, même si il existe quelques restrictions, la conversion des fichiers Oracle lors d’un changement de plateforme et de poids.

Cet article rappelle très brièvement la notion de poids et propose un exemple de conversion d’une instance Oracle 11g R2 de Sun SPARC Solaris 10 vers SunOS X86 Solaris 10.

Poids (little endian, big endian) et ordre de traitement des octets

Le terme "endian" se rapporte à l’ordre de numérotation des octets d’un type de données (entier, caractères…). Les architectures d’ordinateur divergent dans la façon dont elles numérotent les octets d’un type de données de gauche à droite ou de droite à gauche (un peu comme l’écriture). Dans le schéma ci-dessous, les architectures 32 bits « Big Endian » et « Little Endian » sont illustrées pour le stockage d’un entier 0XA0B70708 en notation héxadécimale.

ordre de lecture des octets little endian big endian

Chaque octet équivaut à 8 bits :

  • dans une architecture Big endian, la numérotation des octets se fait de gauche à droite (ex. : HP, Sun Solaris SPARC). On parle aussi dans ce cas de gros-boutiste (poids fort en tête)
  • dans une architecture Little endian, la numérotation des octets se fait de droite à gauche (ex. : Intel x86, Pentium). On parle aussi dans ce cas de petit-boutiste (poids faible en tête).

Le passage d’une plateforme à une autre lorsque les poids diffèrent pour les bases de données, et ceci quelque soit le moteur (Oracle, Sybase…), nécessite impérativement une conversion, le schéma ci-dessous résume les poids par plateformes et dans quel contexte des conversions sont nécessaires :

plateforme big endian little endian conversion

Sybase propose depuis la version 12.5.3 la conversion cross plateforme par dump/load (Sybase 12.5.3 - Dump/Load cross plateforme ), pour Oracle la méthode des transportable tablespaces inclut la fonctionnalité de conversion. Cet article présente un cas concret pour Oracle.

Contexte de la migration cross plateforme

L’instance à migrer s’appelle UBXU1ORA, il s’agit d’une version 11.2.0.1 64 bits comprenant 3 tablespaces non systèmes : UBIX_TABLES, UBIX_INDEX et UBIX_ADMIN.

contexte migration instance Oracle 11g cross plateforme

Pour retrouver les tablespaces utilisateurs à migrer à partir de la vue dba_tablespaces :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

select tablespace_name from dba_tablespaces
     where contents not in ('UNDO','TEMPORARY')
     and tablespace_name not in ('SYSTEM','SYSAUX');
TABLESPACE_NAME
------------------------------
UBIX_TABLES
UBIX_INDEX
UBIX_ADMIN

Pour retrouver les fichiers de données des tablespaces utilisateurs à migrer à partir de la vue dba_data_files :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

select tablespace_name,file_name from dba_data_files
     where tablespace_name in (select tablespace_name 
                                 from dba_tablespaces 
                                 where contents not in ('UNDO','TEMPORARY') 
                                 and tablespace_name not in ('SYSTEM','SYSAUX'))
     order by 1,2;
TABLESPACE_NAME      FILE_NAME
-------------------  -----------------------------------------
UBIX_ADMIN           /ubix/oracle/UBXU1ORA/UBIX_ADMIN_01.dbf
UBIX_INDEX           /ubix/oracle/UBXU1ORA/UBIX_INDEX_01.dbf
UBIX_INDEX           /ubix/oracle/UBXU1ORA/UBIX_INDEX_02.dbf
UBIX_INDEX           /ubix/oracle/UBXU1ORA/UBIX_INDEX_03.dbf
UBIX_INDEX           /ubix/oracle/UBXU1ORA/UBIX_INDEX_04.dbf
UBIX_INDEX           /ubix/oracle/UBXU1ORA/UBIX_INDEX_05.dbf
UBIX_TABLES          /ubix/oracle/UBXU1ORA/UBIX_TABLES_01.dbf
UBIX_TABLES          /ubix/oracle/UBXU1ORA/UBIX_TABLES_02.dbf
UBIX_TABLES          /ubix/oracle/UBXU1ORA/UBIX_TABLES_03.dbf
UBIX_TABLES          /ubix/oracle/UBXU1ORA/UBIX_TABLES_04.dbf
UBIX_TABLES          /ubix/oracle/UBXU1ORA/UBIX_TABLES_05.dbf

11 rows selected.

Vérification de la compatibilité avec les tablespaces transportables DBMS_TTS

Quelques restrictions existent pour pouvoir utiliser les tablespaces transportables. La procédure transport_set_check du package DBMS_TTS permet de vérifier si une incompatibilité avec les tablespaces transportables est détectée.

oracle@UBXU1ORA> sqlplus "/ as sysdba"

begin
	dbms_tts.transport_set_check('UBIX_TABLES',true);
end;
/

L’exécution de cette procédure pour un tablespace remplit la vue système TRANSPORT_SET_VIOLATIONS, vue qui va remonter toutes les incompatibilités avec la technologie des tablespaces transportables.

oracle@UBXU1ORA> sqlplus "/ as sysdba"

select * from TRANSPORT_SET_VIOLATIONS;
no rows selected

La procédure transport_set_check est exécutée pour chaque tablespace à transporter et les résultats remontés dans la vue TRANSPORT_SET_VIOLATIONS sont analysés après chaque exécution.

Quelques cas de violations (l’erreur ORA-39907)

Des violations peuvent survenir lorsque des objets référencés ne sont pas dans le jeu de tablespaces à transporter, c’est notamment le cas de l’erreur ORA-39907. Voici le résultat de la procédure transport_set_check sur le tablespace UBIX_INDEX qui ne contient que les indexes des tables, tables qui sont en revanche stockées dans le tablespace UBIX_TABLES :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

begin
	dbms_tts.transport_set_check('UBIX_INDEX',true);
end;
/
select * from TRANSPORT_SET_VIOLATIONS;
VIOLATIONS
-----------------------------------------------------------

ORA-39907: Index OPS$BRU.MODNEG2 in tablespace UBIX_INDEX points
to table OPS$BRU.MODNEG in tablespace UBIX_TABLES.

Les violations indiquent que l’index s’applique sur une table contenue dans un autre tablespace, il s’agit d’un simple avertissement sans gravité. La procédure transport_set_check permet d’inclure un jeu de tablespaces pour vérifier un transport de plusieurs tablespaces en même temps, ce qui sera la cas :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

begin
	dbms_tts.transport_set_check('UBIX_TABLES,UBIX_INDEX,UBIX_ADMIN',true);
end;
/
select * from TRANSPORT_SET_VIOLATIONS;
no rows selected

Le référencement vers des objets systèmes SYS, des tables externes (external tables), etc. n’est pas pris en charge. Ces types d’objet doivent être préparés dans l’instance cible, par export ou toute autre méthode (script SQL…).

Restrictions avec les tablespaces transportables

Quelques précautions à prendre :

  • Les instances source et cible doivent avoir les mêmes jeux de caractères. Ce point est vu ultérieurement.
  • Les tablespaces systèmes SYSTEM, SYSAUX, etc. ne sont pas transportables.
  • Les nouveaux types de données Oracle 10g BINARY_FLOAT et BINARY_DOUBLE ne sont supportés qu’avec la méthode export/import data pump, ils ne sont pas supportés par la méthode des tablespaces transportables.
  • Les types opaques comme RAW, BLOB, SYS.ANYTYPE, SYS.ANYDATA, etc. peuvent générer une incompatibilité, incompatibilité qui peut se produire également lors des transports de tablespaces en iso-plateformes (même poids). Une validation de ces types de colonnes est nécessaire après le transport, les interprétations de ces types de colonnes étant intimement liées à l’application.

La vue DBA_TAB_COLUMNS et notamment la colonne DATA_TYPE permet de retrouver ces types de colonnes exotiques.

oracle@UBXU1ORA> sqlplus " /as sysdba"

select owner,table_name, column_name, data_type
      from dba_tab_columns
      where owner in ('OPS$BRU','UBXADMIN','UBXREF')
      and data_type='RAW'
OWNER           TABLE_NAME            COLUMN_NAME        DATA_TYPE
--------------- --------------------  -----------------  -------------
OPS$BRU         ORA_STATS             R1                 RAW
OPS$BRU         ORA_STATS             R2                 RAW

Procédure de migration

Les étapes de la migration peuvent être résumées avec le diagramme ci-dessous :

schema migration cross plateforme

La vue v$transportable_plaform rassemble toutes les plateformes supportées par Oracle ainsi que leurs poids. Pour les plateformes Solaris :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

select platform_name, endian_format
     from V$TRANSPORTABLE_PLATFORM
     where upper(platform_name) like '%SOLARIS%'
PLATFORM_NAME                         ENDIAN_FORMAT
----------------------------------    -------------
Solaris[tm] OE (32-bit)               Big
Solaris[tm] OE (64-bit)               Big
Solaris Operating System (x86)        Little
Solaris Operating System (x86-64)     Little

Dans cet exemple pratique, la plateforme source est Solaris [tm] OE (64-bit) et la plateforme cible est Solaris Operating System (x86-64) : les poids sont différents (Big/Little), donc une conversion avec RMAN est nécessaire. Le libellé "Solaris Operating System (x86-64)" va être très important dans la conversion des tablespaces avec RMAN.

La plateforme d’une instance est disponible dans la colonne platform_name de la vue v$database :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

select platform_name from v$database
PLATFORM_NAME
-------------------------
Solaris[tm] OE (64-bit)

Étape 1 : Mise en lecture seule des tablespaces dans l’instance source

Les tablespaces UBIX_TABLES, UBIX_INDEX et UBIX_ADMIN à migrer sont mis en lecture seule (read only) avec la commande ALTER TABLESPACE.

alter tablespace ubix_tables read only;

alter tablespace ubix_index read only;

alter tablespace ubix_admin read only;

Étape 2 : Export des meta données (metadata) avec l’utilitaire export data pump expdp

L’export des meta données des trois tablespaces à migrer est réalisé depuis l’instance source avec l’utilitaire expdp (export data pump). 2 exports vont être réalisés :

  • Un export data pump des meta données des tablespaces transportés.
  • Un export data pump pour les objets non pris en charge par l’export data pump des tablespaces transportés. Les objets non pris en charge sont par exemple les vues, procédures, fonctions, packages, etc.

Le répertoire pour l’export data pump est au préalable créé avec la commande CREATE DIRECTORY :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

create directory dpump_tts as '/ubix/oracle/export/metadata';
Directory created.

Export des meta données des tablespaces à transporter

Un fichier de paramètres export_metadata_tts.par pour l’export data pump des meta données des tablespaces transportables est préparé :

export_metadata_tts.par
userid="/ as sysdba"
directory=dpump_tts
dumpfile=ubix_metadata_tts.dmp
logfile=export_metadata_tts.log
transport_full_check=y
transport_tablespaces=(UBIX_ADMIN,UBIX_TABLES,UBIX_INDEX)

L’option transport_tablespaces liste les tablespaces à transporter, l’option transport_full_check=ydéclenche la vérification de la cohérence des références entre objets dans les tablespaces.

L’export data pump est ensuite appelé avec ce fichier de paramètrage :

oracle@UBXU1ORA> expdp parfile=export_metadata_tts.par

...
Starting "SYS"."SYS_EXPORT_TRANSPORTABLE_01":  /******** AS SYSDBA parfile=export_metadata_tts.par 
Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
Processing object type TRANSPORTABLE_EXPORT/TABLE
 ...
Master table "SYS"."SYS_EXPORT_TRANSPORTABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYS.SYS_EXPORT_TRANSPORTABLE_01 is:
  /ubix/oracle/export/metadata/ubix_metadata_tts.dmp
******************************************************************************
Datafiles required for transportable tablespace UBIX_ADMIN:
  /ubix/oracle/UBXU1ORA/UBIX_ADMIN_01.dbf
Datafiles required for transportable tablespace UBIX_INDEX:
  /ubix/oracle/UBXU1ORA/UBIX_INDEX_01.dbf
  /ubix/oracle/UBXU1ORA/UBIX_INDEX_02.dbf
  /ubix/oracle/UBXU1ORA/UBIX_INDEX_03.dbf
  /ubix/oracle/UBXU1ORA/UBIX_INDEX_04.dbf
  /ubix/oracle/UBXU1ORA/UBIX_INDEX_05.dbf
Datafiles required for transportable tablespace UBIX_TABLES:
  /ubix/oracle/UBXU1ORA/UBIX_TABLES_01.dbf
  /ubix/oracle/UBXU1ORA/UBIX_TABLES_02.dbf
  /ubix/oracle/UBXU1ORA/UBIX_TABLES_03.dbf
  /ubix/oracle/UBXU1ORA/UBIX_TABLES_04.dbf
  /ubix/oracle/UBXU1ORA/UBIX_TABLES_05.dbf

La sortie liste les fichiers de données qui seront nécessaires à l’import.

Export des objets non pris en charge par les tablespaces transportables

Le fichier de paramètres export_metadata_objects.par est créé pour l’export data pump des objets non pris en charge par les tablespaces transportables :

export_metadata_objects.par
userid="/ as sysdba"
directory=dpump_tts
dumpfile=ubix_metadata_objects.dmp
logfile=export_metadata_objects.log
full=y
content=metadata_only

Les options FULL=y et CONTENT=metadata_only garantissent l’export des meta données de tous les objets (tables, indexes, vues, packages, procédures, fonctions, packages, package body, vues matérialisées…) sans exporter les données des tables.

L’export data pump est ensuite appelé avec ce fichier de paramètrage :

oracle@UBXU1ORA> expdp parfile=export_metadata_objects.par

Export: Release 11.2.0.1.0 - Production on Mon Nov 8 16:10:40 2010

Copyright (c) 1982, 2009, Oracle and/or its affiliates.  All rights reserved.

Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
Starting "SYS"."SYS_EXPORT_FULL_01":  /******** AS SYSDBA parfile=export_metadata.par 
Processing object type DATABASE_EXPORT/TABLESPACE
Processing object type DATABASE_EXPORT/PROFILE
 ...
Processing object type DATABASE_EXPORT/SCHEMA/FUNCTION/FUNCTION
Processing object type DATABASE_EXPORT/SCHEMA/PROCEDURE/PROCEDURE
Processing object type DATABASE_EXPORT/SCHEMA/FUNCTION/ALTER_FUNCTION
Processing object type DATABASE_EXPORT/SCHEMA/PROCEDURE/ALTER_PROCEDURE
Processing object type DATABASE_EXPORT/SCHEMA/VIEW/VIEW
Processing object type DATABASE_EXPORT/SCHEMA/VIEW/GRANT/OWNER_GRANT/OBJECT_GRANT
Processing object type DATABASE_EXPORT/SCHEMA/VIEW/GRANT/CROSS_SCHEMA/OBJECT_GRANT
Processing object type DATABASE_EXPORT/SCHEMA/VIEW/COMMENT
Processing object type DATABASE_EXPORT/SCHEMA/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type DATABASE_EXPORT/SCHEMA/PACKAGE_BODIES/PACKAGE/PACKAGE_BODY
 ...
Dump file set for SYS.SYS_EXPORT_FULL_01 is:
  /ubix/oracle/export/metadata/ubix_metadata_objects.dmp
Job "SYS"."SYS_EXPORT_FULL_01" successfully completed at 16:14:55

Le fichier de log de l’export data pump ne doit pas contenir d’erreurs, sauf si il existe des schémas XMLObjects qui ne sont pas supportés par l’export data pump, dans ce contexte l’utilitaire d’export classique exp doit être utilisé.

Vérifier le dimensionnement du tablespace SYSTEM afin que celui-ci contienne assez d’espace disponible lors de l’export data pump : 200 Mb est une bonne marge.

Étape 3 : Conversion avec RMAN des fichiers des tablespaces

Les fichiers de données des tablespaces sont convertis tablespace par tablespace pour être compatible avec la plateforme cible - Solaris Operating System (x86-64) - grâce à la commande convert tablespace de l’utilitaire RMAN, les fichiers de données convertis sont stockés dans le répertoire /ubix/oracle/export de la machine source :

oracle@UBXU1ORA> rman target / nocatalog
connected to target database: UBXU1 (DBID=3277469180)
using target database control file instead of recovery catalog
RMAN> convert tablespace 'UBIX_INDEX'
 to platform="Solaris Operating System (x86-64)"
 db_file_name_convert '/ubix/oracle/UBXU1ORA/UBIX_INDEX_01.dbf','/ubix/oracle/export/UBIX_INDEX_01.dbf'
 '/ubix/oracle/UBXU1ORA/UBIX_INDEX_02.dbf','/ubix/oracle/export/UBIX_INDEX_02.dbf',
 '/ubix/oracle/UBXU1ORA/UBIX_INDEX_03.dbf','/ubix/oracle/export/UBIX_INDEX_03.dbf',
 '/ubix/oracle/UBXU1ORA/UBIX_INDEX_04.dbf','/ubix/oracle/export/UBIX_INDEX_04.dbf',
 '/ubix/oracle/UBXU1ORA/UBIX_INDEX_05.dbf','/ubix/oracle/export/UBIX_INDEX_05.dbf';
Starting conversion at source at 19/10/10
using channel ORA_DISK_1
channel ORA_DISK_1: starting datafile conversion
input datafile file number=00006 name=/ubix/oracle/UBXU1ORA/UBIX_INDEX_01.dbf
converted datafile=/ubix/oracle/export/UBIX_INDEX_01.dbf
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:01:25
channel ORA_DISK_1: starting datafile conversion
input datafile file number=00014 name=/ubix/oracle/UBXU1ORA/UBIX_INDEX_03.dbf
converted datafile=/ubix/oracle/export/UBIX_INDEX_03.dbf
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:01:15
channel ORA_DISK_1: starting datafile conversion
input datafile file number=00015 name=/ubix/oracle/UBXU1ORA/UBIX_INDEX_05.dbf
converted datafile=/ubix/oracle/export/UBIX_INDEX_05.dbf
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:01:15
channel ORA_DISK_1: starting datafile conversion
input datafile file number=00007 name=/ubix/oracle/UBXU1ORA/UBIX_INDEX_02.dbf
converted datafile=/ubix/oracle/export/UBIX_INDEX_02.dbf
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:45
channel ORA_DISK_1: starting datafile conversion
input datafile file number=00010 name=/ubix/oracle/UBXU1ORA/UBIX_INDEX_04.dbf
converted datafile=/ubix/oracle/export/UBIX_INDEX_04.dbf
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:45
Finished conversion at source at 19/10/10

Les temps de conversion sont très rapides : moins de 2 minutes pour des fichiers de données ayant une taille de 3 à 4 Gb. Le temps va dépendre toutefois de la CPU.

Étape 4 : Envoi des fichiers convertis et du fichier d’export des meta données

Les fichiers de données des tablespaces UBIX_TABLES, UBIX_INDEX et UBIX_ADMIN convertis et localisés dans le répertoire /ubix/oracle/export sont envoyés avec le binaire ftp (mode binaire) vers la machine cible Sun X86 64 bits directement dans l’arborescence de l’instance qui va accueillir ces fichiers de données (/ubix/oracle/UBXU1ORA).

Les fichier d’exports ubix_metadata_tts.dmp et ubix_metadata_objects.dmp contenant les meta données sont également envoyés par ftp (mode binaire) vers la machine cible dans le répertoire /ubix/oracle/export/metadata.

Étape 5 : Préparation de l’instance cible (base de données, comptes, rôles)

Jeux de caractères de l’instance cible : nls_database_parameters

Une restriction très importante : l’instance cible doit avoir les mêmes jeux de caractères que l’instance source. Lorsque les jeux de caractères sont différents, l’import des tablespaces transportés est en échec avec l’erreur ORA-19736:

IMP-00003: ORACLE error 19736 encountered
ORA-19736: can not plug a tablespace into a database using a different national character set
ORA-06512: at "SYS.DBMS_PLUGTS", line 1797
ORA-06512: at "SYS.DBMS_PLUGTS", line 1636
ORA-06512: at line 1
IMP-00000: Import terminated unsuccessfully

Pour retrouver les jeux de caractères de l’instance source, interroger la vue nls_database_parameters de l’instance source :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

select parameter, value
    from nls_database_parameters
    where parameter in ('NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET')
PARAMETER                  VALUE
-------------------------- ---------------------------
NLS_CHARACTERSET           WE8PC850
NLS_NCHAR_CHARACTERSET     AL16UTF16

Ces jeux de caractères sont paramatrés dans la commande CREATE DATABASE de l’instance cible :

CREATE DATABASE UBXU1
 ....
   character set WE8PC850
   national character set AL16UTF16
 ...;

Fuseaux horaires : v$timezone_file et la variable $ORA_TZFILE lors de la création de la base de données cible

Dans le cas des tablespaces transportables, la version des fuseaux horaires doit être strictement la même pour les instances source et cible. Pour retrouver la version des fuseaux horaires dans l’instance source :

oracle@UBXU1ORA (source 11.2.0.1)> sqlplus "/ as sysdba"

select * from v$timezone_file;
FILENAME                VERSION
-------------------- ----------
timezlrg_11.dat              11

La version 11 correspond à la dernière version des fuseaux horaires de la version Oracle 11.2.0.1. Si l’instance cible est créée avec la version 11.2.0.2, sans prendre garde, la version des fuseaux horaires est à une version supérieure (version 14) :

oracle@UBXU1ORA (cible 11.2.0.2)> sqlplus "/ as sysdba"

select * from v$timezone_file;
FILENAME                VERSION
-------------------- ----------
timezlrg_14.dat              14

Lors de l’import des tablespaces transportables, l’erreur ORA-39322 sera levée si il existe un delta dans la version des fuseaux horaires

ORA-39002: invalid operation
ORA-39322: Cannot use transportable tablespace with timestamp with timezone
columns and different timezone version.

L’instance cible doit être créée avec une version des fuseaux horaires identique à celle de l’instance source. Pour cela, la variable $ORA_TZFILE est forcée à la version 11 dans la session qui créé la base de données cible afin que la version 14 ne soit pas appliquée automatiquement par le moteur Oracle :

oracle@UBXU1ORA (cible 11.2.0.2)> export ORA_TZFILE=$ORACLE_BASE/$ORACLE_HOME/oracore/zoneinfo/timezlrg_11.dat

oracle@UBXU1ORA (cible 11.2.0.2)> sqlplus "/ as sysdba"

CREATE DATABASE UBXU1
...

Dans la norme appliquée aux instances de cet article, la variable $ORA_TZFILE pointe sur /Software/oracle/app/product/11.2.0/oracore/zoneinfo/timezlrg_11.dat. Vérifier ensuite que la bonne version des fuseaux horaires est appliquée dans l’instance cible en interrogeant v$timezone_file après la création de la base de données cible.

Préparation des comptes, rôles et profils dans l’instance cible

Les comptes et rôles sont préparés dans l’instance cible. Leur existence est indispensable pour l’import des tablespaces tansportables. Pour les comptes, aucun tablespace de données par défaut n’est précisé puisqu’ils ne sont pas encore importés.

oracle@UBXU1ORA (cible)> sqlplus "/ as sysdba"

create user ops$bru identified by *******;
create user ubxref identified by *******;
create user ubxadmin identified by *******;
create user modele_ops$bru identified by *******;
create role useubix_ops$bru identified by *******;

Aucun privilège particulier n’est donné aux comptes (create session, etc.), les privilèges sont attribués lors de l’import.

Pour retrouver dans l’instance source les comptes, rôles, proflls, etc. en interrogeant les vues du dictionnaire : Reverse Engineering Oracle 10g pour les imports .

Étape 6 : Import des tablespaces transportés dans l’instance cible avec l’utilitaire import data pump impdp

L’import des tablespaces et fichiers de données est réalisé à l’aide du fichier ubix_metadata_tts.dmp réalisé à l’étape 2.

Le répertoire pour l’import data pump est au préalable créé avec la commande CREATE DIRECTORY dans l’instance cible, il s’agit du répertoire contenant les fichiers ubix_metadata* :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

create directory dpump_tts as '/ubix/oracle/export/metadata';
Directory created.

Un fichier de paramètres import_metadata_tts.par pour l’import data pump des tablespaces transportés et des meta données est créé :

import_metadata_tts.par
userid="/ as sysdba"
directory=dpump_tts
dumpfile=ubix_metadata_tts.dmp
logfile=import_metadata_tts.log
transport_datafiles=('/ubix/oracle/UBXU1ORA/UBIX_ADMIN_01.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_TABLES_01.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_TABLES_02.dbf', 
'/ubix/oracle/UBXU1ORA/UBIX_TABLES_03.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_TABLES_04.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_TABLES_05.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_INDEX_01.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_INDEX_02.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_INDEX_03.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_INDEX_04.dbf',
'/ubix/oracle/UBXU1ORA/UBIX_INDEX_05.dbf')

Le fichier de dump donné en paramètre (dumpfile) correspond au fichier d’export des meta données des tablespaces réalisé à l’étape 2 (ubix_metadata_tts.dmp).

L’option transport_datafiles liste tous les fichiers de données des tablespaces convertis et transportés.

L’import data pump est alors appelé avec ce fichier de paramètrage :

oracle@UBXU1ORA> impdp parfile=import_metadata_tts.par

Master table "SYS"."SYS_IMPORT_TRANSPORTABLE_01" successfully loaded/unloaded
Starting "SYS"."SYS_IMPORT_TRANSPORTABLE_01":  /******** AS SYSDBA parfile=import_metadata_tts.par 
Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
Processing object type TRANSPORTABLE_EXPORT/TABLE
Processing object type TRANSPORTABLE_EXPORT/GRANT/OWNER_GRANT/OBJECT_GRANT
 ...
Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
Job "SYS"."SYS_IMPORT_TRANSPORTABLE_01" completed with 1129 error(s) at 18:38:25

Cet import met à jour le catalogue de l’instance Oracle cible pour les tables, indexes, contraintes, déclencheurs (triggers). L’import des meta données des tablespaces transportés est très rapide.

Des avertissements sont probablement consignés dans le fichier de log si des triggers sont par exemple invalides, ces avertissements ne sont pas bien graves car il est fort probable que ces triggers dépendent d’autres objets comme par exemple des fonctions, des procédures, etc., objets qui ne sont pas encore importés. Ces objets complémentaires sont importés dans une prochaine étape.

Par conséquent, vérifier à cette étape que toutes les erreurs remontées ne sont pas liées directement à l’import des tablespaces transportables et qu’elles sont uniquement liées à des problèmes de droits ou de dépendances d’objets, problèmes qui seront corrigés avec l’import des objets complémentaires ultérieurement.

Dans le cas de cet article, seulement des problèmes de validité de triggers sont détectés, aucun problème pour l’import des tablespaces. Voici une commande simple pour extraire les erreurs ORA- dans le fichier de log de l’import :

oracle@UBXU1ORA> cat /ubix/oracle/export/metadata/import_metadata_tts.log \
   | grep 'ORA-' | awk -F":" '{print $1}' | sort -u

ORA-39082

Étape 7 : Mise en lecture écriture des tablespaces dans l’instance cible

Les tablespaces UBIX_TABLES, UBIX_INDEX et UBIX_ADMIN sont en mode lecture seule à l’issue de l’import TTS. Ils sont remis en mode lecture/écriture (read write) avec la commande ALTER TABLESPACE.

alter tablespace ubix_tables read write;

alter tablespace ubix_index read write;

alter tablespace ubix_admin read write;

La mise en mode lecture/écriture est indispensable pour l’import des objets complémentaires (procédures, packages…).

Étape 8 : Tablespaces de données et temporaire par défaut

Les tablespaces utilisateurs sont à présent importés dans l’instance cible, les tablespaces par défaut et temporaire des schémas dans l’instance cible sont alors rétablis. Les commandes ALTER USER à appliquer dans la cible peuvent être générées dynamiquement depuis l’instance source avec la requête ci-dessous :

oracle@UBXU1ORA (source)> sqlplus "/ as sysdba"

set pagesize 1000;
set linesize 800;

select 'alter user '||username||' default tablespace '||default_tablespace||' temporary tablespace '||temporary_tablespace||';'
from dba_users
where username in (select distinct owner
                          from dba_segments
                          where tablespace_name not in ('SYSTEM','SYSAUX'));
alter user UBXREF default tablespace UBIX_ADMIN temporary tablespace TEMP;
alter user OPS$BRU default tablespace UBIX_TABLES temporary tablespace TEMP;
alter user UBXADMIN default tablespace UBIX_ADMIN temporary tablespace TEMP;

Étape 9 : Import des objets non pris en charge par l’export data pump TTS

L’import des objets complémentaires (vues, procédures, fonctions, packages…), objets qui ne sont pas pris en charge par l’export des tablespaces transportables, est ensuite exécuté en utilisant le fichier d’export réalisé à l’étape 2.

Un fichier de paramètres import_metadata_objects.par pour l’import des objets est préparé :

import_metadata_objects.par
userid="/ as sysdba"
directory=dpump_tts
dumpfile=ubix_metadata_objects.dmp
logfile=import_metadata_objects.log
full=y
content=metadata_only
table_exists_action=skip

Le fichier de dump donné en paramètre (dumpfile) correspond au fichier d’export des objets réalisé à l’étape 2 (ubix_metadata_objects.dmp).

L’option content=metadata_only indique un import des définitions sans les données (rows=n).

L’option table_exists_action=skip écarte les tables qui existent déjà. Par voie de conséquence, avec cette option, les meta données des tables comme les contraintes, indexes et triggers seront également écartées, meta données déjà importées dans le catalogue lors du premier import.

L’import data pump est alors appelé avec ce fichier de paramètrage :

oracle@UBXU1ORA> impdp parfile=import_metadata_objects.par

Master table "SYS"."SYS_IMPORT_FULL_01" successfully loaded/unloaded
Starting "SYS"."SYS_IMPORT_FULL_01":  /******** AS SYSDBA parfile=import_metadata_objec
ts.par
Processing object type DATABASE_EXPORT/TABLESPACE
 ...
ORA-31684: Object type TABLESPACE:"UBIX_TABLES" already exists
 ...
ORA-31684: Object type USER:"OPS$BRU" already exists
 ...
Table "OPS$BRU"."AXACOS" exists. All dependent metadata and data will be skipped due to
 table_exists_action of skip
Processing object type DATABASE_EXPORT/SCHEMA/JOB
Processing object type DATABASE_EXPORT/SCHEMA/POST_SCHEMA/PROCACT_SCHEMA
Job "SYS"."SYS_IMPORT_FULL_01" completed with 142 error(s) at 18:54:29

De très nombreuses erreurs ORA-31684 sont rencontrées, ce qui est tout à fait normal car l’option FULL=y est donnée. Inutile de les vérifier une par une, il est préférable de passer à l’étape qui suit immédiatement.

Le plus important est de retrouver les messages "All dependent metadata and data will be skipped due to table_exists_action" pour les tables qui existent déjà dans les tablespaces. Ce message indique que les contraintes, indexes, triggers… qui dépendent des tables existantes sont écartés.

Étape 10 : Recompilation de tous les objets et vérifications finales

À l’issue de l’import, rejouer le script $ORACLE_HOME/rdbms/admin/utlrp.sql pour recompiler tous les objets passés au statut invalide dans l’instance cible. Si des objets demeurent au statut invalide, vérifier si la préparation des comptes, rôles, profils, etc. a été correctement faite (cf Reverse Engineering Oracle 10g pour les imports).

Même si c’est fortement déconseillé, il se peut que des objets applicatifs soient créés avec le compte système oracle SYS, or l’import ne prend pas en compte ce cas de figure, ce qui est le cas également des tables externes. Dans cet article le package applicatif UBIX_SYSSTATS appartient à SYS : le code source de cet objet est généré depuis l’instance source avec la procédure get_ddl du package dbms_metadata, code source qui est ensuite compilé dans l’instance cible.

oracle@UBXU1ORA (source)> sqlplus "/ as sysdba"

set long 200000 pages 0;
select dbms_metadata.get_ddl('PACKAGE','UBIX_SYSSTATS','SYS') from dual;

CREATE OR REPLACE PACKAGE "SYS"."UBIX_SYSSTATS" is
  procedure gather_sys_stats;
  procedure delete_sys_stats;
end;

CREATE OR REPLACE PACKAGE BODY "SYS"."UBIX_SYSSTATS" is
  procedure gather_sys_stats is begin sys.dbms_stats.gather_schema_stats('SYS'); end;
  procedure delete_sys_stats is begin sys.dbms_stats.delete_schema_stats('SYS'); end;
end;

Autre point important, l’octroi de droits aux comptes applicatifs sur des objets systèmes oracle SYS et SYSTEM (vues du dictionnaire, packages DBMS%…) peut également être la source d’objets applicatifs invalides. Utiliser l’instance source pour retrouver les éventuels droits à donner sur les objets systèmes aux comptes applicatifs dans l’instance cible :

oracle@UBXU1ORA (source)> sqlplus "/ as sysdba"

select 'GRANT '||privilege||' ON "'||owner||'"."'||table_name||'" TO "'||grantee||'"'||decode(grantable, 'YES', ' WITH GRANT OPTION')||';'
     from dba_tab_privs
     where owner in ('SYS','SYSTEM')
     and grantee in ('OPS$BRU','UBXADMIN','UBXREF');
GRANT SELECT ON "SYS"."DBA_TAB_PRIVS" TO "OPS$BRU"
GRANT EXECUTE ON "SYS"."DBMS_ALERT" TO "OPS$BRU"
GRANT EXECUTE ON "SYS"."DBMS_PIPE" TO "OPS$BRU"
GRANT EXECUTE ON "SYS"."DBMS_LOCK" TO "OPS$BRU"
GRANT SELECT ON "SYS"."DBA_SYNONYMS" TO "OPS$BRU"
GRANT SELECT ON "SYS"."V_$SESSION" TO "OPS$BRU" WITH GRANT OPTION
GRANT SELECT ON "SYS"."DBA_DATA_FILES" TO "UBXADMIN" WITH GRANT OPTION
GRANT SELECT ON "SYS"."DBA_TEMP_FILES" TO "UBXADMIN" WITH GRANT OPTION
 ...

Pour retrouver tous les objets au statut invalide dans l’instance cible :

oracle@UBXU1ORA> sqlplus "/ as sysdba"

select owner, object_type, object_name 
     from dba_objects 
     where status='INVALID' 
     and owner not in ('SYS','SYSTEM');
OWNER        OBJECT_TYPE          OBJECT_NAME
------------ -------------------  ----------------------
OPS$BRU      PACKAGE BODY         UFO_RISK

Un seul package est invalide dans l’exemple de cet article, mais il s’agit d’une erreur applicative "normale".

Dernière vérification d’usage indispensable avant la mise à disposition aux équipes applicatives, comparer le nombre d’objets par type dans l’instance cible et l’instance source, aucun delta ne doit apparaître :

Instance source Instance cible
oracle@UBXU1ORA> sqlplus "/ as sysdba"

select distinct object_type, 
     count(1) 
     from dba_objects 
     where owner in ('OPS$BRU',
                     'UBXADMIN',
                     'UBXREF')
     group by object_type
     order by object_type
OBJECT_TYPE           COUNT(1)
------------------- ----------
FUNCTION                     3
INDEX                     2546
LOB                          3
PACKAGE                    224
PACKAGE BODY               224
PROCEDURE                   32
SEQUENCE                   189
SYNONYM                    152
TABLE                     2905
TRIGGER                    589
TYPE                        22
VIEW                      2930
oracle@UBXU1ORA> sqlplus "/ as sysdba"

select distinct object_type, 
     count(1) 
     from dba_objects 
     where owner in ('OPS$BRU',
                     'UBXADMIN',
                     'UBXREF')
     group by object_type
     order by object_type
OBJECT_TYPE           COUNT(1)
------------------- ----------
FUNCTION                     3
INDEX                     2546
LOB                          3
PACKAGE                    224
PACKAGE BODY               224
PROCEDURE                   32
SEQUENCE                   189
SYNONYM                    152
TABLE                     2905
TRIGGER                    589
TYPE                        22
VIEW                      2930