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.