Gestion de bases de données

ORA-20011 ORA-29913 et ORA-29400 avec erreurs KUP-XXXXX associées provenant de DBMS_STATS .GATHER_STATS_JOB

S'APPLIQUE À : Oracle Database Standard, Enterprise, Personal Edition

Oracle Database - Standard Edition - Version 11.2.0.2 et ultérieures
Oracle Database - Enterprise Edition - Version 11.2.0.2 et ultérieures
Oracle Database - Personal Edition - Version 11.2.0.2 et ultérieures
Les informations de ce document s'appliquent à toutes les plateformes.

SYMPTÔMES : erreurs ORA-20011, ORA-29913 et ORA-29400

L'erreur ORA-29913 indique la fonction externe "ODCIEXTTABLEOPEN".

Dans ces cas, les principaux symptômes sont généralement les suivants :

DBMS_STATS est exécuté sous une forme ou une autre

Des erreurs ORA-20011, ORA-29913 et ORA-29400 apparaissent, l'erreur ORA-29913 indiquant la fonction externe "ODCIEXTTABLEOPEN", ce qui signifie qu'une erreur s'est produite lors de l'appel (callout) de la fonction externe "ODCIEXTTABLEOPEN " pendant la tentative d'ouverture d'une table externe.

Voici quelques exemples précis :

Lors de l'exécution de GATHER_STATS_JOB, les erreurs suivantes se produisent :

ORA-20011: Approximate NDV failed:ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error

généralement accompagnées d'autres erreurs variées, comme :

KUP-11024: This external table can only be accessed from within a Data Pump job

entre autres.

Le journal d'alertes (alert log) peut aussi afficher les erreurs suivantes :

Exception [type: SIGSEGV, Address not mapped to object] [ADDR:0x5400000000] [PC:0xFFFFFFFF7CB19EFC, memcpy%sun4u-opl()+236] [flags: 0x0, count: 1]
ERROR: Unable to normalize symbol name for the following short stack (at offset 200):
dbgexProcessError()+176<-dbgePostErrorKGE()+1348<-dbkePostKGE_kgsf()+48<-kgeade()+

REMARQUE : dans les cas où le fichier est introuvable dans le répertoire indiqué, l'erreur suivante est levée :

KUP-04040: file %s in %s not found

Voir :

Document 150737.1 ORA-29913, ORA-29400, KUP-04040 While Selecting from External Table
Document 1290722.1 "KUP-04040: file timezdif.csv in TIMEZDIF_DIR not found " logged by GATHER_STATS_JOB in alert.log after upgrade
Document 1305127.1 KUP-04040: file TRCA_CONTROL.txt in TRCA$STAGE not found

Vous pouvez aussi obtenir dans le fichier de trace un texte comme celui-ci :

*** 2012-09-10 05:00:11.921
DBMS_STATS: GATHER_STATS_JOB: GATHER_TABLE_STATS('"SH"','"SALES_TRANSACTIONS_EXT"','""', ...)
DBMS_STATS: ORA-20011: Approximate NDV failed: ORA-29913: error in executing ODCIEXTTABLEOPEN callout
ORA-29400: data cartridge error
error opening file ../demo/schema/log/ext_1v3.log

CAUSE : Oracle Datapump, tables externes, tables temporaires Datapump

La cause principale de ce problème est qu'un fichier du système d'exploitation associé à une "table externe" a existé à un moment donné, mais n'existe plus. La base de données croit pourtant que le fichier de la table existe toujours, car les informations du dictionnaire sur cet objet n'ont pas été modifiées pour refléter ce changement. Lorsque DBMS_STATS est exécuté sur la table en question, il fait appel à la table externe, et cet appel échoue parce que l'objet n'est plus là.

Une table externe peut ne plus exister pour de nombreuses raisons, notamment :

Les tables externes temporaires de Datapump n'ont pas été nettoyées correctement. Les informations du dictionnaire auraient dû être supprimées à la fin des tâches DataPump.

Le fichier du système d'exploitation d'une table externe a été supprimé sans que les informations correspondantes du dictionnaire de données aient été nettoyées. Par exemple, des tables des schémas de démonstration d'Oracle, comme la table externe “SALES_TRANSACTIONS_EXT”, ont pu être supprimées sans que le dictionnaire ait été mis à jour en conséquence. La table "SALES_TRANSACTIONS_EXT" est une table externe du schéma "SH", l'un des schémas de démonstration fournis par Oracle.

