Oracle Datapump : Comment gérer l’erreur fatale sur l’import des commentaires

Cet article constitue un retour d’expérience sur une erreur qui peut être rencontrée durant un import Datapump et qui ne permet pas l’aboutissement de celui-ci car le job d’import se termine avec le statut « stopped due to fatal error ».

L’erreur dont il est question est la suivante :

Processing object type DATABASE_EXPORT/SCHEMA/VIEW/COMMENT
ORA-39126: Worker unexpected fatal error in KUPW$WORKER.PUT_DDLS [COMMENT]
ORA-06502: PL/SQL: numeric or value error
LPX-00217: invalid character 0 (U+0000)
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 95
ORA-06512: at "SYS.KUPW$WORKER", line 9001
----- PL/SQL Call Stack -----
object line object
handle number name
0x134309688 20462 package body SYS.KUPW$WORKER
0x134309688 9028 package body SYS.KUPW$WORKER
0x134309688 16665 package body SYS.KUPW$WORKER
0x134309688 3956 package body SYS.KUPW$WORKER
0x134309688 9725 package body SYS.KUPW$WORKER
0x134309688 1775 package body SYS.KUPW$WORKER
0x11c8eae00 2 anonymous block
ORA-39097: Data Pump job encountered unexpected error -1427
ORA-39065: unexpected master process exception in DISPATCH
ORA-01427: single-row subquery returns more than one row

Cette erreur est provoquée par la tentative d’import de métadonnées (commentaires sur tables ou sur colonnes) comportant des caractères ne pouvant être parsés en XML.

Il existe à ce sujet une note Oracle :

 DataPump Import (IMPDP) Fails To Load Comments Due to ORA-06502 And LPX-00217 (Doc ID 2251257.1)

Le contournement de cette erreur se fait par exclusion des commentaires durant l’import grâce à la clause suivante et propose la réintégration des commentaires « manuellement » :

EXCLUDE=TABLE/COMMENT

Cependant, la solution pour extraire les métadonnées depuis la base source afin de les réintégrer sur la cible reste peu détaillée  : La note Oracle propose deux requêtes meta-sql permettant d’identifier les tables et les colonnes de tables ayant des commentaires et de générer les ordres d’extraction DDL pour ces tables. Mais ces deux requêtes génèrent de très nombreux doublons car elles considèrent d’une part les commentaires sur tables et celles sur colonnes distinctement, et d’autre part parce que pour une table ayant n colonnes commentées, le même ordre apparaitra alors n fois (alors qu’un seul aurait suffi).

L’objet de cet article est donc de détailler les étapes nécessaires à la génération des ordres de création des commentaires tout en optimisant les ordres nécessaires.

 

Présentons d’abord la démarche :

Etape 1 :

Une première requête meta-sql à exécuter sur la source permet d’identifier les tables ayant un commentaire (ou dont une ou plusieurs colonnes comportent un commentaire) et de générer l’ordre de type dbms_metadata.get_dependent_ddl qui extraira ensuite les commentaires.

Etape 2 :

L’exécution de ces ordres (toujours sur la source) génère ensuite les ordres de création des commentaires de type COMMENT ON TABLE ou COMMENT ON COLUMN.

Etape 3 :

Les ordres générés dans l’étape 2 peuvent ensuite être joués sur la base cible (après l’import avec exclusion des commentaires pour que celui puisse aboutir).

 

Concrètement, voici les ordres qui peuvent être utilisés :

Etape 1 (sur la base source) :

set lines 300
set pages 50000
set head off
set feed off
spool ordre_dbms_metadata.sql
SELECT distinct 'select dbms_metadata.get_dependent_ddl(''COMMENT'','''|| table_name || ''','''|| owner || ''')FROM DUAL;'
FROM
(select table_name, owner from DBA_TAB_COMMENTS t
where t.COMMENTS is not null
and t.owner in ('SCHEMA1','SCHEMA2',…)
union all
select table_name, owner from DBA_COL_COMMENTS c
where  c.COMMENTS is not null
and c.owner in ('SCHEMA1','SCHEMA2',…));
spool off

Etape 2 (toujours sur la base source) :

set head off
set long 50000
set lines 5000
set pages 50000
set longchunksize 5000
spool ordre_creat_comment.sql
@ordre_dbms_metadata.sql
Spool off

Ici, le « set long 50000 » est important car les ordres dbms_metadata.get_dependent_ddl retournent un long qui pourrait être tronqué.

Etape 2bis :

La suppression des espaces en fin de ligne induit par le set long 50000 permet d’alléger le script de création des commentaires.

Exemple sous linux :

cat ordre_creat_comment.sql | sed 's/\s\+$//' > ordre_creat_comment_bis.sql

Etape 3 (sur la base cible après l’import) :

set define off
spool log_creation_commentaires.log
@ordre_creat_comment_bis.sql
Spool off

Ici, le « set define off » permet de ne pas considérer le caractère « & » comme une variable dans le cas où un commentaire le contiendrait.

 

Bien sûr, toute chose est perfectible, mais j’espère que cet article vous aura permis d’aborder un peu plus complètement la réintégration des commentaires dans le cas où vous auriez rencontré cette erreur.