Datapump : ordre des objects exportés et importés - Datapump: order of exported and imported objects
Introduction
Vous est-il déjà arrivé de regarder, lors d'un export/import datapump, l'ordre de traitement des objets ? Si oui, quelle conclusion en avez-vous tiré : les objets sont exportés/importés selon un ordre bien précis ou bien Oracle traite cela de façon anarchique ?
Faisons un petit test pour essayer d'y voir plus clair.
Points d'attention
N/A.
Base de tests
Une base Oracle 19 multi-tenants.
Exemples
============================================================================================
Base de test
============================================================================================
Je suis dans une PDB, connecté comme SYS.
[oracle@localhost ~]$ sqlplus sys@orcl as sysdba
SQL> show con_name
CON_NAME
------------------------------
ORCL
Création de tables et séquences dans les schémas SYSTEM et HR; attention à garder les guillemets autour des noms pour ce test.
SQL> CREATE TABLE SYSTEM."TA"(id number, id02 number);
SQL> CREATE TABLE SYSTEM."Tc"(name varchar2(50 char));
SQL> CREATE TABLE SYSTEM."TF"(id number(6), name varchar2(50 char));
SQL> CREATE SEQUENCE SYSTEM."seqA";
SQL> CREATE SEQUENCE SYSTEM."seqb";
SQL> CREATE SEQUENCE SYSTEM."seqD";
SQL> BEGIN for i in 1..1000 loop INSERT INTO SYSTEM."TA" (id) values (i); end loop; END; /
SQL> BEGIN for i in 1..10000 loop INSERT INTO SYSTEM."Tc" values('DURAND'||to_char(i)); end loop; END; /
SQL> BEGIN for i in 1..100000 loopINSERT INTO SYSTEM."TF" values(i, 'DURAND'||to_char(i)); end loop; END; /
SQL> commit;
SQL> CREATE TABLE HR."TAA"(id number);
SQL> CREATE TABLE HR."TBb"(name varchar2(50 char));
SQL> CREATE TABLE HR."TXX"(id number(10), name varchar2(50 char));
SQL> BEGIN for i in 1..500000 loop INSERT INTO HR."TAA" values(i); end loop; END; /
SQL> BEGIN for i in 1..800000 loop INSERT INTO HR."TBb" values('DURAND'||to_char(i)); end loop; END; /
SQL> BEGIN for i in 1..1000000 loop INSERT INTO HR."TXX" values(i, 'DURAND'||to_char(i)); end loop; END; /
SQL> commit;
Quelle est la taille des segments créés ? Voyons ça par deux tris, le duo OWNER et SEGMENT_NAME pour le premier, et la taille pour le second. Attention aux minuscules, qui sont plus grandes que les majuscules en langage américain : Tc est bien affichée après TF.
SQL> show parameter nls_
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
...
nls_language string AMERICAN
nls_territory string AMERICA
...
SQL> SELECT OWNER, SEGMENT_TYPE, SEGMENT_NAME, sum(BYTES)/(1024*1024) AS "TAILLE Mo" FROM DBA_SEGMENTS WHERE SEGMENT_NAME LIKE ('T_') OR SEGMENT_NAME LIKE ('T__') GROUP BY OWNER, SEGMENT_TYPE, SEGMENT_NAME ORDER BY OWNER, SEGMENT_NAME ;
OWNER SEGMENT_TYPE SEGMENT_NA TAILLE Mo
---------- ------------------ ---------- ----------
HR TABLE TAA 7
HR TABLE TBb 16
HR TABLE TXX 26
SYSTEM TABLE TA .0625
SYSTEM TABLE TF 3
SYSTEM TABLE Tc .1875
6 rows selected.
SQL> SELECT OWNER, SEGMENT_TYPE, SEGMENT_NAME, sum(BYTES)/(1024*1024) AS "TAILLE Mo" FROM DBA_SEGMENTS WHERE SEGMENT_NAME LIKE ('T_') OR SEGMENT_NAME LIKE ('T__') GROUP BY OWNER, SEGMENT_TYPE, SEGMENT_NAME ORDER BY "TAILLE Mo";
OWNER SEGMENT_TYPE SEGMENT_NA TAILLE Mo
---------- ------------------ ---------- ----------
SYSTEM TABLE TA .0625
SYSTEM TABLE Tc .1875
SYSTEM TABLE TF 3
HR TABLE TAA 7
HR TABLE TBb 16
HR TABLE TXX 26
6 rows selected.
============================================================================================
Export/Import datapump
============================================================================================
J'exporte les deux schémas de test, à savoir SYSTEM et HR. Dans ce qui est affiché à l'écran, l'ordre de traitement est celui alphabétique des schémas puis des tables, mais pas celui du nombre de lignes des tables ni de leur taille. À noter que les séquences exportées ne sont pas listées dans le fichier de log.
[oracle@localhost ~]$ expdp SCHEMAS=SYSTEM, HR DIRECTORY=DATA_PUMP_DIR DUMPFILE=EXP_SCHEMAS_20220221_test.dmp LOGFILE=EXP_SCHEMAS_20220221_test.log
Export: Release 19.0.0.0.0 - Production on Mon Feb 21 10:32:15 2022
Version 19.3.0.0.0
...
. . exported "HR"."TAA" 4.282 MB 500000 rows
. . exported "HR"."TBb" 12.86 MB 800000 rows
. . exported "HR"."TXX" 20.86 MB 1000000 rows
. . exported "SYSTEM"."TA" 13.17 KB 1000 rows
. . exported "SYSTEM"."TF" 1.986 MB 100000 rows
. . exported "SYSTEM"."Tc" 150.4 KB 10000 rows
Master table "SYSTEM"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded
******************************************************************************
Quid de l'ordre lors de l'import ? L'ordre n'est pas le même que lors de l'export : les tables de SYSTEM sont traitées avant et après les tables de HR, sans respecter un ordre quelconque : alphabétique, nombre de lignes, taille. Les tables de HR sont importées selon le même ordre que lors de l'export. En outre, lors de l'import, on voit le nom des séquences traitées, alors que ce n'était pas le cas lors de l'export. Et que voit-on ? Que l'ordre alphabétique n'est pas respecté ; on devrait avoir seqA, seqD, seqb puisque seqb est entièrement en minuscules.
[oracle@localhost ~]$ impdp SYSTEM DIRECTORY=DATA_PUMP_DIR DUMPFILE=EXP_SCHEMAS_20220221_test.dmp logfile=IMP_SCHEMAS_20220222_test.log sqlfile=IMP_SCHEMAS_20220222_sqlfile.sql
...
CREATE SEQUENCE "SYSTEM"."seqA"
CREATE SEQUENCE "SYSTEM"."seqb"
CREATE SEQUENCE "SYSTEM"."seqD"
CREATE TABLE "SYSTEM"."TF"
CREATE TABLE "HR"."TAA"
CREATE TABLE "HR"."TBb"
CREATE TABLE "HR"."TXX"
CREATE TABLE "SYSTEM"."TA"
CREATE TABLE "SYSTEM"."Tc"
...
Tri par nom de schéma et des tables
C'est cet ordre qui est retenu pour l'export.
SQL> SELECT OWNER, OBJECT_NAME, to_char(CREATED, 'DD/MM/YYYY HH24:MI:SSSS') FROM DBA_OBJECTS WHERE OBJECT_TYPE IN ('TABLE', 'SEQUENCE', 'USER') AND (OWNER = 'HR' OR (OWNER = 'SYSTEM' AND OBJECT_NAME LIKE ('T_'))) ORDER BY OWNER, OBJECT_NAME;
OWNER OBJECT_NAME TO_CHAR(CREATED,'DD/M
--------------- ------------------------------ ---------------------
HR TAA 21/02/2022 10:26:5555
HR TBb 21/02/2022 10:27:0202
HR TXX 21/02/2022 10:29:5050
SYSTEM TA 21/02/2022 10:25:4848
SYSTEM TF 21/02/2022 10:25:5858
SYSTEM Tc 21/02/2022 10:25:5454
20 rows selected.
Tri sur date de création
Ce n'est pas l'ordre de l'import datapump.
SQL> SELECT OWNER, OBJECT_NAME, to_char(CREATED, 'DD/MM/YYYY HH24:MI:SSSS') FROM DBA_OBJECTS WHERE OBJECT_TYPE IN ('TABLE', 'SEQUENCE', 'USER') AND (OWNER = 'HR' OR (OWNER = 'SYSTEM' AND OBJECT_NAME LIKE ('T_'))) ORDER BY OWNER, 3;
OWNER OBJECT_NAME TO_CHAR(CREATED,'DD/M
--------------- ------------------------------ ---------------------
HR TAA 21/02/2022 10:26:5555
HR TBb 21/02/2022 10:27:0202
HR TXX 21/02/2022 10:29:5050
SYSTEM TA 21/02/2022 10:25:4848
SYSTEM Tc 21/02/2022 10:25:5454
SYSTEM TF 21/02/2022 10:25:5858
Conclusion
Lors de l'export, un ordre semble être retenu : traiter les objets des schémas puis les tables selon l'ordre alphabétique. Lors de l'import, aucun ordre ne semble retenu mais, me direz-vous, cela est-il important ? A priori non puisqu'Oracle, selon mon test, importe n'importe comment les objets, notamment les tables. Et les contraintes d'intégrité Foreign Key? Elles, elles sont importantes, on ne peut pas importer n'importe comment deux tables qui ont des contraintes de clés étrangères sous risque d'INSERTs qui échouent. Comment fait Oracle ? C'est simple, les contraintes sont désactivées puis réactivées à la fin de l'import :-) C'est tout bête, mais il fallait y penser.
Bref, en conclusion de ce test, aucun ordre ne semble respecté lors d'un import datapump.