SOLUTION : table externe temporaire de Datapump

Pour l'essentiel, la solution consiste à nettoyer les entrées orphelines du dictionnaire. Différentes solutions conviennent selon la nature exacte de la cause principale ; elles sont décrites ci-dessous :

Table externe temporaire de Datapump

  1. Assurez-vous qu'aucune tâche DataPump ne s'exécute en même temps que la tâche DBMS_STATS (afin d'éviter toute complication liée à un nettoyage effectué pendant qu'un autre traitement est en cours).
  2. Vérifiez et nettoyez les tâches DataPump orphelines. L'article suivant traite d'un cas où DBMS_WORKLOAD_CAPTURE ne supprime pas les tables externes (ce qui provoque l'erreur ORA-20011 de DBMS_STATS)

    Document 10327346.8 Bug 10327346 - DBMS_WORKLOAD_CAPTURE does not drop external tables (causing ORA-20011 from DBMS_STATS)


    Les deux étapes ci-dessus peuvent être réalisées en suivant ce document :

    Document 336014.1 How To Cleanup Orphaned DataPump Jobs In DBA_DATAPUMP_JOBS ?

  3. Identifiez les tables externes. Pour cela, exécutez ce qui suit en tant que SYSDBA dans SQL*Plus
spool obj.out
set linesize 200 trimspool on
set pagesize 2000
col owner form a30
col created form a25
col last_ddl_time form a25
col object_name form a30
col object_type form a25

select OWNER,OBJECT_NAME,OBJECT_TYPE, status,
to_char(CREATED,'dd-mon-yyyy hh24:mi:ss') created
,to_char(LAST_DDL_TIME , 'dd-mon-yyyy hh24:mi:ss') last_ddl_time
from dba_objects
where object_name like 'ET$%'
/

select owner, TABLE_NAME, DEFAULT_DIRECTORY_NAME, ACCESS_TYPE
from dba_external_tables
order by 1,2
/

spool off

Recoupez les informations de DBA_OBJECTS et de DBA_EXTERNAL TABLES ci-dessus pour identifier les tables externes temporaires qui appartiennent à DataPump

4. Supprimez les tables externes temporaires qui appartiennent à DataPump, p. ex. :

SQL> drop table system.&1 purge;
Enter value for 1: ET$00654E1E0001
old 1: drop table system.&1 purge
new 1: drop table system.ET$00654E1E0001 purge

Autres tables externes

Lorsque des tables externes précises sont manquantes (qu'il s'agisse de tables des schémas de démonstration ou d'autres tables), la démarche est sensiblement la même, et le problème peut être résolu en suivant les procédures ci-dessous. Par exemple, si l'erreur supplémentaire est 'error opening file ../demo/schema/log/ext_1v3.log', cela indique un problème d'ouverture ou de localisation du fichier journal dans le répertoire du schéma de démonstration. Cela signifie que les tables de démonstration n'ont pas été nettoyées correctement :

1. Essayez de localiser les fichiers de ces tables dans leur répertoire.

Pour vérifier si un fichier se trouve à l'emplacement prévu pour le fichier externe, la requête suivante peut être utile.

undefine owner
undefine table_pattern

select el.table_name, el.owner, dir.directory_path||'/'||dir.directory_name "path"
from dba_external_locations el
, dba_directories dir
where el.table_name like '%&&table_pattern%'
and el.owner like '%&&owner%'
and el.directory_owner = dir.owner
and el.directory_name = dir.directory_name
order by 1, 2;

Il se peut que les fichiers existent toujours, mais qu'ils aient simplement été renommés ou déplacés. Dans ce cas, vous pouvez corriger l'emplacement pour éviter le problème. Si le fichier a été supprimé, suivez l'une ou l'autre des étapes suivantes :

2. Verrouillez les statistiques de ces tables avec la commande suivante :

DBMS_STATS.LOCK_TABLE_STATS ('ownname','tabname');

(Cette étape empêche DBMS_STATS de collecter des statistiques sur la table manquante)

ET/OU

Supprimez l'objet du dictionnaire correspondant à la table externe. Par exemple, si le fichier du système d'exploitation de la table de démonstration "SALES_TRANSACTIONS_EXT" est manquant, vous utiliserez :

DROP TABLE SALES_TRANSACTIONS_EXT;